@fusion.dev/helix-headless 0.155.0 → 0.157.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 +2695 -137
- package/dist/canvas/node/canvas-node.js +1 -1
- package/dist/canvas/root/canvas-root.d.ts +17 -2
- package/dist/canvas/root/canvas-root.js +23 -6
- package/dist/chat/composer/chat-composer.js +1 -1
- package/dist/chat/root/chat-root.d.ts +14 -1
- package/dist/chat/root/chat-root.js +14 -4
- package/dist/combobox/root/combobox-root.d.ts +10 -0
- package/dist/combobox/root/combobox-root.js +18 -3
- package/dist/command/root/command-root.d.ts +116 -1
- package/dist/command/root/command-root.js +124 -15
- package/dist/data-table/root/data-table-root.d.ts +25 -0
- package/dist/data-table/root/data-table-root.js +13 -3
- package/dist/date-input/root/date-input-root.d.ts +32 -1
- package/dist/date-input/root/date-input-root.js +7 -1
- package/dist/drilldown/item/drilldown-item.d.ts +49 -1
- package/dist/drilldown/item/drilldown-item.js +77 -17
- package/dist/drilldown/root/drilldown-root.d.ts +45 -5
- package/dist/drilldown/root/drilldown-root.js +51 -5
- package/dist/element-events.generated.js +2 -1
- package/dist/filter-input/menu/filter-menu.d.ts +1 -0
- package/dist/filter-input/menu/filter-menu.js +4 -4
- package/dist/graph/root/graph-root.d.ts +13 -0
- package/dist/graph/root/graph-root.js +16 -0
- package/dist/list/root/list-root.d.ts +74 -1
- package/dist/list/root/list-root.js +92 -4
- package/dist/list/selection.js +3 -3
- package/dist/map/root/map-root.d.ts +6 -0
- package/dist/map/root/map-root.js +8 -1
- package/dist/megamenu/root/megamenu-root.d.ts +50 -13
- package/dist/megamenu/root/megamenu-root.js +44 -6
- package/dist/menu/item/menu-item.d.ts +24 -1
- package/dist/menu/item/menu-item.js +42 -2
- package/dist/menu/root/menu-root.d.ts +120 -9
- package/dist/menu/root/menu-root.js +329 -26
- package/dist/notifications/root/notifications-root.d.ts +20 -0
- package/dist/notifications/root/notifications-root.js +32 -1
- package/dist/number-input/root/number-input-root.d.ts +63 -6
- package/dist/number-input/root/number-input-root.js +96 -11
- package/dist/object-inspector/root/object-inspector-root.d.ts +36 -1
- package/dist/object-inspector/root/object-inspector-root.js +26 -2
- package/dist/option/root/option-root.d.ts +32 -0
- package/dist/option/root/option-root.js +44 -5
- package/dist/outline/root/outline-root.d.ts +6 -2
- package/dist/outline/root/outline-root.js +7 -3
- package/dist/table/root/table-root.d.ts +20 -0
- package/dist/table/root/table-root.js +13 -3
- package/dist/time-input/root/time-input-root.d.ts +32 -1
- package/dist/time-input/root/time-input-root.js +9 -2
- package/dist/time-picker/root/time-picker-root.d.ts +63 -1
- package/dist/time-picker/root/time-picker-root.js +58 -7
- package/dist/timeline/item/timeline-item.d.ts +25 -0
- package/dist/timeline/item/timeline-item.js +27 -2
- package/dist/toast/item/toast-item.d.ts +26 -0
- package/dist/toast/item/toast-item.js +55 -3
- package/dist/toast/root/toast-root.d.ts +32 -0
- package/dist/toast/root/toast-root.js +47 -2
- package/dist/video/root/keys.d.ts +6 -2
- package/dist/video/root/keys.js +18 -1
- package/dist/video/root/video-root.d.ts +61 -1
- package/dist/video/root/video-root.js +79 -11
- package/dist/video-playlist/item/video-playlist-item.d.ts +15 -1
- package/dist/video-playlist/item/video-playlist-item.js +7 -0
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +1 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +1 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +43 -4
- package/dist/video-playlist/root/video-playlist-root.js +69 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +8 -0
- package/dist/virtual-list/root/virtual-list-root.js +3 -0
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +3346 -266
- package/types/vue.d.ts +910 -66
- package/types/words.d.ts +124 -0
|
@@ -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, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, slotNamed, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { auditName, customElement, deepActiveElement, HelixElement, HelixSelectEvent, hostAria, slotFilled, slotNamed, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -13,11 +13,16 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
15
|
this.disabled = false;
|
|
16
|
+
this.download = false;
|
|
16
17
|
this.focusable = false;
|
|
18
|
+
this.href = '';
|
|
19
|
+
this.listed = false;
|
|
17
20
|
this.isDrilldownItem = true;
|
|
18
21
|
this.onPage = true;
|
|
19
22
|
this.onPath = false;
|
|
23
|
+
this.rel = '';
|
|
20
24
|
this.showingPage = false;
|
|
25
|
+
this.target = '';
|
|
21
26
|
this.value = '';
|
|
22
27
|
this.page = false;
|
|
23
28
|
this.description = false;
|
|
@@ -30,9 +35,23 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
30
35
|
this.description = slotFilled(slotNamed(this.renderRoot, 'description'));
|
|
31
36
|
this.end = slotFilled(slotNamed(this.renderRoot, 'end'));
|
|
32
37
|
};
|
|
38
|
+
this.handleClick = (event) => {
|
|
39
|
+
if (!this.choose() && this.linked) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
this.handleLinkKeydown = (event) => {
|
|
44
|
+
if (event.key !== ' ') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
event.currentTarget.click();
|
|
49
|
+
};
|
|
33
50
|
}
|
|
34
51
|
willUpdate(changed) {
|
|
35
52
|
super.willUpdate(changed);
|
|
53
|
+
const item = this.listed && this.onPage && !this.showingPage && !this.onPath;
|
|
54
|
+
hostAria(this.internals, { role: item ? 'listitem' : '' });
|
|
36
55
|
if (this.childrenKnown) {
|
|
37
56
|
const named = (name) => this.knownChildren.some((child) => child.slot === name);
|
|
38
57
|
this.page = named('page');
|
|
@@ -40,6 +59,12 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
40
59
|
this.end = named('end');
|
|
41
60
|
}
|
|
42
61
|
}
|
|
62
|
+
updated(changed) {
|
|
63
|
+
super.updated(changed);
|
|
64
|
+
if (this.partNamed('item')) {
|
|
65
|
+
auditName(this, () => this.partNamed('item'), 'Give the row words in its default slot, or a label on the icon it holds.');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
43
68
|
firstUpdated(changed) {
|
|
44
69
|
super.firstUpdated(changed);
|
|
45
70
|
this.finishHydration();
|
|
@@ -61,10 +86,16 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
61
86
|
return this.active;
|
|
62
87
|
}
|
|
63
88
|
select() {
|
|
89
|
+
this.choose();
|
|
90
|
+
}
|
|
91
|
+
choose() {
|
|
64
92
|
if (this.disabled) {
|
|
65
|
-
return;
|
|
93
|
+
return false;
|
|
66
94
|
}
|
|
67
|
-
this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
|
|
95
|
+
return this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
|
|
96
|
+
}
|
|
97
|
+
get linked() {
|
|
98
|
+
return this.href !== '' && !this.disabled && !this.page;
|
|
68
99
|
}
|
|
69
100
|
renderMark() {
|
|
70
101
|
return html `<slot name="chevron" aria-hidden="true"
|
|
@@ -80,18 +111,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
80
111
|
if (!this.onPage) {
|
|
81
112
|
return nothing;
|
|
82
113
|
}
|
|
83
|
-
|
|
84
|
-
part="item"
|
|
85
|
-
type="button"
|
|
86
|
-
role="menuitem"
|
|
87
|
-
aria-describedby=${this.describedBy}
|
|
88
|
-
aria-disabled=${this.disabled ? 'true' : nothing}
|
|
89
|
-
aria-haspopup=${this.page ? 'menu' : nothing}
|
|
90
|
-
tabindex=${this.focusable ? '0' : '-1'}
|
|
91
|
-
?data-described=${this.description}
|
|
92
|
-
@click=${() => this.select()}
|
|
93
|
-
>
|
|
94
|
-
<slot name="start"></slot>
|
|
114
|
+
const inside = html `<slot name="start"></slot>
|
|
95
115
|
<span part="label"><slot></slot></span>
|
|
96
116
|
<slot
|
|
97
117
|
id="description"
|
|
@@ -101,26 +121,66 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
101
121
|
@slotchange=${this.readWords}
|
|
102
122
|
></slot>
|
|
103
123
|
<slot id="end" name="end" aria-hidden="true" @slotchange=${this.readWords}></slot>
|
|
104
|
-
${this.page ? this.renderMark() : nothing}
|
|
105
|
-
|
|
124
|
+
${this.page ? this.renderMark() : nothing}`;
|
|
125
|
+
const row = this.linked
|
|
126
|
+
? html `<a
|
|
127
|
+
part="item"
|
|
128
|
+
href=${this.href}
|
|
129
|
+
target=${this.target || nothing}
|
|
130
|
+
rel=${this.rel || nothing}
|
|
131
|
+
?download=${this.download}
|
|
132
|
+
role=${this.listed ? nothing : 'menuitem'}
|
|
133
|
+
aria-describedby=${this.describedBy}
|
|
134
|
+
tabindex=${this.focusable ? '0' : '-1'}
|
|
135
|
+
?data-described=${this.description}
|
|
136
|
+
@click=${this.handleClick}
|
|
137
|
+
@keydown=${this.handleLinkKeydown}
|
|
138
|
+
>${inside}</a>`
|
|
139
|
+
: html `<button
|
|
140
|
+
part="item"
|
|
141
|
+
type="button"
|
|
142
|
+
role=${this.listed ? nothing : 'menuitem'}
|
|
143
|
+
aria-describedby=${this.describedBy}
|
|
144
|
+
aria-disabled=${this.disabled ? 'true' : nothing}
|
|
145
|
+
aria-haspopup=${this.page && !this.listed ? 'menu' : nothing}
|
|
146
|
+
tabindex=${this.focusable ? '0' : '-1'}
|
|
147
|
+
?data-described=${this.description}
|
|
148
|
+
@click=${this.handleClick}
|
|
149
|
+
>${inside}</button>`;
|
|
150
|
+
return html `${row}
|
|
106
151
|
<div hidden><slot name="page" @slotchange=${this.readPage}></slot></div>`;
|
|
107
152
|
}
|
|
108
153
|
};
|
|
109
154
|
__decorate([
|
|
110
155
|
property({ reflect: true, type: Boolean })
|
|
111
156
|
], HelixHeadlessDrilldownItem.prototype, "disabled", void 0);
|
|
157
|
+
__decorate([
|
|
158
|
+
property({ type: Boolean })
|
|
159
|
+
], HelixHeadlessDrilldownItem.prototype, "download", void 0);
|
|
112
160
|
__decorate([
|
|
113
161
|
property({ attribute: false })
|
|
114
162
|
], HelixHeadlessDrilldownItem.prototype, "focusable", void 0);
|
|
163
|
+
__decorate([
|
|
164
|
+
property()
|
|
165
|
+
], HelixHeadlessDrilldownItem.prototype, "href", void 0);
|
|
166
|
+
__decorate([
|
|
167
|
+
property({ attribute: false })
|
|
168
|
+
], HelixHeadlessDrilldownItem.prototype, "listed", void 0);
|
|
115
169
|
__decorate([
|
|
116
170
|
property({ attribute: false })
|
|
117
171
|
], HelixHeadlessDrilldownItem.prototype, "onPage", void 0);
|
|
118
172
|
__decorate([
|
|
119
173
|
property({ attribute: false })
|
|
120
174
|
], HelixHeadlessDrilldownItem.prototype, "onPath", void 0);
|
|
175
|
+
__decorate([
|
|
176
|
+
property()
|
|
177
|
+
], HelixHeadlessDrilldownItem.prototype, "rel", void 0);
|
|
121
178
|
__decorate([
|
|
122
179
|
property({ attribute: false })
|
|
123
180
|
], HelixHeadlessDrilldownItem.prototype, "showingPage", void 0);
|
|
181
|
+
__decorate([
|
|
182
|
+
property()
|
|
183
|
+
], HelixHeadlessDrilldownItem.prototype, "target", void 0);
|
|
124
184
|
__decorate([
|
|
125
185
|
property()
|
|
126
186
|
], HelixHeadlessDrilldownItem.prototype, "value", void 0);
|
|
@@ -20,6 +20,11 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
|
|
|
20
20
|
* and reads the rest from the DOM. The behavior lives in `DrilldownController`,
|
|
21
21
|
* which `Menu` shares.
|
|
22
22
|
*
|
|
23
|
+
* **`page` is the page showing**, as the `value` of the row that opens it,
|
|
24
|
+
* and empty on the top page. Set it to show a page, such as one a link to a
|
|
25
|
+
* settings screen names. A reader's move updates it, and `helix-navigate`
|
|
26
|
+
* comes first, so you can refuse the move or take it yourself.
|
|
27
|
+
*
|
|
23
28
|
* After each move the host carries `data-direction`, `forward` into a page or
|
|
24
29
|
* `back` out of one, and records `:state(forward)` or `:state(back)`, so a
|
|
25
30
|
* stylesheet can slide the new page in from the side the reader is going. Both
|
|
@@ -27,13 +32,25 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
|
|
|
27
32
|
* page, two moves the same way included. The styled tier slides the page and
|
|
28
33
|
* swaps it at once under `prefers-reduced-motion`.
|
|
29
34
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
35
|
+
* **Keyboard.** The drilldown is one tab stop, on the row last focused.
|
|
36
|
+
*
|
|
37
|
+
* | Key | What it does |
|
|
38
|
+
* |---|---|
|
|
39
|
+
* | Down Arrow, Up Arrow | Moves to the next or the previous row. |
|
|
40
|
+
* | Home, End | Moves to the first or the last row. |
|
|
41
|
+
* | A letter | Moves to the next row whose name starts with it. |
|
|
42
|
+
* | Enter, Space | Chooses the row: opens its page, follows its link, or sends `helix-select`. |
|
|
43
|
+
* | Right Arrow | Opens the row's page. Left Arrow on a right-to-left page. |
|
|
44
|
+
* | Left Arrow, Escape | Goes back one page, with focus on the row that opened it. Right Arrow on a right-to-left page. |
|
|
34
45
|
*
|
|
35
46
|
* The rows of the page showing are a `menu`, named by `label` on the top page
|
|
36
|
-
* and by the page's title below it.
|
|
47
|
+
* and by the page's title below it.
|
|
48
|
+
*
|
|
49
|
+
* **`navigation` makes it a site's navigation.** The host is a `navigation`
|
|
50
|
+
* landmark named by `label`, each page is a list, and each row is a list item
|
|
51
|
+
* holding a link or a button, as the APG's disclosure navigation is built,
|
|
52
|
+
* so a reader meets places to go in place of a menu of commands. The keys stay
|
|
53
|
+
* the same. The back button and the title sit above
|
|
37
54
|
* the menu. Disabled rows stay reachable with the arrow keys, and typing a
|
|
38
55
|
* letter moves to the next row whose name starts with it.
|
|
39
56
|
*
|
|
@@ -46,6 +63,7 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
|
|
|
46
63
|
* @slot - The rows of the top page.
|
|
47
64
|
* @slot back-icon - Replaces the icon on the back button.
|
|
48
65
|
*
|
|
66
|
+
* @event {HelixNavigateEvent} helix-navigate - Fired before a reader moves into a page or back out of one. `detail.value` is the `value` of the row whose page is about to show, empty for the top page. Cancelable: cancel it to stay on the page showing.
|
|
49
67
|
* @event {HelixSelectEvent} helix-select - Fired when a row with no page is chosen. Cancelable: canceling it stops the change and leaves the decision to you.
|
|
50
68
|
*
|
|
51
69
|
* @csspart back - The button that goes back one page.
|
|
@@ -79,6 +97,18 @@ export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base
|
|
|
79
97
|
* The text of the back button.
|
|
80
98
|
*/
|
|
81
99
|
backLabel: string;
|
|
100
|
+
/**
|
|
101
|
+
* Whether the drilldown is a site's navigation: a `navigation` landmark
|
|
102
|
+
* named by `label`, whose pages are lists of links. Without it, each page is
|
|
103
|
+
* a `menu`.
|
|
104
|
+
*/
|
|
105
|
+
navigation: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* The page showing, as the `value` of the row that opens it. Empty is the
|
|
108
|
+
* top page. Setting it shows that page, and a value no row with a page has
|
|
109
|
+
* shows the top page.
|
|
110
|
+
*/
|
|
111
|
+
page: string;
|
|
82
112
|
/**
|
|
83
113
|
* Which way the last move went, for whatever animates the change.
|
|
84
114
|
*
|
|
@@ -138,6 +168,13 @@ export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base
|
|
|
138
168
|
* actually showing.
|
|
139
169
|
*/
|
|
140
170
|
private placeTabStop;
|
|
171
|
+
/**
|
|
172
|
+
* Asks before a reader's move to a page, the row's or the top one, and
|
|
173
|
+
* returns whether the move may go ahead.
|
|
174
|
+
*/
|
|
175
|
+
private navigate;
|
|
176
|
+
/** The row whose page holds a row, or null for the top page. */
|
|
177
|
+
private holderOf;
|
|
141
178
|
/** Shows a row's page, and puts focus on the first row of it. */
|
|
142
179
|
private enter;
|
|
143
180
|
/**
|
|
@@ -149,11 +186,14 @@ export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base
|
|
|
149
186
|
* list they have already read.
|
|
150
187
|
*/
|
|
151
188
|
back(): boolean;
|
|
189
|
+
/** Shows the page of the row with a value, or the top page where no row with a page has it. */
|
|
190
|
+
private showPage;
|
|
152
191
|
private readonly handleFocusIn;
|
|
153
192
|
private readonly handleSelect;
|
|
154
193
|
private readonly handleKeydown;
|
|
155
194
|
connectedCallback(): void;
|
|
156
195
|
disconnectedCallback(): void;
|
|
196
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
157
197
|
protected updated(changed: PropertyValues): void;
|
|
158
198
|
/**
|
|
159
199
|
* Writes which way the last move went. After a move, the marks come off and
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadByWords, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, DrilldownController, HelixElement, HelixNavigateEvent, hostAria, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadByWords, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -15,6 +15,8 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
15
15
|
super(...arguments);
|
|
16
16
|
this.label = 'Navigation';
|
|
17
17
|
this.backLabel = 'Back';
|
|
18
|
+
this.navigation = false;
|
|
19
|
+
this.page = '';
|
|
18
20
|
this.moved = false;
|
|
19
21
|
this.drilldown = new DrilldownController(this, {
|
|
20
22
|
isRow: (element) => 'isDrilldownItem' in element && element.isDrilldownItem === true,
|
|
@@ -97,24 +99,50 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
97
99
|
item.focusable = item === stop;
|
|
98
100
|
}
|
|
99
101
|
}
|
|
102
|
+
navigate(to) {
|
|
103
|
+
return this.dispatchEvent(new HelixNavigateEvent({ value: to?.value ?? '' }));
|
|
104
|
+
}
|
|
105
|
+
holderOf(row) {
|
|
106
|
+
const parent = row.parentElement;
|
|
107
|
+
return row.slot === 'page' && parent instanceof HelixHeadlessDrilldownItem ? parent : null;
|
|
108
|
+
}
|
|
100
109
|
enter(item) {
|
|
101
|
-
if (!this.drilldown.enter(item)) {
|
|
110
|
+
if (!this.drilldown.hasPage(item) || !this.navigate(item) || !this.drilldown.enter(item)) {
|
|
102
111
|
return;
|
|
103
112
|
}
|
|
113
|
+
this.page = item.value;
|
|
104
114
|
this.direction = 'forward';
|
|
105
115
|
this.moved = true;
|
|
106
116
|
this.updateComplete.then(() => this.items[0]?.focusItem());
|
|
107
117
|
}
|
|
108
118
|
back() {
|
|
109
119
|
const leaving = this.drilldown.page;
|
|
110
|
-
if (
|
|
120
|
+
if (leaving === null) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
const to = this.holderOf(leaving);
|
|
124
|
+
if (!this.navigate(to) || !this.drilldown.back()) {
|
|
111
125
|
return false;
|
|
112
126
|
}
|
|
127
|
+
this.page = to?.value ?? '';
|
|
113
128
|
this.direction = 'back';
|
|
114
129
|
this.moved = true;
|
|
115
130
|
this.updateComplete.then(() => leaving?.focusItem());
|
|
116
131
|
return true;
|
|
117
132
|
}
|
|
133
|
+
showPage(value) {
|
|
134
|
+
const row = value === ''
|
|
135
|
+
? undefined
|
|
136
|
+
: [...this.querySelectorAll('*')].find((one) => one instanceof HelixHeadlessDrilldownItem &&
|
|
137
|
+
one.value === value &&
|
|
138
|
+
this.drilldown.hasPage(one));
|
|
139
|
+
if (row) {
|
|
140
|
+
this.drilldown.enter(row);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
this.drilldown.reset();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
118
146
|
connectedCallback() {
|
|
119
147
|
super.connectedCallback();
|
|
120
148
|
this.addEventListener('helix-select', this.handleSelect, true);
|
|
@@ -127,6 +155,17 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
127
155
|
this.removeEventListener('keydown', this.handleKeydown);
|
|
128
156
|
this.removeEventListener('focusin', this.handleFocusIn);
|
|
129
157
|
}
|
|
158
|
+
willUpdate(changed) {
|
|
159
|
+
super.willUpdate(changed);
|
|
160
|
+
if (changed.has('page') && (this.drilldown.page?.value ?? '') !== this.page) {
|
|
161
|
+
this.showPage(this.page);
|
|
162
|
+
this.page = this.drilldown.page?.value ?? '';
|
|
163
|
+
}
|
|
164
|
+
hostAria(this.internals, {
|
|
165
|
+
label: this.navigation ? this.label : '',
|
|
166
|
+
role: this.navigation ? 'navigation' : '',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
130
169
|
updated(changed) {
|
|
131
170
|
super.updated(changed);
|
|
132
171
|
const page = this.drilldown.page;
|
|
@@ -162,6 +201,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
162
201
|
}
|
|
163
202
|
mark(item, page, onPage) {
|
|
164
203
|
item.onPage = onPage;
|
|
204
|
+
item.listed = this.navigation;
|
|
165
205
|
item.showingPage = item === page;
|
|
166
206
|
item.onPath = page !== null && item !== page && item.contains(page);
|
|
167
207
|
for (const child of item.children) {
|
|
@@ -188,10 +228,10 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
188
228
|
</div>`}
|
|
189
229
|
<div
|
|
190
230
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
191
|
-
aria-label=${this.drilldown.atRoot ? this.label || nothing : nothing}
|
|
231
|
+
aria-label=${this.drilldown.atRoot && !this.navigation ? this.label || nothing : nothing}
|
|
192
232
|
aria-labelledby=${this.drilldown.atRoot ? nothing : 'title'}
|
|
193
233
|
part="page"
|
|
194
|
-
role
|
|
234
|
+
role=${this.navigation ? 'list' : 'menu'}
|
|
195
235
|
>
|
|
196
236
|
<slot @slotchange=${(event) => this.countRows(event)}></slot>
|
|
197
237
|
${this.renderStatus(this.hasRows)}
|
|
@@ -206,6 +246,12 @@ __decorate([
|
|
|
206
246
|
words,
|
|
207
247
|
property({ attribute: 'back-label' })
|
|
208
248
|
], HelixHeadlessDrilldown.prototype, "backLabel", void 0);
|
|
249
|
+
__decorate([
|
|
250
|
+
property({ type: Boolean })
|
|
251
|
+
], HelixHeadlessDrilldown.prototype, "navigation", void 0);
|
|
252
|
+
__decorate([
|
|
253
|
+
property()
|
|
254
|
+
], HelixHeadlessDrilldown.prototype, "page", void 0);
|
|
209
255
|
__decorate([
|
|
210
256
|
state()
|
|
211
257
|
], HelixHeadlessDrilldown.prototype, "direction", void 0);
|
|
@@ -93,7 +93,7 @@ registerElementEvents({
|
|
|
93
93
|
'helix-headless-date-picker': ['change', 'helix-before-change', 'helix-navigate', 'input'],
|
|
94
94
|
'helix-headless-dialog': ['close', 'helix-before-close', 'helix-before-open', 'toggle'],
|
|
95
95
|
'helix-headless-drawer': ['close', 'helix-before-close', 'helix-before-open', 'toggle'],
|
|
96
|
-
'helix-headless-drilldown': ['helix-select'],
|
|
96
|
+
'helix-headless-drilldown': ['helix-navigate', 'helix-select'],
|
|
97
97
|
'helix-headless-drilldown-item': ['helix-select'],
|
|
98
98
|
'helix-headless-file-input': ['change', 'helix-before-change', 'helix-reject', 'input'],
|
|
99
99
|
'helix-headless-filter-chip': ['helix-dismiss'],
|
|
@@ -141,6 +141,7 @@ registerElementEvents({
|
|
|
141
141
|
'helix-action',
|
|
142
142
|
'helix-before-change',
|
|
143
143
|
'helix-before-reorder',
|
|
144
|
+
'helix-load-more',
|
|
144
145
|
'helix-reorder',
|
|
145
146
|
],
|
|
146
147
|
'helix-headless-list-item': ['helix-action'],
|
|
@@ -74,6 +74,7 @@ import '../../menu/index.js';
|
|
|
74
74
|
* @csspart entry-shortcut-key - One key of the shortcut's chord.
|
|
75
75
|
* @csspart entry-shortcut-separator - The `+` between two keys of the shortcut, where the platform writes one.
|
|
76
76
|
* @csspart entry-start - The leading column.
|
|
77
|
+
* @csspart entry-surface - The panel a row's submenu opens in beside it. The filter menu's rows have none.
|
|
77
78
|
* @csspart menu - The menu the fields are offered in.
|
|
78
79
|
* @csspart menu-back - The button that goes back from a field's page.
|
|
79
80
|
* @csspart menu-back-mark - The icon on the back button.
|
|
@@ -141,7 +141,7 @@ let HelixHeadlessFilterMenu = class HelixHeadlessFilterMenu extends HelixElement
|
|
|
141
141
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
142
142
|
shortcut-kbd: entry-shortcut-kbd,
|
|
143
143
|
shortcut-key: entry-shortcut-key, shortcut-separator: entry-shortcut-separator,
|
|
144
|
-
start: entry-start"
|
|
144
|
+
start: entry-start, surface: entry-surface"
|
|
145
145
|
data-facet="field"
|
|
146
146
|
data-field=${name}
|
|
147
147
|
>
|
|
@@ -152,7 +152,7 @@ let HelixHeadlessFilterMenu = class HelixHeadlessFilterMenu extends HelixElement
|
|
|
152
152
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
153
153
|
shortcut-kbd: entry-shortcut-kbd,
|
|
154
154
|
shortcut-key: entry-shortcut-key, shortcut-separator: entry-shortcut-separator,
|
|
155
|
-
start: entry-start"
|
|
155
|
+
start: entry-start, surface: entry-surface"
|
|
156
156
|
slot="submenu"
|
|
157
157
|
data-facet="comparison"
|
|
158
158
|
data-field=${name}
|
|
@@ -163,7 +163,7 @@ let HelixHeadlessFilterMenu = class HelixHeadlessFilterMenu extends HelixElement
|
|
|
163
163
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
164
164
|
shortcut-kbd: entry-shortcut-kbd,
|
|
165
165
|
shortcut-key: entry-shortcut-key, shortcut-separator: entry-shortcut-separator,
|
|
166
|
-
start: entry-start"
|
|
166
|
+
start: entry-start, surface: entry-surface"
|
|
167
167
|
slot="submenu"
|
|
168
168
|
checkable
|
|
169
169
|
exclusive
|
|
@@ -188,7 +188,7 @@ let HelixHeadlessFilterMenu = class HelixHeadlessFilterMenu extends HelixElement
|
|
|
188
188
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
189
189
|
shortcut-kbd: entry-shortcut-kbd,
|
|
190
190
|
shortcut-key: entry-shortcut-key, shortcut-separator: entry-shortcut-separator,
|
|
191
|
-
start: entry-start"
|
|
191
|
+
start: entry-start, surface: entry-surface"
|
|
192
192
|
slot="submenu"
|
|
193
193
|
checkable
|
|
194
194
|
?exclusive=${using?.arity === 'one'}
|
|
@@ -39,6 +39,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
39
39
|
* @documentation https://fusion.dev/helix/components/graph
|
|
40
40
|
*
|
|
41
41
|
* @slot - The renderer's box, which the drawing is made in.
|
|
42
|
+
* @slot empty - What the panel shows when the list holds no notes. Defaults to `empty-label`.
|
|
42
43
|
* @slot filter-icon - The icon in the search field. Defaults to a magnifying glass.
|
|
43
44
|
* @slot footer - Content below the graph.
|
|
44
45
|
* @slot fullscreen-icon - Replaces the glyph inside the fullscreen button.
|
|
@@ -65,6 +66,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
65
66
|
* @csspart body - The drawing beside the list, or above it where the frame is narrow.
|
|
66
67
|
* @csspart controls - The group the pan and zoom buttons sit in.
|
|
67
68
|
* @csspart count - How many notes the list holds, which a search narrows, at the end of the search bar.
|
|
69
|
+
* @csspart empty - The box in place of the list when it holds no notes, holding the `empty` slot.
|
|
68
70
|
* @csspart filter-icon - The icon beside the search field.
|
|
69
71
|
* @csspart filter-mark - The default icon beside the search field, shown when none is slotted.
|
|
70
72
|
* @csspart footer - The strip below the graph.
|
|
@@ -135,6 +137,11 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
135
137
|
* shows every note. The list holds what the drawing shows.
|
|
136
138
|
*/
|
|
137
139
|
depth?: number;
|
|
140
|
+
/**
|
|
141
|
+
* What the panel shows when the list holds no notes: the graph has none, or
|
|
142
|
+
* a search or the legend hid them all. A slotted `empty` replaces it.
|
|
143
|
+
*/
|
|
144
|
+
emptyLabel: string;
|
|
138
145
|
/**
|
|
139
146
|
* The graph's name where `label` is empty and the host has no
|
|
140
147
|
* `aria-label`.
|
|
@@ -180,6 +187,12 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
180
187
|
noPanel: boolean;
|
|
181
188
|
/** The list's name, read by screen readers, and the name of the button that opens it with `no-panel`. */
|
|
182
189
|
notesLabel: string;
|
|
190
|
+
/**
|
|
191
|
+
* What a screen reader calls the graph in place of its role, after its
|
|
192
|
+
* name: "Research notes, graph". Said only where the graph has a name of its
|
|
193
|
+
* own, since the fallback name is the same word. Empty leaves the role.
|
|
194
|
+
*/
|
|
195
|
+
roleLabel: string;
|
|
183
196
|
/** The search field's name. */
|
|
184
197
|
searchLabel: string;
|
|
185
198
|
/** How the selected note is described in the list. */
|
|
@@ -17,6 +17,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
17
17
|
this.activateHintLabel = 'Press the graph to use it';
|
|
18
18
|
this.controlsLabel = 'Graph controls';
|
|
19
19
|
this.countLabel = '{count, plural, one {# note} other {# notes}}';
|
|
20
|
+
this.emptyLabel = 'No notes';
|
|
20
21
|
this.fallbackLabel = 'Graph';
|
|
21
22
|
this.hiddenGroups = [];
|
|
22
23
|
this.label = '';
|
|
@@ -33,6 +34,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
33
34
|
this.nodes = [];
|
|
34
35
|
this.noPanel = false;
|
|
35
36
|
this.notesLabel = 'Notes';
|
|
37
|
+
this.roleLabel = 'graph';
|
|
36
38
|
this.searchLabel = 'Find a note';
|
|
37
39
|
this.selectedLabel = 'Selected';
|
|
38
40
|
this.twoFingerHintLabel = 'Use two fingers to move the graph';
|
|
@@ -409,6 +411,8 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
409
411
|
part="region"
|
|
410
412
|
role="group"
|
|
411
413
|
aria-label=${this.label || this.getAttribute?.('aria-label') || this.fallbackLabel}
|
|
414
|
+
aria-roledescription=${(this.label || this.getAttribute?.('aria-label')) && this.roleLabel ? this.roleLabel : nothing}
|
|
415
|
+
aria-keyshortcuts="ArrowUp ArrowDown ArrowLeft ArrowRight Plus Minus"
|
|
412
416
|
tabindex="0"
|
|
413
417
|
@focusin=${this.idle.stir}
|
|
414
418
|
@keydown=${this.handleKeydown}
|
|
@@ -454,6 +458,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
454
458
|
data-scroller
|
|
455
459
|
aria-label=${this.notesLabel}
|
|
456
460
|
aria-activedescendant=${cursor}
|
|
461
|
+
aria-keyshortcuts="ArrowUp ArrowDown Home End PageUp PageDown Enter Space"
|
|
457
462
|
@keydown=${this.handleListKeydown}
|
|
458
463
|
@scroll=${() => this.virtualize.measure()}
|
|
459
464
|
>
|
|
@@ -461,6 +466,9 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
461
466
|
${this.renderRows()}
|
|
462
467
|
<div part="after" role="presentation" style="block-size: ${after}px"></div>
|
|
463
468
|
</div>
|
|
469
|
+
${this.entries.length === 0
|
|
470
|
+
? html `<div part="empty"><slot name="empty">${this.emptyLabel}</slot></div>`
|
|
471
|
+
: nothing}
|
|
464
472
|
</div>
|
|
465
473
|
</div>
|
|
466
474
|
<div part="footer">
|
|
@@ -485,6 +493,10 @@ __decorate([
|
|
|
485
493
|
__decorate([
|
|
486
494
|
property({ type: Number })
|
|
487
495
|
], HelixHeadlessGraph.prototype, "depth", void 0);
|
|
496
|
+
__decorate([
|
|
497
|
+
words,
|
|
498
|
+
property({ attribute: 'empty-label' })
|
|
499
|
+
], HelixHeadlessGraph.prototype, "emptyLabel", void 0);
|
|
488
500
|
__decorate([
|
|
489
501
|
words,
|
|
490
502
|
property({ attribute: 'fallback-label' })
|
|
@@ -543,6 +555,10 @@ __decorate([
|
|
|
543
555
|
words,
|
|
544
556
|
property({ attribute: 'notes-label' })
|
|
545
557
|
], HelixHeadlessGraph.prototype, "notesLabel", void 0);
|
|
558
|
+
__decorate([
|
|
559
|
+
words,
|
|
560
|
+
property({ attribute: 'role-label' })
|
|
561
|
+
], HelixHeadlessGraph.prototype, "roleLabel", void 0);
|
|
546
562
|
__decorate([
|
|
547
563
|
words,
|
|
548
564
|
property({ attribute: 'search-label' })
|