@fusion.dev/helix-headless 0.144.0 → 0.145.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +8312 -881
- package/dist/accordion/item/accordion-item.d.ts +48 -12
- package/dist/accordion/item/accordion-item.js +26 -5
- package/dist/accordion/root/accordion-root.d.ts +6 -0
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +21 -1
- package/dist/announcement/root/announcement-root.js +36 -1
- package/dist/app-header/root/app-header-root.d.ts +7 -0
- package/dist/app-header/root/app-header-root.js +5 -1
- package/dist/app-header/sectioning.d.ts +7 -0
- package/dist/app-header/sectioning.js +26 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +121 -40
- package/dist/carousel/root/carousel-root.d.ts +90 -0
- package/dist/carousel/root/carousel-root.js +134 -12
- package/dist/chat/composer/chat-composer.d.ts +38 -6
- package/dist/chat/composer/chat-composer.js +42 -9
- package/dist/chat/message/chat-message.d.ts +32 -1
- package/dist/chat/message/chat-message.js +25 -9
- package/dist/chat/naming.d.ts +22 -0
- package/dist/chat/naming.js +12 -0
- package/dist/chat/relative-clock.d.ts +39 -0
- package/dist/chat/relative-clock.js +31 -0
- package/dist/chat/root/chat-root.d.ts +36 -0
- package/dist/chat/root/chat-root.js +24 -1
- package/dist/code-block/root/code-block-root.d.ts +8 -1
- package/dist/code-block/root/code-block-root.js +5 -5
- package/dist/copy-button/root/copy-button-root.d.ts +21 -1
- package/dist/copy-button/root/copy-button-root.js +2 -2
- package/dist/data-table/root/data-table-root.d.ts +150 -2
- package/dist/data-table/root/data-table-root.js +303 -29
- package/dist/data-table/tree.d.ts +40 -0
- package/dist/data-table/tree.js +55 -0
- package/dist/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/drilldown/item/drilldown-item.d.ts +11 -6
- package/dist/drilldown/item/drilldown-item.js +8 -5
- package/dist/drilldown/root/drilldown-root.d.ts +11 -0
- package/dist/drilldown/root/drilldown-root.js +8 -3
- package/dist/element-events.generated.js +53 -8
- package/dist/filter-input/menu/filter-menu.d.ts +3 -0
- package/dist/filter-input/menu/filter-menu.js +8 -4
- package/dist/image/root/image-root.js +9 -1
- package/dist/input/root/input-root.d.ts +1 -1
- package/dist/input/root/input-root.js +2 -2
- package/dist/list/item/list-item.d.ts +68 -1
- package/dist/list/item/list-item.js +66 -4
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +106 -9
- package/dist/list/root/list-root.js +189 -4
- package/dist/list/selection.d.ts +19 -0
- package/dist/list/selection.js +21 -0
- package/dist/listbox/root/listbox-root.js +1 -2
- package/dist/map/root/map-root.d.ts +6 -2
- package/dist/map/root/map-root.js +5 -2
- package/dist/megamenu/root/megamenu-root.d.ts +21 -0
- package/dist/megamenu/root/megamenu-root.js +16 -2
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +38 -11
- package/dist/menu/item/menu-item.js +33 -1
- package/dist/menu/root/menu-root.d.ts +25 -1
- package/dist/menu/root/menu-root.js +63 -6
- package/dist/menu/section/menu-section.d.ts +55 -0
- package/dist/menu/section/menu-section.js +60 -0
- package/dist/navigation/root/navigation-root.d.ts +16 -1
- package/dist/navigation/root/navigation-root.js +27 -1
- package/dist/notifications/root/notifications-root.d.ts +18 -0
- package/dist/notifications/root/notifications-root.js +17 -1
- package/dist/object-inspector/root/object-inspector-root.d.ts +97 -16
- package/dist/object-inspector/root/object-inspector-root.js +179 -79
- package/dist/object-inspector/rows.d.ts +57 -0
- package/dist/object-inspector/rows.js +86 -0
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +68 -3
- package/dist/outline/root/outline-root.js +73 -8
- package/dist/pagination/size/pagination-size.d.ts +11 -2
- package/dist/pagination/size/pagination-size.js +19 -4
- package/dist/radio/group/radio-group.d.ts +4 -10
- package/dist/radio/group/radio-group.js +5 -10
- package/dist/rating/root/rating-root.d.ts +1 -1
- package/dist/rating/root/rating-root.js +2 -2
- package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
- package/dist/scroll-area/root/scroll-area-root.js +218 -3
- package/dist/scroll-area/scrollbar.d.ts +65 -0
- package/dist/scroll-area/scrollbar.js +24 -0
- package/dist/select/root/select-root.js +1 -1
- package/dist/splitter/root/splitter-root.d.ts +13 -0
- package/dist/splitter/root/splitter-root.js +20 -2
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/steps/reach.d.ts +15 -0
- package/dist/steps/reach.js +12 -0
- package/dist/steps/root/steps-root.d.ts +30 -0
- package/dist/steps/root/steps-root.js +53 -0
- package/dist/steps/step/step.d.ts +38 -2
- package/dist/steps/step/step.js +28 -6
- package/dist/table/column/table-column.d.ts +11 -0
- package/dist/table/column/table-column.js +6 -1
- package/dist/table/root/table-root.d.ts +101 -0
- package/dist/table/root/table-root.js +166 -5
- package/dist/table/row/table-row.d.ts +47 -1
- package/dist/table/row/table-row.js +39 -2
- package/dist/tabs/panel/tab-panel.d.ts +9 -5
- package/dist/tabs/panel/tab-panel.js +3 -4
- package/dist/tabs/root/tabs-root.d.ts +25 -1
- package/dist/tabs/root/tabs-root.js +21 -3
- package/dist/tabs/tab/tab.d.ts +36 -4
- package/dist/tabs/tab/tab.js +46 -3
- package/dist/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 +10 -17
- package/dist/toast/item/toast-item.js +15 -36
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- package/dist/tree/item/tree-item.d.ts +54 -1
- package/dist/tree/item/tree-item.js +89 -20
- package/dist/tree/root/tree-root.d.ts +37 -0
- package/dist/tree/root/tree-root.js +51 -6
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +26 -0
- package/dist/video/media-events.d.ts +49 -0
- package/dist/video/media-events.js +39 -0
- package/dist/video/root/video-root.d.ts +99 -13
- package/dist/video/root/video-root.js +84 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
- package/dist/video-playlist/root/video-playlist-root.js +60 -16
- package/dist/virtual-list/controls.d.ts +4 -0
- package/dist/virtual-list/controls.js +30 -0
- package/dist/virtual-list/fill.d.ts +30 -0
- package/dist/virtual-list/fill.js +39 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
- package/dist/virtual-list/root/virtual-list-root.js +175 -34
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +3778 -801
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +782 -215
- package/dist/listbox/range.d.ts +0 -17
- package/dist/listbox/range.js +0 -5
|
@@ -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,18 @@ 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
|
+
* Set `hidden-until-found` and the browser's find in page searches a closed
|
|
22
|
+
* section too: a match opens it, with `helix-before-open` first, as React
|
|
23
|
+
* Aria's disclosure does. The content is then `hidden="until-found"` while
|
|
24
|
+
* closed, and not `inert`, since an inert region is never searched.
|
|
25
|
+
*
|
|
21
26
|
* @since 0.1.0
|
|
22
27
|
* @status stable
|
|
23
28
|
* @aliases Collapsible, Expander, Disclosure
|
|
24
29
|
* @documentation https://fusion.dev/helix/components/accordion
|
|
25
30
|
*
|
|
26
31
|
* @slot - The content shown when the section is open.
|
|
32
|
+
* @slot chevron - Replaces the open and close indicator, such as with your own icon.
|
|
27
33
|
* @slot summary - The text of the button that opens and closes the section. Always shown.
|
|
28
34
|
*
|
|
29
35
|
* @event {HelixBeforeCloseEvent} helix-before-close - The section is about to close. Cancelable: cancel it to keep it open.
|
|
@@ -51,8 +57,13 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
51
57
|
* have two.
|
|
52
58
|
*/
|
|
53
59
|
chevronPlacement?: 'auto' | 'start' | 'end' | 'none';
|
|
54
|
-
/**
|
|
55
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The chevron, or nothing when suppressed.
|
|
62
|
+
*
|
|
63
|
+
* The drawn chevron is the `chevron` slot's fallback, so an icon of your own
|
|
64
|
+
* replaces it by being slotted, and a tier drawing its own overrides this.
|
|
65
|
+
*/
|
|
66
|
+
protected renderChevron(): TemplateResult | typeof nothing;
|
|
56
67
|
/**
|
|
57
68
|
* Whether the section is disabled, so its trigger cannot be pressed or
|
|
58
69
|
* reached with the arrow keys. A script can still open and close it.
|
|
@@ -64,6 +75,11 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
64
75
|
* causes a hydration mismatch.
|
|
65
76
|
*/
|
|
66
77
|
groupHeadingLevel: number | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* @internal The accordion's `hidden-until-found`, written by the accordion,
|
|
80
|
+
* for the reason `groupHeadingLevel` is a property.
|
|
81
|
+
*/
|
|
82
|
+
groupHiddenUntilFound: boolean;
|
|
67
83
|
/**
|
|
68
84
|
* The level of the heading around the trigger, from 1 to 6.
|
|
69
85
|
*
|
|
@@ -71,6 +87,16 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
71
87
|
* too.
|
|
72
88
|
*/
|
|
73
89
|
headingLevel?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Whether find in page searches the section while it is closed, and opens it
|
|
92
|
+
* on a match.
|
|
93
|
+
*
|
|
94
|
+
* Off by default. A closed section is then `hidden="until-found"`, which
|
|
95
|
+
* hides through `content-visibility`, so a stylesheet that animates the
|
|
96
|
+
* section closed shows an empty box for the length of that animation. The
|
|
97
|
+
* accordion's own `hidden-until-found` turns it on for every section.
|
|
98
|
+
*/
|
|
99
|
+
hiddenUntilFound: boolean;
|
|
74
100
|
/**
|
|
75
101
|
* A group name. Opening an item closes the other items with the same name,
|
|
76
102
|
* as `<details name>` does.
|
|
@@ -92,6 +118,15 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
92
118
|
* absence. Caught by `hydration.dom.spec.ts`.
|
|
93
119
|
*/
|
|
94
120
|
name?: string;
|
|
121
|
+
/** Whether find in page searches this section while it is closed. */
|
|
122
|
+
private get findable();
|
|
123
|
+
/**
|
|
124
|
+
* Opens the section find in page has matched in, before the match is shown.
|
|
125
|
+
*
|
|
126
|
+
* The browser removes `hidden` itself. A refusal puts it back, so the trigger
|
|
127
|
+
* and the region still agree.
|
|
128
|
+
*/
|
|
129
|
+
private readonly handleBeforeMatch;
|
|
95
130
|
/** Whether the item was open at the last update, and `undefined` before one. */
|
|
96
131
|
private wasOpen;
|
|
97
132
|
/**
|
|
@@ -157,16 +192,17 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
|
|
|
157
192
|
* part outranks it and the transition runs exactly as before. Measured on
|
|
158
193
|
* both tiers.
|
|
159
194
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* trigger still reports collapsed.
|
|
195
|
+
* **`hidden="until-found"` only where it was asked for.** It hides through
|
|
196
|
+
* `content-visibility` rather than `display`, which an author `display` does
|
|
197
|
+
* not override, so a section a sheet animates closed shows an empty box while
|
|
198
|
+
* it shrinks. `beforematch` sets `open`, so find in page never reveals text
|
|
199
|
+
* under a trigger that still reports collapsed.
|
|
166
200
|
*
|
|
167
|
-
* `inert` stays
|
|
168
|
-
* the one tabbing through, and wherever a sheet
|
|
169
|
-
* is the only one of the two still in force.
|
|
201
|
+
* `inert` stays, except under `until-found`. `hidden` answers the reader who
|
|
202
|
+
* can see and `inert` answers the one tabbing through, and wherever a sheet
|
|
203
|
+
* overrides `display`, `inert` is the only one of the two still in force.
|
|
204
|
+
* `content-visibility: hidden` keeps skipped content out of the tab order and
|
|
205
|
+
* the accessibility tree by itself, and an inert region is never searched.
|
|
170
206
|
*/
|
|
171
207
|
protected render(): TemplateResult;
|
|
172
208
|
}
|
|
@@ -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) {
|
|
@@ -39,9 +48,14 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
39
48
|
if (this.chevronPlacement === 'none') {
|
|
40
49
|
return nothing;
|
|
41
50
|
}
|
|
42
|
-
return html `<
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
return html `<slot name="chevron"
|
|
52
|
+
><svg part="chevron" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
|
|
53
|
+
${unsafeSVG(caretDown.content)}
|
|
54
|
+
</svg></slot
|
|
55
|
+
>`;
|
|
56
|
+
}
|
|
57
|
+
get findable() {
|
|
58
|
+
return this.hiddenUntilFound || this.groupHiddenUntilFound;
|
|
45
59
|
}
|
|
46
60
|
get accordion() {
|
|
47
61
|
return closestInstance(this, HelixHeadlessAccordion);
|
|
@@ -103,9 +117,10 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
|
|
|
103
117
|
id=${CONTENT_ID}
|
|
104
118
|
aria-labelledby=${TRIGGER_ID}
|
|
105
119
|
part="content"
|
|
106
|
-
|
|
107
|
-
?inert=${!open}
|
|
120
|
+
hidden=${open ? nothing : this.findable ? 'until-found' : ''}
|
|
121
|
+
?inert=${!open && !this.findable}
|
|
108
122
|
role="region"
|
|
123
|
+
@beforematch=${this.handleBeforeMatch}
|
|
109
124
|
>
|
|
110
125
|
<div part="content-inner">
|
|
111
126
|
<slot></slot>
|
|
@@ -124,9 +139,15 @@ __decorate([
|
|
|
124
139
|
__decorate([
|
|
125
140
|
property({ attribute: false })
|
|
126
141
|
], HelixHeadlessAccordionItem.prototype, "groupHeadingLevel", void 0);
|
|
142
|
+
__decorate([
|
|
143
|
+
property({ attribute: false })
|
|
144
|
+
], HelixHeadlessAccordionItem.prototype, "groupHiddenUntilFound", void 0);
|
|
127
145
|
__decorate([
|
|
128
146
|
property({ attribute: 'heading-level', type: Number })
|
|
129
147
|
], HelixHeadlessAccordionItem.prototype, "headingLevel", void 0);
|
|
148
|
+
__decorate([
|
|
149
|
+
property({ attribute: 'hidden-until-found', type: Boolean })
|
|
150
|
+
], HelixHeadlessAccordionItem.prototype, "hiddenUntilFound", void 0);
|
|
130
151
|
__decorate([
|
|
131
152
|
property({ reflect: true })
|
|
132
153
|
], HelixHeadlessAccordionItem.prototype, "name", void 0);
|
|
@@ -39,6 +39,12 @@ export declare class HelixHeadlessAccordion extends HelixElement {
|
|
|
39
39
|
* Unset is 3. An item's own `heading-level` wins over this.
|
|
40
40
|
*/
|
|
41
41
|
headingLevel?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Whether find in page searches every closed section, and opens the one it
|
|
44
|
+
* matches in. Each item's own `hidden-until-found` turns it on for that item
|
|
45
|
+
* alone.
|
|
46
|
+
*/
|
|
47
|
+
hiddenUntilFound: boolean;
|
|
42
48
|
/**
|
|
43
49
|
* How many sections may be open at once.
|
|
44
50
|
*
|
|
@@ -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);
|
|
@@ -28,6 +28,11 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
28
28
|
* announcement beside it, move focus yourself, for example to the page's main
|
|
29
29
|
* heading.
|
|
30
30
|
*
|
|
31
|
+
* Set `duration` to dismiss it after a time. The clock stops while the pointer
|
|
32
|
+
* or focus is on the announcement, and continues from what was left, so a
|
|
33
|
+
* reader partway through is not cut off. When the time runs out it sends
|
|
34
|
+
* `helix-dismiss`, as the button does.
|
|
35
|
+
*
|
|
31
36
|
* @since 0.1.0
|
|
32
37
|
* @status stable
|
|
33
38
|
* @category feedback
|
|
@@ -38,7 +43,7 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
38
43
|
* @slot actions - Actions for the message, usually a link or a button.
|
|
39
44
|
* @slot icon - Replaces the icon inside the dismiss button.
|
|
40
45
|
*
|
|
41
|
-
* @event {HelixDismissEvent} helix-dismiss - The dismiss button was pressed. The announcement does not remove itself, so remove it in response. Cancelable.
|
|
46
|
+
* @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
47
|
*
|
|
43
48
|
* @csspart actions - The region after the message that holds the actions.
|
|
44
49
|
* @csspart content - The region that holds the message.
|
|
@@ -47,6 +52,14 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
|
|
|
47
52
|
* @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
53
|
*/
|
|
49
54
|
export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement_base {
|
|
55
|
+
/**
|
|
56
|
+
* How long the announcement stays, in milliseconds, before it sends
|
|
57
|
+
* `helix-dismiss`. When it is not set, it stays until it is dismissed.
|
|
58
|
+
*
|
|
59
|
+
* Read once when the announcement is first rendered, as `Toast` reads its
|
|
60
|
+
* own. The clock stops while the pointer or focus is on the announcement.
|
|
61
|
+
*/
|
|
62
|
+
duration?: number;
|
|
50
63
|
/**
|
|
51
64
|
* The band's color.
|
|
52
65
|
*
|
|
@@ -71,6 +84,13 @@ export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement
|
|
|
71
84
|
*/
|
|
72
85
|
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
73
86
|
protected readonly arrival: ArrivalController;
|
|
87
|
+
/** The time `duration` gives it, held while a reader is on it. */
|
|
88
|
+
private readonly countdown;
|
|
89
|
+
private readonly handleHold;
|
|
90
|
+
private readonly handleRelease;
|
|
91
|
+
connectedCallback(): void;
|
|
92
|
+
disconnectedCallback(): void;
|
|
93
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
74
94
|
protected updated(changed: PropertyValues): void;
|
|
75
95
|
/**
|
|
76
96
|
* 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);
|
|
@@ -47,6 +79,9 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
|
|
|
47
79
|
: nothing}`;
|
|
48
80
|
}
|
|
49
81
|
};
|
|
82
|
+
__decorate([
|
|
83
|
+
property({ type: Number })
|
|
84
|
+
], HelixHeadlessAnnouncement.prototype, "duration", void 0);
|
|
50
85
|
__decorate([
|
|
51
86
|
property({ reflect: true })
|
|
52
87
|
], HelixHeadlessAnnouncement.prototype, "tone", void 0);
|
|
@@ -19,6 +19,12 @@ 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. A server cannot see the ancestors, so it serves the banner and
|
|
26
|
+
* the browser corrects it when the element connects.
|
|
27
|
+
*
|
|
22
28
|
* @since 0.1.0
|
|
23
29
|
* @status stable
|
|
24
30
|
* @category navigation
|
|
@@ -64,6 +70,7 @@ export declare class HelixHeadlessAppHeader extends HelixElement {
|
|
|
64
70
|
* scrolls a container instead of the window. Unset is the window.
|
|
65
71
|
*/
|
|
66
72
|
scroller?: string;
|
|
73
|
+
private landmark;
|
|
67
74
|
private scrolled;
|
|
68
75
|
/** What scroll is listened to now, so a change of `scroller` moves it. */
|
|
69
76
|
private source;
|
|
@@ -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,10 +43,12 @@ 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.landmark = inSectioningContent(this) ? '' : 'banner';
|
|
51
|
+
hostAria(this.internals, { role: this.landmark });
|
|
48
52
|
this.listen();
|
|
49
53
|
}
|
|
50
54
|
disconnectedCallback() {
|
|
@@ -0,0 +1,26 @@
|
|
|
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 = element.parentElement ?? hostOf(element);
|
|
15
|
+
while (node) {
|
|
16
|
+
if (node.matches(SECTIONING)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
node = node.parentElement ?? hostOf(node);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const hostOf = (element) => {
|
|
24
|
+
const root = element.getRootNode();
|
|
25
|
+
return root instanceof ShadowRoot ? root.host : null;
|
|
26
|
+
};
|
|
@@ -1,5 +1,17 @@
|
|
|
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
|
+
import '../breadcrumb/breadcrumb.js';
|
|
4
|
+
/** One step of a trail written as data, for `items`. */
|
|
5
|
+
export interface BreadcrumbItem {
|
|
6
|
+
/** The URL the step links to. The last step is the current page and takes none. */
|
|
7
|
+
href?: string;
|
|
8
|
+
/** The step's words. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** The link's `rel`. */
|
|
11
|
+
rel?: string;
|
|
12
|
+
/** Where the link opens. */
|
|
13
|
+
target?: string;
|
|
14
|
+
}
|
|
3
15
|
/**
|
|
4
16
|
* @summary Shows the path to the current page.
|
|
5
17
|
*
|
|
@@ -19,6 +31,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
19
31
|
* The trail does not measure itself, and you write its overflow in markup: put
|
|
20
32
|
* the crumb that holds the folded items where the gap should appear.
|
|
21
33
|
*
|
|
34
|
+
* A trail built from data, such as a router's matched routes, takes `items`: an
|
|
35
|
+
* array of `{ label, href }`, drawn as crumbs in order, the last one as the
|
|
36
|
+
* current page. Slotted crumbs follow them. Use one way or the other in a trail.
|
|
37
|
+
*
|
|
22
38
|
* @since 0.1.0
|
|
23
39
|
* @status stable
|
|
24
40
|
* @category navigation
|
|
@@ -28,15 +44,30 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
28
44
|
* @slot - The trail's items, in order from the root to the current page. Put
|
|
29
45
|
* the crumb that holds the folded items where the gap should appear.
|
|
30
46
|
*
|
|
47
|
+
* @csspart crumb - Each crumb drawn from `items`.
|
|
48
|
+
* @csspart crumb-current - The crumb drawn from `items` for the current page.
|
|
49
|
+
* @csspart crumb-link - The link, or the current page's words, of a crumb drawn from `items`.
|
|
50
|
+
* @csspart crumb-separator - The separator before a crumb drawn from `items`.
|
|
51
|
+
* @csspart crumb-separator-mark - The chevron before a crumb drawn from `items`.
|
|
31
52
|
* @csspart list - The ordered list.
|
|
32
53
|
*/
|
|
33
54
|
export declare class HelixHeadlessBreadcrumbs extends HelixElement {
|
|
55
|
+
/**
|
|
56
|
+
* The trail as data, drawn as crumbs before any you slot. The last item is the
|
|
57
|
+
* current page.
|
|
58
|
+
*
|
|
59
|
+
* React Aria's `items`. A property only: a trail is built by script, and an
|
|
60
|
+
* attribute would put the whole path into the markup twice.
|
|
61
|
+
*/
|
|
62
|
+
items: BreadcrumbItem[];
|
|
34
63
|
/**
|
|
35
64
|
* The landmark's name, read by screen readers. An `aria-label` on the host
|
|
36
65
|
* wins over it.
|
|
37
66
|
*/
|
|
38
67
|
label: string;
|
|
39
68
|
protected willUpdate(changed: PropertyValues): void;
|
|
69
|
+
/** The crumbs `items` describes, each a crumb of this tier. */
|
|
70
|
+
protected renderItems(): TemplateResult | typeof nothing;
|
|
40
71
|
protected render(): TemplateResult;
|
|
41
72
|
}
|
|
42
73
|
declare global {
|
|
@@ -5,23 +5,46 @@ 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
|
import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
-
import {
|
|
8
|
+
import { nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
11
|
+
import { html } from 'lit/static-html.js';
|
|
12
|
+
import '../breadcrumb/breadcrumb.js';
|
|
10
13
|
let HelixHeadlessBreadcrumbs = class HelixHeadlessBreadcrumbs extends HelixElement {
|
|
11
14
|
constructor() {
|
|
12
15
|
super(...arguments);
|
|
16
|
+
this.items = [];
|
|
13
17
|
this.label = 'Breadcrumb';
|
|
14
18
|
}
|
|
15
19
|
willUpdate(changed) {
|
|
16
20
|
super.willUpdate(changed);
|
|
17
21
|
hostAria(this.internals, { label: this.label, role: 'navigation' });
|
|
18
22
|
}
|
|
23
|
+
renderItems() {
|
|
24
|
+
if (this.items.length === 0) {
|
|
25
|
+
return nothing;
|
|
26
|
+
}
|
|
27
|
+
const crumb = this.tag('breadcrumb');
|
|
28
|
+
const last = this.items.length - 1;
|
|
29
|
+
return html `${repeat(this.items, (item, index) => html `<${crumb}
|
|
30
|
+
part="crumb${index === last ? ' crumb-current' : ''}"
|
|
31
|
+
exportparts="link: crumb-link, separator: crumb-separator, separator-mark: crumb-separator-mark"
|
|
32
|
+
href=${index === last ? nothing : (item.href ?? nothing)}
|
|
33
|
+
rel=${item.rel ?? nothing}
|
|
34
|
+
target=${item.target ?? nothing}
|
|
35
|
+
?current=${index === last}
|
|
36
|
+
>${item.label}</${crumb}
|
|
37
|
+
>`)}`;
|
|
38
|
+
}
|
|
19
39
|
render() {
|
|
20
40
|
return html `<ol part="list" role="list">
|
|
21
|
-
<slot></slot>
|
|
41
|
+
${this.renderItems()}<slot></slot>
|
|
22
42
|
</ol>`;
|
|
23
43
|
}
|
|
24
44
|
};
|
|
45
|
+
__decorate([
|
|
46
|
+
property({ attribute: false })
|
|
47
|
+
], HelixHeadlessBreadcrumbs.prototype, "items", void 0);
|
|
25
48
|
__decorate([
|
|
26
49
|
property()
|
|
27
50
|
], HelixHeadlessBreadcrumbs.prototype, "label", void 0);
|
|
@@ -98,7 +98,7 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
|
|
|
98
98
|
* @csspart edge - One connector between two cards.
|
|
99
99
|
* @csspart edge-end - An end of a selected connection. Drag it, or click it to pick it up.
|
|
100
100
|
* @csspart edge-target - A wider, invisible line over a connection, which receives focus and presses.
|
|
101
|
-
* @csspart edges -
|
|
101
|
+
* @csspart edges - A layer the connectors are drawn in: one holding the arrowhead, and one after each card holding the connections leaving it, so they are read in the order the arrows walk them. Give it `z-index: -1` to draw it under the cards.
|
|
102
102
|
* @csspart footer - The strip below the board.
|
|
103
103
|
* @csspart fullscreen - The button that makes the board fill the screen.
|
|
104
104
|
* @csspart gesture-hint - Words over the board for a moment when it lets a gesture pass to the page, such as how to zoom it.
|
|
@@ -128,6 +128,10 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
|
|
|
128
128
|
* @cssstate using - A board with `gestures="activate"` has been pressed and has the gestures.
|
|
129
129
|
*/
|
|
130
130
|
export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
|
|
131
|
+
/** The connection whose target had focus as an update began, and that target. */
|
|
132
|
+
private focusedEdge;
|
|
133
|
+
/** Each card is assigned to its own slot, in the order the arrows walk them. */
|
|
134
|
+
static shadowRootOptions: ShadowRootInit;
|
|
131
135
|
/** The text read with a card to say where its connections come from, with `{cards}`. */
|
|
132
136
|
comesFromLabel: string;
|
|
133
137
|
/** The text announced when a connection is requested, with `{from}` and `{to}`. */
|
|
@@ -951,16 +955,47 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
|
|
|
951
955
|
*/
|
|
952
956
|
private renderEnds;
|
|
953
957
|
/**
|
|
954
|
-
* The
|
|
958
|
+
* The layer that holds the arrowhead and the connection being drawn.
|
|
955
959
|
*
|
|
956
960
|
* **The arrowhead is measured in the board's own units, not in multiples of
|
|
957
961
|
* the line's width.** `markerUnits="strokeWidth"` multiplies by the stroke, so
|
|
958
962
|
* an eight-unit head on a two-pixel line drew a sixteen-pixel triangle that
|
|
959
963
|
* read as a shape of its own rather than as a direction. In user space it is
|
|
960
964
|
* eight units of the document, which is what the cards are measured in, and it
|
|
961
|
-
* grows with the zoom like everything else.
|
|
965
|
+
* grows with the zoom like everything else. Each card's connections reach it
|
|
966
|
+
* by its id, which every layer in this shadow root shares.
|
|
962
967
|
*/
|
|
963
968
|
private renderEdges;
|
|
969
|
+
/**
|
|
970
|
+
* Each card, and then the connections leaving it, in the order the arrows
|
|
971
|
+
* walk them.
|
|
972
|
+
*
|
|
973
|
+
* **The order is the accessibility tree's.** The connections were one layer
|
|
974
|
+
* drawn before every card, so a screen reader's reading went through every
|
|
975
|
+
* connection and then every card, while the arrow keys went card by card
|
|
976
|
+
* with each card's connections after it. Each card now has a slot of its
|
|
977
|
+
* own, assigned by hand, with its connections' layer straight after it, so
|
|
978
|
+
* both orders are the walk. The cards are read before hydration, which
|
|
979
|
+
* knows none, from the default slot after these, as they always were.
|
|
980
|
+
*
|
|
981
|
+
* **Every layer sits under the cards by its stacking.** A layer after a card
|
|
982
|
+
* in the tree would otherwise paint over it, so the styled sheet sets
|
|
983
|
+
* `--helix-layer-beneath` on `edges`, and a headless page sets `z-index: -1`.
|
|
984
|
+
*/
|
|
985
|
+
private renderStops;
|
|
986
|
+
/** One connector: the target that takes focus and presses, and the line it paints. */
|
|
987
|
+
private renderEdge;
|
|
988
|
+
/**
|
|
989
|
+
* Sends each card to its slot, and everything else to the slot it names.
|
|
990
|
+
*
|
|
991
|
+
* A root that assigns by hand routes nothing by itself, the named slots
|
|
992
|
+
* included, so the header, the footer and the empty state are assigned here
|
|
993
|
+
* too. Paired with the walk by position, as the template was built, and a
|
|
994
|
+
* card the walk does not reach, a second one of the same name, goes to the
|
|
995
|
+
* default slot with everything else. On a root a server sent, which routes
|
|
996
|
+
* by name, each card is sent to its slot by name instead.
|
|
997
|
+
*/
|
|
998
|
+
private assign;
|
|
964
999
|
/**
|
|
965
1000
|
* The connections' labels, as text on the plane over the lines.
|
|
966
1001
|
*
|