@fusion.dev/helix-headless 0.144.0 → 0.146.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 +15195 -4240
- package/dist/accordion/item/accordion-item.d.ts +62 -12
- package/dist/accordion/item/accordion-item.js +41 -10
- package/dist/accordion/root/accordion-root.d.ts +14 -5
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +24 -3
- package/dist/announcement/root/announcement-root.js +39 -2
- package/dist/app-header/root/app-header-root.d.ts +12 -0
- package/dist/app-header/root/app-header-root.js +13 -1
- package/dist/app-header/sectioning.d.ts +9 -0
- package/dist/app-header/sectioning.js +27 -0
- package/dist/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/badge/root/badge-root.d.ts +3 -1
- package/dist/badge/root/badge-root.js +2 -2
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +52 -15
- package/dist/bar-chart/stack.d.ts +15 -0
- package/dist/bar-chart/stack.js +19 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +57 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +73 -3
- package/dist/button/root/button-root.d.ts +26 -0
- package/dist/button/root/button-root.js +38 -18
- package/dist/button-group/root/button-group-root.d.ts +2 -1
- package/dist/button-group/root/button-group-root.js +5 -1
- package/dist/canvas/node/canvas-node.d.ts +4 -3
- package/dist/canvas/node/canvas-node.js +3 -2
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +123 -42
- package/dist/card/root/card-root.d.ts +24 -3
- package/dist/card/root/card-root.js +20 -8
- package/dist/carousel/root/carousel-root.d.ts +133 -4
- package/dist/carousel/root/carousel-root.js +174 -24
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- 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 +27 -10
- package/dist/chat/naming.d.ts +26 -0
- package/dist/chat/naming.js +14 -0
- package/dist/chat/root/chat-root.d.ts +58 -0
- package/dist/chat/root/chat-root.js +43 -3
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +14 -1
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
- package/dist/checkbox-group/select-all.d.ts +27 -0
- package/dist/checkbox-group/select-all.js +12 -0
- package/dist/code-block/highlight.d.ts +15 -0
- package/dist/code-block/highlight.js +4 -0
- package/dist/code-block/root/code-block-root.d.ts +57 -2
- package/dist/code-block/root/code-block-root.js +63 -8
- package/dist/color-input/root/color-input-root.d.ts +3 -0
- package/dist/color-input/root/color-input-root.js +6 -3
- package/dist/color-picker/root/color-picker-root.d.ts +33 -4
- package/dist/color-picker/root/color-picker-root.js +80 -21
- package/dist/color-picker/swatches.d.ts +12 -0
- package/dist/color-picker/swatches.js +26 -0
- package/dist/combobox/root/combobox-root.d.ts +43 -0
- package/dist/combobox/root/combobox-root.js +79 -15
- package/dist/command/root/command-root.d.ts +16 -1
- package/dist/command/root/command-root.js +22 -4
- package/dist/copy-button/root/copy-button-root.d.ts +26 -1
- package/dist/copy-button/root/copy-button-root.js +12 -5
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +24 -0
- package/dist/data-table/keys.js +24 -0
- package/dist/data-table/root/data-table-root.d.ts +170 -13
- package/dist/data-table/root/data-table-root.js +294 -52
- package/dist/data-table/tree.d.ts +55 -0
- package/dist/data-table/tree.js +54 -0
- package/dist/date-input/root/date-input-root.d.ts +3 -1
- package/dist/date-input/root/date-input-root.js +18 -7
- package/dist/date-picker/root/date-picker-root.js +12 -6
- 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.js +15 -1
- package/dist/dialog/root/dialog-root.d.ts +8 -2
- package/dist/dialog/root/dialog-root.js +16 -1
- package/dist/divider/root/divider-root.d.ts +3 -0
- package/dist/divider/root/divider-root.js +2 -1
- package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
- package/dist/donut-chart/root/donut-chart-root.js +48 -1
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +59 -0
- package/dist/drawer/root/drawer-root.js +63 -4
- 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 +29 -0
- package/dist/drilldown/root/drilldown-root.js +28 -5
- package/dist/element-events.generated.js +83 -12
- package/dist/empty/root/empty-root.d.ts +3 -1
- package/dist/empty/root/empty-root.js +3 -2
- package/dist/file-input/root/file-input-root.d.ts +69 -6
- package/dist/file-input/root/file-input-root.js +82 -19
- package/dist/file-input/screen.d.ts +2 -1
- package/dist/filter-input/menu/filter-menu.d.ts +5 -0
- package/dist/filter-input/menu/filter-menu.js +16 -4
- package/dist/filter-input/root/filter-input-root.d.ts +30 -6
- package/dist/filter-input/root/filter-input-root.js +1 -1
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/root/format-date-root.d.ts +9 -16
- package/dist/format-date/root/format-date-root.js +10 -27
- package/dist/heatmap/root/heatmap-root.d.ts +24 -13
- package/dist/heatmap/root/heatmap-root.js +34 -12
- package/dist/icon/root/icon-root.d.ts +12 -1
- package/dist/icon/root/icon-root.js +21 -10
- package/dist/icon/settle.d.ts +7 -0
- package/dist/icon/settle.js +10 -0
- package/dist/icon-button/root/icon-button-root.d.ts +2 -0
- package/dist/image/root/image-root.d.ts +5 -1
- package/dist/image/root/image-root.js +10 -2
- package/dist/input/root/input-root.d.ts +13 -3
- package/dist/input/root/input-root.js +12 -3
- package/dist/kbd/root/kbd-root.d.ts +35 -1
- package/dist/kbd/root/kbd-root.js +23 -4
- package/dist/legend/root/legend-root.d.ts +55 -8
- package/dist/legend/root/legend-root.js +55 -13
- package/dist/lightbox/root/lightbox-root.d.ts +49 -6
- package/dist/lightbox/root/lightbox-root.js +86 -19
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +22 -0
- package/dist/lightbox/zoom.js +16 -0
- package/dist/line-chart/root/line-chart-root.d.ts +22 -1
- package/dist/line-chart/root/line-chart-root.js +21 -1
- package/dist/list/item/list-item.d.ts +70 -1
- package/dist/list/item/list-item.js +77 -6
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +155 -9
- package/dist/list/root/list-root.js +246 -4
- package/dist/list/selection.d.ts +49 -0
- package/dist/list/selection.js +30 -0
- package/dist/listbox/root/listbox-root.d.ts +37 -1
- package/dist/listbox/root/listbox-root.js +49 -4
- package/dist/loader/busy.d.ts +10 -0
- package/dist/loader/busy.js +11 -0
- package/dist/loader/root/loader-root.d.ts +9 -2
- package/dist/loader/root/loader-root.js +23 -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 +62 -0
- package/dist/megamenu/root/megamenu-root.js +90 -5
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +87 -11
- package/dist/menu/item/menu-item.js +78 -22
- package/dist/menu/root/menu-root.d.ts +39 -1
- package/dist/menu/root/menu-root.js +65 -8
- 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 +20 -1
- package/dist/meter/root/meter-root.js +11 -15
- package/dist/navigation/root/navigation-root.d.ts +18 -2
- package/dist/navigation/root/navigation-root.js +29 -3
- package/dist/notifications/root/notifications-root.d.ts +25 -0
- package/dist/notifications/root/notifications-root.js +33 -5
- package/dist/number-input/root/number-input-root.d.ts +17 -8
- package/dist/number-input/root/number-input-root.js +2 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +161 -32
- package/dist/object-inspector/root/object-inspector-root.js +264 -123
- package/dist/object-inspector/rows.d.ts +75 -0
- package/dist/object-inspector/rows.js +119 -0
- package/dist/option/root/option-root.d.ts +5 -3
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +86 -3
- package/dist/outline/root/outline-root.js +95 -12
- package/dist/pagination/size/pagination-size.d.ts +12 -2
- package/dist/pagination/size/pagination-size.js +20 -5
- package/dist/pin-input/code.d.ts +10 -0
- package/dist/pin-input/code.js +13 -0
- package/dist/pin-input/root/pin-input-root.d.ts +25 -1
- package/dist/pin-input/root/pin-input-root.js +10 -11
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +41 -0
- package/dist/popover/root/popover-root.d.ts +57 -7
- package/dist/popover/root/popover-root.js +58 -3
- package/dist/progress/root/progress-root.d.ts +20 -0
- package/dist/progress/root/progress-root.js +15 -15
- package/dist/qr-code/export.d.ts +26 -1
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/root/qr-code-root.d.ts +19 -5
- package/dist/qr-code/root/qr-code-root.js +58 -9
- package/dist/quote/marks.d.ts +8 -0
- package/dist/quote/marks.js +5 -0
- package/dist/quote/root/quote-root.d.ts +14 -2
- package/dist/quote/root/quote-root.js +23 -1
- package/dist/radio/group/radio-group.d.ts +4 -10
- package/dist/radio/group/radio-group.js +5 -10
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +6 -1
- package/dist/rating/root/rating-root.d.ts +10 -5
- package/dist/rating/root/rating-root.js +32 -8
- package/dist/rating/steps.d.ts +7 -0
- package/dist/rating/steps.js +9 -0
- package/dist/scatter-chart/fit.d.ts +15 -0
- package/dist/scatter-chart/fit.js +35 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
- package/dist/scroll-area/root/scroll-area-root.d.ts +84 -0
- package/dist/scroll-area/root/scroll-area-root.js +106 -7
- package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
- package/dist/scroll-area/scrollbar-controller.js +172 -0
- package/dist/scroll-area/scrollbar.d.ts +92 -0
- package/dist/scroll-area/scrollbar.js +33 -0
- package/dist/select/root/select-root.d.ts +15 -0
- package/dist/select/root/select-root.js +18 -6
- package/dist/skeleton/root/skeleton-root.d.ts +3 -0
- package/dist/skeleton/root/skeleton-root.js +4 -2
- package/dist/skip-link/root/skip-link-root.js +2 -2
- package/dist/slider/root/slider-root.d.ts +41 -4
- package/dist/slider/root/slider-root.js +23 -3
- package/dist/sparkline/readings.d.ts +18 -0
- package/dist/sparkline/readings.js +19 -0
- package/dist/sparkline/root/sparkline-root.d.ts +78 -7
- package/dist/sparkline/root/sparkline-root.js +118 -23
- package/dist/speed-dial/root/speed-dial-root.js +2 -2
- package/dist/splitter/root/splitter-root.d.ts +20 -12
- package/dist/splitter/root/splitter-root.js +226 -203
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/stat/root/stat-root.d.ts +14 -5
- package/dist/stat/root/stat-root.js +21 -5
- package/dist/steps/reach.d.ts +20 -0
- package/dist/steps/reach.js +15 -0
- package/dist/steps/root/steps-root.d.ts +76 -0
- package/dist/steps/root/steps-root.js +93 -1
- package/dist/steps/step/step.d.ts +45 -2
- package/dist/steps/step/step.js +33 -6
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +11 -10
- package/dist/table/column/table-column.js +8 -19
- package/dist/table/root/table-root.d.ts +126 -4
- package/dist/table/root/table-root.js +156 -6
- 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 +22 -5
- package/dist/tabs/panel/tab-panel.js +34 -6
- package/dist/tabs/root/tabs-root.d.ts +37 -1
- package/dist/tabs/root/tabs-root.js +22 -4
- package/dist/tabs/tab/tab.d.ts +41 -4
- package/dist/tabs/tab/tab.js +49 -3
- package/dist/tag/group/tag-group.d.ts +31 -4
- package/dist/tag/group/tag-group.js +46 -7
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +28 -1
- package/dist/textarea/root/textarea-root.js +40 -1
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +16 -8
- package/dist/time-picker/root/time-picker-root.d.ts +18 -4
- package/dist/time-picker/root/time-picker-root.js +7 -10
- package/dist/time-picker/wheel-name.d.ts +9 -0
- package/dist/time-picker/wheel-name.js +15 -0
- 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/item/toast-item.d.ts +24 -18
- package/dist/toast/item/toast-item.js +36 -40
- package/dist/toast/root/toast-root.d.ts +6 -0
- package/dist/toast/root/toast-root.js +16 -1
- package/dist/toggle/group/toggle-group.d.ts +24 -3
- package/dist/toggle/group/toggle-group.js +34 -5
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- package/dist/tooltip/root/tooltip-root.d.ts +13 -2
- package/dist/tooltip/root/tooltip-root.js +9 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +30 -2
- package/dist/tour/root/tour-root.js +34 -8
- package/dist/tree/item/tree-item.d.ts +61 -4
- package/dist/tree/item/tree-item.js +92 -20
- package/dist/tree/root/tree-root.d.ts +58 -0
- package/dist/tree/root/tree-root.js +80 -16
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +13 -0
- package/dist/trend/root/trend-root.d.ts +43 -18
- package/dist/trend/root/trend-root.js +31 -6
- package/dist/video/media-events.d.ts +44 -0
- package/dist/video/media-events.js +35 -0
- package/dist/video/root/video-root.d.ts +117 -18
- package/dist/video/root/video-root.js +93 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +77 -3
- 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 +22 -0
- package/dist/virtual-list/fill.js +23 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/plan.d.ts +49 -0
- package/dist/virtual-list/plan.js +16 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +259 -26
- package/dist/virtual-list/root/virtual-list-root.js +333 -49
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +8113 -1394
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +1678 -353
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/listbox/range.d.ts +0 -17
- package/dist/listbox/range.js +0 -5
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -21,7 +21,15 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
21
21
|
*
|
|
22
22
|
* Pressing a branch, or Enter or Space on it, opens or closes it. A branch with
|
|
23
23
|
* a `value` is chosen as well and sends `helix-select`, unless the tree has
|
|
24
|
-
* `nesting="heading"`, where a branch names the list under it
|
|
24
|
+
* `nesting="heading"`, where a branch names the list under it, or
|
|
25
|
+
* `selection-mode="leaf"`, where only the items at the ends are chosen.
|
|
26
|
+
*
|
|
27
|
+
* A `disabled` item is reached by the arrow keys and announced as unavailable,
|
|
28
|
+
* and a press, Enter or Space on it does nothing.
|
|
29
|
+
*
|
|
30
|
+
* A `lazy` item is a branch whose children you load when it opens: opening it
|
|
31
|
+
* sends `helix-load`, the row says it is busy, and the children you add appear
|
|
32
|
+
* in it. Remove `lazy` once they are in.
|
|
25
33
|
*
|
|
26
34
|
* @since 0.1.0
|
|
27
35
|
* @status stable
|
|
@@ -29,15 +37,20 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
29
37
|
* @documentation https://fusion.dev/helix/components/tree
|
|
30
38
|
*
|
|
31
39
|
* @slot - The item's label.
|
|
40
|
+
* @slot chevron - Replaces the expand and collapse mark of a branch, such as with your own icon.
|
|
32
41
|
* @slot children - Nested items, which make this a branch.
|
|
33
42
|
* @slot end - Content after the label, at the far side of the row, such as a count or a state.
|
|
34
43
|
* @slot start - Content before the label and after the chevron, such as a mark for the item.
|
|
35
44
|
*
|
|
36
45
|
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before a branch closes, and cancelable.
|
|
37
46
|
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before a branch opens, and cancelable.
|
|
47
|
+
* @event {HelixLoadEvent} helix-load - Fired when a `lazy` item opens, so you can load its children.
|
|
38
48
|
* @event {HelixSelectEvent} helix-select - Fired when the item is chosen, and cancelable. Canceling it changes nothing.
|
|
39
49
|
* @event {ToggleEvent} toggle - Sent when the branch opens or closes, with `newState` and `oldState`.
|
|
40
50
|
*
|
|
51
|
+
* @csspart checkbox - The check mark's box, in a tree with `selection-mode="multiple"`.
|
|
52
|
+
* @csspart checkbox-checked - The check mark's box while the item is checked.
|
|
53
|
+
* @csspart checkbox-mixed - The check mark's box while some of a branch's items are checked.
|
|
41
54
|
* @csspart group - The container for nested items.
|
|
42
55
|
* @csspart item - The node, and the focus target unless `href` moves it to the row.
|
|
43
56
|
* @csspart label - The label text.
|
|
@@ -46,14 +59,33 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
46
59
|
*
|
|
47
60
|
* @cssproperty --tree-level - How deep this row sits, counting from one as `aria-level` does, for the indent.
|
|
48
61
|
*
|
|
62
|
+
* @cssstate checked - While it is checked, in a tree with `selection-mode="multiple"`.
|
|
63
|
+
* @cssstate loading - While a `lazy` item is open and its children have not arrived.
|
|
64
|
+
* @cssstate mixed - While some of a branch's items are checked, in a tree with `selection-mode="multiple"`.
|
|
49
65
|
* @cssstate open - While its children are shown.
|
|
50
66
|
* @cssstate selected - While it is selected.
|
|
51
67
|
*/
|
|
52
68
|
export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
69
|
+
/**
|
|
70
|
+
* @internal Set by the tree: whether the item draws a check mark and is
|
|
71
|
+
* checked rather than selected, as under `selection-mode="multiple"`.
|
|
72
|
+
*/
|
|
73
|
+
checkable: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* @internal Set by the tree in `selection-mode="multiple"`: whether the item
|
|
76
|
+
* is checked, `mixed` for a branch some of whose items are.
|
|
77
|
+
*/
|
|
78
|
+
checked: boolean | 'mixed';
|
|
79
|
+
/**
|
|
80
|
+
* Whether the item cannot be chosen, opened or followed. The arrow keys still
|
|
81
|
+
* reach it, so a reader knows it is there.
|
|
82
|
+
*/
|
|
83
|
+
disabled: boolean;
|
|
53
84
|
/**
|
|
54
85
|
* @internal Set by the tree: whether a branch heads the list under it, as
|
|
55
|
-
* under `nesting="heading"
|
|
56
|
-
*
|
|
86
|
+
* under `nesting="heading"`, or is not chosen at all, as under
|
|
87
|
+
* `selection-mode="leaf"`. Such a branch only opens and closes when it is
|
|
88
|
+
* pressed.
|
|
57
89
|
*/
|
|
58
90
|
heads: boolean;
|
|
59
91
|
/**
|
|
@@ -64,6 +96,13 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
64
96
|
* current page on every item a consumer never asked to be one.
|
|
65
97
|
*/
|
|
66
98
|
href: string;
|
|
99
|
+
/**
|
|
100
|
+
* Whether the item is a branch whose children are loaded when it opens.
|
|
101
|
+
*
|
|
102
|
+
* Opening it sends `helix-load`. Add the children to its `children` slot,
|
|
103
|
+
* and remove `lazy` once they are in, as Web Awesome's tree item does.
|
|
104
|
+
*/
|
|
105
|
+
lazy: boolean;
|
|
67
106
|
/**
|
|
68
107
|
* The node's depth from the root. The tree counts it, so indentation needs no
|
|
69
108
|
* nested CSS.
|
|
@@ -151,7 +190,7 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
151
190
|
* row rather than the wrapper around it.
|
|
152
191
|
*/
|
|
153
192
|
focusItem(): void;
|
|
154
|
-
/** Selects this node and sends `helix-select`. */
|
|
193
|
+
/** Selects this node and sends `helix-select`. A disabled node sends nothing. */
|
|
155
194
|
select(): void;
|
|
156
195
|
/**
|
|
157
196
|
* Chooses this node, as a press or Enter does.
|
|
@@ -163,6 +202,13 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
163
202
|
* value and nothing listens for it.
|
|
164
203
|
*/
|
|
165
204
|
activate(): void;
|
|
205
|
+
/**
|
|
206
|
+
* Opens or closes a branch, unless the item is disabled.
|
|
207
|
+
*
|
|
208
|
+
* Every press and key that opens a branch comes through here, so `disabled`
|
|
209
|
+
* holds for all of them. A script can still set `open`.
|
|
210
|
+
*/
|
|
211
|
+
toggleOpen(): boolean;
|
|
166
212
|
/**
|
|
167
213
|
* Follows a link slotted into the name, if there is one.
|
|
168
214
|
*
|
|
@@ -184,8 +230,17 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
184
230
|
* its children.
|
|
185
231
|
*/
|
|
186
232
|
private follow;
|
|
233
|
+
/** A press on the check mark checks the item and leaves a branch as it is. */
|
|
234
|
+
private readonly handleCheckClick;
|
|
187
235
|
private readonly handleToggleClick;
|
|
188
236
|
private readonly handleRowClick;
|
|
237
|
+
/**
|
|
238
|
+
* The expand and collapse mark of a branch, as the `chevron` slot's
|
|
239
|
+
* fallback, so an icon of your own replaces it by being slotted.
|
|
240
|
+
*/
|
|
241
|
+
protected renderToggle(): TemplateResult;
|
|
242
|
+
/** The check mark, in a tree with `selection-mode="multiple"`. */
|
|
243
|
+
private renderCheckbox;
|
|
189
244
|
/** Everything inside the row, which is the same whichever element it is. */
|
|
190
245
|
private renderRow;
|
|
191
246
|
/**
|
|
@@ -204,6 +259,8 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
204
259
|
* a consumer's markup means. What stops is the write back.
|
|
205
260
|
*/
|
|
206
261
|
protected willUpdate(changed: PropertyValues): void;
|
|
262
|
+
/** Asks for a lazy branch's children when it opens. */
|
|
263
|
+
protected updated(changed: PropertyValues): void;
|
|
207
264
|
protected render(): TemplateResult;
|
|
208
265
|
}
|
|
209
266
|
declare global {
|
|
@@ -4,22 +4,31 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, HelixSelectEvent, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
8
|
-
import { caretDown } from '@fusion.dev/helix-icons';
|
|
7
|
+
import { customElement, HelixElement, HelixLoadEvent, HelixSelectEvent, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { caretDown, check, minus } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
12
|
let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerOpen(HelixElement) {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
|
+
this.checkable = false;
|
|
16
|
+
this.checked = false;
|
|
17
|
+
this.disabled = false;
|
|
15
18
|
this.heads = false;
|
|
16
19
|
this.href = '';
|
|
20
|
+
this.lazy = false;
|
|
17
21
|
this.rel = '';
|
|
18
22
|
this.selected = false;
|
|
19
23
|
this.target = '';
|
|
20
24
|
this.focusable = false;
|
|
21
25
|
this.value = '';
|
|
22
26
|
this.branch = false;
|
|
27
|
+
this.handleCheckClick = (event) => {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
event.stopPropagation();
|
|
30
|
+
this.select();
|
|
31
|
+
};
|
|
23
32
|
this.handleToggleClick = (event) => {
|
|
24
33
|
event.preventDefault();
|
|
25
34
|
event.stopPropagation();
|
|
@@ -27,7 +36,11 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
27
36
|
};
|
|
28
37
|
this.handleRowClick = (event) => {
|
|
29
38
|
const onLink = event.composedPath().some((node) => node instanceof HTMLAnchorElement);
|
|
30
|
-
if (this.
|
|
39
|
+
if (this.disabled) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (this.isBranch && this.href === '') {
|
|
31
44
|
if (!onLink) {
|
|
32
45
|
if (this.choosable) {
|
|
33
46
|
this.select();
|
|
@@ -51,10 +64,10 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
51
64
|
});
|
|
52
65
|
}
|
|
53
66
|
get choosable() {
|
|
54
|
-
return this.value !== '' && !this.heads;
|
|
67
|
+
return this.value !== '' && !this.heads && !this.checkable && !this.disabled;
|
|
55
68
|
}
|
|
56
69
|
get isBranch() {
|
|
57
|
-
return this.branch;
|
|
70
|
+
return this.branch || this.lazy;
|
|
58
71
|
}
|
|
59
72
|
focusItem() {
|
|
60
73
|
this.renderRoot
|
|
@@ -62,12 +75,21 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
62
75
|
?.focus({ preventScroll: true });
|
|
63
76
|
}
|
|
64
77
|
select() {
|
|
78
|
+
if (this.disabled) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
65
81
|
this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
|
|
66
82
|
}
|
|
67
83
|
activate() {
|
|
84
|
+
if (this.disabled) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
68
87
|
this.select();
|
|
69
88
|
this.follow();
|
|
70
89
|
}
|
|
90
|
+
toggleOpen() {
|
|
91
|
+
return this.disabled ? false : super.toggleOpen();
|
|
92
|
+
}
|
|
71
93
|
follow() {
|
|
72
94
|
const own = this.renderRoot?.querySelector('a[part="row"]');
|
|
73
95
|
if (own) {
|
|
@@ -85,18 +107,33 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
85
107
|
}
|
|
86
108
|
}
|
|
87
109
|
}
|
|
110
|
+
renderToggle() {
|
|
111
|
+
return html `<slot
|
|
112
|
+
name="chevron"
|
|
113
|
+
aria-hidden="true"
|
|
114
|
+
@click=${this.href === '' ? nothing : this.handleToggleClick}
|
|
115
|
+
><svg part="toggle" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
|
|
116
|
+
${unsafeSVG(caretDown.content)}
|
|
117
|
+
</svg></slot
|
|
118
|
+
>`;
|
|
119
|
+
}
|
|
120
|
+
renderCheckbox() {
|
|
121
|
+
if (!this.checkable) {
|
|
122
|
+
return nothing;
|
|
123
|
+
}
|
|
124
|
+
const mixed = this.checked === 'mixed';
|
|
125
|
+
const glyph = mixed ? minus : this.checked ? check : undefined;
|
|
126
|
+
return html `<span
|
|
127
|
+
part="checkbox${mixed ? ' checkbox-mixed' : this.checked ? ' checkbox-checked' : ''}"
|
|
128
|
+
aria-hidden="true"
|
|
129
|
+
@click=${this.handleCheckClick}
|
|
130
|
+
>${glyph
|
|
131
|
+
? html `<svg fill="currentColor" viewBox=${glyph.viewBox}>${unsafeSVG(glyph.content)}</svg>`
|
|
132
|
+
: nothing}</span
|
|
133
|
+
>`;
|
|
134
|
+
}
|
|
88
135
|
renderRow() {
|
|
89
|
-
return html `${this.
|
|
90
|
-
? html `<svg
|
|
91
|
-
part="toggle"
|
|
92
|
-
fill="currentColor"
|
|
93
|
-
viewBox=${caretDown.viewBox}
|
|
94
|
-
aria-hidden="true"
|
|
95
|
-
@click=${this.href === '' ? nothing : this.handleToggleClick}
|
|
96
|
-
>
|
|
97
|
-
${unsafeSVG(caretDown.content)}
|
|
98
|
-
</svg>`
|
|
99
|
-
: nothing}
|
|
136
|
+
return html `${this.isBranch ? this.renderToggle() : nothing}${this.renderCheckbox()}
|
|
100
137
|
<slot name="start"></slot>
|
|
101
138
|
<span part="label"><slot></slot></span>
|
|
102
139
|
<slot name="end"></slot>`;
|
|
@@ -104,21 +141,41 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
104
141
|
willUpdate(changed) {
|
|
105
142
|
super.willUpdate(changed);
|
|
106
143
|
this.toggleState('selected', this.selected);
|
|
144
|
+
this.toggleState('checked', this.checkable && this.checked === true);
|
|
145
|
+
this.toggleState('mixed', this.checkable && this.checked === 'mixed');
|
|
146
|
+
this.toggleState('loading', this.open && this.lazy);
|
|
107
147
|
if (this.childrenKnown) {
|
|
108
148
|
this.branch = this.knownChildren.some((child) => child.slot === 'children');
|
|
109
149
|
}
|
|
110
150
|
}
|
|
151
|
+
updated(changed) {
|
|
152
|
+
super.updated(changed);
|
|
153
|
+
if (changed.has('open') && this.open && this.lazy) {
|
|
154
|
+
this.dispatchEvent(new HelixLoadEvent());
|
|
155
|
+
}
|
|
156
|
+
}
|
|
111
157
|
render() {
|
|
112
158
|
const linked = this.href !== '';
|
|
113
159
|
const level = this.level ?? 1;
|
|
114
160
|
const depth = this.level ?? nothing;
|
|
115
|
-
const expanded = this.
|
|
161
|
+
const expanded = this.isBranch ? (this.open ? 'true' : 'false') : nothing;
|
|
162
|
+
const chosen = this.checkable ? undefined : this.selected ? 'true' : 'false';
|
|
163
|
+
const checked = this.checkable
|
|
164
|
+
? this.checked === 'mixed'
|
|
165
|
+
? 'mixed'
|
|
166
|
+
: String(this.checked)
|
|
167
|
+
: undefined;
|
|
168
|
+
const busy = this.open && this.lazy ? 'true' : nothing;
|
|
169
|
+
const off = this.disabled ? 'true' : nothing;
|
|
116
170
|
const tabIndex = this.focusable || !this.childrenKnown ? '0' : '-1';
|
|
117
171
|
return html `<div
|
|
118
172
|
part="item"
|
|
119
173
|
role=${linked ? 'none' : 'treeitem'}
|
|
120
174
|
aria-expanded=${linked ? nothing : expanded}
|
|
121
|
-
aria-selected=${linked ? nothing :
|
|
175
|
+
aria-selected=${linked ? nothing : (chosen ?? nothing)}
|
|
176
|
+
aria-checked=${linked ? nothing : (checked ?? nothing)}
|
|
177
|
+
aria-disabled=${linked ? nothing : off}
|
|
178
|
+
aria-busy=${linked ? nothing : busy}
|
|
122
179
|
aria-level=${linked ? nothing : depth}
|
|
123
180
|
tabindex=${linked ? nothing : tabIndex}
|
|
124
181
|
>
|
|
@@ -126,11 +183,14 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
126
183
|
? html `<a
|
|
127
184
|
part="row"
|
|
128
185
|
role="treeitem"
|
|
129
|
-
href=${this.href}
|
|
186
|
+
href=${this.disabled ? nothing : this.href}
|
|
130
187
|
target=${this.target || nothing}
|
|
131
188
|
rel=${this.rel || nothing}
|
|
132
189
|
aria-expanded=${expanded}
|
|
133
|
-
aria-selected=${
|
|
190
|
+
aria-selected=${chosen ?? nothing}
|
|
191
|
+
aria-checked=${checked ?? nothing}
|
|
192
|
+
aria-disabled=${off}
|
|
193
|
+
aria-busy=${busy}
|
|
134
194
|
aria-level=${depth}
|
|
135
195
|
tabindex=${tabIndex}
|
|
136
196
|
style="--tree-level: ${level}"
|
|
@@ -152,12 +212,24 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
152
212
|
</div>`;
|
|
153
213
|
}
|
|
154
214
|
};
|
|
215
|
+
__decorate([
|
|
216
|
+
property({ attribute: false })
|
|
217
|
+
], HelixHeadlessTreeItem.prototype, "checkable", void 0);
|
|
218
|
+
__decorate([
|
|
219
|
+
property({ attribute: false })
|
|
220
|
+
], HelixHeadlessTreeItem.prototype, "checked", void 0);
|
|
221
|
+
__decorate([
|
|
222
|
+
property({ reflect: true, type: Boolean })
|
|
223
|
+
], HelixHeadlessTreeItem.prototype, "disabled", void 0);
|
|
155
224
|
__decorate([
|
|
156
225
|
property({ attribute: false })
|
|
157
226
|
], HelixHeadlessTreeItem.prototype, "heads", void 0);
|
|
158
227
|
__decorate([
|
|
159
228
|
property()
|
|
160
229
|
], HelixHeadlessTreeItem.prototype, "href", void 0);
|
|
230
|
+
__decorate([
|
|
231
|
+
property({ reflect: true, type: Boolean })
|
|
232
|
+
], HelixHeadlessTreeItem.prototype, "lazy", void 0);
|
|
161
233
|
__decorate([
|
|
162
234
|
property({ attribute: false, type: Number })
|
|
163
235
|
], HelixHeadlessTreeItem.prototype, "level", void 0);
|
|
@@ -16,6 +16,26 @@ declare const HelixHeadlessTree_base: (new (...args: any[]) => import("@fusion.d
|
|
|
16
16
|
* Typing a letter moves to the next visible item whose name starts with it,
|
|
17
17
|
* and `*` opens every branch beside the focused item.
|
|
18
18
|
*
|
|
19
|
+
* `selection-mode="multiple"` draws a check mark on every row and lets a
|
|
20
|
+
* reader check many, as Web Awesome's and Ark UI's checkbox trees do. Checking
|
|
21
|
+
* a branch checks every item under it, and a branch some of whose items are
|
|
22
|
+
* checked is partly checked. Space or a press on the mark checks the focused
|
|
23
|
+
* row, and Enter or a press on a branch's row opens it. `active` then holds the
|
|
24
|
+
* checked values, comma separated, which `values` also gives as a list, and
|
|
25
|
+
* the tree says `aria-multiselectable`.
|
|
26
|
+
*
|
|
27
|
+
* `selection-mode="leaf"` chooses one item at a time and only the items at the
|
|
28
|
+
* ends: a press, Enter or Space on a branch opens or closes it and chooses
|
|
29
|
+
* nothing, as Web Awesome's `leaf` mode does.
|
|
30
|
+
*
|
|
31
|
+
* Keys: Up and Down Arrow move between the items a reader can see; Right
|
|
32
|
+
* Arrow opens a shut branch and then moves into it, and Left Arrow shuts an
|
|
33
|
+
* open one and then moves to its parent, the two swapping on a right-to-left
|
|
34
|
+
* page. Home and End go to the first and the last item, Enter and Space choose
|
|
35
|
+
* or open, and the tree's one tab stop stays on the item last reached. In a
|
|
36
|
+
* tree of check marks, Control+A (Command+A on an Apple keyboard) checks every
|
|
37
|
+
* item or clears them all, and Shift with Up or Down Arrow moves and checks.
|
|
38
|
+
*
|
|
19
39
|
* @since 0.1.0
|
|
20
40
|
* @status stable
|
|
21
41
|
* @category navigation
|
|
@@ -82,6 +102,21 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
82
102
|
* The resting state is the absence of the attribute, which is `peer`.
|
|
83
103
|
*/
|
|
84
104
|
nesting?: 'heading' | 'peer' | 'subordinate';
|
|
105
|
+
/**
|
|
106
|
+
* Whether a reader can check many items, or choose only the items at the
|
|
107
|
+
* ends. Unset, one item is chosen at a time, branches included.
|
|
108
|
+
*
|
|
109
|
+
* Optional, so a tree of one choice writes no attribute onto the host.
|
|
110
|
+
*/
|
|
111
|
+
selectionMode?: 'leaf' | 'multiple';
|
|
112
|
+
/**
|
|
113
|
+
* The checked values, as a list, under `selection-mode="multiple"`, and the
|
|
114
|
+
* chosen value alone otherwise. Writing it sets `active`.
|
|
115
|
+
*/
|
|
116
|
+
get values(): string[];
|
|
117
|
+
set values(next: string[]);
|
|
118
|
+
/** Whether many items can be checked. */
|
|
119
|
+
private get multiple();
|
|
85
120
|
private watcher;
|
|
86
121
|
/**
|
|
87
122
|
* Every item, in the order a reader moving down would meet them.
|
|
@@ -100,6 +135,20 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
100
135
|
/** Items a reader can actually reach: not inside a collapsed branch. */
|
|
101
136
|
private get visibleItems();
|
|
102
137
|
private readonly handleSelection;
|
|
138
|
+
/** Every value in the tree, in the order a reader meets the items. */
|
|
139
|
+
private get order();
|
|
140
|
+
/**
|
|
141
|
+
* Whether an item holds others, read from the tree as well as from the item.
|
|
142
|
+
*
|
|
143
|
+
* **An item hydrating what a server sent has not said it is a branch yet**:
|
|
144
|
+
* it learns that from its children on the render after, and nothing then
|
|
145
|
+
* asks the tree again. Read from its own render alone, a folder served with
|
|
146
|
+
* one of its files checked was counted a leaf and drawn unchecked rather
|
|
147
|
+
* than partly checked, once hydrated.
|
|
148
|
+
*/
|
|
149
|
+
private holds;
|
|
150
|
+
/** What the multiple selection reads of an item. */
|
|
151
|
+
private rowOf;
|
|
103
152
|
/**
|
|
104
153
|
* Pushes tree-owned state down: which item is selected, which holds the tab
|
|
105
154
|
* stop, and how deep each one sits.
|
|
@@ -117,6 +166,15 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
117
166
|
* Returns whether the press was one of those.
|
|
118
167
|
*/
|
|
119
168
|
private handleTyping;
|
|
169
|
+
/**
|
|
170
|
+
* The keys of a tree of check marks, as the tree pattern gives them:
|
|
171
|
+
* Control+A (Command+A on an Apple keyboard) checks every item, or clears
|
|
172
|
+
* them all where every one is checked, and Shift with Up or Down Arrow moves
|
|
173
|
+
* to the item before or after and checks or unchecks it.
|
|
174
|
+
*
|
|
175
|
+
* Returns whether the press was one of those.
|
|
176
|
+
*/
|
|
177
|
+
private handleMultiple;
|
|
120
178
|
private move;
|
|
121
179
|
private focusOn;
|
|
122
180
|
private readonly handleKeydown;
|
|
@@ -4,10 +4,11 @@ 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, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, slottedWords, Typeahead, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, closestInstance, commaList, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, slottedWords, Typeahead, treeArrow, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessTreeItem } from '../item/tree-item.js';
|
|
11
|
+
import { checkedState, pressRow } from '../selection.js';
|
|
11
12
|
const KEYS = new Set([
|
|
12
13
|
'ArrowDown',
|
|
13
14
|
'ArrowUp',
|
|
@@ -33,7 +34,9 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
if (!event.defaultPrevented) {
|
|
36
|
-
this.requestActive(
|
|
37
|
+
this.requestActive(this.multiple
|
|
38
|
+
? pressRow(this.rowOf(origin), this.values, this.order).join(',')
|
|
39
|
+
: event.detail.value);
|
|
37
40
|
}
|
|
38
41
|
this.syncItems();
|
|
39
42
|
};
|
|
@@ -42,6 +45,10 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
42
45
|
if (!current || !this.items.includes(current)) {
|
|
43
46
|
return;
|
|
44
47
|
}
|
|
48
|
+
if (this.multiple && this.handleMultiple(current, event)) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
45
52
|
if (this.handleTyping(current, event)) {
|
|
46
53
|
event.preventDefault();
|
|
47
54
|
return;
|
|
@@ -51,6 +58,11 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
51
58
|
}
|
|
52
59
|
this.typeahead.reset();
|
|
53
60
|
const along = inlineStep(this, event.key);
|
|
61
|
+
if (this.multiple && event.key === ' ') {
|
|
62
|
+
current.select();
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
54
66
|
if (event.key === 'ArrowDown') {
|
|
55
67
|
this.move(current, 1);
|
|
56
68
|
}
|
|
@@ -63,21 +75,16 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
63
75
|
else if (event.key === 'End') {
|
|
64
76
|
this.focusOn(this.visibleItems.at(-1));
|
|
65
77
|
}
|
|
66
|
-
else if (along
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
else if (along !== 0) {
|
|
79
|
+
const arrow = treeArrow({ branch: current.isBranch, disabled: current.disabled, open: current.open }, along);
|
|
80
|
+
if (arrow === 'open' || arrow === 'close') {
|
|
81
|
+
current.requestOpen(arrow === 'open');
|
|
69
82
|
this.syncItems();
|
|
70
83
|
}
|
|
71
|
-
else if (
|
|
84
|
+
else if (arrow === 'child') {
|
|
72
85
|
this.move(current, 1);
|
|
73
86
|
}
|
|
74
|
-
|
|
75
|
-
else if (along === -1) {
|
|
76
|
-
if (current.isBranch && current.open) {
|
|
77
|
-
current.requestOpen(false);
|
|
78
|
-
this.syncItems();
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
87
|
+
else if (arrow === 'parent') {
|
|
81
88
|
const parent = closestInstance(current.parentElement, HelixHeadlessTreeItem);
|
|
82
89
|
this.focusOn(parent instanceof HelixHeadlessTreeItem ? parent : undefined);
|
|
83
90
|
}
|
|
@@ -100,6 +107,15 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
100
107
|
this.syncItems();
|
|
101
108
|
};
|
|
102
109
|
}
|
|
110
|
+
get values() {
|
|
111
|
+
return this.multiple ? commaList(this.active) : this.active === '' ? [] : [this.active];
|
|
112
|
+
}
|
|
113
|
+
set values(next) {
|
|
114
|
+
this.active = next.join(',');
|
|
115
|
+
}
|
|
116
|
+
get multiple() {
|
|
117
|
+
return this.selectionMode === 'multiple';
|
|
118
|
+
}
|
|
103
119
|
get items() {
|
|
104
120
|
return [...this.querySelectorAll('*')].filter((node) => node instanceof HelixHeadlessTreeItem);
|
|
105
121
|
}
|
|
@@ -115,15 +131,37 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
115
131
|
return true;
|
|
116
132
|
});
|
|
117
133
|
}
|
|
134
|
+
get order() {
|
|
135
|
+
return this.items.map((item) => item.value).filter((value) => value !== '');
|
|
136
|
+
}
|
|
137
|
+
holds(item) {
|
|
138
|
+
return item.isBranch || this.items.some((other) => other !== item && item.contains(other));
|
|
139
|
+
}
|
|
140
|
+
rowOf(item) {
|
|
141
|
+
const branch = this.holds(item);
|
|
142
|
+
const leaves = branch
|
|
143
|
+
? this.items
|
|
144
|
+
.filter((other) => other !== item &&
|
|
145
|
+
item.contains(other) &&
|
|
146
|
+
!this.holds(other) &&
|
|
147
|
+
!other.disabled &&
|
|
148
|
+
other.value !== '')
|
|
149
|
+
.map((other) => other.value)
|
|
150
|
+
: [];
|
|
151
|
+
return { branch, disabled: item.disabled, leaves, value: item.value };
|
|
152
|
+
}
|
|
118
153
|
syncItems() {
|
|
119
154
|
const visible = this.visibleItems;
|
|
120
155
|
const chosen = this.resolveActive(visible);
|
|
121
156
|
const held = visible.find((item) => item.focusable) ??
|
|
122
157
|
this.visibleAncestor(this.items.find((item) => item.focusable));
|
|
123
158
|
const stop = held ?? chosen;
|
|
124
|
-
const heads = this.nesting === 'heading';
|
|
159
|
+
const heads = this.nesting === 'heading' || this.selectionMode === 'leaf';
|
|
160
|
+
const multiple = this.multiple;
|
|
161
|
+
const checked = new Set(this.values);
|
|
125
162
|
for (const item of this.items) {
|
|
126
|
-
const selected = item.value !== '' && item.value === this.active;
|
|
163
|
+
const selected = !multiple && item.value !== '' && item.value === this.active;
|
|
164
|
+
const state = multiple ? checkedState(this.rowOf(item), checked) : false;
|
|
127
165
|
const focusable = item === stop;
|
|
128
166
|
let level = 1;
|
|
129
167
|
let parent = item.parentElement;
|
|
@@ -135,6 +173,8 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
135
173
|
}
|
|
136
174
|
whenHydrated(item, () => {
|
|
137
175
|
item.selected = selected;
|
|
176
|
+
item.checkable = multiple;
|
|
177
|
+
item.checked = state;
|
|
138
178
|
item.focusable = focusable;
|
|
139
179
|
item.level = level;
|
|
140
180
|
item.heads = heads;
|
|
@@ -176,6 +216,26 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
176
216
|
}
|
|
177
217
|
return true;
|
|
178
218
|
}
|
|
219
|
+
handleMultiple(current, event) {
|
|
220
|
+
if ((event.ctrlKey || event.metaKey) && !event.altKey && event.key.toLowerCase() === 'a') {
|
|
221
|
+
const leaves = this.items
|
|
222
|
+
.filter((item) => !this.holds(item) && !item.disabled && item.value !== '')
|
|
223
|
+
.map((item) => item.value);
|
|
224
|
+
this.requestActive(pressRow({ branch: true, disabled: false, leaves, value: '' }, this.values, this.order).join(','));
|
|
225
|
+
this.syncItems();
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
if (event.shiftKey && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
|
|
229
|
+
const visible = this.visibleItems;
|
|
230
|
+
const next = visible[visible.indexOf(current) + (event.key === 'ArrowDown' ? 1 : -1)];
|
|
231
|
+
if (next) {
|
|
232
|
+
this.focusOn(next);
|
|
233
|
+
next.select();
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
179
239
|
move(from, delta) {
|
|
180
240
|
const visible = this.visibleItems;
|
|
181
241
|
const index = visible.indexOf(from);
|
|
@@ -214,7 +274,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
214
274
|
}
|
|
215
275
|
updated(changed) {
|
|
216
276
|
super.updated(changed);
|
|
217
|
-
if (changed.has('active') || changed.has('nesting')) {
|
|
277
|
+
if (changed.has('active') || changed.has('nesting') || changed.has('selectionMode')) {
|
|
218
278
|
this.syncItems();
|
|
219
279
|
}
|
|
220
280
|
}
|
|
@@ -223,6 +283,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
223
283
|
part="tree"
|
|
224
284
|
role="tree"
|
|
225
285
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
286
|
+
aria-multiselectable=${this.multiple ? 'true' : nothing}
|
|
226
287
|
aria-label=${this.label}
|
|
227
288
|
>
|
|
228
289
|
<slot
|
|
@@ -241,6 +302,9 @@ __decorate([
|
|
|
241
302
|
__decorate([
|
|
242
303
|
property({ reflect: true })
|
|
243
304
|
], HelixHeadlessTree.prototype, "nesting", void 0);
|
|
305
|
+
__decorate([
|
|
306
|
+
property({ attribute: 'selection-mode', reflect: true })
|
|
307
|
+
], HelixHeadlessTree.prototype, "selectionMode", void 0);
|
|
244
308
|
HelixHeadlessTree = __decorate([
|
|
245
309
|
customElement('helix-headless-tree')
|
|
246
310
|
], HelixHeadlessTree);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** What the multiple selection reads of a row. */
|
|
2
|
+
export interface CheckableRow {
|
|
3
|
+
/** Whether the row is a branch, holding rows of its own. */
|
|
4
|
+
branch: boolean;
|
|
5
|
+
/** Whether the row is out of play. Its value is never added or taken away. */
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
/** The values of the leaves under a branch, in order. Empty for a leaf. */
|
|
8
|
+
leaves: readonly string[];
|
|
9
|
+
/** The row's own value. */
|
|
10
|
+
value: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether a row is checked in a tree of check marks: a leaf by its value, and
|
|
14
|
+
* a branch by its leaves, `mixed` where some of them are.
|
|
15
|
+
*/
|
|
16
|
+
export declare const checkedState: (row: CheckableRow, chosen: ReadonlySet<string>) => boolean | 'mixed';
|
|
17
|
+
/**
|
|
18
|
+
* The checked values after a press on `row`, in `order`.
|
|
19
|
+
*
|
|
20
|
+
* A leaf comes in or out. A branch checks every leaf under it, or clears them
|
|
21
|
+
* all where every one is already checked, as Ark UI's and Web Awesome's
|
|
22
|
+
* checkbox trees do. A disabled row changes nothing.
|
|
23
|
+
*/
|
|
24
|
+
export declare const pressRow: (row: CheckableRow, chosen: readonly string[], order: readonly string[]) => string[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { toggleEvery } from '@fusion.dev/helix-core';
|
|
2
|
+
const valuesOf = (row) => row.branch && row.leaves.length > 0 ? [...row.leaves] : row.value === '' ? [] : [row.value];
|
|
3
|
+
export const checkedState = (row, chosen) => {
|
|
4
|
+
const values = valuesOf(row);
|
|
5
|
+
const count = values.filter((value) => chosen.has(value)).length;
|
|
6
|
+
if (count === 0) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return count === values.length ? true : 'mixed';
|
|
10
|
+
};
|
|
11
|
+
export const pressRow = (row, chosen, order) => {
|
|
12
|
+
return row.disabled ? [...chosen] : toggleEvery(chosen, valuesOf(row), order);
|
|
13
|
+
};
|