Skip to content

Commit 17d51f7

Browse files
dfreedmcopybara-github
authored andcommitted
(chore) Fix Typescript 4.4 compilation issues with aria properties
Typescript 4.4 defines aria properties on Element prototype to be non-nullable. This matches the spec language in https://www.w3.org/TR/wai-aria-1.2/#AriaAttributes, but Chrome and Safari as of when these properties were added to MWC allowed the property to be set with `null` to clear the attribute. There should be some ongoing work to align the spec and browsers in behavior, but that is out of scope for this project, unblocking Typescript 4.4 is of higher priority. Related microsoft/TypeScript-DOM-lib-generator#1119 Fixes #2676 PiperOrigin-RevId: 395581595
1 parent 76c6838 commit 17d51f7

File tree

13 files changed

+33
-32
lines changed

13 files changed

+33
-32
lines changed

packages/base/aria-property.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function tsDecorator(
9797
* class MyElement {
9898
* @ariaProperty
9999
* @property({ type: String, attribute: 'aria-label' })
100-
* ariaLabel?: string;
100+
* ariaLabel!: string;
101101
* }
102102
* ```
103103
* @category Decorator

packages/base/test/aria-property.test.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ import {fixture, TestFixture} from '../../../test/src/util/helpers';
2020
class TestElement extends LitElement {
2121
@ariaProperty
2222
@property({type: String, attribute: 'aria-label'})
23-
ariaLabel?: string;
23+
ariaLabel!: string;
2424

25-
protected internalAriaChecked: 'true'|'false'|'mixed'|undefined = undefined;
25+
protected internalAriaChecked: 'true'|'false'|'mixed'|null = null;
2626

2727
@ariaProperty
2828
@property({attribute: 'aria-checked'})
29-
set ariaChecked(value: 'true'|'false'|'mixed'|undefined) {
29+
set ariaChecked(value: 'true'|'false'|'mixed'|null) {
3030
if (value === 'mixed') {
3131
this.internalAriaChecked = value;
3232
} else {
33-
this.internalAriaChecked = undefined;
33+
this.internalAriaChecked = null;
3434
}
3535
this.requestUpdate();
3636
}
@@ -39,7 +39,7 @@ class TestElement extends LitElement {
3939
return this.internalAriaChecked;
4040
}
4141

42-
@property({attribute: 'aria-owns'}) @ariaProperty ariaOwns?: string;
42+
@property({attribute: 'aria-owns'}) @ariaProperty ariaOwns!: string;
4343

4444
override render() {
4545
return html`<input aria-label="${
@@ -86,7 +86,7 @@ describe('aria-property:', () => {
8686
expect(shadowTargetElement).not.toBeNull();
8787
return;
8888
}
89-
expect(component.ariaLabel).toEqual(undefined);
89+
expect(component.ariaLabel).toBeFalsy();
9090
component.ariaLabel = 'foo';
9191
await component.updateComplete;
9292
expect(component.getAttribute('aria-label')).toBeNull();
@@ -107,7 +107,8 @@ describe('aria-property:', () => {
107107
expect(shadowTargetElement).not.toBeNull();
108108
return;
109109
}
110-
expect(component.ariaChecked).toEqual(undefined);
110+
expect(component.ariaChecked).toBeFalsy();
111+
;
111112
component.ariaChecked = 'mixed';
112113
await component.updateComplete;
113114
expect(component.getAttribute('aria-checked')).toBeNull();
@@ -128,7 +129,7 @@ describe('aria-property:', () => {
128129
expect(shadowTargetElement).not.toBeNull();
129130
return;
130131
}
131-
expect(component.ariaOwns).toEqual(undefined);
132+
expect(component.ariaOwns).toBeFalsy();
132133
component.ariaOwns = 'baz';
133134
await component.updateComplete;
134135
expect(component.getAttribute('aria-owns')).toBeNull();
@@ -149,7 +150,7 @@ describe('aria-property:', () => {
149150
expect(shadowTargetElement).not.toBeNull();
150151
return;
151152
}
152-
expect(component.ariaLabel).toEqual(undefined);
153+
expect(component.ariaLabel).toBeFalsy();
153154
component.setAttribute('aria-label', 'foo');
154155
await component.updateComplete;
155156
expect(component.getAttribute('aria-label')).toBeNull();
@@ -170,7 +171,7 @@ describe('aria-property:', () => {
170171
expect(shadowTargetElement).not.toBeNull();
171172
return;
172173
}
173-
expect(component.ariaChecked).toEqual(undefined);
174+
expect(component.ariaChecked).toEqual(null);
174175
component.setAttribute('aria-checked', 'mixed');
175176
await component.updateComplete;
176177
expect(component.getAttribute('aria-checked')).toBeNull();
@@ -192,7 +193,7 @@ describe('aria-property:', () => {
192193
expect(shadowTargetElement).not.toBeNull();
193194
return;
194195
}
195-
expect(component.ariaOwns).toEqual(undefined);
196+
expect(component.ariaOwns).toBeFalsy();
196197
component.setAttribute('aria-owns', 'baz');
197198
await component.updateComplete;
198199
expect(component.getAttribute('aria-owns')).toBeNull();

packages/button/mwc-button-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class ButtonBase extends LitElement {
2525
/** @soyPrefixAttribute */
2626
@ariaProperty
2727
@property({type: String, attribute: 'aria-haspopup'})
28-
ariaHasPopup?: AriaHasPopup;
28+
ariaHasPopup!: AriaHasPopup;
2929

3030
@property({type: Boolean, reflect: true}) raised = false;
3131

packages/checkbox/mwc-checkbox-base.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,17 @@ export class CheckboxBase extends FormElement {
3636
/** @soyPrefixAttribute */
3737
@ariaProperty
3838
@property({type: String, attribute: 'aria-label'})
39-
ariaLabel?: string;
39+
ariaLabel!: string;
4040

4141
/** @soyPrefixAttribute */
4242
@ariaProperty
4343
@property({type: String, attribute: 'aria-labelledby'})
44-
ariaLabelledBy?: string;
44+
ariaLabelledBy!: string;
4545

4646
/** @soyPrefixAttribute */
4747
@ariaProperty
4848
@property({type: String, attribute: 'aria-describedby'})
49-
ariaDescribedBy?: string;
49+
ariaDescribedBy!: string;
5050

5151
/**
5252
* Touch target extends beyond visual boundary of a component by default.

packages/circular-progress-four-color/test/mwc-circular-progress-four-color.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe('mwc-circular-progress-four-color', () => {
5454
expect(element.progress).toEqual(0);
5555
expect(element.density).toEqual(0);
5656
expect(element.closed).toBeFalse();
57-
expect(element.ariaLabel).toEqual(undefined);
57+
expect(element.ariaLabel).toBeFalsy();
5858
});
5959

6060
it('open sets closed to false', async () => {

packages/circular-progress/mwc-circular-progress-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class CircularProgressBase extends LitElement {
2626
/** @soyPrefixAttribute */
2727
@ariaProperty
2828
@property({type: String, attribute: 'aria-label'})
29-
ariaLabel?: string
29+
ariaLabel!: string
3030

3131
open() {
3232
this.closed = false;

packages/circular-progress/test/mwc-circular-progress.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {fixture, TestFixture} from '../../../test/src/util/helpers';
1515
const INDETERMINATE_CLASS = 'mdc-circular-progress--indeterminate';
1616

1717
interface ProgressProps {
18-
ariaLabel: string|undefined;
18+
ariaLabel: string;
1919
progress: number;
2020
indeterminate: true;
2121
density: number;
@@ -56,7 +56,7 @@ describe('mwc-circular-progress', () => {
5656
expect(element.progress).toEqual(0);
5757
expect(element.density).toEqual(0);
5858
expect(element.closed).toBeFalse();
59-
expect(element.ariaLabel).toEqual(undefined);
59+
expect(element.ariaLabel).toBeFalsy();
6060
});
6161

6262
it('open sets closed to false', async () => {

packages/icon-button-toggle/mwc-icon-button-toggle-base.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class IconButtonToggleBase extends LitElement {
2323
/** @soyPrefixAttribute */
2424
@ariaProperty
2525
@property({type: String, attribute: 'aria-label'})
26-
ariaLabel?: string;
26+
ariaLabel!: string;
2727

2828
@property({type: Boolean, reflect: true}) disabled = false;
2929

@@ -32,10 +32,10 @@ export class IconButtonToggleBase extends LitElement {
3232
@property({type: String}) offIcon = '';
3333

3434
// `aria-label` of the button when `on` is true.
35-
@property({type: String}) ariaLabelOn?: string;
35+
@property({type: String}) ariaLabelOn!: string;
3636

3737
// `aria-label` of the button when `on` is false.
38-
@property({type: String}) ariaLabelOff?: string;
38+
@property({type: String}) ariaLabelOff!: string;
3939

4040
@property({type: Boolean, reflect: true}) on = false;
4141

packages/icon-button/mwc-icon-button-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class IconButtonBase extends LitElement {
2929
/** @soyPrefixAttribute */
3030
@ariaProperty
3131
@property({type: String, attribute: 'aria-haspopup'})
32-
ariaHasPopup?: AriaHasPopup;
32+
ariaHasPopup!: AriaHasPopup;
3333

3434
@query('button') buttonElement!: HTMLElement;
3535

packages/linear-progress/mwc-linear-progress-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class LinearProgressBase extends LitElement {
2929
@property({type: Boolean, reflect: true}) closed = false;
3030

3131
/** @soyPrefixAttribute */
32-
@ariaProperty @property({attribute: 'aria-label'}) ariaLabel?: string;
32+
@ariaProperty @property({attribute: 'aria-label'}) ariaLabel!: string;
3333

3434
@state() protected stylePrimaryHalf = '';
3535
@state() protected stylePrimaryFull = '';

0 commit comments

Comments
 (0)