@fusion.dev/helix-headless 0.147.0 → 0.149.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 +11222 -2332
- package/dist/accordion/item/accordion-item.d.ts +5 -2
- package/dist/accordion/item/accordion-item.js +11 -7
- package/dist/accordion/root/accordion-root.js +4 -6
- package/dist/announcement/root/announcement-root.d.ts +61 -5
- package/dist/announcement/root/announcement-root.js +126 -20
- package/dist/area-chart/root/area-chart-root.d.ts +11 -0
- package/dist/area-chart/root/area-chart-root.js +21 -9
- package/dist/avatar/group/avatar-group.d.ts +10 -2
- package/dist/avatar/group/avatar-group.js +10 -5
- package/dist/badge/count.d.ts +19 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +6 -2
- package/dist/badge/root/badge-root.js +8 -22
- package/dist/bar-chart/root/bar-chart-root.d.ts +13 -1
- package/dist/bar-chart/root/bar-chart-root.js +17 -4
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +2 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +8 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +5 -2
- package/dist/button/root/button-root.d.ts +10 -1
- package/dist/button/root/button-root.js +3 -2
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +144 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/callout/root/callout-root.d.ts +16 -2
- package/dist/callout/root/callout-root.js +16 -4
- package/dist/canvas/describe.d.ts +10 -0
- package/dist/canvas/describe.js +9 -0
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/neighbor.d.ts +17 -0
- package/dist/canvas/neighbor.js +1 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +8 -3
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +168 -9
- package/dist/canvas/root/canvas-root.js +239 -69
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/carousel/root/carousel-root.d.ts +9 -3
- package/dist/carousel/root/carousel-root.js +17 -10
- package/dist/chat/composer/chat-composer.d.ts +5 -0
- package/dist/chat/composer/chat-composer.js +4 -1
- package/dist/chat/message/chat-message.d.ts +9 -5
- package/dist/chat/message/chat-message.js +8 -4
- package/dist/chat/naming.js +2 -2
- package/dist/chat/root/chat-root.d.ts +40 -4
- package/dist/chat/root/chat-root.js +38 -14
- package/dist/checkbox/root/checkbox-root.d.ts +11 -0
- package/dist/checkbox/root/checkbox-root.js +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +24 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +28 -12
- package/dist/checkbox-group/select-all.d.ts +11 -0
- package/dist/checkbox-group/select-all.js +5 -0
- package/dist/code-block/root/code-block-root.d.ts +20 -8
- package/dist/code-block/root/code-block-root.js +16 -5
- package/dist/color-input/root/color-input-root.d.ts +13 -0
- package/dist/color-input/root/color-input-root.js +18 -5
- package/dist/color-picker/root/color-picker-root.d.ts +19 -3
- package/dist/color-picker/root/color-picker-root.js +52 -24
- package/dist/color-picker/wheel.d.ts +11 -0
- package/dist/color-picker/wheel.js +9 -0
- package/dist/combobox/root/combobox-root.d.ts +106 -18
- package/dist/combobox/root/combobox-root.js +101 -26
- package/dist/command/root/command-root.d.ts +19 -9
- package/dist/command/root/command-root.js +9 -4
- package/dist/copy-button/root/copy-button-root.d.ts +5 -0
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/root/data-table-root.d.ts +171 -29
- package/dist/data-table/root/data-table-root.js +284 -161
- package/dist/date-input/root/date-input-root.d.ts +32 -9
- package/dist/date-input/root/date-input-root.js +66 -44
- package/dist/date-picker/root/date-picker-root.d.ts +38 -15
- package/dist/date-picker/root/date-picker-root.js +52 -33
- package/dist/description-list/item/description-list-item.d.ts +4 -0
- package/dist/description-list/item/description-list-item.js +7 -1
- package/dist/dialog/root/dialog-root.d.ts +12 -1
- package/dist/dialog/root/dialog-root.js +11 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.d.ts +5 -0
- package/dist/donut-chart/root/donut-chart-root.js +8 -5
- package/dist/drawer/root/drawer-root.d.ts +12 -1
- package/dist/drawer/root/drawer-root.js +9 -2
- package/dist/drilldown/item/drilldown-item.js +3 -4
- package/dist/drilldown/root/drilldown-root.d.ts +5 -0
- package/dist/drilldown/root/drilldown-root.js +4 -1
- package/dist/element-events.generated.js +26 -3
- package/dist/empty/root/empty-root.d.ts +17 -3
- package/dist/empty/root/empty-root.js +29 -5
- package/dist/file-input/root/file-input-root.d.ts +18 -3
- package/dist/file-input/root/file-input-root.js +34 -18
- package/dist/file-input/status.js +2 -1
- package/dist/filter-input/chip/filter-chip.d.ts +13 -0
- package/dist/filter-input/chip/filter-chip.js +7 -3
- package/dist/filter-input/menu/filter-menu.d.ts +5 -0
- package/dist/filter-input/menu/filter-menu.js +3 -1
- package/dist/filter-input/root/filter-input-root.d.ts +20 -3
- package/dist/filter-input/root/filter-input-root.js +8 -4
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +2 -1
- package/dist/format-date/options.js +9 -38
- package/dist/format-date/root/format-date-root.d.ts +55 -5
- package/dist/format-date/root/format-date-root.js +29 -34
- package/dist/graph/root/graph-model.d.ts +11 -0
- package/dist/graph/root/graph-model.js +4 -0
- package/dist/graph/root/graph-root.d.ts +101 -14
- package/dist/graph/root/graph-root.js +140 -46
- package/dist/heatmap/root/heatmap-root.d.ts +37 -4
- package/dist/heatmap/root/heatmap-root.js +51 -16
- package/dist/icon-button/root/icon-button-root.d.ts +5 -0
- package/dist/icon-button/root/icon-button-root.js +1 -0
- package/dist/image/root/image-root.d.ts +11 -0
- package/dist/input/root/input-root.d.ts +5 -0
- package/dist/input/root/input-root.js +4 -1
- package/dist/kbd/root/kbd-root.js +1 -2
- package/dist/legend/root/legend-root.js +4 -17
- package/dist/lightbox/root/lightbox-root.d.ts +14 -4
- package/dist/lightbox/root/lightbox-root.js +25 -7
- package/dist/line-chart/root/line-chart-root.d.ts +5 -0
- package/dist/line-chart/root/line-chart-root.js +4 -2
- package/dist/list/item/list-item.d.ts +32 -0
- package/dist/list/item/list-item.js +34 -7
- package/dist/list/root/list-root.d.ts +87 -0
- package/dist/list/root/list-root.js +119 -23
- package/dist/listbox/reorder/index.d.ts +1 -0
- package/dist/listbox/reorder/index.js +4 -0
- package/dist/listbox/reorder/listbox-reorder.d.ts +83 -0
- package/dist/listbox/reorder/listbox-reorder.js +151 -0
- package/dist/listbox/root/listbox-root.d.ts +185 -33
- package/dist/listbox/root/listbox-root.js +166 -136
- package/dist/loader/root/loader-root.d.ts +5 -0
- package/dist/loader/root/loader-root.js +3 -1
- package/dist/map/area/map-area.d.ts +5 -0
- package/dist/map/area/map-area.js +3 -1
- package/dist/map/buildings/map-buildings.d.ts +5 -0
- package/dist/map/buildings/map-buildings.js +3 -1
- package/dist/map/contours/map-contours.d.ts +5 -0
- package/dist/map/contours/map-contours.js +3 -1
- package/dist/map/landcover/map-landcover.d.ts +5 -0
- package/dist/map/landcover/map-landcover.js +3 -1
- package/dist/map/marker/map-marker.d.ts +18 -2
- package/dist/map/marker/map-marker.js +13 -5
- package/dist/map/points/map-points.d.ts +5 -0
- package/dist/map/points/map-points.js +6 -4
- package/dist/map/position/map-position.d.ts +5 -0
- package/dist/map/position/map-position.js +3 -1
- package/dist/map/raster/map-raster.d.ts +5 -0
- package/dist/map/raster/map-raster.js +3 -1
- package/dist/map/root/map-root.d.ts +73 -16
- package/dist/map/root/map-root.js +122 -44
- package/dist/map/route/map-route.d.ts +5 -0
- package/dist/map/route/map-route.js +3 -1
- package/dist/map/terrain/map-terrain.d.ts +5 -0
- package/dist/map/terrain/map-terrain.js +3 -1
- package/dist/megamenu/root/megamenu-root.js +4 -11
- package/dist/menu/root/menu-root.d.ts +7 -2
- package/dist/menu/root/menu-root.js +3 -1
- package/dist/meter/root/meter-root.d.ts +16 -3
- package/dist/meter/root/meter-root.js +12 -5
- package/dist/navigation/root/navigation-root.d.ts +5 -0
- package/dist/navigation/root/navigation-root.js +7 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +17 -1
- package/dist/notifications/notification/notification.js +6 -2
- package/dist/notifications/root/notifications-root.d.ts +49 -5
- package/dist/notifications/root/notifications-root.js +36 -8
- package/dist/number-input/root/number-input-root.d.ts +21 -8
- package/dist/number-input/root/number-input-root.js +26 -11
- package/dist/object-inspector/root/object-inspector-root.d.ts +56 -13
- package/dist/object-inspector/root/object-inspector-root.js +41 -30
- package/dist/outline/root/outline-root.d.ts +5 -0
- package/dist/outline/root/outline-root.js +3 -1
- package/dist/pagination/root/pagination-root.d.ts +7 -1
- package/dist/pagination/root/pagination-root.js +16 -7
- package/dist/pagination/size/pagination-size.d.ts +8 -3
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pagination/summary/pagination-summary.d.ts +8 -6
- package/dist/pagination/summary/pagination-summary.js +4 -9
- package/dist/pin-input/code.d.ts +23 -0
- package/dist/pin-input/code.js +21 -0
- package/dist/pin-input/root/pin-input-root.d.ts +9 -3
- package/dist/pin-input/root/pin-input-root.js +13 -23
- package/dist/popover/root/popover-root.d.ts +12 -2
- package/dist/popover/root/popover-root.js +10 -4
- package/dist/progress/root/progress-root.d.ts +7 -2
- package/dist/progress/root/progress-root.js +5 -2
- package/dist/qr-code/name.d.ts +3 -2
- package/dist/qr-code/name.js +2 -2
- package/dist/qr-code/root/qr-code-root.d.ts +26 -5
- package/dist/qr-code/root/qr-code-root.js +27 -6
- package/dist/radio/group/radio-group.d.ts +11 -0
- package/dist/radio/group/radio-group.js +8 -2
- package/dist/rating/root/rating-root.d.ts +12 -1
- package/dist/rating/root/rating-root.js +10 -3
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +22 -8
- package/dist/scatter-chart/root/scatter-chart-root.js +25 -23
- package/dist/select/root/select-root.d.ts +67 -8
- package/dist/select/root/select-root.js +45 -11
- package/dist/skip-link/root/skip-link-root.d.ts +5 -0
- package/dist/skip-link/root/skip-link-root.js +3 -1
- package/dist/slider/root/slider-root.d.ts +7 -2
- package/dist/slider/root/slider-root.js +11 -5
- package/dist/sparkline/readings.d.ts +15 -5
- package/dist/sparkline/readings.js +3 -3
- package/dist/sparkline/root/sparkline-root.d.ts +9 -4
- package/dist/sparkline/root/sparkline-root.js +9 -3
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +26 -1
- package/dist/speed-dial/item/speed-dial-item.js +41 -3
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +85 -1
- package/dist/speed-dial/root/speed-dial-root.js +117 -5
- package/dist/splitter/root/splitter-root.d.ts +12 -3
- package/dist/splitter/root/splitter-root.js +22 -4
- package/dist/steps/root/steps-root.d.ts +9 -2
- package/dist/steps/root/steps-root.js +6 -3
- package/dist/steps/step/step.d.ts +12 -0
- package/dist/steps/step/step.js +11 -2
- package/dist/switch/root/switch-root.d.ts +11 -0
- package/dist/switch/root/switch-root.js +8 -2
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +11 -4
- package/dist/table/column/table-column.js +15 -10
- package/dist/table/grid-controller.d.ts +122 -0
- package/dist/table/grid-controller.js +299 -0
- package/dist/table/root/table-root.d.ts +154 -8
- package/dist/table/root/table-root.js +197 -38
- package/dist/table/row/table-row.d.ts +55 -1
- package/dist/table/row/table-row.js +60 -7
- package/dist/tabs/root/tabs-root.d.ts +5 -0
- package/dist/tabs/root/tabs-root.js +3 -1
- package/dist/tag/group/tag-group.d.ts +5 -0
- package/dist/tag/group/tag-group.js +8 -15
- package/dist/tag/root/tag-root.d.ts +14 -1
- package/dist/tag/root/tag-root.js +11 -8
- package/dist/textarea/root/textarea-root.d.ts +5 -0
- package/dist/textarea/root/textarea-root.js +3 -1
- package/dist/time-input/root/time-input-root.d.ts +14 -7
- package/dist/time-input/root/time-input-root.js +43 -32
- package/dist/time-picker/root/time-picker-root.d.ts +16 -7
- package/dist/time-picker/root/time-picker-root.js +28 -12
- package/dist/toast/item/toast-item.d.ts +13 -3
- package/dist/toast/item/toast-item.js +2 -0
- package/dist/toast/root/toast-root.d.ts +22 -2
- package/dist/toast/root/toast-root.js +24 -17
- package/dist/toggle/group/toggle-group.js +3 -5
- package/dist/toolbar/root/toolbar-root.d.ts +36 -0
- package/dist/toolbar/root/toolbar-root.js +43 -9
- package/dist/tooltip/root/tooltip-root.d.ts +27 -17
- package/dist/tooltip/root/tooltip-root.js +1 -2
- package/dist/tour/root/tour-root.d.ts +8 -2
- package/dist/tour/root/tour-root.js +4 -2
- package/dist/tour/stop/tour-stop.d.ts +5 -0
- package/dist/tour/stop/tour-stop.js +6 -1
- package/dist/tree/grip.d.ts +5 -0
- package/dist/tree/grip.js +1 -0
- package/dist/tree/item/tree-item.d.ts +24 -0
- package/dist/tree/item/tree-item.js +27 -5
- package/dist/tree/root/tree-root.d.ts +66 -1
- package/dist/tree/root/tree-root.js +77 -5
- package/dist/trend/root/trend-root.d.ts +20 -4
- package/dist/trend/root/trend-root.js +20 -5
- package/dist/video/root/video-root.d.ts +23 -3
- package/dist/video/root/video-root.js +56 -15
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +5 -0
- package/dist/video-playlist/root/video-playlist-root.js +3 -1
- package/dist/virtual-list/root/virtual-list-root.d.ts +19 -3
- package/dist/virtual-list/root/virtual-list-root.js +10 -19
- package/lint.json +1 -1
- package/package.json +7 -6
- package/types/jsx.d.ts +6005 -2114
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1594 -676
- package/types/words.d.ts +3280 -0
- package/dist/kbd/keys.d.ts +0 -29
- package/dist/kbd/keys.js +0 -52
- package/dist/toast/hotkey.d.ts +0 -22
- package/dist/toast/hotkey.js +0 -23
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.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 { clockLocale, commaList, customElement, dayPeriod,
|
|
7
|
+
import { clockLocale, commaList, customElement, dayPeriod, formatWords, HelixFormElement, hostWords, inlineStep, isTwelveHour, MixinControllerValue, MixinPickerFeedback, nearestTime, offeredTimes, reportValues, secondsAsValue, timeBarred, timeFault, valueAsSeconds, wheelParts, wholeHour, words, wordsLocale, writeClock, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
@@ -14,12 +14,15 @@ import '../../option/index.js';
|
|
|
14
14
|
let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerFeedback(MixinControllerValue(HelixFormElement)) {
|
|
15
15
|
constructor() {
|
|
16
16
|
super(...arguments);
|
|
17
|
+
this.badInputMessage = '{mode, select, single {Enter a time as {shape}.} other {Enter times as {shape}, separated by commas.}}';
|
|
17
18
|
this.disableTimes = '';
|
|
18
19
|
this.label = 'Time';
|
|
19
20
|
this.locale = '';
|
|
20
21
|
this.manual = false;
|
|
21
22
|
this.max = '23:59';
|
|
22
23
|
this.min = '00:00';
|
|
24
|
+
this.rangeOverflowMessage = 'Choose a time at or before {max}.';
|
|
25
|
+
this.rangeUnderflowMessage = 'Choose a time at or after {min}.';
|
|
23
26
|
this.handleListInput = (event) => {
|
|
24
27
|
event.stopPropagation();
|
|
25
28
|
};
|
|
@@ -76,6 +79,9 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
76
79
|
this.required = false;
|
|
77
80
|
this.seconds = false;
|
|
78
81
|
this.step = 15;
|
|
82
|
+
this.stepMismatchMessage = 'Choose one of the times on offer.';
|
|
83
|
+
this.unavailableMessage = 'Choose a time that is available.';
|
|
84
|
+
this.valueMissingMessage = 'Choose a time.';
|
|
79
85
|
this.listRevealed = false;
|
|
80
86
|
this.naming = undefined;
|
|
81
87
|
this.handleColumnsKeydown = (event) => {
|
|
@@ -93,8 +99,9 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
93
99
|
next.focus();
|
|
94
100
|
};
|
|
95
101
|
}
|
|
102
|
+
static { this.words = 'helix-time-picker'; }
|
|
96
103
|
get language() {
|
|
97
|
-
return
|
|
104
|
+
return wordsLocale(this);
|
|
98
105
|
}
|
|
99
106
|
get times() {
|
|
100
107
|
return offeredTimes(this.min, this.max, this.step, this.seconds);
|
|
@@ -183,21 +190,21 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
183
190
|
case 'rangeUnderflow':
|
|
184
191
|
return [
|
|
185
192
|
'rangeUnderflow',
|
|
186
|
-
|
|
193
|
+
formatWords(this, 'rangeUnderflowMessage', {
|
|
187
194
|
min: writeClock(this.min, this.clock, this.seconds),
|
|
188
195
|
}),
|
|
189
196
|
];
|
|
190
197
|
case 'rangeOverflow':
|
|
191
198
|
return [
|
|
192
199
|
'rangeOverflow',
|
|
193
|
-
|
|
200
|
+
formatWords(this, 'rangeOverflowMessage', {
|
|
194
201
|
max: writeClock(this.max, this.clock, this.seconds),
|
|
195
202
|
}),
|
|
196
203
|
];
|
|
197
204
|
case 'unavailable':
|
|
198
|
-
return ['badInput', this.unavailableMessage
|
|
205
|
+
return ['badInput', this.unavailableMessage];
|
|
199
206
|
case 'stepMismatch':
|
|
200
|
-
return ['stepMismatch', this.stepMismatchMessage
|
|
207
|
+
return ['stepMismatch', this.stepMismatchMessage];
|
|
201
208
|
default:
|
|
202
209
|
return undefined;
|
|
203
210
|
}
|
|
@@ -205,16 +212,15 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
205
212
|
reportRequired() {
|
|
206
213
|
const anchor = this.partNamed('list') ?? undefined;
|
|
207
214
|
if (this.required && this.value === '') {
|
|
208
|
-
this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage
|
|
215
|
+
this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage, anchor);
|
|
209
216
|
return;
|
|
210
217
|
}
|
|
211
218
|
const held = this.held;
|
|
212
219
|
if (held.length > 0 && held.some((one) => valueAsSeconds(one) === null)) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
: `Enter times as ${shape}, separated by commas.`), anchor);
|
|
220
|
+
this.internals.setValidity({ badInput: true }, formatWords(this, 'badInputMessage', {
|
|
221
|
+
mode: this.mode ?? 'single',
|
|
222
|
+
shape: this.seconds ? 'HH:mm:ss' : 'HH:mm',
|
|
223
|
+
}), anchor);
|
|
218
224
|
return;
|
|
219
225
|
}
|
|
220
226
|
for (const one of held) {
|
|
@@ -256,6 +262,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
256
262
|
willUpdate(changed) {
|
|
257
263
|
super.willUpdate(changed);
|
|
258
264
|
this.report();
|
|
265
|
+
this.toggleState('blank', this.value === '');
|
|
259
266
|
}
|
|
260
267
|
updated(changed) {
|
|
261
268
|
super.updated(changed);
|
|
@@ -277,6 +284,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
277
284
|
return html `<${this.tag('listbox')}
|
|
278
285
|
part="column"
|
|
279
286
|
data-column=${part}
|
|
287
|
+
aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
|
|
280
288
|
aria-invalid=${this.marked ? 'true' : nothing}
|
|
281
289
|
exportparts="empty: column-empty, error: column-error, feedback: column-feedback, filter-icon: column-filter-icon,
|
|
282
290
|
filter-mark: column-filter-mark, hint: column-hint, items: column-items, label: column-label,
|
|
@@ -328,6 +336,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
328
336
|
renderList() {
|
|
329
337
|
return html `<${this.tag('listbox')}
|
|
330
338
|
part="list"
|
|
339
|
+
aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
|
|
331
340
|
aria-invalid=${this.marked ? 'true' : nothing}
|
|
332
341
|
exportparts="empty: list-empty, error: list-error, feedback: list-feedback, filter-icon: list-filter-icon,
|
|
333
342
|
filter-mark: list-filter-mark, hint: list-hint, items: list-items, label: list-label,
|
|
@@ -382,6 +391,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinPickerF
|
|
|
382
391
|
}
|
|
383
392
|
};
|
|
384
393
|
__decorate([
|
|
394
|
+
words,
|
|
385
395
|
property({ attribute: 'bad-input-message' })
|
|
386
396
|
], HelixHeadlessTimePicker.prototype, "badInputMessage", void 0);
|
|
387
397
|
__decorate([
|
|
@@ -394,6 +404,7 @@ __decorate([
|
|
|
394
404
|
property({ attribute: 'hour-label' })
|
|
395
405
|
], HelixHeadlessTimePicker.prototype, "hourLabel", void 0);
|
|
396
406
|
__decorate([
|
|
407
|
+
words,
|
|
397
408
|
property()
|
|
398
409
|
], HelixHeadlessTimePicker.prototype, "label", void 0);
|
|
399
410
|
__decorate([
|
|
@@ -418,9 +429,11 @@ __decorate([
|
|
|
418
429
|
property({ reflect: true })
|
|
419
430
|
], HelixHeadlessTimePicker.prototype, "mode", void 0);
|
|
420
431
|
__decorate([
|
|
432
|
+
words,
|
|
421
433
|
property({ attribute: 'range-overflow-message' })
|
|
422
434
|
], HelixHeadlessTimePicker.prototype, "rangeOverflowMessage", void 0);
|
|
423
435
|
__decorate([
|
|
436
|
+
words,
|
|
424
437
|
property({ attribute: 'range-underflow-message' })
|
|
425
438
|
], HelixHeadlessTimePicker.prototype, "rangeUnderflowMessage", void 0);
|
|
426
439
|
__decorate([
|
|
@@ -439,12 +452,15 @@ __decorate([
|
|
|
439
452
|
property({ type: Number })
|
|
440
453
|
], HelixHeadlessTimePicker.prototype, "step", void 0);
|
|
441
454
|
__decorate([
|
|
455
|
+
words,
|
|
442
456
|
property({ attribute: 'step-mismatch-message' })
|
|
443
457
|
], HelixHeadlessTimePicker.prototype, "stepMismatchMessage", void 0);
|
|
444
458
|
__decorate([
|
|
459
|
+
words,
|
|
445
460
|
property({ attribute: 'unavailable-message' })
|
|
446
461
|
], HelixHeadlessTimePicker.prototype, "unavailableMessage", void 0);
|
|
447
462
|
__decorate([
|
|
463
|
+
words,
|
|
448
464
|
property({ attribute: 'value-missing-message' })
|
|
449
465
|
], HelixHeadlessTimePicker.prototype, "valueMissingMessage", void 0);
|
|
450
466
|
__decorate([
|
|
@@ -10,7 +10,8 @@ declare const HelixHeadlessToastItem_base: (new (...args: any[]) => import("@fus
|
|
|
10
10
|
*
|
|
11
11
|
* **Each item runs its own timer.** A timer held by the region would restart
|
|
12
12
|
* with each new message, and the last of three messages would stay for nine
|
|
13
|
-
* seconds.
|
|
13
|
+
* seconds. It pauses while the pointer or focus is on the message, and while
|
|
14
|
+
* the page is hidden, so a message is not spent in a background tab.
|
|
14
15
|
*
|
|
15
16
|
* **Each message is an `alertdialog` named by its words**, which is how a reader
|
|
16
17
|
* who moves into the stack hears which message they are on. Give it a
|
|
@@ -58,6 +59,13 @@ declare const HelixHeadlessToastItem_base: (new (...args: any[]) => import("@fus
|
|
|
58
59
|
* @cssproperty --toast-swipe-x - How far a swipe has moved the message across, in pixels, toward the right.
|
|
59
60
|
*/
|
|
60
61
|
export declare class HelixHeadlessToastItem extends HelixHeadlessToastItem_base {
|
|
62
|
+
/**
|
|
63
|
+
* The key this part's words are registered under, its styled tag. The close
|
|
64
|
+
* control's `dismiss-label` comes from a mixin other families share, and
|
|
65
|
+
* registers as `{ 'helix-toast-item': { dismissLabel: 'Schließen' } }` once
|
|
66
|
+
* that mixin declares it a word.
|
|
67
|
+
*/
|
|
68
|
+
static words: string;
|
|
61
69
|
/**
|
|
62
70
|
* How long the message stays, in milliseconds. When it is not set, the
|
|
63
71
|
* message stays until it is dismissed.
|
|
@@ -85,8 +93,10 @@ export declare class HelixHeadlessToastItem extends HelixHeadlessToastItem_base
|
|
|
85
93
|
/** Writes how far a swipe has moved the message toward the end of the line. */
|
|
86
94
|
private slide;
|
|
87
95
|
/**
|
|
88
|
-
* The dismiss timer, which pauses while a reader is on the message and
|
|
89
|
-
* continues from what was left.
|
|
96
|
+
* The dismiss timer, which pauses while a reader is on the message, and
|
|
97
|
+
* while the page is hidden, and continues from what was left. A message that
|
|
98
|
+
* arrives in a background tab waits for the reader to come back, as React
|
|
99
|
+
* Aria's toast queue does.
|
|
90
100
|
*
|
|
91
101
|
* Paused is said on the host so the indicator can freeze with the clock. A
|
|
92
102
|
* `data-` attribute rather than a property, because it is written after
|
|
@@ -35,6 +35,7 @@ let HelixHeadlessToastItem = class HelixHeadlessToastItem extends MixinDismissib
|
|
|
35
35
|
done: () => {
|
|
36
36
|
this.dismiss();
|
|
37
37
|
},
|
|
38
|
+
holdWhileHidden: true,
|
|
38
39
|
paused: (paused) => {
|
|
39
40
|
this.toggleAttribute('data-paused', paused);
|
|
40
41
|
},
|
|
@@ -58,6 +59,7 @@ let HelixHeadlessToastItem = class HelixHeadlessToastItem extends MixinDismissib
|
|
|
58
59
|
});
|
|
59
60
|
};
|
|
60
61
|
}
|
|
62
|
+
static { this.words = 'helix-toast-item'; }
|
|
61
63
|
get open() {
|
|
62
64
|
return this.openState ?? true;
|
|
63
65
|
}
|
|
@@ -63,9 +63,17 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
63
63
|
* @csspart region - The stack the messages are in. It is in the top layer while a message shows, and takes focus from `hotkey` where no message holds a control.
|
|
64
64
|
*/
|
|
65
65
|
export declare class HelixHeadlessToast extends HelixElement {
|
|
66
|
+
/**
|
|
67
|
+
* The key this family's words are registered under, its styled tag:
|
|
68
|
+
* `registerWords('de', { 'helix-toast': { label: 'Benachrichtigungen ({hotkey})' } })`.
|
|
69
|
+
* A message's own words are under `helix-toast-item`.
|
|
70
|
+
*/
|
|
71
|
+
static words: string;
|
|
66
72
|
/**
|
|
67
73
|
* The key that takes focus to the stack and back, such as `F8` or `Alt+T`:
|
|
68
|
-
* keys joined by `+`, the last one the key
|
|
74
|
+
* keys joined by `+`, the last one the key, as `Announcement`'s `hotkey`
|
|
75
|
+
* reads them: `mod` is Command on Apple devices and Control elsewhere.
|
|
76
|
+
* Empty turns it off.
|
|
69
77
|
*/
|
|
70
78
|
hotkey: string;
|
|
71
79
|
/**
|
|
@@ -106,12 +114,24 @@ export declare class HelixHeadlessToast extends HelixElement {
|
|
|
106
114
|
/** What the assertive region is saying. */
|
|
107
115
|
private urgent;
|
|
108
116
|
private readonly hush;
|
|
117
|
+
/**
|
|
118
|
+
* Words waiting for the next frame: the polite ones and the urgent ones.
|
|
119
|
+
*
|
|
120
|
+
* Collected rather than written straight in, because the accessibility tree
|
|
121
|
+
* is built once a frame: two messages that arrive in separate tasks of one
|
|
122
|
+
* frame would otherwise each overwrite the region, and only the second
|
|
123
|
+
* would be heard.
|
|
124
|
+
*/
|
|
125
|
+
private readonly pending;
|
|
126
|
+
/** Whether a frame is already coming to say what is pending. */
|
|
127
|
+
private filling;
|
|
109
128
|
/**
|
|
110
129
|
* Says messages that have just arrived, each once, `danger` ones assertively.
|
|
111
130
|
*
|
|
112
131
|
* Emptied first and filled a frame later, so a message with the same words
|
|
113
132
|
* as the one before is still a change, and so a region the stack has just
|
|
114
|
-
* shown is in the accessibility tree before its words land.
|
|
133
|
+
* shown is in the accessibility tree before its words land. Every message
|
|
134
|
+
* that arrives before that frame is said in it, each as its own sentence.
|
|
115
135
|
*/
|
|
116
136
|
private announce;
|
|
117
137
|
/**
|
|
@@ -4,11 +4,10 @@ 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, DelayController, deepActiveElement, deepContains, FocusScopeController,
|
|
7
|
+
import { animationsFinished, customElement, DelayController, deepActiveElement, deepContains, FocusScopeController, focusableElements, formatWords, HelixElement, hostAria, matchesChord, onApple, scrollHolders, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
|
-
import {
|
|
11
|
-
import { messageWords } from '../words.js';
|
|
10
|
+
import { joinSaid, messageWords } from '../words.js';
|
|
12
11
|
let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
13
12
|
constructor() {
|
|
14
13
|
super(...arguments);
|
|
@@ -17,6 +16,8 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
17
16
|
this.said = '';
|
|
18
17
|
this.urgent = '';
|
|
19
18
|
this.hush = new DelayController(this, { renders: false });
|
|
19
|
+
this.pending = { said: [], urgent: [] };
|
|
20
|
+
this.filling = false;
|
|
20
21
|
this.scope = new FocusScopeController(this, {
|
|
21
22
|
contents: () => this.showing.flatMap((one) => {
|
|
22
23
|
const target = focusTarget(one);
|
|
@@ -25,7 +26,7 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
25
26
|
surface: () => this.region,
|
|
26
27
|
});
|
|
27
28
|
this.handleHotkey = (event) => {
|
|
28
|
-
if (event.defaultPrevented || !
|
|
29
|
+
if (event.defaultPrevented || !matchesChord(event, this.hotkey, onApple())) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
if (this.scope.holdsFocus) {
|
|
@@ -83,27 +84,34 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
83
84
|
});
|
|
84
85
|
};
|
|
85
86
|
}
|
|
87
|
+
static { this.words = 'helix-toast'; }
|
|
86
88
|
willUpdate(changed) {
|
|
87
89
|
super.willUpdate(changed);
|
|
88
90
|
hostAria(this.internals, {
|
|
89
|
-
label:
|
|
91
|
+
label: formatWords(this, 'label', { hotkey: this.hotkey }),
|
|
90
92
|
role: 'region',
|
|
91
93
|
});
|
|
92
94
|
}
|
|
93
95
|
announce(arrived) {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
for (const one of arrived) {
|
|
97
|
+
const words = messageWords(one);
|
|
98
|
+
if (words !== '') {
|
|
99
|
+
;
|
|
100
|
+
(isDanger(one) ? this.pending.urgent : this.pending.said).push(words);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (this.filling || (this.pending.said.length === 0 && this.pending.urgent.length === 0)) {
|
|
100
104
|
return;
|
|
101
105
|
}
|
|
106
|
+
this.filling = true;
|
|
102
107
|
this.said = '';
|
|
103
108
|
this.urgent = '';
|
|
104
109
|
const fill = () => {
|
|
105
|
-
this.
|
|
106
|
-
this.
|
|
110
|
+
this.filling = false;
|
|
111
|
+
this.said = joinSaid(this.pending.said);
|
|
112
|
+
this.urgent = joinSaid(this.pending.urgent);
|
|
113
|
+
this.pending.said = [];
|
|
114
|
+
this.pending.urgent = [];
|
|
107
115
|
this.hush.start(1000, () => {
|
|
108
116
|
this.said = '';
|
|
109
117
|
this.urgent = '';
|
|
@@ -161,8 +169,7 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
161
169
|
continue;
|
|
162
170
|
}
|
|
163
171
|
this.made.delete(one);
|
|
164
|
-
|
|
165
|
-
void Promise.allSettled(running.map((animation) => animation.finished)).then(() => one.remove());
|
|
172
|
+
void animationsFinished(one).then(() => one.remove());
|
|
166
173
|
}
|
|
167
174
|
}
|
|
168
175
|
get showing() {
|
|
@@ -194,8 +201,7 @@ let HelixHeadlessToast = class HelixHeadlessToast extends HelixElement {
|
|
|
194
201
|
}
|
|
195
202
|
}
|
|
196
203
|
lowerWhenStill(region) {
|
|
197
|
-
|
|
198
|
-
void Promise.allSettled(running.map((one) => one.finished)).then(() => {
|
|
204
|
+
void animationsFinished(this).then(() => {
|
|
199
205
|
if (this.showing.length === 0 && popoverOpen(region)) {
|
|
200
206
|
region.hidePopover();
|
|
201
207
|
}
|
|
@@ -266,6 +272,7 @@ __decorate([
|
|
|
266
272
|
property()
|
|
267
273
|
], HelixHeadlessToast.prototype, "hotkey", void 0);
|
|
268
274
|
__decorate([
|
|
275
|
+
words,
|
|
269
276
|
property()
|
|
270
277
|
], HelixHeadlessToast.prototype, "label", void 0);
|
|
271
278
|
__decorate([
|
|
@@ -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, reportValues, rovingStop, toggleValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, reportValues, rovingStop, toggleValue, toolbarAround, } 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';
|
|
@@ -139,9 +139,7 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
139
139
|
if (!this.multiple) {
|
|
140
140
|
return 'radiogroup';
|
|
141
141
|
}
|
|
142
|
-
return this
|
|
143
|
-
? 'group'
|
|
144
|
-
: 'toolbar';
|
|
142
|
+
return toolbarAround(this) ? 'group' : 'toolbar';
|
|
145
143
|
}
|
|
146
144
|
willUpdate(changed) {
|
|
147
145
|
super.willUpdate(changed);
|
|
@@ -152,7 +150,7 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
152
150
|
this.internals.setFormValue(null);
|
|
153
151
|
}
|
|
154
152
|
else if (this.multiple) {
|
|
155
|
-
reportValues(this.internals, this.name, this.values);
|
|
153
|
+
reportValues(this.internals, this.name, this.values, { state: 'entries' });
|
|
156
154
|
}
|
|
157
155
|
else {
|
|
158
156
|
this.internals.setFormValue(this.value);
|
|
@@ -12,6 +12,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
12
12
|
* focus counts as a control, including your own elements. A child that takes no
|
|
13
13
|
* focus, such as a divider, is skipped. A menu is reached at its trigger.
|
|
14
14
|
*
|
|
15
|
+
* A Divider in the toolbar is a separator across the toolbar's axis, as React
|
|
16
|
+
* Aria's is: vertical in a horizontal toolbar and horizontal in a vertical
|
|
17
|
+
* one, without an `orientation` of its own.
|
|
18
|
+
*
|
|
15
19
|
* Controls inside a plain wrapper, such as a `Button Group`, are each a stop
|
|
16
20
|
* of the toolbar's own, as React Aria's toolbar flattens a group: the arrows
|
|
17
21
|
* walk through the group's buttons and on past it, and the group takes no tab
|
|
@@ -20,6 +24,28 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
20
24
|
* The arrows wrap from the last control to the first. Set `stop-at-ends` to
|
|
21
25
|
* keep them at the ends, as Radix's `loop` set to false does.
|
|
22
26
|
*
|
|
27
|
+
* **Keyboard.** Tab enters the toolbar on the control that last had focus, the
|
|
28
|
+
* first control at the start, and the next Tab leaves it.
|
|
29
|
+
*
|
|
30
|
+
* | Key | What it does |
|
|
31
|
+
* |---|---|
|
|
32
|
+
* | Right | Moves to the next control in a horizontal toolbar, from the last back to the first. |
|
|
33
|
+
* | Left | Moves to the control before in a horizontal toolbar, from the first round to the last. |
|
|
34
|
+
* | Down, Up | The same in a vertical toolbar. |
|
|
35
|
+
* | Home, End | Moves to the first or the last control. |
|
|
36
|
+
*
|
|
37
|
+
* Left and Right swap on a right-to-left page, where the first control is on
|
|
38
|
+
* the right. The arrows across the toolbar's axis are left to the control that
|
|
39
|
+
* has focus, so a radio-style toggle group or a select answers them itself.
|
|
40
|
+
* The toolbar is `role="toolbar"` with `aria-orientation`, named by `label`.
|
|
41
|
+
*
|
|
42
|
+
* The stop moves through a control's own `focusable` property where it has
|
|
43
|
+
* one, as Button, Select and Toggle Group do. A control without one has
|
|
44
|
+
* `tabindex` written on the element that takes focus: a native element
|
|
45
|
+
* itself, or the control inside a custom element's open shadow root, so the
|
|
46
|
+
* host keeps the markup you rendered. Only a custom element whose shadow root
|
|
47
|
+
* is closed takes it on the host.
|
|
48
|
+
*
|
|
23
49
|
* A toggle group of pressed buttons, `selection-mode="multiple"`, is walked
|
|
24
50
|
* through the same way, each toggle a stop on the toolbar's axis, as React
|
|
25
51
|
* Aria's toolbar walks its toggle buttons. Another nested composite, such as a
|
|
@@ -44,8 +70,17 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
44
70
|
* @slot - The toolbar's controls.
|
|
45
71
|
*
|
|
46
72
|
* @csspart toolbar - The toolbar container.
|
|
73
|
+
*
|
|
74
|
+
* @cssstate horizontal - The controls run along a row, which is the default.
|
|
75
|
+
* @cssstate nested - The toolbar is a group inside another toolbar, which owns the keys and the tab stop.
|
|
76
|
+
* @cssstate vertical - The controls run down a column, under `orientation="vertical"`.
|
|
47
77
|
*/
|
|
48
78
|
export declare class HelixHeadlessToolbar extends HelixElement {
|
|
79
|
+
/**
|
|
80
|
+
* The key this family's words are registered under, its styled tag:
|
|
81
|
+
* `registerWords('de', { 'helix-toolbar': { label: 'Werkzeugleiste' } })`.
|
|
82
|
+
*/
|
|
83
|
+
static words: string;
|
|
49
84
|
/**
|
|
50
85
|
* The toolbar's name, read by screen readers.
|
|
51
86
|
*
|
|
@@ -159,6 +194,7 @@ export declare class HelixHeadlessToolbar extends HelixElement {
|
|
|
159
194
|
connectedCallback(): void;
|
|
160
195
|
disconnectedCallback(): void;
|
|
161
196
|
protected firstUpdated(changed: PropertyValues): void;
|
|
197
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
162
198
|
protected render(): TemplateResult;
|
|
163
199
|
}
|
|
164
200
|
declare global {
|
|
@@ -5,13 +5,14 @@ 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 HelixHeadlessToolbar_1;
|
|
8
|
-
import { AriaForwardController, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { AriaForwardController, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, toolbarAround, words, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
11
|
const KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);
|
|
12
12
|
const ownsTabStop = (node) => 'focusable' in node;
|
|
13
13
|
const NATIVE = 'a[href], button, input, select, textarea, [tabindex], [contenteditable=""], [contenteditable="true"]';
|
|
14
14
|
const TABBABLE = NATIVE.replace('[tabindex]', '[tabindex]:not([tabindex="-1"])');
|
|
15
|
+
const innerStops = new WeakMap();
|
|
15
16
|
const takesFocus = (node) => {
|
|
16
17
|
if (!(node instanceof HTMLElement) ||
|
|
17
18
|
node.hasAttribute('disabled') ||
|
|
@@ -21,11 +22,29 @@ const takesFocus = (node) => {
|
|
|
21
22
|
return (node.matches(NATIVE) ||
|
|
22
23
|
ownsTabStop(node) ||
|
|
23
24
|
node.shadowRoot?.delegatesFocus === true ||
|
|
24
|
-
node.shadowRoot?.querySelector(TABBABLE) != null
|
|
25
|
+
node.shadowRoot?.querySelector(TABBABLE) != null ||
|
|
26
|
+
innerStops.get(node)?.isConnected === true);
|
|
27
|
+
};
|
|
28
|
+
const stopOf = (node) => {
|
|
29
|
+
if (node.hasAttribute('tabindex')) {
|
|
30
|
+
return node;
|
|
31
|
+
}
|
|
32
|
+
const held = innerStops.get(node);
|
|
33
|
+
if (held?.isConnected && held.getRootNode() === node.shadowRoot) {
|
|
34
|
+
return held;
|
|
35
|
+
}
|
|
36
|
+
const inner = node.localName.includes('-')
|
|
37
|
+
? node.shadowRoot?.querySelector(TABBABLE)
|
|
38
|
+
: null;
|
|
39
|
+
if (!inner) {
|
|
40
|
+
return node;
|
|
41
|
+
}
|
|
42
|
+
innerStops.set(node, inner);
|
|
43
|
+
return inner;
|
|
25
44
|
};
|
|
26
45
|
const flattens = (node) => ownsTabStop(node) &&
|
|
27
46
|
node.selectionMode === 'multiple';
|
|
28
|
-
let HelixHeadlessToolbar =
|
|
47
|
+
let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
|
|
29
48
|
constructor() {
|
|
30
49
|
super(...arguments);
|
|
31
50
|
this.label = 'Toolbar';
|
|
@@ -58,7 +77,7 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
58
77
|
if (ownsTabStop(element)) {
|
|
59
78
|
return element.focusable;
|
|
60
79
|
}
|
|
61
|
-
return composite || element.tabIndex === 0;
|
|
80
|
+
return composite || stopOf(element).tabIndex === 0;
|
|
62
81
|
});
|
|
63
82
|
if (controls.length > 0 && !held) {
|
|
64
83
|
this.setTabStop(controls[0], false);
|
|
@@ -116,11 +135,14 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
116
135
|
if (element && 'focusItem' in element && typeof element.focusItem === 'function') {
|
|
117
136
|
element.focusItem();
|
|
118
137
|
}
|
|
119
|
-
else {
|
|
120
|
-
|
|
138
|
+
else if (element) {
|
|
139
|
+
;
|
|
140
|
+
(ownsTabStop(element) ? element : stopOf(element)).focus();
|
|
121
141
|
}
|
|
122
142
|
};
|
|
123
143
|
}
|
|
144
|
+
static { HelixHeadlessToolbar_1 = this; }
|
|
145
|
+
static { this.words = 'helix-toolbar'; }
|
|
124
146
|
get controls() {
|
|
125
147
|
const controls = [];
|
|
126
148
|
for (const child of this.children) {
|
|
@@ -189,7 +211,7 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
189
211
|
element.focusable = stop;
|
|
190
212
|
}
|
|
191
213
|
else if (foreign || this.wroteForeign) {
|
|
192
|
-
element.tabIndex = stop ? 0 : -1;
|
|
214
|
+
stopOf(element).tabIndex = stop ? 0 : -1;
|
|
193
215
|
}
|
|
194
216
|
}
|
|
195
217
|
}
|
|
@@ -206,8 +228,7 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
206
228
|
if (!parent) {
|
|
207
229
|
return false;
|
|
208
230
|
}
|
|
209
|
-
return
|
|
210
|
-
parent.closest('[role="toolbar"]') !== null);
|
|
231
|
+
return closestInstance(parent, HelixHeadlessToolbar_1) !== null || toolbarAround(this) !== null;
|
|
211
232
|
}
|
|
212
233
|
get axis() {
|
|
213
234
|
return this.orientation ?? 'horizontal';
|
|
@@ -237,6 +258,18 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
237
258
|
super.firstUpdated(changed);
|
|
238
259
|
void this.claimTabStop();
|
|
239
260
|
}
|
|
261
|
+
willUpdate(changed) {
|
|
262
|
+
super.willUpdate(changed);
|
|
263
|
+
this.toggleState('nested', this.nested);
|
|
264
|
+
this.toggleState('horizontal', this.axis === 'horizontal');
|
|
265
|
+
this.toggleState('vertical', this.axis === 'vertical');
|
|
266
|
+
if (this.hasUpdated && changed.has('orientation')) {
|
|
267
|
+
for (const child of this.children) {
|
|
268
|
+
;
|
|
269
|
+
child.requestUpdate?.();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
240
273
|
render() {
|
|
241
274
|
const nested = this.nested;
|
|
242
275
|
return html `<div
|
|
@@ -250,6 +283,7 @@ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar e
|
|
|
250
283
|
}
|
|
251
284
|
};
|
|
252
285
|
__decorate([
|
|
286
|
+
words,
|
|
253
287
|
property()
|
|
254
288
|
], HelixHeadlessToolbar.prototype, "label", void 0);
|
|
255
289
|
__decorate([
|
|
@@ -5,31 +5,33 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
|
|
|
5
5
|
* @summary A short text that appears next to an element on hover and focus.
|
|
6
6
|
*
|
|
7
7
|
* @description
|
|
8
|
-
* The trigger
|
|
8
|
+
* The trigger stays your own element. The bubble renders in the
|
|
9
9
|
* top layer through the popover API, so an ancestor with `overflow: hidden`
|
|
10
10
|
* does not clip it and no `z-index` is needed. `FloatingController` positions
|
|
11
11
|
* it and flips it to another side when the preferred side does not fit.
|
|
12
12
|
*
|
|
13
|
-
* **
|
|
14
|
-
*
|
|
13
|
+
* **Place the tooltip beside its trigger, name the trigger with `for`, and
|
|
14
|
+
* name the tooltip in the trigger's `aria-describedby`.** The description is
|
|
15
|
+
* then in your own markup, so it is in the server's HTML and in the
|
|
16
|
+
* accessibility tree at rest, in every browser, before anyone points at the
|
|
17
|
+
* trigger or focuses it:
|
|
15
18
|
*
|
|
16
19
|
* ```html
|
|
17
|
-
* <helix-headless-button id="save">Save</helix-headless-button>
|
|
18
|
-
* <helix-headless-tooltip
|
|
20
|
+
* <helix-headless-button aria-describedby="save-tip" id="save">Save</helix-headless-button>
|
|
21
|
+
* <helix-headless-tooltip content="Save your work" for="save" id="save-tip"></helix-headless-tooltip>
|
|
19
22
|
* ```
|
|
20
23
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* the trigger's description.
|
|
24
|
+
* Without the attribute, the tooltip links itself through an element reference
|
|
25
|
+
* on the control that takes focus, and it never writes into your markup before
|
|
26
|
+
* you act, so hydration stays intact. A trigger that is a Helix component is
|
|
27
|
+
* described at once, inside its own shadow root. A plain element in your
|
|
28
|
+
* markup is described when you first point at it or focus it, so a screen
|
|
29
|
+
* reader in reading mode meets it with no description until then. Where the
|
|
30
|
+
* browser has no element references, nothing links the two, and the tooltip
|
|
31
|
+
* warns once on first open. The tooltip can also wrap its trigger, which
|
|
32
|
+
* describes a Helix component and leaves a plain element undescribed. In the
|
|
33
|
+
* `for` form the tooltip itself is out of the accessibility tree while its
|
|
34
|
+
* bubble is down, so you meet its words once, as the trigger's description.
|
|
33
35
|
*
|
|
34
36
|
* The tooltip shows on hover and on focus. It hides on pointer leave, on blur,
|
|
35
37
|
* on Escape, and when the trigger is activated. The pointer can move from the
|
|
@@ -114,6 +116,14 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
114
116
|
* Names an element in the same tree, so a tooltip inside another component's
|
|
115
117
|
* shadow root points at one in that root rather than one in the document.
|
|
116
118
|
*
|
|
119
|
+
* Give the tooltip an `id` and name it in the trigger's `aria-describedby`,
|
|
120
|
+
* so the trigger is described in the server's markup and at rest:
|
|
121
|
+
*
|
|
122
|
+
* ```html
|
|
123
|
+
* <button aria-describedby="save-tip" id="save">Save</button>
|
|
124
|
+
* <helix-headless-tooltip content="Save your work" for="save" id="save-tip"></helix-headless-tooltip>
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
117
127
|
* **In React this arrives as a property and not as an attribute**, which is
|
|
118
128
|
* worth knowing before someone reads the DOM and thinks it did not take.
|
|
119
129
|
* Measured against React 19.2.8: `for` exists on the prototype, so React sets
|