@swiftwc/ui 0.0.0-dev.70 → 0.0.0-dev.72
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/components/picker-view.d.ts +1 -1
- package/generated/components/picker-view.js +185 -76
- package/generated/components/scroll-view.d.ts +4 -0
- package/generated/components/text-field.d.ts +4 -0
- package/generated/components/toggle-view.d.ts +4 -0
- package/generated/components/toggle-view.js +1 -1
- package/generated/events/scroll-view.d.ts +3 -5
- package/generated/events/text-field.d.ts +2 -4
- package/generated/events/text-field.js +5 -0
- package/generated/events/toggle-view.d.ts +2 -4
- package/generated/events/toggle-view.js +5 -0
- package/generated/namespace-browser/event.d.ts +10 -0
- package/generated/namespace-browser/event.js +1 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ declare const pickerStyles: readonly ["menu", "inline", "navigation-link", "shee
|
|
|
3
3
|
export type PickerStyle = (typeof pickerStyles)[number];
|
|
4
4
|
export type DictEntry = {
|
|
5
5
|
value: string;
|
|
6
|
-
|
|
6
|
+
title?: string;
|
|
7
7
|
subtitle?: string;
|
|
8
8
|
systemImage?: string;
|
|
9
9
|
children: DictEntry[];
|
|
@@ -6,6 +6,7 @@ import { MutationObserverSet } from '../internal/class/mutation-observer-set';
|
|
|
6
6
|
import { NavigationPath } from '../internal/class/navigation-path';
|
|
7
7
|
import { queryInsertPosition, startViewTransition } from '../internal/privateNamespace';
|
|
8
8
|
import { $, devFlags, kebabCase, onoff, renderLabel, renderLabelIcon, renderLabelTitle } from '../internal/utils';
|
|
9
|
+
import { html, render } from '../tpl';
|
|
9
10
|
const pickerStyles = ['menu', 'inline', 'navigation-link', 'sheet', 'automatic'];
|
|
10
11
|
const update = (path, node, overwrite = true) => {
|
|
11
12
|
if (devFlags.debug)
|
|
@@ -20,9 +21,9 @@ const update = (path, node, overwrite = true) => {
|
|
|
20
21
|
if (page)
|
|
21
22
|
page.insertAdjacentElement(position, node);
|
|
22
23
|
};
|
|
23
|
-
const
|
|
24
|
+
const reflectSpawnedPage = (current, source) => {
|
|
24
25
|
if (devFlags.debug)
|
|
25
|
-
console.debug(`PickerView:
|
|
26
|
+
console.debug(`PickerView: reflectSpawnedPage`);
|
|
26
27
|
const { page: oldSv, toolBarConfig: oldToolbar } = new NavigationPath(current).hydrate(), { page: newSv, toolBarConfig: newToolbar } = new NavigationPath(source).hydrate();
|
|
27
28
|
const oldList = oldSv?.querySelector('list-view'), newList = newSv?.querySelector('list-view'), oldBackBtn = oldToolbar?.at(0)?.querySelector('button'), newBackBtn = newToolbar?.at(0)?.querySelector('button');
|
|
28
29
|
// pre replace list (always exists)
|
|
@@ -37,7 +38,7 @@ const reflectSpawnedElement = (current, source) => {
|
|
|
37
38
|
summary.parentElement?.setAttribute('open', 'open');
|
|
38
39
|
break;
|
|
39
40
|
}
|
|
40
|
-
// replace backbtns (always
|
|
41
|
+
// replace backbtns (always exist)
|
|
41
42
|
if (oldBackBtn && newBackBtn)
|
|
42
43
|
oldBackBtn.replaceWith(newBackBtn);
|
|
43
44
|
// overwrite navtitle (always exists)
|
|
@@ -52,33 +53,43 @@ const reflectSpawnedElement = (current, source) => {
|
|
|
52
53
|
oldSv?.insertAdjacentHTML('afterend', `<sticky-container edge="navbar" style="order: -1" padding>
|
|
53
54
|
<v-stack spacing="0" alignment="fill">
|
|
54
55
|
<input is="search-view" placeholder="Search">
|
|
55
|
-
|
|
56
|
+
<!--<button type="button">Filters</button>-->
|
|
56
57
|
</v-stack>
|
|
57
58
|
</sticky-container>`);
|
|
58
59
|
}
|
|
59
60
|
else
|
|
60
61
|
oldSearch?.remove();
|
|
61
62
|
};
|
|
62
|
-
const
|
|
63
|
+
const extractTag = (node) => {
|
|
63
64
|
if (devFlags.debug)
|
|
64
|
-
console.debug(`PickerView:
|
|
65
|
+
console.debug(`PickerView: extractTag`);
|
|
65
66
|
return node instanceof HTMLOptionElement ? (((node.getAttribute('value') ?? node.textContent?.trim()) || node.getAttribute('label')) ?? '') : (node.value ?? '');
|
|
66
|
-
},
|
|
67
|
-
if (devFlags.debug)
|
|
68
|
-
console.debug(`PickerView: extractCurrentValueFromOption`);
|
|
69
|
-
return node instanceof HTMLOptionElement ? (node.getAttribute('label') ?? node.getAttribute('value') ?? node.textContent?.trim()) || '' : (node.label ?? node.value ?? '');
|
|
70
|
-
}, extractIconFromOption = (node) => {
|
|
71
|
-
if (devFlags.debug)
|
|
72
|
-
console.debug(`PickerView: extractIconFromOption`);
|
|
73
|
-
return node instanceof HTMLOptionElement ? node.getAttribute('data-system-image') : (node.systemImage ?? null);
|
|
74
|
-
}, extractLabelFromGroup = (node) => {
|
|
67
|
+
}, extractLabel = (node) => {
|
|
75
68
|
if (devFlags.debug)
|
|
76
69
|
console.debug(`PickerView: extractLabelFromGroup`);
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
if (node instanceof Element)
|
|
71
|
+
if (node instanceof HTMLOptionElement)
|
|
72
|
+
return (node.getAttribute('label') ?? node.getAttribute('value') ?? node.textContent?.trim()) || null;
|
|
73
|
+
else
|
|
74
|
+
return node.getAttribute('DATALIST' === node.tagName ? 'data-label' : 'label');
|
|
75
|
+
else
|
|
76
|
+
return node.title ?? node.value ?? null;
|
|
77
|
+
// return node instanceof Element ? node.getAttribute('DATALIST' === node.tagName ? 'data-label' : 'label') : (node.title ?? node.value ?? null)
|
|
78
|
+
}, extractIcon = (node) => {
|
|
79
|
+
if (devFlags.debug)
|
|
80
|
+
console.debug(`PickerView: extractIcon`);
|
|
81
|
+
// return node instanceof Element ? node.getAttribute('data-system-image') : (node.systemImage ?? null)
|
|
82
|
+
if (node instanceof Element)
|
|
83
|
+
return node.getAttribute('data-system-image');
|
|
84
|
+
else
|
|
85
|
+
return node.systemImage ?? null;
|
|
86
|
+
}, extractSubtitle = (node) => {
|
|
79
87
|
if (devFlags.debug)
|
|
80
|
-
console.debug(`PickerView:
|
|
81
|
-
|
|
88
|
+
console.debug(`PickerView: extractSubtitle`);
|
|
89
|
+
if (node instanceof Element)
|
|
90
|
+
return node.getAttribute('data-subtitle');
|
|
91
|
+
else
|
|
92
|
+
return node.subtitle ?? null;
|
|
82
93
|
};
|
|
83
94
|
const allLeaves = (node) => node.children.every((c) => 0 === c.children.length);
|
|
84
95
|
const parseDictionary = (value) => {
|
|
@@ -143,7 +154,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
143
154
|
const { target } = evt;
|
|
144
155
|
if (!(target instanceof HTMLElement))
|
|
145
156
|
return;
|
|
146
|
-
const newPage = this.#spawnPage(el instanceof Element ? Array.from(el.children) : el.children, 'body-view', groupId, this.hasAttribute('searchable'),
|
|
157
|
+
const newPage = this.#spawnPage(el instanceof Element ? Array.from(el.children) : el.children, 'body-view', groupId, this.hasAttribute('searchable'), extractLabel(el));
|
|
147
158
|
if (!newPage)
|
|
148
159
|
return;
|
|
149
160
|
newPage.dataset.groupId = groupId; // <-- tag the spawned page
|
|
@@ -165,7 +176,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
165
176
|
list?.insertAdjacentHTML('afterend', `<sticky-container edge="navbar" style="order: -1" padding>
|
|
166
177
|
<v-stack spacing="0" alignment="fill">
|
|
167
178
|
<input is="search-view" placeholder="Search">
|
|
168
|
-
|
|
179
|
+
<!--<button type="button">Filters</button>-->
|
|
169
180
|
</v-stack>
|
|
170
181
|
</sticky-container>`);
|
|
171
182
|
const searchInput = sv?.querySelector('input'); // FIXME: compoennt is=search-view??
|
|
@@ -279,10 +290,10 @@ export class PickerView extends FormAssociatedBase {
|
|
|
279
290
|
continue;
|
|
280
291
|
}
|
|
281
292
|
const children = source instanceof Element ? Array.from(source.children) : source.children;
|
|
282
|
-
const title = source instanceof Element ?
|
|
293
|
+
const title = source instanceof Element ? extractLabel(source) : (source.title ?? null);
|
|
283
294
|
const newPage = this.#spawnPage(children, 'body-view', groupId, this.hasAttribute('searchable'), title);
|
|
284
295
|
newPage.dataset.groupId = groupId;
|
|
285
|
-
|
|
296
|
+
reflectSpawnedPage(el, newPage);
|
|
286
297
|
}
|
|
287
298
|
};
|
|
288
299
|
#renderButtons(input) {
|
|
@@ -300,8 +311,8 @@ export class PickerView extends FormAssociatedBase {
|
|
|
300
311
|
continue;
|
|
301
312
|
}
|
|
302
313
|
idx[idx.length - 1]++;
|
|
303
|
-
const { value,
|
|
304
|
-
out1[value] =
|
|
314
|
+
const { value, title, systemImage, children } = frame[i];
|
|
315
|
+
out1[value] = title;
|
|
305
316
|
out2[value] = systemImage;
|
|
306
317
|
if (children.length) {
|
|
307
318
|
stack.push(children);
|
|
@@ -333,15 +344,15 @@ export class PickerView extends FormAssociatedBase {
|
|
|
333
344
|
this.#lastRenderedIconMap = {};
|
|
334
345
|
for (const el of input.source)
|
|
335
346
|
if (el.matches('option')) {
|
|
336
|
-
const k =
|
|
347
|
+
const k = extractTag(el);
|
|
337
348
|
this.#lastRenderedLabelMap[k] = el.getAttribute('label') ?? undefined;
|
|
338
|
-
this.#lastRenderedIconMap[k] =
|
|
349
|
+
this.#lastRenderedIconMap[k] = extractIcon(el) ?? undefined;
|
|
339
350
|
}
|
|
340
351
|
else
|
|
341
352
|
for (const opt of el.querySelectorAll('option')) {
|
|
342
|
-
const k =
|
|
353
|
+
const k = extractTag(opt);
|
|
343
354
|
this.#lastRenderedLabelMap[k] = opt.getAttribute('label') ?? undefined;
|
|
344
|
-
this.#lastRenderedIconMap[k] =
|
|
355
|
+
this.#lastRenderedIconMap[k] = extractIcon(opt) ?? undefined;
|
|
345
356
|
}
|
|
346
357
|
this.#lastIndexedRoot = input.source;
|
|
347
358
|
// this.#lastRenderedGroupMap = assigned.flatMap<string[]>((el) =>
|
|
@@ -374,7 +385,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
374
385
|
if (!this.#spawn)
|
|
375
386
|
break;
|
|
376
387
|
// rerender level 0
|
|
377
|
-
|
|
388
|
+
reflectSpawnedPage(this.#spawn, this.#spawnPage(input.source, 'DIALOG' === this.#spawn.tagName ? 'sheet-view' : 'body-view', undefined, this.hasAttribute('searchable'), this.getAttribute('label')));
|
|
378
389
|
this.#resyncSpawnedPages(input.source);
|
|
379
390
|
// // FIXME:
|
|
380
391
|
// for (const el of this.#spawn.querySelectorAll<HTMLElement>('body-view')) {
|
|
@@ -473,13 +484,11 @@ export class PickerView extends FormAssociatedBase {
|
|
|
473
484
|
#lastRenderedIconMap = {};
|
|
474
485
|
#lastIndexedRoot = [];
|
|
475
486
|
get #currentValueLabel() {
|
|
476
|
-
const cvl = this.#lastRenderedLabelMap[this.#selection];
|
|
477
487
|
return ((this.getAttribute(this.constructor.ATTR.CURRENT_VALUE_LABEL) ?? '').replaceAll('{{selection}}', this.#selection).replaceAll('{{currentValueLabel}}', this.#selection) ||
|
|
478
|
-
|
|
488
|
+
this.#lastRenderedLabelMap[this.#selection]);
|
|
479
489
|
}
|
|
480
490
|
get #currentValueIcon() {
|
|
481
|
-
|
|
482
|
-
return (this.getAttribute(this.constructor.ATTR.CURRENT_VALUE_ICON) ?? '') || cvl;
|
|
491
|
+
return (this.getAttribute(this.constructor.ATTR.CURRENT_VALUE_ICON) ?? '') || this.#lastRenderedIconMap[this.#selection];
|
|
483
492
|
}
|
|
484
493
|
get #internals() {
|
|
485
494
|
return getInternals(this);
|
|
@@ -774,40 +783,106 @@ export class PickerView extends FormAssociatedBase {
|
|
|
774
783
|
static #wrapOptionSpawnTag(node) {
|
|
775
784
|
if (devFlags.debug)
|
|
776
785
|
console.debug(`${_a.name} #wrapOptionSpawnTag`);
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
+
const title = extractLabel(node), subtitle = extractSubtitle(node), icon = extractIcon(node);
|
|
787
|
+
const mount = document.createElement('div');
|
|
788
|
+
render(html `<button type="button" tabindex="0" navigation-link>
|
|
789
|
+
<h-stack distribution="leading" template="auto spacer">
|
|
790
|
+
<label-view data-role="check" style="visibility: hidden">
|
|
791
|
+
<image-view slot="icon" system-name="check"></image-view>
|
|
792
|
+
</label-view>
|
|
793
|
+
<h-stack distribution="fill" template="${icon ? 'auto spacer' : null}">
|
|
794
|
+
${icon ? html `<label-view system-image="${icon}"></label-view>` : null}
|
|
795
|
+
<v-stack spacing="3" alignment="fill">
|
|
796
|
+
<label-view title="${title}"></label-view>
|
|
797
|
+
${subtitle ? html `<label-view foreground="secondary" font="callout" title="${subtitle}"></label-view>` : null}
|
|
798
|
+
</v-stack>
|
|
799
|
+
</h-stack>
|
|
800
|
+
</h-stack>
|
|
801
|
+
</button>`, mount);
|
|
802
|
+
// const btn = $<HTMLButtonElement>(
|
|
803
|
+
// `<button type="button" tabindex="0" navigation-link><h-stack distribution="leading" template="auto spacer"><label-view data-role="check" style="visibility: hidden"><image-view slot="icon" system-name="check"></image-view></label-view><label-view><span></span></label-view></h-stack></button>`,
|
|
804
|
+
// '>1'
|
|
805
|
+
// ),
|
|
806
|
+
// hStack = btn.querySelector<LabelView>(':scope>h-stack') ?? undefined
|
|
807
|
+
// renderLabel(
|
|
808
|
+
// ':scope>label-view:nth-child(2)',
|
|
809
|
+
// `<label-view><span></span></label-view>`,
|
|
810
|
+
// hStack,
|
|
811
|
+
// extractLabelFromGroup(node as HTMLDataListElement),
|
|
812
|
+
// extractImgFromGroup(node as HTMLDataListElement)
|
|
813
|
+
// )
|
|
814
|
+
// // label = btn.querySelector<LabelView>(':scope>h-stack>label-view:nth-child(2)')
|
|
815
|
+
// // if (label) {
|
|
816
|
+
// // const lbl = extractLabelFromGroup(node as HTMLDataListElement),
|
|
817
|
+
// // img =extractImgFromGroup(node as HTMLDataListElement)
|
|
818
|
+
// // if(lbl) renderLabelTitle(label, node.dataset.label) //label?.setAttribute('title', el.dataset.label)
|
|
819
|
+
// // }
|
|
820
|
+
return mount.firstElementChild; //btn
|
|
786
821
|
}
|
|
787
822
|
static #wrapOptionTag(node) {
|
|
788
823
|
if (devFlags.debug)
|
|
789
824
|
console.debug(`${_a.name} #wrapOptionTag`);
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
825
|
+
const tag = extractTag(node), title = extractLabel(node), subtitle = extractSubtitle(node), icon = extractIcon(node);
|
|
826
|
+
const mount = document.createElement('div');
|
|
827
|
+
render(html `<button type="button" tabindex="0" value="${tag}">
|
|
828
|
+
<h-stack distribution="leading" template="auto spacer">
|
|
829
|
+
<label-view data-role="check">
|
|
830
|
+
<image-view slot="icon" system-name="check"></image-view>
|
|
831
|
+
</label-view>
|
|
832
|
+
<h-stack distribution="fill" template="${icon ? 'auto spacer' : null}">
|
|
833
|
+
${icon ? html `<label-view system-image="${icon}"></label-view>` : null}
|
|
834
|
+
<v-stack spacing="3" alignment="fill">
|
|
835
|
+
<label-view title="${title}"></label-view>
|
|
836
|
+
${subtitle ? html `<label-view foreground="secondary" font="callout" title="${subtitle}"></label-view>` : null}
|
|
837
|
+
</v-stack>
|
|
838
|
+
</h-stack>
|
|
839
|
+
</h-stack>
|
|
840
|
+
</button>`, mount);
|
|
841
|
+
// const btn = $(
|
|
842
|
+
// `<button type="button" tabindex="0"><h-stack distribution="leading" template="auto spacer"><label-view data-role="check"><image-view slot="icon" system-name="check"></image-view></label-view></h-stack></button>`,
|
|
843
|
+
// '>1'
|
|
844
|
+
// ),
|
|
845
|
+
// hStack = btn.querySelector<HTMLElement>(':scope>h-stack')
|
|
846
|
+
// // chevron = hStack?.querySelector<HTMLElement>(':scope>label-view')
|
|
847
|
+
// btn.setAttribute('value', extractTagFromOption(node))
|
|
848
|
+
// // if (selection !== btn.getAttribute('value')) chevron?.style.setProperty('visibility', 'hidden')
|
|
849
|
+
// const label = $<LabelView>(`<label-view></label-view>`, '>1')
|
|
850
|
+
// renderLabelTitle(label, extractLabel(node)) // label.querySelector('span')!.textContent = extractCurrentValueFromOption(node) //label.setAttribute('title', extractCurrentValueFromOption(node))
|
|
851
|
+
// renderLabelIcon(label, extractIcon(node))
|
|
852
|
+
// hStack?.appendChild(label)
|
|
853
|
+
return mount.firstElementChild; //btn
|
|
799
854
|
}
|
|
800
855
|
static #wrapOptgroupTag(node) {
|
|
801
856
|
if (devFlags.debug)
|
|
802
857
|
console.debug(`${_a.name} #wrapOptgroupTag`);
|
|
803
|
-
const
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
858
|
+
const title = extractLabel(node), subtitle = extractSubtitle(node), icon = extractIcon(node);
|
|
859
|
+
const mount = document.createElement('div');
|
|
860
|
+
render(html `<details is="disclosure-group" disclosure-style="marker-trailing">
|
|
861
|
+
<summary>
|
|
862
|
+
<h-stack distribution="leading" template="auto spacer">
|
|
863
|
+
<label-view data-role="check" style="visibility: hidden">
|
|
864
|
+
<image-view slot="icon" system-name="check"></image-view>
|
|
865
|
+
</label-view>
|
|
866
|
+
<h-stack distribution="fill" template="${icon ? 'auto spacer' : null}">
|
|
867
|
+
${icon ? html `<label-view system-image="${icon}"></label-view>` : null}
|
|
868
|
+
<v-stack spacing="3" alignment="fill">
|
|
869
|
+
<label-view title="${title}"></label-view>
|
|
870
|
+
${subtitle ? html `<label-view foreground="secondary" font="callout" title="${subtitle}"></label-view>` : null}
|
|
871
|
+
</v-stack>
|
|
872
|
+
</h-stack>
|
|
873
|
+
</h-stack>
|
|
874
|
+
</summary>
|
|
875
|
+
</details>`, mount);
|
|
876
|
+
return mount.firstElementChild;
|
|
877
|
+
// const labelT = `<label-view><span></span></label-view>`,
|
|
878
|
+
// summaryT = `<summary><h-stack distribution="leading" template="auto spacer"><label-view data-role="check" style="visibility: hidden"><image-view slot="icon" system-name="check"></image-view></label-view>${labelT}</h-stack></summary>`
|
|
879
|
+
// const group = $(`<details is="disclosure-group" disclosure-style="marker-trailing">${summaryT}</details>`, '>1'), // NOTE: already applied, here it covers spawned sheets
|
|
880
|
+
// hStack = group.querySelector(':scope>summary>h-stack') ?? undefined // ?? group.appendChild($(summaryT, '>1'))
|
|
881
|
+
// // summaryLabel = summary.querySelector(':scope>label-view') ?? summary.appendChild($(labelT, '>1'))
|
|
882
|
+
// // if (node.hasAttribute('label')) summaryLabel.setAttribute('title', node.getAttribute('label') ?? '')
|
|
883
|
+
// // if (node.hasAttribute('data-system-image')) summaryLabel.setAttribute('system-image', node.getAttribute('data-system-image') ?? '')
|
|
884
|
+
// renderLabel(':scope>label-view:nth-child(2)', labelT, hStack, extractLabel(node), extractIcon(node))
|
|
885
|
+
// return group
|
|
811
886
|
}
|
|
812
887
|
// static #reflectButtons(nodes: Element[], container: Element): void
|
|
813
888
|
// static #reflectButtons(nodes: Dictionary, container: Element): void
|
|
@@ -818,11 +893,32 @@ export class PickerView extends FormAssociatedBase {
|
|
|
818
893
|
if (node instanceof Element)
|
|
819
894
|
switch (node.tagName) {
|
|
820
895
|
case 'DATALIST': {
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
896
|
+
const title = extractLabel(node), subtitle = extractSubtitle(node), icon = extractIcon(node);
|
|
897
|
+
const mount = document.createElement('div');
|
|
898
|
+
render(html `<menu-view tabindex="0">
|
|
899
|
+
<h-stack slot="label" distribution="leading" template="auto spacer">
|
|
900
|
+
<label-view data-role="check" style="visibility: hidden">
|
|
901
|
+
<image-view slot="icon" system-name="check"></image-view>
|
|
902
|
+
</label-view>
|
|
903
|
+
<h-stack distribution="fill" template="${icon ? 'auto spacer' : null}">
|
|
904
|
+
${icon ? html `<label-view system-image="${icon}"></label-view>` : null}
|
|
905
|
+
<v-stack spacing="3" alignment="fill">
|
|
906
|
+
<label-view title="${title}"></label-view>
|
|
907
|
+
${subtitle ? html `<label-view foreground="secondary" font="callout" title="${subtitle}"></label-view>` : null}
|
|
908
|
+
</v-stack>
|
|
909
|
+
</h-stack>
|
|
910
|
+
</h-stack>
|
|
911
|
+
</menu-view>`, mount);
|
|
912
|
+
const group = mount.firstElementChild;
|
|
913
|
+
// const group = $(
|
|
914
|
+
// `<menu-view tabindex="0"><h-stack slot="label" distribution="leading" template="auto spacer"><label-view data-role="check" style="visibility: hidden"><image-view slot="icon" system-name="check"></image-view></label-view><label-view><span></span></label-view></h-stack></menu-view>`,
|
|
915
|
+
// '>1'
|
|
916
|
+
// ),
|
|
917
|
+
// hStack = group.querySelector(':scope>h-stack[slot=label]') ?? undefined
|
|
918
|
+
// // label = group.querySelector(':scope>label-view[slot=label]') ?? group.appendChild($(`<label-view slot="label"></label-view>`, '>1'))
|
|
919
|
+
// // if (node.hasAttribute('data-label')) label.setAttribute('title', node.getAttribute('data-label') ?? '')
|
|
920
|
+
// // if (node.hasAttribute('data-system-image')) label.setAttribute('system-image', node.getAttribute('data-system-image') ?? '')
|
|
921
|
+
// renderLabel(':scope>label-view:nth-child(2)', `<label-view><span></span></label-view>`, hStack, extractLabel(node as HTMLDataListElement), extractIcon(node as HTMLDataListElement))
|
|
826
922
|
_a.#reflectButtons([...node.children], group);
|
|
827
923
|
container.appendChild(group);
|
|
828
924
|
break;
|
|
@@ -847,8 +943,25 @@ export class PickerView extends FormAssociatedBase {
|
|
|
847
943
|
container.appendChild(group);
|
|
848
944
|
}
|
|
849
945
|
else {
|
|
850
|
-
const
|
|
851
|
-
|
|
946
|
+
const title = extractLabel(node), subtitle = extractSubtitle(node), icon = extractIcon(node);
|
|
947
|
+
const mount = document.createElement('div');
|
|
948
|
+
render(html `<menu-view tabindex="0">
|
|
949
|
+
<h-stack slot="label" distribution="leading" template="auto spacer">
|
|
950
|
+
<label-view data-role="check" style="visibility: hidden">
|
|
951
|
+
<image-view slot="icon" system-name="check"></image-view>
|
|
952
|
+
</label-view>
|
|
953
|
+
<h-stack distribution="fill" template="${icon ? 'auto spacer' : null}">
|
|
954
|
+
${icon ? html `<label-view system-image="${icon}"></label-view>` : null}
|
|
955
|
+
<v-stack spacing="3" alignment="fill">
|
|
956
|
+
<label-view title="${title}"></label-view>
|
|
957
|
+
${subtitle ? html `<label-view foreground="secondary" font="callout" title="${subtitle}"></label-view>` : null}
|
|
958
|
+
</v-stack>
|
|
959
|
+
</h-stack>
|
|
960
|
+
</h-stack>
|
|
961
|
+
</menu-view>`, mount);
|
|
962
|
+
const group = mount.firstElementChild;
|
|
963
|
+
// const group = $(`<menu-view tabindex="0"></menu-view>`, '>1')
|
|
964
|
+
// renderLabel(':scope>label-view[slot=label]', `<label-view slot="label"><span></span></label-view>`, group, extractLabel(node), extractIcon(node))
|
|
852
965
|
_a.#reflectButtons(node.children, group);
|
|
853
966
|
container.appendChild(group);
|
|
854
967
|
}
|
|
@@ -876,9 +989,7 @@ export class PickerView extends FormAssociatedBase {
|
|
|
876
989
|
self.requestAnimationFrame(() => {
|
|
877
990
|
this.ariaCurrent = this.#selection;
|
|
878
991
|
const groupMap = indexGroups(this.#lastIndexedRoot);
|
|
879
|
-
const groupContainsSelection = (source) => source instanceof Element
|
|
880
|
-
? [...source.querySelectorAll('option')].some((opt) => extractTagFromOption(opt) === this.#selection)
|
|
881
|
-
: collectLeafValues(source).includes(this.#selection);
|
|
992
|
+
const groupContainsSelection = (source) => source instanceof Element ? [...source.querySelectorAll('option')].some((opt) => extractTag(opt) === this.#selection) : collectLeafValues(source).includes(this.#selection);
|
|
882
993
|
const syncButtons = (root) => {
|
|
883
994
|
// 1. plain value buttons — unchanged
|
|
884
995
|
for (const el of root.querySelectorAll('button[value]:not([slot])'))
|
|
@@ -914,22 +1025,20 @@ export class PickerView extends FormAssociatedBase {
|
|
|
914
1025
|
const currentValueLabel = this.querySelector(':scope>label-view:not([slot])');
|
|
915
1026
|
if (!currentValueLabel)
|
|
916
1027
|
break;
|
|
917
|
-
const cvl = this.#currentValueLabel, cvi = this.#currentValueIcon;
|
|
918
1028
|
// if (!cvl) currentValueLabel.setAttribute('foreground', 'secondary')
|
|
919
1029
|
// else currentValueLabel.removeAttribute('foreground')
|
|
920
|
-
renderLabelTitle(currentValueLabel,
|
|
921
|
-
renderLabelIcon(currentValueLabel,
|
|
1030
|
+
renderLabelTitle(currentValueLabel, this.#currentValueLabel || this.#selection || this.getAttribute(this.constructor.ATTR.PLACEHOLDER));
|
|
1031
|
+
renderLabelIcon(currentValueLabel, this.#currentValueIcon || this.getAttribute(this.constructor.ATTR.PLACEHOLDER_ICON));
|
|
922
1032
|
break;
|
|
923
1033
|
}
|
|
924
1034
|
case 'menu': {
|
|
925
1035
|
const currentValueLabel = this.querySelector(':scope>menu-view:not([slot])>label-view[slot=label]');
|
|
926
1036
|
if (!currentValueLabel)
|
|
927
1037
|
break;
|
|
928
|
-
const cvl = this.#currentValueLabel, cvi = this.#currentValueIcon;
|
|
929
1038
|
// if (!cvl) currentValueLabel.setAttribute('foreground', 'secondary')
|
|
930
1039
|
// else currentValueLabel.removeAttribute('foreground')
|
|
931
|
-
renderLabelTitle(currentValueLabel,
|
|
932
|
-
renderLabelIcon(currentValueLabel,
|
|
1040
|
+
renderLabelTitle(currentValueLabel, this.#currentValueLabel || this.#selection || this.getAttribute(this.constructor.ATTR.PLACEHOLDER));
|
|
1041
|
+
renderLabelIcon(currentValueLabel, this.#currentValueIcon || this.getAttribute(this.constructor.ATTR.PLACEHOLDER_ICON));
|
|
933
1042
|
break;
|
|
934
1043
|
}
|
|
935
1044
|
case 'inline':
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { ScrollViewEventMap } from '../events';
|
|
2
|
+
import type { TypedEventTargetMethods } from '../namespace-browser/event';
|
|
1
3
|
export declare class ScrollView extends HTMLElement {
|
|
2
4
|
#private;
|
|
5
|
+
addEventListener: TypedEventTargetMethods<ScrollViewEventMap>['addEventListener'];
|
|
6
|
+
removeEventListener: TypedEventTargetMethods<ScrollViewEventMap>['removeEventListener'];
|
|
3
7
|
static get observedAttributes(): string[];
|
|
4
8
|
static get template(): DocumentFragment;
|
|
5
9
|
constructor();
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { TextFieldEventMap } from '../events';
|
|
1
2
|
import { FormAssociatedBase } from '../internal/class/form-associated-base';
|
|
3
|
+
import type { TypedEventTargetMethods } from '../namespace-browser/event';
|
|
2
4
|
declare const keyboardTypes: readonly ["decimal-pad", "number-pad", "default"];
|
|
3
5
|
export type KeyboardType = (typeof keyboardTypes)[number];
|
|
4
6
|
/**
|
|
@@ -7,6 +9,8 @@ export type KeyboardType = (typeof keyboardTypes)[number];
|
|
|
7
9
|
*/
|
|
8
10
|
export declare class TextField extends FormAssociatedBase {
|
|
9
11
|
#private;
|
|
12
|
+
addEventListener: TypedEventTargetMethods<TextFieldEventMap>['addEventListener'];
|
|
13
|
+
removeEventListener: TypedEventTargetMethods<TextFieldEventMap>['removeEventListener'];
|
|
10
14
|
static get observedAttributes(): string[];
|
|
11
15
|
static get template(): DocumentFragment;
|
|
12
16
|
constructor();
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { ToggleViewEventMap } from '../events';
|
|
1
2
|
import { FormAssociatedBase } from '../internal/class/form-associated-base';
|
|
3
|
+
import type { TypedEventTargetMethods } from '../namespace-browser/event';
|
|
2
4
|
declare const toggleStyles: readonly ["switch", "button"];
|
|
3
5
|
export type ToggleStyle = (typeof toggleStyles)[number];
|
|
4
6
|
/**
|
|
@@ -7,6 +9,8 @@ export type ToggleStyle = (typeof toggleStyles)[number];
|
|
|
7
9
|
*/
|
|
8
10
|
export declare class ToggleView extends FormAssociatedBase {
|
|
9
11
|
#private;
|
|
12
|
+
addEventListener: TypedEventTargetMethods<ToggleViewEventMap>['addEventListener'];
|
|
13
|
+
removeEventListener: TypedEventTargetMethods<ToggleViewEventMap>['removeEventListener'];
|
|
10
14
|
static get observedAttributes(): string[];
|
|
11
15
|
static get template(): DocumentFragment;
|
|
12
16
|
constructor();
|
|
@@ -82,7 +82,7 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
82
82
|
this.#sendValueToForm(this.#connected);
|
|
83
83
|
break;
|
|
84
84
|
case 'label':
|
|
85
|
-
renderLabel(':scope>label-view[slot=label]', `<label-view slot="label"
|
|
85
|
+
renderLabel(':scope>label-view[slot=label]', `<label-view slot="label"><span></span></label-view>`, this, newValue);
|
|
86
86
|
break;
|
|
87
87
|
case 'disabled':
|
|
88
88
|
for (const el of this.#shadowRoot.querySelectorAll('input'))
|
|
@@ -2,9 +2,7 @@ import { type ScrollView } from '../components';
|
|
|
2
2
|
export type PageRevealSwapDetail = {
|
|
3
3
|
page: ScrollView;
|
|
4
4
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
pageswap: CustomEvent<PageRevealSwapDetail>;
|
|
9
|
-
}
|
|
5
|
+
export interface ScrollViewEventMap {
|
|
6
|
+
pagereveal: CustomEvent<PageRevealSwapDetail>;
|
|
7
|
+
pageswap: CustomEvent<PageRevealSwapDetail>;
|
|
10
8
|
}
|
|
@@ -2,8 +2,6 @@ export type ToggleChangeDetail = {
|
|
|
2
2
|
isOn: boolean;
|
|
3
3
|
value: string | null;
|
|
4
4
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
change: CustomEvent<ToggleChangeDetail>;
|
|
8
|
-
}
|
|
5
|
+
export interface ToggleViewEventMap {
|
|
6
|
+
commit: CustomEvent<ToggleChangeDetail>;
|
|
9
7
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TypedEventTargetMethods<M> {
|
|
2
|
+
addEventListener: {
|
|
3
|
+
<K extends keyof M>(type: K, listener: (this: HTMLElement, ev: M[K] extends Event ? M[K] : never) => void, options?: boolean | AddEventListenerOptions): void;
|
|
4
|
+
(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
+
};
|
|
6
|
+
removeEventListener: {
|
|
7
|
+
<K extends keyof M>(type: K, listener: (this: HTMLElement, ev: M[K] extends Event ? M[K] : never) => void, options?: boolean | EventListenerOptions): void;
|
|
8
|
+
(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|