@fusion.dev/helix-headless 0.142.1 → 0.144.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 +25381 -1202
- package/dist/accordion/item/accordion-item.d.ts +38 -2
- package/dist/accordion/item/accordion-item.js +38 -6
- package/dist/accordion/root/accordion-root.d.ts +23 -1
- package/dist/accordion/root/accordion-root.js +39 -3
- package/dist/announcement/root/announcement-root.d.ts +11 -7
- package/dist/announcement/root/announcement-root.js +1 -1
- package/dist/app-header/root/app-header-root.d.ts +21 -0
- package/dist/app-header/root/app-header-root.js +31 -5
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +39 -11
- package/dist/avatar/group/avatar-group.d.ts +24 -3
- package/dist/avatar/group/avatar-group.js +34 -2
- package/dist/avatar/root/avatar-root.d.ts +17 -1
- package/dist/avatar/root/avatar-root.js +31 -10
- package/dist/badge/root/badge-root.d.ts +12 -0
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
- package/dist/bar-chart/root/bar-chart-root.js +58 -21
- package/dist/blockquote/root/blockquote-root.d.ts +12 -7
- package/dist/blockquote/root/blockquote-root.js +6 -4
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
- package/dist/button/root/button-root.d.ts +84 -1
- package/dist/button/root/button-root.js +81 -3
- package/dist/callout/root/callout-root.d.ts +32 -6
- package/dist/callout/root/callout-root.js +26 -7
- package/dist/canvas/root/canvas-root.d.ts +1 -0
- package/dist/canvas/root/canvas-root.js +10 -1
- package/dist/card/root/card-root.d.ts +30 -1
- package/dist/card/root/card-root.js +38 -5
- package/dist/carousel/root/carousel-root.d.ts +47 -5
- package/dist/carousel/root/carousel-root.js +53 -21
- package/dist/chat/composer/chat-composer.d.ts +13 -11
- package/dist/chat/composer/chat-composer.js +6 -12
- package/dist/chat/message/chat-message.js +8 -1
- package/dist/chat/root/chat-root.d.ts +1 -0
- package/dist/chat/root/chat-root.js +2 -1
- package/dist/checkbox/root/checkbox-root.d.ts +7 -0
- package/dist/checkbox/root/checkbox-root.js +9 -3
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
- package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
- package/dist/code/root/code-root.d.ts +1 -1
- package/dist/code-block/lines.d.ts +13 -0
- package/dist/code-block/lines.js +2 -0
- package/dist/code-block/root/code-block-root.d.ts +49 -0
- package/dist/code-block/root/code-block-root.js +44 -3
- package/dist/color-input/root/color-input-root.d.ts +60 -2
- package/dist/color-input/root/color-input-root.js +55 -7
- package/dist/color-picker/channels.d.ts +26 -0
- package/dist/color-picker/channels.js +84 -0
- package/dist/color-picker/root/color-picker-root.d.ts +118 -12
- package/dist/color-picker/root/color-picker-root.js +183 -13
- package/dist/combobox/root/combobox-root.d.ts +126 -3
- package/dist/combobox/root/combobox-root.js +224 -21
- package/dist/command/root/command-root.d.ts +47 -10
- package/dist/command/root/command-root.js +45 -4
- package/dist/copy-button/from.d.ts +22 -0
- package/dist/copy-button/from.js +28 -0
- package/dist/copy-button/root/copy-button-root.d.ts +48 -7
- package/dist/copy-button/root/copy-button-root.js +54 -8
- package/dist/data-table/root/data-table-root.d.ts +164 -10
- package/dist/data-table/root/data-table-root.js +488 -57
- package/dist/date-input/root/date-input-root.d.ts +123 -9
- package/dist/date-input/root/date-input-root.js +147 -45
- package/dist/date-picker/root/date-picker-root.d.ts +229 -18
- package/dist/date-picker/root/date-picker-root.js +342 -46
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +101 -10
- package/dist/dialog/root/dialog-root.js +83 -4
- package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
- package/dist/donut-chart/root/donut-chart-root.js +48 -13
- package/dist/drawer/root/drawer-root.d.ts +93 -7
- package/dist/drawer/root/drawer-root.js +126 -5
- package/dist/drawer/swipe-start.d.ts +9 -0
- package/dist/drawer/swipe-start.js +12 -0
- package/dist/drilldown/item/drilldown-item.d.ts +16 -13
- package/dist/drilldown/item/drilldown-item.js +6 -2
- package/dist/drilldown/root/drilldown-root.d.ts +21 -5
- package/dist/drilldown/root/drilldown-root.js +26 -10
- package/dist/element-events.generated.js +42 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +65 -1
- package/dist/file-input/root/file-input-root.js +76 -12
- package/dist/file-input/screen.d.ts +35 -0
- package/dist/file-input/screen.js +49 -0
- package/dist/filter-input/menu/filter-menu.d.ts +9 -0
- package/dist/filter-input/menu/filter-menu.js +8 -0
- package/dist/filter-input/root/filter-input-root.d.ts +43 -6
- package/dist/filter-input/root/filter-input-root.js +89 -10
- package/dist/filter-input/suggest.d.ts +17 -0
- package/dist/filter-input/suggest.js +23 -0
- package/dist/format-date/options.d.ts +33 -0
- package/dist/format-date/options.js +42 -0
- package/dist/format-date/root/format-date-root.d.ts +62 -3
- package/dist/format-date/root/format-date-root.js +78 -37
- package/dist/graph/root/graph-root.d.ts +24 -3
- package/dist/graph/root/graph-root.js +66 -12
- package/dist/heatmap/root/buckets.d.ts +2 -1
- package/dist/heatmap/root/buckets.js +5 -1
- package/dist/heatmap/root/heatmap-root.d.ts +47 -9
- package/dist/heatmap/root/heatmap-root.js +46 -18
- package/dist/icon/index.d.ts +2 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon/registry.d.ts +37 -0
- package/dist/icon/registry.js +83 -0
- package/dist/icon/root/icon-root.d.ts +53 -6
- package/dist/icon/root/icon-root.js +72 -4
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon/set.d.ts +1 -0
- package/dist/icon/set.js +3 -0
- package/dist/icon-button/root/icon-button-root.d.ts +1 -1
- package/dist/image/root/image-root.d.ts +23 -2
- package/dist/image/root/image-root.js +23 -4
- package/dist/input/root/input-root.d.ts +62 -9
- package/dist/input/root/input-root.js +61 -5
- package/dist/kbd/root/kbd-root.d.ts +26 -11
- package/dist/kbd/root/kbd-root.js +35 -38
- package/dist/kbd/shortcut.d.ts +18 -0
- package/dist/kbd/shortcut.js +35 -0
- package/dist/legend/hidden-series.d.ts +8 -0
- package/dist/legend/hidden-series.js +13 -0
- package/dist/legend/root/legend-root.d.ts +63 -0
- package/dist/legend/root/legend-root.js +61 -7
- package/dist/lightbox/item/lightbox-item.d.ts +17 -1
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +77 -6
- package/dist/lightbox/root/lightbox-root.js +116 -5
- package/dist/line-chart/root/line-chart-root.d.ts +29 -4
- package/dist/line-chart/root/line-chart-root.js +58 -17
- package/dist/list/item/list-item.d.ts +11 -5
- package/dist/list/item/list-item.js +5 -6
- package/dist/listbox/range.d.ts +17 -0
- package/dist/listbox/range.js +5 -0
- package/dist/listbox/root/listbox-root.d.ts +184 -4
- package/dist/listbox/root/listbox-root.js +229 -23
- package/dist/loader/busy.d.ts +17 -0
- package/dist/loader/busy.js +24 -0
- package/dist/loader/root/loader-root.d.ts +37 -0
- package/dist/loader/root/loader-root.js +52 -3
- package/dist/map/root/map-root.d.ts +19 -4
- package/dist/map/root/map-root.js +36 -7
- package/dist/megamenu/root/megamenu-root.d.ts +10 -1
- package/dist/megamenu/root/megamenu-root.js +10 -1
- package/dist/menu/item/menu-item.d.ts +41 -12
- package/dist/menu/item/menu-item.js +46 -3
- package/dist/menu/root/menu-root.d.ts +32 -2
- package/dist/menu/root/menu-root.js +48 -8
- package/dist/meter/root/meter-root.d.ts +13 -0
- package/dist/meter/root/meter-root.js +24 -5
- package/dist/navigation/root/navigation-root.d.ts +10 -2
- package/dist/navigation/root/navigation-root.js +13 -2
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/group/notification-group.d.ts +1 -0
- package/dist/notifications/notification/notification.d.ts +29 -0
- package/dist/notifications/notification/notification.js +51 -3
- package/dist/notifications/root/notifications-root.d.ts +49 -0
- package/dist/notifications/root/notifications-root.js +76 -2
- package/dist/number-input/root/number-input-root.d.ts +109 -7
- package/dist/number-input/root/number-input-root.js +109 -21
- package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
- package/dist/object-inspector/root/object-inspector-root.js +92 -12
- package/dist/option/root/option-root.d.ts +58 -6
- package/dist/option/root/option-root.js +35 -5
- package/dist/outline/root/outline-root.d.ts +13 -2
- package/dist/outline/root/outline-root.js +4 -2
- package/dist/pagination/root/pagination-root.d.ts +19 -1
- package/dist/pagination/root/pagination-root.js +49 -9
- package/dist/pagination/size/pagination-size.d.ts +13 -3
- package/dist/pagination/size/pagination-size.js +7 -0
- package/dist/pin-input/format.d.ts +7 -0
- package/dist/pin-input/format.js +16 -0
- package/dist/pin-input/root/pin-input-root.d.ts +37 -0
- package/dist/pin-input/root/pin-input-root.js +48 -7
- package/dist/popover/root/popover-root.d.ts +78 -3
- package/dist/popover/root/popover-root.js +74 -5
- package/dist/progress/root/progress-root.d.ts +23 -1
- package/dist/progress/root/progress-root.js +40 -10
- package/dist/qr-code/export.d.ts +31 -0
- package/dist/qr-code/export.js +10 -0
- package/dist/qr-code/root/qr-code-root.d.ts +45 -0
- package/dist/qr-code/root/qr-code-root.js +78 -3
- package/dist/radio/group/radio-group.d.ts +64 -0
- package/dist/radio/group/radio-group.js +66 -12
- package/dist/radio/root/radio-root.d.ts +8 -5
- package/dist/radio/root/radio-root.js +1 -2
- package/dist/rating/root/rating-root.d.ts +49 -1
- package/dist/rating/root/rating-root.js +69 -10
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
- package/dist/select/root/select-root.d.ts +93 -3
- package/dist/select/root/select-root.js +111 -13
- package/dist/skeleton/root/skeleton-root.d.ts +39 -3
- package/dist/skeleton/root/skeleton-root.js +33 -4
- package/dist/skip-link/root/skip-link-root.d.ts +10 -0
- package/dist/skip-link/root/skip-link-root.js +15 -1
- package/dist/slider/root/slider-root.d.ts +59 -2
- package/dist/slider/root/slider-root.js +82 -8
- package/dist/sparkline/root/sparkline-root.d.ts +9 -10
- package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
- package/dist/speed-dial/item/speed-dial-item.js +7 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
- package/dist/speed-dial/root/speed-dial-root.js +19 -5
- package/dist/splitter/root/splitter-root.d.ts +28 -6
- package/dist/splitter/root/splitter-root.js +35 -1
- package/dist/stat/root/stat-root.d.ts +9 -1
- package/dist/stat/root/stat-root.js +15 -2
- package/dist/steps/root/steps-root.js +1 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/switch/root/switch-root.d.ts +14 -2
- package/dist/switch/root/switch-root.js +7 -1
- package/dist/table/cell/table-cell.d.ts +24 -4
- package/dist/table/cell/table-cell.js +21 -1
- package/dist/table/column/table-column.d.ts +32 -6
- package/dist/table/column/table-column.js +36 -6
- package/dist/table/root/table-root.d.ts +94 -3
- package/dist/table/root/table-root.js +128 -5
- package/dist/table/row/table-row.d.ts +7 -0
- package/dist/table/row/table-row.js +9 -1
- package/dist/tabs/root/tabs-root.d.ts +6 -1
- package/dist/tabs/root/tabs-root.js +6 -2
- package/dist/tag/group/tag-group.d.ts +107 -0
- package/dist/tag/group/tag-group.js +157 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +83 -1
- package/dist/tag/root/tag-root.js +87 -17
- package/dist/tag/selection.d.ts +10 -0
- package/dist/tag/selection.js +12 -0
- package/dist/textarea/grow.d.ts +22 -0
- package/dist/textarea/grow.js +20 -0
- package/dist/textarea/root/textarea-root.d.ts +13 -0
- package/dist/textarea/root/textarea-root.js +10 -2
- package/dist/time-input/root/time-input-root.d.ts +71 -6
- package/dist/time-input/root/time-input-root.js +110 -44
- package/dist/time-picker/root/time-picker-root.d.ts +155 -26
- package/dist/time-picker/root/time-picker-root.js +192 -63
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +16 -1
- package/dist/toast/item/toast-item.js +41 -13
- package/dist/toast/root/toast-root.d.ts +105 -8
- package/dist/toast/root/toast-root.js +209 -4
- package/dist/toggle/group/toggle-group.d.ts +95 -16
- package/dist/toggle/group/toggle-group.js +99 -13
- package/dist/toggle/root/toggle-root.d.ts +26 -11
- package/dist/toggle/root/toggle-root.js +14 -6
- package/dist/toolbar/root/toolbar-root.d.ts +55 -15
- package/dist/toolbar/root/toolbar-root.js +99 -16
- package/dist/tooltip/focus-target.d.ts +6 -0
- package/dist/tooltip/focus-target.js +9 -0
- package/dist/tooltip/root/tooltip-root.d.ts +73 -15
- package/dist/tooltip/root/tooltip-root.js +96 -7
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +67 -3
- package/dist/tour/root/tour-root.js +105 -17
- package/dist/tour/stop/tour-stop.d.ts +65 -3
- package/dist/tour/stop/tour-stop.js +61 -11
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/tree/item/tree-item.d.ts +21 -5
- package/dist/tree/item/tree-item.js +14 -4
- package/dist/tree/root/tree-root.d.ts +29 -5
- package/dist/tree/root/tree-root.js +64 -8
- package/dist/trend/root/trend-root.d.ts +36 -1
- package/dist/trend/root/trend-root.js +41 -15
- package/dist/video/root/keys.d.ts +5 -0
- package/dist/video/root/keys.js +13 -1
- package/dist/video/root/video-root.d.ts +19 -0
- package/dist/video/root/video-root.js +48 -4
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
- package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
- package/dist/video-playlist/root/video-playlist-root.js +6 -3
- package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
- package/dist/virtual-list/root/virtual-list-root.js +103 -21
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +9140 -1149
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +2089 -267
|
@@ -20,6 +20,13 @@ declare const HelixHeadlessSlider_base: (new (...args: any[]) => import("@fusion
|
|
|
20
20
|
*
|
|
21
21
|
* A range with two thumbs is two inputs stacked on one track, because there is
|
|
22
22
|
* no native two-thumb range. Each thumb keeps its own value.
|
|
23
|
+
* `min-steps-between-thumbs` keeps them that many steps apart.
|
|
24
|
+
*
|
|
25
|
+
* `format-options` writes the value with `Intl.NumberFormat` in `locale`, as a
|
|
26
|
+
* currency, a percent or a unit, and `formatter` writes it with a function of
|
|
27
|
+
* your own, such as words for a scale. Either one is what a screen reader
|
|
28
|
+
* hears, what the readout shows and what the marker labels say. `value-text`
|
|
29
|
+
* still wraps it in a sentence, with the formatted value in its place.
|
|
23
30
|
*
|
|
24
31
|
* `required` comes with the field mixin and cannot fail. A range is never
|
|
25
32
|
* empty: the platform shows its midpoint when no value is set, and `willUpdate`
|
|
@@ -33,6 +40,10 @@ declare const HelixHeadlessSlider_base: (new (...args: any[]) => import("@fusion
|
|
|
33
40
|
* @aliases Range, Range input
|
|
34
41
|
* @documentation https://fusion.dev/helix/components/slider
|
|
35
42
|
*
|
|
43
|
+
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
44
|
+
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
45
|
+
* @slot label - The label, for content richer than the `label` text.
|
|
46
|
+
*
|
|
36
47
|
* @event {Event} change - Fired when the user releases the thumb.
|
|
37
48
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired as the value changes. Cancelable: call `preventDefault()` to keep the current value.
|
|
38
49
|
* @event {Event} input - Fired after the value changes.
|
|
@@ -58,6 +69,27 @@ export declare class HelixHeadlessSlider extends HelixHeadlessSlider_base {
|
|
|
58
69
|
protected readonly aria: AriaForwardController;
|
|
59
70
|
/** Typed or dragged, so every edit is announced. See `announcesInput`. */
|
|
60
71
|
protected readonly announcesInput = true;
|
|
72
|
+
/**
|
|
73
|
+
* `Intl.NumberFormat` options the value is written with: a currency, a
|
|
74
|
+
* percent, a unit, or a number of decimals. Written as JSON in the
|
|
75
|
+
* attribute.
|
|
76
|
+
*
|
|
77
|
+
* ```html
|
|
78
|
+
* <helix-slider format-options='{"style":"currency","currency":"USD"}'></helix-slider>
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
82
|
+
/**
|
|
83
|
+
* Writes a value as text, in place of `format-options`: words for a scale,
|
|
84
|
+
* or anything `Intl.NumberFormat` cannot say. A property, since a function
|
|
85
|
+
* cannot be written in an attribute.
|
|
86
|
+
*/
|
|
87
|
+
formatter?: (value: number) => string;
|
|
88
|
+
/**
|
|
89
|
+
* The locale `format-options` writes the value in, such as `de-DE`. Empty is
|
|
90
|
+
* the reader's own.
|
|
91
|
+
*/
|
|
92
|
+
locale: string;
|
|
61
93
|
/**
|
|
62
94
|
* Shows the value at each mark.
|
|
63
95
|
*/
|
|
@@ -98,6 +130,11 @@ export declare class HelixHeadlessSlider extends HelixHeadlessSlider_base {
|
|
|
98
130
|
min: number;
|
|
99
131
|
/** The name of a range's lower thumb, read after the slider's label. */
|
|
100
132
|
minimumLabel: string;
|
|
133
|
+
/**
|
|
134
|
+
* How many steps a range's two thumbs stay apart, as Zag's
|
|
135
|
+
* `minStepsBetweenThumbs`. A thumb pushed closer stops there.
|
|
136
|
+
*/
|
|
137
|
+
minStepsBetweenThumbs: number;
|
|
101
138
|
/**
|
|
102
139
|
* The direction the track runs. `vertical` stands it on end.
|
|
103
140
|
*
|
|
@@ -123,6 +160,8 @@ export declare class HelixHeadlessSlider extends HelixHeadlessSlider_base {
|
|
|
123
160
|
* Shows the chosen value beside the track.
|
|
124
161
|
*/
|
|
125
162
|
showValue: boolean;
|
|
163
|
+
/** How far one press of an arrow key moves the thumb. */
|
|
164
|
+
step: number;
|
|
126
165
|
/**
|
|
127
166
|
* How many characters the readout has to be able to hold, widest case.
|
|
128
167
|
*
|
|
@@ -210,9 +249,27 @@ export declare class HelixHeadlessSlider extends HelixHeadlessSlider_base {
|
|
|
210
249
|
*/
|
|
211
250
|
private snapped;
|
|
212
251
|
protected willUpdate(changed: PropertyValues): void;
|
|
252
|
+
/** One number pulled into the bounds and onto the step, as a range does. */
|
|
253
|
+
private settled;
|
|
254
|
+
/**
|
|
255
|
+
* The value as a native range would hold it: a number in the bounds on the
|
|
256
|
+
* step, or for a range, two of them in order.
|
|
257
|
+
*/
|
|
258
|
+
private sanitize;
|
|
259
|
+
/** How far apart a range's thumbs stay, in the slider's own units. */
|
|
260
|
+
private get gap();
|
|
261
|
+
/** Whether the value is written by `formatter` or `format-options`. */
|
|
262
|
+
private get formats();
|
|
263
|
+
/** A value as the reader sees it: formatted where asked, the number otherwise. */
|
|
264
|
+
private said;
|
|
265
|
+
/** What a screen reader says for one thumb, where `value-text` asks. */
|
|
266
|
+
private spoken;
|
|
213
267
|
protected updated(changed: PropertyValues): void;
|
|
214
|
-
/**
|
|
215
|
-
|
|
268
|
+
/**
|
|
269
|
+
* What a screen reader says for a thumb's value, with `{value}` filled in,
|
|
270
|
+
* such as `{value} degrees`. Empty announces the number alone.
|
|
271
|
+
*/
|
|
272
|
+
valueText: string;
|
|
216
273
|
protected render(): TemplateResult;
|
|
217
274
|
}
|
|
218
275
|
declare global {
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, HelixFormElement, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, fillTemplate, formatNumber, HelixFormElement, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
@@ -14,23 +14,27 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
14
14
|
target: () => this.partNamed('control'),
|
|
15
15
|
});
|
|
16
16
|
this.announcesInput = true;
|
|
17
|
+
this.locale = '';
|
|
17
18
|
this.markerLabels = false;
|
|
18
19
|
this.markers = 0;
|
|
19
20
|
this.max = 100;
|
|
20
21
|
this.maximumLabel = 'maximum';
|
|
21
22
|
this.min = 0;
|
|
22
23
|
this.minimumLabel = 'minimum';
|
|
24
|
+
this.minStepsBetweenThumbs = 0;
|
|
23
25
|
this.range = false;
|
|
24
26
|
this.showValue = false;
|
|
27
|
+
this.step = 1;
|
|
25
28
|
this.handleInput = (event) => {
|
|
26
29
|
event.stopPropagation();
|
|
27
30
|
const control = event.target;
|
|
28
31
|
if (this.range) {
|
|
29
32
|
const [start, end] = this.bounds;
|
|
30
33
|
const moved = Number(control.value);
|
|
34
|
+
const gap = this.gap;
|
|
31
35
|
const pair = control.dataset.thumb === 'start'
|
|
32
|
-
? [Math.min(moved, end), end]
|
|
33
|
-
: [start, Math.max(moved, start)];
|
|
36
|
+
? [Math.min(moved, end - gap), end]
|
|
37
|
+
: [start, Math.max(moved, start + gap)];
|
|
34
38
|
this.requestValue(pair.join(','));
|
|
35
39
|
restoreValue(control, String(control.dataset.thumb === 'start' ? this.bounds[0] : this.bounds[1]));
|
|
36
40
|
return;
|
|
@@ -43,10 +47,10 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
43
47
|
event.stopPropagation();
|
|
44
48
|
this.announceChange();
|
|
45
49
|
};
|
|
46
|
-
this.
|
|
50
|
+
this.valueText = '';
|
|
47
51
|
}
|
|
48
52
|
get reserve() {
|
|
49
|
-
const widest = Math.max(
|
|
53
|
+
const widest = Math.max(this.said(this.min).length, this.said(this.max).length);
|
|
50
54
|
return this.range ? widest * 2 + ' to '.length : widest;
|
|
51
55
|
}
|
|
52
56
|
get precision() {
|
|
@@ -110,8 +114,57 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
110
114
|
willUpdate(changed) {
|
|
111
115
|
super.willUpdate(changed);
|
|
112
116
|
if (!this.hasUpdated && this.value === '') {
|
|
113
|
-
this.defaultValue =
|
|
117
|
+
this.defaultValue = this.range
|
|
118
|
+
? `${this.min},${this.max}`
|
|
119
|
+
: String(this.min + (this.max - this.min) / 2);
|
|
120
|
+
}
|
|
121
|
+
const clean = this.sanitize(this.value);
|
|
122
|
+
if (clean !== this.value) {
|
|
123
|
+
this.value = clean;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
settled(at) {
|
|
127
|
+
const low = Math.min(this.min, this.max);
|
|
128
|
+
const high = Math.max(this.min, this.max);
|
|
129
|
+
return Math.min(high, Math.max(low, this.snapped(Math.min(high, Math.max(low, at)))));
|
|
130
|
+
}
|
|
131
|
+
sanitize(text) {
|
|
132
|
+
if (this.range) {
|
|
133
|
+
const [from, to] = text.split(',').map((part) => Number.parseFloat(part));
|
|
134
|
+
if (from === undefined ||
|
|
135
|
+
to === undefined ||
|
|
136
|
+
!Number.isFinite(from) ||
|
|
137
|
+
!Number.isFinite(to)) {
|
|
138
|
+
return `${this.min},${this.max}`;
|
|
139
|
+
}
|
|
140
|
+
const ends = [this.settled(from), this.settled(to)].sort((a, b) => a - b);
|
|
141
|
+
return ends.join(',');
|
|
114
142
|
}
|
|
143
|
+
const parsed = Number.parseFloat(text);
|
|
144
|
+
const at = Number.isFinite(parsed) ? parsed : this.min + (this.max - this.min) / 2;
|
|
145
|
+
return String(this.settled(at));
|
|
146
|
+
}
|
|
147
|
+
get gap() {
|
|
148
|
+
return Math.max(0, this.minStepsBetweenThumbs) * this.step;
|
|
149
|
+
}
|
|
150
|
+
get formats() {
|
|
151
|
+
return this.formatter !== undefined || this.formatOptions !== undefined;
|
|
152
|
+
}
|
|
153
|
+
said(at) {
|
|
154
|
+
const number = typeof at === 'number' ? at : Number.parseFloat(at);
|
|
155
|
+
if (!Number.isFinite(number)) {
|
|
156
|
+
return String(at);
|
|
157
|
+
}
|
|
158
|
+
if (this.formatter) {
|
|
159
|
+
return this.formatter(number);
|
|
160
|
+
}
|
|
161
|
+
return this.formatOptions ? formatNumber(number, this.locale, this.formatOptions) : String(at);
|
|
162
|
+
}
|
|
163
|
+
spoken(at) {
|
|
164
|
+
if (this.valueText) {
|
|
165
|
+
return fillTemplate(this.valueText, { value: this.said(at) });
|
|
166
|
+
}
|
|
167
|
+
return this.formats ? this.said(at) : nothing;
|
|
115
168
|
}
|
|
116
169
|
updated(changed) {
|
|
117
170
|
super.updated(changed);
|
|
@@ -130,6 +183,9 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
130
183
|
step=${this.step}
|
|
131
184
|
.value=${String(at)}
|
|
132
185
|
aria-labelledby=${this.labeled ? `${this.labelId} ${which}-name` : `${which}-name`}
|
|
186
|
+
aria-valuemin=${which === 'end' ? start + this.gap : nothing}
|
|
187
|
+
aria-valuemax=${which === 'start' ? end - this.gap : nothing}
|
|
188
|
+
aria-valuetext=${this.spoken(at)}
|
|
133
189
|
aria-describedby=${this.describedBy ?? nothing}
|
|
134
190
|
aria-invalid=${this.invalidity ?? nothing}
|
|
135
191
|
?disabled=${this.isDisabled}
|
|
@@ -161,6 +217,7 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
161
217
|
step=${this.step}
|
|
162
218
|
.value=${this.value}
|
|
163
219
|
name=${this.name || nothing}
|
|
220
|
+
aria-valuetext=${this.spoken(this.value)}
|
|
164
221
|
aria-describedby=${this.describedBy ?? nothing}
|
|
165
222
|
aria-invalid=${this.invalidity ?? nothing}
|
|
166
223
|
?disabled=${this.isDisabled}
|
|
@@ -172,7 +229,9 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
172
229
|
${this.markerValues.map((at) => html `<span
|
|
173
230
|
part="marker"
|
|
174
231
|
style="--slider-marker-at: ${((at - this.min) / (this.max - this.min)) * 100}%"
|
|
175
|
-
>${this.markerLabels
|
|
232
|
+
>${this.markerLabels
|
|
233
|
+
? html `<span part="marker-label">${this.said(at)}</span>`
|
|
234
|
+
: nothing}</span
|
|
176
235
|
>`)}
|
|
177
236
|
</div>`
|
|
178
237
|
: nothing}
|
|
@@ -182,13 +241,22 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
|
|
|
182
241
|
for=${this.range ? 'control control-end' : 'control'}
|
|
183
242
|
aria-hidden="true"
|
|
184
243
|
style=${`--_slider-output-reserve: ${this.reserve}ch`}
|
|
185
|
-
>${this.range ? `${start} to ${end}` : this.value}</output
|
|
244
|
+
>${this.range ? `${this.said(start)} to ${this.said(end)}` : this.said(this.value)}</output
|
|
186
245
|
>`
|
|
187
246
|
: nothing}
|
|
188
247
|
</div>
|
|
189
248
|
${this.renderHint()}${this.renderFeedback()}`;
|
|
190
249
|
}
|
|
191
250
|
};
|
|
251
|
+
__decorate([
|
|
252
|
+
property({ attribute: 'format-options', type: Object })
|
|
253
|
+
], HelixHeadlessSlider.prototype, "formatOptions", void 0);
|
|
254
|
+
__decorate([
|
|
255
|
+
property({ attribute: false })
|
|
256
|
+
], HelixHeadlessSlider.prototype, "formatter", void 0);
|
|
257
|
+
__decorate([
|
|
258
|
+
property()
|
|
259
|
+
], HelixHeadlessSlider.prototype, "locale", void 0);
|
|
192
260
|
__decorate([
|
|
193
261
|
property({ attribute: 'marker-labels', reflect: true, type: Boolean })
|
|
194
262
|
], HelixHeadlessSlider.prototype, "markerLabels", void 0);
|
|
@@ -207,6 +275,9 @@ __decorate([
|
|
|
207
275
|
__decorate([
|
|
208
276
|
property({ attribute: 'minimum-label' })
|
|
209
277
|
], HelixHeadlessSlider.prototype, "minimumLabel", void 0);
|
|
278
|
+
__decorate([
|
|
279
|
+
property({ attribute: 'min-steps-between-thumbs', type: Number })
|
|
280
|
+
], HelixHeadlessSlider.prototype, "minStepsBetweenThumbs", void 0);
|
|
210
281
|
__decorate([
|
|
211
282
|
property({ reflect: true })
|
|
212
283
|
], HelixHeadlessSlider.prototype, "orientation", void 0);
|
|
@@ -219,6 +290,9 @@ __decorate([
|
|
|
219
290
|
__decorate([
|
|
220
291
|
property({ type: Number })
|
|
221
292
|
], HelixHeadlessSlider.prototype, "step", void 0);
|
|
293
|
+
__decorate([
|
|
294
|
+
property({ attribute: 'value-text' })
|
|
295
|
+
], HelixHeadlessSlider.prototype, "valueText", void 0);
|
|
222
296
|
HelixHeadlessSlider = __decorate([
|
|
223
297
|
customElement('helix-headless-slider')
|
|
224
298
|
], HelixHeadlessSlider);
|
|
@@ -9,9 +9,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
9
9
|
* `values` to the data and `label` to the one sentence a screen reader
|
|
10
10
|
* announces.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* a sparkline has a real table behind it. `for` wins when both are set.
|
|
12
|
+
* Use `for` when a sparkline has a real table behind it. `for` wins when both
|
|
13
|
+
* are set.
|
|
15
14
|
*
|
|
16
15
|
* Without a `label` the sparkline is decorative and `aria-hidden`, for example
|
|
17
16
|
* beside a stat that already says "Sessions, 1,102". With a `label` it is an
|
|
@@ -95,8 +94,8 @@ export declare class HelixHeadlessSparkline extends HelixElement {
|
|
|
95
94
|
/**
|
|
96
95
|
* What the readings are drawn as.
|
|
97
96
|
*
|
|
98
|
-
* Absent is
|
|
99
|
-
* `bar` is a column per reading.
|
|
97
|
+
* Absent is `area`, a line with the region beneath it washed. `line` is the
|
|
98
|
+
* bare stroke, and `bar` is a column per reading.
|
|
100
99
|
*
|
|
101
100
|
* **A bar plot measures from zero and the other two measure from the data's
|
|
102
101
|
* own range**, which is the one way the plots are not interchangeable. A line
|
|
@@ -125,12 +124,12 @@ export declare class HelixHeadlessSparkline extends HelixElement {
|
|
|
125
124
|
/**
|
|
126
125
|
* The numbers, separated by whitespace or by commas.
|
|
127
126
|
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
127
|
+
* An array assigned to the property works too, which is what React 19 does
|
|
128
|
+
* with `values={[1240, 1318]}`. The attribute is the form to prefer, because
|
|
129
|
+
* a string is what survives React's hydration where an array property does
|
|
130
|
+
* not.
|
|
132
131
|
*/
|
|
133
|
-
values: string;
|
|
132
|
+
values: string | readonly number[];
|
|
134
133
|
protected readonly source: SourceController;
|
|
135
134
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
136
135
|
/** The series to draw: the table if there is one, the attribute otherwise. */
|
|
@@ -52,12 +52,18 @@ export declare class HelixHeadlessSpeedDialItem extends HelixElement {
|
|
|
52
52
|
/** Chooses the action, the same as pressing it. */
|
|
53
53
|
select(): void;
|
|
54
54
|
/**
|
|
55
|
-
* Whether the action has focus, which
|
|
55
|
+
* Whether the action has focus, which makes it the action the keyboard is on.
|
|
56
56
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
|
|
57
|
+
* `Option` calls the same thing `active`. The focused node is found through
|
|
58
|
+
* every shadow root, as `Menu.Item` does, so a dial inside another
|
|
59
|
+
* component's shadow root still knows its current action.
|
|
60
|
+
*/
|
|
61
|
+
get active(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Whether the action has focus, the same as `active`.
|
|
64
|
+
*
|
|
65
|
+
* @deprecated Read `active`. Everywhere else in the library `selected` means
|
|
66
|
+
* chosen out of a set, and a speed dial's action is never chosen that way.
|
|
61
67
|
*/
|
|
62
68
|
get selected(): boolean;
|
|
63
69
|
private choose;
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessSpeedDialItem = class HelixHeadlessSpeedDialItem extends HelixElement {
|
|
@@ -26,8 +26,12 @@ let HelixHeadlessSpeedDialItem = class HelixHeadlessSpeedDialItem extends HelixE
|
|
|
26
26
|
select() {
|
|
27
27
|
this.choose();
|
|
28
28
|
}
|
|
29
|
+
get active() {
|
|
30
|
+
const active = deepActiveElement();
|
|
31
|
+
return active !== null && active.getRootNode() === this.renderRoot;
|
|
32
|
+
}
|
|
29
33
|
get selected() {
|
|
30
|
-
return this.
|
|
34
|
+
return this.active;
|
|
31
35
|
}
|
|
32
36
|
choose() {
|
|
33
37
|
if (this.disabled) {
|
|
@@ -42,6 +46,7 @@ let HelixHeadlessSpeedDialItem = class HelixHeadlessSpeedDialItem extends HelixE
|
|
|
42
46
|
type="button"
|
|
43
47
|
aria-disabled=${this.disabled ? 'true' : nothing}
|
|
44
48
|
?disabled=${this.disabled}
|
|
49
|
+
tabindex="-1"
|
|
45
50
|
@click=${this.handleClick}
|
|
46
51
|
>
|
|
47
52
|
<span part="icon"><slot name="icon"></slot></span>
|
|
@@ -11,8 +11,8 @@ declare const HelixHeadlessSpeedDial_base: (new (...args: any[]) => import("@fus
|
|
|
11
11
|
* - `PopoverController` for the panel
|
|
12
12
|
* - `MixinControllerOpen` for open and closed
|
|
13
13
|
*
|
|
14
|
-
* It is a separate component because a speed dial has no submenus, headers,
|
|
15
|
-
* checkable items
|
|
14
|
+
* It is a separate component because a speed dial has no submenus, headers, or
|
|
15
|
+
* checkable items.
|
|
16
16
|
*
|
|
17
17
|
* You slot the trigger. The usual floating action button is `IconButton` with
|
|
18
18
|
* `shape="circle"` and `raised`. There is no `helix-fab`, because `IconButton`
|
|
@@ -21,7 +21,9 @@ declare const HelixHeadlessSpeedDial_base: (new (...args: any[]) => import("@fus
|
|
|
21
21
|
*
|
|
22
22
|
* All four arrow keys move through the actions, because a speed dial has no
|
|
23
23
|
* nested levels to reserve the horizontal pair for. This is the default
|
|
24
|
-
* behavior of the keyboard controller.
|
|
24
|
+
* behavior of the keyboard controller. Typing a letter moves to the next
|
|
25
|
+
* action whose name starts with it. The actions are one tab stop, and Tab
|
|
26
|
+
* closes the dial and moves on.
|
|
25
27
|
*
|
|
26
28
|
* @since 0.1.0
|
|
27
29
|
* @status stable
|
|
@@ -35,7 +37,7 @@ declare const HelixHeadlessSpeedDial_base: (new (...args: any[]) => import("@fus
|
|
|
35
37
|
* @event {HelixBeforeCloseEvent} helix-before-close - The actions are about to close. Cancelable: cancel it to keep them open.
|
|
36
38
|
* @event {HelixBeforeOpenEvent} helix-before-open - The actions are about to open. Cancelable: cancel it to keep them closed.
|
|
37
39
|
* @event {HelixSelectEvent} helix-select - An action was chosen. The action sends the event, and the dial closes after it. Cancelable: cancel it to keep the dial open.
|
|
38
|
-
* @event {
|
|
40
|
+
* @event {ToggleEvent} toggle - The dial opened or closed. The event carries `newState` and `oldState`.
|
|
39
41
|
*
|
|
40
42
|
* @csspart actions - The region the actions are drawn in.
|
|
41
43
|
* @csspart trigger - The default trigger, drawn when none is slotted.
|
|
@@ -60,6 +62,15 @@ export declare class HelixHeadlessSpeedDial extends HelixHeadlessSpeedDial_base
|
|
|
60
62
|
*/
|
|
61
63
|
placement: Placement;
|
|
62
64
|
protected readonly keys: KeyboardNavigationController;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the trigger asked for the open that is under way, which is the one
|
|
67
|
+
* open that moves focus onto the first action.
|
|
68
|
+
*
|
|
69
|
+
* A dial opened by `default-open` or by a script setting `open` leaves focus
|
|
70
|
+
* where it is: on load that is wherever `autofocus` put it, and later it is
|
|
71
|
+
* wherever the reader is typing.
|
|
72
|
+
*/
|
|
73
|
+
private focusOnOpen;
|
|
63
74
|
protected readonly panel: PopoverController;
|
|
64
75
|
/** Whatever the consumer slotted, or the button rendered in its place. */
|
|
65
76
|
private get trigger();
|
|
@@ -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, customElement, drawIcon, HelixElement, KeyboardNavigationController, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { anchorElement, customElement, drawIcon, HelixElement, KeyboardNavigationController, MixinControllerOpen, PopoverController, slottedWords, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { plus } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -15,9 +15,11 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
15
15
|
this.offset = 12;
|
|
16
16
|
this.placement = 'top-end';
|
|
17
17
|
this.keys = new KeyboardNavigationController(this, {
|
|
18
|
-
items: () => this.items,
|
|
18
|
+
items: () => (this.open ? this.items : []),
|
|
19
19
|
selects: () => false,
|
|
20
|
+
typeahead: (item) => slottedWords(item, ['']),
|
|
20
21
|
});
|
|
22
|
+
this.focusOnOpen = false;
|
|
21
23
|
this.panel = new PopoverController(this, {
|
|
22
24
|
anchor: () => this.trigger,
|
|
23
25
|
boundary: () => this,
|
|
@@ -28,7 +30,11 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
28
30
|
surface: () => this.partNamed('actions'),
|
|
29
31
|
});
|
|
30
32
|
this.handleTriggerClick = () => {
|
|
31
|
-
|
|
33
|
+
if (this.open) {
|
|
34
|
+
this.requestOpen(false);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.focusOnOpen = this.requestOpen(true);
|
|
32
38
|
};
|
|
33
39
|
this.handleSelect = (event) => {
|
|
34
40
|
queueMicrotask(() => {
|
|
@@ -38,6 +44,13 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
38
44
|
});
|
|
39
45
|
};
|
|
40
46
|
this.handleKeydown = (event) => {
|
|
47
|
+
if (!this.open) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (event.key === 'Tab') {
|
|
51
|
+
this.requestOpen(false);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
41
54
|
if (event.key !== 'Escape') {
|
|
42
55
|
return;
|
|
43
56
|
}
|
|
@@ -74,12 +87,13 @@ let HelixHeadlessSpeedDial = class HelixHeadlessSpeedDial extends MixinControlle
|
|
|
74
87
|
if (trigger === this.partNamed('trigger')) {
|
|
75
88
|
return;
|
|
76
89
|
}
|
|
77
|
-
tellDisclosure(trigger, this.open);
|
|
90
|
+
tellDisclosure(trigger, this.open, 'menu');
|
|
78
91
|
}
|
|
79
92
|
updated(changed) {
|
|
80
93
|
super.updated?.(changed);
|
|
81
94
|
this.announce();
|
|
82
|
-
if (this.open) {
|
|
95
|
+
if (this.open && this.focusOnOpen) {
|
|
96
|
+
this.focusOnOpen = false;
|
|
83
97
|
this.updateComplete.then(() => {
|
|
84
98
|
if (this.open) {
|
|
85
99
|
this.items.find((one) => !one.disabled)?.focusItem();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary Two panes and a divider that you can move.
|
|
@@ -13,9 +13,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
13
13
|
* added at `firstUpdated` and is not in the server markup. Before it appears,
|
|
14
14
|
* both dividers work on their own.
|
|
15
15
|
*
|
|
16
|
-
* The divider has `role="separator"` and `aria-valuenow
|
|
17
|
-
* pointer or move it with the arrow keys,
|
|
18
|
-
*
|
|
16
|
+
* The divider has `role="separator"` and `aria-valuenow`, and `aria-controls`
|
|
17
|
+
* names the start pane. Drag it with a pointer or move it with the arrow keys,
|
|
18
|
+
* press `Home` or `End` to move it to its bounds, and press `Enter` to collapse
|
|
19
|
+
* the start pane and open it again. A drag in progress is tracked as a state, so both dividers a
|
|
19
20
|
* corner moves stay lit for as long as they move.
|
|
20
21
|
*
|
|
21
22
|
* By default, `min` and `max` let the divider reach either edge, so you can
|
|
@@ -39,6 +40,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
39
40
|
*
|
|
40
41
|
* @event {HelixBeforeCollapseEvent} helix-before-collapse - Fired before a pane shuts or reopens, whether or not the resize that caused it was allowed. It carries its own position, because a shut pane sits at `collapsed-size`. Cancelable: canceling it leaves the pane as it was and the divider where the gesture put it.
|
|
41
42
|
* @event {HelixBeforeResizeEvent} helix-before-resize - Fired before the divider settles, and only when the gesture moved it. A press that moved nothing, a drag that came back, an arrow key with no room left, and a corner that moved only the other divider do not fire it. Cancelable: canceling it leaves the position to you and keeps the rest of the gesture, so a collapse the gesture reached still fires `helix-before-collapse`, which you can also cancel. A dragged divider stays where it was dropped until you set your own `position`.
|
|
43
|
+
* @event {HelixCollapseEvent} helix-collapse - Fired after a pane shuts or reopens, with the side that is shut, or empty where both are open.
|
|
44
|
+
* @event {HelixResizedEvent} helix-resized - Fired after the divider settles somewhere new, with the new position.
|
|
42
45
|
*
|
|
43
46
|
* @csspart corner - The handle where two dividers cross, added on the client.
|
|
44
47
|
* @csspart end - The box that holds the second pane.
|
|
@@ -96,8 +99,13 @@ export declare class HelixHeadlessSplitter extends HelixElement {
|
|
|
96
99
|
defaultPosition: number;
|
|
97
100
|
/**
|
|
98
101
|
* The divider's name, read by screen readers.
|
|
102
|
+
*
|
|
103
|
+
* An `aria-label` or `aria-labelledby` on the host names the divider too,
|
|
104
|
+
* and wins over this.
|
|
99
105
|
*/
|
|
100
106
|
label: string;
|
|
107
|
+
/** Carries a host `aria-label` and `aria-labelledby` to the divider. */
|
|
108
|
+
protected readonly aria: AriaForwardController;
|
|
101
109
|
/**
|
|
102
110
|
* How close the divider can come to the end, in the same units as `min`.
|
|
103
111
|
*/
|
|
@@ -453,6 +461,19 @@ export declare class HelixHeadlessSplitter extends HelixElement {
|
|
|
453
461
|
* it on every page, which on a right-to-left one sent the divider right.
|
|
454
462
|
*/
|
|
455
463
|
private travel;
|
|
464
|
+
/**
|
|
465
|
+
* Collapses the start pane, or opens whichever pane is collapsed, which is
|
|
466
|
+
* what `Enter` does on the divider.
|
|
467
|
+
*
|
|
468
|
+
* The window splitter pattern's own key, and the one way the keyboard
|
|
469
|
+
* reaches `collapsed` where `min` keeps `Home` short of the edge. Collapse
|
|
470
|
+
* overrides `min` and `max`, as it does for every other way in.
|
|
471
|
+
*
|
|
472
|
+
* Asked through `helix-before-collapse` alone. The pane opens back to the
|
|
473
|
+
* position it was collapsed from, or to `default-position` where that was
|
|
474
|
+
* the edge itself.
|
|
475
|
+
*/
|
|
476
|
+
private toggleCollapse;
|
|
456
477
|
/** Puts the divider back where the markup put it. */
|
|
457
478
|
private reset;
|
|
458
479
|
private readonly handleDoubleClick;
|
|
@@ -465,7 +486,8 @@ export declare class HelixHeadlessSplitter extends HelixElement {
|
|
|
465
486
|
*/
|
|
466
487
|
private readonly handleCornerDoubleClick;
|
|
467
488
|
/**
|
|
468
|
-
* Records that a nested splitter crosses this one at `at` percent
|
|
489
|
+
* @internal Records that a nested splitter crosses this one at `at` percent
|
|
490
|
+
* along it.
|
|
469
491
|
*
|
|
470
492
|
* Public because it is the whole of the channel between the two, and it runs
|
|
471
493
|
* one way: the child tells the parent where it is, and the parent draws the
|
|
@@ -473,7 +495,7 @@ export declare class HelixHeadlessSplitter extends HelixElement {
|
|
|
473
495
|
* anything about the other's state.
|
|
474
496
|
*/
|
|
475
497
|
cross(by: HelixHeadlessSplitter, at: number): void;
|
|
476
|
-
/** Forgets a nested splitter that has left the tree. See `cross`. */
|
|
498
|
+
/** @internal Forgets a nested splitter that has left the tree. See `cross`. */
|
|
477
499
|
uncross(by: HelixHeadlessSplitter): void;
|
|
478
500
|
/**
|
|
479
501
|
* Announces this splitter to the one it is nested in, if they cross.
|
|
@@ -5,7 +5,7 @@ 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 HelixHeadlessSplitter_1;
|
|
8
|
-
import { capturePointer, closestInstance, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixElement, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { AriaForwardController, capturePointer, closestInstance, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixCollapseEvent, HelixElement, HelixResizedEvent, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
const STACK_BELOW = 512;
|
|
@@ -17,6 +17,10 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
17
17
|
this.cornerLabel = 'Resize both';
|
|
18
18
|
this.defaultPosition = 50;
|
|
19
19
|
this.label = 'Resize panes';
|
|
20
|
+
this.aria = new AriaForwardController(this, {
|
|
21
|
+
label: true,
|
|
22
|
+
target: () => this.partNamed('separator'),
|
|
23
|
+
});
|
|
20
24
|
this.max = 100;
|
|
21
25
|
this.min = 0;
|
|
22
26
|
this.step = 2;
|
|
@@ -68,6 +72,11 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
68
72
|
this.settle(this.reached ?? this.position);
|
|
69
73
|
};
|
|
70
74
|
this.handleKeydown = (event) => {
|
|
75
|
+
if (event.key === 'Enter') {
|
|
76
|
+
this.toggleCollapse();
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
71
80
|
const toward = this.travel(event.key);
|
|
72
81
|
let next;
|
|
73
82
|
if (toward !== 0) {
|
|
@@ -313,6 +322,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
313
322
|
const previous = this.position;
|
|
314
323
|
this.positionState = value;
|
|
315
324
|
this.requestUpdate('position', previous);
|
|
325
|
+
this.dispatchEvent(new HelixResizedEvent({ value: String(value) }));
|
|
316
326
|
},
|
|
317
327
|
event: (value) => new HelixBeforeResizeEvent({ value: String(value) }),
|
|
318
328
|
host: this,
|
|
@@ -327,6 +337,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
327
337
|
}
|
|
328
338
|
this.collapsedState = value === '' ? 'none' : value;
|
|
329
339
|
this.requestUpdate('collapsed', previous);
|
|
340
|
+
this.dispatchEvent(new HelixCollapseEvent({ value }));
|
|
330
341
|
},
|
|
331
342
|
event: (value) => new HelixBeforeCollapseEvent({ value }),
|
|
332
343
|
host: this,
|
|
@@ -340,6 +351,27 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
340
351
|
}
|
|
341
352
|
return key === 'ArrowDown' ? 1 : key === 'ArrowUp' ? -1 : 0;
|
|
342
353
|
}
|
|
354
|
+
toggleCollapse() {
|
|
355
|
+
const shut = this.collapsed;
|
|
356
|
+
const opened = shut ? undefined : this.position;
|
|
357
|
+
requestChange({
|
|
358
|
+
apply: (value) => {
|
|
359
|
+
const previous = this.collapsed;
|
|
360
|
+
if (opened !== undefined) {
|
|
361
|
+
this.positionState = opened;
|
|
362
|
+
}
|
|
363
|
+
else if (this.shutAt(this.clamp(this.positionState ?? this.defaultPosition))) {
|
|
364
|
+
this.positionState = this.defaultPosition;
|
|
365
|
+
}
|
|
366
|
+
this.collapsedState = value === '' ? 'none' : value;
|
|
367
|
+
this.requestUpdate('collapsed', previous);
|
|
368
|
+
this.dispatchEvent(new HelixCollapseEvent({ value }));
|
|
369
|
+
},
|
|
370
|
+
event: (value) => new HelixBeforeCollapseEvent({ value }),
|
|
371
|
+
host: this,
|
|
372
|
+
next: shut ? '' : 'start',
|
|
373
|
+
});
|
|
374
|
+
}
|
|
343
375
|
reset() {
|
|
344
376
|
const home = this.clamp(this.defaultPosition);
|
|
345
377
|
this.settle(home);
|
|
@@ -427,6 +459,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
427
459
|
const position = this.showing;
|
|
428
460
|
return html `<div
|
|
429
461
|
part="start"
|
|
462
|
+
id="start"
|
|
430
463
|
?data-dragging=${this.dragging}
|
|
431
464
|
style="--splitter-position: ${position}%"
|
|
432
465
|
>
|
|
@@ -436,6 +469,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
436
469
|
part="separator"
|
|
437
470
|
role="separator"
|
|
438
471
|
tabindex="0"
|
|
472
|
+
aria-controls="start"
|
|
439
473
|
aria-label=${this.label}
|
|
440
474
|
aria-orientation=${this.vertical ? 'horizontal' : 'vertical'}
|
|
441
475
|
aria-valuemax=${this.collapsed ? 100 : this.clamp(this.maxPercent)}
|