@fusion.dev/helix-headless 0.142.1 → 0.144.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 +25381 -1202
- package/dist/accordion/item/accordion-item.d.ts +38 -2
- package/dist/accordion/item/accordion-item.js +38 -6
- package/dist/accordion/root/accordion-root.d.ts +23 -1
- package/dist/accordion/root/accordion-root.js +39 -3
- package/dist/announcement/root/announcement-root.d.ts +11 -7
- package/dist/announcement/root/announcement-root.js +1 -1
- package/dist/app-header/root/app-header-root.d.ts +21 -0
- package/dist/app-header/root/app-header-root.js +31 -5
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +39 -11
- package/dist/avatar/group/avatar-group.d.ts +24 -3
- package/dist/avatar/group/avatar-group.js +34 -2
- package/dist/avatar/root/avatar-root.d.ts +17 -1
- package/dist/avatar/root/avatar-root.js +31 -10
- package/dist/badge/root/badge-root.d.ts +12 -0
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
- package/dist/bar-chart/root/bar-chart-root.js +58 -21
- package/dist/blockquote/root/blockquote-root.d.ts +12 -7
- package/dist/blockquote/root/blockquote-root.js +6 -4
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
- package/dist/button/root/button-root.d.ts +84 -1
- package/dist/button/root/button-root.js +81 -3
- package/dist/callout/root/callout-root.d.ts +32 -6
- package/dist/callout/root/callout-root.js +26 -7
- package/dist/canvas/root/canvas-root.d.ts +1 -0
- package/dist/canvas/root/canvas-root.js +10 -1
- package/dist/card/root/card-root.d.ts +30 -1
- package/dist/card/root/card-root.js +38 -5
- package/dist/carousel/root/carousel-root.d.ts +47 -5
- package/dist/carousel/root/carousel-root.js +53 -21
- package/dist/chat/composer/chat-composer.d.ts +13 -11
- package/dist/chat/composer/chat-composer.js +6 -12
- package/dist/chat/message/chat-message.js +8 -1
- package/dist/chat/root/chat-root.d.ts +1 -0
- package/dist/chat/root/chat-root.js +2 -1
- package/dist/checkbox/root/checkbox-root.d.ts +7 -0
- package/dist/checkbox/root/checkbox-root.js +9 -3
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
- package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
- package/dist/code/root/code-root.d.ts +1 -1
- package/dist/code-block/lines.d.ts +13 -0
- package/dist/code-block/lines.js +2 -0
- package/dist/code-block/root/code-block-root.d.ts +49 -0
- package/dist/code-block/root/code-block-root.js +44 -3
- package/dist/color-input/root/color-input-root.d.ts +60 -2
- package/dist/color-input/root/color-input-root.js +55 -7
- package/dist/color-picker/channels.d.ts +26 -0
- package/dist/color-picker/channels.js +84 -0
- package/dist/color-picker/root/color-picker-root.d.ts +118 -12
- package/dist/color-picker/root/color-picker-root.js +183 -13
- package/dist/combobox/root/combobox-root.d.ts +126 -3
- package/dist/combobox/root/combobox-root.js +224 -21
- package/dist/command/root/command-root.d.ts +47 -10
- package/dist/command/root/command-root.js +45 -4
- package/dist/copy-button/from.d.ts +22 -0
- package/dist/copy-button/from.js +28 -0
- package/dist/copy-button/root/copy-button-root.d.ts +48 -7
- package/dist/copy-button/root/copy-button-root.js +54 -8
- package/dist/data-table/root/data-table-root.d.ts +164 -10
- package/dist/data-table/root/data-table-root.js +488 -57
- package/dist/date-input/root/date-input-root.d.ts +123 -9
- package/dist/date-input/root/date-input-root.js +147 -45
- package/dist/date-picker/root/date-picker-root.d.ts +229 -18
- package/dist/date-picker/root/date-picker-root.js +342 -46
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +101 -10
- package/dist/dialog/root/dialog-root.js +83 -4
- package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
- package/dist/donut-chart/root/donut-chart-root.js +48 -13
- package/dist/drawer/root/drawer-root.d.ts +93 -7
- package/dist/drawer/root/drawer-root.js +126 -5
- package/dist/drawer/swipe-start.d.ts +9 -0
- package/dist/drawer/swipe-start.js +12 -0
- package/dist/drilldown/item/drilldown-item.d.ts +16 -13
- package/dist/drilldown/item/drilldown-item.js +6 -2
- package/dist/drilldown/root/drilldown-root.d.ts +21 -5
- package/dist/drilldown/root/drilldown-root.js +26 -10
- package/dist/element-events.generated.js +42 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +65 -1
- package/dist/file-input/root/file-input-root.js +76 -12
- package/dist/file-input/screen.d.ts +35 -0
- package/dist/file-input/screen.js +49 -0
- package/dist/filter-input/menu/filter-menu.d.ts +9 -0
- package/dist/filter-input/menu/filter-menu.js +8 -0
- package/dist/filter-input/root/filter-input-root.d.ts +43 -6
- package/dist/filter-input/root/filter-input-root.js +89 -10
- package/dist/filter-input/suggest.d.ts +17 -0
- package/dist/filter-input/suggest.js +23 -0
- package/dist/format-date/options.d.ts +33 -0
- package/dist/format-date/options.js +42 -0
- package/dist/format-date/root/format-date-root.d.ts +62 -3
- package/dist/format-date/root/format-date-root.js +78 -37
- package/dist/graph/root/graph-root.d.ts +24 -3
- package/dist/graph/root/graph-root.js +66 -12
- package/dist/heatmap/root/buckets.d.ts +2 -1
- package/dist/heatmap/root/buckets.js +5 -1
- package/dist/heatmap/root/heatmap-root.d.ts +47 -9
- package/dist/heatmap/root/heatmap-root.js +46 -18
- package/dist/icon/index.d.ts +2 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon/registry.d.ts +37 -0
- package/dist/icon/registry.js +83 -0
- package/dist/icon/root/icon-root.d.ts +53 -6
- package/dist/icon/root/icon-root.js +72 -4
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon/set.d.ts +1 -0
- package/dist/icon/set.js +3 -0
- package/dist/icon-button/root/icon-button-root.d.ts +1 -1
- package/dist/image/root/image-root.d.ts +23 -2
- package/dist/image/root/image-root.js +23 -4
- package/dist/input/root/input-root.d.ts +62 -9
- package/dist/input/root/input-root.js +61 -5
- package/dist/kbd/root/kbd-root.d.ts +26 -11
- package/dist/kbd/root/kbd-root.js +35 -38
- package/dist/kbd/shortcut.d.ts +18 -0
- package/dist/kbd/shortcut.js +35 -0
- package/dist/legend/hidden-series.d.ts +8 -0
- package/dist/legend/hidden-series.js +13 -0
- package/dist/legend/root/legend-root.d.ts +63 -0
- package/dist/legend/root/legend-root.js +61 -7
- package/dist/lightbox/item/lightbox-item.d.ts +17 -1
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +77 -6
- package/dist/lightbox/root/lightbox-root.js +116 -5
- package/dist/line-chart/root/line-chart-root.d.ts +29 -4
- package/dist/line-chart/root/line-chart-root.js +58 -17
- package/dist/list/item/list-item.d.ts +11 -5
- package/dist/list/item/list-item.js +5 -6
- package/dist/listbox/range.d.ts +17 -0
- package/dist/listbox/range.js +5 -0
- package/dist/listbox/root/listbox-root.d.ts +184 -4
- package/dist/listbox/root/listbox-root.js +229 -23
- package/dist/loader/busy.d.ts +17 -0
- package/dist/loader/busy.js +24 -0
- package/dist/loader/root/loader-root.d.ts +37 -0
- package/dist/loader/root/loader-root.js +52 -3
- package/dist/map/root/map-root.d.ts +19 -4
- package/dist/map/root/map-root.js +36 -7
- package/dist/megamenu/root/megamenu-root.d.ts +10 -1
- package/dist/megamenu/root/megamenu-root.js +10 -1
- package/dist/menu/item/menu-item.d.ts +41 -12
- package/dist/menu/item/menu-item.js +46 -3
- package/dist/menu/root/menu-root.d.ts +32 -2
- package/dist/menu/root/menu-root.js +48 -8
- package/dist/meter/root/meter-root.d.ts +13 -0
- package/dist/meter/root/meter-root.js +24 -5
- package/dist/navigation/root/navigation-root.d.ts +10 -2
- package/dist/navigation/root/navigation-root.js +13 -2
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/group/notification-group.d.ts +1 -0
- package/dist/notifications/notification/notification.d.ts +29 -0
- package/dist/notifications/notification/notification.js +51 -3
- package/dist/notifications/root/notifications-root.d.ts +49 -0
- package/dist/notifications/root/notifications-root.js +76 -2
- package/dist/number-input/root/number-input-root.d.ts +109 -7
- package/dist/number-input/root/number-input-root.js +109 -21
- package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
- package/dist/object-inspector/root/object-inspector-root.js +92 -12
- package/dist/option/root/option-root.d.ts +58 -6
- package/dist/option/root/option-root.js +35 -5
- package/dist/outline/root/outline-root.d.ts +13 -2
- package/dist/outline/root/outline-root.js +4 -2
- package/dist/pagination/root/pagination-root.d.ts +19 -1
- package/dist/pagination/root/pagination-root.js +49 -9
- package/dist/pagination/size/pagination-size.d.ts +13 -3
- package/dist/pagination/size/pagination-size.js +7 -0
- package/dist/pin-input/format.d.ts +7 -0
- package/dist/pin-input/format.js +16 -0
- package/dist/pin-input/root/pin-input-root.d.ts +37 -0
- package/dist/pin-input/root/pin-input-root.js +48 -7
- package/dist/popover/root/popover-root.d.ts +78 -3
- package/dist/popover/root/popover-root.js +74 -5
- package/dist/progress/root/progress-root.d.ts +23 -1
- package/dist/progress/root/progress-root.js +40 -10
- package/dist/qr-code/export.d.ts +31 -0
- package/dist/qr-code/export.js +10 -0
- package/dist/qr-code/root/qr-code-root.d.ts +45 -0
- package/dist/qr-code/root/qr-code-root.js +78 -3
- package/dist/radio/group/radio-group.d.ts +64 -0
- package/dist/radio/group/radio-group.js +66 -12
- package/dist/radio/root/radio-root.d.ts +8 -5
- package/dist/radio/root/radio-root.js +1 -2
- package/dist/rating/root/rating-root.d.ts +49 -1
- package/dist/rating/root/rating-root.js +69 -10
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
- package/dist/select/root/select-root.d.ts +93 -3
- package/dist/select/root/select-root.js +111 -13
- package/dist/skeleton/root/skeleton-root.d.ts +39 -3
- package/dist/skeleton/root/skeleton-root.js +33 -4
- package/dist/skip-link/root/skip-link-root.d.ts +10 -0
- package/dist/skip-link/root/skip-link-root.js +15 -1
- package/dist/slider/root/slider-root.d.ts +59 -2
- package/dist/slider/root/slider-root.js +82 -8
- package/dist/sparkline/root/sparkline-root.d.ts +9 -10
- package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
- package/dist/speed-dial/item/speed-dial-item.js +7 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
- package/dist/speed-dial/root/speed-dial-root.js +19 -5
- package/dist/splitter/root/splitter-root.d.ts +28 -6
- package/dist/splitter/root/splitter-root.js +35 -1
- package/dist/stat/root/stat-root.d.ts +9 -1
- package/dist/stat/root/stat-root.js +15 -2
- package/dist/steps/root/steps-root.js +1 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/switch/root/switch-root.d.ts +14 -2
- package/dist/switch/root/switch-root.js +7 -1
- package/dist/table/cell/table-cell.d.ts +24 -4
- package/dist/table/cell/table-cell.js +21 -1
- package/dist/table/column/table-column.d.ts +32 -6
- package/dist/table/column/table-column.js +36 -6
- package/dist/table/root/table-root.d.ts +94 -3
- package/dist/table/root/table-root.js +128 -5
- package/dist/table/row/table-row.d.ts +7 -0
- package/dist/table/row/table-row.js +9 -1
- package/dist/tabs/root/tabs-root.d.ts +6 -1
- package/dist/tabs/root/tabs-root.js +6 -2
- package/dist/tag/group/tag-group.d.ts +107 -0
- package/dist/tag/group/tag-group.js +157 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +83 -1
- package/dist/tag/root/tag-root.js +87 -17
- package/dist/tag/selection.d.ts +10 -0
- package/dist/tag/selection.js +12 -0
- package/dist/textarea/grow.d.ts +22 -0
- package/dist/textarea/grow.js +20 -0
- package/dist/textarea/root/textarea-root.d.ts +13 -0
- package/dist/textarea/root/textarea-root.js +10 -2
- package/dist/time-input/root/time-input-root.d.ts +71 -6
- package/dist/time-input/root/time-input-root.js +110 -44
- package/dist/time-picker/root/time-picker-root.d.ts +155 -26
- package/dist/time-picker/root/time-picker-root.js +192 -63
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +16 -1
- package/dist/toast/item/toast-item.js +41 -13
- package/dist/toast/root/toast-root.d.ts +105 -8
- package/dist/toast/root/toast-root.js +209 -4
- package/dist/toggle/group/toggle-group.d.ts +95 -16
- package/dist/toggle/group/toggle-group.js +99 -13
- package/dist/toggle/root/toggle-root.d.ts +26 -11
- package/dist/toggle/root/toggle-root.js +14 -6
- package/dist/toolbar/root/toolbar-root.d.ts +55 -15
- package/dist/toolbar/root/toolbar-root.js +99 -16
- package/dist/tooltip/focus-target.d.ts +6 -0
- package/dist/tooltip/focus-target.js +9 -0
- package/dist/tooltip/root/tooltip-root.d.ts +73 -15
- package/dist/tooltip/root/tooltip-root.js +96 -7
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +67 -3
- package/dist/tour/root/tour-root.js +105 -17
- package/dist/tour/stop/tour-stop.d.ts +65 -3
- package/dist/tour/stop/tour-stop.js +61 -11
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/tree/item/tree-item.d.ts +21 -5
- package/dist/tree/item/tree-item.js +14 -4
- package/dist/tree/root/tree-root.d.ts +29 -5
- package/dist/tree/root/tree-root.js +64 -8
- package/dist/trend/root/trend-root.d.ts +36 -1
- package/dist/trend/root/trend-root.js +41 -15
- package/dist/video/root/keys.d.ts +5 -0
- package/dist/video/root/keys.js +13 -1
- package/dist/video/root/video-root.d.ts +19 -0
- package/dist/video/root/video-root.js +48 -4
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
- package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
- package/dist/video-playlist/root/video-playlist-root.js +6 -3
- package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
- package/dist/virtual-list/root/virtual-list-root.js +103 -21
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +9140 -1149
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +2089 -267
|
@@ -4,10 +4,11 @@ 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,
|
|
7
|
+
import { customElement, deepActiveElement, deepContains, fillTemplate, HelixActivateEvent, HelixBeforeActivateEvent, HelixCompleteEvent, HelixElement, hostAria, MixinControllerOpen, requestChange, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property, queryAssignedElements, state } from 'lit/decorators.js';
|
|
10
|
-
|
|
10
|
+
import { onPage, waitFor } from '../wait.js';
|
|
11
|
+
let HelixHeadlessTour = class HelixHeadlessTour extends MixinControllerOpen(HelixElement) {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
13
14
|
this.backLabel = '';
|
|
@@ -16,7 +17,8 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
16
17
|
this.indexState = undefined;
|
|
17
18
|
this.label = '';
|
|
18
19
|
this.nextLabel = '';
|
|
19
|
-
this.
|
|
20
|
+
this.progress = false;
|
|
21
|
+
this.progressLabel = '{index} of {count}';
|
|
20
22
|
this.skipLabel = '';
|
|
21
23
|
this.spotlightPadding = 8;
|
|
22
24
|
this.sizer = undefined;
|
|
@@ -42,6 +44,8 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
42
44
|
this.handleViewport = () => {
|
|
43
45
|
this.light();
|
|
44
46
|
};
|
|
47
|
+
this.followed = false;
|
|
48
|
+
this.veiled = false;
|
|
45
49
|
}
|
|
46
50
|
get index() {
|
|
47
51
|
return this.indexState ?? this.defaultIndex;
|
|
@@ -71,19 +75,14 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
71
75
|
this.move(this.index - 1);
|
|
72
76
|
}
|
|
73
77
|
skip() {
|
|
74
|
-
|
|
75
|
-
this.dispatchEvent(event);
|
|
76
|
-
if (event.defaultPrevented) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
this.open = false;
|
|
78
|
+
this.requestOpen(false);
|
|
80
79
|
}
|
|
81
80
|
finish() {
|
|
82
81
|
this.dispatchEvent(new HelixCompleteEvent({ value: String(this.index) }));
|
|
83
82
|
this.open = false;
|
|
84
83
|
}
|
|
85
84
|
move(to) {
|
|
86
|
-
requestChange({
|
|
85
|
+
const moved = requestChange({
|
|
87
86
|
apply: (value) => {
|
|
88
87
|
this.index = value;
|
|
89
88
|
},
|
|
@@ -91,6 +90,9 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
91
90
|
host: this,
|
|
92
91
|
next: to,
|
|
93
92
|
});
|
|
93
|
+
if (moved) {
|
|
94
|
+
this.dispatchEvent(new HelixActivateEvent({ value: String(this.index) }));
|
|
95
|
+
}
|
|
94
96
|
}
|
|
95
97
|
connectedCallback() {
|
|
96
98
|
super.connectedCallback();
|
|
@@ -110,15 +112,61 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
110
112
|
window.removeEventListener('scroll', this.handleViewport, { capture: true });
|
|
111
113
|
this.sizer?.disconnect();
|
|
112
114
|
this.sized = undefined;
|
|
115
|
+
this.unwait?.();
|
|
116
|
+
this.unwait = undefined;
|
|
117
|
+
this.waiting = undefined;
|
|
113
118
|
}
|
|
114
119
|
willUpdate(changed) {
|
|
115
120
|
super.willUpdate(changed);
|
|
116
|
-
hostAria(this.internals, {
|
|
121
|
+
hostAria(this.internals, {
|
|
122
|
+
label: this.open ? this.label : '',
|
|
123
|
+
role: this.open ? 'region' : '',
|
|
124
|
+
});
|
|
117
125
|
}
|
|
118
126
|
updated(changed) {
|
|
119
127
|
super.updated(changed);
|
|
120
128
|
this.settle();
|
|
121
129
|
this.light();
|
|
130
|
+
this.follow(changed);
|
|
131
|
+
this.wait();
|
|
132
|
+
}
|
|
133
|
+
follow(changed) {
|
|
134
|
+
if (!this.followed) {
|
|
135
|
+
this.followed = true;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const opened = changed.has('open') && this.open && changed.get('open') === false;
|
|
139
|
+
const closed = changed.has('open') && !this.open && changed.get('open') === true;
|
|
140
|
+
const active = deepActiveElement();
|
|
141
|
+
const inside = active === null || active === document.body || deepContains(this, active);
|
|
142
|
+
if (opened) {
|
|
143
|
+
if (active instanceof HTMLElement && !deepContains(this, active)) {
|
|
144
|
+
this.returnFocus = active;
|
|
145
|
+
}
|
|
146
|
+
this.focusCurrent();
|
|
147
|
+
}
|
|
148
|
+
else if (closed) {
|
|
149
|
+
const back = this.returnFocus;
|
|
150
|
+
this.returnFocus = undefined;
|
|
151
|
+
if (inside && back?.isConnected) {
|
|
152
|
+
back.focus();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (this.open && changed.has('index') && inside) {
|
|
156
|
+
this.focusCurrent();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
focusCurrent() {
|
|
160
|
+
const stops = this.stops;
|
|
161
|
+
const stop = stops[Math.max(0, Math.min(this.index, stops.length - 1))];
|
|
162
|
+
if (!stop) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
void stop.updateComplete.then(() => {
|
|
166
|
+
if (this.open && stop.current) {
|
|
167
|
+
stop.focus();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
122
170
|
}
|
|
123
171
|
settle() {
|
|
124
172
|
const stops = this.stops;
|
|
@@ -128,6 +176,11 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
128
176
|
stop.current = this.open && index === at;
|
|
129
177
|
stop.first = index === 0;
|
|
130
178
|
stop.last = index === stops.length - 1;
|
|
179
|
+
stop.position = fillTemplate(this.progressLabel, {
|
|
180
|
+
count: stops.length,
|
|
181
|
+
index: index + 1,
|
|
182
|
+
});
|
|
183
|
+
stop.progress = this.progress;
|
|
131
184
|
if (this.backLabel !== '') {
|
|
132
185
|
stop.backLabel = this.backLabel;
|
|
133
186
|
}
|
|
@@ -144,12 +197,41 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
144
197
|
});
|
|
145
198
|
}
|
|
146
199
|
get lit() {
|
|
200
|
+
const stop = this.current;
|
|
201
|
+
return this.open && stop?.type === undefined ? stop?.target : undefined;
|
|
202
|
+
}
|
|
203
|
+
get current() {
|
|
147
204
|
const stops = this.stops;
|
|
148
|
-
return this.
|
|
149
|
-
|
|
150
|
-
|
|
205
|
+
return stops[Math.max(0, Math.min(this.index, stops.length - 1))];
|
|
206
|
+
}
|
|
207
|
+
wait() {
|
|
208
|
+
const stop = this.open ? this.current : undefined;
|
|
209
|
+
const next = stop?.type === 'wait' ? stop : undefined;
|
|
210
|
+
if (next === this.waiting) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this.unwait?.();
|
|
214
|
+
this.unwait = undefined;
|
|
215
|
+
this.waiting = next;
|
|
216
|
+
if (!next) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
this.unwait = waitFor(next.getRootNode(), () => onPage(next.target), () => {
|
|
220
|
+
this.waiting = undefined;
|
|
221
|
+
this.unwait = undefined;
|
|
222
|
+
queueMicrotask(() => {
|
|
223
|
+
if (this.open && this.current === next) {
|
|
224
|
+
this.next();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
151
228
|
}
|
|
152
229
|
light() {
|
|
230
|
+
const stop = this.open ? this.current : undefined;
|
|
231
|
+
const veiled = stop !== undefined && stop.type !== 'wait' && (stop.type !== undefined || !stop.target);
|
|
232
|
+
if (veiled !== this.veiled) {
|
|
233
|
+
this.veiled = veiled;
|
|
234
|
+
}
|
|
153
235
|
const target = this.lit;
|
|
154
236
|
this.watch(target);
|
|
155
237
|
if (!target || typeof target.getBoundingClientRect !== 'function') {
|
|
@@ -187,7 +269,7 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
187
269
|
}
|
|
188
270
|
render() {
|
|
189
271
|
const spot = this.spot;
|
|
190
|
-
return html `${spot === undefined
|
|
272
|
+
return html `${this.veiled ? html `<div part="backdrop" aria-hidden="true"></div>` : ''}${spot === undefined
|
|
191
273
|
? ''
|
|
192
274
|
: html `<div
|
|
193
275
|
part="spotlight"
|
|
@@ -216,8 +298,11 @@ __decorate([
|
|
|
216
298
|
property({ attribute: 'next-label' })
|
|
217
299
|
], HelixHeadlessTour.prototype, "nextLabel", void 0);
|
|
218
300
|
__decorate([
|
|
219
|
-
property({
|
|
220
|
-
], HelixHeadlessTour.prototype, "
|
|
301
|
+
property({ type: Boolean })
|
|
302
|
+
], HelixHeadlessTour.prototype, "progress", void 0);
|
|
303
|
+
__decorate([
|
|
304
|
+
property({ attribute: 'progress-label' })
|
|
305
|
+
], HelixHeadlessTour.prototype, "progressLabel", void 0);
|
|
221
306
|
__decorate([
|
|
222
307
|
property({ attribute: 'skip-label' })
|
|
223
308
|
], HelixHeadlessTour.prototype, "skipLabel", void 0);
|
|
@@ -230,6 +315,9 @@ __decorate([
|
|
|
230
315
|
__decorate([
|
|
231
316
|
state()
|
|
232
317
|
], HelixHeadlessTour.prototype, "spot", void 0);
|
|
318
|
+
__decorate([
|
|
319
|
+
state()
|
|
320
|
+
], HelixHeadlessTour.prototype, "veiled", void 0);
|
|
233
321
|
HelixHeadlessTour = __decorate([
|
|
234
322
|
customElement('helix-headless-tour')
|
|
235
323
|
], HelixHeadlessTour);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HelixElement, type Placement } from '@fusion.dev/helix-core';
|
|
2
|
-
import type
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../button/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* @summary One stop on a tour: the element it points at, and a panel of content about it.
|
|
@@ -15,7 +15,16 @@ import '../../button/index.js';
|
|
|
15
15
|
* - **Visibility.** The stop shows when it is `current`, which the root sets.
|
|
16
16
|
*
|
|
17
17
|
* Put any content in the stop, such as a `Card`, or a heading and a line of
|
|
18
|
-
* text.
|
|
18
|
+
* text. The `heading` and `description` slots are optional places for the
|
|
19
|
+
* title and the line under it, which then name and describe the panel.
|
|
20
|
+
*
|
|
21
|
+
* **A stop has a type.** Without one it is a bubble pointing at its target.
|
|
22
|
+
* `type="dialog"` is a panel in the middle of the window, over a backdrop, for
|
|
23
|
+
* a welcome or a summary with nothing to point at. `type="floating"` is a
|
|
24
|
+
* panel in a corner of the window, which the styled tier puts at the end of
|
|
25
|
+
* the line, for a note that points at nothing in particular. `type="wait"` shows nothing: the tour waits
|
|
26
|
+
* for the element `for` names to be on the page, such as a menu the reader has
|
|
27
|
+
* to open, and moves on by itself.
|
|
19
28
|
*
|
|
20
29
|
* **The buttons are slot fallback.** With nothing in the `actions` slot, you
|
|
21
30
|
* get Back, Next, and Skip, already wired. Slot your own `actions` and drive
|
|
@@ -25,6 +34,13 @@ import '../../button/index.js';
|
|
|
25
34
|
* on the page from markup. It resolves against the stop's root node, so a stop
|
|
26
35
|
* inside a shadow tree points at a target in that tree.
|
|
27
36
|
*
|
|
37
|
+
* The panel is a `group`, and a `dialog` for a dialog stop, only while the
|
|
38
|
+
* stop is shown. It is named by the `heading` slot, then by the first heading
|
|
39
|
+
* in the content, then by `label`, and otherwise by its place in the tour. It
|
|
40
|
+
* is described by the `description` slot and by its place, such as "2 of 5",
|
|
41
|
+
* so a screen reader says where the reader is at every stop. `focus()` moves
|
|
42
|
+
* focus to the panel, which is what the tour does when it opens or moves on.
|
|
43
|
+
*
|
|
28
44
|
* @since 0.1.0
|
|
29
45
|
* @status stable
|
|
30
46
|
* @category overlays
|
|
@@ -32,6 +48,8 @@ import '../../button/index.js';
|
|
|
32
48
|
*
|
|
33
49
|
* @slot - The stop's content. Any content works, such as a card, or a heading and a line.
|
|
34
50
|
* @slot actions - Replaces the controls, which are Back, Next, and Skip.
|
|
51
|
+
* @slot description - A line under the title, which describes the panel.
|
|
52
|
+
* @slot heading - The stop's title, which names the panel.
|
|
35
53
|
*
|
|
36
54
|
* @event {HelixTourAskEvent} helix-tour-ask - Fired when one of the stop's controls is pressed, to move the tour.
|
|
37
55
|
*
|
|
@@ -43,14 +61,20 @@ import '../../button/index.js';
|
|
|
43
61
|
* @csspart arrow-top - The arrow while the panel is above its target, on the panel's bottom edge. Applied with `arrow`.
|
|
44
62
|
* @csspart back - The control that goes to the previous stop.
|
|
45
63
|
* @csspart back-button - The button inside `back`.
|
|
64
|
+
* @csspart back-live - The live region inside `back`.
|
|
46
65
|
* @csspart back-text - The words on that button, trimmed to their capitals and baseline.
|
|
47
66
|
* @csspart bubble - The panel that points at the target.
|
|
48
67
|
* @csspart content - The region holding the slotted content.
|
|
68
|
+
* @csspart description - The slot the description is in. It draws no box until you give it one.
|
|
69
|
+
* @csspart heading - The slot the title is in. It draws no box until you give it one.
|
|
49
70
|
* @csspart next - The control that goes to the next stop, and finishes the tour on the last stop.
|
|
50
71
|
* @csspart next-button - The button inside `next`.
|
|
72
|
+
* @csspart next-live - The live region inside `next`.
|
|
51
73
|
* @csspart next-text - The words on that button, trimmed to their capitals and baseline.
|
|
74
|
+
* @csspart progress - The stop's place in the tour, such as "2 of 5". It describes the panel, and is shown when the tour has `progress`.
|
|
52
75
|
* @csspart skip - The control that ends the tour early.
|
|
53
76
|
* @csspart skip-button - The button inside `skip`.
|
|
77
|
+
* @csspart skip-live - The live region inside `skip`.
|
|
54
78
|
* @csspart skip-text - The words on that button, trimmed to their capitals and baseline.
|
|
55
79
|
*
|
|
56
80
|
* @cssstate placed-bottom - The panel sits below its target.
|
|
@@ -85,6 +109,11 @@ export declare class HelixHeadlessTourStop extends HelixElement {
|
|
|
85
109
|
* The id of the element the stop points at.
|
|
86
110
|
*/
|
|
87
111
|
for: string;
|
|
112
|
+
/**
|
|
113
|
+
* The panel's name, where neither the `heading` slot nor the content holds a
|
|
114
|
+
* heading.
|
|
115
|
+
*/
|
|
116
|
+
label: string;
|
|
88
117
|
/**
|
|
89
118
|
* Whether the stop is the last one. Its next control then shows `doneLabel`.
|
|
90
119
|
*/
|
|
@@ -97,10 +126,30 @@ export declare class HelixHeadlessTourStop extends HelixElement {
|
|
|
97
126
|
* The side of the target the panel is placed on when there is room.
|
|
98
127
|
*/
|
|
99
128
|
placement: Placement;
|
|
129
|
+
/**
|
|
130
|
+
* @internal Set by the tour: the stop's place in it, such as "2 of 5".
|
|
131
|
+
*/
|
|
132
|
+
position: string;
|
|
133
|
+
/**
|
|
134
|
+
* @internal Set by the tour: whether the stop's place is drawn as well as
|
|
135
|
+
* read.
|
|
136
|
+
*/
|
|
137
|
+
progress: boolean;
|
|
100
138
|
/**
|
|
101
139
|
* Label for the control that leaves the tour.
|
|
102
140
|
*/
|
|
103
141
|
skipLabel: string;
|
|
142
|
+
/**
|
|
143
|
+
* What kind of stop this is. Unset, it is a bubble pointing at its target.
|
|
144
|
+
*
|
|
145
|
+
* - `dialog`: a panel in the middle of the window, over a backdrop
|
|
146
|
+
* - `floating`: a panel in a corner of the window
|
|
147
|
+
* - `wait`: nothing shown, while the tour waits for the target to be on the page
|
|
148
|
+
*
|
|
149
|
+
* Reflected, because the styled tier places a dialog and a floating panel by
|
|
150
|
+
* it, and unset at rest, so no default is written onto the host.
|
|
151
|
+
*/
|
|
152
|
+
type?: 'dialog' | 'floating' | 'wait';
|
|
104
153
|
/**
|
|
105
154
|
* The side of its target the panel last landed on, which names the arrow's
|
|
106
155
|
* second part. Undefined until the first placement, which the server never
|
|
@@ -110,7 +159,20 @@ export declare class HelixHeadlessTourStop extends HelixElement {
|
|
|
110
159
|
/** The element the stop points at, or `null` when no element has the `for` id. */
|
|
111
160
|
get target(): HTMLElement | null;
|
|
112
161
|
private readonly floating;
|
|
113
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Moves focus to the panel while the stop is shown.
|
|
164
|
+
*
|
|
165
|
+
* The host draws no box and takes no focus, so focusing it did nothing. The
|
|
166
|
+
* panel takes focus without joining the `Tab` order, and a screen reader
|
|
167
|
+
* reads the group it is.
|
|
168
|
+
*/
|
|
169
|
+
focus(options?: FocusOptions): void;
|
|
170
|
+
/**
|
|
171
|
+
* Names and describes the panel, by element reference: the words are in the
|
|
172
|
+
* light DOM and the panel in this shadow root, which an IDREF cannot cross.
|
|
173
|
+
* `stopNaming` decides which words.
|
|
174
|
+
*/
|
|
175
|
+
private nameByHeading;
|
|
114
176
|
protected updated(changed: PropertyValues): void;
|
|
115
177
|
/**
|
|
116
178
|
* Skip, back and next, behind a seam the styled tier can move.
|
|
@@ -4,10 +4,12 @@ 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, elementById, HelixElement, HelixTourAskEvent,
|
|
7
|
+
import { arrowReach, customElement, elementById, HelixElement, HelixTourAskEvent, PopoverController, reflectElements, sideOf, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { nothing } from 'lit';
|
|
8
9
|
import { property, state } from 'lit/decorators.js';
|
|
9
10
|
import { html } from 'lit/static-html.js';
|
|
10
11
|
import '../../button/index.js';
|
|
12
|
+
import { stopNaming } from '../naming.js';
|
|
11
13
|
let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
12
14
|
constructor() {
|
|
13
15
|
super(...arguments);
|
|
@@ -16,26 +18,30 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
16
18
|
this.doneLabel = 'Done';
|
|
17
19
|
this.first = false;
|
|
18
20
|
this.for = '';
|
|
21
|
+
this.label = '';
|
|
19
22
|
this.last = false;
|
|
20
23
|
this.nextLabel = 'Next';
|
|
21
24
|
this.placement = 'bottom';
|
|
25
|
+
this.position = '';
|
|
26
|
+
this.progress = false;
|
|
22
27
|
this.skipLabel = 'Skip';
|
|
23
28
|
this.floating = new PopoverController(this, {
|
|
24
29
|
anchor: () => this.target,
|
|
25
30
|
arrow: () => this.partNamed('arrow'),
|
|
26
31
|
offset: () => {
|
|
27
32
|
const tour = this.parentElement;
|
|
28
|
-
return (
|
|
33
|
+
return (tour?.spotlightPadding ?? 0) + arrowReach(this.partNamed('arrow'));
|
|
29
34
|
},
|
|
30
35
|
onDismiss: () => { },
|
|
31
36
|
onPlace: (placement) => {
|
|
32
|
-
const side = placement
|
|
37
|
+
const side = sideOf(placement);
|
|
33
38
|
this.toggleState('placed-bottom', side === 'bottom');
|
|
34
39
|
this.toggleState('placed-left', side === 'left');
|
|
35
40
|
this.toggleState('placed-right', side === 'right');
|
|
36
41
|
this.toggleState('placed-top', side === 'top');
|
|
37
42
|
this.side = side;
|
|
38
43
|
},
|
|
44
|
+
place: () => this.type === undefined,
|
|
39
45
|
placement: () => this.placement,
|
|
40
46
|
surface: () => this.partNamed('bubble'),
|
|
41
47
|
});
|
|
@@ -43,13 +49,33 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
43
49
|
get target() {
|
|
44
50
|
return this.for === '' ? null : elementById(this, this.for);
|
|
45
51
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
focus(options) {
|
|
53
|
+
const bubble = this.partNamed('bubble');
|
|
54
|
+
if (this.current && bubble) {
|
|
55
|
+
bubble.focus(options);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
super.focus(options);
|
|
59
|
+
}
|
|
60
|
+
nameByHeading() {
|
|
61
|
+
const bubble = this.partNamed('bubble');
|
|
62
|
+
const slotted = (name) => this.renderRoot
|
|
63
|
+
.querySelector(`slot[name="${name}"]`)
|
|
64
|
+
?.assignedElements({ flatten: true }) ?? [];
|
|
65
|
+
const { describedBy, labelledBy } = stopNaming({
|
|
66
|
+
content: [...this.children].filter((one) => !one.slot),
|
|
67
|
+
description: slotted('description'),
|
|
68
|
+
heading: slotted('heading'),
|
|
69
|
+
labeled: this.label !== '',
|
|
70
|
+
progress: this.position === '' ? null : this.partNamed('progress'),
|
|
71
|
+
});
|
|
72
|
+
reflectElements(bubble, 'ariaLabelledByElements', labelledBy, true);
|
|
73
|
+
reflectElements(bubble, 'ariaDescribedByElements', describedBy, true);
|
|
49
74
|
}
|
|
50
75
|
updated(changed) {
|
|
51
76
|
super.updated(changed);
|
|
52
|
-
|
|
77
|
+
this.nameByHeading();
|
|
78
|
+
if (this.current && this.type !== 'wait') {
|
|
53
79
|
this.floating.show();
|
|
54
80
|
}
|
|
55
81
|
else {
|
|
@@ -60,14 +86,14 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
60
86
|
return html `<slot name="actions">
|
|
61
87
|
<${this.tag('button')}
|
|
62
88
|
part="skip"
|
|
63
|
-
exportparts="button: skip-button, text: skip-text" emphasis="ghost" @click=${() => this.ask('skip')}>
|
|
89
|
+
exportparts="button: skip-button, live: skip-live, text: skip-text" emphasis="ghost" @click=${() => this.ask('skip')}>
|
|
64
90
|
${this.skipLabel}
|
|
65
91
|
</${this.tag('button')}>
|
|
66
92
|
${this.first
|
|
67
93
|
? ''
|
|
68
94
|
: html `<${this.tag('button')}
|
|
69
95
|
part="back"
|
|
70
|
-
exportparts="button: back-button, text: back-text"
|
|
96
|
+
exportparts="button: back-button, live: back-live, text: back-text"
|
|
71
97
|
emphasis="outlined"
|
|
72
98
|
@click=${() => this.ask('back')}
|
|
73
99
|
>
|
|
@@ -75,7 +101,7 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
75
101
|
</${this.tag('button')}>`}
|
|
76
102
|
<${this.tag('button')}
|
|
77
103
|
part="next"
|
|
78
|
-
exportparts="button: next-button, text: next-text"
|
|
104
|
+
exportparts="button: next-button, live: next-live, text: next-text"
|
|
79
105
|
emphasis="solid"
|
|
80
106
|
tone="primary"
|
|
81
107
|
@click=${() => this.ask('next')}
|
|
@@ -85,13 +111,25 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
85
111
|
</slot>`;
|
|
86
112
|
}
|
|
87
113
|
render() {
|
|
88
|
-
return html `<div
|
|
114
|
+
return html `<div
|
|
115
|
+
part="bubble"
|
|
116
|
+
popover="manual"
|
|
117
|
+
role=${this.type === 'dialog' ? 'dialog' : 'group'}
|
|
118
|
+
tabindex="-1"
|
|
119
|
+
aria-label=${this.label || nothing}
|
|
120
|
+
?hidden=${!this.current || this.type === 'wait'}
|
|
121
|
+
>
|
|
89
122
|
${''}
|
|
90
123
|
<div
|
|
91
124
|
part="arrow${this.side ? { bottom: ' arrow-bottom', left: ' arrow-left', right: ' arrow-right', top: ' arrow-top' }[this.side] : ''}"
|
|
92
125
|
aria-hidden="true"
|
|
93
126
|
></div>
|
|
127
|
+
<slot name="heading" part="heading" @slotchange=${this.nameByHeading}></slot>
|
|
128
|
+
<slot name="description" part="description" @slotchange=${this.nameByHeading}></slot>
|
|
94
129
|
<div part="content"><slot></slot></div>
|
|
130
|
+
${this.position === ''
|
|
131
|
+
? ''
|
|
132
|
+
: html `<span part="progress" ?hidden=${!this.progress}>${this.position}</span>`}
|
|
95
133
|
<div part="actions">
|
|
96
134
|
${this.renderActions()}
|
|
97
135
|
</div>
|
|
@@ -116,6 +154,9 @@ __decorate([
|
|
|
116
154
|
__decorate([
|
|
117
155
|
property()
|
|
118
156
|
], HelixHeadlessTourStop.prototype, "for", void 0);
|
|
157
|
+
__decorate([
|
|
158
|
+
property()
|
|
159
|
+
], HelixHeadlessTourStop.prototype, "label", void 0);
|
|
119
160
|
__decorate([
|
|
120
161
|
property({ reflect: true, type: Boolean })
|
|
121
162
|
], HelixHeadlessTourStop.prototype, "last", void 0);
|
|
@@ -125,9 +166,18 @@ __decorate([
|
|
|
125
166
|
__decorate([
|
|
126
167
|
property()
|
|
127
168
|
], HelixHeadlessTourStop.prototype, "placement", void 0);
|
|
169
|
+
__decorate([
|
|
170
|
+
property({ attribute: false })
|
|
171
|
+
], HelixHeadlessTourStop.prototype, "position", void 0);
|
|
172
|
+
__decorate([
|
|
173
|
+
property({ attribute: false })
|
|
174
|
+
], HelixHeadlessTourStop.prototype, "progress", void 0);
|
|
128
175
|
__decorate([
|
|
129
176
|
property({ attribute: 'skip-label' })
|
|
130
177
|
], HelixHeadlessTourStop.prototype, "skipLabel", void 0);
|
|
178
|
+
__decorate([
|
|
179
|
+
property({ reflect: true })
|
|
180
|
+
], HelixHeadlessTourStop.prototype, "type", void 0);
|
|
131
181
|
__decorate([
|
|
132
182
|
state()
|
|
133
183
|
], HelixHeadlessTourStop.prototype, "side", void 0);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calls `then` once `ready` answers yes: at once if it already does, and
|
|
3
|
+
* otherwise on the first change to the tree under `root` after which it does.
|
|
4
|
+
*
|
|
5
|
+
* What a tour's `wait` stop rests on: the tour waits for the element the stop
|
|
6
|
+
* names to be on the page, such as a menu the reader has to open, and moves on
|
|
7
|
+
* by itself. Returns a function that stops waiting.
|
|
8
|
+
*/
|
|
9
|
+
export declare const waitFor: (root: Node, ready: () => boolean, then: () => void) => (() => void);
|
|
10
|
+
/** Whether an element is on the page and draws something a reader can see. */
|
|
11
|
+
export declare const onPage: (element: Element | null | undefined) => boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const waitFor = (root, ready, then) => {
|
|
2
|
+
if (ready()) {
|
|
3
|
+
then();
|
|
4
|
+
return () => { };
|
|
5
|
+
}
|
|
6
|
+
if (typeof MutationObserver === 'undefined') {
|
|
7
|
+
return () => { };
|
|
8
|
+
}
|
|
9
|
+
const watcher = new MutationObserver(() => {
|
|
10
|
+
if (ready()) {
|
|
11
|
+
watcher.disconnect();
|
|
12
|
+
then();
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
watcher.observe(root, { attributes: true, childList: true, subtree: true });
|
|
16
|
+
return () => watcher.disconnect();
|
|
17
|
+
};
|
|
18
|
+
export const onPage = (element) => element?.isConnected === true &&
|
|
19
|
+
(typeof element.getClientRects !== 'function' || element.getClientRects().length > 0);
|
|
@@ -19,6 +19,10 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
19
19
|
* **`href` makes the whole row a link**, rendered as an `<a>`. Enter, middle
|
|
20
20
|
* click, and the status bar then work anywhere on the row.
|
|
21
21
|
*
|
|
22
|
+
* Pressing a branch, or Enter or Space on it, opens or closes it. A branch with
|
|
23
|
+
* a `value` is chosen as well and sends `helix-select`, unless the tree has
|
|
24
|
+
* `nesting="heading"`, where a branch names the list under it.
|
|
25
|
+
*
|
|
22
26
|
* @since 0.1.0
|
|
23
27
|
* @status stable
|
|
24
28
|
* @aliases TreeNode, Branch, Leaf
|
|
@@ -32,7 +36,7 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
32
36
|
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before a branch closes, and cancelable.
|
|
33
37
|
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before a branch opens, and cancelable.
|
|
34
38
|
* @event {HelixSelectEvent} helix-select - Fired when the item is chosen, and cancelable. Canceling it changes nothing.
|
|
35
|
-
* @event {
|
|
39
|
+
* @event {ToggleEvent} toggle - Sent when the branch opens or closes, with `newState` and `oldState`.
|
|
36
40
|
*
|
|
37
41
|
* @csspart group - The container for nested items.
|
|
38
42
|
* @csspart item - The node, and the focus target unless `href` moves it to the row.
|
|
@@ -46,6 +50,12 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
46
50
|
* @cssstate selected - While it is selected.
|
|
47
51
|
*/
|
|
48
52
|
export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
53
|
+
/**
|
|
54
|
+
* @internal Set by the tree: whether a branch heads the list under it, as
|
|
55
|
+
* under `nesting="heading"`. Such a branch only opens and closes when it is
|
|
56
|
+
* pressed, because it names a list and is not a destination of its own.
|
|
57
|
+
*/
|
|
58
|
+
heads: boolean;
|
|
49
59
|
/**
|
|
50
60
|
* The URL this node links to. Setting it makes the row a link.
|
|
51
61
|
*
|
|
@@ -101,14 +111,14 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
101
111
|
* Where the link opens. Use it for a row that leaves the site.
|
|
102
112
|
*/
|
|
103
113
|
target: string;
|
|
104
|
-
/**
|
|
105
|
-
* Identifies the item to your code. It is sent in `helix-select`.
|
|
106
|
-
*/
|
|
107
|
-
value: string;
|
|
108
114
|
/**
|
|
109
115
|
* Whether this item holds the tree's single tab stop.
|
|
110
116
|
*/
|
|
111
117
|
focusable: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Identifies the item to your code. It is sent in `helix-select`.
|
|
120
|
+
*/
|
|
121
|
+
value: string;
|
|
112
122
|
/**
|
|
113
123
|
* Whether anything is slotted into `children`.
|
|
114
124
|
*
|
|
@@ -119,6 +129,12 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
119
129
|
*/
|
|
120
130
|
private branch;
|
|
121
131
|
protected firstUpdated(changed: PropertyValues): void;
|
|
132
|
+
/**
|
|
133
|
+
* @internal Whether pressing this branch chooses it as well as opening or
|
|
134
|
+
* closing it: it has a value and does not head its list. Read by the tree
|
|
135
|
+
* for Enter and Space.
|
|
136
|
+
*/
|
|
137
|
+
get choosable(): boolean;
|
|
122
138
|
/**
|
|
123
139
|
* @internal Whether this row holds children, read by the tree, which moves
|
|
124
140
|
* and opens differently for a branch. Public rather than protected because
|
|
@@ -12,12 +12,13 @@ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
|
12
12
|
let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerOpen(HelixElement) {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
|
+
this.heads = false;
|
|
15
16
|
this.href = '';
|
|
16
17
|
this.rel = '';
|
|
17
18
|
this.selected = false;
|
|
18
19
|
this.target = '';
|
|
19
|
-
this.value = '';
|
|
20
20
|
this.focusable = false;
|
|
21
|
+
this.value = '';
|
|
21
22
|
this.branch = false;
|
|
22
23
|
this.handleToggleClick = (event) => {
|
|
23
24
|
event.preventDefault();
|
|
@@ -28,6 +29,9 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
28
29
|
const onLink = event.composedPath().some((node) => node instanceof HTMLAnchorElement);
|
|
29
30
|
if (this.branch && this.href === '') {
|
|
30
31
|
if (!onLink) {
|
|
32
|
+
if (this.choosable) {
|
|
33
|
+
this.select();
|
|
34
|
+
}
|
|
31
35
|
this.toggleOpen();
|
|
32
36
|
}
|
|
33
37
|
return;
|
|
@@ -46,6 +50,9 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
46
50
|
this.branch = slot.assignedElements().length > 0;
|
|
47
51
|
});
|
|
48
52
|
}
|
|
53
|
+
get choosable() {
|
|
54
|
+
return this.value !== '' && !this.heads;
|
|
55
|
+
}
|
|
49
56
|
get isBranch() {
|
|
50
57
|
return this.branch;
|
|
51
58
|
}
|
|
@@ -145,6 +152,9 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
145
152
|
</div>`;
|
|
146
153
|
}
|
|
147
154
|
};
|
|
155
|
+
__decorate([
|
|
156
|
+
property({ attribute: false })
|
|
157
|
+
], HelixHeadlessTreeItem.prototype, "heads", void 0);
|
|
148
158
|
__decorate([
|
|
149
159
|
property()
|
|
150
160
|
], HelixHeadlessTreeItem.prototype, "href", void 0);
|
|
@@ -160,12 +170,12 @@ __decorate([
|
|
|
160
170
|
__decorate([
|
|
161
171
|
property()
|
|
162
172
|
], HelixHeadlessTreeItem.prototype, "target", void 0);
|
|
163
|
-
__decorate([
|
|
164
|
-
property()
|
|
165
|
-
], HelixHeadlessTreeItem.prototype, "value", void 0);
|
|
166
173
|
__decorate([
|
|
167
174
|
state()
|
|
168
175
|
], HelixHeadlessTreeItem.prototype, "focusable", void 0);
|
|
176
|
+
__decorate([
|
|
177
|
+
property()
|
|
178
|
+
], HelixHeadlessTreeItem.prototype, "value", void 0);
|
|
169
179
|
__decorate([
|
|
170
180
|
state()
|
|
171
181
|
], HelixHeadlessTreeItem.prototype, "branch", void 0);
|