@vaadin/component-base 23.2.16 → 23.2.17

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.
Files changed (70) hide show
  1. package/custom_typings/vaadin-usage-statistics.d.ts +2 -2
  2. package/index.d.ts +1 -0
  3. package/index.js +1 -0
  4. package/package.json +3 -3
  5. package/src/a11y-announcer.d.ts +1 -1
  6. package/src/a11y-announcer.js +1 -1
  7. package/src/active-mixin.d.ts +1 -1
  8. package/src/active-mixin.js +1 -1
  9. package/src/async.d.ts +0 -3
  10. package/src/async.js +1 -2
  11. package/src/browser-utils.js +7 -7
  12. package/src/controller-mixin.d.ts +1 -1
  13. package/src/controller-mixin.js +1 -1
  14. package/src/debounce.js +2 -2
  15. package/src/dir-helper.d.ts +42 -0
  16. package/src/dir-helper.js +93 -0
  17. package/src/dir-mixin.d.ts +4 -2
  18. package/src/dir-mixin.js +39 -17
  19. package/src/disabled-mixin.d.ts +1 -1
  20. package/src/disabled-mixin.js +1 -1
  21. package/src/dom-utils.d.ts +1 -6
  22. package/src/dom-utils.js +1 -11
  23. package/src/element-mixin.d.ts +1 -1
  24. package/src/element-mixin.js +5 -11
  25. package/src/focus-mixin.d.ts +1 -1
  26. package/src/focus-mixin.js +2 -2
  27. package/src/focus-trap-controller.d.ts +1 -1
  28. package/src/focus-trap-controller.js +22 -22
  29. package/src/focus-utils.d.ts +1 -1
  30. package/src/focus-utils.js +57 -57
  31. package/src/gestures.d.ts +12 -6
  32. package/src/gestures.js +4 -6
  33. package/src/iron-list-core.js +11 -21
  34. package/src/keyboard-mixin.d.ts +1 -1
  35. package/src/keyboard-mixin.js +1 -1
  36. package/src/media-query-controller.d.ts +1 -1
  37. package/src/media-query-controller.js +1 -1
  38. package/src/overflow-controller.d.ts +1 -1
  39. package/src/overflow-controller.js +3 -3
  40. package/src/polylit-mixin.d.ts +3 -3
  41. package/src/polylit-mixin.js +4 -9
  42. package/src/resize-mixin.d.ts +1 -1
  43. package/src/resize-mixin.js +21 -11
  44. package/src/slot-controller.d.ts +5 -33
  45. package/src/slot-controller.js +40 -103
  46. package/src/slot-mixin.d.ts +18 -0
  47. package/src/slot-mixin.js +60 -0
  48. package/src/tabindex-mixin.d.ts +1 -1
  49. package/src/tabindex-mixin.js +1 -1
  50. package/src/templates.js +1 -1
  51. package/src/unique-id-utils.d.ts +1 -1
  52. package/src/unique-id-utils.js +1 -1
  53. package/src/virtualizer-iron-list-adapter.js +2 -6
  54. package/src/virtualizer.js +18 -18
  55. package/src/delegate-focus-mixin.d.ts +0 -48
  56. package/src/delegate-focus-mixin.js +0 -228
  57. package/src/delegate-state-mixin.d.ts +0 -20
  58. package/src/delegate-state-mixin.js +0 -125
  59. package/src/dir-utils.d.ts +0 -19
  60. package/src/dir-utils.js +0 -36
  61. package/src/keyboard-direction-mixin.d.ts +0 -41
  62. package/src/keyboard-direction-mixin.js +0 -192
  63. package/src/list-mixin.d.ts +0 -57
  64. package/src/list-mixin.js +0 -354
  65. package/src/overlay-class-mixin.d.ts +0 -33
  66. package/src/overlay-class-mixin.js +0 -79
  67. package/src/slot-child-observe-controller.d.ts +0 -28
  68. package/src/slot-child-observe-controller.js +0 -176
  69. package/src/tooltip-controller.d.ts +0 -86
  70. package/src/tooltip-controller.js +0 -130
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
7
- import { isEmptyTextNode } from './dom-utils.js';
8
7
  import { generateUniqueId } from './unique-id-utils.js';
9
8
 
10
9
  /**
@@ -14,97 +13,64 @@ export class SlotController extends EventTarget {
14
13
  /**
15
14
  * Ensure that every instance has unique ID.
16
15
  *
17
- * @param {HTMLElement} host
18
16
  * @param {string} slotName
17
+ * @param {HTMLElement} host
19
18
  * @return {string}
20
19
  * @protected
21
20
  */
22
- static generateId(host, slotName) {
21
+ static generateId(slotName, host) {
23
22
  const prefix = slotName || 'default';
24
23
  return `${prefix}-${host.localName}-${generateUniqueId()}`;
25
24
  }
26
25
 
27
- constructor(host, slotName, tagName, config = {}) {
26
+ constructor(host, slotName, slotFactory, slotInitializer, useUniqueId) {
28
27
  super();
29
28
 
30
- const { initializer, multiple, observe, useUniqueId } = config;
31
-
32
29
  this.host = host;
33
30
  this.slotName = slotName;
34
- this.tagName = tagName;
35
- this.observe = typeof observe === 'boolean' ? observe : true;
36
- this.multiple = typeof multiple === 'boolean' ? multiple : false;
37
- this.slotInitializer = initializer;
38
-
39
- if (multiple) {
40
- this.nodes = [];
41
- }
31
+ this.slotFactory = slotFactory;
32
+ this.slotInitializer = slotInitializer;
42
33
 
43
34
  // Only generate the default ID if requested by the controller.
44
35
  if (useUniqueId) {
45
- this.defaultId = this.constructor.generateId(host, slotName);
36
+ this.defaultId = SlotController.generateId(slotName, host);
46
37
  }
47
38
  }
48
39
 
49
40
  hostConnected() {
50
41
  if (!this.initialized) {
51
- if (this.multiple) {
52
- this.initMultiple();
53
- } else {
54
- this.initSingle();
55
- }
42
+ let node = this.getSlotChild();
56
43
 
57
- if (this.observe) {
58
- this.observeSlot();
44
+ if (!node) {
45
+ node = this.attachDefaultNode();
46
+ } else {
47
+ this.node = node;
48
+ this.initCustomNode(node);
59
49
  }
60
50
 
61
- this.initialized = true;
62
- }
63
- }
64
-
65
- /** @protected */
66
- initSingle() {
67
- let node = this.getSlotChild();
68
-
69
- if (!node) {
70
- node = this.attachDefaultNode();
71
51
  this.initNode(node);
72
- } else {
73
- this.node = node;
74
- this.initAddedNode(node);
75
- }
76
- }
77
52
 
78
- /** @protected */
79
- initMultiple() {
80
- const children = this.getSlotChildren();
81
-
82
- if (children.length === 0) {
83
- const defaultNode = this.attachDefaultNode();
84
- this.nodes = [defaultNode];
85
- this.initNode(defaultNode);
86
- } else {
87
- this.nodes = children;
88
- children.forEach((node) => {
89
- this.initAddedNode(node);
90
- });
53
+ // TODO: Consider making this behavior opt-in to improve performance.
54
+ this.observe();
55
+
56
+ this.initialized = true;
91
57
  }
92
58
  }
93
59
 
94
60
  /**
95
- * Create and attach default node using the provided tag name, if any.
61
+ * Create and attach default node using the slot factory.
96
62
  * @return {Node | undefined}
97
63
  * @protected
98
64
  */
99
65
  attachDefaultNode() {
100
- const { host, slotName, tagName } = this;
66
+ const { host, slotName, slotFactory } = this;
101
67
 
102
68
  // Check if the node was created previously and if so, reuse it.
103
69
  let node = this.defaultNode;
104
70
 
105
- // Tag name is optional, sometimes we don't init default content.
106
- if (!node && tagName) {
107
- node = document.createElement(tagName);
71
+ // Slot factory is optional, some slots don't have default content.
72
+ if (!node && slotFactory) {
73
+ node = slotFactory(host);
108
74
  if (node instanceof Element) {
109
75
  if (slotName !== '') {
110
76
  node.setAttribute('slot', slotName);
@@ -122,12 +88,12 @@ export class SlotController extends EventTarget {
122
88
  }
123
89
 
124
90
  /**
125
- * Return the list of nodes matching the slot managed by the controller.
91
+ * Return a reference to the node managed by the controller.
126
92
  * @return {Node}
127
93
  */
128
- getSlotChildren() {
94
+ getSlotChild() {
129
95
  const { slotName } = this;
130
- return Array.from(this.host.childNodes).filter((node) => {
96
+ return Array.from(this.host.childNodes).find((node) => {
131
97
  // Either an element (any slot) or a text node (only un-named slot).
132
98
  return (
133
99
  (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
@@ -137,16 +103,6 @@ export class SlotController extends EventTarget {
137
103
  }
138
104
 
139
105
  /**
140
- * Return a reference to the node managed by the controller.
141
- * @return {Node}
142
- */
143
- getSlotChild() {
144
- return this.getSlotChildren()[0];
145
- }
146
-
147
- /**
148
- * Run `slotInitializer` for the node managed by the controller.
149
- *
150
106
  * @param {Node} node
151
107
  * @protected
152
108
  */
@@ -155,7 +111,7 @@ export class SlotController extends EventTarget {
155
111
  // Don't try to bind `this` to initializer (normally it's arrow function).
156
112
  // Instead, pass the host as a first argument to access component's state.
157
113
  if (slotInitializer) {
158
- slotInitializer(node, this.host);
114
+ slotInitializer(this.host, node);
159
115
  }
160
116
  }
161
117
 
@@ -175,34 +131,19 @@ export class SlotController extends EventTarget {
175
131
  */
176
132
  teardownNode(_node) {}
177
133
 
178
- /**
179
- * Run both `initCustomNode` and `initNode` for a custom slotted node.
180
- *
181
- * @param {Node} node
182
- * @protected
183
- */
184
- initAddedNode(node) {
185
- if (node !== this.defaultNode) {
186
- this.initCustomNode(node);
187
- this.initNode(node);
188
- }
189
- }
190
-
191
134
  /**
192
135
  * Setup the observer to manage slot content changes.
193
136
  * @protected
194
137
  */
195
- observeSlot() {
138
+ observe() {
196
139
  const { slotName } = this;
197
140
  const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
198
141
  const slot = this.host.shadowRoot.querySelector(selector);
199
142
 
200
143
  this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
201
- const current = this.multiple ? this.nodes : [this.node];
202
-
203
- // Calling `slot.assignedNodes()` includes whitespace text nodes in case of default slot:
204
- // unlike comment nodes, they are not filtered out. So we need to manually ignore them.
205
- const newNodes = info.addedNodes.filter((node) => !isEmptyTextNode(node) && !current.includes(node));
144
+ // TODO: support default slot with multiple nodes (e.g. confirm-dialog)
145
+ const current = this.node;
146
+ const newNode = info.addedNodes.find((node) => node !== current);
206
147
 
207
148
  if (info.removedNodes.length) {
208
149
  info.removedNodes.forEach((node) => {
@@ -210,22 +151,18 @@ export class SlotController extends EventTarget {
210
151
  });
211
152
  }
212
153
 
213
- if (newNodes && newNodes.length > 0) {
154
+ if (newNode) {
214
155
  // Custom node is added, remove the current one.
215
- current.forEach((node) => {
216
- if (node && node.isConnected) {
217
- node.parentNode.removeChild(node);
218
- }
219
- });
156
+ if (current && current.isConnected) {
157
+ this.host.removeChild(current);
158
+ }
159
+
160
+ this.node = newNode;
161
+
162
+ if (newNode !== this.defaultNode) {
163
+ this.initCustomNode(newNode);
220
164
 
221
- if (this.multiple) {
222
- this.nodes = newNodes;
223
- newNodes.forEach((node) => {
224
- this.initAddedNode(node);
225
- });
226
- } else {
227
- this.node = newNodes[0];
228
- this.initAddedNode(this.node);
165
+ this.initNode(newNode);
229
166
  }
230
167
  }
231
168
  });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 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 content for named slots defined by component.
10
+ */
11
+ export declare function SlotMixin<T extends Constructor<HTMLElement>>(base: T): Constructor<SlotMixinClass> & T;
12
+
13
+ export declare class SlotMixinClass {
14
+ /**
15
+ * List of named slots to initialize.
16
+ */
17
+ protected readonly slots: Record<string, () => HTMLElement>;
18
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 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 content for named slots defined by component.
10
+ *
11
+ * @polymerMixin
12
+ */
13
+ export const SlotMixin = dedupingMixin(
14
+ (superclass) =>
15
+ class SlotMixinClass extends superclass {
16
+ /**
17
+ * List of named slots to initialize.
18
+ * @protected
19
+ */
20
+ get slots() {
21
+ return {};
22
+ }
23
+
24
+ /** @protected */
25
+ ready() {
26
+ super.ready();
27
+ this._connectSlotMixin();
28
+ }
29
+
30
+ /** @private */
31
+ _connectSlotMixin() {
32
+ Object.keys(this.slots).forEach((slotName) => {
33
+ // Ignore labels of nested components, if any
34
+ const hasContent = this._getDirectSlotChild(slotName) !== undefined;
35
+
36
+ if (!hasContent) {
37
+ const slotFactory = this.slots[slotName];
38
+ const slotContent = slotFactory();
39
+ if (slotContent instanceof Element) {
40
+ if (slotName !== '') {
41
+ slotContent.setAttribute('slot', slotName);
42
+ }
43
+ this.appendChild(slotContent);
44
+ }
45
+ }
46
+ });
47
+ }
48
+
49
+ /** @protected */
50
+ _getDirectSlotChild(slotName) {
51
+ return Array.from(this.childNodes).find((node) => {
52
+ // Either an element (any slot) or a text node (only un-named slot).
53
+ return (
54
+ (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
55
+ (node.nodeType === Node.TEXT_NODE && node.textContent.trim() && slotName === '')
56
+ );
57
+ });
58
+ }
59
+ },
60
+ );
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { DisabledMixin } from './disabled-mixin.js';
package/src/templates.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
 
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2023 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- /* eslint-disable @typescript-eslint/member-ordering */
7
- // https://github.com/vaadin/eslint-config-vaadin/issues/33
8
6
  import { animationFrame, timeOut } from './async.js';
9
7
  import { isSafari } from './browser-utils.js';
10
8
  import { Debouncer, flush } from './debounce.js';
@@ -482,9 +480,7 @@ export class IronListAdapter {
482
480
  deltaY *= this._scrollPageHeight;
483
481
  }
484
482
 
485
- if (!this._deltaYAcc) {
486
- this._deltaYAcc = 0;
487
- }
483
+ this._deltaYAcc = this._deltaYAcc || 0;
488
484
 
489
485
  if (this._wheelAnimationFrame) {
490
486
  // Accumulate wheel delta while a frame is being processed
@@ -15,24 +15,6 @@ export class Virtualizer {
15
15
  this.__adapter = new IronListAdapter(config);
16
16
  }
17
17
 
18
- /**
19
- * Gets the index of the first visible item in the viewport.
20
- *
21
- * @return {number}
22
- */
23
- get firstVisibleIndex() {
24
- return this.__adapter.adjustedFirstVisibleIndex;
25
- }
26
-
27
- /**
28
- * Gets the index of the last visible item in the viewport.
29
- *
30
- * @return {number}
31
- */
32
- get lastVisibleIndex() {
33
- return this.__adapter.adjustedLastVisibleIndex;
34
- }
35
-
36
18
  /**
37
19
  * The size of the virtualizer
38
20
  * @return {number | undefined} The size of the virtualizer
@@ -80,4 +62,22 @@ export class Virtualizer {
80
62
  flush() {
81
63
  this.__adapter.flush();
82
64
  }
65
+
66
+ /**
67
+ * Gets the index of the first visible item in the viewport.
68
+ *
69
+ * @return {number}
70
+ */
71
+ get firstVisibleIndex() {
72
+ return this.__adapter.adjustedFirstVisibleIndex;
73
+ }
74
+
75
+ /**
76
+ * Gets the index of the last visible item in the viewport.
77
+ *
78
+ * @return {number}
79
+ */
80
+ get lastVisibleIndex() {
81
+ return this.__adapter.adjustedLastVisibleIndex;
82
+ }
83
83
  }
@@ -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
- }