@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
|
@@ -23,12 +23,20 @@ declare const HelixHeadlessRadioGroup_base: (new (...args: any[]) => import("@fu
|
|
|
23
23
|
* the value until something is chosen, and where a reset returns. The two work
|
|
24
24
|
* like `checked` and `defaultChecked`.
|
|
25
25
|
*
|
|
26
|
+
* A choice sends its events in this order: `helix-select` from the radio, then,
|
|
27
|
+
* a microtask later and only if nobody refused it, `helix-before-change` from
|
|
28
|
+
* the group, and once the value has moved, `input` and `change`. The microtask
|
|
29
|
+
* is what lets a listener you add to the group after it connected refuse the
|
|
30
|
+
* `helix-select`. A native radio sends `input` and `change` in the same task as
|
|
31
|
+
* the click.
|
|
32
|
+
*
|
|
26
33
|
* @since 0.1.0
|
|
27
34
|
* @status stable
|
|
28
35
|
* @aliases RadioButtons, Choice group
|
|
29
36
|
* @documentation https://fusion.dev/helix/components/radio
|
|
30
37
|
*
|
|
31
38
|
* @slot - The radios.
|
|
39
|
+
* @slot feedback - The error message, for content richer than a string. It shows while there is a message.
|
|
32
40
|
* @slot hint - The help text under the group, for content richer than a string.
|
|
33
41
|
* @slot label - The group's label, for a question that needs more than a string.
|
|
34
42
|
*
|
|
@@ -45,6 +53,18 @@ declare const HelixHeadlessRadioGroup_base: (new (...args: any[]) => import("@fu
|
|
|
45
53
|
* @cssstate invalid - The group has an error to show, from the browser's validation or from your `feedback`.
|
|
46
54
|
*/
|
|
47
55
|
export declare class HelixHeadlessRadioGroup extends HelixHeadlessRadioGroup_base {
|
|
56
|
+
/**
|
|
57
|
+
* Whether the group holds a tab stop of its own.
|
|
58
|
+
*
|
|
59
|
+
* A toolbar is one tab stop, so a toolbar the group sits in sets this to
|
|
60
|
+
* `false` while its stop is on another control, and every radio, the chosen
|
|
61
|
+
* one too, is then out of the tab order. The arrow keys inside the group
|
|
62
|
+
* work as before once focus is in it.
|
|
63
|
+
*
|
|
64
|
+
* No attribute: it is coordination between elements, and a consumer has no
|
|
65
|
+
* reason to set it.
|
|
66
|
+
*/
|
|
67
|
+
focusable: boolean;
|
|
48
68
|
/**
|
|
49
69
|
* The direction the choices run. `vertical` puts one choice on each line.
|
|
50
70
|
*
|
|
@@ -56,6 +76,22 @@ export declare class HelixHeadlessRadioGroup extends HelixHeadlessRadioGroup_bas
|
|
|
56
76
|
* only `horizontal` has to be named.
|
|
57
77
|
*/
|
|
58
78
|
orientation?: 'horizontal' | 'vertical';
|
|
79
|
+
/**
|
|
80
|
+
* Whether a reader can see and focus the answer and cannot change it. A
|
|
81
|
+
* read-only group still submits its value.
|
|
82
|
+
*
|
|
83
|
+
* React Aria's `isReadOnly`. A press on a radio is refused, and the arrow
|
|
84
|
+
* keys, Home and End leave focus on the answer, so Tab still reaches it and
|
|
85
|
+
* a reader hears it with the group's name. The group says `aria-readonly`.
|
|
86
|
+
* A script can still set `value`.
|
|
87
|
+
*/
|
|
88
|
+
readOnly: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Keeps the keys that would move the answer from the keyboard controller
|
|
91
|
+
* while the group is read-only. A capture listener on the host runs ahead of
|
|
92
|
+
* the controller's own on the same target.
|
|
93
|
+
*/
|
|
94
|
+
private readonly holdKeys;
|
|
59
95
|
protected readonly keys: KeyboardNavigationController;
|
|
60
96
|
protected readonly cascade: DisabledCascadeController;
|
|
61
97
|
/** The radios, in light-DOM order. Client only: the server has no tree. */
|
|
@@ -76,8 +112,36 @@ export declare class HelixHeadlessRadioGroup extends HelixHeadlessRadioGroup_bas
|
|
|
76
112
|
* the item's is the one that was doing nothing.
|
|
77
113
|
*/
|
|
78
114
|
private readonly handleSelection;
|
|
115
|
+
/**
|
|
116
|
+
* The radio holding the answer, or nothing.
|
|
117
|
+
*
|
|
118
|
+
* Nothing where `value` names no radio here: a chosen radio that was removed
|
|
119
|
+
* is no longer an answer, as a native group drops it from the form. `value`
|
|
120
|
+
* keeps the name, so a value written before its radios arrive takes once they
|
|
121
|
+
* do.
|
|
122
|
+
*/
|
|
123
|
+
private get answer();
|
|
124
|
+
/** Whether the group holds an answer the form can submit. */
|
|
125
|
+
private get answered();
|
|
126
|
+
/**
|
|
127
|
+
* Takes the answer from a radio whose markup says `selected`, where nothing
|
|
128
|
+
* else declared one.
|
|
129
|
+
*
|
|
130
|
+
* As `Toggle.Group` does, so `<helix-radio selected>` preselects as
|
|
131
|
+
* `<option selected>` and `<helix-toggle selected>` do, and a reset returns
|
|
132
|
+
* to it. Client only: the server's element shim has no children to read.
|
|
133
|
+
*/
|
|
134
|
+
private adopt;
|
|
79
135
|
/** Writes the answer onto the items, and nothing onto the host. */
|
|
80
136
|
private place;
|
|
137
|
+
/** The radio that holds the group's tab stop: the answer, or the first that can be chosen. */
|
|
138
|
+
private entry;
|
|
139
|
+
/**
|
|
140
|
+
* Focus goes to the radio that holds the stop, and to the radio that would
|
|
141
|
+
* hold it while a toolbar holds the stop instead, so a label press or a
|
|
142
|
+
* refused submission still lands in the group.
|
|
143
|
+
*/
|
|
144
|
+
protected get focusTarget(): HTMLElement | null;
|
|
81
145
|
/** Reports the answer and the verdict on it. */
|
|
82
146
|
private sync;
|
|
83
147
|
connectedCallback(): void;
|
|
@@ -8,55 +8,103 @@ import { customElement, DisabledCascadeController, HelixFormElement, hostAria, K
|
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessRadio } from '../root/radio-root.js';
|
|
11
|
+
const MOVING_KEYS = new Set(['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home']);
|
|
11
12
|
let HelixHeadlessRadioGroup = class HelixHeadlessRadioGroup extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
12
13
|
constructor() {
|
|
13
14
|
super(...arguments);
|
|
15
|
+
this.focusable = true;
|
|
16
|
+
this.readOnly = false;
|
|
17
|
+
this.holdKeys = (event) => {
|
|
18
|
+
if (this.readOnly && MOVING_KEYS.has(event.key)) {
|
|
19
|
+
event.stopImmediatePropagation();
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
14
23
|
this.keys = new KeyboardNavigationController(this, { items: () => this.items });
|
|
15
24
|
this.cascade = new DisabledCascadeController(this, {
|
|
16
25
|
items: () => this.items,
|
|
17
26
|
});
|
|
18
27
|
this.handleSelection = (event) => {
|
|
19
28
|
event.stopPropagation();
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
const next = event.detail.value;
|
|
24
|
-
if (next === this.value) {
|
|
29
|
+
if (this.readOnly) {
|
|
30
|
+
event.preventDefault();
|
|
25
31
|
return;
|
|
26
32
|
}
|
|
27
|
-
|
|
33
|
+
queueMicrotask(() => {
|
|
34
|
+
if (event.defaultPrevented) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const next = event.detail.value;
|
|
38
|
+
if (next === this.value) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this.requestValue(next);
|
|
42
|
+
});
|
|
28
43
|
};
|
|
29
44
|
}
|
|
30
45
|
get items() {
|
|
31
|
-
return [...this.children].filter((child) => child instanceof HelixHeadlessRadio);
|
|
46
|
+
return [...(this.children ?? [])].filter((child) => child instanceof HelixHeadlessRadio);
|
|
47
|
+
}
|
|
48
|
+
get answer() {
|
|
49
|
+
return this.items.find((item) => item.value === this.value);
|
|
50
|
+
}
|
|
51
|
+
get answered() {
|
|
52
|
+
if (this.value === '') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const items = this.items;
|
|
56
|
+
return items.length === 0 || items.some((item) => item.value === this.value);
|
|
57
|
+
}
|
|
58
|
+
adopt() {
|
|
59
|
+
if (this.value !== '' || this.children === undefined) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const declared = this.items.find((item) => item.defaultSelected);
|
|
63
|
+
if (declared) {
|
|
64
|
+
this.defaultValue = declared.value;
|
|
65
|
+
}
|
|
32
66
|
}
|
|
33
67
|
place() {
|
|
34
68
|
const items = this.items;
|
|
35
|
-
const answer =
|
|
69
|
+
const answer = this.answer;
|
|
36
70
|
for (const item of items) {
|
|
37
71
|
item.selected = item === answer;
|
|
38
72
|
}
|
|
39
|
-
const entry =
|
|
73
|
+
const entry = this.focusable ? this.entry() : undefined;
|
|
40
74
|
for (const item of items) {
|
|
41
75
|
item.focusable = item === entry;
|
|
42
76
|
}
|
|
43
77
|
}
|
|
78
|
+
entry() {
|
|
79
|
+
const answer = this.answer;
|
|
80
|
+
return answer && !answer.disabled ? answer : this.items.find((item) => !item.disabled);
|
|
81
|
+
}
|
|
82
|
+
get focusTarget() {
|
|
83
|
+
return (super.focusTarget ??
|
|
84
|
+
this.entry()?.shadowRoot?.querySelector('[part="item"]') ??
|
|
85
|
+
null);
|
|
86
|
+
}
|
|
44
87
|
sync() {
|
|
45
|
-
|
|
46
|
-
this.
|
|
88
|
+
const answered = this.answered;
|
|
89
|
+
this.internals.setFormValue(answered ? this.value : null);
|
|
90
|
+
this.reportRequired(!answered, 'Choose one to continue.', 'items');
|
|
47
91
|
}
|
|
48
92
|
connectedCallback() {
|
|
49
93
|
super.connectedCallback();
|
|
50
94
|
this.addEventListener('helix-select', this.handleSelection);
|
|
95
|
+
this.addEventListener('keydown', this.holdKeys, { capture: true });
|
|
51
96
|
}
|
|
52
97
|
disconnectedCallback() {
|
|
53
98
|
super.disconnectedCallback();
|
|
54
99
|
this.removeEventListener('helix-select', this.handleSelection);
|
|
100
|
+
this.removeEventListener('keydown', this.holdKeys, { capture: true });
|
|
55
101
|
}
|
|
56
102
|
willUpdate(changed) {
|
|
57
103
|
super.willUpdate(changed);
|
|
104
|
+
this.adopt();
|
|
58
105
|
hostAria(this.internals, { label: this.label, role: 'radiogroup' });
|
|
59
106
|
this.internals.ariaRequired = this.required ? 'true' : null;
|
|
107
|
+
this.internals.ariaReadOnly = this.readOnly ? 'true' : null;
|
|
60
108
|
}
|
|
61
109
|
updated(changed) {
|
|
62
110
|
super.updated(changed);
|
|
@@ -67,14 +115,20 @@ let HelixHeadlessRadioGroup = class HelixHeadlessRadioGroup extends MixinControl
|
|
|
67
115
|
render() {
|
|
68
116
|
return html `${this.renderGroupLabel()}
|
|
69
117
|
<div part="items">
|
|
70
|
-
<slot @slotchange=${() => this.
|
|
118
|
+
<slot @slotchange=${() => this.requestUpdate()}></slot>
|
|
71
119
|
</div>
|
|
72
120
|
${this.renderHint()}${this.renderFeedback()}`;
|
|
73
121
|
}
|
|
74
122
|
};
|
|
123
|
+
__decorate([
|
|
124
|
+
property({ attribute: false })
|
|
125
|
+
], HelixHeadlessRadioGroup.prototype, "focusable", void 0);
|
|
75
126
|
__decorate([
|
|
76
127
|
property({ reflect: true })
|
|
77
128
|
], HelixHeadlessRadioGroup.prototype, "orientation", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
131
|
+
], HelixHeadlessRadioGroup.prototype, "readOnly", void 0);
|
|
78
132
|
HelixHeadlessRadioGroup = __decorate([
|
|
79
133
|
customElement('helix-headless-radio-group')
|
|
80
134
|
], HelixHeadlessRadioGroup);
|
|
@@ -73,11 +73,14 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
|
|
|
73
73
|
get defaultSelected(): boolean;
|
|
74
74
|
set defaultSelected(next: boolean);
|
|
75
75
|
/**
|
|
76
|
-
* Whether the radio holds the group's tab stop
|
|
76
|
+
* Whether the radio holds the group's tab stop. Unset, the chosen radio
|
|
77
|
+
* holds it.
|
|
77
78
|
*
|
|
78
79
|
* The stop rides on the selection, and an unanswered group has no selection,
|
|
79
80
|
* so without this every choice is `tabindex="-1"` and the keyboard cannot
|
|
80
|
-
* enter the set at all.
|
|
81
|
+
* enter the set at all. The group writes `true` for the chosen radio, or for
|
|
82
|
+
* the first that can be chosen while nothing is, and `false` for every radio,
|
|
83
|
+
* the chosen one too, while a toolbar the group sits in holds the stop.
|
|
81
84
|
*
|
|
82
85
|
* **Written by the group, with no attribute, and it reaches the control
|
|
83
86
|
* rather than the host.** A `tabindex` on the host is two faults at once: it
|
|
@@ -88,15 +91,15 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
|
|
|
88
91
|
* them an unchecked radio. `Toggle.Root` carries the same property for the
|
|
89
92
|
* same reason.
|
|
90
93
|
*/
|
|
91
|
-
focusable
|
|
94
|
+
focusable?: boolean;
|
|
92
95
|
/**
|
|
93
96
|
* Asks for the render that follows a hydration, so the stop stops being every
|
|
94
97
|
* choice's.
|
|
95
98
|
*
|
|
96
99
|
* `tabindex` reads `childrenKnown` and a hydrating render is one where that is
|
|
97
100
|
* false, which is what keeps the hydrating render the server's. Nothing else
|
|
98
|
-
*
|
|
99
|
-
*
|
|
101
|
+
* is sure to ask: a write from the group that leaves `focusable` as it was
|
|
102
|
+
* re-renders nothing.
|
|
100
103
|
*/
|
|
101
104
|
protected firstUpdated(changed: PropertyValues): void;
|
|
102
105
|
protected render(): TemplateResult;
|
|
@@ -11,7 +11,6 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
|
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.clicks = new HostClickController(this, () => this.partNamed('item'));
|
|
14
|
-
this.focusable = false;
|
|
15
14
|
}
|
|
16
15
|
get defaultSelected() {
|
|
17
16
|
return this.hasAttribute('selected');
|
|
@@ -30,7 +29,7 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
|
|
|
30
29
|
role="radio"
|
|
31
30
|
aria-checked=${this.selected ? 'true' : 'false'}
|
|
32
31
|
?disabled=${this.disabled}
|
|
33
|
-
tabindex=${this.
|
|
32
|
+
tabindex=${(this.focusable ?? this.selected) || !this.childrenKnown ? '0' : '-1'}
|
|
34
33
|
@click=${() => this.select()}
|
|
35
34
|
>
|
|
36
35
|
<span part="box"></span>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixFormElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
@@ -15,14 +15,23 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
|
|
|
15
15
|
* A read-only rating displays a score, which is the most common use. It is
|
|
16
16
|
* announced as a displayed value and does not look disabled.
|
|
17
17
|
*
|
|
18
|
+
* With `clearable`, pressing the chosen score again, or Backspace or Delete on
|
|
19
|
+
* the marks, takes the rating back to unrated and sends `helix-clear`.
|
|
20
|
+
*
|
|
18
21
|
* @since 0.1.0
|
|
19
22
|
* @status stable
|
|
20
23
|
* @category forms
|
|
21
24
|
* @aliases Stars, Score, Review score
|
|
22
25
|
* @documentation https://fusion.dev/helix/components/rating
|
|
23
26
|
*
|
|
27
|
+
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
28
|
+
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
29
|
+
* @slot label - The label, for content richer than the `label` text.
|
|
30
|
+
* @slot mark - The shape of a mark, copied into every position.
|
|
31
|
+
*
|
|
24
32
|
* @event {Event} change - The score was chosen. Sent together with `input`, because each choice commits the score.
|
|
25
33
|
* @event {HelixBeforeChangeEvent} helix-before-change - The score is about to change. Cancelable: cancel it to keep the current score.
|
|
34
|
+
* @event {Event} helix-clear - The rating went back to unrated, under `clearable`. Sent after `input` and `change`.
|
|
26
35
|
* @event {Event} input - The score changed.
|
|
27
36
|
*
|
|
28
37
|
* @csspart feedback - The message that says what is wrong.
|
|
@@ -45,6 +54,12 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
|
|
|
45
54
|
*/
|
|
46
55
|
export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
47
56
|
protected readonly announcesInput = false;
|
|
57
|
+
/**
|
|
58
|
+
* Whether a reader can take the rating back to unrated: by pressing the
|
|
59
|
+
* chosen score again, or with Backspace or Delete. Zag's rating group
|
|
60
|
+
* clears the same way.
|
|
61
|
+
*/
|
|
62
|
+
clearable: boolean;
|
|
48
63
|
/**
|
|
49
64
|
* How many marks there are.
|
|
50
65
|
*/
|
|
@@ -92,6 +107,14 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
92
107
|
* nonsense is the fault this pays off, so neither case is quietly ignored.
|
|
93
108
|
*/
|
|
94
109
|
min: number;
|
|
110
|
+
/**
|
|
111
|
+
* The name of each mark a reader can choose, with `{score}` and `{max}`
|
|
112
|
+
* filled in. Set it to translate "3 out of 5".
|
|
113
|
+
*
|
|
114
|
+
* Also what a read-only rating says for its score where `value-text` is
|
|
115
|
+
* empty.
|
|
116
|
+
*/
|
|
117
|
+
optionLabel: string;
|
|
95
118
|
/**
|
|
96
119
|
* Shows the score without letting users change it.
|
|
97
120
|
*
|
|
@@ -128,6 +151,9 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
128
151
|
* and each of its options by the score that option is.
|
|
129
152
|
*/
|
|
130
153
|
valueText: string;
|
|
154
|
+
protected readonly aria: AriaForwardController;
|
|
155
|
+
/** @internal The element a missing name is checked on: the set of stars, so the name of one star does not count as the name of the rating. */
|
|
156
|
+
protected get namedControl(): HTMLElement | null;
|
|
131
157
|
/**
|
|
132
158
|
* The shape a consumer slotted, if they slotted one.
|
|
133
159
|
*
|
|
@@ -222,8 +248,17 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
222
248
|
* or off the element entirely, has asked for nothing.
|
|
223
249
|
*/
|
|
224
250
|
private readonly handleDragStart;
|
|
251
|
+
/** The score a press began on, so releasing on the chosen one can clear it. */
|
|
252
|
+
private pressedOn;
|
|
253
|
+
/**
|
|
254
|
+
* Whether a drag has just chosen, so the click a browser may send after it
|
|
255
|
+
* does not choose again. Cleared a task later, since the click may not come.
|
|
256
|
+
*/
|
|
257
|
+
private dragChose;
|
|
225
258
|
private readonly handleDragMove;
|
|
226
259
|
private readonly handleDragEnd;
|
|
260
|
+
/** Whether a press on `score` takes a clearable rating back to unrated. */
|
|
261
|
+
private clearsAt;
|
|
227
262
|
private readonly handleDragCancel;
|
|
228
263
|
/**
|
|
229
264
|
* Reports the value, and whether the form may go without one.
|
|
@@ -246,6 +281,10 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
246
281
|
*/
|
|
247
282
|
private sync;
|
|
248
283
|
private readonly handleOptionClick;
|
|
284
|
+
/** Backspace and Delete take a clearable rating back to unrated. */
|
|
285
|
+
private readonly handleClearKey;
|
|
286
|
+
/** Back to unrated, through the same cancelable request as a score, and said. */
|
|
287
|
+
private clear;
|
|
249
288
|
private readonly handleOptionEnter;
|
|
250
289
|
private readonly handleLeave;
|
|
251
290
|
connectedCallback(): void;
|
|
@@ -255,6 +294,15 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
255
294
|
protected updated(changed: PropertyValues): void;
|
|
256
295
|
protected willUpdate(changed: PropertyValues): void;
|
|
257
296
|
protected firstUpdated(changed: PropertyValues): void;
|
|
297
|
+
/** The name of one score, as `optionLabel` writes it. */
|
|
298
|
+
private nameFor;
|
|
299
|
+
/**
|
|
300
|
+
* The option holding the tab stop: the chosen one, or for a score between
|
|
301
|
+
* steps, such as an average of 3.5 on whole marks, the step below it, and
|
|
302
|
+
* the first while nothing is chosen. Between steps no option matched, and
|
|
303
|
+
* the rating left the tab order.
|
|
304
|
+
*/
|
|
305
|
+
private stopAt;
|
|
258
306
|
protected render(): TemplateResult;
|
|
259
307
|
/**
|
|
260
308
|
* The value as a number, or `NaN` while the control is empty.
|
|
@@ -4,19 +4,24 @@ 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 { valueAsNumber as asNumber, customElement, numberAsValue as fromNumber, HelixFormElement, KeyboardNavigationController, MixinControllerValue, MixinField, reportRuntime, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, valueAsNumber as asNumber, customElement, fillTemplate, numberAsValue as fromNumber, HelixFormElement, KeyboardNavigationController, MixinControllerValue, MixinField, reportRuntime, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.announcesInput = false;
|
|
14
|
+
this.clearable = false;
|
|
14
15
|
this.max = 5;
|
|
15
16
|
this.min = 0;
|
|
17
|
+
this.optionLabel = '{score} out of {max}';
|
|
16
18
|
this.readOnly = false;
|
|
17
19
|
this.showValue = false;
|
|
18
20
|
this.step = 1;
|
|
19
21
|
this.valueText = '';
|
|
22
|
+
this.aria = new AriaForwardController(this, {
|
|
23
|
+
target: () => this.partNamed('marks'),
|
|
24
|
+
});
|
|
20
25
|
this.markSource = undefined;
|
|
21
26
|
this.markRead = false;
|
|
22
27
|
this.previewing = undefined;
|
|
@@ -46,8 +51,11 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
46
51
|
catch {
|
|
47
52
|
}
|
|
48
53
|
this.dragging = event.pointerId;
|
|
54
|
+
this.pressedOn = score;
|
|
49
55
|
this.previewing = Number.parseFloat(score);
|
|
50
56
|
};
|
|
57
|
+
this.pressedOn = undefined;
|
|
58
|
+
this.dragChose = false;
|
|
51
59
|
this.handleDragMove = (event) => {
|
|
52
60
|
if (this.dragging !== event.pointerId) {
|
|
53
61
|
return;
|
|
@@ -64,9 +72,18 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
64
72
|
this.dragging = undefined;
|
|
65
73
|
this.previewing = undefined;
|
|
66
74
|
const score = this.scoreAt(event.clientX);
|
|
67
|
-
if (score
|
|
68
|
-
|
|
75
|
+
if (score === undefined) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this.dragChose = true;
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
this.dragChose = false;
|
|
81
|
+
}, 0);
|
|
82
|
+
if (this.clearsAt(score) && score === this.pressedOn) {
|
|
83
|
+
this.clear();
|
|
84
|
+
return;
|
|
69
85
|
}
|
|
86
|
+
this.requestValue(score);
|
|
70
87
|
};
|
|
71
88
|
this.handleDragCancel = (event) => {
|
|
72
89
|
if (this.dragging !== event.pointerId) {
|
|
@@ -76,8 +93,22 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
76
93
|
this.previewing = undefined;
|
|
77
94
|
};
|
|
78
95
|
this.handleOptionClick = (event) => {
|
|
96
|
+
if (this.dragChose) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
79
99
|
const option = event.currentTarget;
|
|
80
|
-
|
|
100
|
+
const score = option.dataset.score ?? '';
|
|
101
|
+
if (this.clearsAt(score)) {
|
|
102
|
+
this.clear();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.requestValue(score);
|
|
106
|
+
};
|
|
107
|
+
this.handleClearKey = (event) => {
|
|
108
|
+
if (this.clearable && (event.key === 'Backspace' || event.key === 'Delete')) {
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
this.clear();
|
|
111
|
+
}
|
|
81
112
|
};
|
|
82
113
|
this.handleOptionEnter = (event) => {
|
|
83
114
|
if (this.isDisabled) {
|
|
@@ -91,6 +122,9 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
91
122
|
};
|
|
92
123
|
this.warned = false;
|
|
93
124
|
}
|
|
125
|
+
get namedControl() {
|
|
126
|
+
return this.partNamed('marks');
|
|
127
|
+
}
|
|
94
128
|
get floor() {
|
|
95
129
|
if (!Number.isFinite(this.min)) {
|
|
96
130
|
return 0;
|
|
@@ -152,10 +186,18 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
152
186
|
}
|
|
153
187
|
return nearest;
|
|
154
188
|
}
|
|
189
|
+
clearsAt(score) {
|
|
190
|
+
return this.clearable && this.value !== '' && Number(score) === Number(this.value);
|
|
191
|
+
}
|
|
155
192
|
sync() {
|
|
156
193
|
this.internals.setFormValue(this.value === '' ? null : this.value);
|
|
157
194
|
this.reportRequired(this.value === '', 'Choose a rating to continue.', 'marks');
|
|
158
195
|
}
|
|
196
|
+
clear() {
|
|
197
|
+
if (this.value !== '' && !this.readOnly && !this.isDisabled && this.requestValue('')) {
|
|
198
|
+
this.dispatchEvent(new Event('helix-clear', { bubbles: true, composed: true }));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
159
201
|
connectedCallback() {
|
|
160
202
|
super.connectedCallback();
|
|
161
203
|
this.addEventListener('pointerleave', this.handleLeave);
|
|
@@ -190,11 +232,23 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
190
232
|
this.finishHydration();
|
|
191
233
|
this.sync();
|
|
192
234
|
}
|
|
235
|
+
nameFor(score) {
|
|
236
|
+
return fillTemplate(this.optionLabel, { max: this.max, score });
|
|
237
|
+
}
|
|
238
|
+
stopAt(answered, first) {
|
|
239
|
+
if (!answered) {
|
|
240
|
+
return first;
|
|
241
|
+
}
|
|
242
|
+
const below = this.steps.filter((score) => score <= this.score);
|
|
243
|
+
return below.at(-1) ?? first;
|
|
244
|
+
}
|
|
193
245
|
render() {
|
|
194
246
|
const showing = this.previewing ?? this.score;
|
|
195
|
-
const said = this.valueText ||
|
|
247
|
+
const said = this.valueText || this.nameFor(this.score);
|
|
196
248
|
const count = Math.max(0, Math.round(this.max));
|
|
197
249
|
const first = this.steps[0];
|
|
250
|
+
const answered = this.value !== '' && Number.isFinite(Number.parseFloat(this.value));
|
|
251
|
+
const stop = this.stopAt(answered, first);
|
|
198
252
|
const mark = (layer, index) => html `<span part="mark">${this.markFor(layer, index)}</span>`;
|
|
199
253
|
const marksIn = (layer) => Array.from({ length: count }, (_, index) => mark(layer, index));
|
|
200
254
|
return html `${this.renderGroupLabel()}
|
|
@@ -210,6 +264,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
210
264
|
data-slotted=${this.markSource ? '' : nothing}
|
|
211
265
|
style=${`--rating-full: ${Math.floor(showing)}; --rating-part: ${showing - Math.floor(showing)}; --rating-steps: ${this.positions.length}`}
|
|
212
266
|
@pointercancel=${this.handleDragCancel}
|
|
267
|
+
@keydown=${this.handleClearKey}
|
|
213
268
|
@pointerdown=${this.handleDragStart}
|
|
214
269
|
@pointermove=${this.handleDragMove}
|
|
215
270
|
@pointerup=${this.handleDragEnd}
|
|
@@ -240,14 +295,12 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
240
295
|
part="option"
|
|
241
296
|
role="radio"
|
|
242
297
|
type="button"
|
|
243
|
-
aria-checked=${this.score === score ? 'true' : 'false'}
|
|
244
|
-
aria-label=${
|
|
298
|
+
aria-checked=${answered && this.score === score ? 'true' : 'false'}
|
|
299
|
+
aria-label=${this.nameFor(score)}
|
|
245
300
|
data-score=${String(score)}
|
|
246
301
|
style=${`--rating-step: ${index + 1}`}
|
|
247
302
|
?disabled=${this.isDisabled}
|
|
248
|
-
tabindex=${
|
|
249
|
-
? '0'
|
|
250
|
-
: '-1'}
|
|
303
|
+
tabindex=${score === stop ? '0' : '-1'}
|
|
251
304
|
@click=${this.handleOptionClick}
|
|
252
305
|
@pointerenter=${this.handleOptionEnter}
|
|
253
306
|
></button>`)}
|
|
@@ -269,12 +322,18 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
|
|
|
269
322
|
this.value = fromNumber(count);
|
|
270
323
|
}
|
|
271
324
|
};
|
|
325
|
+
__decorate([
|
|
326
|
+
property({ type: Boolean })
|
|
327
|
+
], HelixHeadlessRating.prototype, "clearable", void 0);
|
|
272
328
|
__decorate([
|
|
273
329
|
property({ type: Number })
|
|
274
330
|
], HelixHeadlessRating.prototype, "max", void 0);
|
|
275
331
|
__decorate([
|
|
276
332
|
property({ type: Number })
|
|
277
333
|
], HelixHeadlessRating.prototype, "min", void 0);
|
|
334
|
+
__decorate([
|
|
335
|
+
property({ attribute: 'option-label' })
|
|
336
|
+
], HelixHeadlessRating.prototype, "optionLabel", void 0);
|
|
278
337
|
__decorate([
|
|
279
338
|
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
280
339
|
], HelixHeadlessRating.prototype, "readOnly", void 0);
|
|
@@ -33,7 +33,14 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
|
|
|
33
33
|
* round numbers, and the range extends to them.
|
|
34
34
|
*
|
|
35
35
|
* The summary gives each series' correlation coefficient and its number of
|
|
36
|
-
* points. The table has every number, and the drawing is
|
|
36
|
+
* points. The table has every number, and the drawing is hidden from screen
|
|
37
|
+
* readers.
|
|
38
|
+
*
|
|
39
|
+
* **The plot is read by key.** It takes focus, named by `label` or the caption.
|
|
40
|
+
* The left and right arrows move from row to row in the table's order, Home
|
|
41
|
+
* and End go to the first and the last, and the up and down arrows move among
|
|
42
|
+
* the series of a row. The tooltip sits on that point, the `live` part says the
|
|
43
|
+
* row in words, and Escape puts the tooltip away.
|
|
37
44
|
*
|
|
38
45
|
* Each point is a `<span>` placed by percentage over the drawing, as
|
|
39
46
|
* `LineChart` places its end points, so points stay round when the drawing
|
|
@@ -52,9 +59,10 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
|
|
|
52
59
|
* @documentation https://fusion.dev/helix/components/scatter-chart
|
|
53
60
|
*
|
|
54
61
|
* @csspart gridline - One line across the plot, drawn when `gridlines` is set.
|
|
62
|
+
* @csspart live - The readout: a polite live region that says the row the keys moved to. Hide it visually.
|
|
55
63
|
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
56
64
|
* @csspart plane - The grid that holds the plot, both axes, and their names. It runs left to right on every page.
|
|
57
|
-
* @csspart plot - The drawing.
|
|
65
|
+
* @csspart plot - The drawing, which takes focus to be read by key.
|
|
58
66
|
* @csspart point - One row, as a point.
|
|
59
67
|
* @csspart point-active - A point in the row under the pointer. Set alongside `point`.
|
|
60
68
|
* @csspart summary - The text that says how strongly the measures relate, for people who cannot see the points.
|
|
@@ -68,6 +76,7 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
|
|
|
68
76
|
* @csspart tooltip-arrow-top - The point while the bubble is above the reading, on its bottom edge. Set alongside `tooltip-arrow`.
|
|
69
77
|
* @csspart tooltip-bottom - The bubble while it is below the reading. Set alongside `tooltip`.
|
|
70
78
|
* @csspart tooltip-cell - One column's name and value inside the tooltip.
|
|
79
|
+
* @csspart tooltip-cell-current - The cell the up and down arrows rest on, while they rest there. Set alongside `tooltip-cell`.
|
|
71
80
|
* @csspart tooltip-label - The row's own name inside the tooltip.
|
|
72
81
|
* @csspart tooltip-left - The bubble while it is left of the reading. Set alongside `tooltip`.
|
|
73
82
|
* @csspart tooltip-name - A column's name inside the tooltip.
|
|
@@ -149,7 +158,12 @@ export declare class HelixHeadlessScatterChart extends HelixHeadlessScatterChart
|
|
|
149
158
|
* absent where there are fewer than three points or no spread to measure.
|
|
150
159
|
*/
|
|
151
160
|
protected renderSummary(field: ScatterField): TemplateResult;
|
|
152
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* The row a pointer is resting on, over the point it is nearest.
|
|
163
|
+
*
|
|
164
|
+
* A row reached by key has no nearest point, so the bubble sits on the
|
|
165
|
+
* point of the series the keys rest on, or on the row's first point.
|
|
166
|
+
*/
|
|
153
167
|
protected renderTooltip(): TemplateResult | typeof nothing;
|
|
154
168
|
/**
|
|
155
169
|
* The point a pointer is nearest, within reach.
|