@vaadin/a11y-base 25.2.0-alpha9 → 25.2.0-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,237 +9,236 @@ import { TabindexMixin } from './tabindex-mixin.js';
9
9
 
10
10
  /**
11
11
  * A mixin to forward focus to an element in the light DOM.
12
- *
13
- * @polymerMixin
14
- * @mixes FocusMixin
15
- * @mixes TabindexMixin
16
12
  */
17
- export const DelegateFocusMixin = dedupeMixin(
18
- (superclass) =>
19
- class DelegateFocusMixinClass extends FocusMixin(TabindexMixin(superclass)) {
20
- static get properties() {
21
- return {
22
- /**
23
- * Specify that this control should have input focus when the page loads.
24
- */
25
- autofocus: {
26
- type: Boolean,
27
- },
28
-
29
- /**
30
- * A reference to the focusable element controlled by the mixin.
31
- * It can be an input, textarea, button or any element with tabindex > -1.
32
- *
33
- * Any component implementing this mixin is expected to provide it
34
- * by using `this._setFocusElement(input)` Polymer API.
35
- *
36
- * Toggling `tabindex` attribute on the host element propagates its value to `focusElement`.
37
- *
38
- * @protected
39
- * @type {!HTMLElement}
40
- */
41
- focusElement: {
42
- type: Object,
43
- readOnly: true,
44
- observer: '_focusElementChanged',
45
- sync: true,
46
- },
47
-
48
- /**
49
- * Override the property from `TabIndexMixin`
50
- * to ensure the `tabindex` attribute of the focus element
51
- * will be restored to `0` after re-enabling the element.
52
- *
53
- * @protected
54
- * @override
55
- */
56
- _lastTabIndex: {
57
- value: 0,
58
- },
59
- };
60
- }
61
-
62
- constructor() {
63
- super();
64
-
65
- this._boundOnBlur = this._onBlur.bind(this);
66
- this._boundOnFocus = this._onFocus.bind(this);
67
- }
68
-
69
- /** @protected */
70
- ready() {
71
- super.ready();
72
-
73
- if (this.autofocus && !this.disabled) {
74
- requestAnimationFrame(() => {
75
- this.focus();
76
- });
77
- }
78
- }
79
-
80
- /**
81
- * @param {FocusOptions=} options
82
- * @protected
83
- * @override
84
- */
85
- focus(options) {
86
- if (this.focusElement && !this.disabled) {
87
- this.focusElement.focus();
88
-
89
- // Set focus-ring attribute on programmatic focus by default
90
- // unless explicitly disabled by `{ focusVisible: false }`.
91
- if (!(options && options.focusVisible === false)) {
92
- this.setAttribute('focus-ring', '');
93
- }
94
- }
95
- }
96
-
97
- /**
98
- * @protected
99
- * @override
100
- */
101
- blur() {
102
- if (this.focusElement) {
103
- this.focusElement.blur();
13
+ const DelegateFocusMixinImplementation = (superclass) => {
14
+ return class DelegateFocusMixinClass extends FocusMixin(TabindexMixin(superclass)) {
15
+ static get properties() {
16
+ return {
17
+ /**
18
+ * Specify that this control should have input focus when the page loads.
19
+ */
20
+ autofocus: {
21
+ type: Boolean,
22
+ },
23
+
24
+ /**
25
+ * A reference to the focusable element controlled by the mixin.
26
+ * It can be an input, textarea, button or any element with tabindex > -1.
27
+ *
28
+ * Any component implementing this mixin is expected to provide it
29
+ * by using `this._setFocusElement(input)` Polymer API.
30
+ *
31
+ * Toggling `tabindex` attribute on the host element propagates its value to `focusElement`.
32
+ *
33
+ * @protected
34
+ * @type {!HTMLElement}
35
+ */
36
+ focusElement: {
37
+ type: Object,
38
+ readOnly: true,
39
+ observer: '_focusElementChanged',
40
+ sync: true,
41
+ },
42
+
43
+ /**
44
+ * Override the property from `TabIndexMixin`
45
+ * to ensure the `tabindex` attribute of the focus element
46
+ * will be restored to `0` after re-enabling the element.
47
+ *
48
+ * @protected
49
+ * @override
50
+ */
51
+ _lastTabIndex: {
52
+ value: 0,
53
+ },
54
+ };
55
+ }
56
+
57
+ constructor() {
58
+ super();
59
+
60
+ this._boundOnBlur = this._onBlur.bind(this);
61
+ this._boundOnFocus = this._onFocus.bind(this);
62
+ }
63
+
64
+ /** @protected */
65
+ ready() {
66
+ super.ready();
67
+
68
+ if (this.autofocus && !this.disabled) {
69
+ requestAnimationFrame(() => {
70
+ this.focus();
71
+ });
72
+ }
73
+ }
74
+
75
+ /**
76
+ * @param {FocusOptions=} options
77
+ * @protected
78
+ * @override
79
+ */
80
+ focus(options) {
81
+ if (this.focusElement && !this.disabled) {
82
+ this.focusElement.focus();
83
+
84
+ // Set focus-ring attribute on programmatic focus by default
85
+ // unless explicitly disabled by `{ focusVisible: false }`.
86
+ if (options?.focusVisible !== false) {
87
+ this.setAttribute('focus-ring', '');
104
88
  }
105
89
  }
106
-
107
- /**
108
- * @protected
109
- * @override
110
- */
111
- click() {
112
- if (this.focusElement && !this.disabled) {
113
- this.focusElement.click();
90
+ }
91
+
92
+ /**
93
+ * @protected
94
+ * @override
95
+ */
96
+ blur() {
97
+ if (this.focusElement) {
98
+ this.focusElement.blur();
99
+ }
100
+ }
101
+
102
+ /**
103
+ * @protected
104
+ * @override
105
+ */
106
+ click() {
107
+ if (this.focusElement && !this.disabled) {
108
+ this.focusElement.click();
109
+ }
110
+ }
111
+
112
+ /** @protected */
113
+ _focusElementChanged(element, oldElement) {
114
+ if (element) {
115
+ element.disabled = this.disabled;
116
+ this._addFocusListeners(element);
117
+ this.__forwardTabIndex(this.tabindex);
118
+ } else if (oldElement) {
119
+ this._removeFocusListeners(oldElement);
120
+ }
121
+ }
122
+
123
+ /**
124
+ * @param {HTMLElement} element
125
+ * @protected
126
+ */
127
+ _addFocusListeners(element) {
128
+ element.addEventListener('blur', this._boundOnBlur);
129
+ element.addEventListener('focus', this._boundOnFocus);
130
+ }
131
+
132
+ /**
133
+ * @param {HTMLElement} element
134
+ * @protected
135
+ */
136
+ _removeFocusListeners(element) {
137
+ element.removeEventListener('blur', this._boundOnBlur);
138
+ element.removeEventListener('focus', this._boundOnFocus);
139
+ }
140
+
141
+ /**
142
+ * Focus event does not bubble, so we dispatch it manually
143
+ * on the host element to support adding focus listeners
144
+ * when the focusable element is placed in light DOM.
145
+ * @param {FocusEvent} event
146
+ * @protected
147
+ */
148
+ _onFocus(event) {
149
+ event.stopPropagation();
150
+ /** @internal to not document it in CEM */
151
+ this.dispatchEvent(new Event('focus'));
152
+ }
153
+
154
+ /**
155
+ * Blur event does not bubble, so we dispatch it manually
156
+ * on the host element to support adding blur listeners
157
+ * when the focusable element is placed in light DOM.
158
+ * @param {FocusEvent} event
159
+ * @protected
160
+ */
161
+ _onBlur(event) {
162
+ event.stopPropagation();
163
+ /** @internal to not document it in CEM */
164
+ this.dispatchEvent(new Event('blur'));
165
+ }
166
+
167
+ /**
168
+ * @param {FocusEvent} event
169
+ * @return {boolean}
170
+ * @protected
171
+ * @override
172
+ */
173
+ _shouldSetFocus(event) {
174
+ return event.target === this.focusElement;
175
+ }
176
+
177
+ /**
178
+ * @param {FocusEvent} event
179
+ * @return {boolean}
180
+ * @protected
181
+ * @override
182
+ */
183
+ _shouldRemoveFocus(event) {
184
+ return event.target === this.focusElement;
185
+ }
186
+
187
+ /**
188
+ * @param {boolean} disabled
189
+ * @param {boolean} oldDisabled
190
+ * @protected
191
+ * @override
192
+ */
193
+ _disabledChanged(disabled, oldDisabled) {
194
+ super._disabledChanged(disabled, oldDisabled);
195
+
196
+ if (this.focusElement) {
197
+ this.focusElement.disabled = disabled;
198
+ }
199
+
200
+ if (disabled) {
201
+ this.blur();
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Override an observer from `TabindexMixin`.
207
+ * Do not call super to remove tabindex attribute
208
+ * from the host after it has been forwarded.
209
+ * @param {string} tabindex
210
+ * @protected
211
+ * @override
212
+ */
213
+ _tabindexChanged(tabindex) {
214
+ this.__forwardTabIndex(tabindex);
215
+ }
216
+
217
+ /** @private */
218
+ __forwardTabIndex(tabindex) {
219
+ if (tabindex !== undefined && this.focusElement) {
220
+ this.focusElement.tabIndex = tabindex;
221
+
222
+ // Preserve tabindex="-1" on the host element
223
+ if (tabindex !== -1) {
224
+ this.tabindex = undefined;
114
225
  }
115
226
  }
116
227
 
117
- /** @protected */
118
- _focusElementChanged(element, oldElement) {
119
- if (element) {
120
- element.disabled = this.disabled;
121
- this._addFocusListeners(element);
122
- this.__forwardTabIndex(this.tabindex);
123
- } else if (oldElement) {
124
- this._removeFocusListeners(oldElement);
228
+ if (this.disabled && tabindex) {
229
+ // If tabindex attribute was changed while component was disabled
230
+ if (tabindex !== -1) {
231
+ this._lastTabIndex = tabindex;
125
232
  }
233
+ this.tabindex = undefined;
126
234
  }
127
235
 
128
- /**
129
- * @param {HTMLElement} element
130
- * @protected
131
- */
132
- _addFocusListeners(element) {
133
- element.addEventListener('blur', this._boundOnBlur);
134
- element.addEventListener('focus', this._boundOnFocus);
135
- }
136
-
137
- /**
138
- * @param {HTMLElement} element
139
- * @protected
140
- */
141
- _removeFocusListeners(element) {
142
- element.removeEventListener('blur', this._boundOnBlur);
143
- element.removeEventListener('focus', this._boundOnFocus);
144
- }
145
-
146
- /**
147
- * Focus event does not bubble, so we dispatch it manually
148
- * on the host element to support adding focus listeners
149
- * when the focusable element is placed in light DOM.
150
- * @param {FocusEvent} event
151
- * @protected
152
- */
153
- _onFocus(event) {
154
- event.stopPropagation();
155
- this.dispatchEvent(new Event('focus'));
156
- }
157
-
158
- /**
159
- * Blur event does not bubble, so we dispatch it manually
160
- * on the host element to support adding blur listeners
161
- * when the focusable element is placed in light DOM.
162
- * @param {FocusEvent} event
163
- * @protected
164
- */
165
- _onBlur(event) {
166
- event.stopPropagation();
167
- this.dispatchEvent(new Event('blur'));
236
+ // Lit does not remove attribute when setting property to undefined
237
+ if (tabindex === undefined && this.hasAttribute('tabindex')) {
238
+ this.removeAttribute('tabindex');
168
239
  }
240
+ }
241
+ };
242
+ };
169
243
 
170
- /**
171
- * @param {FocusEvent} event
172
- * @return {boolean}
173
- * @protected
174
- * @override
175
- */
176
- _shouldSetFocus(event) {
177
- return event.target === this.focusElement;
178
- }
179
-
180
- /**
181
- * @param {FocusEvent} event
182
- * @return {boolean}
183
- * @protected
184
- * @override
185
- */
186
- _shouldRemoveFocus(event) {
187
- return event.target === this.focusElement;
188
- }
189
-
190
- /**
191
- * @param {boolean} disabled
192
- * @param {boolean} oldDisabled
193
- * @protected
194
- * @override
195
- */
196
- _disabledChanged(disabled, oldDisabled) {
197
- super._disabledChanged(disabled, oldDisabled);
198
-
199
- if (this.focusElement) {
200
- this.focusElement.disabled = disabled;
201
- }
202
-
203
- if (disabled) {
204
- this.blur();
205
- }
206
- }
207
-
208
- /**
209
- * Override an observer from `TabindexMixin`.
210
- * Do not call super to remove tabindex attribute
211
- * from the host after it has been forwarded.
212
- * @param {string} tabindex
213
- * @protected
214
- * @override
215
- */
216
- _tabindexChanged(tabindex) {
217
- this.__forwardTabIndex(tabindex);
218
- }
219
-
220
- /** @private */
221
- __forwardTabIndex(tabindex) {
222
- if (tabindex !== undefined && this.focusElement) {
223
- this.focusElement.tabIndex = tabindex;
224
-
225
- // Preserve tabindex="-1" on the host element
226
- if (tabindex !== -1) {
227
- this.tabindex = undefined;
228
- }
229
- }
230
-
231
- if (this.disabled && tabindex) {
232
- // If tabindex attribute was changed while component was disabled
233
- if (tabindex !== -1) {
234
- this._lastTabIndex = tabindex;
235
- }
236
- this.tabindex = undefined;
237
- }
238
-
239
- // Lit does not remove attribute when setting property to undefined
240
- if (tabindex === undefined && this.hasAttribute('tabindex')) {
241
- this.removeAttribute('tabindex');
242
- }
243
- }
244
- },
245
- );
244
+ export const DelegateFocusMixin = dedupeMixin(DelegateFocusMixinImplementation);
@@ -7,57 +7,56 @@ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
 
8
8
  /**
9
9
  * A mixin to provide disabled property for field components.
10
- *
11
- * @polymerMixin
12
10
  */
13
- export const DisabledMixin = dedupeMixin(
14
- (superclass) =>
15
- class DisabledMixinClass extends superclass {
16
- static get properties() {
17
- return {
18
- /**
19
- * If true, the user cannot interact with this element.
20
- */
21
- disabled: {
22
- type: Boolean,
23
- value: false,
24
- observer: '_disabledChanged',
25
- reflectToAttribute: true,
26
- sync: true,
27
- },
28
- };
29
- }
11
+ const DisabledMixinImplementation = (superclass) => {
12
+ return class DisabledMixinClass extends superclass {
13
+ static get properties() {
14
+ return {
15
+ /**
16
+ * If true, the user cannot interact with this element.
17
+ */
18
+ disabled: {
19
+ type: Boolean,
20
+ value: false,
21
+ observer: '_disabledChanged',
22
+ reflectToAttribute: true,
23
+ sync: true,
24
+ },
25
+ };
26
+ }
30
27
 
31
- /**
32
- * @param {boolean} disabled
33
- * @protected
34
- */
35
- _disabledChanged(disabled) {
36
- this._setAriaDisabled(disabled);
37
- }
28
+ /**
29
+ * @param {boolean} disabled
30
+ * @protected
31
+ */
32
+ _disabledChanged(disabled) {
33
+ this._setAriaDisabled(disabled);
34
+ }
38
35
 
39
- /**
40
- * @param {boolean} disabled
41
- * @protected
42
- */
43
- _setAriaDisabled(disabled) {
44
- if (disabled) {
45
- this.setAttribute('aria-disabled', 'true');
46
- } else {
47
- this.removeAttribute('aria-disabled');
48
- }
36
+ /**
37
+ * @param {boolean} disabled
38
+ * @protected
39
+ */
40
+ _setAriaDisabled(disabled) {
41
+ if (disabled) {
42
+ this.setAttribute('aria-disabled', 'true');
43
+ } else {
44
+ this.removeAttribute('aria-disabled');
49
45
  }
46
+ }
50
47
 
51
- /**
52
- * Overrides the default element `click` method in order to prevent
53
- * firing the `click` event when the element is disabled.
54
- * @protected
55
- * @override
56
- */
57
- click() {
58
- if (!this.disabled) {
59
- super.click();
60
- }
48
+ /**
49
+ * Overrides the default element `click` method in order to prevent
50
+ * firing the `click` event when the element is disabled.
51
+ * @protected
52
+ * @override
53
+ */
54
+ click() {
55
+ if (!this.disabled) {
56
+ super.click();
61
57
  }
62
- },
63
- );
58
+ }
59
+ };
60
+ };
61
+
62
+ export const DisabledMixin = dedupeMixin(DisabledMixinImplementation);