@fusion.dev/helix-headless 0.162.0 → 0.163.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 +342 -15
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +3 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -1
- package/dist/canvas/index.d.ts +1 -1
- package/dist/canvas/root/canvas-document.d.ts +33 -0
- package/dist/canvas/root/canvas-root.d.ts +50 -2
- package/dist/canvas/root/canvas-root.js +98 -3
- package/dist/chat/composer/chat-composer.js +1 -1
- package/dist/chat/root/chat-root.d.ts +21 -5
- package/dist/chat/root/chat-root.js +21 -9
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +3 -1
- package/dist/checkbox-group/root/checkbox-group-root.js +2 -1
- package/dist/combobox/root/combobox-root.d.ts +8 -1
- package/dist/combobox/root/combobox-root.js +5 -1
- package/dist/list/root/list-root.d.ts +3 -1
- package/dist/list/root/list-root.js +2 -1
- package/dist/listbox/root/listbox-root.d.ts +2 -1
- package/dist/listbox/root/listbox-root.js +2 -1
- package/dist/map/root/map-root.d.ts +8 -1
- package/dist/map/root/map-root.js +12 -0
- package/dist/menu/item/menu-item.d.ts +38 -7
- package/dist/menu/item/menu-item.js +20 -9
- package/dist/menu/root/menu-root.d.ts +10 -1
- package/dist/menu/root/menu-root.js +8 -3
- package/dist/notifications/group/notification-group.d.ts +4 -1
- package/dist/notifications/group/notification-group.js +5 -3
- package/dist/notifications/root/notifications-root.d.ts +7 -2
- package/dist/notifications/root/notifications-root.js +2 -1
- package/dist/radio/group/radio-group.d.ts +2 -1
- package/dist/radio/group/radio-group.js +2 -1
- package/dist/select/root/select-root.d.ts +8 -1
- package/dist/select/root/select-root.js +5 -1
- package/dist/steps/root/steps-root.d.ts +7 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/tag/group/tag-group.d.ts +3 -1
- package/dist/tag/group/tag-group.js +2 -1
- package/dist/toggle/group/toggle-group.d.ts +2 -1
- package/dist/toggle/group/toggle-group.js +4 -1
- package/dist/tree/root/tree-root.d.ts +2 -1
- package/dist/tree/root/tree-root.js +4 -1
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +162 -24
- package/types/vue.d.ts +40 -7
|
@@ -10,16 +10,22 @@ import '../../kbd/index.js';
|
|
|
10
10
|
* - `checked` makes the row a choice.
|
|
11
11
|
* - With neither, the row is a command.
|
|
12
12
|
*
|
|
13
|
-
* The role follows the kind. A row with `
|
|
14
|
-
* `aria-checked`, and `exclusive`
|
|
15
|
-
* only one can be on. A row that opens a page
|
|
16
|
-
* `aria-haspopup`.
|
|
13
|
+
* The role follows the kind. A row with `checkable` or `checked` is
|
|
14
|
+
* `menuitemcheckbox` with `aria-checked`, and an `exclusive` row is
|
|
15
|
+
* `menuitemradio`, for a set where only one can be on. A row that opens a page
|
|
16
|
+
* keeps `menuitem` and sets `aria-haspopup`.
|
|
17
17
|
*
|
|
18
18
|
* Choosing a choice row checks or unchecks it before `helix-select` is sent,
|
|
19
19
|
* so a listener reads the new `checked`. An `exclusive` row turns on and turns
|
|
20
20
|
* off the `exclusive` rows next to it. Cancel `helix-before-toggle` to keep a
|
|
21
21
|
* row as it is and set `checked` yourself.
|
|
22
22
|
*
|
|
23
|
+
* Space on a choice row changes it and leaves the menu open, so a reader can
|
|
24
|
+
* set several in a row, as the APG's menu does. Enter and a press change it and
|
|
25
|
+
* close the menu. `close-on-select="false"` on the row keeps the menu open after
|
|
26
|
+
* any choice of it, and `close-on-select` on the row closes it after a Space as
|
|
27
|
+
* well.
|
|
28
|
+
*
|
|
23
29
|
* The menu sets whether the row's page is showing as a property, never as an
|
|
24
30
|
* attribute. An attribute written onto your element after it upgrades causes a
|
|
25
31
|
* hydration mismatch.
|
|
@@ -82,7 +88,8 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
|
|
|
82
88
|
* as a checkbox tells a reader its siblings are commands, which is the one
|
|
83
89
|
* thing they are not.
|
|
84
90
|
*
|
|
85
|
-
* `checked`
|
|
91
|
+
* `checked` and `exclusive` imply it, so a row that is on, or one of a set,
|
|
92
|
+
* never has to say both.
|
|
86
93
|
*
|
|
87
94
|
* Choosing the row checks or unchecks it, after a `helix-before-toggle` that
|
|
88
95
|
* you can cancel.
|
|
@@ -95,6 +102,14 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
|
|
|
95
102
|
* state you start the row in, and `:state(checked)` carries the current one.
|
|
96
103
|
*/
|
|
97
104
|
checked: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Whether choosing the row closes the menu.
|
|
107
|
+
*
|
|
108
|
+
* Unset takes the menu's `close-on-select`, which is on, and keeps the menu
|
|
109
|
+
* open after a Space on a choice row. Write `close-on-select="false"` for a
|
|
110
|
+
* row that changes something the reader is watching, such as a zoom step.
|
|
111
|
+
*/
|
|
112
|
+
closeOnSelect?: boolean;
|
|
98
113
|
/**
|
|
99
114
|
* Whether the row is disabled, so it cannot be chosen.
|
|
100
115
|
*/
|
|
@@ -116,8 +131,7 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
|
|
|
116
131
|
* it checked. `menuitemradio` tells a reader which kind of set they are in,
|
|
117
132
|
* where `menuitemcheckbox` says every row is independent.
|
|
118
133
|
*
|
|
119
|
-
*
|
|
120
|
-
* one of a set of anything.
|
|
134
|
+
* It makes the row a choice, so it needs no `checkable` beside it.
|
|
121
135
|
*/
|
|
122
136
|
exclusive: boolean;
|
|
123
137
|
/**
|
|
@@ -192,6 +206,17 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
|
|
|
192
206
|
* protected. Not a consumer's to read or set.
|
|
193
207
|
*/
|
|
194
208
|
readonly isMenuItem = true;
|
|
209
|
+
/**
|
|
210
|
+
* @internal Whether the last choice of this row asked the menu to stay open:
|
|
211
|
+
* a Space on a choice row, or `close-on-select="false"`. Read by the menu
|
|
212
|
+
* while it hears the row's `helix-select`.
|
|
213
|
+
*/
|
|
214
|
+
keepsOpen: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* @internal Whether the row is a choice: it can be ticked, or is one of a
|
|
217
|
+
* set. Read by the menu to reserve the trailing column.
|
|
218
|
+
*/
|
|
219
|
+
get choice(): boolean;
|
|
195
220
|
/**
|
|
196
221
|
* Whether anything was slotted into `submenu`.
|
|
197
222
|
*
|
|
@@ -342,8 +367,14 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
|
|
|
342
367
|
private tick;
|
|
343
368
|
/** The other `exclusive` rows in this row's run of siblings. */
|
|
344
369
|
private exclusivePeers;
|
|
370
|
+
/**
|
|
371
|
+
* Chooses the row. `space` is whether a Space chose it, which keeps the menu
|
|
372
|
+
* open on a choice row unless the row says otherwise.
|
|
373
|
+
*/
|
|
345
374
|
private choose;
|
|
346
375
|
private readonly handleClick;
|
|
376
|
+
/** Whether the click on its way is the one a Space on a linked row sent. */
|
|
377
|
+
private spacePressed;
|
|
347
378
|
/**
|
|
348
379
|
* Enter and Space choose the row, which a `<div>` would not do on its own.
|
|
349
380
|
*
|
|
@@ -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 { ariaChord, auditName, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, isRtl, onApple, PopoverController, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ariaChord, auditName, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, isRtl, onApple, onUnlessFalse, PopoverController, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight, check } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -29,6 +29,7 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
29
29
|
this.target = '';
|
|
30
30
|
this.value = '';
|
|
31
31
|
this.isMenuItem = true;
|
|
32
|
+
this.keepsOpen = false;
|
|
32
33
|
this.submenu = false;
|
|
33
34
|
this.start = false;
|
|
34
35
|
this.end = false;
|
|
@@ -58,8 +59,10 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
58
59
|
surface: () => (this.flyout ? this.partNamed('surface') : null),
|
|
59
60
|
});
|
|
60
61
|
this.handleClick = () => {
|
|
61
|
-
this.choose();
|
|
62
|
+
this.choose(this.spacePressed);
|
|
63
|
+
this.spacePressed = false;
|
|
62
64
|
};
|
|
65
|
+
this.spacePressed = false;
|
|
63
66
|
this.handleKeydown = (event) => {
|
|
64
67
|
if (event.key !== 'Enter' && event.key !== ' ') {
|
|
65
68
|
return;
|
|
@@ -70,12 +73,17 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
70
73
|
}
|
|
71
74
|
event.preventDefault();
|
|
72
75
|
if (link) {
|
|
76
|
+
this.spacePressed = true;
|
|
73
77
|
link.click();
|
|
78
|
+
this.spacePressed = false;
|
|
74
79
|
return;
|
|
75
80
|
}
|
|
76
|
-
this.
|
|
81
|
+
this.choose(event.key === ' ');
|
|
77
82
|
};
|
|
78
83
|
}
|
|
84
|
+
get choice() {
|
|
85
|
+
return this.checkable || this.checked || this.exclusive;
|
|
86
|
+
}
|
|
79
87
|
get hasSubmenu() {
|
|
80
88
|
return this.submenu;
|
|
81
89
|
}
|
|
@@ -93,9 +101,7 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
93
101
|
const rows = this.knownChildren.filter((child) => child.slot === 'submenu' && child.isMenuItem);
|
|
94
102
|
this.toggleState('submenu-start', this.flyout && rows.some((row) => row.querySelector(':scope > [slot="start"]') !== null));
|
|
95
103
|
this.toggleState('submenu-mark', this.flyout &&
|
|
96
|
-
rows.some((row) => row.
|
|
97
|
-
row.checked ||
|
|
98
|
-
[...row.children].some((child) => child.slot === 'submenu')));
|
|
104
|
+
rows.some((row) => row.choice || [...row.children].some((child) => child.slot === 'submenu')));
|
|
99
105
|
}
|
|
100
106
|
firstUpdated(changed) {
|
|
101
107
|
super.firstUpdated(changed);
|
|
@@ -152,7 +158,7 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
152
158
|
return this.active;
|
|
153
159
|
}
|
|
154
160
|
tick() {
|
|
155
|
-
if (!
|
|
161
|
+
if (!this.choice || this.hasSubmenu) {
|
|
156
162
|
return;
|
|
157
163
|
}
|
|
158
164
|
const next = this.exclusive ? true : !this.checked;
|
|
@@ -188,10 +194,12 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
188
194
|
}
|
|
189
195
|
return peers;
|
|
190
196
|
}
|
|
191
|
-
choose() {
|
|
197
|
+
choose(space = false) {
|
|
192
198
|
if (this.disabled) {
|
|
193
199
|
return;
|
|
194
200
|
}
|
|
201
|
+
const spaceKeeps = space && this.choice && !this.hasSubmenu;
|
|
202
|
+
this.keepsOpen = this.closeOnSelect === undefined ? spaceKeeps : !this.closeOnSelect;
|
|
195
203
|
this.tick();
|
|
196
204
|
this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
|
|
197
205
|
}
|
|
@@ -221,7 +229,7 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
221
229
|
}
|
|
222
230
|
const submenu = this.hasSubmenu;
|
|
223
231
|
const linked = this.href !== '' && !this.disabled;
|
|
224
|
-
const ticks = this.
|
|
232
|
+
const ticks = this.choice;
|
|
225
233
|
const role = ticks ? (this.exclusive ? 'menuitemradio' : 'menuitemcheckbox') : 'menuitem';
|
|
226
234
|
const checkedState = ticks ? (this.checked ? 'true' : 'false') : nothing;
|
|
227
235
|
const keys = this.shortcut === '' ? nothing : ariaChord(this.shortcut, !this.hydrating && onApple());
|
|
@@ -281,6 +289,9 @@ __decorate([
|
|
|
281
289
|
__decorate([
|
|
282
290
|
property({ type: Boolean })
|
|
283
291
|
], HelixHeadlessMenuItem.prototype, "checked", void 0);
|
|
292
|
+
__decorate([
|
|
293
|
+
property({ attribute: 'close-on-select', converter: onUnlessFalse })
|
|
294
|
+
], HelixHeadlessMenuItem.prototype, "closeOnSelect", void 0);
|
|
284
295
|
__decorate([
|
|
285
296
|
property({ reflect: true, type: Boolean })
|
|
286
297
|
], HelixHeadlessMenuItem.prototype, "disabled", void 0);
|
|
@@ -40,7 +40,8 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
|
|
|
40
40
|
* Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first
|
|
41
41
|
* row, and Up Arrow on its last. In the menu, Up and Down Arrow move between
|
|
42
42
|
* rows, Home and End go to the first and the last, a typed letter moves to
|
|
43
|
-
* the next row whose name starts with it, Enter and Space choose
|
|
43
|
+
* the next row whose name starts with it, Enter and Space choose (Space on a
|
|
44
|
+
* choice row changes it and leaves the menu open), Right Arrow
|
|
44
45
|
* opens a row's submenu and Left Arrow goes back, the two swapping on a
|
|
45
46
|
* right-to-left page. Left Arrow on the top page does nothing. Escape closes
|
|
46
47
|
* the menu and returns focus to the trigger. Tab closes it and moves on.
|
|
@@ -109,6 +110,14 @@ export declare class HelixHeadlessMenu extends HelixHeadlessMenu_base {
|
|
|
109
110
|
* The text of the row that returns from a submenu.
|
|
110
111
|
*/
|
|
111
112
|
backLabel: string;
|
|
113
|
+
/**
|
|
114
|
+
* Whether choosing a row closes the menu.
|
|
115
|
+
*
|
|
116
|
+
* On by default, and a Space on a choice row leaves the menu open either way.
|
|
117
|
+
* Write `close-on-select="false"` to keep the menu open after every choice, as
|
|
118
|
+
* Ark UI's `closeOnSelect` does. A row's own `close-on-select` wins over this.
|
|
119
|
+
*/
|
|
120
|
+
closeOnSelect: boolean;
|
|
112
121
|
/**
|
|
113
122
|
* Whether the menu is the trigger's context menu: it opens where the reader
|
|
114
123
|
* asks for one, with a right-click, a long press, Shift+F10 or the menu key.
|
|
@@ -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, anchorElement, customElement, DrilldownController, deepActiveElement, deepContains, focusTarget, HelixElement, inlineStep, KeyboardNavigationController, linkDescription, MixinCollection, MixinControllerOpen, PopoverController, scrollItemIntoView, sideOf, slottedWords, tellDisclosure, typeaheadBy, unlinkDescription, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, anchorElement, customElement, DrilldownController, deepActiveElement, deepContains, focusTarget, HelixElement, inlineStep, KeyboardNavigationController, linkDescription, MixinCollection, MixinControllerOpen, onUnlessFalse, PopoverController, scrollItemIntoView, sideOf, slottedWords, tellDisclosure, typeaheadBy, unlinkDescription, 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 } from 'lit/decorators.js';
|
|
@@ -31,6 +31,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
31
31
|
constructor() {
|
|
32
32
|
super(...arguments);
|
|
33
33
|
this.backLabel = 'Back';
|
|
34
|
+
this.closeOnSelect = true;
|
|
34
35
|
this.context = false;
|
|
35
36
|
this.label = '';
|
|
36
37
|
this.longPressLabel = 'Long press or press Alt+Down to show the menu';
|
|
@@ -119,8 +120,9 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
119
120
|
this.enter(chosen);
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
123
|
+
const keep = chosen.keepsOpen || (chosen.closeOnSelect === undefined && !this.closeOnSelect);
|
|
122
124
|
queueMicrotask(() => {
|
|
123
|
-
if (!event.defaultPrevented) {
|
|
125
|
+
if (!(event.defaultPrevented || keep)) {
|
|
124
126
|
this.hide();
|
|
125
127
|
}
|
|
126
128
|
});
|
|
@@ -538,7 +540,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
538
540
|
markColumns() {
|
|
539
541
|
const rows = this.flies ? this.topRows : this.drilldown.rows;
|
|
540
542
|
this.toggleState('start', rows.some((row) => row.querySelector(':scope > [slot="start"]') !== null));
|
|
541
|
-
this.toggleState('mark', rows.some((row) => row.
|
|
543
|
+
this.toggleState('mark', rows.some((row) => row.choice || this.drilldown.hasPage(row)));
|
|
542
544
|
}
|
|
543
545
|
mark(item, onPage) {
|
|
544
546
|
const page = this.drilldown.page;
|
|
@@ -608,6 +610,9 @@ __decorate([
|
|
|
608
610
|
words,
|
|
609
611
|
property({ attribute: 'back-label' })
|
|
610
612
|
], HelixHeadlessMenu.prototype, "backLabel", void 0);
|
|
613
|
+
__decorate([
|
|
614
|
+
property({ attribute: 'close-on-select', converter: onUnlessFalse })
|
|
615
|
+
], HelixHeadlessMenu.prototype, "closeOnSelect", void 0);
|
|
611
616
|
__decorate([
|
|
612
617
|
property({ reflect: true, type: Boolean })
|
|
613
618
|
], HelixHeadlessMenu.prototype, "context", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ChildrenController, HelixElement, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import type { HelixHeadlessNotification } from '../notification/notification.js';
|
|
4
4
|
declare const HelixHeadlessNotificationGroup_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
@@ -140,7 +140,10 @@ export declare class HelixHeadlessNotificationGroup extends HelixHeadlessNotific
|
|
|
140
140
|
* the group is in is asked to update as well, since it counts the group's
|
|
141
141
|
* rows and does not watch inside the group.
|
|
142
142
|
*/
|
|
143
|
+
private readonly recount;
|
|
143
144
|
protected readonly childWatch: ChildrenController;
|
|
145
|
+
/** Hears a row upgrade after it arrived, which neither the slot nor `childWatch` reports. */
|
|
146
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
144
147
|
private readonly handleToggle;
|
|
145
148
|
protected render(): TemplateResult;
|
|
146
149
|
}
|
|
@@ -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 { assignSlots, ChildrenController, customElement, HelixElement, hostAria, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { assignSlots, ChildrenController, customElement, HelixElement, hostAria, MixinControllerOpen, UpgradeController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
const TRIGGER_ID = 'trigger';
|
|
@@ -16,10 +16,12 @@ let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extend
|
|
|
16
16
|
this.collapsible = false;
|
|
17
17
|
this.label = '';
|
|
18
18
|
this.isNotificationGroup = true;
|
|
19
|
-
this.
|
|
19
|
+
this.recount = () => {
|
|
20
20
|
this.requestUpdate();
|
|
21
21
|
this.parentElement?.requestUpdate?.();
|
|
22
|
-
}
|
|
22
|
+
};
|
|
23
|
+
this.childWatch = new ChildrenController(this, this.recount);
|
|
24
|
+
this.upgradeWatch = new UpgradeController(this, this.recount);
|
|
23
25
|
this.handleToggle = () => {
|
|
24
26
|
this.toggleOpen();
|
|
25
27
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { ChildrenController, HelixElement, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import type { HelixHeadlessNotificationGroup } from '../group/notification-group.js';
|
|
4
4
|
import type { HelixHeadlessNotification } from '../notification/notification.js';
|
|
@@ -239,6 +239,11 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
|
|
|
239
239
|
* a group is the group's to hear, and the group asks the feed to count again.
|
|
240
240
|
*/
|
|
241
241
|
protected readonly childWatch: ChildrenController;
|
|
242
|
+
/**
|
|
243
|
+
* Hears a row upgrade after it arrived. A row is known by its marker, which
|
|
244
|
+
* an element that has not upgraded lacks, so the row was assigned nowhere.
|
|
245
|
+
*/
|
|
246
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
242
247
|
/**
|
|
243
248
|
* An item's own read event, heard on the way past, so the count follows.
|
|
244
249
|
*
|
|
@@ -328,7 +333,7 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
|
|
|
328
333
|
* moment the markup is parsed. The rows themselves come from `items`, which
|
|
329
334
|
* does need them upgraded, and that is the honest limit rather than a claim
|
|
330
335
|
* this had made the other way: a row that upgrades late is counted on the next
|
|
331
|
-
* update, which
|
|
336
|
+
* update, which `UpgradeController` asks for when its definition arrives.
|
|
332
337
|
*/
|
|
333
338
|
private markMedia;
|
|
334
339
|
/**
|
|
@@ -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 { assignSlots, ChildrenController, customElement, DelayController, deepContains, focusableElements, formatWords, HelixElement, HelixLoadMoreEvent, HelixReadEvent, hostAria, MixinCollection, markRegion, rovingStop, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { assignSlots, ChildrenController, customElement, DelayController, deepContains, focusableElements, formatWords, HelixElement, HelixLoadMoreEvent, HelixReadEvent, hostAria, MixinCollection, markRegion, rovingStop, UpgradeController, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { feedStep } from '../feed-keys.js';
|
|
@@ -24,6 +24,7 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
24
24
|
this.requestUpdate();
|
|
25
25
|
};
|
|
26
26
|
this.childWatch = new ChildrenController(this, this.handleSlotChange);
|
|
27
|
+
this.upgradeWatch = new UpgradeController(this, this.handleSlotChange);
|
|
27
28
|
this.handleRead = () => {
|
|
28
29
|
queueMicrotask(() => this.requestUpdate());
|
|
29
30
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DisabledCascadeController, HelixFormElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { DisabledCascadeController, HelixFormElement, KeyboardNavigationController, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { HelixHeadlessRadio } from '../root/radio-root.js';
|
|
4
4
|
declare const HelixHeadlessRadioGroup_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
@@ -123,6 +123,7 @@ export declare class HelixHeadlessRadioGroup extends HelixHeadlessRadioGroup_bas
|
|
|
123
123
|
*/
|
|
124
124
|
get items(): HelixHeadlessRadio[];
|
|
125
125
|
private observer;
|
|
126
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
126
127
|
/**
|
|
127
128
|
* Announces before it applies, so a listener can refuse the change.
|
|
128
129
|
*
|
|
@@ -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, DisabledCascadeController, HelixFormElement, hostAria, KeyboardNavigationController, MixinControllerValue, MixinField, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, DisabledCascadeController, HelixFormElement, hostAria, KeyboardNavigationController, MixinControllerValue, MixinField, UpgradeController, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessRadio } from '../root/radio-root.js';
|
|
@@ -22,6 +22,7 @@ let HelixHeadlessRadioGroup = class HelixHeadlessRadioGroup extends MixinControl
|
|
|
22
22
|
this.cascade = new DisabledCascadeController(this, {
|
|
23
23
|
items: () => this.items,
|
|
24
24
|
});
|
|
25
|
+
this.upgradeWatch = new UpgradeController(this, undefined, { subtree: true });
|
|
25
26
|
this.handleSelection = (event) => {
|
|
26
27
|
event.stopPropagation();
|
|
27
28
|
if (this.readOnly) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, type DataOptionItem, HelixFormElement, PopoverController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, type DataOptionItem, HelixFormElement, PopoverController, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { type HelixHeadlessOption } from '../../option/root/option-root.js';
|
|
4
4
|
import '../../listbox/index.js';
|
|
@@ -251,6 +251,13 @@ export declare class HelixHeadlessSelect extends HelixHeadlessSelect_base {
|
|
|
251
251
|
* be reached from the server and are left plain.
|
|
252
252
|
*/
|
|
253
253
|
private get listbox();
|
|
254
|
+
/**
|
|
255
|
+
* Hears an option upgrade after it arrived. The options are this element's
|
|
256
|
+
* children, which the listbox reaches through a slot and does not watch, so
|
|
257
|
+
* both read them again: the listbox to select the one `value` names, and this
|
|
258
|
+
* element for the words on its trigger.
|
|
259
|
+
*/
|
|
260
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
254
261
|
protected readonly panel: PopoverController;
|
|
255
262
|
/**
|
|
256
263
|
* What the trigger says: the chosen options' words, or the placeholder.
|
|
@@ -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, afterLinkFollowed, chosenValues, customElement, dataOptions, drawAutofill, drawStatus, HelixFormElement, hostAria, hostWords, isRtl, MixinControllerOpen, MixinControllerValue, MixinField, onApple, PopoverController, reportValues, StatusController, sideOf, typesCharacter, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, afterLinkFollowed, chosenValues, customElement, dataOptions, drawAutofill, drawStatus, HelixFormElement, hostAria, hostWords, isRtl, MixinControllerOpen, MixinControllerValue, MixinField, onApple, PopoverController, reportValues, StatusController, sideOf, typesCharacter, UpgradeController, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretDown } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -36,6 +36,10 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
36
36
|
this.placeholder = 'Choose';
|
|
37
37
|
this.position = 'floating';
|
|
38
38
|
this.valueMissingMessage = 'Choose one to continue.';
|
|
39
|
+
this.upgradeWatch = new UpgradeController(this, () => {
|
|
40
|
+
this.listbox?.requestUpdate();
|
|
41
|
+
this.requestUpdate();
|
|
42
|
+
}, { subtree: true });
|
|
39
43
|
this.panel = new PopoverController(this, {
|
|
40
44
|
anchor: () => this.partNamed('trigger'),
|
|
41
45
|
boundary: () => [
|
|
@@ -150,7 +150,13 @@ export declare class HelixHeadlessSteps extends HelixHeadlessSteps_base {
|
|
|
150
150
|
protected readonly keys: KeyboardNavigationController;
|
|
151
151
|
/** The steps, in the order the consumer wrote them. */
|
|
152
152
|
private get steps();
|
|
153
|
-
/**
|
|
153
|
+
/**
|
|
154
|
+
* The index of the stage the reader is on, or `-1`.
|
|
155
|
+
*
|
|
156
|
+
* Read from `active` once anything has set it, because a move writes
|
|
157
|
+
* `active` at once and each step's `current` only on the next update: two
|
|
158
|
+
* calls to `next()` in one task then move two stages.
|
|
159
|
+
*/
|
|
154
160
|
private get at();
|
|
155
161
|
/**
|
|
156
162
|
* Moves to the next stage that can be gone to, as Ark UI's `goToNextStep`
|
|
@@ -58,7 +58,12 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
|
|
|
58
58
|
return [...this.querySelectorAll(':scope > *')].filter((one) => 'current' in one);
|
|
59
59
|
}
|
|
60
60
|
get at() {
|
|
61
|
-
|
|
61
|
+
const steps = this.steps;
|
|
62
|
+
if (this.active === '') {
|
|
63
|
+
return steps.findIndex((step) => step.current);
|
|
64
|
+
}
|
|
65
|
+
const item = this.resolveActive(steps);
|
|
66
|
+
return item ? steps.indexOf(item) : -1;
|
|
62
67
|
}
|
|
63
68
|
next() {
|
|
64
69
|
return this.step(1);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement, KeyboardNavigationController, type SelectionMode } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, KeyboardNavigationController, type SelectionMode, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import { HelixHeadlessTag } from '../root/tag-root.js';
|
|
4
4
|
/** How many tags a group lets a reader select: core's `SelectionMode`. */
|
|
@@ -179,6 +179,8 @@ export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
|
179
179
|
*/
|
|
180
180
|
private readonly handleDismiss;
|
|
181
181
|
private readonly handleSlotchange;
|
|
182
|
+
/** Reads a tag again once it upgrades, so it takes its role and its place. */
|
|
183
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
182
184
|
private readonly handleFocusin;
|
|
183
185
|
connectedCallback(): void;
|
|
184
186
|
disconnectedCallback(): void;
|
|
@@ -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 { commaList, customElement, deepActiveElement, deepContains, focusItemOf, HelixElement, hostAria, KeyboardNavigationController, pressedValue, prunedValue, requestValue, rovingStop, slottedWords, typeaheadByWords, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { commaList, customElement, deepActiveElement, deepContains, focusItemOf, HelixElement, hostAria, KeyboardNavigationController, pressedValue, prunedValue, requestValue, rovingStop, slottedWords, typeaheadByWords, UpgradeController, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessTag } from '../root/tag-root.js';
|
|
@@ -126,6 +126,7 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
126
126
|
this.sync();
|
|
127
127
|
this.requestUpdate();
|
|
128
128
|
};
|
|
129
|
+
this.upgradeWatch = new UpgradeController(this, this.handleSlotchange);
|
|
129
130
|
this.handleFocusin = (event) => {
|
|
130
131
|
const tag = this.tagOf(event);
|
|
131
132
|
if (tag && tag !== this.last) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DisabledCascadeController, HelixFormElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { DisabledCascadeController, HelixFormElement, KeyboardNavigationController, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessToggleGroup_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
@@ -215,6 +215,7 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
|
|
|
215
215
|
*/
|
|
216
216
|
private get items();
|
|
217
217
|
private observer;
|
|
218
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
218
219
|
private readonly handleSelection;
|
|
219
220
|
/**
|
|
220
221
|
* Whether the group holds an answer the form can submit: a value an item
|
|
@@ -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 { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, reportValues, rovingStop, toggleValue, toolbarAround, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, reportValues, rovingStop, toggleValue, toolbarAround, UpgradeController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessToggle } from '../root/toggle-root.js';
|
|
@@ -35,6 +35,9 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
35
35
|
this.cascade = new DisabledCascadeController(this, {
|
|
36
36
|
items: () => this.items,
|
|
37
37
|
});
|
|
38
|
+
this.upgradeWatch = new UpgradeController(this, () => this.handleItems(), {
|
|
39
|
+
subtree: true,
|
|
40
|
+
});
|
|
38
41
|
this.handleSelection = (event) => {
|
|
39
42
|
queueMicrotask(() => {
|
|
40
43
|
if (event.defaultPrevented) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixElement, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTree_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerActiveInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -209,6 +209,7 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
209
209
|
/** Whether many items can be checked. */
|
|
210
210
|
private get multiple();
|
|
211
211
|
private watcher;
|
|
212
|
+
protected readonly upgradeWatch: UpgradeController;
|
|
212
213
|
/** The item that last had focus, so its removal can hand focus on. */
|
|
213
214
|
private focused;
|
|
214
215
|
/** The item last checked or unchecked, where a range Shift+Space checks starts. */
|
|
@@ -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, auditName, closestInstance, commaList, customElement, deepActiveElement, formatWords, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, ReorderController, requestReorder, scrollItemIntoView, selectsAll, slottedWords, Typeahead, treeArrow, typesCharacter, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, auditName, closestInstance, commaList, customElement, deepActiveElement, formatWords, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, ReorderController, requestReorder, scrollItemIntoView, selectsAll, slottedWords, Typeahead, treeArrow, typesCharacter, UpgradeController, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { fromGrip } from '../grip.js';
|
|
@@ -53,6 +53,9 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
53
53
|
});
|
|
54
54
|
this.pickedUpLabel = 'Picked up {name}';
|
|
55
55
|
this.reorderable = false;
|
|
56
|
+
this.upgradeWatch = new UpgradeController(this, () => this.syncItems(), {
|
|
57
|
+
subtree: true,
|
|
58
|
+
});
|
|
56
59
|
this.handleFocusIn = (event) => {
|
|
57
60
|
this.focused = event
|
|
58
61
|
.composedPath()
|