@fusion.dev/helix-headless 0.145.0 → 0.147.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 +12286 -4281
- package/dist/accordion/item/accordion-item.d.ts +51 -18
- package/dist/accordion/item/accordion-item.js +45 -13
- package/dist/accordion/root/accordion-root.d.ts +16 -7
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +16 -6
- package/dist/announcement/root/announcement-root.js +37 -7
- package/dist/app-header/root/app-header-root.d.ts +7 -2
- package/dist/app-header/root/app-header-root.js +9 -1
- package/dist/app-header/sectioning.d.ts +3 -1
- package/dist/app-header/sectioning.js +3 -2
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +11 -3
- package/dist/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/root/badge-root.d.ts +60 -7
- package/dist/badge/root/badge-root.js +89 -6
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +48 -20
- package/dist/bar-chart/stack.d.ts +25 -0
- package/dist/bar-chart/stack.js +27 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +51 -4
- package/dist/button/root/button-root.d.ts +50 -38
- package/dist/button/root/button-root.js +42 -53
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- 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.js +2 -2
- package/dist/card/root/card-root.d.ts +36 -4
- package/dist/card/root/card-root.js +29 -10
- package/dist/carousel/root/carousel-root.d.ts +43 -4
- package/dist/carousel/root/carousel-root.js +40 -12
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- package/dist/chat/message/chat-message.js +5 -4
- package/dist/chat/naming.d.ts +5 -1
- package/dist/chat/naming.js +4 -2
- package/dist/chat/root/chat-root.d.ts +40 -4
- package/dist/chat/root/chat-root.js +32 -6
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +18 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +14 -11
- package/dist/checkbox-group/select-all.d.ts +21 -0
- package/dist/checkbox-group/select-all.js +7 -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 +79 -10
- package/dist/code-block/root/code-block-root.js +74 -5
- package/dist/color-input/root/color-input-root.d.ts +14 -0
- package/dist/color-input/root/color-input-root.js +17 -7
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +53 -16
- package/dist/color-picker/root/color-picker-root.js +155 -46
- package/dist/color-picker/wheel.d.ts +17 -0
- package/dist/color-picker/wheel.js +6 -0
- package/dist/combobox/root/combobox-root.d.ts +56 -0
- package/dist/combobox/root/combobox-root.js +92 -15
- package/dist/command/root/command-root.d.ts +19 -2
- package/dist/command/root/command-root.js +24 -23
- package/dist/copy-button/root/copy-button-root.d.ts +21 -1
- package/dist/copy-button/root/copy-button-root.js +16 -4
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +6 -0
- package/dist/data-table/keys.js +14 -0
- package/dist/data-table/root/data-table-root.d.ts +27 -18
- package/dist/data-table/root/data-table-root.js +31 -57
- package/dist/data-table/tree.d.ts +16 -1
- package/dist/data-table/tree.js +2 -3
- package/dist/date-input/root/date-input-root.d.ts +11 -2
- package/dist/date-input/root/date-input-root.js +26 -12
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +33 -22
- package/dist/description-list/item/description-list-item.d.ts +18 -4
- package/dist/description-list/item/description-list-item.js +8 -4
- 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 +55 -1
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +75 -4
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +40 -5
- package/dist/drilldown/root/drilldown-root.d.ts +21 -3
- package/dist/drilldown/root/drilldown-root.js +22 -3
- package/dist/element-events.generated.js +35 -6
- package/dist/empty/root/empty-root.d.ts +34 -2
- package/dist/empty/root/empty-root.js +26 -4
- package/dist/file-input/root/file-input-root.d.ts +99 -8
- package/dist/file-input/root/file-input-root.js +120 -22
- package/dist/file-input/screen.d.ts +2 -1
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +10 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +11 -2
- package/dist/filter-input/menu/filter-menu.d.ts +2 -0
- package/dist/filter-input/menu/filter-menu.js +12 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -6
- package/dist/filter-input/root/filter-input-root.js +18 -28
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/options.d.ts +3 -4
- package/dist/format-date/options.js +2 -2
- package/dist/format-date/root/format-date-root.d.ts +27 -17
- package/dist/format-date/root/format-date-root.js +27 -48
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +83 -11
- package/dist/heatmap/root/heatmap-root.js +104 -12
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +25 -1
- package/dist/icon/root/icon-root.js +44 -12
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- 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 +14 -1
- package/dist/image/root/image-root.js +7 -2
- package/dist/input/root/input-root.d.ts +34 -3
- package/dist/input/root/input-root.js +17 -4
- package/dist/kbd/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +52 -1
- package/dist/kbd/root/kbd-root.js +40 -47
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +77 -12
- package/dist/legend/root/legend-root.js +71 -17
- package/dist/lightbox/root/lightbox-root.d.ts +98 -10
- package/dist/lightbox/root/lightbox-root.js +153 -18
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +24 -0
- package/dist/lightbox/zoom.js +18 -0
- package/dist/line-chart/root/line-chart-root.d.ts +38 -1
- package/dist/line-chart/root/line-chart-root.js +31 -3
- package/dist/list/item/list-item.d.ts +2 -0
- package/dist/list/item/list-item.js +11 -2
- package/dist/list/root/list-root.d.ts +70 -13
- package/dist/list/root/list-root.js +91 -13
- package/dist/list/selection.d.ts +54 -7
- package/dist/list/selection.js +32 -7
- package/dist/listbox/root/listbox-root.d.ts +44 -4
- package/dist/listbox/root/listbox-root.js +72 -34
- 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/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +80 -15
- package/dist/megamenu/root/megamenu-root.js +76 -19
- package/dist/menu/item/menu-item.d.ts +51 -2
- package/dist/menu/item/menu-item.js +50 -26
- package/dist/menu/root/menu-root.d.ts +17 -0
- package/dist/menu/root/menu-root.js +2 -2
- package/dist/meter/root/meter-root.d.ts +62 -1
- package/dist/meter/root/meter-root.js +38 -16
- package/dist/navigation/root/navigation-root.d.ts +2 -1
- package/dist/navigation/root/navigation-root.js +2 -2
- package/dist/notifications/root/notifications-root.d.ts +20 -4
- package/dist/notifications/root/notifications-root.js +30 -8
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +34 -9
- package/dist/number-input/root/number-input-root.js +31 -25
- package/dist/object-inspector/root/object-inspector-root.d.ts +88 -33
- package/dist/object-inspector/root/object-inspector-root.js +134 -92
- package/dist/object-inspector/rows.d.ts +18 -0
- package/dist/object-inspector/rows.js +33 -0
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/root/option-root.d.ts +5 -3
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +30 -0
- package/dist/outline/root/outline-root.js +17 -13
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +37 -0
- package/dist/pin-input/code.js +25 -0
- package/dist/pin-input/root/pin-input-root.d.ts +116 -115
- package/dist/pin-input/root/pin-input-root.js +163 -155
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +34 -0
- package/dist/popover/root/popover-root.d.ts +64 -8
- package/dist/popover/root/popover-root.js +67 -4
- package/dist/progress/root/progress-root.d.ts +47 -0
- package/dist/progress/root/progress-root.js +34 -16
- package/dist/qr-code/export.d.ts +45 -1
- package/dist/qr-code/export.js +28 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +36 -11
- package/dist/qr-code/root/qr-code-root.js +58 -11
- 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 +15 -0
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +7 -2
- package/dist/rating/root/rating-root.d.ts +30 -12
- package/dist/rating/root/rating-root.js +27 -27
- 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 +51 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +64 -24
- package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
- package/dist/scroll-area/root/scroll-area-root.js +57 -173
- 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 +27 -8
- package/dist/scroll-area/scrollbar.js +10 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +71 -0
- package/dist/select/root/select-root.js +78 -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 +59 -5
- package/dist/slider/root/slider-root.js +45 -3
- package/dist/sparkline/readings.d.ts +36 -0
- package/dist/sparkline/readings.js +36 -0
- package/dist/sparkline/root/sparkline-root.d.ts +121 -7
- package/dist/sparkline/root/sparkline-root.js +160 -26
- package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
- package/dist/speed-dial/item/speed-dial-item.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
- package/dist/speed-dial/root/speed-dial-root.js +11 -3
- package/dist/splitter/root/splitter-root.d.ts +10 -12
- package/dist/splitter/root/splitter-root.js +211 -204
- 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 +5 -0
- package/dist/steps/reach.js +3 -0
- package/dist/steps/root/steps-root.d.ts +56 -3
- package/dist/steps/root/steps-root.js +50 -6
- package/dist/steps/step/step.d.ts +8 -0
- package/dist/steps/step/step.js +8 -3
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +6 -10
- package/dist/table/column/table-column.js +8 -20
- package/dist/table/root/table-root.d.ts +31 -10
- package/dist/table/root/table-root.js +14 -18
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- package/dist/tabs/panel/tab-panel.d.ts +16 -3
- package/dist/tabs/panel/tab-panel.js +34 -5
- package/dist/tabs/root/tabs-root.d.ts +17 -3
- package/dist/tabs/root/tabs-root.js +1 -1
- package/dist/tabs/tab/tab.d.ts +5 -0
- package/dist/tabs/tab/tab.js +5 -2
- package/dist/tag/group/tag-group.d.ts +44 -5
- package/dist/tag/group/tag-group.js +60 -9
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +41 -2
- package/dist/textarea/root/textarea-root.js +39 -1
- package/dist/time-input/root/time-input-root.d.ts +10 -2
- package/dist/time-input/root/time-input-root.js +24 -13
- package/dist/time-picker/root/time-picker-root.d.ts +28 -17
- package/dist/time-picker/root/time-picker-root.js +18 -29
- 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.js +2 -2
- package/dist/toast/item/toast-item.d.ts +16 -3
- package/dist/toast/item/toast-item.js +22 -6
- package/dist/toast/root/toast-root.d.ts +34 -4
- package/dist/toast/root/toast-root.js +74 -13
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +52 -7
- package/dist/toggle/group/toggle-group.js +58 -44
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +21 -5
- package/dist/toolbar/root/toolbar-root.js +52 -8
- package/dist/tooltip/root/tooltip-root.d.ts +20 -3
- package/dist/tooltip/root/tooltip-root.js +18 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +45 -2
- package/dist/tour/root/tour-root.js +53 -8
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/item/tree-item.d.ts +7 -3
- package/dist/tree/item/tree-item.js +3 -0
- package/dist/tree/root/tree-root.d.ts +24 -3
- package/dist/tree/root/tree-root.js +32 -13
- package/dist/tree/selection.js +2 -15
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +83 -19
- package/dist/trend/root/trend-root.js +59 -8
- package/dist/video/media-events.d.ts +13 -18
- package/dist/video/media-events.js +1 -5
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +23 -6
- package/dist/video/root/video-root.js +19 -10
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +17 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -8
- package/dist/virtual-list/fill.js +10 -17
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +65 -0
- package/dist/virtual-list/plan.js +27 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +136 -13
- package/dist/virtual-list/root/virtual-list-root.js +218 -51
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +7441 -1458
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1501 -326
- package/dist/chat/relative-clock.d.ts +0 -39
- package/dist/chat/relative-clock.js +0 -31
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -5,14 +5,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessObjectInspector_1;
|
|
8
|
-
import { AriaForwardController, CopyController, countLabel, customElement, drawStatus, elementById, fillTemplate, formatNumbers, HelixActivateEvent, HelixBeforeActivateEvent, HelixElement, HelixFilterEvent, HelixFilteredEvent, inlineStep, requestChange, StatusController, scrollItemIntoView, searchableById, VirtualizeController, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { AriaForwardController, CopyController, countLabel, customElement, drawStatus, elementById, fillTemplate, formatNumbers, HelixActivateEvent, HelixBeforeActivateEvent, HelixBeforeCloseEvent, HelixBeforeOpenEvent, HelixElement, HelixFilterEvent, HelixFilteredEvent, inlineStep, requestChange, StatusController, scrollItemIntoView, searchableById, Typeahead, treeArrow, VirtualizeController, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { caretDown, caretRight } from '@fusion.dev/helix-icons';
|
|
10
10
|
import { html, nothing } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
12
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
12
13
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
13
14
|
import { html as staticHtml } from 'lit/static-html.js';
|
|
14
15
|
import '../../copy-button/index.js';
|
|
15
|
-
import {
|
|
16
|
+
import { cursorFor, entries, flatten, search, seed, siblingBranches, withAncestors, } from '../rows.js';
|
|
16
17
|
let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends HelixElement {
|
|
17
18
|
constructor() {
|
|
18
19
|
super(...arguments);
|
|
@@ -38,7 +39,9 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
38
39
|
this.opened = new Set();
|
|
39
40
|
this.cursor = 0;
|
|
40
41
|
this.revealing = false;
|
|
41
|
-
this.
|
|
42
|
+
this.focusing = false;
|
|
43
|
+
this.hadFocus = false;
|
|
44
|
+
this.typed = new Typeahead();
|
|
42
45
|
this.branches = new Set();
|
|
43
46
|
this.aria = new AriaForwardController(this, {
|
|
44
47
|
label: true,
|
|
@@ -81,24 +84,31 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
81
84
|
case 'End':
|
|
82
85
|
this.move(rows.length - 1);
|
|
83
86
|
break;
|
|
87
|
+
case 'PageDown':
|
|
88
|
+
this.move(this.cursor + this.pageRows());
|
|
89
|
+
break;
|
|
90
|
+
case 'PageUp':
|
|
91
|
+
this.move(this.cursor - this.pageRows());
|
|
92
|
+
break;
|
|
84
93
|
case 'ArrowRight':
|
|
85
94
|
case 'ArrowLeft':
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
switch (treeArrow(row, inlineStep(this, event.key) === 1 ? 1 : -1)) {
|
|
96
|
+
case 'open':
|
|
97
|
+
case 'close':
|
|
98
|
+
this.toggle(row, !row.open);
|
|
99
|
+
break;
|
|
100
|
+
case 'child':
|
|
91
101
|
this.move(this.cursor + 1);
|
|
102
|
+
break;
|
|
103
|
+
case 'parent': {
|
|
104
|
+
const parent = rows.findLastIndex((candidate, at) => at < this.cursor && candidate.depth === row.depth - 1);
|
|
105
|
+
if (parent >= 0) {
|
|
106
|
+
this.move(parent);
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
92
109
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.toggle(row, false);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
const parent = rows.findLastIndex((candidate, at) => at < this.cursor && candidate.depth === row.depth - 1);
|
|
99
|
-
if (parent >= 0) {
|
|
100
|
-
this.move(parent);
|
|
101
|
-
}
|
|
110
|
+
default:
|
|
111
|
+
break;
|
|
102
112
|
}
|
|
103
113
|
break;
|
|
104
114
|
case 'Enter':
|
|
@@ -108,7 +118,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
108
118
|
}
|
|
109
119
|
break;
|
|
110
120
|
case '*':
|
|
111
|
-
this.
|
|
121
|
+
this.requestOpen(siblingBranches(rows, row), true);
|
|
112
122
|
break;
|
|
113
123
|
default:
|
|
114
124
|
if (event.key.length !== 1 || event.altKey || event.ctrlKey || event.metaKey) {
|
|
@@ -136,9 +146,22 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
136
146
|
}
|
|
137
147
|
};
|
|
138
148
|
this.handleFilterKeydown = (event) => {
|
|
139
|
-
if (event.key === 'ArrowDown') {
|
|
149
|
+
if (event.key === 'ArrowDown' && this.rows.length > 0) {
|
|
140
150
|
event.preventDefault();
|
|
141
|
-
this.
|
|
151
|
+
this.revealing = true;
|
|
152
|
+
this.focusing = true;
|
|
153
|
+
this.requestUpdate();
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
this.handleFocusIn = (event) => {
|
|
157
|
+
const index = Number(event.target.dataset?.index);
|
|
158
|
+
if (Number.isInteger(index) && index !== this.cursor) {
|
|
159
|
+
this.move(index);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
this.handleFocusOut = () => {
|
|
163
|
+
if (this.windowed) {
|
|
164
|
+
this.requestUpdate();
|
|
142
165
|
}
|
|
143
166
|
};
|
|
144
167
|
}
|
|
@@ -173,18 +196,11 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
173
196
|
}
|
|
174
197
|
}
|
|
175
198
|
openAround(paths) {
|
|
176
|
-
|
|
177
|
-
for (const path of paths) {
|
|
178
|
-
for (const above of ancestorsOf(path)) {
|
|
179
|
-
if (this.branches.has(above)) {
|
|
180
|
-
opened.add(above);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
this.opened = opened;
|
|
199
|
+
this.opened = withAncestors(this.opened, this.branches, paths);
|
|
185
200
|
}
|
|
186
201
|
willUpdate(changed) {
|
|
187
202
|
super.willUpdate(changed);
|
|
203
|
+
this.hadFocus = this.hasFocusedRow();
|
|
188
204
|
if (this.loadedFor !== this.for && searchableById(this) && !this.hydrating) {
|
|
189
205
|
this.loadedFor = this.for;
|
|
190
206
|
this.load();
|
|
@@ -212,26 +228,12 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
212
228
|
wanted !== undefined ||
|
|
213
229
|
['active', 'defaultDepth', 'expanded', 'filter', 'opened'].some((name) => changed.has(name))) {
|
|
214
230
|
this.rows = flatten(this.root, this.opened, this.found);
|
|
215
|
-
this.cursor = this.
|
|
231
|
+
this.cursor = cursorFor(this.rows, wanted ?? was, this.cursor, changed.has('filter'));
|
|
216
232
|
}
|
|
217
233
|
if (changed.has('filter') && this.hasUpdated) {
|
|
218
234
|
this.tell();
|
|
219
235
|
}
|
|
220
236
|
}
|
|
221
|
-
place(path, filtered) {
|
|
222
|
-
const rows = this.rows;
|
|
223
|
-
const at = (one) => rows.findIndex((row) => row.path === one);
|
|
224
|
-
const own = path === undefined ? -1 : at(path);
|
|
225
|
-
if (own >= 0 || path === undefined) {
|
|
226
|
-
return own >= 0 ? own : Math.min(this.cursor, Math.max(0, rows.length - 1));
|
|
227
|
-
}
|
|
228
|
-
const match = filtered ? rows.findIndex((row) => row.match) : -1;
|
|
229
|
-
const around = ancestorsOf(path)
|
|
230
|
-
.reverse()
|
|
231
|
-
.map(at)
|
|
232
|
-
.find((one) => one >= 0);
|
|
233
|
-
return match >= 0 ? match : (around ?? 0);
|
|
234
|
-
}
|
|
235
237
|
tell() {
|
|
236
238
|
if (this.found) {
|
|
237
239
|
this.status.say(countLabel(this.found.size, this.resultLabel, this.resultsLabel, this.lang));
|
|
@@ -250,6 +252,19 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
250
252
|
this.revealing = false;
|
|
251
253
|
this.reveal();
|
|
252
254
|
}
|
|
255
|
+
const lost = this.hadFocus &&
|
|
256
|
+
!this.hasFocusedRow() &&
|
|
257
|
+
this.ownerDocument.activeElement === this.ownerDocument.body;
|
|
258
|
+
if (this.focusing || lost) {
|
|
259
|
+
this.focusing = false;
|
|
260
|
+
this.focusActive();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
focusActive() {
|
|
264
|
+
const row = this.partNamed('tree')?.querySelector(`[data-index="${this.cursor}"]`);
|
|
265
|
+
if (row && this.shadowRoot?.activeElement !== row) {
|
|
266
|
+
row.focus({ preventScroll: true });
|
|
267
|
+
}
|
|
253
268
|
}
|
|
254
269
|
load() {
|
|
255
270
|
const text = this.for === '' ? '' : (elementById(this, this.for)?.textContent ?? '');
|
|
@@ -277,7 +292,10 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
277
292
|
const from = Number(this.cursor > Number(last.dataset.index) ? last.dataset.index : first.dataset.index);
|
|
278
293
|
tree.scrollTop += (this.cursor - from) * height;
|
|
279
294
|
this.virtualize.measure();
|
|
280
|
-
void this.updateComplete.then(() =>
|
|
295
|
+
void this.updateComplete.then(() => {
|
|
296
|
+
this.reveal(attempts - 1);
|
|
297
|
+
this.focusActive();
|
|
298
|
+
});
|
|
281
299
|
}
|
|
282
300
|
copyable(row) {
|
|
283
301
|
if (!row) {
|
|
@@ -288,15 +306,44 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
288
306
|
}
|
|
289
307
|
return JSON.stringify(row.value, null, 2) ?? String(row.value);
|
|
290
308
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
opened.add(row.path);
|
|
309
|
+
requestOpen(paths, open) {
|
|
310
|
+
if (paths.length === 0) {
|
|
311
|
+
return false;
|
|
295
312
|
}
|
|
296
|
-
|
|
297
|
-
|
|
313
|
+
const applied = requestChange({
|
|
314
|
+
apply: () => {
|
|
315
|
+
const opened = new Set(this.opened);
|
|
316
|
+
for (const path of paths) {
|
|
317
|
+
if (open) {
|
|
318
|
+
opened.add(path);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
opened.delete(path);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
this.opened = opened;
|
|
325
|
+
},
|
|
326
|
+
event: (next) => (next ? new HelixBeforeOpenEvent() : new HelixBeforeCloseEvent()),
|
|
327
|
+
host: this,
|
|
328
|
+
next: open,
|
|
329
|
+
});
|
|
330
|
+
if (applied) {
|
|
331
|
+
this.announceToggle(open);
|
|
298
332
|
}
|
|
299
|
-
|
|
333
|
+
return applied;
|
|
334
|
+
}
|
|
335
|
+
announceToggle(open) {
|
|
336
|
+
const states = { newState: open ? 'open' : 'closed', oldState: open ? 'closed' : 'open' };
|
|
337
|
+
if (typeof ToggleEvent === 'function') {
|
|
338
|
+
this.dispatchEvent(new ToggleEvent('toggle', states));
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const event = new Event('toggle', { bubbles: false, cancelable: false, composed: false });
|
|
342
|
+
Object.assign(event, states);
|
|
343
|
+
this.dispatchEvent(event);
|
|
344
|
+
}
|
|
345
|
+
toggle(row, open = !row.open) {
|
|
346
|
+
this.requestOpen([row.path], open);
|
|
300
347
|
}
|
|
301
348
|
move(to) {
|
|
302
349
|
const at = Math.max(0, Math.min(to, this.rows.length - 1));
|
|
@@ -319,37 +366,21 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
319
366
|
this.dispatchEvent(new HelixActivateEvent({ value: path }));
|
|
320
367
|
}
|
|
321
368
|
this.revealing = true;
|
|
369
|
+
this.focusing = true;
|
|
322
370
|
return true;
|
|
323
371
|
}
|
|
324
|
-
openSiblings(row) {
|
|
325
|
-
const parent = row.path.slice(0, row.path.lastIndexOf('/'));
|
|
326
|
-
const opened = new Set(this.opened);
|
|
327
|
-
for (const one of this.rows) {
|
|
328
|
-
if (one.branch &&
|
|
329
|
-
one.depth === row.depth &&
|
|
330
|
-
one.path.slice(0, one.path.lastIndexOf('/')) === parent) {
|
|
331
|
-
opened.add(one.path);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
this.opened = opened;
|
|
335
|
-
}
|
|
336
372
|
typeahead(letter) {
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const wanted = text.toLocaleLowerCase();
|
|
341
|
-
const repeated = [...wanted].every((one) => one === wanted[0]);
|
|
342
|
-
const rows = this.rows;
|
|
343
|
-
const start = wanted.length === 1 || repeated ? this.cursor + 1 : this.cursor;
|
|
344
|
-
for (let step = 0; step < rows.length; step += 1) {
|
|
345
|
-
const at = (start + step) % rows.length;
|
|
346
|
-
const key = rows[at]?.key?.toLocaleLowerCase();
|
|
347
|
-
if (key?.startsWith(repeated ? (wanted[0] ?? '') : wanted)) {
|
|
348
|
-
this.move(at);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
373
|
+
const at = this.typed.match(letter, this.rows.map((row) => row.key ?? ''), this.cursor);
|
|
374
|
+
if (at >= 0) {
|
|
375
|
+
this.move(at);
|
|
351
376
|
}
|
|
352
377
|
}
|
|
378
|
+
pageRows() {
|
|
379
|
+
const tree = this.partNamed('tree');
|
|
380
|
+
const room = tree && tree.scrollHeight > tree.clientHeight + 1 ? tree.clientHeight : window.innerHeight;
|
|
381
|
+
const tall = this.virtualize.sizeOf(this.cursor) || HelixHeadlessObjectInspector_1.ESTIMATE;
|
|
382
|
+
return Math.max(1, Math.floor(room / tall) - 1);
|
|
383
|
+
}
|
|
353
384
|
handleRowClick(index, row) {
|
|
354
385
|
if (this.move(index) && row.branch) {
|
|
355
386
|
this.toggle(row);
|
|
@@ -391,18 +422,17 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
391
422
|
const active = index === this.cursor;
|
|
392
423
|
return html `<div
|
|
393
424
|
part="row${active ? ' row-active' : ''}${row.match ? ' row-match' : ''}"
|
|
394
|
-
role="
|
|
425
|
+
role="row"
|
|
395
426
|
id=${`row-${index}`}
|
|
396
427
|
data-index=${index}
|
|
428
|
+
tabindex=${active ? '0' : '-1'}
|
|
397
429
|
aria-level=${row.depth + 1}
|
|
398
430
|
aria-posinset=${row.position}
|
|
399
|
-
aria-selected="false"
|
|
400
431
|
aria-setsize=${row.siblings}
|
|
401
432
|
aria-expanded=${row.branch ? String(row.open) : nothing}
|
|
402
433
|
style=${`--object-inspector-level: ${row.depth}`}
|
|
403
434
|
@click=${() => this.handleRowClick(index, row)}
|
|
404
|
-
|
|
405
|
-
${row.branch
|
|
435
|
+
><div role="gridcell" style="display: contents">${row.branch
|
|
406
436
|
? html `<svg
|
|
407
437
|
part="toggle"
|
|
408
438
|
?data-mirror=${!row.open}
|
|
@@ -412,13 +442,17 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
412
442
|
>
|
|
413
443
|
${unsafeSVG((row.open ? caretDown : caretRight).content)}
|
|
414
444
|
</svg>`
|
|
415
|
-
: nothing}${row.key === undefined ? nothing : html `<span part="key">${row.key}</span>: `}${this.renderValue(row)}
|
|
445
|
+
: nothing}${row.key === undefined ? nothing : html `<span part="key">${row.key}</span>: `}${this.renderValue(row)}</div>
|
|
416
446
|
</div>`;
|
|
417
447
|
}
|
|
448
|
+
hasFocusedRow() {
|
|
449
|
+
const focused = this.shadowRoot?.activeElement;
|
|
450
|
+
return focused?.getAttribute?.('role') === 'row';
|
|
451
|
+
}
|
|
418
452
|
renderCopyButton(row) {
|
|
419
453
|
return staticHtml `<${this.tag('copy-button')}
|
|
420
454
|
part="copy"
|
|
421
|
-
exportparts="button: copy-button, live: copy-live, text: copy-text, mark: copy-mark, tooltip: copy-tooltip,
|
|
455
|
+
exportparts="button: copy-button, live: copy-live, spinner: copy-spinner, text: copy-text, mark: copy-mark, tooltip: copy-tooltip,
|
|
422
456
|
tooltip-arrow: copy-tooltip-arrow, tooltip-arrow-bottom: copy-tooltip-arrow-bottom,
|
|
423
457
|
tooltip-arrow-left: copy-tooltip-arrow-left, tooltip-arrow-right: copy-tooltip-arrow-right,
|
|
424
458
|
tooltip-arrow-top: copy-tooltip-arrow-top, tooltip-bottom: copy-tooltip-bottom,
|
|
@@ -429,10 +463,18 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
429
463
|
}
|
|
430
464
|
render() {
|
|
431
465
|
const rows = this.rows;
|
|
432
|
-
const {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
466
|
+
const { first, last } = this.windowed ? this.virtualize.window : { first: 0, last: rows.length };
|
|
467
|
+
const kept = this.windowed && (this.cursor < first || this.cursor >= last) && this.hasFocusedRow()
|
|
468
|
+
? this.cursor
|
|
469
|
+
: undefined;
|
|
470
|
+
const { after, before } = this.windowed
|
|
471
|
+
? this.virtualize.spacers(kept)
|
|
472
|
+
: { after: 0, before: 0 };
|
|
473
|
+
const shown = rows.slice(first, last).map((row, at) => [row, first + at]);
|
|
474
|
+
const keptRow = kept === undefined ? undefined : rows[kept];
|
|
475
|
+
if (kept !== undefined && keptRow) {
|
|
476
|
+
shown.splice(kept < first ? 0 : shown.length, 0, [keptRow, kept]);
|
|
477
|
+
}
|
|
436
478
|
return html `${this.label ? html `<div part="header"><span part="label">${this.label}</span></div>` : nothing}${this.filterable
|
|
437
479
|
? html `<input
|
|
438
480
|
part="search-field"
|
|
@@ -450,16 +492,16 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
|
|
|
450
492
|
<div
|
|
451
493
|
part="tree"
|
|
452
494
|
id="tree"
|
|
453
|
-
role="
|
|
454
|
-
tabindex="0"
|
|
495
|
+
role="treegrid"
|
|
455
496
|
?data-scroller=${this.windowed}
|
|
456
497
|
aria-label=${this.label || this.treeLabel}
|
|
457
|
-
aria-activedescendant=${rows.length > 0 ? `row-${this.cursor}` : nothing}
|
|
458
498
|
@keydown=${this.handleKeydown}
|
|
499
|
+
@focusin=${this.handleFocusIn}
|
|
500
|
+
@focusout=${this.handleFocusOut}
|
|
459
501
|
@scroll=${() => this.virtualize.measure()}
|
|
460
502
|
>
|
|
461
503
|
${this.windowed ? html `<div part="before" role="presentation" style="block-size: ${before}px"></div>` : nothing}
|
|
462
|
-
${shown.
|
|
504
|
+
${repeat(shown, ([row]) => row.path, ([row, at]) => this.renderRow(row, at))}
|
|
463
505
|
${this.windowed ? html `<div part="after" role="presentation" style="block-size: ${after}px"></div>` : nothing}
|
|
464
506
|
</div>
|
|
465
507
|
${this.noCopy ? nothing : this.renderCopyButton(rows[this.cursor])}
|
|
@@ -55,3 +55,21 @@ export declare const seed: (root: unknown, depth: number, known?: Set<string>, o
|
|
|
55
55
|
branches: Set<string>;
|
|
56
56
|
opened: Set<string>;
|
|
57
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Where the active row goes once the rows have moved, as an index into `rows`.
|
|
60
|
+
*
|
|
61
|
+
* Onto `path` where it is still shown. Where a filter just hid it
|
|
62
|
+
* (`filtered`), onto the first match. Otherwise onto the nearest branch around
|
|
63
|
+
* it that is shown. With no path to keep, `cursor` held inside the rows.
|
|
64
|
+
*/
|
|
65
|
+
export declare const cursorFor: (rows: readonly Row[], path: string | undefined, cursor: number, filtered: boolean) => number;
|
|
66
|
+
/**
|
|
67
|
+
* The open branches with every branch around each of `paths` opened too,
|
|
68
|
+
* where the value has that branch (`branches`).
|
|
69
|
+
*/
|
|
70
|
+
export declare const withAncestors: (opened: ReadonlySet<string>, branches: ReadonlySet<string>, paths: Iterable<string>) => Set<string>;
|
|
71
|
+
/**
|
|
72
|
+
* The branches `*` opens from `row`: every branch at its depth under the same
|
|
73
|
+
* parent, itself included, that is not open yet.
|
|
74
|
+
*/
|
|
75
|
+
export declare const siblingBranches: (rows: readonly Row[], row: Row) => string[];
|
|
@@ -84,3 +84,36 @@ export const seed = (root, depth, known = new Set(), opened = new Set()) => {
|
|
|
84
84
|
visit(root, '', 0);
|
|
85
85
|
return { branches, opened: open };
|
|
86
86
|
};
|
|
87
|
+
export const cursorFor = (rows, path, cursor, filtered) => {
|
|
88
|
+
const at = (one) => rows.findIndex((row) => row.path === one);
|
|
89
|
+
const own = path === undefined ? -1 : at(path);
|
|
90
|
+
if (own >= 0 || path === undefined) {
|
|
91
|
+
return own >= 0 ? own : Math.min(cursor, Math.max(0, rows.length - 1));
|
|
92
|
+
}
|
|
93
|
+
const match = filtered ? rows.findIndex((row) => row.match) : -1;
|
|
94
|
+
const around = ancestorsOf(path)
|
|
95
|
+
.reverse()
|
|
96
|
+
.map(at)
|
|
97
|
+
.find((one) => one >= 0);
|
|
98
|
+
return match >= 0 ? match : (around ?? 0);
|
|
99
|
+
};
|
|
100
|
+
export const withAncestors = (opened, branches, paths) => {
|
|
101
|
+
const next = new Set(opened);
|
|
102
|
+
for (const path of paths) {
|
|
103
|
+
for (const above of ancestorsOf(path)) {
|
|
104
|
+
if (branches.has(above)) {
|
|
105
|
+
next.add(above);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return next;
|
|
110
|
+
};
|
|
111
|
+
export const siblingBranches = (rows, row) => {
|
|
112
|
+
const parent = row.path.slice(0, row.path.lastIndexOf('/'));
|
|
113
|
+
return rows
|
|
114
|
+
.filter((one) => one.branch &&
|
|
115
|
+
!one.open &&
|
|
116
|
+
one.depth === row.depth &&
|
|
117
|
+
one.path.slice(0, one.path.lastIndexOf('/')) === parent)
|
|
118
|
+
.map((one) => one.path);
|
|
119
|
+
};
|
package/dist/option/index.d.ts
CHANGED
package/dist/option/index.js
CHANGED
|
@@ -63,9 +63,11 @@ export declare class HelixHeadlessOption extends HelixElement {
|
|
|
63
63
|
/**
|
|
64
64
|
* Whether this is the option the keyboard is on.
|
|
65
65
|
*
|
|
66
|
-
* Written by the listbox
|
|
67
|
-
*
|
|
68
|
-
*
|
|
66
|
+
* Written by the listbox once a reader moves the highlight. Style it with
|
|
67
|
+
* `:state(active)`, or `::part(item-active)` for an option inside another
|
|
68
|
+
* component's shadow root. The `data-active` attribute sets it from markup;
|
|
69
|
+
* it is also written back for stylesheets from before the state, and no
|
|
70
|
+
* stylesheet of the library's own selects it.
|
|
69
71
|
*/
|
|
70
72
|
active: boolean;
|
|
71
73
|
/**
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type PropertyValues } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary A rule between options or groups inside a listbox.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* Sets one run of options apart from the next where a heading would say too
|
|
8
|
+
* much, as React Aria's ListBox takes a `Separator`: actions apart from
|
|
9
|
+
* choices in a command palette, say, or the options a reader uses most apart
|
|
10
|
+
* from the rest.
|
|
11
|
+
*
|
|
12
|
+
* It has `role="separator"`, so a screen reader can say where one run ends,
|
|
13
|
+
* and it is no stop: the arrow keys move from the option before it to the one
|
|
14
|
+
* after. The list hides it while a filter is narrowing the options, since a
|
|
15
|
+
* rule between two runs of which only some options are left separates nothing.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.1.0
|
|
18
|
+
* @status stable
|
|
19
|
+
* @aliases Divider, ListBoxSeparator
|
|
20
|
+
* @documentation https://fusion.dev/helix/components/option
|
|
21
|
+
*/
|
|
22
|
+
export declare class HelixHeadlessOptionSeparator extends HelixElement {
|
|
23
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
24
|
+
protected render(): typeof nothing;
|
|
25
|
+
}
|
|
26
|
+
declare global {
|
|
27
|
+
interface HTMLElementTagNameMap {
|
|
28
|
+
'helix-headless-option-separator': HelixHeadlessOptionSeparator;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
+
import { nothing } from 'lit';
|
|
9
|
+
let HelixHeadlessOptionSeparator = class HelixHeadlessOptionSeparator extends HelixElement {
|
|
10
|
+
willUpdate(changed) {
|
|
11
|
+
super.willUpdate(changed);
|
|
12
|
+
hostAria(this.internals, { role: 'separator' });
|
|
13
|
+
}
|
|
14
|
+
render() {
|
|
15
|
+
return nothing;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
HelixHeadlessOptionSeparator = __decorate([
|
|
19
|
+
customElement('helix-headless-option-separator')
|
|
20
|
+
], HelixHeadlessOptionSeparator);
|
|
21
|
+
export { HelixHeadlessOptionSeparator };
|
|
@@ -20,6 +20,21 @@ import { type Branch } from '../levels.js';
|
|
|
20
20
|
*
|
|
21
21
|
* A heading slotted into `heading` names the navigation, in place of `label`.
|
|
22
22
|
*
|
|
23
|
+
* In a contents rail with a scrollbar of its own, `follow` keeps the link of
|
|
24
|
+
* the section in view showing as the reader scrolls the page.
|
|
25
|
+
*
|
|
26
|
+
* **Keyboard.** The links are your anchors, in the tab order as you wrote
|
|
27
|
+
* them, so the outline adds no keys of its own: Tab moves through the links
|
|
28
|
+
* and Enter follows one. Following a link moves focus to its section, so the
|
|
29
|
+
* next Tab goes on from the heading, also with `behavior` set.
|
|
30
|
+
*
|
|
31
|
+
* **What a screen reader hears.** A navigation landmark named by `label`, "On
|
|
32
|
+
* this page", or by the slotted heading. The links are lists, nested by level,
|
|
33
|
+
* so a reader hears how many links a level holds and where each one is. The
|
|
34
|
+
* link to the section in view carries `aria-current="location"`, read as
|
|
35
|
+
* "current location", and it moves as the page scrolls without announcing,
|
|
36
|
+
* which would interrupt the reading it follows.
|
|
37
|
+
*
|
|
23
38
|
* The current section is decided by the headings' positions. An
|
|
24
39
|
* `IntersectionObserver` with a band near the top fails both ways: when
|
|
25
40
|
* headings are far apart, none is in the band and no section is marked, and
|
|
@@ -73,6 +88,13 @@ export declare class HelixHeadlessOutline extends HelixElement {
|
|
|
73
88
|
* JavaScript rather than CSS decides.
|
|
74
89
|
*/
|
|
75
90
|
behavior: ScrollBehavior;
|
|
91
|
+
/**
|
|
92
|
+
* Keeps the link of the section in view in view itself, in an outline
|
|
93
|
+
* longer than the box it scrolls in, such as a contents rail with a
|
|
94
|
+
* scrollbar of its own. Only that box moves: never the page, and never the
|
|
95
|
+
* box the sections scroll in.
|
|
96
|
+
*/
|
|
97
|
+
follow: boolean;
|
|
76
98
|
/**
|
|
77
99
|
* The navigation's name, read by screen readers. A heading in the `heading`
|
|
78
100
|
* slot names it in place of this.
|
|
@@ -154,6 +176,14 @@ export declare class HelixHeadlessOutline extends HelixElement {
|
|
|
154
176
|
private mark;
|
|
155
177
|
/** Where the destination is set, whether measured or asked for. */
|
|
156
178
|
private markTo;
|
|
179
|
+
/**
|
|
180
|
+
* Scrolls the box the links scroll in to show `link`, under `follow`.
|
|
181
|
+
*
|
|
182
|
+
* The nearest box above the link that scrolls, and only where it is the
|
|
183
|
+
* rail's own: the page, the box the sections scroll in, or a box holding it
|
|
184
|
+
* would move the reading under the reader, which is the scroll this marks.
|
|
185
|
+
*/
|
|
186
|
+
private reveal;
|
|
157
187
|
/**
|
|
158
188
|
* Whether the page has no more scroll left.
|
|
159
189
|
*
|
|
@@ -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, elementById, HelixActivateEvent, HelixElement, IndicatorController, reflectElements, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, elementById, HelixActivateEvent, HelixElement, IndicatorController, plainClick, reflectElements, scrollItemIntoView, scrollingAncestor, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { levelOf, nest } from '../levels.js';
|
|
@@ -18,6 +18,7 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
18
18
|
surface: () => this.partNamed('nav'),
|
|
19
19
|
});
|
|
20
20
|
this.behavior = 'auto';
|
|
21
|
+
this.follow = false;
|
|
21
22
|
this.label = 'On this page';
|
|
22
23
|
this.offset = 0;
|
|
23
24
|
this.reading = '';
|
|
@@ -32,10 +33,7 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
32
33
|
});
|
|
33
34
|
};
|
|
34
35
|
this.handleClick = (event) => {
|
|
35
|
-
if (event.defaultPrevented || event
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
36
|
+
if (event.defaultPrevented || !plainClick(event)) {
|
|
39
37
|
return;
|
|
40
38
|
}
|
|
41
39
|
const link = event.target?.closest?.('a[href^="#"]');
|
|
@@ -142,9 +140,19 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
142
140
|
if (next !== this.reading) {
|
|
143
141
|
this.reading = next;
|
|
144
142
|
this.indicator.place();
|
|
143
|
+
if (this.follow && active) {
|
|
144
|
+
this.reveal(active.link);
|
|
145
|
+
}
|
|
145
146
|
this.dispatchEvent(new HelixActivateEvent({ value: next }));
|
|
146
147
|
}
|
|
147
148
|
}
|
|
149
|
+
reveal(link) {
|
|
150
|
+
const sections = this.scroller;
|
|
151
|
+
const node = scrollingAncestor(link, { axis: 'y', overflowing: true, stop: this.page });
|
|
152
|
+
if (node && node !== sections && !node.contains(sections)) {
|
|
153
|
+
scrollItemIntoView(link, { scroller: node });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
148
156
|
get atEnd() {
|
|
149
157
|
const doc = this.scroller;
|
|
150
158
|
return Math.ceil(doc.scrollTop + doc.clientHeight) >= doc.scrollHeight - 1;
|
|
@@ -154,15 +162,8 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
154
162
|
return (doc.scrollingElement ?? doc.documentElement);
|
|
155
163
|
}
|
|
156
164
|
get scroller() {
|
|
157
|
-
const doc = globalThis.document;
|
|
158
165
|
const first = this.sections[0]?.target;
|
|
159
|
-
|
|
160
|
-
const { overflowY } = getComputedStyle(node);
|
|
161
|
-
if (/auto|scroll|overlay/.test(overflowY) && node.scrollHeight > node.clientHeight) {
|
|
162
|
-
return node;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return this.page;
|
|
166
|
+
return (first && scrollingAncestor(first, { axis: 'y', overflowing: true })) || this.page;
|
|
166
167
|
}
|
|
167
168
|
reach() {
|
|
168
169
|
for (const { target } of this.sections) {
|
|
@@ -282,6 +283,9 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
282
283
|
__decorate([
|
|
283
284
|
property()
|
|
284
285
|
], HelixHeadlessOutline.prototype, "behavior", void 0);
|
|
286
|
+
__decorate([
|
|
287
|
+
property({ type: Boolean })
|
|
288
|
+
], HelixHeadlessOutline.prototype, "follow", void 0);
|
|
285
289
|
__decorate([
|
|
286
290
|
property()
|
|
287
291
|
], HelixHeadlessOutline.prototype, "label", void 0);
|
|
@@ -14,6 +14,11 @@ import '../../select/index.js';
|
|
|
14
14
|
* `currentColor`, and the label is a real `<label for>` pointing at the
|
|
15
15
|
* trigger's id.
|
|
16
16
|
*
|
|
17
|
+
* A `<label for>` pointing at this element, or its own `aria-label` or
|
|
18
|
+
* `aria-labelledby`, names the select in place of `label`, so a reader hears
|
|
19
|
+
* the page's words for it, and the select draws no label of its own beside
|
|
20
|
+
* the page's.
|
|
21
|
+
*
|
|
17
22
|
* The label sits on the same row as the select. `Select`'s host is a column,
|
|
18
23
|
* and an outer-tree rule overrides a `:host` rule, so the row layout needs no
|
|
19
24
|
* property on `Select` and nothing added to your markup.
|
|
@@ -49,6 +54,7 @@ import '../../select/index.js';
|
|
|
49
54
|
* @csspart control-label - The label beside the number.
|
|
50
55
|
* @csspart control-listbox - The list inside the panel.
|
|
51
56
|
* @csspart control-listbox-empty - The text shown when the filter hides every option.
|
|
57
|
+
* @csspart control-listbox-error - The inner list's `error` part, shown while its `load-error` is set.
|
|
52
58
|
* @csspart control-listbox-feedback - The inner list's message that says what is wrong with the value.
|
|
53
59
|
* @csspart control-listbox-filter-icon - The icon beside the filter field.
|
|
54
60
|
* @csspart control-listbox-filter-mark - The default icon beside the filter field, shown when none is slotted.
|