@swiftwc/ui 0.0.0-dev.20 → 0.0.0-dev.22
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/generated/buses/alert-dialog.d.ts +2 -0
- package/generated/buses/alert-dialog.js +1 -0
- package/generated/buses/confirmation-dialog.d.ts +2 -0
- package/generated/buses/confirmation-dialog.js +1 -0
- package/generated/buses/index.d.ts +6 -0
- package/generated/buses/index.js +6 -0
- package/generated/buses/lifecycle-observer.d.ts +2 -0
- package/generated/buses/lifecycle-observer.js +1 -0
- package/generated/client/index.d.ts +17 -4
- package/generated/client/index.js +83 -32
- package/generated/components/alert-dialog.d.ts +8 -0
- package/generated/components/alert-dialog.js +94 -0
- package/generated/components/bordered-button.d.ts +6 -0
- package/generated/components/bordered-button.js +22 -1
- package/generated/components/bordered-prominent-button.d.ts +6 -0
- package/generated/components/bordered-prominent-button.js +22 -1
- package/generated/components/borderless-button.d.ts +5 -1
- package/generated/components/borderless-button.js +13 -7
- package/generated/components/confirmation-dialog.d.ts +1 -1
- package/generated/components/confirmation-dialog.js +26 -20
- package/generated/components/content-unavailable-view.js +2 -2
- package/generated/components/date-picker.js +24 -10
- package/generated/components/disclosure-group.js +4 -1
- package/generated/components/glass-button.d.ts +6 -0
- package/generated/components/glass-button.js +22 -1
- package/generated/components/glass-prominent-button.d.ts +6 -0
- package/generated/components/glass-prominent-button.js +22 -1
- package/generated/components/index.d.ts +1 -0
- package/generated/components/index.js +1 -0
- package/generated/components/label-view.js +3 -35
- package/generated/components/menu-view.js +12 -7
- package/generated/components/navigation-title.js +4 -4
- package/generated/components/picker-view.js +35 -25
- package/generated/components/scroll-view.js +27 -13
- package/generated/components/section-view.js +3 -3
- package/generated/components/sheet-view.d.ts +1 -2
- package/generated/components/sheet-view.js +38 -22
- package/generated/components/sidebar-toggle.js +6 -4
- package/generated/components/sidebar-view.js +10 -4
- package/generated/components/sticky-container.js +3 -1
- package/generated/components/tab-bar.js +10 -4
- package/generated/components/tab-item.js +3 -1
- package/generated/components/tab-view.js +11 -8
- package/generated/components/table-view.js +22 -10
- package/generated/components/text-field.js +37 -32
- package/generated/components/tool-bar-item-group.js +17 -0
- package/generated/components/tool-bar-item.js +20 -1
- package/generated/components/tool-bar.d.ts +12 -0
- package/generated/components/tool-bar.js +20 -7
- package/generated/components/v-stack.d.ts +5 -0
- package/generated/components/v-stack.js +5 -0
- package/generated/css/index.css +377 -86
- package/generated/events/alert-dialog.d.ts +8 -0
- package/generated/events/alert-dialog.js +1 -0
- package/generated/events/confirmation-dialog.d.ts +2 -2
- package/generated/events/index.d.ts +1 -0
- package/generated/events/index.js +1 -0
- package/generated/events/tab-view.d.ts +6 -2
- package/generated/i18n/locales/el.d.ts +9 -0
- package/generated/i18n/locales/el.js +9 -0
- package/generated/i18n/locales/en.d.ts +9 -0
- package/generated/i18n/locales/en.js +9 -0
- package/generated/internal/class/css-style-observer.js +1 -1
- package/generated/internal/class/form-associated-base.js +4 -1
- package/generated/internal/class/navigation-view.js +4 -4
- package/generated/internal/utils/button-role.d.ts +1 -0
- package/generated/internal/utils/button-role.js +39 -0
- package/generated/internal/utils/cash/index.d.ts +4 -3
- package/generated/internal/utils/cash/index.js +6 -4
- package/generated/internal/utils/index.d.ts +2 -0
- package/generated/internal/utils/index.js +2 -0
- package/generated/internal/utils/is-inside.d.ts +1 -0
- package/generated/internal/utils/is-inside.js +4 -0
- package/generated/internal/utils/list-active.js +15 -5
- package/generated/snapshot/index.d.ts +2 -0
- package/generated/snapshot/index.js +21 -0
- package/package.json +7 -4
- package/scss/_components.scss +2 -0
- package/scss/_functions.scss +10 -0
- package/scss/_transitions.scss +1 -0
- package/scss/_vars.scss +5 -0
- package/scss/base/_reboot.scss +10 -0
- package/scss/colors/_index.scss +39 -21
- package/scss/components/_alert-dialog.scss +106 -0
- package/scss/components/_bordered-button.scss +14 -0
- package/scss/components/_bordered-prominent-button.scss +13 -0
- package/scss/components/_borderless-button.scss +4 -0
- package/scss/components/_confirmation-dialog.scss +39 -39
- package/scss/components/_content-unavailable-view.scss +1 -1
- package/scss/components/_disclosure-group.scss +80 -33
- package/scss/components/_glass-button.scss +14 -0
- package/scss/components/_glass-prominent-button.scss +14 -0
- package/scss/components/_h-stack.scss +3 -13
- package/scss/components/_index.scss +1 -0
- package/scss/components/_label-view.scss +42 -16
- package/scss/components/_label-view.scss.txt +536 -0
- package/scss/components/_sheet-view.scss +13 -3
- package/scss/components/_tab-bar.scss +5 -0
- package/scss/components/_tool-bar-item.scss +19 -0
- package/scss/components/_tool-bar.scss +25 -0
- package/scss/components/_v-stack.scss +3 -13
- package/scss/final/_touch-glass.scss +7 -0
- package/scss/mixins/_index.scss +17 -0
- package/scss/placeholders/_buttons.scss +87 -10
- package/scss/transitions/_alert-dialog.scss +19 -0
- package/scss/transitions/_tab-bar.scss +6 -5
- package/scss/utils/_frame.scss +7 -0
- package/web-components.html-data/en.json +81 -13
- package/generated/confirmation-dialog/index.d.ts +0 -1
- package/generated/confirmation-dialog/index.js +0 -1
- package/generated/lifecycle-observer/index.d.ts +0 -1
- package/generated/lifecycle-observer/index.js +0 -1
- package/scss/components/_components.scss +0 -76
|
@@ -26,7 +26,8 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
26
26
|
// #lastRenderedStyle?: DatePickerStyle //string | null
|
|
27
27
|
#shadowRoot;
|
|
28
28
|
#customValidity = '';
|
|
29
|
-
#
|
|
29
|
+
#slots = new Map();
|
|
30
|
+
// #validitiesSlot?: HTMLSlotElement
|
|
30
31
|
#inputs = [];
|
|
31
32
|
get #internals() {
|
|
32
33
|
return getInternals(this);
|
|
@@ -48,7 +49,7 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
48
49
|
<input type="text" name="year" inputmode="numeric" pattern="\d*" minlength="4" maxlength="4" min="0" max="9999" part="root input date-picker-form-input">
|
|
49
50
|
</div>
|
|
50
51
|
<slot name="validity-options" hidden></slot>
|
|
51
|
-
</label
|
|
52
|
+
</label>`));
|
|
52
53
|
break;
|
|
53
54
|
}
|
|
54
55
|
return _a.#templates.get(this.datePickerStyle);
|
|
@@ -99,7 +100,7 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
99
100
|
case 'label':
|
|
100
101
|
let label = this.querySelector(':scope>[slot=label]');
|
|
101
102
|
if (newValue) {
|
|
102
|
-
label ??= this.appendChild($(`<span slot="label"></span
|
|
103
|
+
label ??= this.appendChild($(`<span slot="label"></span>`, '>1'));
|
|
103
104
|
label.textContent = newValue;
|
|
104
105
|
}
|
|
105
106
|
else
|
|
@@ -123,9 +124,14 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
123
124
|
// this.#lastRenderedStyle = this.datePickerStyle
|
|
124
125
|
// clear shadow DOM
|
|
125
126
|
this.#shadowRoot.replaceChildren(document.importNode(this.template, true));
|
|
126
|
-
this
|
|
127
|
+
CleanupRegistry.unregister(this, 'slots');
|
|
128
|
+
for (const slot of this.#shadowRoot.querySelectorAll('slot'))
|
|
129
|
+
this.#slots?.set(slot.name, slot);
|
|
130
|
+
CleanupRegistry.register(this, () => {
|
|
131
|
+
this.#slots = new Map();
|
|
132
|
+
}, 'slots');
|
|
127
133
|
CleanupRegistry.unregister(this, 'validities');
|
|
128
|
-
CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#
|
|
134
|
+
CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#slots?.get('validity-options')).on(), 'validities');
|
|
129
135
|
switch (this.datePickerStyle) {
|
|
130
136
|
default:
|
|
131
137
|
const [yyyy = '', mm = '', dd = ''] = new Date().toISOString().split('T').shift()?.split('-') ?? [], map = { year: yyyy, month: mm, day: dd };
|
|
@@ -177,7 +183,10 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
177
183
|
}
|
|
178
184
|
#handleClick = (evt) => {
|
|
179
185
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
180
|
-
const
|
|
186
|
+
const target = evt.target instanceof HTMLElement && evt.target;
|
|
187
|
+
if (!target)
|
|
188
|
+
return;
|
|
189
|
+
const input = target.closest('input');
|
|
181
190
|
if (input)
|
|
182
191
|
return;
|
|
183
192
|
this.#shadowRoot.querySelector('input.focus')?.focus?.();
|
|
@@ -217,7 +226,7 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
217
226
|
};
|
|
218
227
|
#handleInputPaste = (evt) => {
|
|
219
228
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
220
|
-
const input = evt.target;
|
|
229
|
+
const input = evt.target instanceof HTMLInputElement && evt.target;
|
|
221
230
|
if (!input)
|
|
222
231
|
return;
|
|
223
232
|
evt.preventDefault();
|
|
@@ -239,7 +248,7 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
239
248
|
};
|
|
240
249
|
#handleInputBeforeinput = (evt) => {
|
|
241
250
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
242
|
-
const input = evt.target;
|
|
251
|
+
const input = evt.target instanceof HTMLInputElement && evt.target;
|
|
243
252
|
if (!input)
|
|
244
253
|
return;
|
|
245
254
|
if ('insertText' !== evt.inputType)
|
|
@@ -262,6 +271,8 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
262
271
|
};
|
|
263
272
|
#handleInputKeydown = ({ type, target, key }) => {
|
|
264
273
|
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
274
|
+
if (!(target instanceof HTMLInputElement && target))
|
|
275
|
+
return;
|
|
265
276
|
const input = target;
|
|
266
277
|
if (!input)
|
|
267
278
|
return;
|
|
@@ -284,7 +295,10 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
284
295
|
};
|
|
285
296
|
#handleInputBlur = (evt) => {
|
|
286
297
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
287
|
-
const
|
|
298
|
+
const target = evt.target instanceof HTMLInputElement && evt.target;
|
|
299
|
+
if (!target)
|
|
300
|
+
return;
|
|
301
|
+
const input = target;
|
|
288
302
|
if (0 === input.value.length)
|
|
289
303
|
return;
|
|
290
304
|
const finalText = `${clamp(this.value[input.name] ?? '0', _a.#min(input), _a.#max(input))}`.padStart(parseInt(input.getAttribute('maxlength') ?? '0'), '0');
|
|
@@ -377,7 +391,7 @@ export class DatePicker extends FormAssociatedBase {
|
|
|
377
391
|
const key = k; // ✅ type-safe cast
|
|
378
392
|
if (true !== flags[key])
|
|
379
393
|
continue;
|
|
380
|
-
for (const el of this.#
|
|
394
|
+
for (const el of this.#slots?.get('validity-options')?.assignedElements({ flatten: true }) ?? []) {
|
|
381
395
|
if (!el.matches('option'))
|
|
382
396
|
continue;
|
|
383
397
|
const option = el;
|
|
@@ -35,7 +35,10 @@ export class DisclosureGroup extends DetailsBase {
|
|
|
35
35
|
}
|
|
36
36
|
static #handleToggle = async (evt) => {
|
|
37
37
|
console.debug(`${DisclosureGroup.name} ⚡️ ${evt?.type}`);
|
|
38
|
-
const details = evt.currentTarget
|
|
38
|
+
const details = evt.currentTarget instanceof HTMLDetailsElement && evt.currentTarget;
|
|
39
|
+
if (!details)
|
|
40
|
+
return;
|
|
41
|
+
const newValue = details.open ? 'opening' : 'closing';
|
|
39
42
|
if (newValue !== details.dataset.state)
|
|
40
43
|
details.dataset.state = newValue;
|
|
41
44
|
if (!toggleTimers.has(details))
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { ButtonBase } from '../namespace-browser/base';
|
|
2
|
+
/**
|
|
3
|
+
* @slot overlay
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
2
6
|
export declare class GlassButton extends ButtonBase {
|
|
7
|
+
static get observedAttributes(): string[];
|
|
3
8
|
constructor();
|
|
4
9
|
static polyfillDisconnectedCallback(el: ButtonBase): void;
|
|
5
10
|
static polyfillConnectedCallback(el: ButtonBase): void;
|
|
11
|
+
static polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]: Pick<MutationRecord, 'attributeName' | 'oldValue' | 'target'>[]): void;
|
|
6
12
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { CleanupRegistry } from '../internal/class/cleanup-registry';
|
|
2
|
-
import { onoff, touchGlass } from '../internal/utils';
|
|
2
|
+
import { buttonRole, onoff, touchGlass } from '../internal/utils';
|
|
3
3
|
import { ButtonBase } from '../namespace-browser/base';
|
|
4
|
+
import { Snapshot } from '../snapshot';
|
|
5
|
+
/**
|
|
6
|
+
* @slot overlay
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
4
9
|
export class GlassButton extends ButtonBase {
|
|
10
|
+
static get observedAttributes() {
|
|
11
|
+
return ['role'];
|
|
12
|
+
}
|
|
5
13
|
constructor() {
|
|
6
14
|
super();
|
|
7
15
|
}
|
|
@@ -14,4 +22,17 @@ export class GlassButton extends ButtonBase {
|
|
|
14
22
|
CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, () => true), el).on());
|
|
15
23
|
el.tabIndex = 0;
|
|
16
24
|
}
|
|
25
|
+
static polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]) {
|
|
26
|
+
console.debug(`${GlassButton.name} ⚡️ attr-change [${attributeName}] ("${oldValue}" → "${target.getAttribute(attributeName ?? '')}")`);
|
|
27
|
+
const node = target instanceof HTMLButtonElement && target;
|
|
28
|
+
if (!node)
|
|
29
|
+
return;
|
|
30
|
+
switch (attributeName) {
|
|
31
|
+
case 'role':
|
|
32
|
+
Snapshot.waitReady.then(() => {
|
|
33
|
+
buttonRole(target, attributeName);
|
|
34
|
+
});
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
17
38
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { ButtonBase } from '../namespace-browser/base';
|
|
2
|
+
/**
|
|
3
|
+
* @slot overlay
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
2
6
|
export declare class GlassProminentButton extends ButtonBase {
|
|
7
|
+
static get observedAttributes(): string[];
|
|
3
8
|
constructor();
|
|
4
9
|
static polyfillDisconnectedCallback(el: ButtonBase): void;
|
|
5
10
|
static polyfillConnectedCallback(el: ButtonBase): void;
|
|
11
|
+
static polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]: Pick<MutationRecord, 'attributeName' | 'oldValue' | 'target'>[]): void;
|
|
6
12
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { CleanupRegistry } from '../internal/class/cleanup-registry';
|
|
2
|
-
import { onoff, touchGlass } from '../internal/utils';
|
|
2
|
+
import { buttonRole, onoff, touchGlass } from '../internal/utils';
|
|
3
3
|
import { ButtonBase } from '../namespace-browser/base';
|
|
4
|
+
import { Snapshot } from '../snapshot';
|
|
5
|
+
/**
|
|
6
|
+
* @slot overlay
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
4
9
|
export class GlassProminentButton extends ButtonBase {
|
|
10
|
+
static get observedAttributes() {
|
|
11
|
+
return ['role'];
|
|
12
|
+
}
|
|
5
13
|
constructor() {
|
|
6
14
|
super();
|
|
7
15
|
}
|
|
@@ -14,4 +22,17 @@ export class GlassProminentButton extends ButtonBase {
|
|
|
14
22
|
CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, () => true), el).on());
|
|
15
23
|
el.tabIndex = 0;
|
|
16
24
|
}
|
|
25
|
+
static polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]) {
|
|
26
|
+
console.debug(`${GlassProminentButton.name} ⚡️ attr-change [${attributeName}] ("${oldValue}" → "${target.getAttribute(attributeName ?? '')}")`);
|
|
27
|
+
const node = target instanceof HTMLButtonElement && target;
|
|
28
|
+
if (!node)
|
|
29
|
+
return;
|
|
30
|
+
switch (attributeName) {
|
|
31
|
+
case 'role':
|
|
32
|
+
Snapshot.waitReady.then(() => {
|
|
33
|
+
buttonRole(target, attributeName);
|
|
34
|
+
});
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
17
38
|
}
|
|
@@ -11,73 +11,41 @@ export class LabelView extends HTMLElement {
|
|
|
11
11
|
</div>
|
|
12
12
|
<div part="root label-title-stack">
|
|
13
13
|
<slot></slot>
|
|
14
|
-
</div
|
|
14
|
+
</div>`));
|
|
15
15
|
}
|
|
16
16
|
#shadowRoot;
|
|
17
|
-
// #imgSlot?: HTMLSlotElement
|
|
18
|
-
// #slot?: HTMLSlotElement
|
|
19
17
|
constructor() {
|
|
20
18
|
super();
|
|
21
19
|
this.#shadowRoot = this.attachShadow({ mode: 'closed' });
|
|
22
|
-
// Snapshot.waitReady.then(() => {
|
|
23
20
|
this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
|
|
24
|
-
// // this.#imgSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot[name=image]') ?? undefined
|
|
25
|
-
// // this.#slot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot:not([name])') ?? undefined
|
|
26
|
-
//
|
|
27
|
-
// // this.#slot?.addEventListener('slotchange', this.#handleSlotchange)
|
|
28
|
-
// // // this.#imgSlot?.addEventListener('slotchange', this.#handleSlotchange)
|
|
29
|
-
// // // this.#handleSlotchange(new CustomEvent('slotchange'))
|
|
30
|
-
// })
|
|
31
21
|
}
|
|
32
22
|
disconnectedCallback() {
|
|
33
23
|
console.debug(`${LabelView.name} ⚡️ disconnect`);
|
|
34
|
-
// this.#slot?.removeEventListener('slotchange', this.#handleSlotchange)
|
|
35
24
|
}
|
|
36
25
|
connectedCallback() {
|
|
37
26
|
console.debug(`${LabelView.name} ⚡️ connect`);
|
|
38
27
|
}
|
|
39
28
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
40
29
|
console.debug(`${LabelView.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
|
|
41
|
-
// Snapshot.waitReady.then(() => {
|
|
42
30
|
switch (name) {
|
|
43
31
|
case 'system-image':
|
|
44
32
|
let image = this.querySelector(':scope>[slot=image]');
|
|
45
33
|
if (newValue) {
|
|
46
|
-
image ??= this.appendChild($(`<i slot="image"></i
|
|
34
|
+
image ??= this.appendChild($(`<i slot="image" style="line-height: 1.05"></i>`, '>1'));
|
|
47
35
|
image.setAttribute('class', `ph ph-${newValue}`);
|
|
48
36
|
}
|
|
49
37
|
else
|
|
50
38
|
image?.remove();
|
|
51
|
-
// // const imgSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot[name=image]')
|
|
52
|
-
// // if (!imgSlot) break
|
|
53
|
-
// const assigned = this.#imgSlot!.assignedElements({ flatten: true }) as HTMLElement[]
|
|
54
|
-
// let el = assigned[0] as HTMLElement | undefined
|
|
55
|
-
// if (!el) {
|
|
56
|
-
// el = document.createElement('i')
|
|
57
|
-
// el.slot = 'image'
|
|
58
|
-
// this.append(el)
|
|
59
|
-
// }
|
|
60
|
-
// el.setAttribute('class', `ph ph-${newValue}`)
|
|
61
39
|
break;
|
|
62
40
|
case 'title':
|
|
63
41
|
let title = this.querySelector(':scope>:not([slot])');
|
|
64
42
|
if (newValue) {
|
|
65
|
-
title ??= this.appendChild($(`<span></span
|
|
43
|
+
title ??= this.appendChild($(`<span></span>`, '>1'));
|
|
66
44
|
title.textContent = newValue;
|
|
67
45
|
}
|
|
68
46
|
else
|
|
69
47
|
title?.remove();
|
|
70
|
-
// // const titleSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot:not([name])')
|
|
71
|
-
// // if (!titleSlot) break
|
|
72
|
-
// const title = this.#slot!.assignedElements({ flatten: true }) as HTMLElement[]
|
|
73
|
-
// let el2 = title[0] as HTMLElement | undefined
|
|
74
|
-
// if (!el2) {
|
|
75
|
-
// el2 = document.createElement('span')
|
|
76
|
-
// this.append(el2)
|
|
77
|
-
// }
|
|
78
|
-
// el2.textContent = newValue //el2.replaceChildren(escapeHTMLPolicy.createHTML(newValue))
|
|
79
48
|
break;
|
|
80
49
|
}
|
|
81
|
-
// })
|
|
82
50
|
}
|
|
83
51
|
}
|
|
@@ -17,7 +17,7 @@ export class MenuView extends HTMLElement {
|
|
|
17
17
|
<slot></slot>
|
|
18
18
|
</div>
|
|
19
19
|
</form>
|
|
20
|
-
</dialog
|
|
20
|
+
</dialog>`));
|
|
21
21
|
}
|
|
22
22
|
#shadowRoot;
|
|
23
23
|
#dialog;
|
|
@@ -50,9 +50,12 @@ export class MenuView extends HTMLElement {
|
|
|
50
50
|
{ types: 'cancel', listener: this.#handleDialogCancel },
|
|
51
51
|
], this.#dialog).on());
|
|
52
52
|
CleanupRegistry.register(this, onoff(touchGlass(this, (t) => t, (evt) => {
|
|
53
|
-
|
|
53
|
+
const target = evt.target instanceof HTMLElement && evt.target;
|
|
54
|
+
if (!target)
|
|
55
|
+
return true;
|
|
56
|
+
if (target.matches('menu-view'))
|
|
54
57
|
return false;
|
|
55
|
-
if (!
|
|
58
|
+
if (!target.closest('menu-view[open]'))
|
|
56
59
|
return false;
|
|
57
60
|
return true;
|
|
58
61
|
}), this).on());
|
|
@@ -89,7 +92,7 @@ export class MenuView extends HTMLElement {
|
|
|
89
92
|
case 'label':
|
|
90
93
|
let label = this.querySelector(':scope>[slot=label]');
|
|
91
94
|
if (newValue) {
|
|
92
|
-
label ??= this.appendChild($(`<label-view slot="label"></label-view
|
|
95
|
+
label ??= this.appendChild($(`<label-view slot="label"></label-view>`, '>1'));
|
|
93
96
|
label.setAttribute('title', newValue);
|
|
94
97
|
}
|
|
95
98
|
else
|
|
@@ -99,15 +102,17 @@ export class MenuView extends HTMLElement {
|
|
|
99
102
|
}
|
|
100
103
|
#handleDialogClick = (evt) => {
|
|
101
104
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
102
|
-
|
|
105
|
+
const target = evt.target instanceof HTMLElement && evt.target;
|
|
106
|
+
if (!target)
|
|
107
|
+
return;
|
|
108
|
+
if (target.matches('dialog'))
|
|
103
109
|
return this.toggleAttribute('open', false); // click outside
|
|
104
|
-
const target = evt.target;
|
|
105
110
|
target.scrollIntoView({
|
|
106
111
|
behavior: self.matchMedia('(prefers-reduced-motion: no-preference)').matches ? 'smooth' : 'instant',
|
|
107
112
|
block: 'nearest',
|
|
108
113
|
inline: 'nearest',
|
|
109
114
|
});
|
|
110
|
-
if (!
|
|
115
|
+
if (!target.closest('button'))
|
|
111
116
|
return;
|
|
112
117
|
// TODO: Handle btns this.toggleAttribute('open', false)
|
|
113
118
|
this.toggleAttribute('open', false);
|
|
@@ -34,18 +34,18 @@ export class NavigationTitle extends HTMLElement {
|
|
|
34
34
|
}
|
|
35
35
|
#render = (title, subtitle) => {
|
|
36
36
|
const el = this.querySelector(':scope>:not([slot])') ??
|
|
37
|
-
this.appendChild($(`<navigation-large-title><v-stack spacing="0" alignment="fill" slot="top-bar-principal"><label-view line-limit="1" truncation-mode="tail" font="headline"></label-view><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></v-stack></navigation-large-title
|
|
38
|
-
el.appendChild($(`<v-stack spacing="0" alignment="fill" slot="top-bar-principal"><label-view line-limit="1" truncation-mode="tail" font="headline"></label-view><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></v-stack
|
|
37
|
+
this.appendChild($(`<navigation-large-title><v-stack spacing="0" alignment="fill" slot="top-bar-principal"><label-view line-limit="1" truncation-mode="tail" font="headline"></label-view><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></v-stack></navigation-large-title>`, '>1')), vStack = el.querySelector(':scope>v-stack') ??
|
|
38
|
+
el.appendChild($(`<v-stack spacing="0" alignment="fill" slot="top-bar-principal"><label-view line-limit="1" truncation-mode="tail" font="headline"></label-view><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></v-stack>`, '>1'));
|
|
39
39
|
let titleLabel = vStack.querySelector(':scope>label-view:nth-child(1)');
|
|
40
40
|
if (title) {
|
|
41
|
-
titleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="headline"></label-view
|
|
41
|
+
titleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="headline"></label-view>`, '>1'));
|
|
42
42
|
titleLabel.setAttribute('title', title);
|
|
43
43
|
}
|
|
44
44
|
else
|
|
45
45
|
titleLabel?.remove();
|
|
46
46
|
let subtitleLabel = vStack.querySelector(':scope>label-view:nth-child(2)');
|
|
47
47
|
if (subtitle) {
|
|
48
|
-
subtitleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="callout"></label-view
|
|
48
|
+
subtitleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="callout"></label-view>`, '>1'));
|
|
49
49
|
subtitleLabel.setAttribute('title', subtitle);
|
|
50
50
|
}
|
|
51
51
|
else
|
|
@@ -21,9 +21,10 @@ export class PickerView extends FormAssociatedBase {
|
|
|
21
21
|
#lastRenderedStyle; //string | null
|
|
22
22
|
#shadowRoot;
|
|
23
23
|
#customValidity = '';
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
24
|
+
#slots = new Map();
|
|
25
|
+
// #validitiesSlot?: HTMLSlotElement
|
|
26
|
+
// #datalistSlot?: HTMLSlotElement
|
|
27
|
+
// #tagSlot?: HTMLSlotElement
|
|
27
28
|
#trackedElements = new Set();
|
|
28
29
|
#selection = '';
|
|
29
30
|
get #internals() {
|
|
@@ -54,7 +55,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
54
55
|
<slot name="tag" hidden></slot>
|
|
55
56
|
<slot name="validity-options" hidden></slot>
|
|
56
57
|
</label>
|
|
57
|
-
|
|
58
|
+
`));
|
|
58
59
|
// break
|
|
59
60
|
// case 'compact':
|
|
60
61
|
// PickerView.#templates.set(
|
|
@@ -114,7 +115,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
114
115
|
<slot name="options" hidden></slot>
|
|
115
116
|
<slot name="tag" hidden></slot>
|
|
116
117
|
<slot name="validity-options" hidden></slot>
|
|
117
|
-
</label
|
|
118
|
+
</label>`));
|
|
118
119
|
break;
|
|
119
120
|
}
|
|
120
121
|
return _a.#templates.get(this.pickerStyle);
|
|
@@ -176,21 +177,24 @@ export class PickerView extends FormAssociatedBase {
|
|
|
176
177
|
this.#lastRenderedStyle = this.pickerStyle;
|
|
177
178
|
// clear shadow DOM
|
|
178
179
|
this.#shadowRoot.replaceChildren(document.importNode(this.template, true));
|
|
179
|
-
this
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
CleanupRegistry.unregister(this, 'slots');
|
|
181
|
+
for (const slot of this.#shadowRoot.querySelectorAll('slot'))
|
|
182
|
+
this.#slots?.set(slot.name, slot);
|
|
183
|
+
CleanupRegistry.register(this, () => {
|
|
184
|
+
this.#slots = new Map();
|
|
185
|
+
}, 'slots');
|
|
182
186
|
CleanupRegistry.unregister(this, 'validities');
|
|
183
|
-
CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#
|
|
187
|
+
CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#slots?.get('validity-options')).on(), 'validities');
|
|
184
188
|
CleanupRegistry.unregister(this, 'datalist'); //off1()
|
|
185
|
-
CleanupRegistry.register(this, onoff('slotchange', this.#handleSlotchange, this.#
|
|
189
|
+
CleanupRegistry.register(this, onoff('slotchange', this.#handleSlotchange, this.#slots?.get('options')).on(), 'datalist');
|
|
186
190
|
CleanupRegistry.unregister(this, 'tags'); //off2()
|
|
187
|
-
CleanupRegistry.register(this, onoff('slotchange', this.#handleSlotchange, this.#
|
|
188
|
-
// if (0 < (this.#
|
|
189
|
-
// if (0 < (this.#
|
|
191
|
+
CleanupRegistry.register(this, onoff('slotchange', this.#handleSlotchange, this.#slots?.get('tag')).on(), 'tags');
|
|
192
|
+
// if (0 < (this.#slots?.get('options')?.assignedElements({ flatten: true }) ?? []).length) this.#handleTagMutation()
|
|
193
|
+
// if (0 < (this.#slots?.get('tag')?.assignedElements({ flatten: true }) ?? []).length) this.#handleTagMutation()
|
|
190
194
|
//this.getAttribute((this.constructor as typeof PickerView).ATTR.PICKER_STYLE)) {
|
|
191
195
|
switch (this.pickerStyle
|
|
192
196
|
// case 'menu':
|
|
193
|
-
// // if (0 < (this.#
|
|
197
|
+
// // if (0 < (this.#slots?.get('options')?.assignedElements({ flatten: true }) ?? []).length) this.#handleMenuDatalistMutation()
|
|
194
198
|
// break
|
|
195
199
|
// case 'gg':
|
|
196
200
|
// // reattach input listener
|
|
@@ -209,7 +213,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
209
213
|
// break
|
|
210
214
|
// case 'inline':
|
|
211
215
|
// default:
|
|
212
|
-
// // if (0 < (this.#
|
|
216
|
+
// // if (0 < (this.#slots?.get('options')?.assignedElements({ flatten: true }) ?? []).length) this.#handleInlineDatalistMutation()
|
|
213
217
|
// break
|
|
214
218
|
) {
|
|
215
219
|
}
|
|
@@ -235,7 +239,10 @@ export class PickerView extends FormAssociatedBase {
|
|
|
235
239
|
};
|
|
236
240
|
#handleClick(evt) {
|
|
237
241
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
238
|
-
const target = evt.target
|
|
242
|
+
const target = evt.target instanceof HTMLElement && evt.target;
|
|
243
|
+
if (!target)
|
|
244
|
+
return;
|
|
245
|
+
const btn = target?.closest('button');
|
|
239
246
|
if (!btn)
|
|
240
247
|
return;
|
|
241
248
|
if (btn.hasAttribute('tag')) {
|
|
@@ -248,7 +255,10 @@ export class PickerView extends FormAssociatedBase {
|
|
|
248
255
|
}
|
|
249
256
|
#handleSlotchange = (evt) => {
|
|
250
257
|
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
251
|
-
const slot = evt.target
|
|
258
|
+
const slot = evt.target instanceof HTMLSlotElement && evt.target;
|
|
259
|
+
if (!slot)
|
|
260
|
+
return;
|
|
261
|
+
const assigned = slot.assignedElements({ flatten: true });
|
|
252
262
|
observers.syncObservations(this.#trackedElements, assigned, this.#handleTagMutation);
|
|
253
263
|
// for (const el of this.#trackedElements)
|
|
254
264
|
// if (!assigned.includes(el)) {
|
|
@@ -270,7 +280,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
270
280
|
this.#handleTagMutation();
|
|
271
281
|
};
|
|
272
282
|
static wrapTag(node, slotName) {
|
|
273
|
-
const btn = $(`<button type="button" tabindex="0"></button
|
|
283
|
+
const btn = $(`<button type="button" tabindex="0"></button>`, '>1'); //document.createElement('button')
|
|
274
284
|
// btn.type = 'button'
|
|
275
285
|
// btn.tabIndex = 0
|
|
276
286
|
switch (slotName) {
|
|
@@ -283,7 +293,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
283
293
|
default:
|
|
284
294
|
if (node.hasAttribute('value'))
|
|
285
295
|
btn.setAttribute('tag', node.getAttribute('value') ?? '');
|
|
286
|
-
const label = $(`<label-view></label-view
|
|
296
|
+
const label = $(`<label-view></label-view>`, '>1'); //document.createElement('label-view')
|
|
287
297
|
if (node.hasAttribute('label'))
|
|
288
298
|
label.setAttribute('title', node.getAttribute('label') ?? '');
|
|
289
299
|
btn.appendChild(label);
|
|
@@ -293,11 +303,11 @@ export class PickerView extends FormAssociatedBase {
|
|
|
293
303
|
}
|
|
294
304
|
#handleTagMutation = (entry) => {
|
|
295
305
|
console.debug(`${_a.name} ⚡️ mutation`);
|
|
296
|
-
const sourceSlot = 0 < (this.#
|
|
306
|
+
const sourceSlot = 0 < (this.#slots?.get('options')?.assignedElements({ flatten: true }) ?? []).length ? this.#slots?.get('options') : this.#slots?.get('tag');
|
|
297
307
|
// switch (this.getAttribute((this.constructor as typeof PickerView).ATTR.PICKER_STYLE)) {
|
|
298
308
|
switch (this.pickerStyle) {
|
|
299
309
|
case 'menu':
|
|
300
|
-
const menu = this.querySelector(':scope>menu-view:not([slot])') ?? this.appendChild($(`<menu-view tabindex="0"></menu-view
|
|
310
|
+
const menu = this.querySelector(':scope>menu-view:not([slot])') ?? this.appendChild($(`<menu-view tabindex="0"></menu-view>`, '>1'));
|
|
301
311
|
menu.innerHTML = `<label-view slot="label" system-image="dots-three" title="rtyty"></label-view>`;
|
|
302
312
|
for (const el of sourceSlot?.assignedElements({ flatten: true }) ?? [])
|
|
303
313
|
menu.insertAdjacentElement('beforeend', _a.wrapTag(el, sourceSlot?.name));
|
|
@@ -308,11 +318,11 @@ export class PickerView extends FormAssociatedBase {
|
|
|
308
318
|
break;
|
|
309
319
|
case 'inline':
|
|
310
320
|
default:
|
|
311
|
-
const inlineList = this.querySelector(':scope>list-view:not([slot])') ?? this.appendChild($(`<list-view><section-view></section-view></list-view
|
|
321
|
+
const inlineList = this.querySelector(':scope>list-view:not([slot])') ?? this.appendChild($(`<list-view><section-view></section-view></list-view>`, '>1')), section = inlineList.querySelector(':scope>section-view') ?? inlineList.appendChild($(`<section-view></section-view>`, '>1'));
|
|
312
322
|
const label = this.getAttribute(this.constructor.ATTR.LABEL);
|
|
313
323
|
// if (label) section.setAttribute('header', label)
|
|
314
324
|
if (label) {
|
|
315
|
-
const el = $(`<label-view></label-view
|
|
325
|
+
const el = $(`<label-view></label-view>`, '>1');
|
|
316
326
|
el.setAttribute('title', label);
|
|
317
327
|
section.insertAdjacentElement('beforeend', el);
|
|
318
328
|
}
|
|
@@ -360,7 +370,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
360
370
|
// default:
|
|
361
371
|
let label = this.querySelector(':scope>[slot=label]');
|
|
362
372
|
if (value) {
|
|
363
|
-
label ??= this.appendChild($(`<span slot="label"></span
|
|
373
|
+
label ??= this.appendChild($(`<span slot="label"></span>`, '>1'));
|
|
364
374
|
label.textContent = value;
|
|
365
375
|
}
|
|
366
376
|
else
|
|
@@ -396,7 +406,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
396
406
|
const key = k; // ✅ type-safe cast
|
|
397
407
|
if (true !== flags[key])
|
|
398
408
|
continue;
|
|
399
|
-
for (const el of this.#
|
|
409
|
+
for (const el of this.#slots?.get('validity-options')?.assignedElements({ flatten: true }) ?? []) {
|
|
400
410
|
if (!el.matches('option'))
|
|
401
411
|
continue;
|
|
402
412
|
const option = el;
|