@vaadin/component-base 24.0.0 → 24.1.0-alpha2

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.
package/index.d.ts CHANGED
@@ -1,11 +1,6 @@
1
- export { ActiveMixin } from './src/active-mixin.js';
2
1
  export { ControllerMixin } from './src/controller-mixin.js';
2
+ export { DelegateStateMixin } from './src/delegate-state-mixin.js';
3
3
  export { DirMixin } from './src/dir-mixin.js';
4
- export { DisabledMixin } from './src/disabled-mixin.js';
5
4
  export { ElementMixin } from './src/element-mixin.js';
6
- export { FocusMixin } from './src/focus-mixin.js';
7
- export { FocusTrapController } from './src/focus-trap-controller.js';
8
- export { KeyboardMixin } from './src/keyboard-mixin.js';
9
5
  export { ResizeMixin } from './src/resize-mixin.js';
10
6
  export { SlotController } from './src/slot-controller.js';
11
- export { TabindexMixin } from './src/tabindex-mixin.js';
package/index.js CHANGED
@@ -1,10 +1,6 @@
1
- export { ActiveMixin } from './src/active-mixin.js';
2
1
  export { ControllerMixin } from './src/controller-mixin.js';
2
+ export { DelegateStateMixin } from './src/delegate-state-mixin.js';
3
3
  export { DirMixin } from './src/dir-mixin.js';
4
- export { DisabledMixin } from './src/disabled-mixin.js';
5
4
  export { ElementMixin } from './src/element-mixin.js';
6
- export { FocusMixin } from './src/focus-mixin.js';
7
- export { FocusTrapController } from './src/focus-trap-controller.js';
8
- export { KeyboardMixin } from './src/keyboard-mixin.js';
5
+ export { ResizeMixin } from './src/resize-mixin.js';
9
6
  export { SlotController } from './src/slot-controller.js';
10
- export { TabindexMixin } from './src/tabindex-mixin.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/component-base",
3
- "version": "24.0.0",
3
+ "version": "24.1.0-alpha2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -42,5 +42,5 @@
42
42
  "@vaadin/testing-helpers": "^0.4.0",
43
43
  "sinon": "^13.0.2"
44
44
  },
45
- "gitHead": "b0cf651bb624d74b78a42b3e3ea889b2e401daec"
45
+ "gitHead": "9e3ee2557109030f2aba59e17a84e4e121d699c0"
46
46
  }
@@ -45,7 +45,7 @@ const registered = new Set();
45
45
  export const ElementMixin = (superClass) =>
46
46
  class VaadinElementMixin extends DirMixin(superClass) {
47
47
  static get version() {
48
- return '24.0.0';
48
+ return '24.1.0-alpha2';
49
49
  }
50
50
 
51
51
  /** @protected */
@@ -249,42 +249,28 @@ export class IronListAdapter {
249
249
  this._debouncers._increasePoolIfNeeded.cancel();
250
250
  }
251
251
 
252
- // Prevent element update while the scroll position is being restored
253
- this.__preventElementUpdates = true;
254
-
255
- // Record the scroll position before changing the size
256
- let fvi; // First visible index
257
- let fviOffsetBefore; // Scroll offset of the first visible index
258
- if (size > 0) {
259
- fvi = this.adjustedFirstVisibleIndex;
260
- fviOffsetBefore = this.__getIndexScrollOffset(fvi);
261
- }
262
-
263
252
  // Change the size
264
253
  this.__size = size;
265
254
 
266
- this._itemsChanged({
267
- path: 'items',
268
- });
269
- flush();
270
-
271
- // Try to restore the scroll position if the new size is larger than 0
272
- if (size > 0) {
273
- fvi = Math.min(fvi, size - 1);
274
- this.scrollToIndex(fvi);
275
-
276
- const fviOffsetAfter = this.__getIndexScrollOffset(fvi);
277
- if (fviOffsetBefore !== undefined && fviOffsetAfter !== undefined) {
278
- this._scrollTop += fviOffsetBefore - fviOffsetAfter;
279
- }
255
+ if (!this._physicalItems) {
256
+ // Not initialized yet
257
+ this._itemsChanged({
258
+ path: 'items',
259
+ });
260
+ this.__preventElementUpdates = true;
261
+ flush();
262
+ this.__preventElementUpdates = false;
263
+ } else {
264
+ // Already initialized, just update _virtualCount
265
+ this._virtualCount = this.items.length;
280
266
  }
281
267
 
282
268
  if (!this.elementsContainer.children.length) {
283
269
  requestAnimationFrame(() => this._resizeHandler());
284
270
  }
285
271
 
286
- this.__preventElementUpdates = false;
287
- // Schedule and flush a resize handler
272
+ // Schedule and flush a resize handler. This will cause a
273
+ // re-render for the elements.
288
274
  this._resizeHandler();
289
275
  flush();
290
276
  }
@@ -1,10 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2022 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
-
7
- /**
8
- * Cause a text string to be announced by screen readers.
9
- */
10
- export function announce(text: string, options?: { mode?: 'alert' | 'assertive' | 'polite'; timeout?: number }): void;
@@ -1,47 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2022 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { animationFrame } from './async.js';
7
- import { Debouncer } from './debounce.js';
8
-
9
- const region = document.createElement('div');
10
-
11
- region.style.position = 'fixed';
12
- region.style.clip = 'rect(0px, 0px, 0px, 0px)';
13
- region.setAttribute('aria-live', 'polite');
14
-
15
- document.body.appendChild(region);
16
-
17
- let alertDebouncer;
18
- /**
19
- * Cause a text string to be announced by screen readers.
20
- *
21
- * @param {string} text The text that should be announced by the screen reader.
22
- * @param {{mode?: string, timeout?: number}} options Additional options.
23
- */
24
- export function announce(text, options = {}) {
25
- const mode = options.mode || 'polite';
26
- const timeout = options.timeout === undefined ? 150 : options.timeout;
27
-
28
- if (mode === 'alert') {
29
- region.removeAttribute('aria-live');
30
- region.removeAttribute('role');
31
- alertDebouncer = Debouncer.debounce(alertDebouncer, animationFrame, () => {
32
- region.setAttribute('role', 'alert');
33
- });
34
- } else {
35
- if (alertDebouncer) {
36
- alertDebouncer.cancel();
37
- }
38
- region.removeAttribute('role');
39
- region.setAttribute('aria-live', mode);
40
- }
41
-
42
- region.textContent = '';
43
-
44
- setTimeout(() => {
45
- region.textContent = text;
46
- }, timeout);
47
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { Constructor } from '@open-wc/dedupe-mixin';
7
- import type { DisabledMixinClass } from './disabled-mixin.js';
8
- import type { KeyboardMixinClass } from './keyboard-mixin.js';
9
-
10
- /**
11
- * A mixin to toggle the `active` attribute.
12
- *
13
- * The attribute is set whenever the user activates the element by a pointer
14
- * or presses an activation key on the element from the keyboard.
15
- *
16
- * The attribute is removed as soon as the element is deactivated
17
- * by the pointer or by releasing the activation key.
18
- */
19
- export declare function ActiveMixin<T extends Constructor<HTMLElement>>(
20
- base: T,
21
- ): Constructor<ActiveMixinClass> & Constructor<DisabledMixinClass> & Constructor<KeyboardMixinClass> & T;
22
-
23
- export declare class ActiveMixinClass {
24
- /**
25
- * An array of activation keys.
26
- *
27
- * See possible values here:
28
- * https://developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key/Key_Values
29
- */
30
- protected readonly _activeKeys: string[];
31
-
32
- /**
33
- * Override to define if the component needs to be activated.
34
- */
35
- protected _shouldSetFocus(event: KeyboardEvent | MouseEvent): boolean;
36
-
37
- /**
38
- * Toggles the `active` attribute on the element.
39
- */
40
- protected _setActive(active: boolean): void;
41
- }
@@ -1,106 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { DisabledMixin } from './disabled-mixin.js';
7
- import { addListener } from './gestures.js';
8
- import { KeyboardMixin } from './keyboard-mixin.js';
9
-
10
- /**
11
- * A mixin to toggle the `active` attribute.
12
- *
13
- * The attribute is set whenever the user activates the element by a pointer
14
- * or presses an activation key on the element from the keyboard.
15
- *
16
- * The attribute is removed as soon as the element is deactivated
17
- * by the pointer or by releasing the activation key.
18
- *
19
- * @polymerMixin
20
- */
21
- export const ActiveMixin = (superclass) =>
22
- class ActiveMixinClass extends DisabledMixin(KeyboardMixin(superclass)) {
23
- /**
24
- * An array of activation keys.
25
- *
26
- * See possible values here:
27
- * https://developer.mozilla.org/ru/docs/Web/API/KeyboardEvent/key/Key_Values
28
- *
29
- * @protected
30
- * @return {!Array<!string>}
31
- */
32
- get _activeKeys() {
33
- return [' '];
34
- }
35
-
36
- /** @protected */
37
- ready() {
38
- super.ready();
39
-
40
- addListener(this, 'down', (event) => {
41
- if (this._shouldSetActive(event)) {
42
- this._setActive(true);
43
- }
44
- });
45
-
46
- addListener(this, 'up', () => {
47
- this._setActive(false);
48
- });
49
- }
50
-
51
- /** @protected */
52
- disconnectedCallback() {
53
- super.disconnectedCallback();
54
-
55
- // When the element is disconnecting from the DOM at the moment being active,
56
- // the `active` attribute needs to be manually removed from the element.
57
- // Otherwise, it will preserve on the element until the element is activated once again.
58
- // The case reproduces for `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
59
- this._setActive(false);
60
- }
61
-
62
- /**
63
- * @param {KeyboardEvent | MouseEvent} _event
64
- * @protected
65
- */
66
- _shouldSetActive(_event) {
67
- return !this.disabled;
68
- }
69
-
70
- /**
71
- * Sets the `active` attribute on the element if an activation key is pressed.
72
- *
73
- * @param {KeyboardEvent} event
74
- * @protected
75
- * @override
76
- */
77
- _onKeyDown(event) {
78
- super._onKeyDown(event);
79
-
80
- if (this._shouldSetActive(event) && this._activeKeys.includes(event.key)) {
81
- this._setActive(true);
82
-
83
- // Element can become hidden before the `keyup` event, e.g. on button click.
84
- // Use document listener to ensure `active` attribute is removed correctly.
85
- document.addEventListener(
86
- 'keyup',
87
- (e) => {
88
- if (this._activeKeys.includes(e.key)) {
89
- this._setActive(false);
90
- }
91
- },
92
- { once: true },
93
- );
94
- }
95
- }
96
-
97
- /**
98
- * Toggles the `active` attribute on the element.
99
- *
100
- * @param {boolean} active
101
- * @protected
102
- */
103
- _setActive(active) {
104
- this.toggleAttribute('active', active);
105
- }
106
- };
@@ -1,48 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { Constructor } from '@open-wc/dedupe-mixin';
7
- import type { DisabledMixinClass } from './disabled-mixin.js';
8
- import type { FocusMixinClass } from './focus-mixin.js';
9
- import type { TabindexMixinClass } from './tabindex-mixin.js';
10
-
11
- /**
12
- * A mixin to forward focus to an element in the light DOM.
13
- */
14
- export declare function DelegateFocusMixin<T extends Constructor<HTMLElement>>(
15
- base: T,
16
- ): Constructor<DelegateFocusMixinClass> &
17
- Constructor<DisabledMixinClass> &
18
- Constructor<FocusMixinClass> &
19
- Constructor<TabindexMixinClass> &
20
- T;
21
-
22
- export declare class DelegateFocusMixinClass {
23
- /**
24
- * Specify that this control should have input focus when the page loads.
25
- */
26
- autofocus: boolean;
27
-
28
- /**
29
- * A reference to the focusable element controlled by the mixin.
30
- * It can be an input, textarea, button or any element with tabindex > -1.
31
- *
32
- * Any component implementing this mixin is expected to provide it
33
- * by using `this._setFocusElement(input)` Polymer API.
34
- */
35
- readonly focusElement: HTMLElement | null | undefined;
36
-
37
- protected _addFocusListeners(element: HTMLElement): void;
38
-
39
- protected _removeFocusListeners(element: HTMLElement): void;
40
-
41
- protected _focusElementChanged(element: HTMLElement, oldElement: HTMLElement): void;
42
-
43
- protected _onBlur(event: FocusEvent): void;
44
-
45
- protected _onFocus(event: FocusEvent): void;
46
-
47
- protected _setFocusElement(element: HTMLElement): void;
48
- }
@@ -1,228 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
7
- import { FocusMixin } from './focus-mixin.js';
8
- import { TabindexMixin } from './tabindex-mixin.js';
9
-
10
- /**
11
- * A mixin to forward focus to an element in the light DOM.
12
- *
13
- * @polymerMixin
14
- * @mixes FocusMixin
15
- * @mixes TabindexMixin
16
- */
17
- export const DelegateFocusMixin = dedupingMixin(
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
- },
46
-
47
- /**
48
- * Override the property from `TabIndexMixin`
49
- * to ensure the `tabindex` attribute of the focus element
50
- * will be restored to `0` after re-enabling the element.
51
- *
52
- * @protected
53
- * @override
54
- */
55
- _lastTabIndex: {
56
- value: 0,
57
- },
58
- };
59
- }
60
-
61
- constructor() {
62
- super();
63
-
64
- this._boundOnBlur = this._onBlur.bind(this);
65
- this._boundOnFocus = this._onFocus.bind(this);
66
- }
67
-
68
- /** @protected */
69
- ready() {
70
- super.ready();
71
-
72
- if (this.autofocus && !this.disabled) {
73
- requestAnimationFrame(() => {
74
- this.focus();
75
- this.setAttribute('focus-ring', '');
76
- });
77
- }
78
- }
79
-
80
- /**
81
- * @protected
82
- * @override
83
- */
84
- focus() {
85
- if (!this.focusElement || this.disabled) {
86
- return;
87
- }
88
-
89
- this.focusElement.focus();
90
- this._setFocused(true);
91
- }
92
-
93
- /**
94
- * @protected
95
- * @override
96
- */
97
- blur() {
98
- if (!this.focusElement) {
99
- return;
100
- }
101
- this.focusElement.blur();
102
- this._setFocused(false);
103
- }
104
-
105
- /**
106
- * @protected
107
- * @override
108
- */
109
- click() {
110
- if (this.focusElement && !this.disabled) {
111
- this.focusElement.click();
112
- }
113
- }
114
-
115
- /** @protected */
116
- _focusElementChanged(element, oldElement) {
117
- if (element) {
118
- element.disabled = this.disabled;
119
- this._addFocusListeners(element);
120
- this.__forwardTabIndex(this.tabindex);
121
- } else if (oldElement) {
122
- this._removeFocusListeners(oldElement);
123
- }
124
- }
125
-
126
- /**
127
- * @param {HTMLElement} element
128
- * @protected
129
- */
130
- _addFocusListeners(element) {
131
- element.addEventListener('blur', this._boundOnBlur);
132
- element.addEventListener('focus', this._boundOnFocus);
133
- }
134
-
135
- /**
136
- * @param {HTMLElement} element
137
- * @protected
138
- */
139
- _removeFocusListeners(element) {
140
- element.removeEventListener('blur', this._boundOnBlur);
141
- element.removeEventListener('focus', this._boundOnFocus);
142
- }
143
-
144
- /**
145
- * Focus event does not bubble, so we dispatch it manually
146
- * on the host element to support adding focus listeners
147
- * when the focusable element is placed in light DOM.
148
- * @param {FocusEvent} event
149
- * @protected
150
- */
151
- _onFocus(event) {
152
- event.stopPropagation();
153
- this.dispatchEvent(new Event('focus'));
154
- }
155
-
156
- /**
157
- * Blur event does not bubble, so we dispatch it manually
158
- * on the host element to support adding blur listeners
159
- * when the focusable element is placed in light DOM.
160
- * @param {FocusEvent} event
161
- * @protected
162
- */
163
- _onBlur(event) {
164
- event.stopPropagation();
165
- this.dispatchEvent(new Event('blur'));
166
- }
167
-
168
- /**
169
- * @param {Event} event
170
- * @return {boolean}
171
- * @protected
172
- * @override
173
- */
174
- _shouldSetFocus(event) {
175
- return event.target === this.focusElement;
176
- }
177
-
178
- /**
179
- * @param {boolean} disabled
180
- * @param {boolean} oldDisabled
181
- * @protected
182
- * @override
183
- */
184
- _disabledChanged(disabled, oldDisabled) {
185
- super._disabledChanged(disabled, oldDisabled);
186
-
187
- if (this.focusElement) {
188
- this.focusElement.disabled = disabled;
189
- }
190
-
191
- if (disabled) {
192
- this.blur();
193
- }
194
- }
195
-
196
- /**
197
- * Override an observer from `TabindexMixin`.
198
- * Do not call super to remove tabindex attribute
199
- * from the host after it has been forwarded.
200
- * @param {string} tabindex
201
- * @protected
202
- * @override
203
- */
204
- _tabindexChanged(tabindex) {
205
- this.__forwardTabIndex(tabindex);
206
- }
207
-
208
- /** @private */
209
- __forwardTabIndex(tabindex) {
210
- if (tabindex !== undefined && this.focusElement) {
211
- this.focusElement.tabIndex = tabindex;
212
-
213
- // Preserve tabindex="-1" on the host element
214
- if (tabindex !== -1) {
215
- this.tabindex = undefined;
216
- }
217
- }
218
-
219
- if (this.disabled && tabindex) {
220
- // If tabindex attribute was changed while component was disabled
221
- if (tabindex !== -1) {
222
- this._lastTabIndex = tabindex;
223
- }
224
- this.tabindex = undefined;
225
- }
226
- }
227
- },
228
- );
@@ -1,20 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { Constructor } from '@open-wc/dedupe-mixin';
7
-
8
- /**
9
- * A mixin to provide disabled property for field components.
10
- */
11
- export declare function DisabledMixin<T extends Constructor<HTMLElement>>(base: T): Constructor<DisabledMixinClass> & T;
12
-
13
- export declare class DisabledMixinClass {
14
- /**
15
- * If true, the user cannot interact with this element.
16
- */
17
- disabled: boolean;
18
-
19
- protected _disabledChanged(disabled: boolean, oldDisabled: boolean): void;
20
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
7
-
8
- /**
9
- * A mixin to provide disabled property for field components.
10
- *
11
- * @polymerMixin
12
- */
13
- export const DisabledMixin = dedupingMixin(
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
- },
27
- };
28
- }
29
-
30
- /**
31
- * @param {boolean} disabled
32
- * @protected
33
- */
34
- _disabledChanged(disabled) {
35
- this._setAriaDisabled(disabled);
36
- }
37
-
38
- /**
39
- * @param {boolean} disabled
40
- * @protected
41
- */
42
- _setAriaDisabled(disabled) {
43
- if (disabled) {
44
- this.setAttribute('aria-disabled', 'true');
45
- } else {
46
- this.removeAttribute('aria-disabled');
47
- }
48
- }
49
-
50
- /**
51
- * Overrides the default element `click` method in order to prevent
52
- * firing the `click` event when the element is disabled.
53
- * @protected
54
- * @override
55
- */
56
- click() {
57
- if (!this.disabled) {
58
- super.click();
59
- }
60
- }
61
- },
62
- );