@fusion.dev/helix-headless 0.144.0 → 0.145.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +8312 -881
- package/dist/accordion/item/accordion-item.d.ts +48 -12
- package/dist/accordion/item/accordion-item.js +26 -5
- package/dist/accordion/root/accordion-root.d.ts +6 -0
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +21 -1
- package/dist/announcement/root/announcement-root.js +36 -1
- package/dist/app-header/root/app-header-root.d.ts +7 -0
- package/dist/app-header/root/app-header-root.js +5 -1
- package/dist/app-header/sectioning.d.ts +7 -0
- package/dist/app-header/sectioning.js +26 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +121 -40
- package/dist/carousel/root/carousel-root.d.ts +90 -0
- package/dist/carousel/root/carousel-root.js +134 -12
- package/dist/chat/composer/chat-composer.d.ts +38 -6
- package/dist/chat/composer/chat-composer.js +42 -9
- package/dist/chat/message/chat-message.d.ts +32 -1
- package/dist/chat/message/chat-message.js +25 -9
- package/dist/chat/naming.d.ts +22 -0
- package/dist/chat/naming.js +12 -0
- package/dist/chat/relative-clock.d.ts +39 -0
- package/dist/chat/relative-clock.js +31 -0
- package/dist/chat/root/chat-root.d.ts +36 -0
- package/dist/chat/root/chat-root.js +24 -1
- package/dist/code-block/root/code-block-root.d.ts +8 -1
- package/dist/code-block/root/code-block-root.js +5 -5
- package/dist/copy-button/root/copy-button-root.d.ts +21 -1
- package/dist/copy-button/root/copy-button-root.js +2 -2
- package/dist/data-table/root/data-table-root.d.ts +150 -2
- package/dist/data-table/root/data-table-root.js +303 -29
- package/dist/data-table/tree.d.ts +40 -0
- package/dist/data-table/tree.js +55 -0
- package/dist/description-list/item/description-list-item.d.ts +17 -2
- package/dist/description-list/item/description-list-item.js +15 -2
- package/dist/description-list/root/description-list-root.d.ts +27 -1
- package/dist/description-list/root/description-list-root.js +26 -1
- package/dist/drilldown/item/drilldown-item.d.ts +11 -6
- package/dist/drilldown/item/drilldown-item.js +8 -5
- package/dist/drilldown/root/drilldown-root.d.ts +11 -0
- package/dist/drilldown/root/drilldown-root.js +8 -3
- package/dist/element-events.generated.js +53 -8
- package/dist/filter-input/menu/filter-menu.d.ts +3 -0
- package/dist/filter-input/menu/filter-menu.js +8 -4
- package/dist/image/root/image-root.js +9 -1
- package/dist/input/root/input-root.d.ts +1 -1
- package/dist/input/root/input-root.js +2 -2
- package/dist/list/item/list-item.d.ts +68 -1
- package/dist/list/item/list-item.js +66 -4
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +106 -9
- package/dist/list/root/list-root.js +189 -4
- package/dist/list/selection.d.ts +19 -0
- package/dist/list/selection.js +21 -0
- package/dist/listbox/root/listbox-root.js +1 -2
- package/dist/map/root/map-root.d.ts +6 -2
- package/dist/map/root/map-root.js +5 -2
- package/dist/megamenu/root/megamenu-root.d.ts +21 -0
- package/dist/megamenu/root/megamenu-root.js +16 -2
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +38 -11
- package/dist/menu/item/menu-item.js +33 -1
- package/dist/menu/root/menu-root.d.ts +25 -1
- package/dist/menu/root/menu-root.js +63 -6
- package/dist/menu/section/menu-section.d.ts +55 -0
- package/dist/menu/section/menu-section.js +60 -0
- package/dist/navigation/root/navigation-root.d.ts +16 -1
- package/dist/navigation/root/navigation-root.js +27 -1
- package/dist/notifications/root/notifications-root.d.ts +18 -0
- package/dist/notifications/root/notifications-root.js +17 -1
- package/dist/object-inspector/root/object-inspector-root.d.ts +97 -16
- package/dist/object-inspector/root/object-inspector-root.js +179 -79
- package/dist/object-inspector/rows.d.ts +57 -0
- package/dist/object-inspector/rows.js +86 -0
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +68 -3
- package/dist/outline/root/outline-root.js +73 -8
- package/dist/pagination/size/pagination-size.d.ts +11 -2
- package/dist/pagination/size/pagination-size.js +19 -4
- package/dist/radio/group/radio-group.d.ts +4 -10
- package/dist/radio/group/radio-group.js +5 -10
- package/dist/rating/root/rating-root.d.ts +1 -1
- package/dist/rating/root/rating-root.js +2 -2
- package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
- package/dist/scroll-area/root/scroll-area-root.js +218 -3
- package/dist/scroll-area/scrollbar.d.ts +65 -0
- package/dist/scroll-area/scrollbar.js +24 -0
- package/dist/select/root/select-root.js +1 -1
- package/dist/splitter/root/splitter-root.d.ts +13 -0
- package/dist/splitter/root/splitter-root.js +20 -2
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/steps/reach.d.ts +15 -0
- package/dist/steps/reach.js +12 -0
- package/dist/steps/root/steps-root.d.ts +30 -0
- package/dist/steps/root/steps-root.js +53 -0
- package/dist/steps/step/step.d.ts +38 -2
- package/dist/steps/step/step.js +28 -6
- package/dist/table/column/table-column.d.ts +11 -0
- package/dist/table/column/table-column.js +6 -1
- package/dist/table/root/table-root.d.ts +101 -0
- package/dist/table/root/table-root.js +166 -5
- package/dist/table/row/table-row.d.ts +47 -1
- package/dist/table/row/table-row.js +39 -2
- package/dist/tabs/panel/tab-panel.d.ts +9 -5
- package/dist/tabs/panel/tab-panel.js +3 -4
- package/dist/tabs/root/tabs-root.d.ts +25 -1
- package/dist/tabs/root/tabs-root.js +21 -3
- package/dist/tabs/tab/tab.d.ts +36 -4
- package/dist/tabs/tab/tab.js +46 -3
- package/dist/timeline/group/timeline-group.d.ts +46 -0
- package/dist/timeline/group/timeline-group.js +37 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +1 -0
- package/dist/timeline/root/timeline-root.d.ts +10 -3
- package/dist/toast/item/toast-item.d.ts +10 -17
- package/dist/toast/item/toast-item.js +15 -36
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- package/dist/tree/item/tree-item.d.ts +54 -1
- package/dist/tree/item/tree-item.js +89 -20
- package/dist/tree/root/tree-root.d.ts +37 -0
- package/dist/tree/root/tree-root.js +51 -6
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +26 -0
- package/dist/video/media-events.d.ts +49 -0
- package/dist/video/media-events.js +39 -0
- package/dist/video/root/video-root.d.ts +99 -13
- package/dist/video/root/video-root.js +84 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
- package/dist/video-playlist/root/video-playlist-root.js +60 -16
- package/dist/virtual-list/controls.d.ts +4 -0
- package/dist/virtual-list/controls.js +30 -0
- package/dist/virtual-list/fill.d.ts +30 -0
- package/dist/virtual-list/fill.js +39 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
- package/dist/virtual-list/root/virtual-list-root.js +175 -34
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +3778 -801
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +782 -215
- package/dist/listbox/range.d.ts +0 -17
- package/dist/listbox/range.js +0 -5
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, HelixElement } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property, state } from 'lit/decorators.js';
|
|
10
|
+
let HelixHeadlessMenuSection = class HelixHeadlessMenuSection extends HelixElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.label = '';
|
|
14
|
+
this.onPage = true;
|
|
15
|
+
this.isMenuSection = true;
|
|
16
|
+
this.heading = false;
|
|
17
|
+
this.readHeading = (event) => {
|
|
18
|
+
this.heading = event.target.assignedNodes().length > 0;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
willUpdate(changed) {
|
|
22
|
+
super.willUpdate(changed);
|
|
23
|
+
if (this.childrenKnown) {
|
|
24
|
+
this.heading = this.knownChildren.some((child) => child.slot === 'heading');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
firstUpdated(changed) {
|
|
28
|
+
super.firstUpdated(changed);
|
|
29
|
+
this.finishHydration();
|
|
30
|
+
}
|
|
31
|
+
render() {
|
|
32
|
+
if (!this.onPage) {
|
|
33
|
+
return nothing;
|
|
34
|
+
}
|
|
35
|
+
return html `<div part="section" role="group" aria-labelledby="heading">
|
|
36
|
+
<div
|
|
37
|
+
id="heading"
|
|
38
|
+
part="heading"
|
|
39
|
+
role="presentation"
|
|
40
|
+
?hidden=${this.label === '' && !this.heading}
|
|
41
|
+
>
|
|
42
|
+
<slot name="heading" @slotchange=${this.readHeading}>${this.label}</slot>
|
|
43
|
+
</div>
|
|
44
|
+
<slot></slot>
|
|
45
|
+
</div>`;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
__decorate([
|
|
49
|
+
property()
|
|
50
|
+
], HelixHeadlessMenuSection.prototype, "label", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
property({ attribute: false })
|
|
53
|
+
], HelixHeadlessMenuSection.prototype, "onPage", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
state()
|
|
56
|
+
], HelixHeadlessMenuSection.prototype, "heading", void 0);
|
|
57
|
+
HelixHeadlessMenuSection = __decorate([
|
|
58
|
+
customElement('helix-headless-menu-section')
|
|
59
|
+
], HelixHeadlessMenuSection);
|
|
60
|
+
export { HelixHeadlessMenuSection };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary A set of destinations, with a marker on the current one.
|
|
@@ -22,6 +22,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
22
22
|
* Set `orientation="vertical"` to stack the destinations in a column, for a
|
|
23
23
|
* sidebar.
|
|
24
24
|
*
|
|
25
|
+
* Set `arrows` and the arrow keys move focus between the destinations, as
|
|
26
|
+
* Radix's navigation menu does: left and right along a row, up and down a
|
|
27
|
+
* column, Home and End to the ends. A `Megamenu` among them is reached at its
|
|
28
|
+
* trigger. Tab still stops at every link, since a navigation is a list of
|
|
29
|
+
* links and not a single control, and the keys across the other axis are
|
|
30
|
+
* left to the page and to an open panel.
|
|
31
|
+
*
|
|
25
32
|
* @since 0.1.0
|
|
26
33
|
* @status stable
|
|
27
34
|
* @category navigation
|
|
@@ -35,6 +42,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
35
42
|
*/
|
|
36
43
|
export declare class HelixHeadlessNavigation extends HelixElement {
|
|
37
44
|
private readonly indicator;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the arrow keys move focus between the destinations.
|
|
47
|
+
*
|
|
48
|
+
* Off by default, so a page whose readers scroll with the arrow keys while
|
|
49
|
+
* a link has focus keeps doing so.
|
|
50
|
+
*/
|
|
51
|
+
arrows: boolean;
|
|
38
52
|
/**
|
|
39
53
|
* The landmark's name, read by screen readers.
|
|
40
54
|
*
|
|
@@ -43,6 +57,7 @@ export declare class HelixHeadlessNavigation extends HelixElement {
|
|
|
43
57
|
* second "Main".
|
|
44
58
|
*/
|
|
45
59
|
label: string;
|
|
60
|
+
protected readonly keys: KeyboardNavigationController;
|
|
46
61
|
/** Carries a host `aria-label` and `aria-labelledby` to the `<nav>`. */
|
|
47
62
|
protected readonly aria: AriaForwardController;
|
|
48
63
|
/**
|
|
@@ -4,9 +4,24 @@ 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, HelixElement, IndicatorController, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, focusableElements, HelixElement, IndicatorController, KeyboardNavigationController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
const FOCUSABLE = 'a[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
11
|
+
const navigable = (item) => {
|
|
12
|
+
const control = () => item.navigationControl ??
|
|
13
|
+
(item.matches(FOCUSABLE) ? item : focusableElements(item)[0]);
|
|
14
|
+
return {
|
|
15
|
+
contains: (node) => {
|
|
16
|
+
const target = control();
|
|
17
|
+
return target !== undefined && node !== null && (node === target || target.contains(node));
|
|
18
|
+
},
|
|
19
|
+
disabled: false,
|
|
20
|
+
focusItem: () => control()?.focus(),
|
|
21
|
+
select: () => { },
|
|
22
|
+
selected: false,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
10
25
|
let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement {
|
|
11
26
|
constructor() {
|
|
12
27
|
super(...arguments);
|
|
@@ -23,7 +38,15 @@ let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement
|
|
|
23
38
|
observe: () => this.items,
|
|
24
39
|
surface: () => this.partNamed('nav'),
|
|
25
40
|
});
|
|
41
|
+
this.arrows = false;
|
|
26
42
|
this.label = 'Main';
|
|
43
|
+
this.keys = new KeyboardNavigationController(this, {
|
|
44
|
+
items: () => (this.arrows ? this.items.map(navigable) : []),
|
|
45
|
+
origin: 'focus',
|
|
46
|
+
reserved: () => this.orientation === 'vertical' ? ['ArrowLeft', 'ArrowRight'] : ['ArrowDown', 'ArrowUp'],
|
|
47
|
+
selects: () => false,
|
|
48
|
+
wrap: false,
|
|
49
|
+
});
|
|
27
50
|
this.aria = new AriaForwardController(this, {
|
|
28
51
|
label: true,
|
|
29
52
|
target: () => this.partNamed('nav'),
|
|
@@ -62,6 +85,9 @@ let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement
|
|
|
62
85
|
</nav>`;
|
|
63
86
|
}
|
|
64
87
|
};
|
|
88
|
+
__decorate([
|
|
89
|
+
property({ type: Boolean })
|
|
90
|
+
], HelixHeadlessNavigation.prototype, "arrows", void 0);
|
|
65
91
|
__decorate([
|
|
66
92
|
property()
|
|
67
93
|
], HelixHeadlessNavigation.prototype, "label", void 0);
|
|
@@ -29,6 +29,11 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
|
|
|
29
29
|
* the feed holds one page of a longer list, and each row says its place in the
|
|
30
30
|
* whole of it.
|
|
31
31
|
*
|
|
32
|
+
* **`load-more` adds a button after the list** that sends `helix-load-more`,
|
|
33
|
+
* for a feed that holds one page of a longer list. Append the next page, set
|
|
34
|
+
* `loading` while it is on its way, and take `load-more` off once there is
|
|
35
|
+
* nothing more. The button is hidden while the feed is loading.
|
|
36
|
+
*
|
|
32
37
|
* @since 0.1.0
|
|
33
38
|
* @status stable
|
|
34
39
|
* @category feedback
|
|
@@ -40,6 +45,7 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
|
|
|
40
45
|
* @slot header - Above the list, for a title and the mark-all control.
|
|
41
46
|
*
|
|
42
47
|
* @event {HelixDismissEvent} helix-dismiss - Fired when the user dismisses a row. The row dispatches it, and you can listen for it on the feed. Cancelable: cancel it to keep the row.
|
|
48
|
+
* @event {HelixLoadMoreEvent} helix-load-more - Fired when a reader presses the `load-more` button, asking for the next page of the feed.
|
|
43
49
|
* @event {HelixReadEvent} helix-read - Fired by an item when it is marked read or unread, and by the feed when everything is marked read. Cancelable.
|
|
44
50
|
*
|
|
45
51
|
* @csspart empty - Shown when there is nothing in the feed.
|
|
@@ -49,6 +55,7 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
|
|
|
49
55
|
* @csspart live - A copy of the empty and loading messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.
|
|
50
56
|
* @csspart loading - Shown while the feed is loading.
|
|
51
57
|
* @csspart mark-all - The control that marks everything read.
|
|
58
|
+
* @csspart more - The button after the list that asks for more, while `load-more` is set and the feed is not loading.
|
|
52
59
|
*
|
|
53
60
|
* @cssstate media - While a notification in the list holds something in its media slot, so every row keeps that column.
|
|
54
61
|
*/
|
|
@@ -67,6 +74,15 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
|
|
|
67
74
|
* The feed's name, read by screen readers.
|
|
68
75
|
*/
|
|
69
76
|
label: string;
|
|
77
|
+
/**
|
|
78
|
+
* Whether to draw a button after the list that asks for the next page, by
|
|
79
|
+
* sending `helix-load-more`. Take it off once there is nothing more.
|
|
80
|
+
*/
|
|
81
|
+
loadMore: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* The text of the `load-more` button.
|
|
84
|
+
*/
|
|
85
|
+
loadMoreLabel: string;
|
|
70
86
|
/**
|
|
71
87
|
* Whether to draw a control that marks everything read.
|
|
72
88
|
*/
|
|
@@ -244,6 +260,8 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
|
|
|
244
260
|
private markEmpty;
|
|
245
261
|
protected updated(changed: PropertyValues): void;
|
|
246
262
|
protected render(): TemplateResult;
|
|
263
|
+
/** Asks for the next page, for the `load-more` button. */
|
|
264
|
+
private readonly askForMore;
|
|
247
265
|
/**
|
|
248
266
|
* Marks everything read, and keeps focus in the feed.
|
|
249
267
|
*
|
|
@@ -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, deepContains, focusableElements, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, rovingStop, whenHydrated, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepContains, focusableElements, HelixElement, HelixLoadMoreEvent, HelixReadEvent, hostAria, MixinCollection, markRegion, rovingStop, whenHydrated, } 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';
|
|
@@ -12,6 +12,8 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.label = '';
|
|
15
|
+
this.loadMore = false;
|
|
16
|
+
this.loadMoreLabel = 'Load more';
|
|
15
17
|
this.markAll = false;
|
|
16
18
|
this.markAllLabel = 'Mark all as read';
|
|
17
19
|
this.handleSlotChange = () => {
|
|
@@ -51,6 +53,9 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
51
53
|
rowBox(next)?.focus();
|
|
52
54
|
}
|
|
53
55
|
};
|
|
56
|
+
this.askForMore = () => {
|
|
57
|
+
this.dispatchEvent(new HelixLoadMoreEvent());
|
|
58
|
+
};
|
|
54
59
|
this.handleMarkAll = (event) => {
|
|
55
60
|
const button = event.currentTarget;
|
|
56
61
|
const focused = this.shadowRoot?.activeElement === button;
|
|
@@ -210,12 +215,23 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
210
215
|
${this.renderStatus(hasItems)}
|
|
211
216
|
</div>
|
|
212
217
|
${this.renderLive(hasItems)}
|
|
218
|
+
${this.loadMore && !this.loading
|
|
219
|
+
? html `<button part="more" type="button" @click=${this.askForMore}>
|
|
220
|
+
${this.loadMoreLabel}
|
|
221
|
+
</button>`
|
|
222
|
+
: nothing}
|
|
213
223
|
<div part="footer"><slot name="footer"></slot></div>`;
|
|
214
224
|
}
|
|
215
225
|
};
|
|
216
226
|
__decorate([
|
|
217
227
|
property()
|
|
218
228
|
], HelixHeadlessNotifications.prototype, "label", void 0);
|
|
229
|
+
__decorate([
|
|
230
|
+
property({ attribute: 'load-more', type: Boolean })
|
|
231
|
+
], HelixHeadlessNotifications.prototype, "loadMore", void 0);
|
|
232
|
+
__decorate([
|
|
233
|
+
property({ attribute: 'load-more-label' })
|
|
234
|
+
], HelixHeadlessNotifications.prototype, "loadMoreLabel", void 0);
|
|
219
235
|
__decorate([
|
|
220
236
|
property({ attribute: 'mark-all', type: Boolean })
|
|
221
237
|
], HelixHeadlessNotifications.prototype, "markAll", void 0);
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../copy-button/index.js';
|
|
4
|
-
|
|
5
|
-
interface Row {
|
|
6
|
-
branch: boolean;
|
|
7
|
-
depth: number;
|
|
8
|
-
/** The property name or array index this value is under; absent for the root. */
|
|
9
|
-
key?: string;
|
|
10
|
-
open: boolean;
|
|
11
|
-
path: string;
|
|
12
|
-
position: number;
|
|
13
|
-
siblings: number;
|
|
14
|
-
value: unknown;
|
|
15
|
-
}
|
|
4
|
+
import { type Row } from '../rows.js';
|
|
16
5
|
/**
|
|
17
6
|
* @summary A structured value shown as a tree, where you can close branches,
|
|
18
7
|
* see how many entries each holds, and copy any part.
|
|
@@ -34,6 +23,22 @@ interface Row {
|
|
|
34
23
|
* row. Each row carries its real level, position, and set size, including in
|
|
35
24
|
* a windowed tree.
|
|
36
25
|
*
|
|
26
|
+
* `active` is the active row's path, written the way a JSON Pointer writes it:
|
|
27
|
+
* the empty string for the root and `/meta/tags/0` for an entry under it.
|
|
28
|
+
* Moving to another row sends `helix-before-activate`, which you can cancel,
|
|
29
|
+
* and then `helix-activate`, both with the path. Writing `active` moves there
|
|
30
|
+
* and opens the branches around it, and sends nothing. `expanded` holds the
|
|
31
|
+
* open branches by path, and writing it opens those and closes the rest. A row
|
|
32
|
+
* that closes around the active one hands it to the nearest open branch.
|
|
33
|
+
*
|
|
34
|
+
* `filter` narrows the tree to the entries whose key or value holds the text,
|
|
35
|
+
* ignoring case, and the branches that lead to them, which it opens. A matched
|
|
36
|
+
* branch keeps everything under it. Each matched row carries `row-match`, and
|
|
37
|
+
* a screen reader hears how many entries matched from `result-label` and
|
|
38
|
+
* `results-label`. `filterable` adds a field that sets it: typing sends
|
|
39
|
+
* `helix-filter`, which you can cancel, and then `helix-filtered`, and Down
|
|
40
|
+
* moves from the field to the tree.
|
|
41
|
+
*
|
|
37
42
|
* A new `value` keeps the branches a reader opened or closed, and the active
|
|
38
43
|
* row, where the new value still has them. A branch the old value did not have
|
|
39
44
|
* opens to `default-depth`.
|
|
@@ -53,7 +58,11 @@ interface Row {
|
|
|
53
58
|
* @aliases JSON viewer, Object viewer, Inspector, Data explorer
|
|
54
59
|
* @documentation https://fusion.dev/helix/components/object-inspector
|
|
55
60
|
*
|
|
61
|
+
* @event {HelixActivateEvent} helix-activate - The active row moved, by a key or a click. The detail's `value` is its path.
|
|
62
|
+
* @event {HelixBeforeActivateEvent} helix-before-activate - The active row is about to move, with its new path. Cancelable: cancel it to keep the row where it is.
|
|
56
63
|
* @event {HelixCopyEvent} helix-copy - A value was put on the clipboard, from the copy button or the keyboard.
|
|
64
|
+
* @event {HelixFilterEvent} helix-filter - Text was typed in the filter field, with what it now holds. Cancelable: cancel it to keep the filter as it was.
|
|
65
|
+
* @event {HelixFilteredEvent} helix-filtered - The filter field changed `filter`, which now holds the text.
|
|
57
66
|
*
|
|
58
67
|
* @csspart after - The space the rows below the drawn rows would take, when `windowed` is set.
|
|
59
68
|
* @csspart before - The space the rows above the drawn rows would take, when `windowed` is set.
|
|
@@ -78,10 +87,13 @@ interface Row {
|
|
|
78
87
|
* @csspart header - The bar that holds the label, when there is one.
|
|
79
88
|
* @csspart key - A property name or an array index.
|
|
80
89
|
* @csspart label - The label.
|
|
90
|
+
* @csspart live - How many entries a filter matched, in a region that screen readers announce when it changes. Drawn from the first filter on. Visually hidden in the styled tier.
|
|
81
91
|
* @csspart null - A `null`.
|
|
82
92
|
* @csspart number - A number.
|
|
83
93
|
* @csspart row - One entry, as a tree item.
|
|
84
94
|
* @csspart row-active - The entry the keyboard is on. Set alongside `row`.
|
|
95
|
+
* @csspart row-match - An entry whose key or value holds the filter. Set alongside `row`.
|
|
96
|
+
* @csspart search-field - The field that sets `filter`, with `filterable`.
|
|
85
97
|
* @csspart string - A string, in quotes.
|
|
86
98
|
* @csspart summary - The brackets that stand for a branch's contents.
|
|
87
99
|
* @csspart toggle - The caret on a branch. It points down when the branch is open and sideways when it is closed.
|
|
@@ -90,6 +102,17 @@ interface Row {
|
|
|
90
102
|
* @cssproperty --object-inspector-level - How deep a row is, from 0 at the root, for indenting it.
|
|
91
103
|
*/
|
|
92
104
|
export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
105
|
+
/**
|
|
106
|
+
* The active row's path, such as `/meta/tags/0`, and the empty string for the
|
|
107
|
+
* root.
|
|
108
|
+
*
|
|
109
|
+
* Reading gives the row the keys are on. Writing moves there, opening the
|
|
110
|
+
* branches around it, and sends no event, the way a script's write to any
|
|
111
|
+
* current value sends none. A path the value does not hold moves to the
|
|
112
|
+
* nearest branch above it that it does.
|
|
113
|
+
*/
|
|
114
|
+
get active(): string;
|
|
115
|
+
set active(path: string);
|
|
93
116
|
/**
|
|
94
117
|
* The copy button's accessible name on a row with a key, with the key filled
|
|
95
118
|
* in as `{name}`.
|
|
@@ -109,6 +132,23 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
109
132
|
* wall of text this exists to avoid.
|
|
110
133
|
*/
|
|
111
134
|
defaultDepth: number;
|
|
135
|
+
/**
|
|
136
|
+
* The open branches, by path, in no set order.
|
|
137
|
+
*
|
|
138
|
+
* Writing opens exactly these and closes every other, keeping the active row
|
|
139
|
+
* where it stays visible. A property, never an attribute.
|
|
140
|
+
*/
|
|
141
|
+
get expanded(): string[];
|
|
142
|
+
set expanded(paths: string[]);
|
|
143
|
+
/**
|
|
144
|
+
* Text the tree is narrowed to: the entries whose key or value holds it,
|
|
145
|
+
* ignoring case, and the branches that lead to them. Empty shows everything.
|
|
146
|
+
*/
|
|
147
|
+
filter: string;
|
|
148
|
+
/** Whether to show a field that sets `filter`. */
|
|
149
|
+
filterable: boolean;
|
|
150
|
+
/** The filter field's placeholder and accessible name. */
|
|
151
|
+
filterLabel: string;
|
|
112
152
|
/**
|
|
113
153
|
* The id of a `<script type="application/json">` holding the value.
|
|
114
154
|
*
|
|
@@ -143,6 +183,13 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
143
183
|
* reach a value.
|
|
144
184
|
*/
|
|
145
185
|
noCopy: boolean;
|
|
186
|
+
/** What a screen reader hears when a filter matches one entry. `{count}` is the count. */
|
|
187
|
+
resultLabel: string;
|
|
188
|
+
/**
|
|
189
|
+
* What a screen reader hears when a filter matches any other number of
|
|
190
|
+
* entries. `{count}` is the count. The two are chosen by `Intl.PluralRules`.
|
|
191
|
+
*/
|
|
192
|
+
resultsLabel: string;
|
|
146
193
|
/**
|
|
147
194
|
* The tree's accessible name when `label` is empty and the host names it
|
|
148
195
|
* with neither `aria-label` nor `aria-labelledby`.
|
|
@@ -169,7 +216,18 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
169
216
|
/** Which branches are open, by path. */
|
|
170
217
|
private opened;
|
|
171
218
|
/** The row the arrow keys are on, by its place among the visible rows. */
|
|
172
|
-
private
|
|
219
|
+
private cursor;
|
|
220
|
+
/** A path written to `active` and not yet found among the rows. */
|
|
221
|
+
private wanted;
|
|
222
|
+
/**
|
|
223
|
+
* The branches written to `expanded`, until the next update applies them.
|
|
224
|
+
*
|
|
225
|
+
* Its own field, because a property declared with an accessor is in the
|
|
226
|
+
* first update's changes whether or not anybody wrote it.
|
|
227
|
+
*/
|
|
228
|
+
private declared;
|
|
229
|
+
/** The paths the filter matched, or nothing while there is no filter. */
|
|
230
|
+
private found;
|
|
173
231
|
/** Set by a keyboard move, so the next render brings the active row into view. */
|
|
174
232
|
private revealing;
|
|
175
233
|
/** What has been typed toward a key, and when the last letter came. */
|
|
@@ -178,6 +236,8 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
178
236
|
private branches;
|
|
179
237
|
/** Carries a host `aria-label` and `aria-labelledby` to the tree, which is what takes focus. */
|
|
180
238
|
protected readonly aria: AriaForwardController;
|
|
239
|
+
/** Says how many entries a filter matched. */
|
|
240
|
+
private readonly status;
|
|
181
241
|
/**
|
|
182
242
|
* How tall a row is taken to be before it has been drawn, in pixels.
|
|
183
243
|
*
|
|
@@ -193,8 +253,6 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
193
253
|
/** Every visible row, in order, worked out once per change rather than per read. */
|
|
194
254
|
private rows;
|
|
195
255
|
private readonly copier;
|
|
196
|
-
/** Every visible row, in order, for the tree as it stands. */
|
|
197
|
-
private flatten;
|
|
198
256
|
/**
|
|
199
257
|
* Opens every branch shallower than `defaultDepth`.
|
|
200
258
|
*
|
|
@@ -205,7 +263,17 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
205
263
|
* place on every update.
|
|
206
264
|
*/
|
|
207
265
|
private seed;
|
|
266
|
+
/** Opens the branches around each path, where the value has them. */
|
|
267
|
+
private openAround;
|
|
208
268
|
protected willUpdate(changed: PropertyValues): void;
|
|
269
|
+
/**
|
|
270
|
+
* Where the active row goes once the rows have moved: onto `path` where it
|
|
271
|
+
* is still shown, onto the first match where a filter just hid it, and
|
|
272
|
+
* otherwise onto the nearest branch around it that is.
|
|
273
|
+
*/
|
|
274
|
+
private place;
|
|
275
|
+
/** Says how many entries the filter matched, and nothing for an empty one. */
|
|
276
|
+
private tell;
|
|
209
277
|
protected firstUpdated(changed: PropertyValues): void;
|
|
210
278
|
protected updated(changed: PropertyValues): void;
|
|
211
279
|
private load;
|
|
@@ -225,6 +293,10 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
225
293
|
/** What copying takes: a branch as indented JSON, a string as itself. */
|
|
226
294
|
private copyable;
|
|
227
295
|
private toggle;
|
|
296
|
+
/**
|
|
297
|
+
* Moves the active row, asking first: `helix-before-activate` with the path,
|
|
298
|
+
* then `helix-activate` once it has moved. Returns whether it is there.
|
|
299
|
+
*/
|
|
228
300
|
private move;
|
|
229
301
|
private readonly handleKeydown;
|
|
230
302
|
/** Opens every branch at the active row's level under the same parent, as `*` asks. */
|
|
@@ -237,7 +309,12 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
237
309
|
* keys that start with it.
|
|
238
310
|
*/
|
|
239
311
|
private typeahead;
|
|
312
|
+
/** A press opens or closes the row it lands on, once that row is the active one. */
|
|
240
313
|
private handleRowClick;
|
|
314
|
+
/** Text typed in the filter field, asked for before the tree narrows to it. */
|
|
315
|
+
private readonly handleFilterInput;
|
|
316
|
+
/** Down from the filter field goes to the tree, where the matches are. */
|
|
317
|
+
private readonly handleFilterKeydown;
|
|
241
318
|
private renderValue;
|
|
242
319
|
/**
|
|
243
320
|
* One entry, named for its state where it holds one.
|
|
@@ -248,6 +325,11 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
|
|
|
248
325
|
* attribute would be a second spelling with no reader. The name is the one a
|
|
249
326
|
* consumer can reach, nothing being able to follow `::part()` with an
|
|
250
327
|
* attribute selector.
|
|
328
|
+
*
|
|
329
|
+
* **`aria-selected="false"` on every row**, because nothing here is chosen.
|
|
330
|
+
* Chromium takes the active descendant of a single-selection tree as selected
|
|
331
|
+
* when no row says otherwise, so every arrow press was also announced as a
|
|
332
|
+
* selection. An explicit false is the one thing that turns that off.
|
|
251
333
|
*/
|
|
252
334
|
private renderRow;
|
|
253
335
|
/** The copy button, behind the seam Code Block's uses, so each tier renders its own. */
|
|
@@ -259,4 +341,3 @@ declare global {
|
|
|
259
341
|
'helix-headless-object-inspector': HelixHeadlessObjectInspector;
|
|
260
342
|
}
|
|
261
343
|
}
|
|
262
|
-
export {};
|