@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,15 +4,19 @@ 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, deepContains, FocusScopeController, fillTemplate, focusableElements, HelixElement, hostAria, scrollHolders, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, DelayController, deepActiveElement, deepContains, FocusScopeController, fillTemplate, focusableElements, HelixElement, hostAria, scrollHolders, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
|
-
import { property } from 'lit/decorators.js';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { matchesHotkey, parseHotkey } from '../hotkey.js';
|
|
11
|
+
import { messageWords } from '../words.js';
|
|
11
12
|
let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
12
13
|
constructor() {
|
|
13
14
|
super(...arguments);
|
|
14
15
|
this.hotkey = 'F8';
|
|
15
16
|
this.label = 'Notifications ({hotkey})';
|
|
17
|
+
this.said = '';
|
|
18
|
+
this.urgent = '';
|
|
19
|
+
this.hush = new DelayController(this, { renders: false });
|
|
16
20
|
this.scope = new FocusScopeController(this, {
|
|
17
21
|
contents: () => this.showing.flatMap((one) => {
|
|
18
22
|
const target = focusTarget(one);
|
|
@@ -85,9 +89,45 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
85
89
|
label: fillTemplate(this.label, { hotkey: this.hotkey }),
|
|
86
90
|
role: 'region',
|
|
87
91
|
});
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
}
|
|
93
|
+
announce(arrived) {
|
|
94
|
+
const urgent = arrived.filter(isDanger).map(messageWords).join(' ');
|
|
95
|
+
const said = arrived
|
|
96
|
+
.filter((one) => !isDanger(one))
|
|
97
|
+
.map(messageWords)
|
|
98
|
+
.join(' ');
|
|
99
|
+
if (said.trim() === '' && urgent.trim() === '') {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.said = '';
|
|
103
|
+
this.urgent = '';
|
|
104
|
+
const fill = () => {
|
|
105
|
+
this.said = said;
|
|
106
|
+
this.urgent = urgent;
|
|
107
|
+
this.hush.start(1000, () => {
|
|
108
|
+
this.said = '';
|
|
109
|
+
this.urgent = '';
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
113
|
+
requestAnimationFrame(fill);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
fill();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
tell(added) {
|
|
120
|
+
const showing = this.showing;
|
|
121
|
+
const arrived = added.filter((one) => one instanceof HTMLElement && showing.includes(one));
|
|
122
|
+
if (arrived.length === 0) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (this.blocked()) {
|
|
126
|
+
this.notify(arrived);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.announce(arrived);
|
|
130
|
+
}
|
|
91
131
|
}
|
|
92
132
|
add(message, options = {}) {
|
|
93
133
|
const tier = this.constructor.tier;
|
|
@@ -152,9 +192,6 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
152
192
|
if (!open || blocked) {
|
|
153
193
|
region.showPopover();
|
|
154
194
|
}
|
|
155
|
-
if (blocked) {
|
|
156
|
-
this.notify(arrived);
|
|
157
|
-
}
|
|
158
195
|
}
|
|
159
196
|
lowerWhenStill(region) {
|
|
160
197
|
const running = typeof this.getAnimations === 'function' ? this.getAnimations({ subtree: true }) : [];
|
|
@@ -182,9 +219,9 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
182
219
|
return;
|
|
183
220
|
}
|
|
184
221
|
for (const one of arrived) {
|
|
185
|
-
const words = (one
|
|
222
|
+
const words = messageWords(one);
|
|
186
223
|
if (words !== '') {
|
|
187
|
-
speaker.ariaNotify(words);
|
|
224
|
+
speaker.ariaNotify(words, { priority: isDanger(one) ? 'high' : 'normal' });
|
|
188
225
|
}
|
|
189
226
|
}
|
|
190
227
|
}
|
|
@@ -194,7 +231,9 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
194
231
|
this.addEventListener('helix-dismiss', this.handleDismiss);
|
|
195
232
|
document.addEventListener('keydown', this.handleHotkey);
|
|
196
233
|
this.watcher = new MutationObserver((records) => {
|
|
197
|
-
|
|
234
|
+
const added = records.flatMap((record) => [...record.addedNodes]);
|
|
235
|
+
this.place(added);
|
|
236
|
+
this.tell(added);
|
|
198
237
|
this.sweep();
|
|
199
238
|
});
|
|
200
239
|
this.watcher.observe(this, {
|
|
@@ -220,7 +259,7 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
220
259
|
this.place();
|
|
221
260
|
}
|
|
222
261
|
render() {
|
|
223
|
-
return html `<div part="region" popover="manual" tabindex="-1"><slot></slot></div>`;
|
|
262
|
+
return html `<div part="region" popover="manual" tabindex="-1"><slot></slot><span part="live" role="status">${this.said}</span><span part="live" role="alert">${this.urgent}</span></div>`;
|
|
224
263
|
}
|
|
225
264
|
};
|
|
226
265
|
__decorate([
|
|
@@ -232,10 +271,17 @@ __decorate([
|
|
|
232
271
|
__decorate([
|
|
233
272
|
property({ reflect: true })
|
|
234
273
|
], HelixHeadlessToast.prototype, "placement", void 0);
|
|
274
|
+
__decorate([
|
|
275
|
+
state()
|
|
276
|
+
], HelixHeadlessToast.prototype, "said", void 0);
|
|
277
|
+
__decorate([
|
|
278
|
+
state()
|
|
279
|
+
], HelixHeadlessToast.prototype, "urgent", void 0);
|
|
235
280
|
HelixHeadlessToast = __decorate([
|
|
236
281
|
customElement('helix-headless-toast')
|
|
237
282
|
], HelixHeadlessToast);
|
|
238
283
|
export { HelixHeadlessToast };
|
|
284
|
+
const isDanger = (item) => (item.tone ?? item.getAttribute('tone')) === 'danger';
|
|
239
285
|
const popoverOpen = (region) => {
|
|
240
286
|
try {
|
|
241
287
|
return region.matches(':popover-open');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pieces of a message joined into one line a screen reader says, with a full
|
|
3
|
+
* stop between two where the first does not already end a sentence, so a
|
|
4
|
+
* heading and its detail are heard as two sentences and not run together.
|
|
5
|
+
*/
|
|
6
|
+
export declare const joinSaid: (pieces: readonly string[]) => string;
|
|
7
|
+
/**
|
|
8
|
+
* What a message says as it arrives: the word for its tone, then its heading,
|
|
9
|
+
* its description and its text, and never its actions or its dismiss control,
|
|
10
|
+
* which a reader finds by moving into the message.
|
|
11
|
+
*/
|
|
12
|
+
export declare const messageWords: (item: Element) => string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { toneMark } from '@fusion.dev/helix-core';
|
|
2
|
+
const UNSAID = new Set(['actions', 'dismiss-icon', 'icon']);
|
|
3
|
+
export const joinSaid = (pieces) => pieces
|
|
4
|
+
.map((piece) => piece.replace(/\s+/gu, ' ').trim())
|
|
5
|
+
.filter((piece) => piece !== '')
|
|
6
|
+
.reduce((line, piece) => line === '' ? piece : `${line}${/[.!?:;]$/u.test(line) ? '' : '.'} ${piece}`, '');
|
|
7
|
+
export const messageWords = (item) => {
|
|
8
|
+
const tone = item.tone ?? item.getAttribute('tone') ?? undefined;
|
|
9
|
+
const label = toneMark(tone)?.label;
|
|
10
|
+
const heading = [];
|
|
11
|
+
const rest = [];
|
|
12
|
+
for (const node of item.childNodes) {
|
|
13
|
+
if (node instanceof Element) {
|
|
14
|
+
const slot = node.getAttribute('slot') ?? '';
|
|
15
|
+
if (!UNSAID.has(slot)) {
|
|
16
|
+
;
|
|
17
|
+
(slot === 'heading' ? heading : rest).push(node.textContent ?? '');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (node.nodeType === 3) {
|
|
21
|
+
rest.push(node.textContent ?? '');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return joinSaid([...(label ? [label] : []), ...heading, ...rest]);
|
|
25
|
+
};
|
|
@@ -28,6 +28,23 @@ declare const HelixHeadlessToggleGroup_base: (new (...args: any[]) => import("@f
|
|
|
28
28
|
* `orientation="vertical"` runs the items down a column, says so to the
|
|
29
29
|
* accessibility tree, and the up and down arrows move between them.
|
|
30
30
|
*
|
|
31
|
+
* **Keyboard.** The group is one tab stop: the chosen item, or the first that
|
|
32
|
+
* can be chosen, as in a radio group, and in a multiple group the item focus
|
|
33
|
+
* was last on.
|
|
34
|
+
*
|
|
35
|
+
* | Key | What it does |
|
|
36
|
+
* |---|---|
|
|
37
|
+
* | Right, Down | Moves to the next item, from the last back to the first. In a single group, chooses it. |
|
|
38
|
+
* | Left, Up | Moves to the item before, from the first round to the last. In a single group, chooses it. |
|
|
39
|
+
* | Home, End | Moves to the first or the last item. In a single group, chooses it. |
|
|
40
|
+
* | Space, Enter | Chooses the focused item, or presses or releases it in a multiple group. |
|
|
41
|
+
*
|
|
42
|
+
* Left and Right swap on a right-to-left page, and a disabled item is passed
|
|
43
|
+
* over. A single group is a `radiogroup` of items with `role="radio"` and
|
|
44
|
+
* `aria-checked`. A multiple group is a `toolbar` of buttons with
|
|
45
|
+
* `aria-pressed`, or a `group` inside a toolbar. The group is named by
|
|
46
|
+
* `label` and carries `aria-orientation` under `orientation`.
|
|
47
|
+
*
|
|
31
48
|
* @since 0.1.0
|
|
32
49
|
* @status stable
|
|
33
50
|
* @aliases SegmentedControl, Segmented, Navigation, Switcher
|
|
@@ -115,6 +132,11 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
|
|
|
115
132
|
/** The item focus was last on, in a toolbar, which holds its tab stop. */
|
|
116
133
|
private lastFocused;
|
|
117
134
|
private readonly noteFocus;
|
|
135
|
+
/**
|
|
136
|
+
* The item whose value is the group's, in a single group: the exact match,
|
|
137
|
+
* so nothing chosen marks nothing. A multiple group has none.
|
|
138
|
+
*/
|
|
139
|
+
private get chosenItem();
|
|
118
140
|
/** Whether several items can be pressed at once. */
|
|
119
141
|
private get multiple();
|
|
120
142
|
/**
|
|
@@ -192,11 +214,6 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
|
|
|
192
214
|
*/
|
|
193
215
|
private get groupRole();
|
|
194
216
|
protected willUpdate(changed: PropertyValues): void;
|
|
195
|
-
/**
|
|
196
|
-
* What the form receives: the value, or under `selection-mode="multiple"`
|
|
197
|
-
* one entry per pressed value, as a native `<select multiple>` sends.
|
|
198
|
-
*/
|
|
199
|
-
private formValue;
|
|
200
217
|
/**
|
|
201
218
|
* The verdict on the answer `required` asks for.
|
|
202
219
|
*
|
|
@@ -238,6 +255,13 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
|
|
|
238
255
|
* in it.
|
|
239
256
|
*/
|
|
240
257
|
protected render(): TemplateResult;
|
|
258
|
+
/**
|
|
259
|
+
* Items that arrive after the first render, which is every item on a page
|
|
260
|
+
* the parser is still reading. Outside an update here, so taking the
|
|
261
|
+
* declaration schedules one rather than warning, and the update reports the
|
|
262
|
+
* form, which a removed answer no longer holds.
|
|
263
|
+
*/
|
|
264
|
+
private readonly handleItems;
|
|
241
265
|
}
|
|
242
266
|
declare global {
|
|
243
267
|
interface HTMLElementTagNameMap {
|
|
@@ -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 { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, rovingStop, toggleValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, reportValues, rovingStop, toggleValue, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessToggle } from '../root/toggle-root.js';
|
|
@@ -13,15 +13,15 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.lastFocused = undefined;
|
|
15
15
|
this.noteFocus = (event) => {
|
|
16
|
-
const item =
|
|
17
|
-
if (this.multiple && item
|
|
16
|
+
const item = event.target;
|
|
17
|
+
if (this.multiple && item !== this.lastFocused && this.items.includes(item)) {
|
|
18
18
|
this.lastFocused = item;
|
|
19
19
|
this.sync();
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
this.focusable = true;
|
|
23
23
|
this.indicator = new IndicatorController(this, {
|
|
24
|
-
active: () => this.
|
|
24
|
+
active: () => this.chosenItem,
|
|
25
25
|
indicator: () => this.partNamed('indicator'),
|
|
26
26
|
observe: () => this.items,
|
|
27
27
|
surface: () => this.partNamed('track'),
|
|
@@ -52,6 +52,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
52
52
|
});
|
|
53
53
|
};
|
|
54
54
|
this.chosen = undefined;
|
|
55
|
+
this.handleItems = () => {
|
|
56
|
+
this.adopt();
|
|
57
|
+
this.sync();
|
|
58
|
+
this.indicator.place();
|
|
59
|
+
this.requestUpdate();
|
|
60
|
+
};
|
|
55
61
|
}
|
|
56
62
|
adopt() {
|
|
57
63
|
if (this.value !== '' || this.children === undefined) {
|
|
@@ -63,7 +69,7 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
sync() {
|
|
66
|
-
const active = this.
|
|
72
|
+
const active = this.chosenItem;
|
|
67
73
|
const pressed = new Set(this.values);
|
|
68
74
|
const entry = this.focusable ? this.entry() : undefined;
|
|
69
75
|
for (const item of this.items) {
|
|
@@ -80,9 +86,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
80
86
|
selected: (item) => item.pressed === true,
|
|
81
87
|
});
|
|
82
88
|
}
|
|
83
|
-
const active =
|
|
89
|
+
const active = this.chosenItem;
|
|
84
90
|
return active && !active.disabled ? active : items.find((item) => !item.disabled);
|
|
85
91
|
}
|
|
92
|
+
get chosenItem() {
|
|
93
|
+
return this.multiple ? undefined : this.items.find((item) => item.value === this.value);
|
|
94
|
+
}
|
|
86
95
|
get multiple() {
|
|
87
96
|
return this.selectionMode === 'multiple';
|
|
88
97
|
}
|
|
@@ -98,14 +107,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
98
107
|
if (this.value === '') {
|
|
99
108
|
return false;
|
|
100
109
|
}
|
|
101
|
-
if (this.multiple) {
|
|
102
|
-
return this.children === undefined || this.values.length > 0;
|
|
103
|
-
}
|
|
104
110
|
if (this.children === undefined) {
|
|
105
111
|
return true;
|
|
106
112
|
}
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
return this.multiple
|
|
114
|
+
? this.values.length > 0
|
|
115
|
+
: this.items.length === 0 || this.chosenItem !== undefined;
|
|
109
116
|
}
|
|
110
117
|
connectedCallback() {
|
|
111
118
|
super.connectedCallback();
|
|
@@ -132,7 +139,7 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
132
139
|
if (!this.multiple) {
|
|
133
140
|
return 'radiogroup';
|
|
134
141
|
}
|
|
135
|
-
return this.parentElement?.closest('[role=
|
|
142
|
+
return this.parentElement?.closest('[role=toolbar],helix-toolbar,helix-headless-toolbar')
|
|
136
143
|
? 'group'
|
|
137
144
|
: 'toolbar';
|
|
138
145
|
}
|
|
@@ -141,20 +148,15 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
141
148
|
this.adopt();
|
|
142
149
|
hostAria(this.internals, { label: this.label, role: this.groupRole });
|
|
143
150
|
this.internals.ariaOrientation = this.orientation ?? null;
|
|
144
|
-
this.internals.setFormValue(this.formValue());
|
|
145
|
-
}
|
|
146
|
-
formValue() {
|
|
147
151
|
if (!this.answered) {
|
|
148
|
-
|
|
152
|
+
this.internals.setFormValue(null);
|
|
149
153
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
154
|
+
else if (this.multiple) {
|
|
155
|
+
reportValues(this.internals, this.name, this.values);
|
|
152
156
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
data.append(this.name, value);
|
|
157
|
+
else {
|
|
158
|
+
this.internals.setFormValue(this.value);
|
|
156
159
|
}
|
|
157
|
-
return data;
|
|
158
160
|
}
|
|
159
161
|
validate() {
|
|
160
162
|
this.reportRequired(!this.answered, 'Choose one to continue.', 'track');
|
|
@@ -176,29 +178,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
176
178
|
super.formStateRestoreCallback(state);
|
|
177
179
|
return;
|
|
178
180
|
}
|
|
179
|
-
this.values = state.getAll(this.name)
|
|
181
|
+
this.values = state.getAll(this.name);
|
|
180
182
|
}
|
|
181
183
|
render() {
|
|
182
184
|
const inside = this.labelPlacement === 'start';
|
|
183
185
|
const label = this.renderGroupLabel();
|
|
184
|
-
return html `${inside ? nothing : label}
|
|
185
|
-
<div part="row">
|
|
186
|
-
<slot name="start"></slot>
|
|
187
|
-
<div part="track">
|
|
188
|
-
${inside ? label : nothing}
|
|
189
|
-
<div part="indicator" aria-hidden="true"></div>
|
|
190
|
-
<slot
|
|
191
|
-
@slotchange=${() => {
|
|
192
|
-
this.adopt();
|
|
193
|
-
this.sync();
|
|
194
|
-
this.indicator.place();
|
|
195
|
-
this.requestUpdate();
|
|
196
|
-
}}
|
|
197
|
-
></slot>
|
|
198
|
-
</div>
|
|
199
|
-
<slot name="end"></slot>
|
|
200
|
-
</div>
|
|
201
|
-
${this.renderHint()}${this.renderFeedback()}`;
|
|
186
|
+
return html `${inside ? nothing : label}<div part="row"><slot name="start"></slot><div part="track">${inside ? label : nothing}<div part="indicator" aria-hidden="true"></div><slot @slotchange=${this.handleItems}></slot></div><slot name="end"></slot></div>${this.renderHint()}${this.renderFeedback()}`;
|
|
202
187
|
}
|
|
203
188
|
};
|
|
204
189
|
__decorate([
|
|
@@ -31,14 +31,12 @@ let HelixHeadlessToggle = class HelixHeadlessToggle extends MixinSelectableItem(
|
|
|
31
31
|
part="item"
|
|
32
32
|
type="button"
|
|
33
33
|
role=${this.pressed === undefined ? 'radio' : nothing}
|
|
34
|
-
aria-checked=${this.pressed === undefined ? (this.selected
|
|
34
|
+
aria-checked=${this.pressed === undefined ? String(this.selected) : nothing}
|
|
35
35
|
aria-pressed=${this.pressed === undefined ? nothing : String(this.pressed)}
|
|
36
36
|
?disabled=${this.disabled}
|
|
37
37
|
tabindex=${(this.focusable ?? this.selected) || !this.childrenKnown ? '0' : '-1'}
|
|
38
38
|
@click=${() => this.select()}
|
|
39
|
-
|
|
40
|
-
<slot></slot>
|
|
41
|
-
</button>`;
|
|
39
|
+
><slot></slot></button>`;
|
|
42
40
|
}
|
|
43
41
|
};
|
|
44
42
|
__decorate([
|
|
@@ -20,11 +20,20 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
20
20
|
* The arrows wrap from the last control to the first. Set `stop-at-ends` to
|
|
21
21
|
* keep them at the ends, as Radix's `loop` set to false does.
|
|
22
22
|
*
|
|
23
|
-
* A
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* A toggle group of pressed buttons, `selection-mode="multiple"`, is walked
|
|
24
|
+
* through the same way, each toggle a stop on the toolbar's axis, as React
|
|
25
|
+
* Aria's toolbar walks its toggle buttons. Another nested composite, such as a
|
|
26
|
+
* radio-style toggle group, is one stop on the toolbar's axis: the toolbar's
|
|
27
|
+
* arrows move past it, and the arrows across the toolbar move inside it. A
|
|
28
|
+
* composite with a `focusable` property, as Toggle Group has, gives up its own
|
|
29
|
+
* tab stop while the toolbar's is elsewhere, so Tab stops once in the
|
|
30
|
+
* toolbar. A composite without one keeps its own tab stop.
|
|
31
|
+
*
|
|
32
|
+
* A toolbar inside another toolbar, a Helix one or the page's own
|
|
33
|
+
* `role="toolbar"`, is a `group` of the outer one, as React Aria's is: the
|
|
34
|
+
* outer toolbar's arrows walk through its controls and on past them, and it
|
|
35
|
+
* takes no keys and no tab stop of its own. A server renders it as a toolbar,
|
|
36
|
+
* having no parent to read, until it upgrades.
|
|
28
37
|
*
|
|
29
38
|
* @since 0.1.0
|
|
30
39
|
* @status stable
|
|
@@ -123,6 +132,13 @@ export declare class HelixHeadlessToolbar extends HelixElement {
|
|
|
123
132
|
* the stop hands it to the first one left.
|
|
124
133
|
*/
|
|
125
134
|
private readonly restoreTabStop;
|
|
135
|
+
/**
|
|
136
|
+
* Whether this toolbar sits inside another, which then owns the keys and the
|
|
137
|
+
* tab stop: a toolbar inside a toolbar held the reader's arrows inside it.
|
|
138
|
+
* Read when it renders and when it connects, there being no parent on a
|
|
139
|
+
* server.
|
|
140
|
+
*/
|
|
141
|
+
private get nested();
|
|
126
142
|
/**
|
|
127
143
|
* The orientation in force.
|
|
128
144
|
*
|
|
@@ -4,8 +4,9 @@ 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
|
-
|
|
8
|
-
import {
|
|
7
|
+
var HelixHeadlessToolbar_1;
|
|
8
|
+
import { AriaForwardController, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, } from '@fusion.dev/helix-core';
|
|
9
|
+
import { html, nothing } from 'lit';
|
|
9
10
|
import { property } from 'lit/decorators.js';
|
|
10
11
|
const KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);
|
|
11
12
|
const ownsTabStop = (node) => 'focusable' in node;
|
|
@@ -22,7 +23,9 @@ const takesFocus = (node) => {
|
|
|
22
23
|
node.shadowRoot?.delegatesFocus === true ||
|
|
23
24
|
node.shadowRoot?.querySelector(TABBABLE) != null);
|
|
24
25
|
};
|
|
25
|
-
|
|
26
|
+
const flattens = (node) => ownsTabStop(node) &&
|
|
27
|
+
node.selectionMode === 'multiple';
|
|
28
|
+
let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar extends HelixElement {
|
|
26
29
|
constructor() {
|
|
27
30
|
super(...arguments);
|
|
28
31
|
this.label = 'Toolbar';
|
|
@@ -33,14 +36,23 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
33
36
|
this.wroteForeign = false;
|
|
34
37
|
this.stopAtEnds = false;
|
|
35
38
|
this.handleFocusIn = (event) => {
|
|
39
|
+
if (this.nested) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
36
42
|
const control = this.origin(event);
|
|
37
43
|
if (control) {
|
|
38
44
|
this.setTabStop(control);
|
|
39
45
|
}
|
|
40
46
|
};
|
|
41
47
|
this.restoreTabStop = () => {
|
|
48
|
+
if (this.nested) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
42
51
|
const controls = this.controls;
|
|
43
52
|
const held = controls.some((control) => {
|
|
53
|
+
if (control.group) {
|
|
54
|
+
return control.group.focusable;
|
|
55
|
+
}
|
|
44
56
|
const composite = control.stops.length !== 1;
|
|
45
57
|
const element = composite ? control.child : control.stops[0];
|
|
46
58
|
if (ownsTabStop(element)) {
|
|
@@ -53,8 +65,11 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
53
65
|
}
|
|
54
66
|
};
|
|
55
67
|
this.handleCompositeKeydown = (event) => {
|
|
68
|
+
if (this.nested) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
56
71
|
const control = this.origin(event);
|
|
57
|
-
if (!control || control.stops.length === 1) {
|
|
72
|
+
if (!control || (control.stops.length === 1 && !control.group)) {
|
|
58
73
|
return;
|
|
59
74
|
}
|
|
60
75
|
this.handleKeydown(event);
|
|
@@ -63,7 +78,7 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
63
78
|
}
|
|
64
79
|
};
|
|
65
80
|
this.handleKeydown = (event) => {
|
|
66
|
-
if (!KEYS.has(event.key) || keyClaimed(event)) {
|
|
81
|
+
if (this.nested || !KEYS.has(event.key) || keyClaimed(event)) {
|
|
67
82
|
return;
|
|
68
83
|
}
|
|
69
84
|
const along = inlineStep(this, event.key);
|
|
@@ -115,7 +130,14 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
115
130
|
continue;
|
|
116
131
|
}
|
|
117
132
|
if (takesFocus(child)) {
|
|
118
|
-
|
|
133
|
+
const stops = this.inside(child);
|
|
134
|
+
if (stops.length > 1 && flattens(child)) {
|
|
135
|
+
for (const stop of stops) {
|
|
136
|
+
controls.push({ child: stop, group: child, stops: [stop] });
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
controls.push({ child, stops });
|
|
119
141
|
continue;
|
|
120
142
|
}
|
|
121
143
|
for (const stop of this.within(child)) {
|
|
@@ -151,6 +173,10 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
151
173
|
this.wroteForeign = true;
|
|
152
174
|
}
|
|
153
175
|
for (const control of this.controls) {
|
|
176
|
+
if (control.group) {
|
|
177
|
+
control.group.focusable = control.group === active?.group;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
154
180
|
if (control.stops.length !== 1) {
|
|
155
181
|
if (ownsTabStop(control.child)) {
|
|
156
182
|
control.child.focusable = control.child === active?.child;
|
|
@@ -168,15 +194,27 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
168
194
|
}
|
|
169
195
|
}
|
|
170
196
|
async claimTabStop() {
|
|
197
|
+
if (this.nested) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
171
200
|
const pending = [...new Set([...this.children].map((child) => child.localName))].filter((name) => name.includes('-'));
|
|
172
201
|
await Promise.all(pending.map((name) => customElements.whenDefined(name)));
|
|
173
202
|
this.setTabStop(this.controls[0], false);
|
|
174
203
|
}
|
|
204
|
+
get nested() {
|
|
205
|
+
const parent = this.parentElement;
|
|
206
|
+
if (!parent) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return (closestInstance(parent, HelixHeadlessToolbar_1) !== null ||
|
|
210
|
+
parent.closest('[role="toolbar"]') !== null);
|
|
211
|
+
}
|
|
175
212
|
get axis() {
|
|
176
213
|
return this.orientation ?? 'horizontal';
|
|
177
214
|
}
|
|
178
215
|
connectedCallback() {
|
|
179
216
|
super.connectedCallback();
|
|
217
|
+
this.requestUpdate();
|
|
180
218
|
this.addEventListener('keydown', this.handleCompositeKeydown, true);
|
|
181
219
|
this.addEventListener('keydown', this.handleKeydown);
|
|
182
220
|
this.addEventListener('focusin', this.handleFocusIn);
|
|
@@ -200,7 +238,13 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
|
200
238
|
void this.claimTabStop();
|
|
201
239
|
}
|
|
202
240
|
render() {
|
|
203
|
-
|
|
241
|
+
const nested = this.nested;
|
|
242
|
+
return html `<div
|
|
243
|
+
part="toolbar"
|
|
244
|
+
role=${nested ? 'group' : 'toolbar'}
|
|
245
|
+
aria-label=${this.label}
|
|
246
|
+
aria-orientation=${nested ? nothing : this.axis}
|
|
247
|
+
>
|
|
204
248
|
<slot @slotchange=${() => this.claimTabStop()}></slot>
|
|
205
249
|
</div>`;
|
|
206
250
|
}
|
|
@@ -214,7 +258,7 @@ __decorate([
|
|
|
214
258
|
__decorate([
|
|
215
259
|
property({ attribute: 'stop-at-ends', type: Boolean })
|
|
216
260
|
], HelixHeadlessToolbar.prototype, "stopAtEnds", void 0);
|
|
217
|
-
HelixHeadlessToolbar = __decorate([
|
|
261
|
+
HelixHeadlessToolbar = HelixHeadlessToolbar_1 = __decorate([
|
|
218
262
|
customElement('helix-headless-toolbar')
|
|
219
263
|
], HelixHeadlessToolbar);
|
|
220
264
|
export { HelixHeadlessToolbar };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement, type Placement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, OpenPhaseController, type Placement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -27,6 +27,9 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
|
|
|
27
27
|
* `aria-describedby` pointing at the tooltip yourself to have the link in the
|
|
28
28
|
* server's markup. Where the browser has no element references, write it
|
|
29
29
|
* yourself; the tooltip warns once on first open if nothing links the two.
|
|
30
|
+
* In the `for` form the tooltip itself is out of the accessibility tree while
|
|
31
|
+
* its bubble is down, so a reader walking the page meets its words once, as
|
|
32
|
+
* the trigger's description.
|
|
30
33
|
*
|
|
31
34
|
* The tooltip shows on hover and on focus. It hides on pointer leave, on blur,
|
|
32
35
|
* on Escape, and when the trigger is activated. The pointer can move from the
|
|
@@ -65,6 +68,8 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
|
|
|
65
68
|
* @csspart tooltip-right - Added to `tooltip` while the bubble is right of its trigger.
|
|
66
69
|
* @csspart tooltip-top - Added to `tooltip` while the bubble is above its trigger.
|
|
67
70
|
*
|
|
71
|
+
* @cssstate entering - From the moment the bubble shows until its entrance has finished.
|
|
72
|
+
* @cssstate exiting - From the moment the bubble hides until its exit has finished.
|
|
68
73
|
* @cssstate open - While the tooltip shows.
|
|
69
74
|
* @cssstate placed-bottom - While the bubble sits below its trigger.
|
|
70
75
|
* @cssstate placed-left - While the bubble sits to the left of its trigger.
|
|
@@ -236,6 +241,7 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
236
241
|
* it must stay inside, and a component often has one and not the other.
|
|
237
242
|
*/
|
|
238
243
|
private get enclosure();
|
|
244
|
+
protected readonly phases: OpenPhaseController;
|
|
239
245
|
private get bubble();
|
|
240
246
|
/**
|
|
241
247
|
* Whether there is anything to show.
|
|
@@ -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 { anchorElement, arrowReach, customElement, elementById, HelixElement, hostAria, linkDescription, MixinControllerOpen, onUnlessFalse, PopoverController, reportRuntime, sideOf, unlinkDescription, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { anchorElement, arrowReach, customElement, elementById, HelixElement, hostAria, linkDescription, MixinControllerOpen, OpenPhaseController, onUnlessFalse, PopoverController, reportRuntime, sideOf, unlinkDescription, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { focusTarget } from '../focus-target.js';
|
|
@@ -51,6 +51,14 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
51
51
|
surface: () => this.partNamed('tooltip'),
|
|
52
52
|
within: () => this.enclosure,
|
|
53
53
|
});
|
|
54
|
+
this.phases = new OpenPhaseController(this, {
|
|
55
|
+
mark: {
|
|
56
|
+
entering: (on) => this.toggleState('entering', on),
|
|
57
|
+
exiting: (on) => this.toggleState('exiting', on),
|
|
58
|
+
},
|
|
59
|
+
open: () => this.open,
|
|
60
|
+
surface: () => this.partNamed('tooltip'),
|
|
61
|
+
});
|
|
54
62
|
this.handleContentChange = () => {
|
|
55
63
|
this.requestUpdate();
|
|
56
64
|
};
|
|
@@ -335,6 +343,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
335
343
|
describedBy: this.hasContent ? [bubble] : [],
|
|
336
344
|
label: this.describedText,
|
|
337
345
|
});
|
|
346
|
+
this.internals.ariaHidden = this.for !== '' && !this.open ? 'true' : null;
|
|
338
347
|
}
|
|
339
348
|
render() {
|
|
340
349
|
const side = this.side;
|