@vaadin/component-base 25.3.0-alpha5 → 25.3.0-alpha7
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 +4 -4
- package/src/define.js +1 -1
- package/src/media-query-controller.js +17 -19
- package/src/overflow-controller.js +30 -29
- package/src/slot-child-observe-controller.d.ts +5 -0
- package/src/slot-child-observe-controller.js +19 -18
- package/src/slot-controller.js +2 -1
- package/src/tooltip-controller.js +8 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/component-base",
|
|
3
|
-
"version": "25.3.0-
|
|
3
|
+
"version": "25.3.0-alpha7",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"lit": "^3.0.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@vaadin/chai-plugins": "25.3.0-
|
|
42
|
-
"@vaadin/test-runner-commands": "25.3.0-
|
|
41
|
+
"@vaadin/chai-plugins": "25.3.0-alpha7",
|
|
42
|
+
"@vaadin/test-runner-commands": "25.3.0-alpha7",
|
|
43
43
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
44
44
|
"sinon": "^22.0.0"
|
|
45
45
|
},
|
|
46
46
|
"customElements": "custom-elements.json",
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "ae7b9823df5598faebd7a482993029ee489c35ae"
|
|
48
48
|
}
|
package/src/define.js
CHANGED
|
@@ -13,7 +13,7 @@ function dashToCamelCase(dash) {
|
|
|
13
13
|
|
|
14
14
|
const experimentalMap = {};
|
|
15
15
|
|
|
16
|
-
export function defineCustomElement(CustomElement, version = '25.3.0-
|
|
16
|
+
export function defineCustomElement(CustomElement, version = '25.3.0-alpha7') {
|
|
17
17
|
Object.defineProperty(CustomElement, 'version', {
|
|
18
18
|
get() {
|
|
19
19
|
return version;
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
* A controller for listening on media query changes.
|
|
9
9
|
*/
|
|
10
10
|
export class MediaQueryController {
|
|
11
|
+
/** @type {MediaQueryList | null} */
|
|
12
|
+
#mediaQuery = null;
|
|
13
|
+
|
|
11
14
|
constructor(query, callback) {
|
|
12
15
|
/**
|
|
13
16
|
* The CSS media query to evaluate.
|
|
@@ -24,44 +27,39 @@ export class MediaQueryController {
|
|
|
24
27
|
* @protected
|
|
25
28
|
*/
|
|
26
29
|
this.callback = callback;
|
|
27
|
-
|
|
28
|
-
this._boundQueryHandler = this._queryHandler.bind(this);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
hostConnected() {
|
|
32
|
-
this
|
|
33
|
+
this.#removeListener();
|
|
33
34
|
|
|
34
|
-
this
|
|
35
|
+
this.#mediaQuery = window.matchMedia(this.query);
|
|
35
36
|
|
|
36
|
-
this
|
|
37
|
+
this.#addListener();
|
|
37
38
|
|
|
38
|
-
this
|
|
39
|
+
this.#queryHandler(this.#mediaQuery);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
hostDisconnected() {
|
|
42
|
-
this
|
|
43
|
+
this.#removeListener();
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this._mediaQuery.addListener(this._boundQueryHandler);
|
|
46
|
+
#addListener() {
|
|
47
|
+
if (this.#mediaQuery) {
|
|
48
|
+
this.#mediaQuery.addListener(this.#queryHandler);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this._mediaQuery.removeListener(this._boundQueryHandler);
|
|
52
|
+
#removeListener() {
|
|
53
|
+
if (this.#mediaQuery) {
|
|
54
|
+
this.#mediaQuery.removeListener(this.#queryHandler);
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
this
|
|
57
|
+
this.#mediaQuery = null;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
_queryHandler(mediaQuery) {
|
|
60
|
+
#queryHandler = (mediaQuery) => {
|
|
63
61
|
if (typeof this.callback === 'function') {
|
|
64
62
|
this.callback(mediaQuery.matches);
|
|
65
63
|
}
|
|
66
|
-
}
|
|
64
|
+
};
|
|
67
65
|
}
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
* where content is overflowing. Supported values are: `top`, `bottom`, `start`, `end`.
|
|
11
11
|
*/
|
|
12
12
|
export class OverflowController {
|
|
13
|
+
/** @type {ResizeObserver} */
|
|
14
|
+
#resizeObserver;
|
|
15
|
+
|
|
16
|
+
/** @type {MutationObserver} */
|
|
17
|
+
#childObserver;
|
|
18
|
+
|
|
19
|
+
/** @type {number} */
|
|
20
|
+
#resizeRaf;
|
|
21
|
+
|
|
13
22
|
constructor(host, scrollTarget) {
|
|
14
23
|
/**
|
|
15
24
|
* The controller host element.
|
|
@@ -25,9 +34,6 @@ export class OverflowController {
|
|
|
25
34
|
* @type {HTMLElement}
|
|
26
35
|
*/
|
|
27
36
|
this.scrollTarget = scrollTarget || host;
|
|
28
|
-
|
|
29
|
-
/** @private */
|
|
30
|
-
this.__boundOnScroll = this.__onScroll.bind(this);
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
hostConnected() {
|
|
@@ -46,64 +52,60 @@ export class OverflowController {
|
|
|
46
52
|
observe() {
|
|
47
53
|
const { host } = this;
|
|
48
54
|
|
|
49
|
-
this
|
|
50
|
-
this.
|
|
55
|
+
this.#resizeObserver = new ResizeObserver(() => this.#onResize());
|
|
56
|
+
this.#resizeObserver.observe(host);
|
|
51
57
|
|
|
52
58
|
// Observe initial children
|
|
53
59
|
[...host.children].forEach((child) => {
|
|
54
|
-
this.
|
|
60
|
+
this.#resizeObserver.observe(child);
|
|
55
61
|
});
|
|
56
62
|
|
|
57
|
-
this
|
|
63
|
+
this.#childObserver = new MutationObserver((mutations) => {
|
|
58
64
|
mutations.forEach(({ addedNodes, removedNodes }) => {
|
|
59
65
|
addedNodes.forEach((node) => {
|
|
60
66
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
61
|
-
this.
|
|
67
|
+
this.#resizeObserver.observe(node);
|
|
62
68
|
}
|
|
63
69
|
});
|
|
64
70
|
|
|
65
71
|
removedNodes.forEach((node) => {
|
|
66
72
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
67
|
-
this.
|
|
73
|
+
this.#resizeObserver.unobserve(node);
|
|
68
74
|
}
|
|
69
75
|
});
|
|
70
76
|
|
|
71
77
|
if (addedNodes.length === 0 && removedNodes.length > 0) {
|
|
72
|
-
this
|
|
78
|
+
this.#updateState({ sync: true });
|
|
73
79
|
}
|
|
74
80
|
});
|
|
75
81
|
});
|
|
76
82
|
|
|
77
|
-
this.
|
|
83
|
+
this.#childObserver.observe(host, { childList: true });
|
|
78
84
|
|
|
79
85
|
// Update overflow attribute on scroll
|
|
80
|
-
this.scrollTarget.addEventListener('scroll', this
|
|
86
|
+
this.scrollTarget.addEventListener('scroll', this.#onScroll);
|
|
81
87
|
}
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.__updateState({ sync: false });
|
|
89
|
+
#onResize() {
|
|
90
|
+
this.#updateState({ sync: false });
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
93
|
+
#onScroll = () => {
|
|
94
|
+
this.#updateState({ sync: true });
|
|
95
|
+
};
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
cancelAnimationFrame(this.__resizeRaf);
|
|
97
|
+
#updateState({ sync }) {
|
|
98
|
+
cancelAnimationFrame(this.#resizeRaf);
|
|
96
99
|
|
|
97
|
-
const state = this
|
|
100
|
+
const state = this.#readState();
|
|
98
101
|
if (sync) {
|
|
99
|
-
this
|
|
102
|
+
this.#writeState(state);
|
|
100
103
|
} else {
|
|
101
|
-
this
|
|
104
|
+
this.#resizeRaf = requestAnimationFrame(() => this.#writeState(state));
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
__readState() {
|
|
108
|
+
#readState() {
|
|
107
109
|
const target = this.scrollTarget;
|
|
108
110
|
|
|
109
111
|
let overflow = '';
|
|
@@ -128,8 +130,7 @@ export class OverflowController {
|
|
|
128
130
|
return { overflow: overflow.trim() };
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
__writeState({ overflow }) {
|
|
133
|
+
#writeState({ overflow }) {
|
|
133
134
|
if (overflow) {
|
|
134
135
|
this.host.setAttribute('overflow', overflow);
|
|
135
136
|
} else {
|
|
@@ -25,4 +25,9 @@ export class SlotChildObserveController extends SlotController {
|
|
|
25
25
|
* Override to update default node text on property change.
|
|
26
26
|
*/
|
|
27
27
|
protected updateDefaultNode(node: Node): void;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Fire an event to notify the controller host about node changes.
|
|
31
|
+
*/
|
|
32
|
+
protected _notifyChange(node: Node): void;
|
|
28
33
|
}
|
|
@@ -10,6 +10,9 @@ import { SlotController } from './slot-controller.js';
|
|
|
10
10
|
* and the text content, and fires an event to notify host element about those.
|
|
11
11
|
*/
|
|
12
12
|
export class SlotChildObserveController extends SlotController {
|
|
13
|
+
/** @type {MutationObserver} */
|
|
14
|
+
#nodeObserver;
|
|
15
|
+
|
|
13
16
|
constructor(host, slot, tagName, config = {}) {
|
|
14
17
|
super(host, slot, tagName, { ...config, useUniqueId: true });
|
|
15
18
|
}
|
|
@@ -22,8 +25,8 @@ export class SlotChildObserveController extends SlotController {
|
|
|
22
25
|
* @override
|
|
23
26
|
*/
|
|
24
27
|
initCustomNode(node) {
|
|
25
|
-
this
|
|
26
|
-
this.
|
|
28
|
+
this.#updateNodeId(node);
|
|
29
|
+
this._notifyChange(node);
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
/**
|
|
@@ -39,7 +42,7 @@ export class SlotChildObserveController extends SlotController {
|
|
|
39
42
|
|
|
40
43
|
// Custom node is added to the slot
|
|
41
44
|
if (node && node !== this.defaultNode) {
|
|
42
|
-
this.
|
|
45
|
+
this._notifyChange(node);
|
|
43
46
|
} else {
|
|
44
47
|
this.restoreDefaultNode();
|
|
45
48
|
this.updateDefaultNode(this.node);
|
|
@@ -58,7 +61,7 @@ export class SlotChildObserveController extends SlotController {
|
|
|
58
61
|
const node = super.attachDefaultNode();
|
|
59
62
|
|
|
60
63
|
if (node) {
|
|
61
|
-
this
|
|
64
|
+
this.#updateNodeId(node);
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
return node;
|
|
@@ -80,7 +83,7 @@ export class SlotChildObserveController extends SlotController {
|
|
|
80
83
|
* @protected
|
|
81
84
|
*/
|
|
82
85
|
updateDefaultNode(node) {
|
|
83
|
-
this.
|
|
86
|
+
this._notifyChange(node);
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
/**
|
|
@@ -92,11 +95,11 @@ export class SlotChildObserveController extends SlotController {
|
|
|
92
95
|
*/
|
|
93
96
|
observeNode(node) {
|
|
94
97
|
// Stop observing the previous node, if any.
|
|
95
|
-
if (this
|
|
96
|
-
this.
|
|
98
|
+
if (this.#nodeObserver) {
|
|
99
|
+
this.#nodeObserver.disconnect();
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
this
|
|
102
|
+
this.#nodeObserver = new MutationObserver((mutations) => {
|
|
100
103
|
mutations.forEach((mutation) => {
|
|
101
104
|
const target = mutation.target;
|
|
102
105
|
|
|
@@ -108,17 +111,17 @@ export class SlotChildObserveController extends SlotController {
|
|
|
108
111
|
// We use attributeFilter to only observe ID mutation,
|
|
109
112
|
// no need to check for attribute name separately.
|
|
110
113
|
if (isCurrentNodeMutation) {
|
|
111
|
-
this
|
|
114
|
+
this.#updateNodeId(target);
|
|
112
115
|
}
|
|
113
116
|
} else if (isCurrentNodeMutation || target.parentElement === this.node) {
|
|
114
117
|
// Node text content has changed.
|
|
115
|
-
this.
|
|
118
|
+
this._notifyChange(this.node);
|
|
116
119
|
}
|
|
117
120
|
});
|
|
118
121
|
});
|
|
119
122
|
|
|
120
123
|
// Observe changes to node ID attribute, text content and children.
|
|
121
|
-
this.
|
|
124
|
+
this.#nodeObserver.observe(node, {
|
|
122
125
|
attributes: true,
|
|
123
126
|
attributeFilter: ['id'],
|
|
124
127
|
childList: true,
|
|
@@ -133,9 +136,8 @@ export class SlotChildObserveController extends SlotController {
|
|
|
133
136
|
*
|
|
134
137
|
* @param {Node} node
|
|
135
138
|
* @return {boolean}
|
|
136
|
-
* @private
|
|
137
139
|
*/
|
|
138
|
-
|
|
140
|
+
#hasContent(node) {
|
|
139
141
|
if (!node) {
|
|
140
142
|
return false;
|
|
141
143
|
}
|
|
@@ -150,12 +152,12 @@ export class SlotChildObserveController extends SlotController {
|
|
|
150
152
|
* Fire an event to notify the controller host about node changes.
|
|
151
153
|
*
|
|
152
154
|
* @param {Node} node
|
|
153
|
-
* @
|
|
155
|
+
* @protected
|
|
154
156
|
*/
|
|
155
|
-
|
|
157
|
+
_notifyChange(node) {
|
|
156
158
|
this.dispatchEvent(
|
|
157
159
|
new CustomEvent('slot-content-changed', {
|
|
158
|
-
detail: { hasContent: this
|
|
160
|
+
detail: { hasContent: this.#hasContent(node), node },
|
|
159
161
|
}),
|
|
160
162
|
);
|
|
161
163
|
}
|
|
@@ -164,9 +166,8 @@ export class SlotChildObserveController extends SlotController {
|
|
|
164
166
|
* Set default ID on the node in case it is an HTML element.
|
|
165
167
|
*
|
|
166
168
|
* @param {Node} node
|
|
167
|
-
* @private
|
|
168
169
|
*/
|
|
169
|
-
|
|
170
|
+
#updateNodeId(node) {
|
|
170
171
|
// When in multiple mode, only set ID attribute on the element in default slot.
|
|
171
172
|
const isFirstNode = !this.nodes || node === this.nodes[0];
|
|
172
173
|
if (node.nodeType === Node.ELEMENT_NODE && (!this.multiple || isFirstNode) && !node.id) {
|
package/src/slot-controller.js
CHANGED
|
@@ -202,7 +202,8 @@ export class SlotController extends EventTarget {
|
|
|
202
202
|
const selector = slotName === '' ? 'slot:not([name])' : `slot[name=${slotName}]`;
|
|
203
203
|
const slot = this.host.shadowRoot.querySelector(selector);
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
// eslint-disable-next-line no-new
|
|
206
|
+
new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
|
|
206
207
|
const current = this.multiple ? this.nodes : [this.node];
|
|
207
208
|
|
|
208
209
|
// Calling `slot.assignedNodes()` includes whitespace text nodes in case of default slot:
|
|
@@ -14,7 +14,6 @@ export class TooltipController extends SlotController {
|
|
|
14
14
|
super(host, 'tooltip');
|
|
15
15
|
|
|
16
16
|
this.setTarget(host);
|
|
17
|
-
this.__onContentChange = this.__onContentChange.bind(this);
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
/**
|
|
@@ -50,8 +49,8 @@ export class TooltipController extends SlotController {
|
|
|
50
49
|
if (!this.manual) {
|
|
51
50
|
this.host.setAttribute('has-tooltip', '');
|
|
52
51
|
}
|
|
53
|
-
this
|
|
54
|
-
tooltipNode.addEventListener('content-changed', this
|
|
52
|
+
this.#notifyChange(tooltipNode);
|
|
53
|
+
tooltipNode.addEventListener('content-changed', this.#onContentChange);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
/**
|
|
@@ -65,8 +64,8 @@ export class TooltipController extends SlotController {
|
|
|
65
64
|
if (!this.manual) {
|
|
66
65
|
this.host.removeAttribute('has-tooltip');
|
|
67
66
|
}
|
|
68
|
-
tooltipNode.removeEventListener('content-changed', this
|
|
69
|
-
this
|
|
67
|
+
tooltipNode.removeEventListener('content-changed', this.#onContentChange);
|
|
68
|
+
this.#notifyChange(null);
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
/**
|
|
@@ -179,13 +178,11 @@ export class TooltipController extends SlotController {
|
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
181
|
+
#onContentChange = (event) => {
|
|
182
|
+
this.#notifyChange(event.target);
|
|
183
|
+
};
|
|
186
184
|
|
|
187
|
-
|
|
188
|
-
__notifyChange(node) {
|
|
185
|
+
#notifyChange(node) {
|
|
189
186
|
this.dispatchEvent(new CustomEvent('tooltip-changed', { detail: { node } }));
|
|
190
187
|
}
|
|
191
188
|
}
|