@fusion.dev/helix-headless 0.145.0 → 0.146.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 +7373 -3849
- package/dist/accordion/item/accordion-item.d.ts +14 -0
- package/dist/accordion/item/accordion-item.js +16 -6
- package/dist/accordion/root/accordion-root.d.ts +8 -5
- package/dist/announcement/root/announcement-root.d.ts +3 -2
- package/dist/announcement/root/announcement-root.js +3 -1
- package/dist/app-header/root/app-header-root.d.ts +7 -2
- package/dist/app-header/root/app-header-root.js +9 -1
- package/dist/app-header/sectioning.d.ts +3 -1
- package/dist/app-header/sectioning.js +3 -2
- package/dist/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/badge/root/badge-root.d.ts +3 -1
- package/dist/badge/root/badge-root.js +2 -2
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +52 -15
- package/dist/bar-chart/stack.d.ts +15 -0
- package/dist/bar-chart/stack.js +19 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +50 -3
- package/dist/button/root/button-root.d.ts +26 -0
- package/dist/button/root/button-root.js +38 -18
- package/dist/button-group/root/button-group-root.d.ts +2 -1
- package/dist/button-group/root/button-group-root.js +5 -1
- package/dist/canvas/node/canvas-node.d.ts +4 -3
- package/dist/canvas/node/canvas-node.js +3 -2
- package/dist/canvas/root/canvas-root.js +2 -2
- package/dist/card/root/card-root.d.ts +24 -3
- package/dist/card/root/card-root.js +20 -8
- package/dist/carousel/root/carousel-root.d.ts +43 -4
- package/dist/carousel/root/carousel-root.js +40 -12
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- package/dist/chat/message/chat-message.js +5 -4
- package/dist/chat/naming.d.ts +5 -1
- package/dist/chat/naming.js +4 -2
- package/dist/chat/root/chat-root.d.ts +25 -3
- package/dist/chat/root/chat-root.js +22 -5
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +14 -1
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
- package/dist/checkbox-group/select-all.d.ts +27 -0
- package/dist/checkbox-group/select-all.js +12 -0
- package/dist/code-block/highlight.d.ts +15 -0
- package/dist/code-block/highlight.js +4 -0
- package/dist/code-block/root/code-block-root.d.ts +49 -1
- package/dist/code-block/root/code-block-root.js +58 -3
- package/dist/color-input/root/color-input-root.d.ts +3 -0
- package/dist/color-input/root/color-input-root.js +6 -3
- package/dist/color-picker/root/color-picker-root.d.ts +33 -4
- package/dist/color-picker/root/color-picker-root.js +80 -21
- package/dist/color-picker/swatches.d.ts +12 -0
- package/dist/color-picker/swatches.js +26 -0
- package/dist/combobox/root/combobox-root.d.ts +43 -0
- package/dist/combobox/root/combobox-root.js +79 -15
- package/dist/command/root/command-root.d.ts +16 -1
- package/dist/command/root/command-root.js +22 -4
- package/dist/copy-button/root/copy-button-root.d.ts +5 -0
- package/dist/copy-button/root/copy-button-root.js +10 -3
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +24 -0
- package/dist/data-table/keys.js +24 -0
- package/dist/data-table/root/data-table-root.d.ts +27 -18
- package/dist/data-table/root/data-table-root.js +20 -52
- package/dist/data-table/tree.d.ts +16 -1
- package/dist/data-table/tree.js +2 -3
- package/dist/date-input/root/date-input-root.d.ts +3 -1
- package/dist/date-input/root/date-input-root.js +18 -7
- package/dist/date-picker/root/date-picker-root.js +12 -6
- package/dist/dialog/description.js +15 -1
- package/dist/dialog/root/dialog-root.d.ts +8 -2
- package/dist/dialog/root/dialog-root.js +16 -1
- package/dist/divider/root/divider-root.d.ts +3 -0
- package/dist/divider/root/divider-root.js +2 -1
- package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
- package/dist/donut-chart/root/donut-chart-root.js +48 -1
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +59 -0
- package/dist/drawer/root/drawer-root.js +63 -4
- package/dist/drilldown/item/drilldown-item.js +1 -1
- package/dist/drilldown/root/drilldown-root.d.ts +21 -3
- package/dist/drilldown/root/drilldown-root.js +21 -3
- package/dist/element-events.generated.js +31 -5
- package/dist/empty/root/empty-root.d.ts +3 -1
- package/dist/empty/root/empty-root.js +3 -2
- package/dist/file-input/root/file-input-root.d.ts +69 -6
- package/dist/file-input/root/file-input-root.js +82 -19
- package/dist/file-input/screen.d.ts +2 -1
- package/dist/filter-input/menu/filter-menu.d.ts +2 -0
- package/dist/filter-input/menu/filter-menu.js +12 -4
- package/dist/filter-input/root/filter-input-root.d.ts +30 -6
- package/dist/filter-input/root/filter-input-root.js +1 -1
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/root/format-date-root.d.ts +9 -16
- package/dist/format-date/root/format-date-root.js +10 -27
- package/dist/heatmap/root/heatmap-root.d.ts +24 -13
- package/dist/heatmap/root/heatmap-root.js +34 -12
- package/dist/icon/root/icon-root.d.ts +12 -1
- package/dist/icon/root/icon-root.js +21 -10
- package/dist/icon/settle.d.ts +7 -0
- package/dist/icon/settle.js +10 -0
- package/dist/icon-button/root/icon-button-root.d.ts +2 -0
- package/dist/image/root/image-root.d.ts +5 -1
- package/dist/image/root/image-root.js +1 -1
- package/dist/input/root/input-root.d.ts +12 -2
- package/dist/input/root/input-root.js +11 -2
- package/dist/kbd/root/kbd-root.d.ts +35 -1
- package/dist/kbd/root/kbd-root.js +23 -4
- package/dist/legend/root/legend-root.d.ts +55 -8
- package/dist/legend/root/legend-root.js +55 -13
- package/dist/lightbox/root/lightbox-root.d.ts +49 -6
- package/dist/lightbox/root/lightbox-root.js +86 -19
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +22 -0
- package/dist/lightbox/zoom.js +16 -0
- package/dist/line-chart/root/line-chart-root.d.ts +22 -1
- package/dist/line-chart/root/line-chart-root.js +21 -1
- package/dist/list/item/list-item.d.ts +2 -0
- package/dist/list/item/list-item.js +11 -2
- package/dist/list/root/list-root.d.ts +62 -13
- package/dist/list/root/list-root.js +70 -13
- package/dist/list/selection.d.ts +37 -7
- package/dist/list/selection.js +16 -7
- package/dist/listbox/root/listbox-root.d.ts +37 -1
- package/dist/listbox/root/listbox-root.js +49 -3
- package/dist/loader/busy.d.ts +10 -0
- package/dist/loader/busy.js +11 -0
- package/dist/loader/root/loader-root.d.ts +9 -2
- package/dist/loader/root/loader-root.js +23 -3
- package/dist/megamenu/root/megamenu-root.d.ts +51 -10
- package/dist/megamenu/root/megamenu-root.js +76 -5
- package/dist/menu/item/menu-item.d.ts +51 -2
- package/dist/menu/item/menu-item.js +47 -23
- package/dist/menu/root/menu-root.d.ts +14 -0
- package/dist/menu/root/menu-root.js +2 -2
- package/dist/meter/root/meter-root.d.ts +20 -1
- package/dist/meter/root/meter-root.js +11 -15
- package/dist/navigation/root/navigation-root.d.ts +2 -1
- package/dist/navigation/root/navigation-root.js +2 -2
- package/dist/notifications/root/notifications-root.d.ts +10 -3
- package/dist/notifications/root/notifications-root.js +19 -7
- package/dist/number-input/root/number-input-root.d.ts +17 -8
- package/dist/number-input/root/number-input-root.js +2 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +75 -27
- package/dist/object-inspector/root/object-inspector-root.js +117 -76
- package/dist/object-inspector/rows.d.ts +18 -0
- package/dist/object-inspector/rows.js +33 -0
- package/dist/option/root/option-root.d.ts +5 -3
- package/dist/outline/root/outline-root.d.ts +18 -0
- package/dist/outline/root/outline-root.js +23 -5
- package/dist/pagination/size/pagination-size.d.ts +1 -0
- package/dist/pagination/size/pagination-size.js +1 -1
- package/dist/pin-input/code.d.ts +10 -0
- package/dist/pin-input/code.js +13 -0
- package/dist/pin-input/root/pin-input-root.d.ts +25 -1
- package/dist/pin-input/root/pin-input-root.js +10 -11
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +41 -0
- package/dist/popover/root/popover-root.d.ts +57 -7
- package/dist/popover/root/popover-root.js +58 -3
- package/dist/progress/root/progress-root.d.ts +20 -0
- package/dist/progress/root/progress-root.js +15 -15
- package/dist/qr-code/export.d.ts +26 -1
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/root/qr-code-root.d.ts +19 -5
- package/dist/qr-code/root/qr-code-root.js +58 -9
- package/dist/quote/marks.d.ts +8 -0
- package/dist/quote/marks.js +5 -0
- package/dist/quote/root/quote-root.d.ts +14 -2
- package/dist/quote/root/quote-root.js +23 -1
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +6 -1
- package/dist/rating/root/rating-root.d.ts +9 -4
- package/dist/rating/root/rating-root.js +31 -7
- package/dist/rating/steps.d.ts +7 -0
- package/dist/rating/steps.js +9 -0
- package/dist/scatter-chart/fit.d.ts +15 -0
- package/dist/scatter-chart/fit.js +35 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
- package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
- package/dist/scroll-area/root/scroll-area-root.js +57 -173
- package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
- package/dist/scroll-area/scrollbar-controller.js +172 -0
- package/dist/scroll-area/scrollbar.d.ts +27 -0
- package/dist/scroll-area/scrollbar.js +9 -0
- package/dist/select/root/select-root.d.ts +15 -0
- package/dist/select/root/select-root.js +18 -6
- package/dist/skeleton/root/skeleton-root.d.ts +3 -0
- package/dist/skeleton/root/skeleton-root.js +4 -2
- package/dist/skip-link/root/skip-link-root.js +2 -2
- package/dist/slider/root/slider-root.d.ts +41 -4
- package/dist/slider/root/slider-root.js +23 -3
- package/dist/sparkline/readings.d.ts +18 -0
- package/dist/sparkline/readings.js +19 -0
- package/dist/sparkline/root/sparkline-root.d.ts +78 -7
- package/dist/sparkline/root/sparkline-root.js +118 -23
- package/dist/speed-dial/root/speed-dial-root.js +2 -2
- package/dist/splitter/root/splitter-root.d.ts +7 -12
- package/dist/splitter/root/splitter-root.js +209 -204
- package/dist/stat/root/stat-root.d.ts +14 -5
- package/dist/stat/root/stat-root.js +21 -5
- package/dist/steps/reach.d.ts +5 -0
- package/dist/steps/reach.js +3 -0
- package/dist/steps/root/steps-root.d.ts +49 -3
- package/dist/steps/root/steps-root.js +44 -5
- package/dist/steps/step/step.d.ts +7 -0
- package/dist/steps/step/step.js +7 -2
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +0 -10
- package/dist/table/column/table-column.js +3 -19
- package/dist/table/root/table-root.d.ts +31 -10
- package/dist/table/root/table-root.js +2 -13
- package/dist/tabs/panel/tab-panel.d.ts +16 -3
- package/dist/tabs/panel/tab-panel.js +34 -5
- package/dist/tabs/root/tabs-root.d.ts +12 -0
- package/dist/tabs/root/tabs-root.js +1 -1
- package/dist/tabs/tab/tab.d.ts +5 -0
- package/dist/tabs/tab/tab.js +5 -2
- package/dist/tag/group/tag-group.d.ts +31 -4
- package/dist/tag/group/tag-group.js +46 -7
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +28 -1
- package/dist/textarea/root/textarea-root.js +40 -1
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +16 -8
- package/dist/time-picker/root/time-picker-root.d.ts +18 -4
- package/dist/time-picker/root/time-picker-root.js +7 -10
- package/dist/time-picker/wheel-name.d.ts +9 -0
- package/dist/time-picker/wheel-name.js +15 -0
- package/dist/timeline/group/timeline-group.js +2 -2
- package/dist/toast/item/toast-item.d.ts +14 -1
- package/dist/toast/item/toast-item.js +22 -5
- package/dist/toast/root/toast-root.d.ts +6 -0
- package/dist/toast/root/toast-root.js +16 -1
- package/dist/toggle/group/toggle-group.d.ts +24 -3
- package/dist/toggle/group/toggle-group.js +34 -5
- package/dist/tooltip/root/tooltip-root.d.ts +13 -2
- package/dist/tooltip/root/tooltip-root.js +9 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +30 -2
- package/dist/tour/root/tour-root.js +34 -8
- package/dist/tree/item/tree-item.d.ts +7 -3
- package/dist/tree/item/tree-item.js +3 -0
- package/dist/tree/root/tree-root.d.ts +24 -3
- package/dist/tree/root/tree-root.js +32 -13
- package/dist/tree/selection.js +2 -15
- package/dist/trend/root/trend-root.d.ts +43 -18
- package/dist/trend/root/trend-root.js +31 -6
- package/dist/video/media-events.d.ts +13 -18
- package/dist/video/media-events.js +1 -5
- package/dist/video/root/video-root.d.ts +18 -5
- package/dist/video/root/video-root.js +19 -10
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +7 -1
- package/dist/virtual-list/fill.d.ts +0 -8
- package/dist/virtual-list/fill.js +1 -17
- package/dist/virtual-list/plan.d.ts +49 -0
- package/dist/virtual-list/plan.js +16 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +114 -13
- package/dist/virtual-list/root/virtual-list-root.js +183 -40
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +4577 -835
- package/types/vue.d.ts +926 -168
- package/dist/chat/relative-clock.d.ts +0 -39
- package/dist/chat/relative-clock.js +0 -31
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { customElement, HelixElement, hostAria, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
-
import { canReach } from '../reach.js';
|
|
10
|
+
import { canReach, progressOf } from '../reach.js';
|
|
11
11
|
let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(HelixElement) {
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
@@ -17,7 +17,8 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
17
17
|
if (event.defaultPrevented || !this.steps.includes(event.target)) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
const index = this.steps.indexOf(event.target);
|
|
21
|
+
if (!this.reachable(index) || !this.valid(index)) {
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
this.requestActive(event.detail.value);
|
|
@@ -27,6 +28,9 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
27
28
|
this.lock();
|
|
28
29
|
};
|
|
29
30
|
}
|
|
31
|
+
get progress() {
|
|
32
|
+
return progressOf(this.steps);
|
|
33
|
+
}
|
|
30
34
|
get steps() {
|
|
31
35
|
return [...this.querySelectorAll(':scope > *')].filter((one) => 'current' in one);
|
|
32
36
|
}
|
|
@@ -46,11 +50,20 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
46
50
|
index += delta;
|
|
47
51
|
}
|
|
48
52
|
const target = steps[index];
|
|
49
|
-
if (!target || !this.reachable(index)) {
|
|
53
|
+
if (!target || !this.reachable(index) || !this.valid(index)) {
|
|
50
54
|
return false;
|
|
51
55
|
}
|
|
52
56
|
return this.requestActive(target.value);
|
|
53
57
|
}
|
|
58
|
+
valid(index) {
|
|
59
|
+
const from = this.steps[this.at];
|
|
60
|
+
if (!from || index <= this.at || !this.validate || from.optional) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const valid = this.validate(from);
|
|
64
|
+
from.invalid = !valid;
|
|
65
|
+
return valid;
|
|
66
|
+
}
|
|
54
67
|
reachable(index) {
|
|
55
68
|
return !this.linear || canReach(this.steps, this.at, index);
|
|
56
69
|
}
|
|
@@ -79,7 +92,10 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
79
92
|
connectedCallback() {
|
|
80
93
|
super.connectedCallback();
|
|
81
94
|
this.addEventListener('helix-select', this.handleSelection);
|
|
82
|
-
this.watcher = new MutationObserver(() =>
|
|
95
|
+
this.watcher = new MutationObserver(() => {
|
|
96
|
+
this.lock();
|
|
97
|
+
this.requestUpdate();
|
|
98
|
+
});
|
|
83
99
|
this.watcher.observe(this, {
|
|
84
100
|
attributeFilter: ['complete', 'current', 'optional'],
|
|
85
101
|
attributes: true,
|
|
@@ -92,9 +108,18 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
92
108
|
this.watcher?.disconnect();
|
|
93
109
|
this.watcher = undefined;
|
|
94
110
|
}
|
|
111
|
+
get known() {
|
|
112
|
+
return this.knownChildren.filter((one) => 'current' in one);
|
|
113
|
+
}
|
|
95
114
|
willUpdate(changed) {
|
|
96
115
|
super.willUpdate(changed);
|
|
97
116
|
hostAria(this.internals, { label: this.label, role: 'list' });
|
|
117
|
+
const known = this.known;
|
|
118
|
+
this.toggleState('complete', known.length > 0 && known.every((step) => step.complete));
|
|
119
|
+
}
|
|
120
|
+
firstUpdated(changed) {
|
|
121
|
+
super.firstUpdated(changed);
|
|
122
|
+
this.finishHydration();
|
|
98
123
|
}
|
|
99
124
|
updated(changed) {
|
|
100
125
|
super.updated(changed);
|
|
@@ -106,7 +131,18 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
106
131
|
}
|
|
107
132
|
}
|
|
108
133
|
render() {
|
|
109
|
-
|
|
134
|
+
const progress = progressOf(this.known);
|
|
135
|
+
return html `<slot @slotchange=${this.handleSlotChange}></slot>
|
|
136
|
+
<div
|
|
137
|
+
part="progress"
|
|
138
|
+
role="progressbar"
|
|
139
|
+
aria-label=${this.label}
|
|
140
|
+
aria-valuemin="0"
|
|
141
|
+
aria-valuemax="100"
|
|
142
|
+
aria-valuenow=${progress}
|
|
143
|
+
style="--steps-progress: ${progress}%"
|
|
144
|
+
hidden
|
|
145
|
+
></div>`;
|
|
110
146
|
}
|
|
111
147
|
};
|
|
112
148
|
__decorate([
|
|
@@ -118,6 +154,9 @@ __decorate([
|
|
|
118
154
|
__decorate([
|
|
119
155
|
property({ reflect: true })
|
|
120
156
|
], HelixHeadlessSteps.prototype, "orientation", void 0);
|
|
157
|
+
__decorate([
|
|
158
|
+
property({ attribute: false })
|
|
159
|
+
], HelixHeadlessSteps.prototype, "validate", void 0);
|
|
121
160
|
__decorate([
|
|
122
161
|
property({ reflect: true })
|
|
123
162
|
], HelixHeadlessSteps.prototype, "variant", void 0);
|
|
@@ -50,6 +50,8 @@ import '../../button/index.js';
|
|
|
50
50
|
* @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
|
|
51
51
|
* @csspart marker - The shape carrying the number or the check.
|
|
52
52
|
* @csspart state - The words that describe a finished stage's button. Hidden.
|
|
53
|
+
*
|
|
54
|
+
* @cssstate invalid - The sequence's `validate` last answered that this stage is not valid.
|
|
53
55
|
*/
|
|
54
56
|
export declare class HelixHeadlessStep extends HelixElement {
|
|
55
57
|
/**
|
|
@@ -69,6 +71,11 @@ export declare class HelixHeadlessStep extends HelixElement {
|
|
|
69
71
|
* Whether the stage is disabled, so the user cannot go to it.
|
|
70
72
|
*/
|
|
71
73
|
disabled: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* @internal Set by the sequence: whether its `validate` last answered that
|
|
76
|
+
* this stage is not valid. Recorded as `:state(invalid)`.
|
|
77
|
+
*/
|
|
78
|
+
invalid: boolean;
|
|
72
79
|
/**
|
|
73
80
|
* @internal Set by a linear sequence: whether the stage is out of reach
|
|
74
81
|
* until the ones before it are finished. A property, because the sequence
|
package/dist/steps/step/step.js
CHANGED
|
@@ -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, drawStatus, HelixElement, HelixSelectEvent, hostAria, StatusController, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, drawStatus, HelixElement, HelixSelectEvent, hostAria, StatusController, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { check, circle, record } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -18,6 +18,7 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
|
|
|
18
18
|
this.completeLabel = 'Complete';
|
|
19
19
|
this.current = false;
|
|
20
20
|
this.disabled = false;
|
|
21
|
+
this.invalid = false;
|
|
21
22
|
this.locked = false;
|
|
22
23
|
this.optional = false;
|
|
23
24
|
this.value = '';
|
|
@@ -40,11 +41,12 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
|
|
|
40
41
|
willUpdate(changed) {
|
|
41
42
|
super.willUpdate(changed);
|
|
42
43
|
hostAria(this.internals, { role: 'listitem' });
|
|
44
|
+
this.toggleState('invalid', this.invalid);
|
|
43
45
|
}
|
|
44
46
|
updated(changed) {
|
|
45
47
|
super.updated(changed);
|
|
46
48
|
if (changed.get('complete') === false && this.complete) {
|
|
47
|
-
const name = (this
|
|
49
|
+
const name = slottedWords(this, ['']);
|
|
48
50
|
this.status.say(name === '' ? this.completeLabel : `${name}, ${this.completeLabel}`);
|
|
49
51
|
}
|
|
50
52
|
}
|
|
@@ -84,6 +86,9 @@ __decorate([
|
|
|
84
86
|
__decorate([
|
|
85
87
|
property({ reflect: true, type: Boolean })
|
|
86
88
|
], HelixHeadlessStep.prototype, "disabled", void 0);
|
|
89
|
+
__decorate([
|
|
90
|
+
property({ attribute: false })
|
|
91
|
+
], HelixHeadlessStep.prototype, "invalid", void 0);
|
|
87
92
|
__decorate([
|
|
88
93
|
property({ attribute: false })
|
|
89
94
|
], HelixHeadlessStep.prototype, "locked", void 0);
|
|
@@ -18,6 +18,16 @@ declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion
|
|
|
18
18
|
* press, the same as a checkbox. The hint and the message go below the row,
|
|
19
19
|
* because the switch and its label share one line.
|
|
20
20
|
*
|
|
21
|
+
* **Keyboard.** The switch is one tab stop.
|
|
22
|
+
*
|
|
23
|
+
* | Key | What it does |
|
|
24
|
+
* |---|---|
|
|
25
|
+
* | Space | Turns the switch on or off, as a native checkbox does. |
|
|
26
|
+
*
|
|
27
|
+
* The input carries `role="switch"`, so a screen reader says "on" or "off".
|
|
28
|
+
* `aria-readonly` is set under `readonly`, and `aria-invalid` and
|
|
29
|
+
* `aria-describedby` point at the message while one shows.
|
|
30
|
+
*
|
|
21
31
|
* @since 0.1.0
|
|
22
32
|
* @status stable
|
|
23
33
|
* @category forms
|
|
@@ -10,16 +10,6 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
10
10
|
* `undefined` falls back to the field.
|
|
11
11
|
*/
|
|
12
12
|
export type CellReader = (row: Readonly<Record<string, unknown>>) => unknown;
|
|
13
|
-
/**
|
|
14
|
-
* A dot path resolved against a row.
|
|
15
|
-
*
|
|
16
|
-
* Written here rather than taken from a library, because the whole of what is
|
|
17
|
-
* needed is "walk the keys and stop at the first thing that is not an object".
|
|
18
|
-
* Returns `undefined` for a path that does not resolve, which the table renders
|
|
19
|
-
* as an empty cell: a missing key is a hole in the data and drawing `undefined`
|
|
20
|
-
* into a table tells a reader the software is broken rather than the row is.
|
|
21
|
-
*/
|
|
22
|
-
export declare const at: (row: Readonly<Record<string, unknown>>, path: string) => unknown;
|
|
23
13
|
/**
|
|
24
14
|
* The edge a column names, where it names one of the three.
|
|
25
15
|
*
|
|
@@ -5,27 +5,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessTableColumn_1;
|
|
8
|
-
import { customElement, fillTemplate, HelixBeforeResizeEvent, HelixElement, HelixResizedEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { customElement, fillTemplate, HelixBeforeResizeEvent, HelixElement, HelixResizedEvent, hostAria, inlineStep, isRtl, requestChange, valueAt, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { dotsThreeVertical } from '@fusion.dev/helix-icons';
|
|
10
10
|
import { html, nothing } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
12
12
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
13
|
-
export const at = (row, path) => {
|
|
14
|
-
if (path === '') {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
if (!path.includes('.')) {
|
|
18
|
-
return row[path];
|
|
19
|
-
}
|
|
20
|
-
let cursor = row;
|
|
21
|
-
for (const key of path.split('.')) {
|
|
22
|
-
if (cursor === null || typeof cursor !== 'object') {
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
cursor = cursor[key];
|
|
26
|
-
}
|
|
27
|
-
return cursor;
|
|
28
|
-
};
|
|
29
13
|
const EDGES = new Set(['center', 'end', 'start']);
|
|
30
14
|
export const edgeOf = (align) => align && EDGES.has(align) ? align : undefined;
|
|
31
15
|
let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixElement {
|
|
@@ -96,11 +80,11 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
|
|
|
96
80
|
}
|
|
97
81
|
read(row) {
|
|
98
82
|
const rendered = this.cell?.(row);
|
|
99
|
-
return rendered === undefined ?
|
|
83
|
+
return rendered === undefined ? valueAt(row, this.field) : rendered;
|
|
100
84
|
}
|
|
101
85
|
order(row) {
|
|
102
86
|
const compared = this.compare?.(row);
|
|
103
|
-
return compared === undefined ?
|
|
87
|
+
return compared === undefined ? valueAt(row, this.field) : compared;
|
|
104
88
|
}
|
|
105
89
|
willUpdate(changed) {
|
|
106
90
|
super.willUpdate(changed);
|
|
@@ -17,21 +17,42 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
|
|
|
17
17
|
* `rowheader` for a `header` cell in a row of values. Rows are
|
|
18
18
|
* `display: contents`, so their cells become items of the one grid.
|
|
19
19
|
*
|
|
20
|
-
* A column with `sortable` and a `field`
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* **Sorting.** A column with `sortable` and a `field` draws its heading as a
|
|
21
|
+
* button that sorts the rows by the text of its cells, numbers by their value.
|
|
22
|
+
* Your markup is not reordered: the table draws the rows in the sorted order.
|
|
23
|
+
*
|
|
24
|
+
* 1. Each press cycles the column through ascending, descending, and the
|
|
25
|
+
* order the rows were written in, which keeps a server's own ranking
|
|
26
|
+
* reachable.
|
|
27
|
+
* 2. `helix-sort` asks first, with `field:direction`, or empty for the written
|
|
28
|
+
* order. Refuse it to keep the order, or to sort the rows yourself and set
|
|
29
|
+
* `sort`.
|
|
30
|
+
* 3. `helix-sorted` follows once the order stands, and `sort` holds it.
|
|
31
|
+
* 4. The heading carries `aria-sort`, and a screen reader hears `sorted-label`
|
|
32
|
+
* ("Sorted by Name, ascending") or `unsorted-label` from a polite region.
|
|
33
|
+
*
|
|
34
|
+
* Tab reaches each sort button, and Enter or Space presses it.
|
|
24
35
|
*
|
|
25
36
|
* The `heading` slot names the table: slot a heading or a line of text into
|
|
26
37
|
* it, and the table is named by its words. An `aria-label` or `aria-labelledby` on the
|
|
27
38
|
* host wins over it.
|
|
28
39
|
*
|
|
29
|
-
* `selectable` adds a column of checkboxes.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
40
|
+
* **Selecting.** `selectable` adds a column of checkboxes.
|
|
41
|
+
*
|
|
42
|
+
* 1. Each row is known by its `value`, or by its place among the rows where it
|
|
43
|
+
* has none, and `selected` holds the chosen keys, comma separated, the same
|
|
44
|
+
* shape `DataTable` uses. `default-selected` is where it starts.
|
|
45
|
+
* 2. A row's checkbox is named by `select-row-label` ("Select {row}") with the
|
|
46
|
+
* words of the row's first cell. The checkbox in the heading selects every
|
|
47
|
+
* row, and shows a dash while only some are chosen.
|
|
48
|
+
* 3. `helix-select` asks first, with every key the change would leave.
|
|
49
|
+
* Refuse it to keep the selection. `helix-selected` follows once it stands.
|
|
50
|
+
* 4. A chosen row takes `:state(selected)`, and a screen reader hears
|
|
51
|
+
* `selected-label` ("2 selected") from a polite region.
|
|
52
|
+
*
|
|
53
|
+
* Tab reaches each checkbox, and Space ticks it. For a grid a reader moves
|
|
54
|
+
* through with the arrow keys, with typeahead and range selection, use
|
|
55
|
+
* `DataTable`. To act on one row, put a link or a button in a cell.
|
|
35
56
|
*
|
|
36
57
|
* The CSS custom properties listed for this component are written by it and
|
|
37
58
|
* read by the stylesheet that draws it. Do not set them. Each holds a number
|
|
@@ -4,12 +4,11 @@ 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, commaList, customElement, fillTemplate, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, MixinCollection, reflectElements, requestChange, splitValues, whenHydrated, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, commaList, customElement, cycle, fillTemplate, format, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, MixinCollection, parse, reflectElements, requestChange, sort, splitValues, toggleEvery, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
11
11
|
import '../../checkbox/index.js';
|
|
12
|
-
import { cycle, format, parse, sort } from '../../data-table/root/order.js';
|
|
13
12
|
import { edgeOf } from '../column/table-column.js';
|
|
14
13
|
const tracksOf = (list, wanted) => {
|
|
15
14
|
const words = splitValues(list, ' ');
|
|
@@ -78,17 +77,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
78
77
|
const keys = this.chosen;
|
|
79
78
|
if (root === this.renderRoot) {
|
|
80
79
|
event.preventDefault();
|
|
81
|
-
|
|
82
|
-
const all = every.length > 0 && every.every((key) => keys.has(key));
|
|
83
|
-
for (const key of every) {
|
|
84
|
-
if (all) {
|
|
85
|
-
keys.delete(key);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
keys.add(key);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
this.requestSelected(keys);
|
|
80
|
+
this.requestSelected(new Set(toggleEvery(keys, this.keyed.map(({ key }) => key))));
|
|
92
81
|
return;
|
|
93
82
|
}
|
|
94
83
|
const found = this.keyed.find(({ row }) => row.shadowRoot === root);
|
|
@@ -10,8 +10,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
10
10
|
*
|
|
11
11
|
* The host is the `tabpanel` while its tab is selected, through
|
|
12
12
|
* `ElementInternals`, so the tab's `aria-controls` can reach it from the tab's
|
|
13
|
-
* shadow root. The box inside
|
|
14
|
-
* focusable
|
|
13
|
+
* shadow root. The box inside is a tab stop only while the panel holds nothing
|
|
14
|
+
* focusable, as the ARIA tabs pattern and React Aria's tab panel do: Tab from
|
|
15
|
+
* the tab list lands on the panel's first link or control where there is one,
|
|
16
|
+
* and on the panel itself where there is none.
|
|
15
17
|
*
|
|
16
18
|
* @since 0.1.0
|
|
17
19
|
* @status stable
|
|
@@ -20,7 +22,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
20
22
|
*
|
|
21
23
|
* @slot - The panel's content.
|
|
22
24
|
*
|
|
23
|
-
* @csspart panel - The panel container, which takes the focus.
|
|
25
|
+
* @csspart panel - The panel container, which takes the focus while it holds nothing focusable.
|
|
24
26
|
*
|
|
25
27
|
* @cssstate selected - While its tab is the one selected.
|
|
26
28
|
*/
|
|
@@ -46,6 +48,17 @@ export declare class HelixHeadlessTabPanel extends HelixElement {
|
|
|
46
48
|
* Pairs the panel with the tab of the same value.
|
|
47
49
|
*/
|
|
48
50
|
value: string;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the content holds a tab stop of its own, so the panel needs none.
|
|
53
|
+
* False on a server, which serves the panel as a stop: it cannot look.
|
|
54
|
+
*/
|
|
55
|
+
private holdsStop;
|
|
56
|
+
/** Re-reads the content when it changes in a way that adds or removes a stop. */
|
|
57
|
+
private readonly watcher;
|
|
58
|
+
private readonly readStops;
|
|
59
|
+
connectedCallback(): void;
|
|
60
|
+
disconnectedCallback(): void;
|
|
61
|
+
protected updated(changed: PropertyValues): void;
|
|
49
62
|
/**
|
|
50
63
|
* Mirrors the chosen state where a stylesheet can select on it.
|
|
51
64
|
*
|
|
@@ -4,15 +4,41 @@ 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, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
-
import { html } from 'lit';
|
|
9
|
-
import { property } from 'lit/decorators.js';
|
|
7
|
+
import { customElement, focusableElements, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessTabPanel = class HelixHeadlessTabPanel extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.label = '';
|
|
14
14
|
this.selected = false;
|
|
15
15
|
this.value = '';
|
|
16
|
+
this.holdsStop = false;
|
|
17
|
+
this.watcher = typeof MutationObserver === 'undefined'
|
|
18
|
+
? undefined
|
|
19
|
+
: new MutationObserver(() => this.readStops());
|
|
20
|
+
this.readStops = () => {
|
|
21
|
+
this.holdsStop = this.selected && focusableElements(this).length > 0;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
connectedCallback() {
|
|
25
|
+
super.connectedCallback();
|
|
26
|
+
this.watcher?.observe(this, {
|
|
27
|
+
attributeFilter: ['contenteditable', 'disabled', 'hidden', 'href', 'tabindex'],
|
|
28
|
+
attributes: true,
|
|
29
|
+
childList: true,
|
|
30
|
+
subtree: true,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
super.disconnectedCallback();
|
|
35
|
+
this.watcher?.disconnect();
|
|
36
|
+
}
|
|
37
|
+
updated(changed) {
|
|
38
|
+
super.updated(changed);
|
|
39
|
+
if (changed.has('selected')) {
|
|
40
|
+
this.readStops();
|
|
41
|
+
}
|
|
16
42
|
}
|
|
17
43
|
willUpdate(changed) {
|
|
18
44
|
super.willUpdate(changed);
|
|
@@ -23,9 +49,9 @@ let HelixHeadlessTabPanel = class HelixHeadlessTabPanel extends HelixElement {
|
|
|
23
49
|
return html `<div
|
|
24
50
|
part="panel"
|
|
25
51
|
?hidden=${!this.selected}
|
|
26
|
-
tabindex
|
|
52
|
+
tabindex=${this.holdsStop ? nothing : '0'}
|
|
27
53
|
>
|
|
28
|
-
<slot></slot>
|
|
54
|
+
<slot @slotchange=${this.readStops}></slot>
|
|
29
55
|
</div>`;
|
|
30
56
|
}
|
|
31
57
|
};
|
|
@@ -38,6 +64,9 @@ __decorate([
|
|
|
38
64
|
__decorate([
|
|
39
65
|
property()
|
|
40
66
|
], HelixHeadlessTabPanel.prototype, "value", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
state()
|
|
69
|
+
], HelixHeadlessTabPanel.prototype, "holdsStop", void 0);
|
|
41
70
|
HelixHeadlessTabPanel = __decorate([
|
|
42
71
|
customElement('helix-headless-tab-panel')
|
|
43
72
|
], HelixHeadlessTabPanel);
|
|
@@ -28,6 +28,17 @@ declare const HelixHeadlessTabs_base: (new (...args: any[]) => import("@fusion.d
|
|
|
28
28
|
* Each tab says which panel it controls through `aria-controls`, set as an
|
|
29
29
|
* element reference to the panel's host, where the engine has reflection.
|
|
30
30
|
*
|
|
31
|
+
* Keys, on the tab list: Left and Right Arrow move between tabs, and so do Up
|
|
32
|
+
* and Down; Home and End go to the first and the last. The horizontal arrows
|
|
33
|
+
* follow the reading direction, so on a right-to-left page Left moves on.
|
|
34
|
+
* Disabled tabs are passed over. Tab leaves the list for the selected panel,
|
|
35
|
+
* which is a tab stop only while it holds nothing focusable.
|
|
36
|
+
*
|
|
37
|
+
* The `indicator` part moves to the selected tab and carries its place and
|
|
38
|
+
* size, so a mark of your own can be drawn there: style the part, or slot an
|
|
39
|
+
* element into `indicator`, which sits inside the part and reads the same
|
|
40
|
+
* properties.
|
|
41
|
+
*
|
|
31
42
|
* @since 0.1.0
|
|
32
43
|
* @status stable
|
|
33
44
|
* @category navigation
|
|
@@ -35,6 +46,7 @@ declare const HelixHeadlessTabs_base: (new (...args: any[]) => import("@fusion.d
|
|
|
35
46
|
* @documentation https://fusion.dev/helix/components/tabs
|
|
36
47
|
*
|
|
37
48
|
* @slot - The tabs, as direct children of this element.
|
|
49
|
+
* @slot indicator - A mark of your own, drawn inside the `indicator` part, where `--indicator-x`, `--indicator-y`, `--indicator-inline-size` and `--indicator-block-size` reach it.
|
|
38
50
|
* @slot panels - The panels, as direct children of this element. Panels inside a wrapper are not paired with tabs, because pairing reads only the direct children.
|
|
39
51
|
*
|
|
40
52
|
* @event {HelixActivateEvent} helix-activate - Fired after the active tab changes, so the element already holds the new value.
|
|
@@ -105,7 +105,7 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
|
|
|
105
105
|
aria-orientation=${this.orientation === 'vertical' ? 'vertical' : nothing}
|
|
106
106
|
>
|
|
107
107
|
<slot @slotchange=${this.handleSlotChange}></slot>
|
|
108
|
-
<span part="indicator" aria-hidden="true"></span>
|
|
108
|
+
<span part="indicator" aria-hidden="true"><slot name="indicator"></slot></span>
|
|
109
109
|
</div>
|
|
110
110
|
<div part="panels"><slot name="panels" @slotchange=${this.handleSlotChange}></slot></div>`;
|
|
111
111
|
}
|
package/dist/tabs/tab/tab.d.ts
CHANGED
|
@@ -47,6 +47,11 @@ export declare class HelixHeadlessTab extends HelixHeadlessTab_base {
|
|
|
47
47
|
* Where the link opens, such as `_blank`, for a tab with an `href`.
|
|
48
48
|
*/
|
|
49
49
|
target?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Moves focus to the tab's control, the button or the link inside it, so a
|
|
52
|
+
* script can focus the tab the way it focuses a native one.
|
|
53
|
+
*/
|
|
54
|
+
focus(options?: FocusOptions): void;
|
|
50
55
|
/**
|
|
51
56
|
* Chooses the tab before the browser follows its link, and keeps the browser
|
|
52
57
|
* from following where the choice was refused. A press with a modifier, or
|
package/dist/tabs/tab/tab.js
CHANGED
|
@@ -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, MixinSelectableItem, reflectElements, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, MixinSelectableItem, plainClick, reflectElements, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixElement) {
|
|
@@ -13,7 +13,7 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
|
|
|
13
13
|
this.itemPart = 'tab';
|
|
14
14
|
this.controls = undefined;
|
|
15
15
|
this.handleLinkClick = (event) => {
|
|
16
|
-
if (event
|
|
16
|
+
if (!plainClick(event)) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
if (!this.select()) {
|
|
@@ -21,6 +21,9 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
+
focus(options) {
|
|
25
|
+
this.partNamed('tab')?.focus(options);
|
|
26
|
+
}
|
|
24
27
|
updated(changed) {
|
|
25
28
|
super.updated(changed);
|
|
26
29
|
const control = this.renderRoot.querySelector('[part="tab"]');
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { HelixElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, KeyboardNavigationController, type SelectionMode } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { HelixHeadlessTag } from '../root/tag-root.js';
|
|
4
|
-
|
|
4
|
+
/** How many tags a group lets a reader select: core's `SelectionMode`. */
|
|
5
|
+
export type TagSelectionMode = SelectionMode;
|
|
5
6
|
/**
|
|
6
7
|
* @summary A set of tags that the arrow keys move through, and that can be removed and selected from the keyboard.
|
|
7
8
|
*
|
|
@@ -17,9 +18,16 @@ import { type TagSelectionMode } from '../selection.js';
|
|
|
17
18
|
* `single` selects one at a time and `multiple` any number. `value` holds the
|
|
18
19
|
* selected tags' values, separated by commas, and a change asks with
|
|
19
20
|
* `helix-before-change` and tells with `change`. Enter on a tag with an
|
|
20
|
-
* `href` follows its link. A `disabled` tag is passed over.
|
|
21
|
+
* `href` follows its link. A `disabled` tag is passed over. A selected tag
|
|
22
|
+
* that is removed leaves `value`, which then sends `change`.
|
|
21
23
|
*
|
|
22
|
-
* Name the set with `label`.
|
|
24
|
+
* Name the set with `label`. Each tag is named by its words alone, without
|
|
25
|
+
* its remove button.
|
|
26
|
+
*
|
|
27
|
+
* **Removing the last tag keeps focus in the group.** With no tags left the
|
|
28
|
+
* set is a `group`, and focus moves to its `empty` part,
|
|
29
|
+
* which holds the `empty` slot: put words there such as "No filters" for a
|
|
30
|
+
* reader to hear.
|
|
23
31
|
*
|
|
24
32
|
* @since 0.1.0
|
|
25
33
|
* @status stable
|
|
@@ -27,10 +35,13 @@ import { type TagSelectionMode } from '../selection.js';
|
|
|
27
35
|
* @documentation https://fusion.dev/helix/components/tag
|
|
28
36
|
*
|
|
29
37
|
* @slot - The tags, in the order they are read.
|
|
38
|
+
* @slot empty - Shown in place of the tags while there are none, such as "No filters".
|
|
30
39
|
*
|
|
31
40
|
* @event {Event} change - Fired once a press has changed which tags are selected.
|
|
32
41
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a press changes which tags are selected, with the `value` it would leave. Cancelable.
|
|
33
42
|
* @event {HelixDismissEvent} helix-dismiss - A tag's remove button was pressed, or Delete or Backspace on the focused tag. Bubbles from that tag, which is its `target`; remove the tag in response. Cancelable.
|
|
43
|
+
*
|
|
44
|
+
* @csspart empty - Holds the `empty` slot while the group has no tags, rendered only then. Takes focus when the last tag is removed.
|
|
34
45
|
*/
|
|
35
46
|
export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
36
47
|
/**
|
|
@@ -93,9 +104,25 @@ export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
|
93
104
|
protected press(tag: HelixHeadlessTag): void;
|
|
94
105
|
private readonly handleKeydown;
|
|
95
106
|
private readonly handleClick;
|
|
107
|
+
/**
|
|
108
|
+
* What happens once a tag has asked to be removed and the page has had its
|
|
109
|
+
* turn: a selected tag that left takes its value out of `value`, and focus
|
|
110
|
+
* that the last tag took with it comes to the group's `empty` part.
|
|
111
|
+
*
|
|
112
|
+
* Asked after the event and again a frame later, as `MixinDismissible`
|
|
113
|
+
* asks, because a framework removes the tag on its next render, after the
|
|
114
|
+
* handler. A canceled dismissal changes nothing.
|
|
115
|
+
*/
|
|
116
|
+
private readonly handleDismiss;
|
|
117
|
+
private readonly handleSlotchange;
|
|
96
118
|
private readonly handleFocusin;
|
|
97
119
|
connectedCallback(): void;
|
|
98
120
|
disconnectedCallback(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Whether the group is known to hold no tags, which a server and a
|
|
123
|
+
* hydrating render cannot know: there it holds whatever it was given.
|
|
124
|
+
*/
|
|
125
|
+
private get empty();
|
|
99
126
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
100
127
|
protected updated(changed: PropertyValues<this>): void;
|
|
101
128
|
protected render(): TemplateResult;
|