@vaadin/component-base 24.0.0-alpha1 → 24.0.0-alpha11
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 +0 -1
- package/index.js +0 -1
- package/package.json +2 -2
- package/src/a11y-announcer.d.ts +1 -1
- package/src/a11y-announcer.js +1 -1
- package/src/active-mixin.d.ts +1 -1
- package/src/active-mixin.js +1 -1
- package/src/browser-utils.js +7 -7
- package/src/controller-mixin.d.ts +1 -1
- package/src/controller-mixin.js +1 -1
- package/src/delegate-focus-mixin.d.ts +48 -0
- package/src/delegate-focus-mixin.js +228 -0
- package/src/delegate-state-mixin.d.ts +20 -0
- package/src/delegate-state-mixin.js +125 -0
- package/src/dir-mixin.d.ts +2 -4
- package/src/dir-mixin.js +7 -29
- package/src/dir-utils.d.ts +19 -0
- package/src/dir-utils.js +36 -0
- package/src/disabled-mixin.d.ts +1 -1
- package/src/disabled-mixin.js +1 -1
- package/src/dom-utils.d.ts +1 -1
- package/src/dom-utils.js +1 -1
- package/src/element-mixin.d.ts +1 -1
- package/src/element-mixin.js +11 -5
- package/src/focus-mixin.d.ts +1 -1
- package/src/focus-mixin.js +1 -1
- package/src/focus-trap-controller.d.ts +1 -1
- package/src/focus-trap-controller.js +22 -22
- package/src/focus-utils.d.ts +1 -1
- package/src/focus-utils.js +1 -1
- package/src/gestures.js +1 -1
- package/src/iron-list-core.js +32 -12
- package/src/keyboard-direction-mixin.d.ts +1 -1
- package/src/keyboard-direction-mixin.js +12 -12
- package/src/keyboard-mixin.d.ts +1 -1
- package/src/keyboard-mixin.js +1 -1
- package/src/list-mixin.d.ts +50 -0
- package/src/list-mixin.js +343 -0
- package/src/media-query-controller.d.ts +1 -1
- package/src/media-query-controller.js +1 -1
- package/src/overflow-controller.d.ts +1 -1
- package/src/overflow-controller.js +3 -3
- package/src/overlay-class-mixin.d.ts +33 -0
- package/src/overlay-class-mixin.js +79 -0
- package/src/polylit-mixin.d.ts +1 -1
- package/src/polylit-mixin.js +9 -4
- package/src/resize-mixin.d.ts +1 -1
- package/src/resize-mixin.js +11 -21
- package/src/slot-child-observe-controller.d.ts +28 -0
- package/src/slot-child-observe-controller.js +176 -0
- package/src/slot-controller.d.ts +33 -5
- package/src/slot-controller.js +103 -40
- package/src/tabindex-mixin.d.ts +1 -1
- package/src/tabindex-mixin.js +1 -1
- package/src/templates.js +1 -1
- package/src/tooltip-controller.d.ts +1 -1
- package/src/tooltip-controller.js +1 -1
- package/src/unique-id-utils.d.ts +1 -1
- package/src/unique-id-utils.js +1 -1
- package/src/virtualizer-iron-list-adapter.js +67 -9
- package/src/virtualizer.js +18 -18
- package/src/dir-helper.d.ts +0 -42
- package/src/dir-helper.js +0 -93
- package/src/slot-mixin.d.ts +0 -18
- package/src/slot-mixin.js +0 -60
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
7
|
+
import { timeOut } from './async.js';
|
|
8
|
+
import { Debouncer } from './debounce.js';
|
|
9
|
+
import { getNormalizedScrollLeft, setNormalizedScrollLeft } from './dir-utils.js';
|
|
10
|
+
import { KeyboardDirectionMixin } from './keyboard-direction-mixin.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A mixin for list elements, facilitating navigation and selection of items.
|
|
14
|
+
*
|
|
15
|
+
* @polymerMixin
|
|
16
|
+
* @mixes KeyboardDirectionMixin
|
|
17
|
+
*/
|
|
18
|
+
export const ListMixin = (superClass) =>
|
|
19
|
+
class ListMixinClass extends KeyboardDirectionMixin(superClass) {
|
|
20
|
+
static get properties() {
|
|
21
|
+
return {
|
|
22
|
+
/**
|
|
23
|
+
* Used for mixin detection because `instanceof` does not work with mixins.
|
|
24
|
+
* @type {boolean}
|
|
25
|
+
*/
|
|
26
|
+
_hasVaadinListMixin: {
|
|
27
|
+
value: true,
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The index of the item selected in the items array.
|
|
32
|
+
* Note: Not updated when used in `multiple` selection mode.
|
|
33
|
+
*/
|
|
34
|
+
selected: {
|
|
35
|
+
type: Number,
|
|
36
|
+
reflectToAttribute: true,
|
|
37
|
+
notify: true,
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Define how items are disposed in the dom.
|
|
42
|
+
* Possible values are: `horizontal|vertical`.
|
|
43
|
+
* It also changes navigation keys from left/right to up/down.
|
|
44
|
+
* @type {!ListOrientation}
|
|
45
|
+
*/
|
|
46
|
+
orientation: {
|
|
47
|
+
type: String,
|
|
48
|
+
reflectToAttribute: true,
|
|
49
|
+
value: '',
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The list of items from which a selection can be made.
|
|
54
|
+
* It is populated from the elements passed to the light DOM,
|
|
55
|
+
* and updated dynamically when adding or removing items.
|
|
56
|
+
*
|
|
57
|
+
* The item elements must implement `Vaadin.ItemMixin`.
|
|
58
|
+
*
|
|
59
|
+
* Note: unlike `<vaadin-combo-box>`, this property is read-only,
|
|
60
|
+
* so if you want to provide items by iterating array of data,
|
|
61
|
+
* you have to use `dom-repeat` and place it to the light DOM.
|
|
62
|
+
* @type {!Array<!Element> | undefined}
|
|
63
|
+
*/
|
|
64
|
+
items: {
|
|
65
|
+
type: Array,
|
|
66
|
+
readOnly: true,
|
|
67
|
+
notify: true,
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The search buffer for the keyboard selection feature.
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
_searchBuf: {
|
|
75
|
+
type: String,
|
|
76
|
+
value: '',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static get observers() {
|
|
82
|
+
return ['_enhanceItems(items, orientation, selected, disabled)'];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @return {boolean}
|
|
87
|
+
* @protected
|
|
88
|
+
*/
|
|
89
|
+
get _isRTL() {
|
|
90
|
+
return !this._vertical && this.getAttribute('dir') === 'rtl';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @return {!HTMLElement}
|
|
95
|
+
* @protected
|
|
96
|
+
*/
|
|
97
|
+
get _scrollerElement() {
|
|
98
|
+
// Returning scroller element of the component
|
|
99
|
+
console.warn(`Please implement the '_scrollerElement' property in <${this.localName}>`);
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @return {boolean}
|
|
105
|
+
* @protected
|
|
106
|
+
*/
|
|
107
|
+
get _vertical() {
|
|
108
|
+
return this.orientation !== 'horizontal';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
focus() {
|
|
112
|
+
// In initialization (e.g vaadin-select) observer might not been run yet.
|
|
113
|
+
if (this._observer) {
|
|
114
|
+
this._observer.flush();
|
|
115
|
+
}
|
|
116
|
+
const firstItem = this.querySelector('[tabindex="0"]') || (this.items ? this.items[0] : null);
|
|
117
|
+
this._focusItem(firstItem);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** @protected */
|
|
121
|
+
ready() {
|
|
122
|
+
super.ready();
|
|
123
|
+
|
|
124
|
+
this.addEventListener('click', (e) => this._onClick(e));
|
|
125
|
+
|
|
126
|
+
this._observer = new FlattenedNodesObserver(this, () => {
|
|
127
|
+
this._setItems(this._filterItems(FlattenedNodesObserver.getFlattenedNodes(this)));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Override method inherited from `KeyboardDirectionMixin`
|
|
133
|
+
* to use the stored list of item elements.
|
|
134
|
+
*
|
|
135
|
+
* @return {Element[]}
|
|
136
|
+
* @protected
|
|
137
|
+
* @override
|
|
138
|
+
*/
|
|
139
|
+
_getItems() {
|
|
140
|
+
return this.items;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** @private */
|
|
144
|
+
_enhanceItems(items, orientation, selected, disabled) {
|
|
145
|
+
if (!disabled) {
|
|
146
|
+
if (items) {
|
|
147
|
+
this.setAttribute('aria-orientation', orientation || 'vertical');
|
|
148
|
+
this.items.forEach((item) => {
|
|
149
|
+
if (orientation) {
|
|
150
|
+
item.setAttribute('orientation', orientation);
|
|
151
|
+
} else {
|
|
152
|
+
item.removeAttribute('orientation');
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
this._setFocusable(selected || 0);
|
|
157
|
+
|
|
158
|
+
const itemToSelect = items[selected];
|
|
159
|
+
items.forEach((item) => {
|
|
160
|
+
item.selected = item === itemToSelect;
|
|
161
|
+
});
|
|
162
|
+
if (itemToSelect && !itemToSelect.disabled) {
|
|
163
|
+
this._scrollToItem(selected);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @param {!Array<!Element>} array
|
|
171
|
+
* @return {!Array<!Element>}
|
|
172
|
+
* @protected
|
|
173
|
+
*/
|
|
174
|
+
_filterItems(array) {
|
|
175
|
+
return array.filter((e) => e._hasVaadinItemMixin);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {!MouseEvent} event
|
|
180
|
+
* @protected
|
|
181
|
+
*/
|
|
182
|
+
_onClick(event) {
|
|
183
|
+
if (event.metaKey || event.shiftKey || event.ctrlKey || event.defaultPrevented) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const item = this._filterItems(event.composedPath())[0];
|
|
188
|
+
let idx;
|
|
189
|
+
if (item && !item.disabled && (idx = this.items.indexOf(item)) >= 0) {
|
|
190
|
+
this.selected = idx;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @param {number} currentIdx
|
|
196
|
+
* @param {string} key
|
|
197
|
+
* @return {number}
|
|
198
|
+
* @protected
|
|
199
|
+
*/
|
|
200
|
+
_searchKey(currentIdx, key) {
|
|
201
|
+
this._searchReset = Debouncer.debounce(this._searchReset, timeOut.after(500), () => {
|
|
202
|
+
this._searchBuf = '';
|
|
203
|
+
});
|
|
204
|
+
this._searchBuf += key.toLowerCase();
|
|
205
|
+
|
|
206
|
+
if (!this.items.some((item) => this.__isMatchingKey(item))) {
|
|
207
|
+
this._searchBuf = key.toLowerCase();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const idx = this._searchBuf.length === 1 ? currentIdx + 1 : currentIdx;
|
|
211
|
+
return this._getAvailableIndex(
|
|
212
|
+
this.items,
|
|
213
|
+
idx,
|
|
214
|
+
1,
|
|
215
|
+
(item) => this.__isMatchingKey(item) && getComputedStyle(item).display !== 'none',
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** @private */
|
|
220
|
+
__isMatchingKey(item) {
|
|
221
|
+
return item.textContent
|
|
222
|
+
.replace(/[^\p{L}\p{Nd}]/gu, '')
|
|
223
|
+
.toLowerCase()
|
|
224
|
+
.startsWith(this._searchBuf);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Override an event listener from `KeyboardMixin`
|
|
229
|
+
* to search items by key.
|
|
230
|
+
*
|
|
231
|
+
* @param {!KeyboardEvent} event
|
|
232
|
+
* @protected
|
|
233
|
+
* @override
|
|
234
|
+
*/
|
|
235
|
+
_onKeyDown(event) {
|
|
236
|
+
if (event.metaKey || event.ctrlKey) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const key = event.key;
|
|
241
|
+
|
|
242
|
+
const currentIdx = this.items.indexOf(this.focused);
|
|
243
|
+
if (/[a-zA-Z0-9]/u.test(key) && key.length === 1) {
|
|
244
|
+
const idx = this._searchKey(currentIdx, key);
|
|
245
|
+
if (idx >= 0) {
|
|
246
|
+
this._focus(idx);
|
|
247
|
+
}
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
super._onKeyDown(event);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @param {!Element} item
|
|
256
|
+
* @return {boolean}
|
|
257
|
+
* @protected
|
|
258
|
+
*/
|
|
259
|
+
_isItemHidden(item) {
|
|
260
|
+
return getComputedStyle(item).display === 'none';
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {number} idx
|
|
265
|
+
* @protected
|
|
266
|
+
*/
|
|
267
|
+
_setFocusable(idx) {
|
|
268
|
+
idx = this._getAvailableIndex(this.items, idx, 1);
|
|
269
|
+
const item = this.items[idx];
|
|
270
|
+
this.items.forEach((e) => {
|
|
271
|
+
e.tabIndex = e === item ? 0 : -1;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @param {number} idx
|
|
277
|
+
* @protected
|
|
278
|
+
*/
|
|
279
|
+
_focus(idx) {
|
|
280
|
+
this.items.forEach((e, index) => {
|
|
281
|
+
e.focused = index === idx;
|
|
282
|
+
});
|
|
283
|
+
this._setFocusable(idx);
|
|
284
|
+
this._scrollToItem(idx);
|
|
285
|
+
super._focus(idx);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Scroll the container to have the next item by the edge of the viewport.
|
|
290
|
+
* @param {number} idx
|
|
291
|
+
* @protected
|
|
292
|
+
*/
|
|
293
|
+
_scrollToItem(idx) {
|
|
294
|
+
const item = this.items[idx];
|
|
295
|
+
if (!item) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const props = this._vertical ? ['top', 'bottom'] : this._isRTL ? ['right', 'left'] : ['left', 'right'];
|
|
300
|
+
|
|
301
|
+
const scrollerRect = this._scrollerElement.getBoundingClientRect();
|
|
302
|
+
const nextItemRect = (this.items[idx + 1] || item).getBoundingClientRect();
|
|
303
|
+
const prevItemRect = (this.items[idx - 1] || item).getBoundingClientRect();
|
|
304
|
+
|
|
305
|
+
let scrollDistance = 0;
|
|
306
|
+
if (
|
|
307
|
+
(!this._isRTL && nextItemRect[props[1]] >= scrollerRect[props[1]]) ||
|
|
308
|
+
(this._isRTL && nextItemRect[props[1]] <= scrollerRect[props[1]])
|
|
309
|
+
) {
|
|
310
|
+
scrollDistance = nextItemRect[props[1]] - scrollerRect[props[1]];
|
|
311
|
+
} else if (
|
|
312
|
+
(!this._isRTL && prevItemRect[props[0]] <= scrollerRect[props[0]]) ||
|
|
313
|
+
(this._isRTL && prevItemRect[props[0]] >= scrollerRect[props[0]])
|
|
314
|
+
) {
|
|
315
|
+
scrollDistance = prevItemRect[props[0]] - scrollerRect[props[0]];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this._scroll(scrollDistance);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* @param {number} pixels
|
|
323
|
+
* @protected
|
|
324
|
+
*/
|
|
325
|
+
_scroll(pixels) {
|
|
326
|
+
if (this._vertical) {
|
|
327
|
+
this._scrollerElement.scrollTop += pixels;
|
|
328
|
+
} else {
|
|
329
|
+
const dir = this.getAttribute('dir') || 'ltr';
|
|
330
|
+
const scrollLeft = getNormalizedScrollLeft(this._scrollerElement, dir) + pixels;
|
|
331
|
+
setNormalizedScrollLeft(this._scrollerElement, dir, scrollLeft);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Fired when the selection is changed.
|
|
337
|
+
* Not fired when used in `multiple` selection mode.
|
|
338
|
+
*
|
|
339
|
+
* @event selected-changed
|
|
340
|
+
* @param {Object} detail
|
|
341
|
+
* @param {Object} detail.value the index of the item selected in the items array.
|
|
342
|
+
*/
|
|
343
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
3
|
+
* Copyright (c) 2021 - 2023 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';
|
|
@@ -92,7 +92,7 @@ export class OverflowController {
|
|
|
92
92
|
overflow += ' top';
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
if (target.scrollTop < target.scrollHeight - target.clientHeight) {
|
|
95
|
+
if (Math.ceil(target.scrollTop) < Math.ceil(target.scrollHeight - target.clientHeight)) {
|
|
96
96
|
overflow += ' bottom';
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -101,7 +101,7 @@ export class OverflowController {
|
|
|
101
101
|
overflow += ' start';
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
if (scrollLeft < target.scrollWidth - target.clientWidth) {
|
|
104
|
+
if (Math.ceil(scrollLeft) < Math.ceil(target.scrollWidth - target.clientWidth)) {
|
|
105
105
|
overflow += ' end';
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 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 that forwards CSS class names to the internal overlay element
|
|
10
|
+
* by setting the `overlayClass` property or `overlay-class` attribute.
|
|
11
|
+
*/
|
|
12
|
+
export declare function OverlayClassMixin<T extends Constructor<HTMLElement>>(
|
|
13
|
+
base: T,
|
|
14
|
+
): Constructor<OverlayClassMixinClass> & T;
|
|
15
|
+
|
|
16
|
+
export declare class OverlayClassMixinClass {
|
|
17
|
+
/**
|
|
18
|
+
* A space-delimited list of CSS class names to set on the overlay element.
|
|
19
|
+
* This property does not affect other CSS class names set manually via JS.
|
|
20
|
+
*
|
|
21
|
+
* Note, if the CSS class name was set with this property, clearing it will
|
|
22
|
+
* remove it from the overlay, even if the same class name was also added
|
|
23
|
+
* manually, e.g. by using `classList.add()` in the `renderer` function.
|
|
24
|
+
*
|
|
25
|
+
* @attr {string} overlay-class
|
|
26
|
+
*/
|
|
27
|
+
overlayClass: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An overlay element on which CSS class names are set.
|
|
31
|
+
*/
|
|
32
|
+
protected _overlayElement: HTMLElement;
|
|
33
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A mixin that forwards CSS class names to the internal overlay element
|
|
9
|
+
* by setting the `overlayClass` property or `overlay-class` attribute.
|
|
10
|
+
*
|
|
11
|
+
* @polymerMixin
|
|
12
|
+
*/
|
|
13
|
+
export const OverlayClassMixin = (superclass) =>
|
|
14
|
+
class OverlayClassMixinClass extends superclass {
|
|
15
|
+
static get properties() {
|
|
16
|
+
return {
|
|
17
|
+
/**
|
|
18
|
+
* A space-delimited list of CSS class names to set on the overlay element.
|
|
19
|
+
* This property does not affect other CSS class names set manually via JS.
|
|
20
|
+
*
|
|
21
|
+
* Note, if the CSS class name was set with this property, clearing it will
|
|
22
|
+
* remove it from the overlay, even if the same class name was also added
|
|
23
|
+
* manually, e.g. by using `classList.add()` in the `renderer` function.
|
|
24
|
+
*
|
|
25
|
+
* @attr {string} overlay-class
|
|
26
|
+
*/
|
|
27
|
+
overlayClass: {
|
|
28
|
+
type: String,
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* An overlay element on which CSS class names are set.
|
|
33
|
+
*
|
|
34
|
+
* @protected
|
|
35
|
+
*/
|
|
36
|
+
_overlayElement: {
|
|
37
|
+
type: Object,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static get observers() {
|
|
43
|
+
return ['__updateOverlayClassNames(overlayClass, _overlayElement)'];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @private */
|
|
47
|
+
__updateOverlayClassNames(overlayClass, overlayElement) {
|
|
48
|
+
if (!overlayElement) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Overlay is set but overlayClass is not set
|
|
53
|
+
if (overlayClass === undefined) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { classList } = overlayElement;
|
|
58
|
+
|
|
59
|
+
if (!this.__initialClasses) {
|
|
60
|
+
this.__initialClasses = new Set(classList);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (Array.isArray(this.__previousClasses)) {
|
|
64
|
+
// Remove old classes that no longer apply
|
|
65
|
+
const classesToRemove = this.__previousClasses.filter((name) => !this.__initialClasses.has(name));
|
|
66
|
+
if (classesToRemove.length > 0) {
|
|
67
|
+
classList.remove(...classesToRemove);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Add new classes based on the overlayClass
|
|
72
|
+
const classesToAdd = typeof overlayClass === 'string' ? overlayClass.split(' ') : [];
|
|
73
|
+
if (classesToAdd.length > 0) {
|
|
74
|
+
classList.add(...classesToAdd);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.__previousClasses = classesToAdd;
|
|
78
|
+
}
|
|
79
|
+
};
|
package/src/polylit-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
3
|
+
* Copyright (c) 2021 - 2023 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';
|
package/src/polylit-mixin.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
3
|
+
* Copyright (c) 2021 - 2023 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 { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
7
7
|
|
|
8
8
|
const caseMap = {};
|
|
9
9
|
|
|
10
|
-
const CAMEL_TO_DASH = /([A-Z])/
|
|
10
|
+
const CAMEL_TO_DASH = /([A-Z])/gu;
|
|
11
11
|
|
|
12
12
|
function camelToDash(camel) {
|
|
13
|
-
|
|
13
|
+
if (!caseMap[camel]) {
|
|
14
|
+
caseMap[camel] = camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase();
|
|
15
|
+
}
|
|
14
16
|
return caseMap[camel];
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -169,7 +171,10 @@ const PolylitMixinImplementation = (superclass) => {
|
|
|
169
171
|
firstUpdated() {
|
|
170
172
|
super.firstUpdated();
|
|
171
173
|
|
|
172
|
-
|
|
174
|
+
if (!this.$) {
|
|
175
|
+
this.$ = {};
|
|
176
|
+
}
|
|
177
|
+
|
|
173
178
|
this.shadowRoot.querySelectorAll('[id]').forEach((node) => {
|
|
174
179
|
this.$[node.id] = node;
|
|
175
180
|
});
|
package/src/resize-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
3
|
+
* Copyright (c) 2021 - 2023 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';
|
package/src/resize-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
3
|
+
* Copyright (c) 2021 - 2023 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 { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
@@ -28,6 +28,16 @@ const observer = new ResizeObserver((entries) => {
|
|
|
28
28
|
export const ResizeMixin = dedupingMixin(
|
|
29
29
|
(superclass) =>
|
|
30
30
|
class ResizeMixinClass extends superclass {
|
|
31
|
+
/**
|
|
32
|
+
* When true, the parent element resize will be also observed.
|
|
33
|
+
* Override this getter and return `true` to enable this.
|
|
34
|
+
*
|
|
35
|
+
* @protected
|
|
36
|
+
*/
|
|
37
|
+
get _observeParent() {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
/** @protected */
|
|
32
42
|
connectedCallback() {
|
|
33
43
|
super.connectedCallback();
|
|
@@ -67,16 +77,6 @@ export const ResizeMixin = dedupingMixin(
|
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
|
|
70
|
-
/**
|
|
71
|
-
* When true, the parent element resize will be also observed.
|
|
72
|
-
* Override this getter and return `true` to enable this.
|
|
73
|
-
*
|
|
74
|
-
* @protected
|
|
75
|
-
*/
|
|
76
|
-
get _observeParent() {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
80
|
/**
|
|
81
81
|
* A handler invoked on host resize. By default, it does nothing.
|
|
82
82
|
* Override the method to implement your own behavior.
|
|
@@ -86,15 +86,5 @@ export const ResizeMixin = dedupingMixin(
|
|
|
86
86
|
_onResize(_contentRect) {
|
|
87
87
|
// To be implemented.
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @deprecated Since Vaadin 23, `notifyResize()` is deprecated. The component uses a
|
|
92
|
-
* ResizeObserver internally and doesn't need to be explicitly notified of resizes.
|
|
93
|
-
*/
|
|
94
|
-
notifyResize() {
|
|
95
|
-
console.warn(
|
|
96
|
-
`WARNING: Since Vaadin 23, notifyResize() is deprecated. The component uses a ResizeObserver internally and doesn't need to be explicitly notified of resizes.`,
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
89
|
},
|
|
100
90
|
);
|
|
@@ -0,0 +1,28 @@
|
|
|
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 { SlotController } from './slot-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller that observes slotted element mutations, especially ID attribute
|
|
10
|
+
* and the text content, and fires an event to notify host element about those.
|
|
11
|
+
*/
|
|
12
|
+
export class SlotChildObserveController extends SlotController {
|
|
13
|
+
/**
|
|
14
|
+
* Setup the mutation observer on the node to update ID and notify host.
|
|
15
|
+
* Node doesn't get observed automatically until this method is called.
|
|
16
|
+
*/
|
|
17
|
+
protected observeNode(node: Node): void;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Override to restore default node when a custom one is removed.
|
|
21
|
+
*/
|
|
22
|
+
protected restoreDefaultNode(): void;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Override to update default node text on property change.
|
|
26
|
+
*/
|
|
27
|
+
protected updateDefaultNode(node: Node): void;
|
|
28
|
+
}
|