@fusion.dev/helix-headless 0.143.0 → 0.145.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 +16990 -1383
- package/dist/accordion/item/accordion-item.d.ts +48 -12
- package/dist/accordion/item/accordion-item.js +26 -5
- package/dist/accordion/root/accordion-root.d.ts +6 -0
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +21 -1
- package/dist/announcement/root/announcement-root.js +36 -1
- package/dist/app-header/root/app-header-root.d.ts +7 -0
- package/dist/app-header/root/app-header-root.js +5 -1
- package/dist/app-header/sectioning.d.ts +7 -0
- package/dist/app-header/sectioning.js +26 -0
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +24 -7
- package/dist/avatar/root/avatar-root.d.ts +14 -0
- package/dist/avatar/root/avatar-root.js +23 -9
- package/dist/badge/root/badge-root.d.ts +11 -7
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
- package/dist/bar-chart/root/bar-chart-root.js +17 -10
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
- package/dist/button/root/button-root.d.ts +47 -1
- package/dist/button/root/button-root.js +38 -4
- package/dist/callout/root/callout-root.d.ts +18 -1
- package/dist/callout/root/callout-root.js +15 -4
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +121 -40
- 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 +90 -0
- package/dist/carousel/root/carousel-root.js +134 -12
- package/dist/chat/composer/chat-composer.d.ts +38 -6
- package/dist/chat/composer/chat-composer.js +42 -9
- package/dist/chat/message/chat-message.d.ts +32 -1
- package/dist/chat/message/chat-message.js +25 -9
- package/dist/chat/naming.d.ts +22 -0
- package/dist/chat/naming.js +12 -0
- package/dist/chat/relative-clock.d.ts +39 -0
- package/dist/chat/relative-clock.js +31 -0
- package/dist/chat/root/chat-root.d.ts +36 -0
- package/dist/chat/root/chat-root.js +24 -1
- package/dist/checkbox/root/checkbox-root.js +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
- package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
- 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 +38 -1
- package/dist/code-block/root/code-block-root.js +28 -7
- package/dist/color-input/root/color-input-root.d.ts +34 -1
- package/dist/color-input/root/color-input-root.js +23 -4
- 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 +81 -5
- package/dist/color-picker/root/color-picker-root.js +103 -10
- package/dist/combobox/root/combobox-root.d.ts +38 -3
- package/dist/combobox/root/combobox-root.js +64 -2
- package/dist/command/root/command-root.d.ts +30 -4
- package/dist/command/root/command-root.js +33 -3
- 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 +47 -1
- package/dist/copy-button/root/copy-button-root.js +44 -8
- package/dist/data-table/root/data-table-root.d.ts +150 -2
- package/dist/data-table/root/data-table-root.js +303 -29
- package/dist/data-table/tree.d.ts +40 -0
- package/dist/data-table/tree.js +55 -0
- package/dist/date-input/root/date-input-root.d.ts +73 -4
- package/dist/date-input/root/date-input-root.js +93 -43
- package/dist/date-picker/root/date-picker-root.d.ts +145 -1
- package/dist/date-picker/root/date-picker-root.js +239 -48
- package/dist/description-list/item/description-list-item.d.ts +17 -2
- package/dist/description-list/item/description-list-item.js +15 -2
- package/dist/description-list/root/description-list-root.d.ts +27 -1
- package/dist/description-list/root/description-list-root.js +26 -1
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +64 -1
- package/dist/dialog/root/dialog-root.js +49 -23
- package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
- package/dist/donut-chart/root/donut-chart-root.js +21 -6
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +95 -19
- 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 +11 -6
- package/dist/drilldown/item/drilldown-item.js +8 -5
- package/dist/drilldown/root/drilldown-root.d.ts +11 -0
- package/dist/drilldown/root/drilldown-root.js +8 -3
- package/dist/element-events.generated.js +61 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +47 -0
- package/dist/file-input/root/file-input-root.js +60 -22
- 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 +3 -0
- package/dist/filter-input/menu/filter-menu.js +8 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -4
- package/dist/filter-input/root/filter-input-root.js +67 -3
- 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 +51 -0
- package/dist/format-date/root/format-date-root.js +58 -38
- package/dist/heatmap/root/heatmap-root.d.ts +23 -6
- package/dist/heatmap/root/heatmap-root.js +24 -13
- 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 +30 -4
- package/dist/icon/root/icon-root.js +41 -6
- 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/image/root/image-root.d.ts +14 -0
- package/dist/image/root/image-root.js +23 -2
- package/dist/input/root/input-root.d.ts +11 -0
- package/dist/input/root/input-root.js +16 -1
- package/dist/kbd/root/kbd-root.d.ts +20 -13
- package/dist/kbd/root/kbd-root.js +35 -37
- 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 +56 -0
- package/dist/legend/root/legend-root.js +54 -5
- package/dist/lightbox/item/lightbox-item.d.ts +15 -0
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +61 -1
- package/dist/lightbox/root/lightbox-root.js +94 -4
- package/dist/line-chart/root/line-chart-root.d.ts +11 -3
- package/dist/line-chart/root/line-chart-root.js +19 -5
- package/dist/list/item/list-item.d.ts +68 -1
- package/dist/list/item/list-item.js +66 -4
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +106 -9
- package/dist/list/root/list-root.js +189 -4
- package/dist/list/selection.d.ts +19 -0
- package/dist/list/selection.js +21 -0
- package/dist/listbox/root/listbox-root.d.ts +74 -3
- package/dist/listbox/root/listbox-root.js +86 -9
- 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 +6 -2
- package/dist/map/root/map-root.js +5 -2
- package/dist/megamenu/root/megamenu-root.d.ts +21 -0
- package/dist/megamenu/root/megamenu-root.js +16 -2
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +38 -11
- package/dist/menu/item/menu-item.js +33 -1
- package/dist/menu/root/menu-root.d.ts +25 -1
- package/dist/menu/root/menu-root.js +63 -6
- package/dist/menu/section/menu-section.d.ts +55 -0
- package/dist/menu/section/menu-section.js +60 -0
- package/dist/meter/root/meter-root.d.ts +7 -0
- package/dist/meter/root/meter-root.js +6 -3
- package/dist/navigation/root/navigation-root.d.ts +16 -1
- package/dist/navigation/root/navigation-root.js +27 -1
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/notification/notification.d.ts +17 -0
- package/dist/notifications/notification/notification.js +21 -2
- package/dist/notifications/root/notifications-root.d.ts +60 -0
- package/dist/notifications/root/notifications-root.js +76 -1
- package/dist/number-input/root/number-input-root.d.ts +47 -0
- package/dist/number-input/root/number-input-root.js +58 -22
- package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
- package/dist/object-inspector/root/object-inspector-root.js +180 -80
- package/dist/object-inspector/rows.d.ts +57 -0
- package/dist/object-inspector/rows.js +86 -0
- package/dist/option/root/option-root.d.ts +54 -5
- package/dist/option/root/option-root.js +34 -5
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +68 -3
- package/dist/outline/root/outline-root.js +73 -8
- package/dist/pagination/size/pagination-size.d.ts +11 -2
- package/dist/pagination/size/pagination-size.js +19 -4
- 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 +21 -0
- package/dist/pin-input/root/pin-input-root.js +29 -2
- package/dist/popover/root/popover-root.d.ts +62 -4
- package/dist/popover/root/popover-root.js +53 -5
- package/dist/progress/root/progress-root.d.ts +7 -0
- package/dist/progress/root/progress-root.js +9 -3
- 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 +26 -0
- package/dist/qr-code/root/qr-code-root.js +49 -2
- package/dist/radio/group/radio-group.d.ts +17 -0
- package/dist/radio/group/radio-group.js +14 -1
- package/dist/rating/root/rating-root.d.ts +25 -0
- package/dist/rating/root/rating-root.js +46 -4
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
- package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
- package/dist/scroll-area/root/scroll-area-root.js +218 -3
- package/dist/scroll-area/scrollbar.d.ts +65 -0
- package/dist/scroll-area/scrollbar.js +24 -0
- package/dist/select/root/select-root.d.ts +24 -0
- package/dist/select/root/select-root.js +21 -7
- package/dist/skeleton/root/skeleton-root.d.ts +25 -0
- package/dist/skeleton/root/skeleton-root.js +17 -2
- package/dist/slider/root/slider-root.d.ts +39 -0
- package/dist/slider/root/slider-root.js +45 -9
- package/dist/splitter/root/splitter-root.d.ts +13 -0
- package/dist/splitter/root/splitter-root.js +20 -2
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/stat/root/stat-root.d.ts +2 -0
- package/dist/stat/root/stat-root.js +1 -1
- package/dist/steps/reach.d.ts +15 -0
- package/dist/steps/reach.js +12 -0
- package/dist/steps/root/steps-root.d.ts +30 -0
- package/dist/steps/root/steps-root.js +53 -0
- package/dist/steps/step/step.d.ts +39 -2
- package/dist/steps/step/step.js +29 -7
- package/dist/switch/root/switch-root.d.ts +12 -2
- package/dist/switch/root/switch-root.js +6 -1
- package/dist/table/column/table-column.d.ts +11 -0
- package/dist/table/column/table-column.js +6 -1
- package/dist/table/root/table-root.d.ts +101 -0
- package/dist/table/root/table-root.js +166 -5
- package/dist/table/row/table-row.d.ts +47 -1
- package/dist/table/row/table-row.js +39 -2
- package/dist/tabs/panel/tab-panel.d.ts +9 -5
- package/dist/tabs/panel/tab-panel.js +3 -4
- package/dist/tabs/root/tabs-root.d.ts +25 -1
- package/dist/tabs/root/tabs-root.js +21 -3
- package/dist/tabs/tab/tab.d.ts +36 -4
- package/dist/tabs/tab/tab.js +46 -3
- 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 +60 -0
- package/dist/tag/root/tag-root.js +74 -18
- 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 +9 -0
- package/dist/textarea/root/textarea-root.js +9 -1
- package/dist/time-input/root/time-input-root.d.ts +44 -5
- package/dist/time-input/root/time-input-root.js +69 -39
- package/dist/time-picker/root/time-picker-root.d.ts +54 -8
- package/dist/time-picker/root/time-picker-root.js +121 -91
- package/dist/timeline/group/timeline-group.d.ts +46 -0
- package/dist/timeline/group/timeline-group.js +37 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +1 -0
- package/dist/timeline/root/timeline-root.d.ts +10 -3
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +26 -18
- package/dist/toast/item/toast-item.js +55 -48
- package/dist/toast/root/toast-root.d.ts +42 -8
- package/dist/toast/root/toast-root.js +64 -4
- package/dist/toggle/group/toggle-group.d.ts +57 -15
- package/dist/toggle/group/toggle-group.js +69 -9
- package/dist/toggle/root/toggle-root.d.ts +12 -1
- package/dist/toggle/root/toggle-root.js +11 -3
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- 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 +42 -17
- package/dist/tooltip/root/tooltip-root.js +50 -9
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +35 -0
- package/dist/tour/root/tour-root.js +56 -5
- package/dist/tour/stop/tour-stop.d.ts +53 -8
- package/dist/tour/stop/tour-stop.js +45 -15
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/tree/item/tree-item.d.ts +54 -1
- package/dist/tree/item/tree-item.js +89 -20
- package/dist/tree/root/tree-root.d.ts +37 -0
- package/dist/tree/root/tree-root.js +51 -6
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +26 -0
- package/dist/trend/root/trend-root.d.ts +13 -0
- package/dist/trend/root/trend-root.js +14 -9
- package/dist/video/media-events.d.ts +49 -0
- package/dist/video/media-events.js +39 -0
- package/dist/video/root/video-root.d.ts +99 -13
- package/dist/video/root/video-root.js +84 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
- package/dist/video-playlist/root/video-playlist-root.js +60 -16
- package/dist/virtual-list/controls.d.ts +4 -0
- package/dist/virtual-list/controls.js +30 -0
- package/dist/virtual-list/fill.d.ts +30 -0
- package/dist/virtual-list/fill.js +39 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
- package/dist/virtual-list/root/virtual-list-root.js +175 -34
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +8871 -1286
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1918 -269
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AriaForwardController, DisabledCascadeController, HelixFormElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { HelixHeadlessOption } from '../../option/root/option-root.js';
|
|
4
4
|
declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
5
5
|
/**
|
|
@@ -24,10 +24,18 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
|
|
|
24
24
|
* letters move it to the next option whose words start with them. In a
|
|
25
25
|
* single-choice list the highlight is the choice unless `manual` is set; then
|
|
26
26
|
* Enter, Space or a click chooses. With `multiple`, Space toggles the
|
|
27
|
-
* highlighted option, Shift with an arrow adds the option it moves to,
|
|
27
|
+
* highlighted option, Shift with an arrow adds the option it moves to, Shift
|
|
28
|
+
* with Home or End adds every option from the highlight to that end, and
|
|
28
29
|
* Control+A or Command+A chooses every option, or none where all are chosen.
|
|
29
30
|
* In a filter field, Space, Home, End and letters edit the text.
|
|
30
31
|
*
|
|
32
|
+
* An option with `href` is a link: Enter or a press follows it and selects
|
|
33
|
+
* nothing, and moving onto it with the arrows does not follow it.
|
|
34
|
+
*
|
|
35
|
+
* As a filter narrows the list, a screen reader hears how many options are
|
|
36
|
+
* left, such as "3 results", from `result-label` and `results-label`. A filter
|
|
37
|
+
* that leaves none says `empty-text`.
|
|
38
|
+
*
|
|
31
39
|
* @since 0.1.0
|
|
32
40
|
* @status stable
|
|
33
41
|
* @category forms
|
|
@@ -35,10 +43,12 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
|
|
|
35
43
|
* @documentation https://fusion.dev/helix/components/listbox
|
|
36
44
|
*
|
|
37
45
|
* @slot - The options, and any groups of them.
|
|
46
|
+
* @slot empty - What the list shows when it has no options to show, for content richer than `empty-text`.
|
|
38
47
|
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
39
48
|
* @slot filter-icon - The icon in the filter field. Defaults to a magnifying glass.
|
|
40
49
|
* @slot hint - The hint, for content richer than plain text.
|
|
41
50
|
* @slot label - The label, for content richer than plain text.
|
|
51
|
+
* @slot loading - What the list shows while its options load, for content richer than `loading-text`.
|
|
42
52
|
*
|
|
43
53
|
* @event {Event} change - Fired after the value changes.
|
|
44
54
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired when the value is about to change, and cancelable.
|
|
@@ -52,12 +62,14 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
|
|
|
52
62
|
* @csspart hint - Help under the list.
|
|
53
63
|
* @csspart items - The list of options.
|
|
54
64
|
* @csspart label - The label above the list.
|
|
55
|
-
* @csspart live - A copy of the empty and loading text, in a region that screen readers announce when it changes. Visually hidden in the styled tier.
|
|
65
|
+
* @csspart live - A copy of the empty and loading text, and how many options a filter left, in a region that screen readers announce when it changes. Visually hidden in the styled tier.
|
|
56
66
|
* @csspart loading - The text shown while the options load.
|
|
57
67
|
* @csspart search - The region that holds the filter field.
|
|
58
68
|
* @csspart search-field - The filter field.
|
|
59
69
|
*
|
|
70
|
+
* @cssstate empty - The list has no options to show: none were given, or the filter hid every one.
|
|
60
71
|
* @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
|
|
72
|
+
* @cssstate loading - While `loading` is set.
|
|
61
73
|
*/
|
|
62
74
|
export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
63
75
|
protected readonly aria: AriaForwardController;
|
|
@@ -104,6 +116,16 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
104
116
|
* own search boxes would be three copies of one field.
|
|
105
117
|
*/
|
|
106
118
|
filterable: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* How long typing in the filter field rests before the list is filtered, in
|
|
121
|
+
* milliseconds. `0` filters on every keystroke.
|
|
122
|
+
*
|
|
123
|
+
* For a list filtered on a server, where `helix-filter` starts a request: a
|
|
124
|
+
* reader typing a word sends one request for the word, not one for each
|
|
125
|
+
* letter. Enter and the arrow keys filter at once on what is typed, so they
|
|
126
|
+
* act on the list the reader expects.
|
|
127
|
+
*/
|
|
128
|
+
filterDelay: number;
|
|
107
129
|
/**
|
|
108
130
|
* Placeholder text for the filter field.
|
|
109
131
|
*/
|
|
@@ -121,6 +143,20 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
121
143
|
* Whether more than one option can be chosen.
|
|
122
144
|
*/
|
|
123
145
|
multiple: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* What a screen reader hears when a filter leaves one option. `{count}` is
|
|
148
|
+
* the count.
|
|
149
|
+
*/
|
|
150
|
+
resultLabel: string;
|
|
151
|
+
/**
|
|
152
|
+
* What a screen reader hears when a filter leaves any other number of
|
|
153
|
+
* options. `{count}` is the count.
|
|
154
|
+
*
|
|
155
|
+
* **Two sentences, chosen by `Intl.PluralRules`**, which is Data Table's
|
|
156
|
+
* pair: a language with more forms than two picks the one for its `one` and
|
|
157
|
+
* writes the rest here.
|
|
158
|
+
*/
|
|
159
|
+
resultsLabel: string;
|
|
124
160
|
/**
|
|
125
161
|
* Which option the keyboard is on, which is not what is chosen.
|
|
126
162
|
*/
|
|
@@ -189,6 +225,18 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
189
225
|
* ArrowUp, and Combobox moves the highlight off the list onto its create row.
|
|
190
226
|
*/
|
|
191
227
|
highlight(where: 'first' | 'last' | 'none' | 'selected'): void;
|
|
228
|
+
/**
|
|
229
|
+
* Says how many options a filter left, in the live region.
|
|
230
|
+
*
|
|
231
|
+
* **A reader typing into a filter cannot see the list narrow**, and React
|
|
232
|
+
* Aria and Web Awesome both say the count as it changes. Only "No matches"
|
|
233
|
+
* was said here, so a query that left forty options and one that left one
|
|
234
|
+
* sounded the same. Said when the filter changes and the count with it, so
|
|
235
|
+
* a keystroke that leaves the same options says nothing new. An empty filter
|
|
236
|
+
* says nothing, being the list as it was given; no matches is `empty-text`,
|
|
237
|
+
* which the region says in place of this.
|
|
238
|
+
*/
|
|
239
|
+
private tell;
|
|
192
240
|
/**
|
|
193
241
|
* @internal Moves the highlight to the option whose words start with the
|
|
194
242
|
* letters typed, and returns its value, or nothing where none matches.
|
|
@@ -376,6 +424,12 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
376
424
|
* their answer moved when it did not is worse than telling them nothing.
|
|
377
425
|
*/
|
|
378
426
|
private readonly handleFilter;
|
|
427
|
+
/** The filter waiting out `filterDelay`, if any. */
|
|
428
|
+
private readonly filtering;
|
|
429
|
+
/** Filters on what the field holds, and puts the field back where that was refused. */
|
|
430
|
+
private takeFilter;
|
|
431
|
+
/** Filters at once on a filter still waiting out `filterDelay`. */
|
|
432
|
+
private flushFilter;
|
|
379
433
|
/** Requests a new filter, and returns whether the request went through. */
|
|
380
434
|
requestFilter(next: string): boolean;
|
|
381
435
|
/**
|
|
@@ -414,6 +468,23 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
414
468
|
* cannot change.
|
|
415
469
|
*/
|
|
416
470
|
protected renderFilterIcon(): TemplateResult;
|
|
471
|
+
/**
|
|
472
|
+
* Whether there is anything to show.
|
|
473
|
+
*
|
|
474
|
+
* Showing nothing is not the same as empty. A filter that hides every option
|
|
475
|
+
* is empty, and one with no filter and no options is empty too, but a list
|
|
476
|
+
* still waiting on its options is neither.
|
|
477
|
+
*/
|
|
478
|
+
private get showsOptions();
|
|
479
|
+
/**
|
|
480
|
+
* The empty or loading line, with a slot for each so either can be richer
|
|
481
|
+
* than its text.
|
|
482
|
+
*
|
|
483
|
+
* **The text is the slot's fallback**, which is this library's rule for a
|
|
484
|
+
* content property, so `empty-text` still shows where nothing is slotted and
|
|
485
|
+
* the live region still says it.
|
|
486
|
+
*/
|
|
487
|
+
protected renderStatus(hasContent: boolean): TemplateResult | typeof nothing;
|
|
417
488
|
protected render(): TemplateResult;
|
|
418
489
|
}
|
|
419
490
|
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, DisabledCascadeController, HelixFilterEvent, HelixFormElement, hostAria, MixinCollection, MixinControllerValue, MixinField, reportValues, requestChange, scrollItemIntoView, Typeahead, typesCharacter, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, countLabel, customElement, DelayController, DisabledCascadeController, HelixFilterEvent, HelixFormElement, hostAria, MixinCollection, MixinControllerValue, MixinField, rangeAdd, reportValues, requestChange, scrollItemIntoView, Typeahead, typesCharacter, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { magnifyingGlass } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -68,9 +68,12 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
68
68
|
this.emptyText = 'No matches';
|
|
69
69
|
this.filterState = undefined;
|
|
70
70
|
this.filterable = false;
|
|
71
|
+
this.filterDelay = 0;
|
|
71
72
|
this.filterLabel = 'Filter';
|
|
72
73
|
this.manual = false;
|
|
73
74
|
this.multiple = false;
|
|
75
|
+
this.resultLabel = '{count} result';
|
|
76
|
+
this.resultsLabel = '{count} results';
|
|
74
77
|
this.activeValue = '';
|
|
75
78
|
this.parked = false;
|
|
76
79
|
this.typeahead = new Typeahead();
|
|
@@ -82,6 +85,9 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
82
85
|
items: () => this.options,
|
|
83
86
|
});
|
|
84
87
|
this.handleSelection = (event) => {
|
|
88
|
+
if (event.detail.href !== undefined) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
85
91
|
event.stopPropagation();
|
|
86
92
|
if (event.defaultPrevented) {
|
|
87
93
|
return;
|
|
@@ -96,7 +102,14 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
96
102
|
}
|
|
97
103
|
const typing = this.forwarded || event.composedPath()[0] === this.partNamed('search-field');
|
|
98
104
|
if (event.key === 'Enter' || (event.key === ' ' && !typing && !this.typeahead.typing())) {
|
|
99
|
-
|
|
105
|
+
const link = shown.find((option) => option.value === this.activeValue && Boolean(option.href));
|
|
106
|
+
if (link !== undefined) {
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
if (event.key === 'Enter') {
|
|
109
|
+
link.select(event);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (this.activeValue !== '') {
|
|
100
113
|
event.preventDefault();
|
|
101
114
|
this.choose(this.activeValue);
|
|
102
115
|
}
|
|
@@ -155,6 +168,14 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
155
168
|
const target = shown[next];
|
|
156
169
|
if (target) {
|
|
157
170
|
this.arrive(target.value);
|
|
171
|
+
const ranged = event.key === 'Home' || event.key === 'End';
|
|
172
|
+
if (this.multiple && !typing && event.shiftKey && ranged) {
|
|
173
|
+
const taken = rangeAdd(this.values, shown.map((option) => option.value), at, next);
|
|
174
|
+
if (taken) {
|
|
175
|
+
this.requestValue(taken.join(','));
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
158
179
|
if (this.multiple && !typing && event.shiftKey && !this.values.includes(target.value)) {
|
|
159
180
|
this.choose(target.value);
|
|
160
181
|
}
|
|
@@ -163,16 +184,27 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
163
184
|
this.handleFilter = (event) => {
|
|
164
185
|
event.stopPropagation();
|
|
165
186
|
const control = event.target;
|
|
166
|
-
this.
|
|
167
|
-
if (
|
|
168
|
-
|
|
187
|
+
this.filtering.cancel();
|
|
188
|
+
if (this.filterDelay > 0) {
|
|
189
|
+
this.filtering.start(this.filterDelay, () => this.takeFilter(control));
|
|
190
|
+
return;
|
|
169
191
|
}
|
|
192
|
+
this.takeFilter(control);
|
|
170
193
|
};
|
|
194
|
+
this.filtering = new DelayController(this, { renders: false });
|
|
171
195
|
this.handleFilterKeydown = (event) => {
|
|
172
|
-
if (event.key === '
|
|
196
|
+
if (event.key === 'Enter' || FIELD_MOVES.has(event.key)) {
|
|
197
|
+
this.flushFilter();
|
|
198
|
+
}
|
|
199
|
+
if (event.key === 'Escape' && (this.filter !== '' || this.filtering.pending)) {
|
|
173
200
|
event.stopPropagation();
|
|
174
201
|
event.preventDefault();
|
|
202
|
+
this.filtering.cancel();
|
|
175
203
|
this.requestFilter('');
|
|
204
|
+
const control = this.partNamed('search-field');
|
|
205
|
+
if (control && control.value !== this.filter) {
|
|
206
|
+
control.value = this.filter;
|
|
207
|
+
}
|
|
176
208
|
return;
|
|
177
209
|
}
|
|
178
210
|
if (!FIELD_MOVES.has(event.key)) {
|
|
@@ -218,6 +250,17 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
218
250
|
this.place();
|
|
219
251
|
}
|
|
220
252
|
}
|
|
253
|
+
tell(changed) {
|
|
254
|
+
if (!changed.has('filter') || !this.hasUpdated) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const count = this.shown.length;
|
|
258
|
+
if (this.filter.trim() === '' || count === 0) {
|
|
259
|
+
this.announced = '';
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
this.announced = countLabel(count, this.resultLabel, this.resultsLabel, this.lang);
|
|
263
|
+
}
|
|
221
264
|
typeaheadTo(key) {
|
|
222
265
|
const shown = this.shown.filter((option) => !option.disabled);
|
|
223
266
|
const from = shown.findIndex((option) => option.value === this.currentValue);
|
|
@@ -294,7 +337,8 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
294
337
|
arrive(value) {
|
|
295
338
|
this.parked = false;
|
|
296
339
|
this.activeValue = value;
|
|
297
|
-
|
|
340
|
+
const link = this.options.some((option) => option.value === value && Boolean(option.href));
|
|
341
|
+
if (!this.multiple && !this.manual && !this.forwarded && !link) {
|
|
298
342
|
this.choose(value);
|
|
299
343
|
}
|
|
300
344
|
}
|
|
@@ -423,7 +467,10 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
423
467
|
}
|
|
424
468
|
if (this.childrenKnown) {
|
|
425
469
|
this.place();
|
|
470
|
+
this.tell(changed);
|
|
426
471
|
}
|
|
472
|
+
this.toggleState('empty', !this.showsOptions);
|
|
473
|
+
this.toggleState('loading', this.loading);
|
|
427
474
|
}
|
|
428
475
|
seedDeclared() {
|
|
429
476
|
if (this.owned || this.defaultValue !== '' || this.hasAttribute('default-value')) {
|
|
@@ -453,6 +500,16 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
453
500
|
this.sync();
|
|
454
501
|
this.linkActive();
|
|
455
502
|
}
|
|
503
|
+
takeFilter(control) {
|
|
504
|
+
this.filtering.cancel();
|
|
505
|
+
this.requestFilter(control.value);
|
|
506
|
+
if (control.value !== this.filter) {
|
|
507
|
+
control.value = this.filter;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
flushFilter() {
|
|
511
|
+
this.filtering.flush();
|
|
512
|
+
}
|
|
456
513
|
requestFilter(next) {
|
|
457
514
|
if (next === this.filter) {
|
|
458
515
|
return true;
|
|
@@ -480,12 +537,23 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
480
537
|
</svg>
|
|
481
538
|
</slot>`;
|
|
482
539
|
}
|
|
483
|
-
|
|
484
|
-
|
|
540
|
+
get showsOptions() {
|
|
541
|
+
return this.counted && !this.loading
|
|
485
542
|
? this.filter === ''
|
|
486
543
|
? this.options.length > 0
|
|
487
544
|
: this.hasMatches
|
|
488
545
|
: true;
|
|
546
|
+
}
|
|
547
|
+
renderStatus(hasContent) {
|
|
548
|
+
if (!this.loading && hasContent) {
|
|
549
|
+
return nothing;
|
|
550
|
+
}
|
|
551
|
+
return this.loading
|
|
552
|
+
? html `<p part="loading"><slot name="loading">${this.loadingText}</slot></p>`
|
|
553
|
+
: html `<p part="empty"><slot name="empty">${this.emptyText}</slot></p>`;
|
|
554
|
+
}
|
|
555
|
+
render() {
|
|
556
|
+
const shown = this.showsOptions;
|
|
489
557
|
return html `${this.renderGroupLabel()}
|
|
490
558
|
${this.filterable
|
|
491
559
|
? html `<div part="search">
|
|
@@ -542,6 +610,9 @@ __decorate([
|
|
|
542
610
|
__decorate([
|
|
543
611
|
property({ attribute: 'filterable', reflect: true, type: Boolean })
|
|
544
612
|
], HelixHeadlessListbox.prototype, "filterable", void 0);
|
|
613
|
+
__decorate([
|
|
614
|
+
property({ attribute: 'filter-delay', type: Number })
|
|
615
|
+
], HelixHeadlessListbox.prototype, "filterDelay", void 0);
|
|
545
616
|
__decorate([
|
|
546
617
|
property({ attribute: 'filter-label' })
|
|
547
618
|
], HelixHeadlessListbox.prototype, "filterLabel", void 0);
|
|
@@ -551,6 +622,12 @@ __decorate([
|
|
|
551
622
|
__decorate([
|
|
552
623
|
property({ reflect: true, type: Boolean })
|
|
553
624
|
], HelixHeadlessListbox.prototype, "multiple", void 0);
|
|
625
|
+
__decorate([
|
|
626
|
+
property({ attribute: 'result-label' })
|
|
627
|
+
], HelixHeadlessListbox.prototype, "resultLabel", void 0);
|
|
628
|
+
__decorate([
|
|
629
|
+
property({ attribute: 'results-label' })
|
|
630
|
+
], HelixHeadlessListbox.prototype, "resultsLabel", void 0);
|
|
554
631
|
__decorate([
|
|
555
632
|
state()
|
|
556
633
|
], HelixHeadlessListbox.prototype, "activeValue", void 0);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks a region busy for as long as something is loading into it, and
|
|
3
|
+
* counts, so two loaders in one region do not clear each other.
|
|
4
|
+
*
|
|
5
|
+
* Beside the family's `index.ts`, because which element is busy and how many
|
|
6
|
+
* claims it holds is bookkeeping about elements, not about a loader's
|
|
7
|
+
* template.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Adds a claim on the region, setting `aria-busy="true"` on the first.
|
|
11
|
+
*
|
|
12
|
+
* Only an `aria-busy` this file wrote is ever taken off again: a region the
|
|
13
|
+
* page marked busy itself keeps its own attribute.
|
|
14
|
+
*/
|
|
15
|
+
export declare const claimBusy: (region: Element) => void;
|
|
16
|
+
/** Takes a claim back, and the attribute with the last one. */
|
|
17
|
+
export declare const releaseBusy: (region: Element) => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const CLAIMS = new WeakMap();
|
|
2
|
+
export const claimBusy = (region) => {
|
|
3
|
+
const held = CLAIMS.get(region) ?? 0;
|
|
4
|
+
if (held === 0 && region.getAttribute('aria-busy') === 'true') {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
CLAIMS.set(region, held + 1);
|
|
8
|
+
if (held === 0) {
|
|
9
|
+
region.setAttribute('aria-busy', 'true');
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const releaseBusy = (region) => {
|
|
13
|
+
const held = CLAIMS.get(region);
|
|
14
|
+
if (held === undefined) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (held <= 1) {
|
|
18
|
+
CLAIMS.delete(region);
|
|
19
|
+
region.removeAttribute('aria-busy');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
CLAIMS.set(region, held - 1);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -19,6 +19,15 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
19
19
|
* a `role` attribute on the host would be missing from React server-rendered
|
|
20
20
|
* markup.
|
|
21
21
|
*
|
|
22
|
+
* **`for` names the region being loaded**, and the loader sets
|
|
23
|
+
* `aria-busy="true"` on it for as long as the loader is on the page, so a
|
|
24
|
+
* screen reader waits for the region rather than reading it half filled. Two
|
|
25
|
+
* loaders in one region hold it busy until the last one leaves.
|
|
26
|
+
*
|
|
27
|
+
* **`delay` keeps a quick load from flashing a loader.** The loader stays
|
|
28
|
+
* hidden, and silent, for that many milliseconds, and appears only if the work
|
|
29
|
+
* is still going.
|
|
30
|
+
*
|
|
22
31
|
* @since 0.1.0
|
|
23
32
|
* @status stable
|
|
24
33
|
* @category feedback
|
|
@@ -33,11 +42,39 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
33
42
|
* @csspart track - The full circle behind the indicator.
|
|
34
43
|
*/
|
|
35
44
|
export declare class HelixHeadlessLoader extends HelixElement {
|
|
45
|
+
/**
|
|
46
|
+
* How long the loader waits before it shows, in milliseconds, so work that
|
|
47
|
+
* finishes quickly never flashes one.
|
|
48
|
+
*
|
|
49
|
+
* Absent shows it at once. Hidden in the served markup too, so a page that
|
|
50
|
+
* loads quickly never draws it.
|
|
51
|
+
*/
|
|
52
|
+
delay: number;
|
|
53
|
+
/**
|
|
54
|
+
* The id of the region being loaded, which is marked `aria-busy` while the
|
|
55
|
+
* loader is on the page.
|
|
56
|
+
*
|
|
57
|
+
* Names an element in the same tree. In React it arrives as a property, the
|
|
58
|
+
* way `Tooltip.for` does.
|
|
59
|
+
*/
|
|
60
|
+
for: string;
|
|
36
61
|
/**
|
|
37
62
|
* The loader's name, announced by screen readers while the work is in
|
|
38
63
|
* progress.
|
|
39
64
|
*/
|
|
40
65
|
label: string;
|
|
66
|
+
/** The wait `delay` asks for, and whether it has run out. */
|
|
67
|
+
private readonly due;
|
|
68
|
+
/** The region this loader marked busy, so it is the one released. */
|
|
69
|
+
private region;
|
|
70
|
+
/** Whether the loader is still waiting out its `delay`. */
|
|
71
|
+
private get waiting();
|
|
72
|
+
connectedCallback(): void;
|
|
73
|
+
disconnectedCallback(): void;
|
|
74
|
+
/** Marks the region `for` names busy, releasing one it named before. */
|
|
75
|
+
private mark;
|
|
76
|
+
private release;
|
|
77
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
41
78
|
protected willUpdate(changed: PropertyValues): void;
|
|
42
79
|
protected render(): TemplateResult;
|
|
43
80
|
}
|
|
@@ -4,27 +4,76 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, DelayController, elementById, HelixElement, hostAria, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { claimBusy, releaseBusy } from '../busy.js';
|
|
10
11
|
let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
14
|
+
this.delay = 0;
|
|
15
|
+
this.for = '';
|
|
13
16
|
this.label = 'Loading';
|
|
17
|
+
this.due = new DelayController(this);
|
|
18
|
+
this.region = null;
|
|
19
|
+
}
|
|
20
|
+
get waiting() {
|
|
21
|
+
return this.delay > 0 && !this.due.elapsed;
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
super.connectedCallback();
|
|
25
|
+
if (this.delay > 0 && !this.due.elapsed) {
|
|
26
|
+
this.due.start(this.delay);
|
|
27
|
+
}
|
|
28
|
+
requestAnimationFrame(() => this.mark());
|
|
29
|
+
}
|
|
30
|
+
disconnectedCallback() {
|
|
31
|
+
super.disconnectedCallback();
|
|
32
|
+
this.release();
|
|
33
|
+
}
|
|
34
|
+
mark() {
|
|
35
|
+
const region = this.isConnected && this.for !== '' ? elementById(this, this.for) : null;
|
|
36
|
+
if (region === this.region) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.release();
|
|
40
|
+
if (region) {
|
|
41
|
+
claimBusy(region);
|
|
42
|
+
this.region = region;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
release() {
|
|
46
|
+
if (this.region) {
|
|
47
|
+
releaseBusy(this.region);
|
|
48
|
+
this.region = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
updated(changed) {
|
|
52
|
+
super.updated(changed);
|
|
53
|
+
if (changed.has('for') && changed.get('for') !== undefined) {
|
|
54
|
+
this.mark();
|
|
55
|
+
}
|
|
14
56
|
}
|
|
15
57
|
willUpdate(changed) {
|
|
16
58
|
super.willUpdate(changed);
|
|
17
59
|
hostAria(this.internals, { label: this.label, role: 'progressbar' });
|
|
18
60
|
this.internals.ariaBusy = 'true';
|
|
61
|
+
this.internals.ariaHidden = this.waiting ? 'true' : null;
|
|
19
62
|
}
|
|
20
63
|
render() {
|
|
21
|
-
return html `<svg part="svg" viewBox="0 0 24 24" aria-hidden="true">
|
|
64
|
+
return html `<svg part="svg" viewBox="0 0 24 24" aria-hidden="true" ?hidden=${this.waiting}>
|
|
22
65
|
<circle part="track" cx="12" cy="12" r="10" fill="none" />
|
|
23
66
|
<circle part="indicator" cx="12" cy="12" r="10" fill="none" />
|
|
24
67
|
</svg>
|
|
25
|
-
<span part="mark" aria-hidden="true"><slot></slot></span>`;
|
|
68
|
+
<span part="mark" aria-hidden="true" ?hidden=${this.waiting}><slot></slot></span>`;
|
|
26
69
|
}
|
|
27
70
|
};
|
|
71
|
+
__decorate([
|
|
72
|
+
property({ type: Number })
|
|
73
|
+
], HelixHeadlessLoader.prototype, "delay", void 0);
|
|
74
|
+
__decorate([
|
|
75
|
+
property()
|
|
76
|
+
], HelixHeadlessLoader.prototype, "for", void 0);
|
|
28
77
|
__decorate([
|
|
29
78
|
property()
|
|
30
79
|
], HelixHeadlessLoader.prototype, "label", void 0);
|
|
@@ -45,7 +45,8 @@ declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.de
|
|
|
45
45
|
* for each layer, which sets the layer's `hidden` attribute. Layers with the
|
|
46
46
|
* same `group`, such as a route and its dotted legs, share one tile. A tile
|
|
47
47
|
* sends `helix-before-toggle` from the layer first, so you can store the
|
|
48
|
-
* choice or refuse it
|
|
48
|
+
* choice or refuse it, and `helix-toggle` from it once `hidden` holds the
|
|
49
|
+
* choice.
|
|
49
50
|
*
|
|
50
51
|
* Imagery, a `helix-map-raster` with `ground`, is a map type and not a tile.
|
|
51
52
|
* The menu opens with a card for each type, Standard, Hybrid, and Satellite,
|
|
@@ -80,6 +81,7 @@ declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.de
|
|
|
80
81
|
* @event {HelixMapRotateEvent} helix-map-rotate - A rotate or Face north button, or Shift with Left or Right, was pressed. Turn your map in response.
|
|
81
82
|
* @event {HelixMapTiltEvent} helix-map-tilt - The 3D button, or Shift with Up or Down, was pressed. Tilt your map in response.
|
|
82
83
|
* @event {HelixMapZoomEvent} helix-map-zoom - A zoom button or key was pressed, with a direction. Zoom your map in response.
|
|
84
|
+
* @event {HelixToggleEvent} helix-toggle - A layer's tile in the layers menu showed or hid it. Sent from the layer once its `hidden` attribute holds the choice, with `checked` true when it is shown.
|
|
83
85
|
*
|
|
84
86
|
* @csspart attribution - The strip under the map that holds the credit.
|
|
85
87
|
* @csspart compass - The compass and the pan and rotate buttons around it.
|
|
@@ -291,7 +293,9 @@ export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
|
|
|
291
293
|
* **Asked first, from the layer.** The tile wrote `hidden` onto the
|
|
292
294
|
* consumer's element and said nothing, so a page could neither keep the
|
|
293
295
|
* choice nor keep its own state in step. The request comes from the first
|
|
294
|
-
* layer of the tile, which is the element the page wrote.
|
|
296
|
+
* layer of the tile, which is the element the page wrote. Once `hidden`
|
|
297
|
+
* holds the answer, the same layer sends `helix-toggle`, the request's verb
|
|
298
|
+
* without `before`, since the platform has no word for a layer shown.
|
|
295
299
|
*/
|
|
296
300
|
private showLayers;
|
|
297
301
|
/** Asks for a map type, and sends `change` once it holds. */
|
|
@@ -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, fillTemplate, formatNumbers, HelixActivateEvent, HelixBeforeChangeEvent, HelixBeforeToggleEvent, HelixElement, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, hostAria, KeyboardNavigationController, MixinViewport, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, fillTemplate, formatNumbers, HelixActivateEvent, HelixBeforeChangeEvent, HelixBeforeToggleEvent, HelixElement, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixToggleEvent, hostAria, KeyboardNavigationController, MixinViewport, requestChange, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { buildings, cloudRain, dotsNine, leaf, mountains, path, polygon, stack, target, } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -210,7 +210,7 @@ let HelixHeadlessMap = class HelixHeadlessMap extends MixinViewport(HelixElement
|
|
|
210
210
|
if (!first) {
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
|
-
requestChange({
|
|
213
|
+
const applied = requestChange({
|
|
214
214
|
apply: () => {
|
|
215
215
|
for (const layer of layers) {
|
|
216
216
|
layer.hidden = !shown;
|
|
@@ -221,6 +221,9 @@ let HelixHeadlessMap = class HelixHeadlessMap extends MixinViewport(HelixElement
|
|
|
221
221
|
host: first,
|
|
222
222
|
next: shown,
|
|
223
223
|
});
|
|
224
|
+
if (applied) {
|
|
225
|
+
first.dispatchEvent(new HelixToggleEvent({ checked: shown }));
|
|
226
|
+
}
|
|
224
227
|
}
|
|
225
228
|
chooseMapType(type) {
|
|
226
229
|
const applied = requestChange({
|
|
@@ -20,6 +20,13 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
|
|
|
20
20
|
* which. Hover is the default because in a navigation bar people expect to move
|
|
21
21
|
* along the row and see each section.
|
|
22
22
|
*
|
|
23
|
+
* When one panel opens in place of another, each says which way the reader
|
|
24
|
+
* moved, as Radix's `data-motion` does: the one opening is
|
|
25
|
+
* `:state(from-start)` or `:state(from-end)`, by where the one closing sits in
|
|
26
|
+
* the bar, and the one closing is `:state(to-start)` or `:state(to-end)`. A
|
|
27
|
+
* stylesheet slides them on that. Put megamenus in a `Navigation` with
|
|
28
|
+
* `arrows` and the arrow keys move between their triggers.
|
|
29
|
+
*
|
|
23
30
|
* @since 0.1.0
|
|
24
31
|
* @status stable
|
|
25
32
|
* @category navigation
|
|
@@ -38,8 +45,12 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
|
|
|
38
45
|
*
|
|
39
46
|
* @cssproperty --megamenu-top - Where the panel starts, measured from the bar above it.
|
|
40
47
|
*
|
|
48
|
+
* @cssstate from-end - The panel opened in place of one later in the bar, so it can enter from that side.
|
|
49
|
+
* @cssstate from-start - The panel opened in place of one earlier in the bar.
|
|
41
50
|
* @cssstate narrow - The page is narrower than `band-below`, so the panel is shown as a band whatever its variant.
|
|
42
51
|
* @cssstate open - The panel is open, and the trigger is shown as current.
|
|
52
|
+
* @cssstate to-end - The panel closed because one later in the bar opened, so it can leave toward it.
|
|
53
|
+
* @cssstate to-start - The panel closed because one earlier in the bar opened.
|
|
43
54
|
*/
|
|
44
55
|
export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
45
56
|
/**
|
|
@@ -119,6 +130,11 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
|
119
130
|
private get slotted();
|
|
120
131
|
/** Whatever the consumer slotted, or the button rendered in its place. */
|
|
121
132
|
private get trigger();
|
|
133
|
+
/**
|
|
134
|
+
* @internal The control a `Navigation`'s arrow keys move to: the trigger
|
|
135
|
+
* the consumer slotted, or the button drawn in its place.
|
|
136
|
+
*/
|
|
137
|
+
get navigationControl(): HTMLElement;
|
|
122
138
|
/** Shuts it and puts the reader back where they were. */
|
|
123
139
|
private close;
|
|
124
140
|
/**
|
|
@@ -241,6 +257,11 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
|
241
257
|
* overruled.
|
|
242
258
|
*/
|
|
243
259
|
protected willUpdate(changed: PropertyValues): void;
|
|
260
|
+
/**
|
|
261
|
+
* Says which way the reader moved when one panel took over from another.
|
|
262
|
+
* Nothing clears all four, for a panel opened on its own.
|
|
263
|
+
*/
|
|
264
|
+
private motion;
|
|
244
265
|
protected updated(changed: PropertyValues): void;
|
|
245
266
|
/**
|
|
246
267
|
* The control that opens it, behind a seam the styled tier can move.
|
|
@@ -117,6 +117,9 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
117
117
|
get trigger() {
|
|
118
118
|
return anchorElement(this.renderRoot?.querySelector('slot[name="trigger"]'), this.partNamed('trigger') ?? this);
|
|
119
119
|
}
|
|
120
|
+
get navigationControl() {
|
|
121
|
+
return this.trigger;
|
|
122
|
+
}
|
|
120
123
|
close() {
|
|
121
124
|
if (!this.requestOpen(false)) {
|
|
122
125
|
return;
|
|
@@ -184,8 +187,13 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
184
187
|
return;
|
|
185
188
|
}
|
|
186
189
|
if (this.open) {
|
|
187
|
-
|
|
188
|
-
|
|
190
|
+
const previous = showing && showing !== this ? showing : undefined;
|
|
191
|
+
const forward = previous !== undefined &&
|
|
192
|
+
(previous.compareDocumentPosition(this) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
|
|
193
|
+
this.motion(previous ? (forward ? 'from-end' : 'from-start') : undefined);
|
|
194
|
+
if (previous) {
|
|
195
|
+
previous.motion(forward ? 'to-end' : 'to-start');
|
|
196
|
+
previous.requestOpen(false);
|
|
189
197
|
}
|
|
190
198
|
showing = this;
|
|
191
199
|
}
|
|
@@ -193,6 +201,12 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
193
201
|
showing = undefined;
|
|
194
202
|
}
|
|
195
203
|
}
|
|
204
|
+
motion(to) {
|
|
205
|
+
this.toggleState('from-end', to === 'from-end');
|
|
206
|
+
this.toggleState('from-start', to === 'from-start');
|
|
207
|
+
this.toggleState('to-end', to === 'to-end');
|
|
208
|
+
this.toggleState('to-start', to === 'to-start');
|
|
209
|
+
}
|
|
196
210
|
updated(changed) {
|
|
197
211
|
super.updated?.(changed);
|
|
198
212
|
if (changed.has('bandBelow')) {
|