@fusion.dev/helix-headless 0.171.0 → 0.173.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 +1350 -124
- package/dist/button-group/root/button-group-root.d.ts +30 -0
- package/dist/button-group/root/button-group-root.js +50 -4
- package/dist/canvas/root/canvas-root.d.ts +7 -0
- package/dist/canvas/root/canvas-root.js +7 -0
- package/dist/chat/composer/chat-composer.d.ts +28 -1
- package/dist/chat/composer/chat-composer.js +22 -3
- package/dist/chat/root/chat-root.d.ts +38 -2
- package/dist/chat/root/chat-root.js +38 -1
- package/dist/color-input/root/color-input-root.d.ts +15 -1
- package/dist/color-input/root/color-input-root.js +19 -1
- package/dist/color-picker/root/color-picker-root.d.ts +5 -1
- package/dist/color-picker/root/color-picker-root.js +1 -1
- package/dist/copy-button/root/copy-button-root.d.ts +43 -3
- package/dist/copy-button/root/copy-button-root.js +49 -3
- package/dist/data-table/root/data-table-root.d.ts +5 -1
- package/dist/data-table/root/data-table-root.js +1 -0
- package/dist/dialog/root/dialog-root.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -0
- package/dist/drawer/root/drawer-root.js +1 -0
- package/dist/element-events.generated.js +3 -0
- package/dist/graph/root/graph-root.d.ts +22 -0
- package/dist/graph/root/graph-root.js +21 -5
- package/dist/lightbox/root/lightbox-root.js +1 -0
- package/dist/list/root/list-root.d.ts +6 -1
- package/dist/list/root/list-root.js +3 -2
- package/dist/listbox/root/listbox-root.d.ts +2 -1
- package/dist/listbox/root/listbox-root.js +3 -2
- package/dist/menu/item/menu-item.d.ts +2 -0
- package/dist/menu/item/menu-item.js +2 -0
- package/dist/menu/root/menu-root.d.ts +73 -12
- package/dist/menu/root/menu-root.js +103 -7
- package/dist/outline/root/outline-root.d.ts +57 -0
- package/dist/outline/root/outline-root.js +98 -29
- package/dist/popover/root/popover-root.d.ts +59 -6
- package/dist/popover/root/popover-root.js +51 -3
- package/dist/select/root/select-root.d.ts +2 -2
- package/dist/select/root/select-root.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +14 -0
- package/dist/speed-dial/root/speed-dial-root.js +34 -2
- package/dist/splitter/root/splitter-root.d.ts +25 -2
- package/dist/splitter/root/splitter-root.js +19 -4
- package/dist/tag/group/tag-group.d.ts +8 -1
- package/dist/tag/group/tag-group.js +8 -0
- package/dist/tag/root/tag-root.d.ts +12 -0
- package/dist/tag/root/tag-root.js +12 -0
- package/dist/textarea/root/textarea-root.d.ts +8 -0
- package/dist/textarea/root/textarea-root.js +16 -0
- package/dist/time-picker/root/time-picker-root.d.ts +14 -0
- package/dist/time-picker/root/time-picker-root.js +8 -1
- package/dist/timeline/item/timeline-item.d.ts +5 -1
- package/dist/timeline/item/timeline-item.js +9 -0
- package/dist/timeline/root/timeline-root.d.ts +23 -0
- package/dist/timeline/root/timeline-root.js +17 -3
- package/dist/tooltip/root/tooltip-root.d.ts +10 -0
- package/dist/tooltip/root/tooltip-root.js +14 -2
- package/dist/virtual-list/reorder/index.d.ts +1 -0
- package/dist/virtual-list/reorder/index.js +4 -0
- package/dist/virtual-list/reorder/virtual-list-reorder.d.ts +86 -0
- package/dist/virtual-list/reorder/virtual-list-reorder.js +193 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +49 -11
- package/dist/virtual-list/root/virtual-list-root.js +10 -1
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +880 -48
- package/types/vue.d.ts +174 -19
- package/types/words.d.ts +22 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Placement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
2
3
|
import { HelixHeadlessIconButton } from '../../icon-button/root/icon-button-root.js';
|
|
3
4
|
import '../../tooltip/index.js';
|
|
4
5
|
/**
|
|
@@ -31,7 +32,17 @@ import '../../tooltip/index.js';
|
|
|
31
32
|
* The button is named `label`, or the host's `aria-label`, and its name
|
|
32
33
|
* changes to `copied-label` or `error-label` for the moment after a press. The
|
|
33
34
|
* same words are said in a live region, so a screen reader hears the result,
|
|
34
|
-
* and the tooltip shows them.
|
|
35
|
+
* and the tooltip shows them. The tooltip does not also describe the button,
|
|
36
|
+
* since its words are the button's name.
|
|
37
|
+
*
|
|
38
|
+
* **The tooltip.** It shows the name on hover and focus and the result after a
|
|
39
|
+
* press. `tooltip="copy"` shows it only for the result, and `tooltip="none"`
|
|
40
|
+
* draws none, as Web Awesome's copy button offers. `tooltip-placement` is the
|
|
41
|
+
* side it prefers, and it moves to another side where that one does not fit.
|
|
42
|
+
*
|
|
43
|
+
* **Words on the button.** `show-label` draws the name beside the icon, and
|
|
44
|
+
* the result in its place after a press. The button is as wide as the longest
|
|
45
|
+
* of the three, so a press does not resize it.
|
|
35
46
|
*
|
|
36
47
|
* @since 0.1.0
|
|
37
48
|
* @status stable
|
|
@@ -50,6 +61,7 @@ import '../../tooltip/index.js';
|
|
|
50
61
|
* @csspart live - The live region that says `copied-label` or `error-label` after a press, and `pending-label` when the button becomes pending under focus. It is rendered from the first time it says anything.
|
|
51
62
|
* @csspart mark - The clipboard icon, and the confirmation icon that replaces it.
|
|
52
63
|
* @csspart spinner - The ring a pending button turns, an empty element the styled button draws over the icon. It is rendered only while the button is pending.
|
|
64
|
+
* @csspart text - The words beside the icon, under `show-label`. It holds all three, `label`, `copied-label` and `error-label`, with all but the current one hidden.
|
|
53
65
|
* @csspart tooltip - The tooltip bubble, forwarded from the tooltip inside the button.
|
|
54
66
|
* @csspart tooltip-arrow - The tooltip's arrow, which points at the button.
|
|
55
67
|
* @csspart tooltip-arrow-bottom - The arrow while the bubble is below the button, on the bubble's top edge. Set together with `tooltip-arrow`.
|
|
@@ -64,7 +76,6 @@ import '../../tooltip/index.js';
|
|
|
64
76
|
* @cssstate copied - The moment after a successful copy, while `copied-label` names the button.
|
|
65
77
|
* @cssstate failed - The moment after a press that put nothing on the clipboard, while `error-label` names the button.
|
|
66
78
|
*
|
|
67
|
-
* @withheld csspart text - Button's words, which this does not render: the label is the icon's name.
|
|
68
79
|
* @withheld slot end - Button's, which this does not render.
|
|
69
80
|
* @withheld slot start - Button's, which this does not render.
|
|
70
81
|
*/
|
|
@@ -106,6 +117,24 @@ export declare class HelixHeadlessCopyButton extends HelixHeadlessIconButton {
|
|
|
106
117
|
* world is called Copy. A consumer with a better word still sets it.
|
|
107
118
|
*/
|
|
108
119
|
label: string;
|
|
120
|
+
/**
|
|
121
|
+
* Draws the name as words beside the icon, and the result in their place
|
|
122
|
+
* after a press. The button stays as wide as the longest of them.
|
|
123
|
+
*/
|
|
124
|
+
showLabel: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* When the tooltip shows: `full` on hover and focus and after a press,
|
|
127
|
+
* `copy` only after a press, to show the result, and `none` never, for a
|
|
128
|
+
* button whose result shows another way, such as under `show-label`.
|
|
129
|
+
*
|
|
130
|
+
* Unset is `full`, and the attribute stays absent until you write it.
|
|
131
|
+
*/
|
|
132
|
+
tooltip?: 'copy' | 'full' | 'none';
|
|
133
|
+
/**
|
|
134
|
+
* The side the tooltip prefers. It moves to another side where this one
|
|
135
|
+
* does not fit.
|
|
136
|
+
*/
|
|
137
|
+
tooltipPlacement: Placement;
|
|
109
138
|
/**
|
|
110
139
|
* The text copied to the clipboard.
|
|
111
140
|
*
|
|
@@ -156,6 +185,9 @@ export declare class HelixHeadlessCopyButton extends HelixHeadlessIconButton {
|
|
|
156
185
|
*/
|
|
157
186
|
protected get forwardsLabel(): boolean;
|
|
158
187
|
protected willUpdate(changed: PropertyValues): void;
|
|
188
|
+
/** Whether the last render showed a result, so `tooltip="copy"` opens and closes on the change. */
|
|
189
|
+
private showedResult;
|
|
190
|
+
protected updated(changed: PropertyValues): void;
|
|
159
191
|
/** @internal A copy button never submits, so it is no form's default button. */
|
|
160
192
|
protected get submitsForm(): boolean;
|
|
161
193
|
/**
|
|
@@ -211,6 +243,14 @@ export declare class HelixHeadlessCopyButton extends HelixHeadlessIconButton {
|
|
|
211
243
|
protected renderCopiedIcon(): TemplateResult;
|
|
212
244
|
/** The mark for a press that put nothing on the clipboard, behind a seam of its own. */
|
|
213
245
|
protected renderFailedIcon(): TemplateResult;
|
|
246
|
+
/**
|
|
247
|
+
* The words beside the icon, under `show-label`, behind a seam of its own.
|
|
248
|
+
*
|
|
249
|
+
* All three are drawn and only the current one shows, so the button is as
|
|
250
|
+
* wide as the longest of them and a press does not resize it. Hidden from a
|
|
251
|
+
* screen reader, which hears the same words as the button's name.
|
|
252
|
+
*/
|
|
253
|
+
protected renderText(): TemplateResult | typeof nothing;
|
|
214
254
|
/**
|
|
215
255
|
* The bubble the control sits inside, behind a seam.
|
|
216
256
|
*
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessCopyButton_1;
|
|
8
|
-
import { CopyController, customElement, HelixCopyErrorEvent, words } from '@fusion.dev/helix-core';
|
|
8
|
+
import { CopyController, customElement, HelixCopyErrorEvent, words, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { check, copy, x } from '@fusion.dev/helix-icons';
|
|
10
10
|
import { nothing } from 'lit';
|
|
11
11
|
import { property } from 'lit/decorators.js';
|
|
@@ -22,8 +22,11 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
22
22
|
this.feedbackDuration = 1600;
|
|
23
23
|
this.from = '';
|
|
24
24
|
this.label = 'Copy';
|
|
25
|
+
this.showLabel = false;
|
|
26
|
+
this.tooltipPlacement = 'top';
|
|
25
27
|
this.value = '';
|
|
26
28
|
this.namedBy = null;
|
|
29
|
+
this.showedResult = false;
|
|
27
30
|
this.clipboard = new CopyController(this, { after: () => this.feedbackDuration });
|
|
28
31
|
this.handleCopy = async (event) => {
|
|
29
32
|
if (this.pending) {
|
|
@@ -62,6 +65,24 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
62
65
|
this.toggleState('copied', this.copied);
|
|
63
66
|
this.toggleState('failed', this.failed);
|
|
64
67
|
}
|
|
68
|
+
updated(changed) {
|
|
69
|
+
super.updated(changed);
|
|
70
|
+
const result = this.copied || this.failed;
|
|
71
|
+
if (result === this.showedResult) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.showedResult = result;
|
|
75
|
+
if (this.tooltip !== 'copy') {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const tip = this.renderRoot.querySelector('[data-copy-tooltip]');
|
|
79
|
+
if (result) {
|
|
80
|
+
tip?.show();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
tip?.hide();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
65
86
|
get submitsForm() {
|
|
66
87
|
return false;
|
|
67
88
|
}
|
|
@@ -94,7 +115,7 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
94
115
|
@keydown=${this.notePress}
|
|
95
116
|
@pointerdown=${this.notePress}
|
|
96
117
|
>
|
|
97
|
-
${this.renderCopiedIcon()} ${this.renderFailedIcon()} ${this.renderCopyIcon()}${this.renderSpinner()}
|
|
118
|
+
${this.renderCopiedIcon()} ${this.renderFailedIcon()} ${this.renderCopyIcon()}${this.renderSpinner()}${this.renderText()}
|
|
98
119
|
</button>`)}${this.renderLive()}`;
|
|
99
120
|
}
|
|
100
121
|
renderCopyIcon() {
|
|
@@ -112,8 +133,24 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
112
133
|
>${HelixHeadlessCopyButton_1.icon(x)}</slot
|
|
113
134
|
>`;
|
|
114
135
|
}
|
|
136
|
+
renderText() {
|
|
137
|
+
if (!this.showLabel) {
|
|
138
|
+
return nothing;
|
|
139
|
+
}
|
|
140
|
+
const resting = !this.copied && !this.failed;
|
|
141
|
+
return html `<span part="text" aria-hidden="true"
|
|
142
|
+
><span ?hidden=${!resting}>${this.namedBy || this.label}</span
|
|
143
|
+
><span ?hidden=${!this.copied}>${this.copiedLabel}</span
|
|
144
|
+
><span ?hidden=${!this.failed}>${this.errorLabel}</span
|
|
145
|
+
></span>`;
|
|
146
|
+
}
|
|
115
147
|
renderTooltip(control) {
|
|
116
|
-
|
|
148
|
+
if (this.tooltip === 'none') {
|
|
149
|
+
return control;
|
|
150
|
+
}
|
|
151
|
+
const content = this.tooltip === 'copy' && !this.copied && !this.failed ? '' : this.says;
|
|
152
|
+
return html `<${this.tag('tooltip')} content=${content} persist
|
|
153
|
+
data-copy-tooltip placement=${this.tooltipPlacement}
|
|
117
154
|
exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom,
|
|
118
155
|
arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right,
|
|
119
156
|
arrow-top: tooltip-arrow-top, tooltip, tooltip-bottom, tooltip-left, tooltip-right,
|
|
@@ -140,6 +177,15 @@ __decorate([
|
|
|
140
177
|
words,
|
|
141
178
|
property()
|
|
142
179
|
], HelixHeadlessCopyButton.prototype, "label", void 0);
|
|
180
|
+
__decorate([
|
|
181
|
+
property({ attribute: 'show-label', reflect: true, type: Boolean })
|
|
182
|
+
], HelixHeadlessCopyButton.prototype, "showLabel", void 0);
|
|
183
|
+
__decorate([
|
|
184
|
+
property()
|
|
185
|
+
], HelixHeadlessCopyButton.prototype, "tooltip", void 0);
|
|
186
|
+
__decorate([
|
|
187
|
+
property({ attribute: 'tooltip-placement' })
|
|
188
|
+
], HelixHeadlessCopyButton.prototype, "tooltipPlacement", void 0);
|
|
143
189
|
__decorate([
|
|
144
190
|
property()
|
|
145
191
|
], HelixHeadlessCopyButton.prototype, "value", void 0);
|
|
@@ -208,7 +208,7 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
|
|
|
208
208
|
* @csspart select - The cell that holds a row's checkbox.
|
|
209
209
|
* @csspart select-all - The heading that holds the checkbox that selects every row.
|
|
210
210
|
* @csspart select-selected - Added to `select` in a selected row.
|
|
211
|
-
* @csspart table - The grid.
|
|
211
|
+
* @csspart table - The grid. While `windowed`, the box that scrolls, which needs only a block size on this tier.
|
|
212
212
|
* @csspart toggle - The mark in a row header that a press opens and closes its row by, in a tree grid.
|
|
213
213
|
* @csspart toggle-mark - The caret in `toggle`. It points along the line while the row is closed and down while it is open.
|
|
214
214
|
* @csspart toggle-open - Added to `toggle` while its row is open.
|
|
@@ -586,6 +586,10 @@ export declare class HelixHeadlessDataTable extends HelixHeadlessDataTable_base
|
|
|
586
586
|
* Off by default. Windowing costs a scroll listener, a measurement per row
|
|
587
587
|
* drawn, and a `block-size` on the scrolling box, and a table of twenty rows
|
|
588
588
|
* should pay none of them.
|
|
589
|
+
*
|
|
590
|
+
* While windowed, the `table` part scrolls on this tier: it carries
|
|
591
|
+
* `data-scroller`, and `core` ships `[data-scroller] { overflow: auto }` into
|
|
592
|
+
* every shadow root. You still need to give it a block size.
|
|
589
593
|
*/
|
|
590
594
|
windowed: boolean;
|
|
591
595
|
private sortState;
|
|
@@ -1228,6 +1228,7 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
1228
1228
|
part="table"
|
|
1229
1229
|
role="rowgroup"
|
|
1230
1230
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
1231
|
+
?data-scroller=${this.windowed}
|
|
1231
1232
|
style=${template ? `--data-table-template: ${template}` : nothing}
|
|
1232
1233
|
@scroll=${this.handleScroll}
|
|
1233
1234
|
>
|
|
@@ -74,6 +74,10 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
|
|
|
74
74
|
* <helix-headless-drawer id="nav">…</helix-headless-drawer>
|
|
75
75
|
* ```
|
|
76
76
|
*
|
|
77
|
+
* From its first press, a button that opens the drawer this way says whether
|
|
78
|
+
* the drawer is open: a Helix button through `expanded`, and any other
|
|
79
|
+
* element with `aria-expanded`.
|
|
80
|
+
*
|
|
77
81
|
* @since 0.1.0
|
|
78
82
|
* @status stable
|
|
79
83
|
* @category overlays
|
|
@@ -19,6 +19,7 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
|
|
|
19
19
|
'--show': () => this.requestOpen(true),
|
|
20
20
|
'--toggle': () => this.toggleOpen(),
|
|
21
21
|
},
|
|
22
|
+
expanded: () => this.open,
|
|
22
23
|
});
|
|
23
24
|
this.dismissible = false;
|
|
24
25
|
this.dismissLabel = 'Close';
|
|
@@ -196,6 +196,7 @@ registerElementEvents({
|
|
|
196
196
|
'helix-headless-map-terrain': ['helix-map-part-change'],
|
|
197
197
|
'helix-headless-megamenu': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
198
198
|
'helix-headless-menu': [
|
|
199
|
+
'change',
|
|
199
200
|
'helix-before-close',
|
|
200
201
|
'helix-before-open',
|
|
201
202
|
'helix-filter',
|
|
@@ -362,7 +363,9 @@ registerElementEvents({
|
|
|
362
363
|
'helix-headless-virtual-list': [
|
|
363
364
|
'change',
|
|
364
365
|
'helix-before-change',
|
|
366
|
+
'helix-before-reorder',
|
|
365
367
|
'helix-load-more',
|
|
366
368
|
'helix-range-change',
|
|
369
|
+
'helix-reorder',
|
|
367
370
|
],
|
|
368
371
|
});
|
|
@@ -44,6 +44,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
44
44
|
* @slot footer - Content below the graph.
|
|
45
45
|
* @slot fullscreen-icon - Replaces the glyph inside the fullscreen button.
|
|
46
46
|
* @slot header - Content above the graph.
|
|
47
|
+
* @slot loading - What the panel shows while `loading` is set and the list holds no notes. Defaults to `loading-label`.
|
|
47
48
|
* @slot pan-down-icon - Replaces the glyph inside the pan down button.
|
|
48
49
|
* @slot pan-end-icon - Replaces the glyph inside the button that pans toward the end of a line of text.
|
|
49
50
|
* @slot pan-start-icon - Replaces the glyph inside the button that pans toward the start of a line of text.
|
|
@@ -80,6 +81,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
80
81
|
* @csspart legend-swatch - The mark in a group's color, before its name.
|
|
81
82
|
* @csspart list - The list of notes, which draws only the rows in view.
|
|
82
83
|
* @csspart live - What screen readers hear: how many notes there are when a search or the legend changes it, and which way the drawing went after a key or a control moved it.
|
|
84
|
+
* @csspart loading - The box in place of the list while `loading` is set and it holds no notes, holding the `loading` slot.
|
|
83
85
|
* @csspart note - One note in the list.
|
|
84
86
|
* @csspart note-cursor - The note the keyboard is on in the list.
|
|
85
87
|
* @csspart note-linked - A note linked to or from the selected one.
|
|
@@ -103,6 +105,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
103
105
|
* @cssstate empty - The list holds no notes: the graph has none, or a search or the groups hid them all.
|
|
104
106
|
* @cssstate fullscreen - The graph fills the screen.
|
|
105
107
|
* @cssstate idle - The user has been still long enough for the header and footer to fade.
|
|
108
|
+
* @cssstate loading - While `loading` is set.
|
|
106
109
|
* @cssstate local - The drawing shows the selected note's local graph, with `depth`.
|
|
107
110
|
* @cssstate panel-open - A graph with `no-panel` has the search and the list open over the drawing.
|
|
108
111
|
* @cssstate ready - The graph has been drawn whole, after `helix-graph-ready`.
|
|
@@ -169,6 +172,13 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
169
172
|
links: readonly GraphLink[];
|
|
170
173
|
/** How a note that links to the selected one is described, with `{note}`. */
|
|
171
174
|
linksToLabel: string;
|
|
175
|
+
/**
|
|
176
|
+
* Marks the graph as busy while its notes arrive: the list is `aria-busy`,
|
|
177
|
+
* and the panel says so where it holds no notes yet.
|
|
178
|
+
*/
|
|
179
|
+
loading: boolean;
|
|
180
|
+
/** What the panel says while `loading` is set and the list holds no notes. */
|
|
181
|
+
loadingLabel: string;
|
|
172
182
|
/** What screen readers hear once the drawing has moved down, after `moved()`. */
|
|
173
183
|
movedDownLabel: string;
|
|
174
184
|
/** What screen readers hear once the drawing has moved left, after `moved()`. */
|
|
@@ -185,6 +195,18 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
185
195
|
* such as at the top of a page, where the drawing takes the whole frame.
|
|
186
196
|
*/
|
|
187
197
|
noPanel: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* What each note's row in the list shows in place of its name: a function
|
|
200
|
+
* given the note that returns text, an element or a Lit template.
|
|
201
|
+
*
|
|
202
|
+
* For an icon by its kind, or a date under its name, as React Aria's
|
|
203
|
+
* `ListBoxItem` takes children. The row is still named by the note's name,
|
|
204
|
+
* which typeahead and the search find it by, and described by how it stands
|
|
205
|
+
* to the selected note. Return the name with your content where it should
|
|
206
|
+
* still show. A property only, there being no way to write a function in
|
|
207
|
+
* markup.
|
|
208
|
+
*/
|
|
209
|
+
noteContent?: ((node: GraphNode) => unknown) | undefined;
|
|
188
210
|
/** The list's name, read by screen readers, and the name of the button that opens it with `no-panel`. */
|
|
189
211
|
notesLabel: string;
|
|
190
212
|
/**
|
|
@@ -27,6 +27,8 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
27
27
|
this.linkedFromLabel = 'Linked from {note}';
|
|
28
28
|
this.links = [];
|
|
29
29
|
this.linksToLabel = 'Links to {note}';
|
|
30
|
+
this.loading = false;
|
|
31
|
+
this.loadingLabel = 'Loading notes';
|
|
30
32
|
this.movedDownLabel = 'Moved down';
|
|
31
33
|
this.movedLeftLabel = 'Moved left';
|
|
32
34
|
this.movedRightLabel = 'Moved right';
|
|
@@ -163,6 +165,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
163
165
|
super.willUpdate(changed);
|
|
164
166
|
this.toggleState('fullscreen', this.filled);
|
|
165
167
|
this.toggleState('idle', this.resting);
|
|
168
|
+
this.toggleState('loading', this.loading);
|
|
166
169
|
this.toggleState('panel-open', this.noPanel && this.panelOpen);
|
|
167
170
|
this.toggleState('searching', this.query.trim() !== '');
|
|
168
171
|
this.toggleState('selected', this.active !== '');
|
|
@@ -389,14 +392,15 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
389
392
|
aria-selected=${chosen ? 'true' : 'false'}
|
|
390
393
|
aria-posinset=${index + 1}
|
|
391
394
|
aria-setsize=${total}
|
|
392
|
-
aria-
|
|
395
|
+
aria-describedby=${relation ? `note-${index}-relation` : nothing}
|
|
396
|
+
aria-label=${this.noteContent ? nameOf(entry.node) : nothing}
|
|
393
397
|
@click=${() => {
|
|
394
398
|
this.cursor = index;
|
|
395
399
|
this.choose(index);
|
|
396
400
|
}}
|
|
397
401
|
>
|
|
398
|
-
<span part="note-name">${nameOf(entry.node)}</span>
|
|
399
|
-
${relation ? html `<span part="note-relation" aria-hidden="true">${relation}</span>` : nothing}
|
|
402
|
+
<span part="note-name">${this.noteContent ? this.noteContent(entry.node) : nameOf(entry.node)}</span>
|
|
403
|
+
${relation ? html `<span part="note-relation" id=${`note-${index}-relation`} aria-hidden="true">${relation}</span>` : nothing}
|
|
400
404
|
</div>`;
|
|
401
405
|
})}`;
|
|
402
406
|
}
|
|
@@ -458,7 +462,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
458
462
|
data-scroller
|
|
459
463
|
aria-label=${this.notesLabel}
|
|
460
464
|
aria-activedescendant=${cursor}
|
|
461
|
-
aria-
|
|
465
|
+
aria-busy=${this.loading ? 'true' : nothing}
|
|
462
466
|
@keydown=${this.handleListKeydown}
|
|
463
467
|
@scroll=${() => this.virtualize.measure()}
|
|
464
468
|
>
|
|
@@ -467,7 +471,9 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
467
471
|
<div part="after" role="presentation" style="block-size: ${after}px"></div>
|
|
468
472
|
</div>
|
|
469
473
|
${this.entries.length === 0
|
|
470
|
-
?
|
|
474
|
+
? this.loading
|
|
475
|
+
? html `<div part="loading"><slot name="loading">${this.loadingLabel}</slot></div>`
|
|
476
|
+
: html `<div part="empty"><slot name="empty">${this.emptyLabel}</slot></div>`
|
|
471
477
|
: nothing}
|
|
472
478
|
</div>
|
|
473
479
|
</div>
|
|
@@ -529,6 +535,13 @@ __decorate([
|
|
|
529
535
|
words,
|
|
530
536
|
property({ attribute: 'links-to-label' })
|
|
531
537
|
], HelixHeadlessGraph.prototype, "linksToLabel", void 0);
|
|
538
|
+
__decorate([
|
|
539
|
+
property({ reflect: true, type: Boolean })
|
|
540
|
+
], HelixHeadlessGraph.prototype, "loading", void 0);
|
|
541
|
+
__decorate([
|
|
542
|
+
words,
|
|
543
|
+
property({ attribute: 'loading-label' })
|
|
544
|
+
], HelixHeadlessGraph.prototype, "loadingLabel", void 0);
|
|
532
545
|
__decorate([
|
|
533
546
|
words,
|
|
534
547
|
property({ attribute: 'moved-down-label' })
|
|
@@ -551,6 +564,9 @@ __decorate([
|
|
|
551
564
|
__decorate([
|
|
552
565
|
property({ attribute: 'no-panel', reflect: true, type: Boolean })
|
|
553
566
|
], HelixHeadlessGraph.prototype, "noPanel", void 0);
|
|
567
|
+
__decorate([
|
|
568
|
+
property({ attribute: false })
|
|
569
|
+
], HelixHeadlessGraph.prototype, "noteContent", void 0);
|
|
554
570
|
__decorate([
|
|
555
571
|
words,
|
|
556
572
|
property({ attribute: 'notes-label' })
|
|
@@ -244,7 +244,8 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
244
244
|
/**
|
|
245
245
|
* The selected rows' values, separated by commas with no spaces, such as `a,c`, in a list that selects.
|
|
246
246
|
*
|
|
247
|
-
*
|
|
247
|
+
* A press or a key writes it in row order, as Data Table does, whatever
|
|
248
|
+
* order the rows were chosen in. Set it to start with rows selected. A row's value is its `value`, or its
|
|
248
249
|
* words where it has none.
|
|
249
250
|
*/
|
|
250
251
|
value: string;
|
|
@@ -328,6 +329,10 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
328
329
|
/**
|
|
329
330
|
* Selects what a press or a key leaves, asking first. `helix-before-change`
|
|
330
331
|
* carries the `value` it would leave, and `change` follows once it has moved.
|
|
332
|
+
*
|
|
333
|
+
* In row order, as Data Table and Table write theirs, whatever order the
|
|
334
|
+
* rows were chosen in: a press on the fourth row and then the first is
|
|
335
|
+
* `a,d`.
|
|
331
336
|
*/
|
|
332
337
|
private choose;
|
|
333
338
|
/** What `choiceValue` needs of this list for a row. */
|
|
@@ -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 { auditName, commaList, customElement, deepActiveElement, drawStatus, focusItemOf, formatWords, HelixActionEvent, HelixElement, HelixLoadMoreEvent, hostAria, inlineStep, KeyboardNavigationController, placeKey, pressedOwnControl, ReorderController, requestReorder, requestValue, rovingStop, StatusController, scrollingAncestor, scrollRoom, selectsAll, typeaheadByWords, UpgradeController, whenHydrated, words, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { auditName, commaList, customElement, deepActiveElement, drawStatus, focusItemOf, formatWords, HelixActionEvent, HelixElement, HelixLoadMoreEvent, hostAria, inlineStep, inRowOrder, KeyboardNavigationController, placeKey, pressedOwnControl, ReorderController, requestReorder, requestValue, rovingStop, StatusController, scrollingAncestor, scrollRoom, selectsAll, 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 { HelixHeadlessListItem } from '../item/list-item.js';
|
|
@@ -262,7 +262,8 @@ let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
|
|
|
262
262
|
if (next === null) {
|
|
263
263
|
return;
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
const ordered = inRowOrder(commaList(next), this.rows.map((row) => this.valueFor(row))).join(',');
|
|
266
|
+
requestValue(this, ordered, (value) => {
|
|
266
267
|
this.value = value;
|
|
267
268
|
});
|
|
268
269
|
}
|
|
@@ -394,7 +394,8 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
394
394
|
* sounded the same. Said when the filter changes and the count with it, so
|
|
395
395
|
* a keystroke that leaves the same options says nothing new. An empty filter
|
|
396
396
|
* says nothing, being the list as it was given; no matches is `empty-text`,
|
|
397
|
-
* which the region says in place of this.
|
|
397
|
+
* which the region says in place of this. A load that ends says the count
|
|
398
|
+
* too, whatever the filter.
|
|
398
399
|
*/
|
|
399
400
|
private tell;
|
|
400
401
|
/**
|
|
@@ -260,13 +260,14 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
260
260
|
if (!this.hasUpdated) {
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
|
-
|
|
263
|
+
const loaded = changed.get('loading') === true && !this.loading;
|
|
264
|
+
if (!changed.has('filter') && !loaded) {
|
|
264
265
|
this.tellActive(changed);
|
|
265
266
|
return;
|
|
266
267
|
}
|
|
267
268
|
const count = this.shown.length;
|
|
268
269
|
this.announced =
|
|
269
|
-
this.filter.trim() && count
|
|
270
|
+
(this.filter.trim() || loaded) && count
|
|
270
271
|
? this.resultLabel
|
|
271
272
|
? countLabel(count, this.resultLabel, this.resultsLabel, wordsLocale(this))
|
|
272
273
|
: formatWords(this, 'resultsLabel', { count })
|
|
@@ -81,6 +81,8 @@ import '../../kbd/index.js';
|
|
|
81
81
|
* @csspart surface - The panel a submenu opens in beside the row, under the menu's `submenus="flyout"`.
|
|
82
82
|
*
|
|
83
83
|
* @cssstate checked - The row is checked.
|
|
84
|
+
* @cssstate disabled - The row is disabled.
|
|
85
|
+
* @cssstate expanded - Under `submenus="flyout"`, the row's submenu is open beside it.
|
|
84
86
|
* @cssstate highlighted - In a menu with `filterable`, the arrow keys or the pointer reached the row while focus stays in the filter field.
|
|
85
87
|
* @cssstate submenu-mark - Under `submenus="flyout"`, a row in this row's submenu can be ticked or opens a submenu, so the submenu keeps its trailing column.
|
|
86
88
|
* @cssstate submenu-start - Under `submenus="flyout"`, a row in this row's submenu has content before its label, so the submenu keeps its leading column.
|
|
@@ -93,6 +93,8 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
93
93
|
super.willUpdate(changed);
|
|
94
94
|
this.toggleState('checked', this.checked);
|
|
95
95
|
this.toggleState('highlighted', this.virtual && this.highlighted);
|
|
96
|
+
this.toggleState('disabled', this.disabled);
|
|
97
|
+
this.toggleState('expanded', this.expanded);
|
|
96
98
|
if (!this.childrenKnown) {
|
|
97
99
|
return;
|
|
98
100
|
}
|