@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary One collapsible section of an accordion.
|
|
@@ -18,12 +18,22 @@ declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("
|
|
|
18
18
|
* out of the tab order and the accessibility tree after the styled tier's
|
|
19
19
|
* `display` overrides `hidden`.
|
|
20
20
|
*
|
|
21
|
+
* While it is open, the content part carries the content's height as
|
|
22
|
+
* `--accordion-content-height`, as Radix's accordion does, for a stylesheet
|
|
23
|
+
* that animates the section open with keyframes of its own.
|
|
24
|
+
*
|
|
25
|
+
* Set `hidden-until-found` and the browser's find in page searches a closed
|
|
26
|
+
* section too: a match opens it, with `helix-before-open` first, as React
|
|
27
|
+
* Aria's disclosure does. The content is then `hidden="until-found"` while
|
|
28
|
+
* closed, and not `inert`, since an inert region is never searched.
|
|
29
|
+
*
|
|
21
30
|
* @since 0.1.0
|
|
22
31
|
* @status stable
|
|
23
32
|
* @aliases Collapsible, Expander, Disclosure
|
|
24
33
|
* @documentation https://fusion.dev/helix/components/accordion
|
|
25
34
|
*
|
|
26
35
|
* @slot - The content shown when the section is open.
|
|
36
|
+
* @slot chevron - Replaces the open and close indicator, such as with your own icon.
|
|
27
37
|
* @slot summary - The text of the button that opens and closes the section. Always shown.
|
|
28
38
|
*
|
|
29
39
|
* @event {HelixBeforeCloseEvent} helix-before-close - The section is about to close. Cancelable: cancel it to keep it open.
|
|
@@ -37,6 +47,8 @@ declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("
|
|
|
37
47
|
* @csspart heading - The heading that holds the trigger.
|
|
38
48
|
* @csspart trigger - The button that opens and closes the section, holding the summary.
|
|
39
49
|
*
|
|
50
|
+
* @cssproperty --accordion-content-height - The height of the content, in pixels, written on the `content` part while the section is open.
|
|
51
|
+
*
|
|
40
52
|
* @cssstate open - While the item is open.
|
|
41
53
|
*/
|
|
42
54
|
export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionItem_base {
|
|
@@ -51,8 +63,13 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
51
63
|
* have two.
|
|
52
64
|
*/
|
|
53
65
|
chevronPlacement?: 'auto' | 'start' | 'end' | 'none';
|
|
54
|
-
/**
|
|
55
|
-
|
|
66
|
+
/**
|
|
67
|
+
* The chevron, or nothing when suppressed.
|
|
68
|
+
*
|
|
69
|
+
* The drawn chevron is the `chevron` slot's fallback, so an icon of your own
|
|
70
|
+
* replaces it by being slotted, and a tier drawing its own overrides this.
|
|
71
|
+
*/
|
|
72
|
+
protected renderChevron(): TemplateResult | typeof nothing;
|
|
56
73
|
/**
|
|
57
74
|
* Whether the section is disabled, so its trigger cannot be pressed or
|
|
58
75
|
* reached with the arrow keys. A script can still open and close it.
|
|
@@ -64,6 +81,11 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
64
81
|
* causes a hydration mismatch.
|
|
65
82
|
*/
|
|
66
83
|
groupHeadingLevel: number | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* @internal The accordion's `hidden-until-found`, written by the accordion,
|
|
86
|
+
* for the reason `groupHeadingLevel` is a property.
|
|
87
|
+
*/
|
|
88
|
+
groupHiddenUntilFound: boolean;
|
|
67
89
|
/**
|
|
68
90
|
* The level of the heading around the trigger, from 1 to 6.
|
|
69
91
|
*
|
|
@@ -71,6 +93,16 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
71
93
|
* too.
|
|
72
94
|
*/
|
|
73
95
|
headingLevel?: number;
|
|
96
|
+
/**
|
|
97
|
+
* Whether find in page searches the section while it is closed, and opens it
|
|
98
|
+
* on a match.
|
|
99
|
+
*
|
|
100
|
+
* Off by default. A closed section is then `hidden="until-found"`, which
|
|
101
|
+
* hides through `content-visibility`, so a stylesheet that animates the
|
|
102
|
+
* section closed shows an empty box for the length of that animation. The
|
|
103
|
+
* accordion's own `hidden-until-found` turns it on for every section.
|
|
104
|
+
*/
|
|
105
|
+
hiddenUntilFound: boolean;
|
|
74
106
|
/**
|
|
75
107
|
* A group name. Opening an item closes the other items with the same name,
|
|
76
108
|
* as `<details name>` does.
|
|
@@ -92,6 +124,15 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
92
124
|
* absence. Caught by `hydration.dom.spec.ts`.
|
|
93
125
|
*/
|
|
94
126
|
name?: string;
|
|
127
|
+
/** Whether find in page searches this section while it is closed. */
|
|
128
|
+
private get findable();
|
|
129
|
+
/**
|
|
130
|
+
* Opens the section find in page has matched in, before the match is shown.
|
|
131
|
+
*
|
|
132
|
+
* The browser removes `hidden` itself. A refusal puts it back, so the trigger
|
|
133
|
+
* and the region still agree.
|
|
134
|
+
*/
|
|
135
|
+
private readonly handleBeforeMatch;
|
|
95
136
|
/** Whether the item was open at the last update, and `undefined` before one. */
|
|
96
137
|
private wasOpen;
|
|
97
138
|
/**
|
|
@@ -131,6 +172,12 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
131
172
|
* settle, once every item is there to compare.
|
|
132
173
|
*/
|
|
133
174
|
protected updated(changed: PropertyValues): void;
|
|
175
|
+
/**
|
|
176
|
+
* Writes the content's height onto the content part while the section is
|
|
177
|
+
* open. `scrollHeight`, so a sheet that clips the box while it grows still
|
|
178
|
+
* reads the whole height.
|
|
179
|
+
*/
|
|
180
|
+
private readonly measure;
|
|
134
181
|
/**
|
|
135
182
|
* Moves focus to this item's trigger.
|
|
136
183
|
*
|
|
@@ -157,16 +204,19 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
157
204
|
* part outranks it and the transition runs exactly as before. Measured on
|
|
158
205
|
* both tiers.
|
|
159
206
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* trigger still reports collapsed.
|
|
207
|
+
* **`hidden="until-found"` only where it was asked for.** It hides through
|
|
208
|
+
* `content-visibility` rather than `display`, which an author `display` does
|
|
209
|
+
* not override, so a section a sheet animates closed shows an empty box while
|
|
210
|
+
* it shrinks. `beforematch` sets `open`, so find in page never reveals text
|
|
211
|
+
* under a trigger that still reports collapsed.
|
|
166
212
|
*
|
|
167
|
-
* `inert` stays
|
|
168
|
-
* the one tabbing through, and wherever a sheet
|
|
169
|
-
* is the only one of the two still in force.
|
|
213
|
+
* `inert` stays, except under `until-found`. `hidden` answers the reader who
|
|
214
|
+
* can see and `inert` answers the one tabbing through, and wherever a sheet
|
|
215
|
+
* overrides `display`, `inert` is the only one of the two still in force.
|
|
216
|
+
* `content-visibility: hidden` keeps skipped content out of the tab order and
|
|
217
|
+
* the accessibility tree by itself, and an inert region is never searched.
|
|
218
|
+
* It leaves the region's own box in the tree, so a closed findable section
|
|
219
|
+
* drops `role="region"` and its name until it opens.
|
|
170
220
|
*/
|
|
171
221
|
protected render(): TemplateResult;
|
|
172
222
|
}
|
|
@@ -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 { closestInstance, customElement, HelixElement, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { closestInstance, customElement, HelixElement, headingLevel, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretDown } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -17,6 +17,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
17
17
|
super(...arguments);
|
|
18
18
|
this.disabled = false;
|
|
19
19
|
this.groupHeadingLevel = undefined;
|
|
20
|
+
this.groupHiddenUntilFound = false;
|
|
21
|
+
this.hiddenUntilFound = false;
|
|
22
|
+
this.handleBeforeMatch = (event) => {
|
|
23
|
+
if (this.open || this.requestOpen(true)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
;
|
|
27
|
+
event.currentTarget.setAttribute('hidden', 'until-found');
|
|
28
|
+
};
|
|
20
29
|
this.wasOpen = undefined;
|
|
21
30
|
this.handleToggle = () => {
|
|
22
31
|
if (this.disabled) {
|
|
@@ -34,14 +43,27 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
34
43
|
this.closePeers();
|
|
35
44
|
}
|
|
36
45
|
};
|
|
46
|
+
this.measure = () => {
|
|
47
|
+
const content = this.partNamed('content');
|
|
48
|
+
const inner = this.partNamed('content-inner');
|
|
49
|
+
if (!content || !inner || !this.open) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
content.style.setProperty('--accordion-content-height', `${inner.scrollHeight}px`);
|
|
53
|
+
};
|
|
37
54
|
}
|
|
38
55
|
renderChevron() {
|
|
39
56
|
if (this.chevronPlacement === 'none') {
|
|
40
57
|
return nothing;
|
|
41
58
|
}
|
|
42
|
-
return html `<
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
return html `<slot name="chevron" aria-hidden="true"
|
|
60
|
+
><svg part="chevron" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
|
|
61
|
+
${unsafeSVG(caretDown.content)}
|
|
62
|
+
</svg></slot
|
|
63
|
+
>`;
|
|
64
|
+
}
|
|
65
|
+
get findable() {
|
|
66
|
+
return this.hiddenUntilFound || this.groupHiddenUntilFound;
|
|
45
67
|
}
|
|
46
68
|
get accordion() {
|
|
47
69
|
return closestInstance(this, HelixHeadlessAccordion);
|
|
@@ -75,13 +97,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
75
97
|
this.closePeers();
|
|
76
98
|
}
|
|
77
99
|
this.wasOpen = this.open;
|
|
100
|
+
this.measure();
|
|
78
101
|
}
|
|
79
102
|
focusTrigger() {
|
|
80
103
|
this.renderRoot.querySelector(`#${TRIGGER_ID}`)?.focus();
|
|
81
104
|
}
|
|
82
105
|
render() {
|
|
83
106
|
const open = this.open;
|
|
84
|
-
const
|
|
107
|
+
const landmark = open || !this.findable;
|
|
108
|
+
const level = headingLevel(this.headingLevel ?? this.groupHeadingLevel);
|
|
85
109
|
return html `
|
|
86
110
|
<div part="container">
|
|
87
111
|
<div part="heading" role="heading" aria-level=${level}>
|
|
@@ -101,14 +125,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
101
125
|
</div>
|
|
102
126
|
<div
|
|
103
127
|
id=${CONTENT_ID}
|
|
104
|
-
aria-labelledby=${TRIGGER_ID}
|
|
128
|
+
aria-labelledby=${landmark ? TRIGGER_ID : nothing}
|
|
105
129
|
part="content"
|
|
106
|
-
|
|
107
|
-
?inert=${!open}
|
|
108
|
-
role
|
|
130
|
+
hidden=${open ? nothing : this.findable ? 'until-found' : ''}
|
|
131
|
+
?inert=${!open && !this.findable}
|
|
132
|
+
role=${landmark ? 'region' : nothing}
|
|
133
|
+
@beforematch=${this.handleBeforeMatch}
|
|
109
134
|
>
|
|
110
135
|
<div part="content-inner">
|
|
111
|
-
<slot></slot>
|
|
136
|
+
<slot @slotchange=${this.measure}></slot>
|
|
112
137
|
</div>
|
|
113
138
|
</div>
|
|
114
139
|
</div>
|
|
@@ -124,9 +149,15 @@ __decorate([
|
|
|
124
149
|
__decorate([
|
|
125
150
|
property({ attribute: false })
|
|
126
151
|
], HelixHeadlessAccordionItem.prototype, "groupHeadingLevel", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
property({ attribute: false })
|
|
154
|
+
], HelixHeadlessAccordionItem.prototype, "groupHiddenUntilFound", void 0);
|
|
127
155
|
__decorate([
|
|
128
156
|
property({ attribute: 'heading-level', type: Number })
|
|
129
157
|
], HelixHeadlessAccordionItem.prototype, "headingLevel", void 0);
|
|
158
|
+
__decorate([
|
|
159
|
+
property({ attribute: 'hidden-until-found', type: Boolean })
|
|
160
|
+
], HelixHeadlessAccordionItem.prototype, "hiddenUntilFound", void 0);
|
|
130
161
|
__decorate([
|
|
131
162
|
property({ reflect: true })
|
|
132
163
|
], HelixHeadlessAccordionItem.prototype, "name", void 0);
|
|
@@ -17,12 +17,15 @@ import { HelixHeadlessAccordionItem } from '../item/accordion-item.js';
|
|
|
17
17
|
* matched with `instanceof HelixHeadlessAccordionItem`, so the headless tier
|
|
18
18
|
* does not depend on the styled tier's tag names.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
* so
|
|
20
|
+
* Keys, on a trigger: Up and Down Arrow move to the previous and the next
|
|
21
|
+
* trigger, and so do Left and Right, wrapping at the ends; Home and End go to
|
|
22
|
+
* the first and the last. Enter and Space open and close the section. Disabled
|
|
23
|
+
* sections are passed over.
|
|
22
24
|
*
|
|
23
|
-
* Each trigger
|
|
24
|
-
*
|
|
25
|
-
*
|
|
25
|
+
* Each trigger is a button with `aria-expanded` and `aria-controls`, inside a
|
|
26
|
+
* heading, level 3 unless `heading-level` says otherwise, so the sections are
|
|
27
|
+
* in a screen reader's list of headings. An open section is a region named by
|
|
28
|
+
* its trigger. Set the level that fits the page's outline.
|
|
26
29
|
*
|
|
27
30
|
* @since 0.1.0
|
|
28
31
|
* @status stable
|
|
@@ -39,6 +42,12 @@ export declare class HelixHeadlessAccordion extends HelixElement {
|
|
|
39
42
|
* Unset is 3. An item's own `heading-level` wins over this.
|
|
40
43
|
*/
|
|
41
44
|
headingLevel?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Whether find in page searches every closed section, and opens the one it
|
|
47
|
+
* matches in. Each item's own `hidden-until-found` turns it on for that item
|
|
48
|
+
* alone.
|
|
49
|
+
*/
|
|
50
|
+
hiddenUntilFound: boolean;
|
|
42
51
|
/**
|
|
43
52
|
* How many sections may be open at once.
|
|
44
53
|
*
|
|
@@ -18,6 +18,7 @@ const navigable = (item) => ({
|
|
|
18
18
|
let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
|
|
19
19
|
constructor() {
|
|
20
20
|
super(...arguments);
|
|
21
|
+
this.hiddenUntilFound = false;
|
|
21
22
|
this.keys = new KeyboardNavigationController(this, {
|
|
22
23
|
items: () => this.items.map(navigable),
|
|
23
24
|
origin: 'focus',
|
|
@@ -32,6 +33,7 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
|
|
|
32
33
|
for (const item of items) {
|
|
33
34
|
whenHydrated(item, () => {
|
|
34
35
|
item.groupHeadingLevel = this.headingLevel;
|
|
36
|
+
item.groupHiddenUntilFound = this.hiddenUntilFound;
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
39
|
if (this.mode === undefined) {
|
|
@@ -56,7 +58,8 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
|
|
|
56
58
|
}
|
|
57
59
|
updated(changed) {
|
|
58
60
|
super.updated(changed);
|
|
59
|
-
if (this.hasUpdated &&
|
|
61
|
+
if (this.hasUpdated &&
|
|
62
|
+
(changed.has('mode') || changed.has('headingLevel') || changed.has('hiddenUntilFound'))) {
|
|
60
63
|
this.settle();
|
|
61
64
|
}
|
|
62
65
|
}
|
|
@@ -67,6 +70,9 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
|
|
|
67
70
|
__decorate([
|
|
68
71
|
property({ attribute: 'heading-level', type: Number })
|
|
69
72
|
], HelixHeadlessAccordion.prototype, "headingLevel", void 0);
|
|
73
|
+
__decorate([
|
|
74
|
+
property({ attribute: 'hidden-until-found', type: Boolean })
|
|
75
|
+
], HelixHeadlessAccordion.prototype, "hiddenUntilFound", void 0);
|
|
70
76
|
__decorate([
|
|
71
77
|
property({ reflect: true })
|
|
72
78
|
], HelixHeadlessAccordion.prototype, "mode", void 0);
|
|
@@ -16,8 +16,9 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
16
16
|
*
|
|
17
17
|
* The live region is its own part. When the announcement appears after the page
|
|
18
18
|
* has loaded, the message is written into the region one frame later, so screen
|
|
19
|
-
* readers read it reliably, and the region is emptied seven seconds later
|
|
20
|
-
* the
|
|
19
|
+
* readers read it reliably, and the region is emptied seven seconds later.
|
|
20
|
+
* While the region holds the copy, the message itself is hidden from screen
|
|
21
|
+
* readers, so it is in the page once. When the announcement is in the served
|
|
21
22
|
* HTML, the region stays empty and nothing is read out.
|
|
22
23
|
*
|
|
23
24
|
* The dismiss button fires `helix-dismiss`, and the announcement stays in the
|
|
@@ -28,6 +29,11 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
28
29
|
* announcement beside it, move focus yourself, for example to the page's main
|
|
29
30
|
* heading.
|
|
30
31
|
*
|
|
32
|
+
* Set `duration` to dismiss it after a time. The clock stops while the pointer
|
|
33
|
+
* or focus is on the announcement, and continues from what was left, so a
|
|
34
|
+
* reader partway through is not cut off. When the time runs out it sends
|
|
35
|
+
* `helix-dismiss`, as the button does.
|
|
36
|
+
*
|
|
31
37
|
* @since 0.1.0
|
|
32
38
|
* @status stable
|
|
33
39
|
* @category feedback
|
|
@@ -38,7 +44,7 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
38
44
|
* @slot actions - Actions for the message, usually a link or a button.
|
|
39
45
|
* @slot icon - Replaces the icon inside the dismiss button.
|
|
40
46
|
*
|
|
41
|
-
* @event {HelixDismissEvent} helix-dismiss - The dismiss button was pressed. The announcement does not remove itself, so remove it in response. Cancelable.
|
|
47
|
+
* @event {HelixDismissEvent} helix-dismiss - The dismiss button was pressed, or `duration` ran out. The announcement does not remove itself, so remove it in response. Cancelable.
|
|
42
48
|
*
|
|
43
49
|
* @csspart actions - The region after the message that holds the actions.
|
|
44
50
|
* @csspart content - The region that holds the message.
|
|
@@ -47,6 +53,14 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
47
53
|
* @csspart live - A copy of the message in a live region, read by screen readers when the announcement appears after the page has loaded, and emptied seven seconds later. Visually hidden in the styled tier.
|
|
48
54
|
*/
|
|
49
55
|
export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement_base {
|
|
56
|
+
/**
|
|
57
|
+
* How long the announcement stays, in milliseconds, before it sends
|
|
58
|
+
* `helix-dismiss`. When it is not set, it stays until it is dismissed.
|
|
59
|
+
*
|
|
60
|
+
* Read once when the announcement is first rendered, as `Toast` reads its
|
|
61
|
+
* own. The clock stops while the pointer or focus is on the announcement.
|
|
62
|
+
*/
|
|
63
|
+
duration?: number;
|
|
50
64
|
/**
|
|
51
65
|
* The band's color.
|
|
52
66
|
*
|
|
@@ -71,6 +85,13 @@ export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement
|
|
|
71
85
|
*/
|
|
72
86
|
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
73
87
|
protected readonly arrival: ArrivalController;
|
|
88
|
+
/** The time `duration` gives it, held while a reader is on it. */
|
|
89
|
+
private readonly countdown;
|
|
90
|
+
private readonly handleHold;
|
|
91
|
+
private readonly handleRelease;
|
|
92
|
+
connectedCallback(): void;
|
|
93
|
+
disconnectedCallback(): void;
|
|
94
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
74
95
|
protected updated(changed: PropertyValues): void;
|
|
75
96
|
/**
|
|
76
97
|
* Says on the `actions` region whether anything is in it.
|
|
@@ -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 { ArrivalController, customElement, HelixElement, MixinDismissible, markRegion, slottedWords, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ArrivalController, CountdownController, customElement, HelixElement, MixinDismissible, markRegion, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { x } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -16,6 +16,38 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
|
|
|
16
16
|
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
17
17
|
text: () => slottedWords(this, ['']),
|
|
18
18
|
});
|
|
19
|
+
this.countdown = new CountdownController(this, {
|
|
20
|
+
done: () => {
|
|
21
|
+
this.dismiss();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
this.handleHold = () => {
|
|
25
|
+
this.countdown.hold();
|
|
26
|
+
};
|
|
27
|
+
this.handleRelease = () => {
|
|
28
|
+
this.countdown.release();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
super.connectedCallback();
|
|
33
|
+
this.addEventListener('mouseenter', this.handleHold);
|
|
34
|
+
this.addEventListener('mouseleave', this.handleRelease);
|
|
35
|
+
this.addEventListener('focusin', this.handleHold);
|
|
36
|
+
this.addEventListener('focusout', this.handleRelease);
|
|
37
|
+
if (this.hasUpdated) {
|
|
38
|
+
this.countdown.resume();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
disconnectedCallback() {
|
|
42
|
+
super.disconnectedCallback();
|
|
43
|
+
this.removeEventListener('mouseenter', this.handleHold);
|
|
44
|
+
this.removeEventListener('mouseleave', this.handleRelease);
|
|
45
|
+
this.removeEventListener('focusin', this.handleHold);
|
|
46
|
+
this.removeEventListener('focusout', this.handleRelease);
|
|
47
|
+
}
|
|
48
|
+
firstUpdated(changed) {
|
|
49
|
+
super.firstUpdated(changed);
|
|
50
|
+
this.countdown.start(this.duration);
|
|
19
51
|
}
|
|
20
52
|
updated(changed) {
|
|
21
53
|
super.updated(changed);
|
|
@@ -32,7 +64,9 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
|
|
|
32
64
|
</slot>`;
|
|
33
65
|
}
|
|
34
66
|
render() {
|
|
35
|
-
return html `<div
|
|
67
|
+
return html `<div aria-hidden=${this.arrival.said === '' ? nothing : 'true'} part="content"
|
|
68
|
+
><slot @slotchange=${() => this.arrival.say()}></slot
|
|
69
|
+
></div>
|
|
36
70
|
<span part="live" role="status">${this.arrival.said}</span>
|
|
37
71
|
<div part="actions"><slot name="actions" @slotchange=${() => this.markEmpty()}></slot></div>
|
|
38
72
|
${this.dismissible
|
|
@@ -47,6 +81,9 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
|
|
|
47
81
|
: nothing}`;
|
|
48
82
|
}
|
|
49
83
|
};
|
|
84
|
+
__decorate([
|
|
85
|
+
property({ type: Number })
|
|
86
|
+
], HelixHeadlessAnnouncement.prototype, "duration", void 0);
|
|
50
87
|
__decorate([
|
|
51
88
|
property({ reflect: true })
|
|
52
89
|
], HelixHeadlessAnnouncement.prototype, "tone", void 0);
|
|
@@ -19,6 +19,15 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
19
19
|
* The page is the window unless `scroller` names the element that scrolls, for
|
|
20
20
|
* an app shell whose content scrolls inside a container.
|
|
21
21
|
*
|
|
22
|
+
* The host is the page's `banner` landmark. Placed inside `main`, `article`,
|
|
23
|
+
* `aside`, `nav` or `section`, it is a plain box instead, as a native
|
|
24
|
+
* `<header>` is there, so a header inside a card or a pane does not add a
|
|
25
|
+
* second banner. The ancestors are read as the accessibility tree reads them,
|
|
26
|
+
* through the slots that take the header in, so one slotted into a component
|
|
27
|
+
* that draws a `<nav>`, such as `Navigation`, is not a banner either. A server
|
|
28
|
+
* cannot see the ancestors, so it serves the banner and the browser corrects
|
|
29
|
+
* it when the element connects.
|
|
30
|
+
*
|
|
22
31
|
* @since 0.1.0
|
|
23
32
|
* @status stable
|
|
24
33
|
* @category navigation
|
|
@@ -64,6 +73,7 @@ export declare class HelixHeadlessAppHeader extends HelixElement {
|
|
|
64
73
|
* scrolls a container instead of the window. Unset is the window.
|
|
65
74
|
*/
|
|
66
75
|
scroller?: string;
|
|
76
|
+
private landmark;
|
|
67
77
|
private scrolled;
|
|
68
78
|
/** What scroll is listened to now, so a change of `scroller` moves it. */
|
|
69
79
|
private source;
|
|
@@ -98,6 +108,8 @@ export declare class HelixHeadlessAppHeader extends HelixElement {
|
|
|
98
108
|
private readonly handleScroll;
|
|
99
109
|
protected willUpdate(changed: PropertyValues): void;
|
|
100
110
|
connectedCallback(): void;
|
|
111
|
+
/** Whether this header is the page's banner, read from where it sits. */
|
|
112
|
+
private readLandmark;
|
|
101
113
|
disconnectedCallback(): void;
|
|
102
114
|
protected updated(changed: PropertyValues): void;
|
|
103
115
|
protected render(): TemplateResult;
|
|
@@ -7,9 +7,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { customElement, elementById, HelixElement, HelixScrolledEvent, hostAria, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { inSectioningContent } from '../sectioning.js';
|
|
10
11
|
let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
14
|
+
this.landmark = 'banner';
|
|
13
15
|
this.scrolled = false;
|
|
14
16
|
this.handleScroll = () => {
|
|
15
17
|
const source = this.source ?? window;
|
|
@@ -41,12 +43,22 @@ let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
|
|
|
41
43
|
}
|
|
42
44
|
willUpdate(changed) {
|
|
43
45
|
super.willUpdate(changed);
|
|
44
|
-
hostAria(this.internals, { role:
|
|
46
|
+
hostAria(this.internals, { role: this.landmark });
|
|
45
47
|
}
|
|
46
48
|
connectedCallback() {
|
|
47
49
|
super.connectedCallback();
|
|
50
|
+
this.readLandmark();
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
if (this.isConnected) {
|
|
53
|
+
this.readLandmark();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
48
56
|
this.listen();
|
|
49
57
|
}
|
|
58
|
+
readLandmark() {
|
|
59
|
+
this.landmark = inSectioningContent(this) ? '' : 'banner';
|
|
60
|
+
hostAria(this.internals, { role: this.landmark });
|
|
61
|
+
}
|
|
50
62
|
disconnectedCallback() {
|
|
51
63
|
super.disconnectedCallback();
|
|
52
64
|
this.source?.removeEventListener('scroll', this.handleScroll);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether an element sits inside sectioning content, read across shadow
|
|
3
|
+
* boundaries as the accessibility tree reads it: through the slot an element
|
|
4
|
+
* is assigned to, so a header slotted into a component that draws a `<nav>`
|
|
5
|
+
* around its slot, as `Navigation` does, is inside that `<nav>`.
|
|
6
|
+
*
|
|
7
|
+
* Client only: a server has no ancestors to read.
|
|
8
|
+
*/
|
|
9
|
+
export declare const inSectioningContent: (element: Element) => boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const SECTIONING = [
|
|
2
|
+
'article',
|
|
3
|
+
'aside',
|
|
4
|
+
'main',
|
|
5
|
+
'nav',
|
|
6
|
+
'section',
|
|
7
|
+
'[role="article"]',
|
|
8
|
+
'[role="complementary"]',
|
|
9
|
+
'[role="main"]',
|
|
10
|
+
'[role="navigation"]',
|
|
11
|
+
'[role="region"]',
|
|
12
|
+
].join(', ');
|
|
13
|
+
export const inSectioningContent = (element) => {
|
|
14
|
+
let node = above(element);
|
|
15
|
+
while (node) {
|
|
16
|
+
if (node.matches(SECTIONING)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
node = above(node);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const above = (element) => element.assignedSlot ?? element.parentElement ?? hostOf(element);
|
|
24
|
+
const hostOf = (element) => {
|
|
25
|
+
const root = element.getRootNode();
|
|
26
|
+
return root instanceof ShadowRoot ? root.host : null;
|
|
27
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
|
-
* The largest `max` a stylesheet
|
|
4
|
+
* The largest `max` a stylesheet folds a server's markup at.
|
|
5
5
|
*
|
|
6
|
-
* The
|
|
6
|
+
* The rule is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
|
|
7
7
|
* per value, because `An+B` takes a literal and no custom property can be read
|
|
8
|
-
* into it. So the range
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* into it. So the range a stylesheet covers is finite. The group folds any
|
|
9
|
+
* `max` itself once it runs, with the platform's `hidden`; past this one, a
|
|
10
|
+
* server's markup shows every avatar until the page hydrates.
|
|
11
11
|
*/
|
|
12
12
|
export declare const FOLDS_UP_TO = 12;
|
|
13
13
|
/**
|
|
@@ -21,9 +21,10 @@ export declare const FOLDS_UP_TO = 12;
|
|
|
21
21
|
* hidden.
|
|
22
22
|
*
|
|
23
23
|
* Avatars past `max` stay in the DOM and are hidden. The group writes `hidden`
|
|
24
|
-
* on each of them, so they are hidden on the headless tier as well, and
|
|
25
|
-
* count is read out as `overflow-label`, such as "3 more
|
|
26
|
-
*
|
|
24
|
+
* on each of them, so they are hidden on the headless tier as well, and at any
|
|
25
|
+
* `max`. The count is read out as `overflow-label`, such as "3 more: Grace
|
|
26
|
+
* Hopper, Alan Turing, Barbara Liskov", so a screen reader hears who is there
|
|
27
|
+
* past the ones it can reach.
|
|
27
28
|
*
|
|
28
29
|
* @since 0.1.0
|
|
29
30
|
* @status stable
|
|
@@ -59,10 +60,11 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
|
|
|
59
60
|
*/
|
|
60
61
|
max?: number;
|
|
61
62
|
/**
|
|
62
|
-
* What a screen reader is told the count is, with `{count}` for the number
|
|
63
|
+
* What a screen reader is told the count is, with `{count}` for the number
|
|
64
|
+
* and `{names}` for the people it stands for, by each avatar's `name`.
|
|
63
65
|
*
|
|
64
66
|
* The count shows "+3", which reads as "plus three" and says nothing about
|
|
65
|
-
* what was counted.
|
|
67
|
+
* what was counted, nor who.
|
|
66
68
|
*/
|
|
67
69
|
overflowLabel: string;
|
|
68
70
|
/** The avatars this group hid, so it unhides only those. */
|
|
@@ -78,8 +80,6 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
|
|
|
78
80
|
* the attribute that hides the whole group.
|
|
79
81
|
*/
|
|
80
82
|
get overflow(): number;
|
|
81
|
-
/** Said once per element, because a re-render is not a second mistake. */
|
|
82
|
-
private warned;
|
|
83
83
|
protected willUpdate(changed: PropertyValues): void;
|
|
84
84
|
protected firstUpdated(changed: PropertyValues): void;
|
|
85
85
|
protected updated(changed: PropertyValues): void;
|
|
@@ -89,10 +89,16 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
|
|
|
89
89
|
* **State in markup, so the headless tier folds too.** The fold was a styled
|
|
90
90
|
* rule alone, and on the headless tier every avatar was drawn beside a "+3".
|
|
91
91
|
* The styled rule stays, because it is what folds a server's markup before
|
|
92
|
-
* this runs
|
|
93
|
-
*
|
|
92
|
+
* this runs, up to `FOLDS_UP_TO`, and this folds at any `max`. Written
|
|
93
|
+
* through `whenHydrated`, so an avatar's hydrating render is the server's,
|
|
94
|
+
* and undone only on the avatars this group hid.
|
|
94
95
|
*/
|
|
95
96
|
private fold;
|
|
97
|
+
/**
|
|
98
|
+
* The names of the people past `max`, by each avatar's `name`, then its
|
|
99
|
+
* `aria-label`, in the order they are read.
|
|
100
|
+
*/
|
|
101
|
+
private foldedNames;
|
|
96
102
|
protected render(): TemplateResult;
|
|
97
103
|
}
|
|
98
104
|
declare global {
|