@fusion.dev/helix-headless 0.146.0 → 0.147.0
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/custom-elements.json +5266 -785
- package/dist/accordion/item/accordion-item.d.ts +38 -19
- package/dist/accordion/item/accordion-item.js +31 -9
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +13 -4
- package/dist/announcement/root/announcement-root.js +34 -6
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +11 -3
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +88 -5
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/chat/root/chat-root.d.ts +15 -1
- package/dist/chat/root/chat-root.js +11 -2
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.js +4 -3
- package/dist/checkbox-group/select-all.d.ts +0 -6
- package/dist/checkbox-group/select-all.js +0 -5
- package/dist/code-block/root/code-block-root.d.ts +35 -14
- package/dist/code-block/root/code-block-root.js +17 -3
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +101 -51
- package/dist/color-picker/wheel.d.ts +17 -0
- package/dist/color-picker/wheel.js +6 -0
- package/dist/combobox/root/combobox-root.d.ts +13 -0
- package/dist/combobox/root/combobox-root.js +14 -1
- package/dist/command/root/command-root.d.ts +3 -1
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +13 -7
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +18 -4
- package/dist/description-list/item/description-list-item.js +8 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +39 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +4 -1
- package/dist/empty/root/empty-root.d.ts +31 -1
- package/dist/empty/root/empty-root.js +26 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +54 -19
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +10 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +11 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/options.d.ts +3 -4
- package/dist/format-date/options.js +2 -2
- package/dist/format-date/root/format-date-root.d.ts +18 -1
- package/dist/format-date/root/format-date-root.js +19 -23
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +64 -3
- package/dist/heatmap/root/heatmap-root.js +89 -19
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +9 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +24 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +22 -10
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +26 -5
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +9 -5
- package/dist/listbox/root/listbox-root.js +29 -37
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +36 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +3 -0
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/notifications/root/notifications-root.d.ts +10 -1
- package/dist/notifications/root/notifications-root.js +11 -1
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +13 -6
- package/dist/object-inspector/root/object-inspector-root.js +18 -17
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +5 -0
- package/dist/pagination/size/pagination-size.js +4 -2
- package/dist/pin-input/code.d.ts +28 -1
- package/dist/pin-input/code.js +12 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +157 -148
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +17 -6
- package/dist/qr-code/root/qr-code-root.js +10 -12
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +30 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +34 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +59 -3
- package/dist/select/root/select-root.js +72 -12
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
- package/dist/speed-dial/item/speed-dial-item.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
- package/dist/speed-dial/root/speed-dial-root.js +9 -1
- package/dist/splitter/root/splitter-root.d.ts +3 -0
- package/dist/splitter/root/splitter-root.js +2 -0
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/root/table-root.js +13 -6
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +19 -7
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +11 -14
- package/dist/time-picker/root/time-picker-root.js +15 -23
- package/dist/toast/item/toast-item.d.ts +3 -3
- package/dist/toast/item/toast-item.js +0 -1
- package/dist/toast/root/toast-root.d.ts +28 -4
- package/dist/toast/root/toast-root.js +58 -12
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -41
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +21 -5
- package/dist/toolbar/root/toolbar-root.js +52 -8
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -1
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +5 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +48 -24
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2979 -738
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +619 -202
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -16,24 +16,41 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
16
16
|
this.focusable = false;
|
|
17
17
|
this.isDrilldownItem = true;
|
|
18
18
|
this.onPage = true;
|
|
19
|
+
this.onPath = false;
|
|
19
20
|
this.showingPage = false;
|
|
20
21
|
this.value = '';
|
|
21
22
|
this.page = false;
|
|
23
|
+
this.description = false;
|
|
24
|
+
this.end = false;
|
|
22
25
|
this.readPage = () => {
|
|
23
26
|
const slot = this.renderRoot.querySelector('slot[name="page"]');
|
|
24
27
|
this.page = (slot?.assignedElements().length ?? 0) > 0;
|
|
25
28
|
};
|
|
29
|
+
this.readWords = () => {
|
|
30
|
+
const slot = (name) => this.renderRoot.querySelector(`slot[name="${name}"]`);
|
|
31
|
+
this.description = slotFilled(slot('description'));
|
|
32
|
+
this.end = slotFilled(slot('end'));
|
|
33
|
+
};
|
|
26
34
|
}
|
|
27
35
|
willUpdate(changed) {
|
|
28
36
|
super.willUpdate(changed);
|
|
29
37
|
if (this.childrenKnown) {
|
|
30
|
-
|
|
38
|
+
const named = (name) => this.knownChildren.some((child) => child.slot === name);
|
|
39
|
+
this.page = named('page');
|
|
40
|
+
this.description = named('description');
|
|
41
|
+
this.end = named('end');
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
44
|
firstUpdated(changed) {
|
|
34
45
|
super.firstUpdated(changed);
|
|
35
46
|
this.finishHydration();
|
|
36
47
|
}
|
|
48
|
+
get describedBy() {
|
|
49
|
+
const ids = [this.description ? 'description' : '', this.end ? 'end' : '']
|
|
50
|
+
.filter((id) => id !== '')
|
|
51
|
+
.join(' ');
|
|
52
|
+
return ids === '' ? nothing : ids;
|
|
53
|
+
}
|
|
37
54
|
focusItem() {
|
|
38
55
|
this.partNamed('item')?.focus();
|
|
39
56
|
}
|
|
@@ -58,7 +75,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
58
75
|
>`;
|
|
59
76
|
}
|
|
60
77
|
render() {
|
|
61
|
-
if (this.showingPage) {
|
|
78
|
+
if (this.showingPage || this.onPath) {
|
|
62
79
|
return html `<slot name="page" @slotchange=${this.readPage}></slot>`;
|
|
63
80
|
}
|
|
64
81
|
if (!this.onPage) {
|
|
@@ -68,14 +85,23 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
68
85
|
part="item"
|
|
69
86
|
type="button"
|
|
70
87
|
role="menuitem"
|
|
88
|
+
aria-describedby=${this.describedBy}
|
|
71
89
|
aria-disabled=${this.disabled ? 'true' : nothing}
|
|
72
90
|
aria-haspopup=${this.page ? 'menu' : nothing}
|
|
73
91
|
tabindex=${this.focusable ? '0' : '-1'}
|
|
92
|
+
?data-described=${this.description}
|
|
74
93
|
@click=${() => this.select()}
|
|
75
94
|
>
|
|
76
95
|
<slot name="start"></slot>
|
|
77
96
|
<span part="label"><slot></slot></span>
|
|
78
|
-
<slot
|
|
97
|
+
<slot
|
|
98
|
+
id="description"
|
|
99
|
+
name="description"
|
|
100
|
+
aria-hidden="true"
|
|
101
|
+
?data-empty=${!this.description}
|
|
102
|
+
@slotchange=${this.readWords}
|
|
103
|
+
></slot>
|
|
104
|
+
<slot id="end" name="end" aria-hidden="true" @slotchange=${this.readWords}></slot>
|
|
79
105
|
${this.page ? this.renderMark() : nothing}
|
|
80
106
|
</button>
|
|
81
107
|
<div hidden><slot name="page" @slotchange=${this.readPage}></slot></div>`;
|
|
@@ -90,6 +116,9 @@ __decorate([
|
|
|
90
116
|
__decorate([
|
|
91
117
|
property({ attribute: false })
|
|
92
118
|
], HelixHeadlessDrilldownItem.prototype, "onPage", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
property({ attribute: false })
|
|
121
|
+
], HelixHeadlessDrilldownItem.prototype, "onPath", void 0);
|
|
93
122
|
__decorate([
|
|
94
123
|
property({ attribute: false })
|
|
95
124
|
], HelixHeadlessDrilldownItem.prototype, "showingPage", void 0);
|
|
@@ -99,6 +128,12 @@ __decorate([
|
|
|
99
128
|
__decorate([
|
|
100
129
|
state()
|
|
101
130
|
], HelixHeadlessDrilldownItem.prototype, "page", void 0);
|
|
131
|
+
__decorate([
|
|
132
|
+
state()
|
|
133
|
+
], HelixHeadlessDrilldownItem.prototype, "description", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
state()
|
|
136
|
+
], HelixHeadlessDrilldownItem.prototype, "end", void 0);
|
|
102
137
|
HelixHeadlessDrilldownItem = __decorate([
|
|
103
138
|
customElement('helix-headless-drilldown-item')
|
|
104
139
|
], HelixHeadlessDrilldownItem);
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords,
|
|
7
|
+
import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadByWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -38,7 +38,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
38
38
|
})),
|
|
39
39
|
reserved: () => ['ArrowLeft', 'ArrowRight'],
|
|
40
40
|
selects: () => false,
|
|
41
|
-
typeahead:
|
|
41
|
+
typeahead: typeaheadByWords(),
|
|
42
42
|
});
|
|
43
43
|
this.handleFocusIn = (event) => {
|
|
44
44
|
const item = this.drilldown.rows.find((row) => row.contains(event.target));
|
|
@@ -162,6 +162,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
162
162
|
mark(item, page, onPage) {
|
|
163
163
|
item.onPage = onPage;
|
|
164
164
|
item.showingPage = item === page;
|
|
165
|
+
item.onPath = page !== null && item !== page && item.contains(page);
|
|
165
166
|
for (const child of item.children) {
|
|
166
167
|
if (child instanceof HelixHeadlessDrilldownItem && child.slot === 'page') {
|
|
167
168
|
this.mark(child, page, item === page);
|
|
@@ -115,7 +115,7 @@ registerElementEvents({
|
|
|
115
115
|
'helix-graph-signal',
|
|
116
116
|
'helix-graph-zoom',
|
|
117
117
|
],
|
|
118
|
-
'helix-headless-heatmap': ['helix-resize'],
|
|
118
|
+
'helix-headless-heatmap': ['change', 'helix-before-change', 'helix-resize'],
|
|
119
119
|
'helix-headless-icon': ['error', 'load'],
|
|
120
120
|
'helix-headless-icon-button': ['helix-press'],
|
|
121
121
|
'helix-headless-image': ['error', 'load'],
|
|
@@ -166,6 +166,7 @@ registerElementEvents({
|
|
|
166
166
|
'helix-headless-megamenu': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
167
167
|
'helix-headless-menu': ['helix-before-close', 'helix-before-open', 'helix-select', 'toggle'],
|
|
168
168
|
'helix-headless-menu-item': ['helix-before-toggle', 'helix-select'],
|
|
169
|
+
'helix-headless-meter': ['helix-band'],
|
|
169
170
|
'helix-headless-notification': ['helix-dismiss', 'helix-read'],
|
|
170
171
|
'helix-headless-notification-group': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
171
172
|
'helix-headless-notifications': ['helix-dismiss', 'helix-load-more', 'helix-read'],
|
|
@@ -186,6 +187,7 @@ registerElementEvents({
|
|
|
186
187
|
'helix-headless-pagination-size': ['change', 'helix-before-change', 'input'],
|
|
187
188
|
'helix-headless-pin-input': ['change', 'helix-before-change', 'helix-complete', 'input'],
|
|
188
189
|
'helix-headless-popover': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
190
|
+
'helix-headless-progress': ['helix-complete'],
|
|
189
191
|
'helix-headless-qr-code': ['error'],
|
|
190
192
|
'helix-headless-radio': ['helix-select'],
|
|
191
193
|
'helix-headless-radio-group': ['change', 'helix-before-change', 'helix-select', 'input'],
|
|
@@ -220,6 +222,7 @@ registerElementEvents({
|
|
|
220
222
|
'helix-before-resize',
|
|
221
223
|
'helix-collapse',
|
|
222
224
|
'helix-resized',
|
|
225
|
+
'input',
|
|
223
226
|
],
|
|
224
227
|
'helix-headless-step': ['helix-select'],
|
|
225
228
|
'helix-headless-steps': ['helix-activate', 'helix-before-activate', 'helix-select'],
|
|
@@ -19,6 +19,11 @@ import { type TemplateResult } from 'lit';
|
|
|
19
19
|
* `empty-state-actions` element: assign your own heading and actions to the
|
|
20
20
|
* slots.
|
|
21
21
|
*
|
|
22
|
+
* **Or give the heading as words.** `heading` draws them in a `heading` part
|
|
23
|
+
* that is a heading at `heading-level`, 3 where it is not set, so a page
|
|
24
|
+
* rendering from data or on a server gets a heading a reader finds in the
|
|
25
|
+
* outline without writing the element. A heading slotted in replaces it.
|
|
26
|
+
*
|
|
22
27
|
* @since 0.1.0
|
|
23
28
|
* @status stable
|
|
24
29
|
* @category feedback
|
|
@@ -27,12 +32,27 @@ import { type TemplateResult } from 'lit';
|
|
|
27
32
|
*
|
|
28
33
|
* @slot - The message: why the region is empty, and what to do about it.
|
|
29
34
|
* @slot actions - The action that would put something in the region.
|
|
30
|
-
* @slot heading - The heading, which names what is missing. Slot a heading element, such as an `<h3>`, so a reader can find it in the page's outline.
|
|
35
|
+
* @slot heading - The heading, which names what is missing. Slot a heading element, such as an `<h3>`, so a reader can find it in the page's outline. Replaces the one `heading` draws.
|
|
31
36
|
* @slot icon - An icon above the heading.
|
|
32
37
|
*
|
|
38
|
+
* @csspart heading - The heading `heading` draws, a heading at `heading-level`. Drawn only while `heading` holds words and nothing is slotted into `heading`.
|
|
33
39
|
* @csspart live - A copy of the heading and the message, in a live region that screen readers announce when the view appears. Visually hidden in the styled tier.
|
|
34
40
|
*/
|
|
35
41
|
export declare class HelixHeadlessEmpty extends HelixElement {
|
|
42
|
+
/**
|
|
43
|
+
* The heading as words, such as "No results", drawn as a heading when
|
|
44
|
+
* nothing is slotted into `heading`.
|
|
45
|
+
*
|
|
46
|
+
* Absent draws none, and the `heading` slot is the only heading.
|
|
47
|
+
*/
|
|
48
|
+
heading: string;
|
|
49
|
+
/**
|
|
50
|
+
* The level of the heading `heading` draws, from 1 to 6.
|
|
51
|
+
*
|
|
52
|
+
* Absent is 3, the level of a heading inside a page's section. Set it to fit
|
|
53
|
+
* the outline the empty view sits in. A slotted heading keeps its own.
|
|
54
|
+
*/
|
|
55
|
+
headingLevel?: number;
|
|
36
56
|
/**
|
|
37
57
|
* Whether the state is announced when it appears.
|
|
38
58
|
*
|
|
@@ -42,6 +62,16 @@ export declare class HelixHeadlessEmpty extends HelixElement {
|
|
|
42
62
|
*/
|
|
43
63
|
noAnnounce: boolean;
|
|
44
64
|
protected readonly arrival: ArrivalController;
|
|
65
|
+
/**
|
|
66
|
+
* The `heading` slot, with the heading `heading` draws as its fallback, so
|
|
67
|
+
* one slotted in replaces it; no fallback while `heading` holds no words.
|
|
68
|
+
*
|
|
69
|
+
* A method, so a tier above can draw its own, as the slot lets a page.
|
|
70
|
+
*
|
|
71
|
+
* @param hidden Whether the live copy holds the heading's words, which
|
|
72
|
+
* hides them from readers until it empties.
|
|
73
|
+
*/
|
|
74
|
+
protected renderHeading(hidden: boolean): TemplateResult;
|
|
45
75
|
protected render(): TemplateResult;
|
|
46
76
|
}
|
|
47
77
|
declare global {
|
|
@@ -4,30 +4,51 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { ArrivalController, customElement, HelixElement, slottedWords, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ArrivalController, customElement, HelixElement, headingLevel, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
|
+
this.heading = '';
|
|
13
14
|
this.noAnnounce = false;
|
|
14
15
|
this.arrival = new ArrivalController(this, {
|
|
15
16
|
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
16
|
-
text: () => slottedWords(this, ['heading', ''])
|
|
17
|
+
text: () => [slottedWords(this, ['heading']) || this.heading.trim(), slottedWords(this, [''])]
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.join(' '),
|
|
17
20
|
});
|
|
18
21
|
}
|
|
22
|
+
renderHeading(hidden) {
|
|
23
|
+
return html `<slot
|
|
24
|
+
aria-hidden=${hidden ? 'true' : nothing}
|
|
25
|
+
name="heading"
|
|
26
|
+
@slotchange=${() => this.arrival.say()}
|
|
27
|
+
>${this.heading.trim()
|
|
28
|
+
? html `<div aria-level=${headingLevel(this.headingLevel)} part="heading" role="heading">
|
|
29
|
+
${this.heading}
|
|
30
|
+
</div>`
|
|
31
|
+
: nothing}</slot
|
|
32
|
+
>`;
|
|
33
|
+
}
|
|
19
34
|
render() {
|
|
20
35
|
const say = () => this.arrival.say();
|
|
21
|
-
const
|
|
36
|
+
const held = this.arrival.said !== '' && !this.noAnnounce;
|
|
22
37
|
return html `<slot name="icon"></slot>
|
|
23
|
-
|
|
24
|
-
<slot aria-hidden=${
|
|
38
|
+
${this.renderHeading(held)}
|
|
39
|
+
<slot aria-hidden=${held ? 'true' : nothing} @slotchange=${say}></slot>
|
|
25
40
|
<slot name="actions"></slot>
|
|
26
41
|
${this.noAnnounce
|
|
27
42
|
? nothing
|
|
28
43
|
: html `<span part="live" role="status">${this.arrival.said}</span>`}`;
|
|
29
44
|
}
|
|
30
45
|
};
|
|
46
|
+
__decorate([
|
|
47
|
+
property()
|
|
48
|
+
], HelixHeadlessEmpty.prototype, "heading", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
property({ attribute: 'heading-level', type: Number })
|
|
51
|
+
], HelixHeadlessEmpty.prototype, "headingLevel", void 0);
|
|
31
52
|
__decorate([
|
|
32
53
|
property({ attribute: 'no-announce', reflect: true, type: Boolean })
|
|
33
54
|
], HelixHeadlessEmpty.prototype, "noAnnounce", void 0);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AriaForwardController, HelixFormElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
import { type FileStatus } from '../status.js';
|
|
4
|
+
export type { FileStatus } from '../status.js';
|
|
3
5
|
import '../../tag/index.js';
|
|
4
6
|
declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
5
7
|
/**
|
|
@@ -59,6 +61,9 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
|
|
|
59
61
|
* @csspart feedback - The message that says what is wrong.
|
|
60
62
|
* @csspart field - The box you press or drop files on.
|
|
61
63
|
* @csspart file - One chosen file.
|
|
64
|
+
* @csspart file-done - A file whose upload `setFileStatus` says is done. Set together with `file`.
|
|
65
|
+
* @csspart file-error - A file whose upload `setFileStatus` says failed. Set together with `file`.
|
|
66
|
+
* @csspart file-uploading - A file whose upload `setFileStatus` says is under way. Set together with `file`.
|
|
62
67
|
* @csspart hint - Help under the field, while nothing is wrong.
|
|
63
68
|
* @csspart kind - A file's type.
|
|
64
69
|
* @csspart kind-cell - The grid cell around the tag, rendered only when the tag sits in a `Tag.Group`.
|
|
@@ -72,6 +77,7 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
|
|
|
72
77
|
* @csspart live - The live region that says `added-text`, `rejected-text`, and `removed-text`. It is rendered from the first time it has something to say.
|
|
73
78
|
* @csspart meta - The row that holds a file's size and type.
|
|
74
79
|
* @csspart name - A file's name.
|
|
80
|
+
* @csspart progress - A file's upload bar, a `<progress>`, while `setFileStatus` gives it a measure or says it is under way.
|
|
75
81
|
* @csspart remove - The control that removes a file.
|
|
76
82
|
* @csspart size - A file's size.
|
|
77
83
|
* @csspart size-cell - The grid cell around the tag, rendered only when the tag sits in a `Tag.Group`.
|
|
@@ -80,6 +86,8 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
|
|
|
80
86
|
* @csspart size-label - The label, trimmed to its capitals and baseline.
|
|
81
87
|
* @csspart size-link - The link around the label, when the tag has an `href`.
|
|
82
88
|
* @csspart size-start - The category before the label.
|
|
89
|
+
* @csspart status - How a file's upload is going, from `setFileStatus`: the bar and the words.
|
|
90
|
+
* @csspart status-text - The words `setFileStatus` gives a file, such as the reason it failed.
|
|
83
91
|
* @csspart trigger - The label that opens the picker.
|
|
84
92
|
*
|
|
85
93
|
* @cssstate dropping - Files are being dragged over the field.
|
|
@@ -128,6 +136,11 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
|
|
|
128
136
|
* Whether more than one file can be chosen.
|
|
129
137
|
*/
|
|
130
138
|
multiple: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* The name of a file's progress bar, read by screen readers, with `{name}`
|
|
141
|
+
* filled in. A label with no `{name}` has it added after it.
|
|
142
|
+
*/
|
|
143
|
+
progressLabel: string;
|
|
131
144
|
/**
|
|
132
145
|
* What a reader hears when files are refused, with `{count}` and `{names}`
|
|
133
146
|
* filled in.
|
|
@@ -170,6 +183,19 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
|
|
|
170
183
|
validate?: (file: File) => string | null | undefined;
|
|
171
184
|
/** The live region, rendered from the first time it has something to say. */
|
|
172
185
|
private readonly status;
|
|
186
|
+
/** What the page has said of each file's upload, by file. */
|
|
187
|
+
private readonly statuses;
|
|
188
|
+
/**
|
|
189
|
+
* Shows how a file's upload is going, in its row: a bar for `progress`,
|
|
190
|
+
* from 0 to 1, or a bar without a measure while `state` is `uploading`, and
|
|
191
|
+
* `text` beside it. `state` names the row `file-uploading`, `file-done` or
|
|
192
|
+
* `file-error` beside `file`, and a reader hears `text` when the state
|
|
193
|
+
* becomes `done` or `error`. `null` clears it.
|
|
194
|
+
*
|
|
195
|
+
* The field uploads nothing, as Zag's file upload does not: your page sends
|
|
196
|
+
* the file and says here how it is going.
|
|
197
|
+
*/
|
|
198
|
+
setFileStatus(file: File, status: FileStatus | null): void;
|
|
173
199
|
/**
|
|
174
200
|
* Screens arriving files and commits what is taken, after the files the
|
|
175
201
|
* field keeps, through `transformFiles` where it is set.
|
|
@@ -193,10 +219,8 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
|
|
|
193
219
|
* count is written as the language writes a number.
|
|
194
220
|
*/
|
|
195
221
|
private listed;
|
|
196
|
-
/** The element slotted into `remove-icon`,
|
|
197
|
-
private removeIcon;
|
|
198
|
-
/** One copy of `removeIcon` per row, kept so a render does not replace it. */
|
|
199
|
-
private readonly removeIcons;
|
|
222
|
+
/** The element slotted into `remove-icon`, one copy per row's remove button. */
|
|
223
|
+
private readonly removeIcon;
|
|
200
224
|
private readonly handleRemoveIcon;
|
|
201
225
|
/** The icon on one row's remove button: a copy of `remove-icon`, or the bin. */
|
|
202
226
|
private removeMark;
|
|
@@ -342,6 +366,11 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
|
|
|
342
366
|
* renders the styled one from the same template.
|
|
343
367
|
*/
|
|
344
368
|
protected renderMeta(file: File): TemplateResult;
|
|
369
|
+
/**
|
|
370
|
+
* How a file's upload is going, from `setFileStatus`, behind a seam a tier
|
|
371
|
+
* can move: a `<progress>` named by `progress-label` and the status words.
|
|
372
|
+
*/
|
|
373
|
+
protected renderFileStatus(file: File): TemplateResult | typeof nothing;
|
|
345
374
|
protected render(): TemplateResult;
|
|
346
375
|
}
|
|
347
376
|
declare global {
|
|
@@ -349,4 +378,3 @@ declare global {
|
|
|
349
378
|
'helix-headless-file-input': HelixHeadlessFileInput;
|
|
350
379
|
}
|
|
351
380
|
}
|
|
352
|
-
export {};
|
|
@@ -4,12 +4,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, drawIcon, drawStatus, fillTemplate, formatNumbers, HelixBeforeChangeEvent, HelixFormElement, HelixRejectEvent, MixinField, requestChange, restoreValue, StatusController, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, drawIcon, drawStatus, fillTemplate, formatNumbers, HelixBeforeChangeEvent, HelixFormElement, HelixRejectEvent, MixinField, requestChange, restoreValue, SlottedGlyph, StatusController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { trash } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { html } from 'lit/static-html.js';
|
|
12
12
|
import { screenFiles } from '../screen.js';
|
|
13
|
+
import { barOf, saysStatus } from '../status.js';
|
|
13
14
|
import '../../tag/index.js';
|
|
14
15
|
const named = (label, name) => label.includes('{name}') ? fillTemplate(label, { name }) : `${label} ${name}`;
|
|
15
16
|
const size = (bytes, locale) => {
|
|
@@ -46,16 +47,17 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
46
47
|
this.directory = false;
|
|
47
48
|
this.locale = '';
|
|
48
49
|
this.multiple = false;
|
|
50
|
+
this.progressLabel = 'Uploading {name}';
|
|
49
51
|
this.rejectedText = 'Not added: {names}';
|
|
50
52
|
this.removedText = 'Removed: {name}';
|
|
51
53
|
this.removeLabel = 'Remove {name}';
|
|
52
54
|
this.triggerLabel = 'Choose files';
|
|
53
55
|
this.status = new StatusController(this);
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
+
this.statuses = new WeakMap();
|
|
57
|
+
this.removeIcon = new SlottedGlyph();
|
|
56
58
|
this.handleRemoveIcon = (event) => {
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
59
|
+
this.removeIcon.read(event.target);
|
|
60
|
+
this.requestUpdate();
|
|
59
61
|
};
|
|
60
62
|
this.handlePaste = (event) => {
|
|
61
63
|
const pasted = [...(event.clipboardData?.files ?? [])];
|
|
@@ -106,6 +108,19 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
106
108
|
});
|
|
107
109
|
};
|
|
108
110
|
}
|
|
111
|
+
setFileStatus(file, status) {
|
|
112
|
+
const was = this.statuses.get(file);
|
|
113
|
+
if (status) {
|
|
114
|
+
this.statuses.set(file, status);
|
|
115
|
+
if (saysStatus(status, was)) {
|
|
116
|
+
this.status.say(status.text ?? '');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.statuses.delete(file);
|
|
121
|
+
}
|
|
122
|
+
this.requestUpdate();
|
|
123
|
+
}
|
|
109
124
|
take(arriving, keeping, picked = false) {
|
|
110
125
|
const { kept, refused } = screenFiles(arriving, keeping, {
|
|
111
126
|
accept: this.accept,
|
|
@@ -152,12 +167,7 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
152
167
|
});
|
|
153
168
|
}
|
|
154
169
|
removeMark(at) {
|
|
155
|
-
|
|
156
|
-
return drawIcon(trash);
|
|
157
|
-
}
|
|
158
|
-
const held = this.removeIcons.get(at) ?? this.removeIcon.cloneNode(true);
|
|
159
|
-
this.removeIcons.set(at, held);
|
|
160
|
-
return held;
|
|
170
|
+
return this.removeIcon.copyFor(at) ?? drawIcon(trash);
|
|
161
171
|
}
|
|
162
172
|
get files() {
|
|
163
173
|
return [...(this.control?.files ?? [])];
|
|
@@ -258,6 +268,23 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
258
268
|
part="kind"
|
|
259
269
|
exportparts="cell: kind-cell, dismiss: kind-dismiss, dismiss-mark: kind-dismiss-mark, label: kind-label, link: kind-link, start: kind-start">${kind(file)}</${this.tag('tag')}>`;
|
|
260
270
|
}
|
|
271
|
+
renderFileStatus(file) {
|
|
272
|
+
const status = this.statuses.get(file);
|
|
273
|
+
if (!status) {
|
|
274
|
+
return nothing;
|
|
275
|
+
}
|
|
276
|
+
const bar = barOf(status);
|
|
277
|
+
return html `<span part="status"
|
|
278
|
+
>${bar === undefined
|
|
279
|
+
? nothing
|
|
280
|
+
: html `<progress
|
|
281
|
+
part="progress"
|
|
282
|
+
max="1"
|
|
283
|
+
value=${bar === 'unmeasured' ? nothing : bar}
|
|
284
|
+
aria-label=${named(this.progressLabel, file.name)}
|
|
285
|
+
></progress>`}${status.text ? html `<span part="status-text">${status.text}</span>` : nothing}</span
|
|
286
|
+
>`;
|
|
287
|
+
}
|
|
261
288
|
render() {
|
|
262
289
|
const files = this.files;
|
|
263
290
|
return html `${this.renderLabel()}
|
|
@@ -300,14 +327,21 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
300
327
|
${files.length === 0
|
|
301
328
|
? nothing
|
|
302
329
|
: html `<ul part="list">
|
|
303
|
-
${files.map((file, at) =>
|
|
330
|
+
${files.map((file, at) => {
|
|
331
|
+
const state = this.statuses.get(file)?.state;
|
|
332
|
+
const done = state === 'done';
|
|
333
|
+
const failed = state === 'error';
|
|
334
|
+
const sending = state === 'uploading';
|
|
335
|
+
return html `<li
|
|
336
|
+
part="file${done ? ' file-done' : ''}${failed ? ' file-error' : ''}${sending ? ' file-uploading' : ''}"
|
|
337
|
+
>
|
|
304
338
|
<span part="detail">
|
|
305
339
|
${this.renderFile
|
|
306
|
-
|
|
307
|
-
|
|
340
|
+
? this.renderFile(file, at)
|
|
341
|
+
: html `<span part="name">${file.name}</span>
|
|
308
342
|
<span part="meta">
|
|
309
343
|
${this.renderMeta(file)}
|
|
310
|
-
</span>`}
|
|
344
|
+
</span>`}${this.renderFileStatus(file)}
|
|
311
345
|
</span>
|
|
312
346
|
<button
|
|
313
347
|
part="remove"
|
|
@@ -319,7 +353,8 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
319
353
|
>
|
|
320
354
|
${this.removeMark(at)}
|
|
321
355
|
</button>
|
|
322
|
-
</li
|
|
356
|
+
</li>`;
|
|
357
|
+
})}
|
|
323
358
|
</ul>`}`;
|
|
324
359
|
}
|
|
325
360
|
};
|
|
@@ -347,6 +382,9 @@ __decorate([
|
|
|
347
382
|
__decorate([
|
|
348
383
|
property({ reflect: true, type: Boolean })
|
|
349
384
|
], HelixHeadlessFileInput.prototype, "multiple", void 0);
|
|
385
|
+
__decorate([
|
|
386
|
+
property({ attribute: 'progress-label' })
|
|
387
|
+
], HelixHeadlessFileInput.prototype, "progressLabel", void 0);
|
|
350
388
|
__decorate([
|
|
351
389
|
property({ attribute: 'rejected-text' })
|
|
352
390
|
], HelixHeadlessFileInput.prototype, "rejectedText", void 0);
|
|
@@ -368,9 +406,6 @@ __decorate([
|
|
|
368
406
|
__decorate([
|
|
369
407
|
property({ attribute: false })
|
|
370
408
|
], HelixHeadlessFileInput.prototype, "validate", void 0);
|
|
371
|
-
__decorate([
|
|
372
|
-
state()
|
|
373
|
-
], HelixHeadlessFileInput.prototype, "removeIcon", void 0);
|
|
374
409
|
__decorate([
|
|
375
410
|
state()
|
|
376
411
|
], HelixHeadlessFileInput.prototype, "dropping", void 0);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How one file's upload is going, as a page reports it to File Input. The
|
|
3
|
+
* field does not upload anything: the page does, and says how it is going.
|
|
4
|
+
*/
|
|
5
|
+
export interface FileStatus {
|
|
6
|
+
/** How much is done, from 0 to 1. Left out, the bar moves without a measure while `state` is `uploading`. */
|
|
7
|
+
readonly progress?: number | undefined;
|
|
8
|
+
/** Where the upload is: under way, finished, or failed. */
|
|
9
|
+
readonly state?: 'done' | 'error' | 'uploading' | undefined;
|
|
10
|
+
/** Words beside the bar, such as "Uploaded" or the reason it failed. */
|
|
11
|
+
readonly text?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The bar's value, held between 0 and 1, or nothing for a bar without a
|
|
15
|
+
* measure, and no bar at all for a status that is neither measured nor under
|
|
16
|
+
* way.
|
|
17
|
+
*/
|
|
18
|
+
export declare const barOf: (status: FileStatus) => number | 'unmeasured' | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Whether a new status is worth saying: a finish or a failure with words, the
|
|
21
|
+
* first time the file reaches it. Progress is shown and not said, since a
|
|
22
|
+
* reader hearing every percent hears nothing else.
|
|
23
|
+
*/
|
|
24
|
+
export declare const saysStatus: (next: FileStatus, was: FileStatus | undefined) => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const barOf = (status) => {
|
|
2
|
+
const { progress, state } = status;
|
|
3
|
+
if (typeof progress === 'number' && Number.isFinite(progress)) {
|
|
4
|
+
return Math.min(1, Math.max(0, progress));
|
|
5
|
+
}
|
|
6
|
+
return state === 'uploading' ? 'unmeasured' : undefined;
|
|
7
|
+
};
|
|
8
|
+
export const saysStatus = (next, was) => Boolean(next.text) &&
|
|
9
|
+
(next.state === 'done' || next.state === 'error') &&
|
|
10
|
+
next.state !== was?.state;
|
|
@@ -27,6 +27,15 @@ declare const HelixHeadlessFilterChip_base: (new (...args: any[]) => import("@fu
|
|
|
27
27
|
* dismissal, which is also how you take control of the interaction for one
|
|
28
28
|
* press. `requestChange` documents the pattern.
|
|
29
29
|
*
|
|
30
|
+
* **Keyboard.** The remove button is a tab stop of its own, and Enter or Space
|
|
31
|
+
* on it asks to remove the filter. In a `FilterInput`, Backspace in the empty
|
|
32
|
+
* field asks to remove the last chip.
|
|
33
|
+
*
|
|
34
|
+
* The remove button is named `dismiss-label` followed by the chip's words,
|
|
35
|
+
* such as "Remove filter Status is not open", so a row of chips says which
|
|
36
|
+
* filter each button removes. Write `{label}` in `dismiss-label` to put the
|
|
37
|
+
* words elsewhere.
|
|
38
|
+
*
|
|
30
39
|
* To let the user change the operator, slot a menu trigger into `operator`.
|
|
31
40
|
* With the text fallback, the operator is a label. The chip does not interpret
|
|
32
41
|
* operators: their meaning belongs to your domain, as `FilterOperator`
|
|
@@ -100,6 +109,20 @@ export declare class HelixHeadlessFilterChip extends HelixHeadlessFilterChip_bas
|
|
|
100
109
|
* makes an unusual filter look unusual.
|
|
101
110
|
*/
|
|
102
111
|
operatorLabel: string;
|
|
112
|
+
/**
|
|
113
|
+
* The remove button's name: `dismissLabel` with the chip's words, its field,
|
|
114
|
+
* its comparison and its values, such as "Remove filter Status is not open".
|
|
115
|
+
*
|
|
116
|
+
* **Named for its chip**, as File Input names each remove button for its
|
|
117
|
+
* file: a row of buttons each called "Remove filter" says nothing about
|
|
118
|
+
* which filter each one takes away. `{label}` in `dismiss-label` says where
|
|
119
|
+
* the words go, and without it they follow the label.
|
|
120
|
+
*
|
|
121
|
+
* Each word is read from what is slotted and otherwise from `label` and
|
|
122
|
+
* `operator-label`, which is all a server and a hydrating render can read,
|
|
123
|
+
* so the values join the update after.
|
|
124
|
+
*/
|
|
125
|
+
private get removeName();
|
|
103
126
|
protected firstUpdated(changed: PropertyValues): void;
|
|
104
127
|
protected render(): TemplateResult;
|
|
105
128
|
}
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, MixinDismissible } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, MixinDismissible, slottedWords } from '@fusion.dev/helix-core';
|
|
8
8
|
import { x } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -16,8 +16,17 @@ let HelixHeadlessFilterChip = class HelixHeadlessFilterChip extends MixinDismiss
|
|
|
16
16
|
this.label = '';
|
|
17
17
|
this.operatorLabel = '';
|
|
18
18
|
}
|
|
19
|
+
get removeName() {
|
|
20
|
+
const read = (slot, fallback) => (this.childrenKnown && slottedWords(this, [slot])) || fallback;
|
|
21
|
+
const words = [read('field', this.label), read('operator', this.operatorLabel), read('', '')]
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.join(' ');
|
|
24
|
+
const label = this.dismissLabel;
|
|
25
|
+
return label.includes('{label}') ? label.replace('{label}', words) : `${label} ${words}`.trim();
|
|
26
|
+
}
|
|
19
27
|
firstUpdated(changed) {
|
|
20
28
|
super.firstUpdated(changed);
|
|
29
|
+
this.renderRoot.addEventListener('slotchange', () => this.requestUpdate());
|
|
21
30
|
this.finishHydration();
|
|
22
31
|
}
|
|
23
32
|
render() {
|
|
@@ -33,7 +42,7 @@ let HelixHeadlessFilterChip = class HelixHeadlessFilterChip extends MixinDismiss
|
|
|
33
42
|
? html `<button
|
|
34
43
|
part="dismiss"
|
|
35
44
|
type="button"
|
|
36
|
-
aria-label=${this.
|
|
45
|
+
aria-label=${this.removeName}
|
|
37
46
|
@click=${() => this.dismiss()}
|
|
38
47
|
>
|
|
39
48
|
<svg part="dismiss-mark" fill="currentColor" viewBox=${x.viewBox} aria-hidden="true">
|