@vaadin/component-base 24.0.0-alpha3 → 24.0.0-alpha4
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/package.json +2 -2
- package/src/dir-mixin.d.ts +2 -0
- package/src/dir-mixin.js +8 -0
- package/src/element-mixin.js +1 -1
- package/src/slot-controller.d.ts +16 -0
- package/src/slot-controller.js +73 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/component-base",
|
|
3
|
-
"version": "24.0.0-
|
|
3
|
+
"version": "24.0.0-alpha4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
43
43
|
"sinon": "^13.0.2"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "66be46e82c4d0a673859fbc9bdb1581dd89f360c"
|
|
46
46
|
}
|
package/src/dir-mixin.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
|
11
11
|
export declare function DirMixin<T extends Constructor<HTMLElement>>(base: T): Constructor<DirMixinClass> & T;
|
|
12
12
|
|
|
13
13
|
export declare class DirMixinClass {
|
|
14
|
+
protected readonly __isRTL: boolean;
|
|
15
|
+
|
|
14
16
|
protected __getNormalizedScrollLeft(element: Element | null): number;
|
|
15
17
|
|
|
16
18
|
protected __setNormalizedScrollLeft(element: Element | null, scrollLeft: number): void;
|
package/src/dir-mixin.js
CHANGED
|
@@ -112,6 +112,14 @@ export const DirMixin = (superClass) =>
|
|
|
112
112
|
this.__unsubscribe();
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* @return {boolean}
|
|
117
|
+
* @protected
|
|
118
|
+
*/
|
|
119
|
+
get __isRTL() {
|
|
120
|
+
return this.getAttribute('dir') === 'rtl';
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
/** @protected */
|
|
116
124
|
_valueToNodeAttribute(node, value, attribute) {
|
|
117
125
|
// Override default Polymer attribute reflection to match native behavior of HTMLElement.dir property
|
package/src/element-mixin.js
CHANGED
package/src/slot-controller.d.ts
CHANGED
|
@@ -16,8 +16,16 @@ export class SlotController extends EventTarget implements ReactiveController {
|
|
|
16
16
|
*/
|
|
17
17
|
node: HTMLElement;
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The list of slotted nodes managed by the controller.
|
|
21
|
+
* Only used when `multiple` property is set to `true`.
|
|
22
|
+
*/
|
|
23
|
+
nodes: HTMLElement[];
|
|
24
|
+
|
|
19
25
|
protected initialized: boolean;
|
|
20
26
|
|
|
27
|
+
protected multiple: boolean;
|
|
28
|
+
|
|
21
29
|
protected defaultNode: Node;
|
|
22
30
|
|
|
23
31
|
protected defaultId: string;
|
|
@@ -27,6 +35,7 @@ export class SlotController extends EventTarget implements ReactiveController {
|
|
|
27
35
|
slotName: string,
|
|
28
36
|
tagName?: string,
|
|
29
37
|
config?: {
|
|
38
|
+
multiple?: boolean;
|
|
30
39
|
observe?: boolean;
|
|
31
40
|
useUniqueId?: boolean;
|
|
32
41
|
initializer?(host: HTMLElement, node: HTMLElement): void;
|
|
@@ -35,6 +44,11 @@ export class SlotController extends EventTarget implements ReactiveController {
|
|
|
35
44
|
|
|
36
45
|
hostConnected(): void;
|
|
37
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Return the list of nodes matching the slot managed by the controller.
|
|
49
|
+
*/
|
|
50
|
+
getSlotChildren(): Node[];
|
|
51
|
+
|
|
38
52
|
/**
|
|
39
53
|
* Return a reference to the node managed by the controller.
|
|
40
54
|
*/
|
|
@@ -42,6 +56,8 @@ export class SlotController extends EventTarget implements ReactiveController {
|
|
|
42
56
|
|
|
43
57
|
protected attachDefaultNode(): Node | undefined;
|
|
44
58
|
|
|
59
|
+
protected initAddedNode(node: Node): void;
|
|
60
|
+
|
|
45
61
|
protected initNode(node: Node): void;
|
|
46
62
|
|
|
47
63
|
/**
|
package/src/slot-controller.js
CHANGED
|
@@ -26,14 +26,19 @@ export class SlotController extends EventTarget {
|
|
|
26
26
|
constructor(host, slotName, tagName, config = {}) {
|
|
27
27
|
super();
|
|
28
28
|
|
|
29
|
-
const { initializer, observe, useUniqueId } = config;
|
|
29
|
+
const { initializer, multiple, observe, useUniqueId } = config;
|
|
30
30
|
|
|
31
31
|
this.host = host;
|
|
32
32
|
this.slotName = slotName;
|
|
33
33
|
this.tagName = tagName;
|
|
34
34
|
this.observe = typeof observe === 'boolean' ? observe : true;
|
|
35
|
+
this.multiple = typeof multiple === 'boolean' ? multiple : false;
|
|
35
36
|
this.slotInitializer = initializer;
|
|
36
37
|
|
|
38
|
+
if (multiple) {
|
|
39
|
+
this.nodes = [];
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
// Only generate the default ID if requested by the controller.
|
|
38
43
|
if (useUniqueId) {
|
|
39
44
|
this.defaultId = SlotController.generateId(slotName, host);
|
|
@@ -42,17 +47,12 @@ export class SlotController extends EventTarget {
|
|
|
42
47
|
|
|
43
48
|
hostConnected() {
|
|
44
49
|
if (!this.initialized) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (!node) {
|
|
48
|
-
node = this.attachDefaultNode();
|
|
50
|
+
if (this.multiple) {
|
|
51
|
+
this.initMultiple();
|
|
49
52
|
} else {
|
|
50
|
-
this.
|
|
51
|
-
this.initCustomNode(node);
|
|
53
|
+
this.initSingle();
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
this.initNode(node);
|
|
55
|
-
|
|
56
56
|
if (this.observe) {
|
|
57
57
|
this.observeSlot();
|
|
58
58
|
}
|
|
@@ -61,6 +61,35 @@ export class SlotController extends EventTarget {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/** @protected */
|
|
65
|
+
initSingle() {
|
|
66
|
+
let node = this.getSlotChild();
|
|
67
|
+
|
|
68
|
+
if (!node) {
|
|
69
|
+
node = this.attachDefaultNode();
|
|
70
|
+
this.initNode(node);
|
|
71
|
+
} else {
|
|
72
|
+
this.node = node;
|
|
73
|
+
this.initAddedNode(node);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @protected */
|
|
78
|
+
initMultiple() {
|
|
79
|
+
const children = this.getSlotChildren();
|
|
80
|
+
|
|
81
|
+
if (children.length === 0) {
|
|
82
|
+
const defaultNode = this.attachDefaultNode();
|
|
83
|
+
this.nodes = [defaultNode];
|
|
84
|
+
this.initNode(defaultNode);
|
|
85
|
+
} else {
|
|
86
|
+
this.nodes = children;
|
|
87
|
+
children.forEach((node) => {
|
|
88
|
+
this.initAddedNode(node);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
64
93
|
/**
|
|
65
94
|
* Create and attach default node using the slot factory.
|
|
66
95
|
* @return {Node | undefined}
|
|
@@ -92,12 +121,12 @@ export class SlotController extends EventTarget {
|
|
|
92
121
|
}
|
|
93
122
|
|
|
94
123
|
/**
|
|
95
|
-
* Return
|
|
124
|
+
* Return the list of nodes matching the slot managed by the controller.
|
|
96
125
|
* @return {Node}
|
|
97
126
|
*/
|
|
98
|
-
|
|
127
|
+
getSlotChildren() {
|
|
99
128
|
const { slotName } = this;
|
|
100
|
-
return Array.from(this.host.childNodes).
|
|
129
|
+
return Array.from(this.host.childNodes).filter((node) => {
|
|
101
130
|
// Either an element (any slot) or a text node (only un-named slot).
|
|
102
131
|
return (
|
|
103
132
|
(node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) ||
|
|
@@ -106,6 +135,14 @@ export class SlotController extends EventTarget {
|
|
|
106
135
|
});
|
|
107
136
|
}
|
|
108
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Return a reference to the node managed by the controller.
|
|
140
|
+
* @return {Node}
|
|
141
|
+
*/
|
|
142
|
+
getSlotChild() {
|
|
143
|
+
return this.getSlotChildren()[0];
|
|
144
|
+
}
|
|
145
|
+
|
|
109
146
|
/**
|
|
110
147
|
* @param {Node} node
|
|
111
148
|
* @protected
|
|
@@ -135,6 +172,14 @@ export class SlotController extends EventTarget {
|
|
|
135
172
|
*/
|
|
136
173
|
teardownNode(_node) {}
|
|
137
174
|
|
|
175
|
+
/** @protected */
|
|
176
|
+
initAddedNode(node) {
|
|
177
|
+
if (node !== this.defaultNode) {
|
|
178
|
+
this.initCustomNode(node);
|
|
179
|
+
this.initNode(node);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
138
183
|
/**
|
|
139
184
|
* Setup the observer to manage slot content changes.
|
|
140
185
|
* @protected
|
|
@@ -145,9 +190,8 @@ export class SlotController extends EventTarget {
|
|
|
145
190
|
const slot = this.host.shadowRoot.querySelector(selector);
|
|
146
191
|
|
|
147
192
|
this.__slotObserver = new FlattenedNodesObserver(slot, (info) => {
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
const newNode = info.addedNodes.find((node) => node !== current);
|
|
193
|
+
const current = this.multiple ? this.nodes : [this.node];
|
|
194
|
+
const newNodes = info.addedNodes.filter((node) => !current.includes(node));
|
|
151
195
|
|
|
152
196
|
if (info.removedNodes.length) {
|
|
153
197
|
info.removedNodes.forEach((node) => {
|
|
@@ -155,18 +199,22 @@ export class SlotController extends EventTarget {
|
|
|
155
199
|
});
|
|
156
200
|
}
|
|
157
201
|
|
|
158
|
-
if (
|
|
202
|
+
if (newNodes && newNodes.length > 0) {
|
|
159
203
|
// Custom node is added, remove the current one.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (newNode !== this.defaultNode) {
|
|
167
|
-
this.initCustomNode(newNode);
|
|
204
|
+
current.forEach((node) => {
|
|
205
|
+
if (node && node.isConnected) {
|
|
206
|
+
node.parentNode.removeChild(node);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
168
209
|
|
|
169
|
-
|
|
210
|
+
if (this.multiple) {
|
|
211
|
+
this.nodes = newNodes;
|
|
212
|
+
newNodes.forEach((node) => {
|
|
213
|
+
this.initAddedNode(node);
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
this.node = newNodes[0];
|
|
217
|
+
this.initAddedNode(this.node);
|
|
170
218
|
}
|
|
171
219
|
}
|
|
172
220
|
});
|