@fusion.dev/helix-headless 0.143.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 +16990 -1383
- 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/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +24 -7
- package/dist/avatar/root/avatar-root.d.ts +14 -0
- package/dist/avatar/root/avatar-root.js +23 -9
- package/dist/badge/root/badge-root.d.ts +11 -7
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
- package/dist/bar-chart/root/bar-chart-root.js +17 -10
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
- package/dist/button/root/button-root.d.ts +47 -1
- package/dist/button/root/button-root.js +38 -4
- package/dist/callout/root/callout-root.d.ts +18 -1
- package/dist/callout/root/callout-root.js +15 -4
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +121 -40
- 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 +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/checkbox/root/checkbox-root.js +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
- package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
- 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 +38 -1
- package/dist/code-block/root/code-block-root.js +28 -7
- package/dist/color-input/root/color-input-root.d.ts +34 -1
- package/dist/color-input/root/color-input-root.js +23 -4
- 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 +81 -5
- package/dist/color-picker/root/color-picker-root.js +103 -10
- package/dist/combobox/root/combobox-root.d.ts +38 -3
- package/dist/combobox/root/combobox-root.js +64 -2
- package/dist/command/root/command-root.d.ts +30 -4
- package/dist/command/root/command-root.js +33 -3
- 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 +47 -1
- package/dist/copy-button/root/copy-button-root.js +44 -8
- 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/date-input/root/date-input-root.d.ts +73 -4
- package/dist/date-input/root/date-input-root.js +93 -43
- package/dist/date-picker/root/date-picker-root.d.ts +145 -1
- package/dist/date-picker/root/date-picker-root.js +239 -48
- 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/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +64 -1
- package/dist/dialog/root/dialog-root.js +49 -23
- package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
- package/dist/donut-chart/root/donut-chart-root.js +21 -6
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +95 -19
- 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 +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 +61 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +47 -0
- package/dist/file-input/root/file-input-root.js +60 -22
- 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 +3 -0
- package/dist/filter-input/menu/filter-menu.js +8 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -4
- package/dist/filter-input/root/filter-input-root.js +67 -3
- 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 +51 -0
- package/dist/format-date/root/format-date-root.js +58 -38
- package/dist/heatmap/root/heatmap-root.d.ts +23 -6
- package/dist/heatmap/root/heatmap-root.js +24 -13
- 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 +30 -4
- package/dist/icon/root/icon-root.js +41 -6
- 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/image/root/image-root.d.ts +14 -0
- package/dist/image/root/image-root.js +23 -2
- package/dist/input/root/input-root.d.ts +11 -0
- package/dist/input/root/input-root.js +16 -1
- package/dist/kbd/root/kbd-root.d.ts +20 -13
- package/dist/kbd/root/kbd-root.js +35 -37
- 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 +56 -0
- package/dist/legend/root/legend-root.js +54 -5
- package/dist/lightbox/item/lightbox-item.d.ts +15 -0
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +61 -1
- package/dist/lightbox/root/lightbox-root.js +94 -4
- package/dist/line-chart/root/line-chart-root.d.ts +11 -3
- package/dist/line-chart/root/line-chart-root.js +19 -5
- 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.d.ts +74 -3
- package/dist/listbox/root/listbox-root.js +86 -9
- 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 +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/meter/root/meter-root.d.ts +7 -0
- package/dist/meter/root/meter-root.js +6 -3
- package/dist/navigation/root/navigation-root.d.ts +16 -1
- package/dist/navigation/root/navigation-root.js +27 -1
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/notification/notification.d.ts +17 -0
- package/dist/notifications/notification/notification.js +21 -2
- package/dist/notifications/root/notifications-root.d.ts +60 -0
- package/dist/notifications/root/notifications-root.js +76 -1
- package/dist/number-input/root/number-input-root.d.ts +47 -0
- package/dist/number-input/root/number-input-root.js +58 -22
- package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
- package/dist/object-inspector/root/object-inspector-root.js +180 -80
- package/dist/object-inspector/rows.d.ts +57 -0
- package/dist/object-inspector/rows.js +86 -0
- package/dist/option/root/option-root.d.ts +54 -5
- package/dist/option/root/option-root.js +34 -5
- 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/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 +21 -0
- package/dist/pin-input/root/pin-input-root.js +29 -2
- package/dist/popover/root/popover-root.d.ts +62 -4
- package/dist/popover/root/popover-root.js +53 -5
- package/dist/progress/root/progress-root.d.ts +7 -0
- package/dist/progress/root/progress-root.js +9 -3
- 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 +26 -0
- package/dist/qr-code/root/qr-code-root.js +49 -2
- package/dist/radio/group/radio-group.d.ts +17 -0
- package/dist/radio/group/radio-group.js +14 -1
- package/dist/rating/root/rating-root.d.ts +25 -0
- package/dist/rating/root/rating-root.js +46 -4
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
- 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.d.ts +24 -0
- package/dist/select/root/select-root.js +21 -7
- package/dist/skeleton/root/skeleton-root.d.ts +25 -0
- package/dist/skeleton/root/skeleton-root.js +17 -2
- package/dist/slider/root/slider-root.d.ts +39 -0
- package/dist/slider/root/slider-root.js +45 -9
- 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/stat/root/stat-root.d.ts +2 -0
- package/dist/stat/root/stat-root.js +1 -1
- 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 +39 -2
- package/dist/steps/step/step.js +29 -7
- package/dist/switch/root/switch-root.d.ts +12 -2
- package/dist/switch/root/switch-root.js +6 -1
- 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/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 +60 -0
- package/dist/tag/root/tag-root.js +74 -18
- 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 +9 -0
- package/dist/textarea/root/textarea-root.js +9 -1
- package/dist/time-input/root/time-input-root.d.ts +44 -5
- package/dist/time-input/root/time-input-root.js +69 -39
- package/dist/time-picker/root/time-picker-root.d.ts +54 -8
- package/dist/time-picker/root/time-picker-root.js +121 -91
- 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/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +26 -18
- package/dist/toast/item/toast-item.js +55 -48
- package/dist/toast/root/toast-root.d.ts +42 -8
- package/dist/toast/root/toast-root.js +64 -4
- package/dist/toggle/group/toggle-group.d.ts +57 -15
- package/dist/toggle/group/toggle-group.js +69 -9
- package/dist/toggle/root/toggle-root.d.ts +12 -1
- package/dist/toggle/root/toggle-root.js +11 -3
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- 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 +42 -17
- package/dist/tooltip/root/tooltip-root.js +50 -9
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +35 -0
- package/dist/tour/root/tour-root.js +56 -5
- package/dist/tour/stop/tour-stop.d.ts +53 -8
- package/dist/tour/stop/tour-stop.js +45 -15
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- 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/trend/root/trend-root.d.ts +13 -0
- package/dist/trend/root/trend-root.js +14 -9
- 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 +8871 -1286
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1918 -269
|
@@ -4,22 +4,31 @@ 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, HelixElement, HelixSelectEvent, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
8
|
-
import { caretDown } from '@fusion.dev/helix-icons';
|
|
7
|
+
import { customElement, HelixElement, HelixLoadEvent, HelixSelectEvent, MixinControllerOpen, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { caretDown, check, minus } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
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.checkable = false;
|
|
16
|
+
this.checked = false;
|
|
17
|
+
this.disabled = false;
|
|
15
18
|
this.heads = false;
|
|
16
19
|
this.href = '';
|
|
20
|
+
this.lazy = false;
|
|
17
21
|
this.rel = '';
|
|
18
22
|
this.selected = false;
|
|
19
23
|
this.target = '';
|
|
20
24
|
this.focusable = false;
|
|
21
25
|
this.value = '';
|
|
22
26
|
this.branch = false;
|
|
27
|
+
this.handleCheckClick = (event) => {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
event.stopPropagation();
|
|
30
|
+
this.select();
|
|
31
|
+
};
|
|
23
32
|
this.handleToggleClick = (event) => {
|
|
24
33
|
event.preventDefault();
|
|
25
34
|
event.stopPropagation();
|
|
@@ -27,7 +36,11 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
27
36
|
};
|
|
28
37
|
this.handleRowClick = (event) => {
|
|
29
38
|
const onLink = event.composedPath().some((node) => node instanceof HTMLAnchorElement);
|
|
30
|
-
if (this.
|
|
39
|
+
if (this.disabled) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (this.isBranch && this.href === '') {
|
|
31
44
|
if (!onLink) {
|
|
32
45
|
if (this.choosable) {
|
|
33
46
|
this.select();
|
|
@@ -51,10 +64,10 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
51
64
|
});
|
|
52
65
|
}
|
|
53
66
|
get choosable() {
|
|
54
|
-
return this.value !== '' && !this.heads;
|
|
67
|
+
return this.value !== '' && !this.heads && !this.checkable && !this.disabled;
|
|
55
68
|
}
|
|
56
69
|
get isBranch() {
|
|
57
|
-
return this.branch;
|
|
70
|
+
return this.branch || this.lazy;
|
|
58
71
|
}
|
|
59
72
|
focusItem() {
|
|
60
73
|
this.renderRoot
|
|
@@ -62,12 +75,21 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
62
75
|
?.focus({ preventScroll: true });
|
|
63
76
|
}
|
|
64
77
|
select() {
|
|
78
|
+
if (this.disabled) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
65
81
|
this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
|
|
66
82
|
}
|
|
67
83
|
activate() {
|
|
84
|
+
if (this.disabled) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
68
87
|
this.select();
|
|
69
88
|
this.follow();
|
|
70
89
|
}
|
|
90
|
+
toggleOpen() {
|
|
91
|
+
return this.disabled ? false : super.toggleOpen();
|
|
92
|
+
}
|
|
71
93
|
follow() {
|
|
72
94
|
const own = this.renderRoot?.querySelector('a[part="row"]');
|
|
73
95
|
if (own) {
|
|
@@ -85,18 +107,32 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
85
107
|
}
|
|
86
108
|
}
|
|
87
109
|
}
|
|
110
|
+
renderToggle() {
|
|
111
|
+
return html `<slot
|
|
112
|
+
name="chevron"
|
|
113
|
+
@click=${this.href === '' ? nothing : this.handleToggleClick}
|
|
114
|
+
><svg part="toggle" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
|
|
115
|
+
${unsafeSVG(caretDown.content)}
|
|
116
|
+
</svg></slot
|
|
117
|
+
>`;
|
|
118
|
+
}
|
|
119
|
+
renderCheckbox() {
|
|
120
|
+
if (!this.checkable) {
|
|
121
|
+
return nothing;
|
|
122
|
+
}
|
|
123
|
+
const mixed = this.checked === 'mixed';
|
|
124
|
+
const glyph = mixed ? minus : this.checked ? check : undefined;
|
|
125
|
+
return html `<span
|
|
126
|
+
part="checkbox${mixed ? ' checkbox-mixed' : this.checked ? ' checkbox-checked' : ''}"
|
|
127
|
+
aria-hidden="true"
|
|
128
|
+
@click=${this.handleCheckClick}
|
|
129
|
+
>${glyph
|
|
130
|
+
? html `<svg fill="currentColor" viewBox=${glyph.viewBox}>${unsafeSVG(glyph.content)}</svg>`
|
|
131
|
+
: nothing}</span
|
|
132
|
+
>`;
|
|
133
|
+
}
|
|
88
134
|
renderRow() {
|
|
89
|
-
return html `${this.
|
|
90
|
-
? html `<svg
|
|
91
|
-
part="toggle"
|
|
92
|
-
fill="currentColor"
|
|
93
|
-
viewBox=${caretDown.viewBox}
|
|
94
|
-
aria-hidden="true"
|
|
95
|
-
@click=${this.href === '' ? nothing : this.handleToggleClick}
|
|
96
|
-
>
|
|
97
|
-
${unsafeSVG(caretDown.content)}
|
|
98
|
-
</svg>`
|
|
99
|
-
: nothing}
|
|
135
|
+
return html `${this.isBranch ? this.renderToggle() : nothing}${this.renderCheckbox()}
|
|
100
136
|
<slot name="start"></slot>
|
|
101
137
|
<span part="label"><slot></slot></span>
|
|
102
138
|
<slot name="end"></slot>`;
|
|
@@ -104,21 +140,39 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
104
140
|
willUpdate(changed) {
|
|
105
141
|
super.willUpdate(changed);
|
|
106
142
|
this.toggleState('selected', this.selected);
|
|
143
|
+
this.toggleState('loading', this.open && this.lazy);
|
|
107
144
|
if (this.childrenKnown) {
|
|
108
145
|
this.branch = this.knownChildren.some((child) => child.slot === 'children');
|
|
109
146
|
}
|
|
110
147
|
}
|
|
148
|
+
updated(changed) {
|
|
149
|
+
super.updated(changed);
|
|
150
|
+
if (changed.has('open') && this.open && this.lazy) {
|
|
151
|
+
this.dispatchEvent(new HelixLoadEvent());
|
|
152
|
+
}
|
|
153
|
+
}
|
|
111
154
|
render() {
|
|
112
155
|
const linked = this.href !== '';
|
|
113
156
|
const level = this.level ?? 1;
|
|
114
157
|
const depth = this.level ?? nothing;
|
|
115
|
-
const expanded = this.
|
|
158
|
+
const expanded = this.isBranch ? (this.open ? 'true' : 'false') : nothing;
|
|
159
|
+
const chosen = this.checkable ? undefined : this.selected ? 'true' : 'false';
|
|
160
|
+
const checked = this.checkable
|
|
161
|
+
? this.checked === 'mixed'
|
|
162
|
+
? 'mixed'
|
|
163
|
+
: String(this.checked)
|
|
164
|
+
: undefined;
|
|
165
|
+
const busy = this.open && this.lazy ? 'true' : nothing;
|
|
166
|
+
const off = this.disabled ? 'true' : nothing;
|
|
116
167
|
const tabIndex = this.focusable || !this.childrenKnown ? '0' : '-1';
|
|
117
168
|
return html `<div
|
|
118
169
|
part="item"
|
|
119
170
|
role=${linked ? 'none' : 'treeitem'}
|
|
120
171
|
aria-expanded=${linked ? nothing : expanded}
|
|
121
|
-
aria-selected=${linked ? nothing :
|
|
172
|
+
aria-selected=${linked ? nothing : (chosen ?? nothing)}
|
|
173
|
+
aria-checked=${linked ? nothing : (checked ?? nothing)}
|
|
174
|
+
aria-disabled=${linked ? nothing : off}
|
|
175
|
+
aria-busy=${linked ? nothing : busy}
|
|
122
176
|
aria-level=${linked ? nothing : depth}
|
|
123
177
|
tabindex=${linked ? nothing : tabIndex}
|
|
124
178
|
>
|
|
@@ -126,11 +180,14 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
126
180
|
? html `<a
|
|
127
181
|
part="row"
|
|
128
182
|
role="treeitem"
|
|
129
|
-
href=${this.href}
|
|
183
|
+
href=${this.disabled ? nothing : this.href}
|
|
130
184
|
target=${this.target || nothing}
|
|
131
185
|
rel=${this.rel || nothing}
|
|
132
186
|
aria-expanded=${expanded}
|
|
133
|
-
aria-selected=${
|
|
187
|
+
aria-selected=${chosen ?? nothing}
|
|
188
|
+
aria-checked=${checked ?? nothing}
|
|
189
|
+
aria-disabled=${off}
|
|
190
|
+
aria-busy=${busy}
|
|
134
191
|
aria-level=${depth}
|
|
135
192
|
tabindex=${tabIndex}
|
|
136
193
|
style="--tree-level: ${level}"
|
|
@@ -152,12 +209,24 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
152
209
|
</div>`;
|
|
153
210
|
}
|
|
154
211
|
};
|
|
212
|
+
__decorate([
|
|
213
|
+
property({ attribute: false })
|
|
214
|
+
], HelixHeadlessTreeItem.prototype, "checkable", void 0);
|
|
215
|
+
__decorate([
|
|
216
|
+
property({ attribute: false })
|
|
217
|
+
], HelixHeadlessTreeItem.prototype, "checked", void 0);
|
|
218
|
+
__decorate([
|
|
219
|
+
property({ reflect: true, type: Boolean })
|
|
220
|
+
], HelixHeadlessTreeItem.prototype, "disabled", void 0);
|
|
155
221
|
__decorate([
|
|
156
222
|
property({ attribute: false })
|
|
157
223
|
], HelixHeadlessTreeItem.prototype, "heads", void 0);
|
|
158
224
|
__decorate([
|
|
159
225
|
property()
|
|
160
226
|
], HelixHeadlessTreeItem.prototype, "href", void 0);
|
|
227
|
+
__decorate([
|
|
228
|
+
property({ reflect: true, type: Boolean })
|
|
229
|
+
], HelixHeadlessTreeItem.prototype, "lazy", void 0);
|
|
161
230
|
__decorate([
|
|
162
231
|
property({ attribute: false, type: Number })
|
|
163
232
|
], HelixHeadlessTreeItem.prototype, "level", void 0);
|
|
@@ -16,6 +16,14 @@ declare const HelixHeadlessTree_base: (new (...args: any[]) => import("@fusion.d
|
|
|
16
16
|
* Typing a letter moves to the next visible item whose name starts with it,
|
|
17
17
|
* and `*` opens every branch beside the focused item.
|
|
18
18
|
*
|
|
19
|
+
* `selection-mode="multiple"` draws a check mark on every row and lets a
|
|
20
|
+
* reader check many, as Web Awesome's and Ark UI's checkbox trees do. Checking
|
|
21
|
+
* a branch checks every item under it, and a branch some of whose items are
|
|
22
|
+
* checked is partly checked. Space or a press on the mark checks the focused
|
|
23
|
+
* row, and Enter or a press on a branch's row opens it. `active` then holds the
|
|
24
|
+
* checked values, comma separated, which `values` also gives as a list, and
|
|
25
|
+
* the tree says `aria-multiselectable`.
|
|
26
|
+
*
|
|
19
27
|
* @since 0.1.0
|
|
20
28
|
* @status stable
|
|
21
29
|
* @category navigation
|
|
@@ -82,6 +90,21 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
82
90
|
* The resting state is the absence of the attribute, which is `peer`.
|
|
83
91
|
*/
|
|
84
92
|
nesting?: 'heading' | 'peer' | 'subordinate';
|
|
93
|
+
/**
|
|
94
|
+
* Whether a reader can check many items. Unset, one item is chosen at a
|
|
95
|
+
* time.
|
|
96
|
+
*
|
|
97
|
+
* Optional, so a tree of one choice writes no attribute onto the host.
|
|
98
|
+
*/
|
|
99
|
+
selectionMode?: 'multiple';
|
|
100
|
+
/**
|
|
101
|
+
* The checked values, as a list, under `selection-mode="multiple"`, and the
|
|
102
|
+
* chosen value alone otherwise. Writing it sets `active`.
|
|
103
|
+
*/
|
|
104
|
+
get values(): string[];
|
|
105
|
+
set values(next: string[]);
|
|
106
|
+
/** Whether many items can be checked. */
|
|
107
|
+
private get multiple();
|
|
85
108
|
private watcher;
|
|
86
109
|
/**
|
|
87
110
|
* Every item, in the order a reader moving down would meet them.
|
|
@@ -100,6 +123,20 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
|
|
|
100
123
|
/** Items a reader can actually reach: not inside a collapsed branch. */
|
|
101
124
|
private get visibleItems();
|
|
102
125
|
private readonly handleSelection;
|
|
126
|
+
/** Every value in the tree, in the order a reader meets the items. */
|
|
127
|
+
private get order();
|
|
128
|
+
/**
|
|
129
|
+
* Whether an item holds others, read from the tree as well as from the item.
|
|
130
|
+
*
|
|
131
|
+
* **An item hydrating what a server sent has not said it is a branch yet**:
|
|
132
|
+
* it learns that from its children on the render after, and nothing then
|
|
133
|
+
* asks the tree again. Read from its own render alone, a folder served with
|
|
134
|
+
* one of its files checked was counted a leaf and drawn unchecked rather
|
|
135
|
+
* than partly checked, once hydrated.
|
|
136
|
+
*/
|
|
137
|
+
private holds;
|
|
138
|
+
/** What the multiple selection reads of an item. */
|
|
139
|
+
private rowOf;
|
|
103
140
|
/**
|
|
104
141
|
* Pushes tree-owned state down: which item is selected, which holds the tab
|
|
105
142
|
* stop, and how deep each one sits.
|
|
@@ -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 { AriaForwardController, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, slottedWords, Typeahead, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, closestInstance, commaList, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, slottedWords, Typeahead, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessTreeItem } from '../item/tree-item.js';
|
|
11
|
+
import { checkedState, pressRow } from '../selection.js';
|
|
11
12
|
const KEYS = new Set([
|
|
12
13
|
'ArrowDown',
|
|
13
14
|
'ArrowUp',
|
|
@@ -33,7 +34,9 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
if (!event.defaultPrevented) {
|
|
36
|
-
this.requestActive(
|
|
37
|
+
this.requestActive(this.multiple
|
|
38
|
+
? pressRow(this.rowOf(origin), this.values, this.order).join(',')
|
|
39
|
+
: event.detail.value);
|
|
37
40
|
}
|
|
38
41
|
this.syncItems();
|
|
39
42
|
};
|
|
@@ -51,6 +54,11 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
51
54
|
}
|
|
52
55
|
this.typeahead.reset();
|
|
53
56
|
const along = inlineStep(this, event.key);
|
|
57
|
+
if (this.multiple && event.key === ' ') {
|
|
58
|
+
current.select();
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
54
62
|
if (event.key === 'ArrowDown') {
|
|
55
63
|
this.move(current, 1);
|
|
56
64
|
}
|
|
@@ -64,7 +72,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
64
72
|
this.focusOn(this.visibleItems.at(-1));
|
|
65
73
|
}
|
|
66
74
|
else if (along === 1) {
|
|
67
|
-
if (current.isBranch && !current.open) {
|
|
75
|
+
if (current.isBranch && !current.open && !current.disabled) {
|
|
68
76
|
current.requestOpen(true);
|
|
69
77
|
this.syncItems();
|
|
70
78
|
}
|
|
@@ -73,7 +81,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
73
81
|
}
|
|
74
82
|
}
|
|
75
83
|
else if (along === -1) {
|
|
76
|
-
if (current.isBranch && current.open) {
|
|
84
|
+
if (current.isBranch && current.open && !current.disabled) {
|
|
77
85
|
current.requestOpen(false);
|
|
78
86
|
this.syncItems();
|
|
79
87
|
}
|
|
@@ -100,6 +108,15 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
100
108
|
this.syncItems();
|
|
101
109
|
};
|
|
102
110
|
}
|
|
111
|
+
get values() {
|
|
112
|
+
return this.multiple ? commaList(this.active) : this.active === '' ? [] : [this.active];
|
|
113
|
+
}
|
|
114
|
+
set values(next) {
|
|
115
|
+
this.active = next.join(',');
|
|
116
|
+
}
|
|
117
|
+
get multiple() {
|
|
118
|
+
return this.selectionMode === 'multiple';
|
|
119
|
+
}
|
|
103
120
|
get items() {
|
|
104
121
|
return [...this.querySelectorAll('*')].filter((node) => node instanceof HelixHeadlessTreeItem);
|
|
105
122
|
}
|
|
@@ -115,6 +132,25 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
115
132
|
return true;
|
|
116
133
|
});
|
|
117
134
|
}
|
|
135
|
+
get order() {
|
|
136
|
+
return this.items.map((item) => item.value).filter((value) => value !== '');
|
|
137
|
+
}
|
|
138
|
+
holds(item) {
|
|
139
|
+
return item.isBranch || this.items.some((other) => other !== item && item.contains(other));
|
|
140
|
+
}
|
|
141
|
+
rowOf(item) {
|
|
142
|
+
const branch = this.holds(item);
|
|
143
|
+
const leaves = branch
|
|
144
|
+
? this.items
|
|
145
|
+
.filter((other) => other !== item &&
|
|
146
|
+
item.contains(other) &&
|
|
147
|
+
!this.holds(other) &&
|
|
148
|
+
!other.disabled &&
|
|
149
|
+
other.value !== '')
|
|
150
|
+
.map((other) => other.value)
|
|
151
|
+
: [];
|
|
152
|
+
return { branch, disabled: item.disabled, leaves, value: item.value };
|
|
153
|
+
}
|
|
118
154
|
syncItems() {
|
|
119
155
|
const visible = this.visibleItems;
|
|
120
156
|
const chosen = this.resolveActive(visible);
|
|
@@ -122,8 +158,11 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
122
158
|
this.visibleAncestor(this.items.find((item) => item.focusable));
|
|
123
159
|
const stop = held ?? chosen;
|
|
124
160
|
const heads = this.nesting === 'heading';
|
|
161
|
+
const multiple = this.multiple;
|
|
162
|
+
const checked = new Set(this.values);
|
|
125
163
|
for (const item of this.items) {
|
|
126
|
-
const selected = item.value !== '' && item.value === this.active;
|
|
164
|
+
const selected = !multiple && item.value !== '' && item.value === this.active;
|
|
165
|
+
const state = multiple ? checkedState(this.rowOf(item), checked) : false;
|
|
127
166
|
const focusable = item === stop;
|
|
128
167
|
let level = 1;
|
|
129
168
|
let parent = item.parentElement;
|
|
@@ -135,6 +174,8 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
135
174
|
}
|
|
136
175
|
whenHydrated(item, () => {
|
|
137
176
|
item.selected = selected;
|
|
177
|
+
item.checkable = multiple;
|
|
178
|
+
item.checked = state;
|
|
138
179
|
item.focusable = focusable;
|
|
139
180
|
item.level = level;
|
|
140
181
|
item.heads = heads;
|
|
@@ -214,7 +255,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
214
255
|
}
|
|
215
256
|
updated(changed) {
|
|
216
257
|
super.updated(changed);
|
|
217
|
-
if (changed.has('active') || changed.has('nesting')) {
|
|
258
|
+
if (changed.has('active') || changed.has('nesting') || changed.has('selectionMode')) {
|
|
218
259
|
this.syncItems();
|
|
219
260
|
}
|
|
220
261
|
}
|
|
@@ -223,6 +264,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
|
|
|
223
264
|
part="tree"
|
|
224
265
|
role="tree"
|
|
225
266
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
267
|
+
aria-multiselectable=${this.multiple ? 'true' : nothing}
|
|
226
268
|
aria-label=${this.label}
|
|
227
269
|
>
|
|
228
270
|
<slot
|
|
@@ -241,6 +283,9 @@ __decorate([
|
|
|
241
283
|
__decorate([
|
|
242
284
|
property({ reflect: true })
|
|
243
285
|
], HelixHeadlessTree.prototype, "nesting", void 0);
|
|
286
|
+
__decorate([
|
|
287
|
+
property({ attribute: 'selection-mode', reflect: true })
|
|
288
|
+
], HelixHeadlessTree.prototype, "selectionMode", void 0);
|
|
244
289
|
HelixHeadlessTree = __decorate([
|
|
245
290
|
customElement('helix-headless-tree')
|
|
246
291
|
], HelixHeadlessTree);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** What the multiple selection reads of a row. */
|
|
2
|
+
export interface CheckableRow {
|
|
3
|
+
/** Whether the row is a branch, holding rows of its own. */
|
|
4
|
+
branch: boolean;
|
|
5
|
+
/** Whether the row is out of play. Its value is never added or taken away. */
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
/** The values of the leaves under a branch, in order. Empty for a leaf. */
|
|
8
|
+
leaves: readonly string[];
|
|
9
|
+
/** The row's own value. */
|
|
10
|
+
value: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether a row is checked in a tree of check marks: a leaf by its value, and
|
|
14
|
+
* a branch by its leaves, `mixed` where some of them are.
|
|
15
|
+
*/
|
|
16
|
+
export declare const checkedState: (row: CheckableRow, chosen: ReadonlySet<string>) => boolean | 'mixed';
|
|
17
|
+
/**
|
|
18
|
+
* The checked values after a press on `row`, in `order`.
|
|
19
|
+
*
|
|
20
|
+
* A leaf comes in or out. A branch checks every leaf under it, or clears them
|
|
21
|
+
* all where every one is already checked, as Ark UI's and Web Awesome's
|
|
22
|
+
* checkbox trees do. A disabled row changes nothing.
|
|
23
|
+
*/
|
|
24
|
+
export declare const pressRow: (row: CheckableRow, chosen: readonly string[], order: readonly string[]) => string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const valuesOf = (row) => row.branch && row.leaves.length > 0 ? [...row.leaves] : row.value === '' ? [] : [row.value];
|
|
2
|
+
export const checkedState = (row, chosen) => {
|
|
3
|
+
const values = valuesOf(row);
|
|
4
|
+
const count = values.filter((value) => chosen.has(value)).length;
|
|
5
|
+
if (count === 0) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return count === values.length ? true : 'mixed';
|
|
9
|
+
};
|
|
10
|
+
export const pressRow = (row, chosen, order) => {
|
|
11
|
+
if (row.disabled) {
|
|
12
|
+
return [...chosen];
|
|
13
|
+
}
|
|
14
|
+
const values = valuesOf(row);
|
|
15
|
+
const all = values.every((value) => chosen.includes(value));
|
|
16
|
+
const next = new Set(chosen);
|
|
17
|
+
for (const value of values) {
|
|
18
|
+
if (all) {
|
|
19
|
+
next.delete(value);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
next.add(value);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return order.filter((value) => next.has(value));
|
|
26
|
+
};
|
|
@@ -30,6 +30,7 @@ import { type TemplateResult } from 'lit';
|
|
|
30
30
|
* @documentation https://fusion.dev/helix/components/trend
|
|
31
31
|
*
|
|
32
32
|
* @slot - The metric that moved.
|
|
33
|
+
* @slot icon - Replaces the arrow, such as with a glyph of your own set. Slot the one for the current direction.
|
|
33
34
|
* @slot label - The period the metric moved over.
|
|
34
35
|
*
|
|
35
36
|
* @csspart direction - The direction as a word, for people who cannot see the arrow.
|
|
@@ -77,6 +78,18 @@ export declare class HelixHeadlessTrend extends HelixElement {
|
|
|
77
78
|
* The word read out after the direction when the move is a setback.
|
|
78
79
|
*/
|
|
79
80
|
worseLabel: string;
|
|
81
|
+
/**
|
|
82
|
+
* The arrow for the direction, as the fallback of the `icon` slot.
|
|
83
|
+
*
|
|
84
|
+
* Slot fallback, so the page replaces it by slotting a glyph of its own and
|
|
85
|
+
* a trend with none draws the arrow it always did; and a method, so the tier
|
|
86
|
+
* above replaces it by overriding. The word beside it still says the
|
|
87
|
+
* direction either way.
|
|
88
|
+
*/
|
|
89
|
+
protected renderIcon(icon: {
|
|
90
|
+
content: string;
|
|
91
|
+
viewBox: string;
|
|
92
|
+
}): TemplateResult;
|
|
80
93
|
protected render(): TemplateResult;
|
|
81
94
|
}
|
|
82
95
|
declare global {
|
|
@@ -24,20 +24,25 @@ let HelixHeadlessTrend = class HelixHeadlessTrend extends HelixElement {
|
|
|
24
24
|
this.upLabel = 'Up';
|
|
25
25
|
this.worseLabel = 'worse';
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
? `, ${this.good === this.direction ? this.betterLabel : this.worseLabel}`
|
|
31
|
-
: '';
|
|
32
|
-
return html `<svg
|
|
27
|
+
renderIcon(icon) {
|
|
28
|
+
return html `<slot name="icon"
|
|
29
|
+
><svg
|
|
33
30
|
aria-hidden="true"
|
|
34
31
|
data-glyph
|
|
35
32
|
fill="currentColor"
|
|
36
33
|
part="icon"
|
|
37
|
-
viewBox=${
|
|
34
|
+
viewBox=${icon.viewBox}
|
|
38
35
|
>
|
|
39
|
-
${unsafeSVG(
|
|
40
|
-
</svg
|
|
36
|
+
${unsafeSVG(icon.content)}
|
|
37
|
+
</svg></slot
|
|
38
|
+
>`;
|
|
39
|
+
}
|
|
40
|
+
render() {
|
|
41
|
+
const direction = readDirection(this.direction);
|
|
42
|
+
const judgment = this.good && this.direction && this.direction !== 'neutral'
|
|
43
|
+
? `, ${this.good === this.direction ? this.betterLabel : this.worseLabel}`
|
|
44
|
+
: '';
|
|
45
|
+
return html `${this.renderIcon(direction.icon)}
|
|
41
46
|
<span part="direction">${`${this[direction.word]}${judgment}`}</span>
|
|
42
47
|
<slot></slot>
|
|
43
48
|
<slot name="label"></slot>`;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The media events a player sends on from its inner `<video>`, and how.
|
|
3
|
+
*
|
|
4
|
+
* Separable because the set is a decision about the platform, and nothing in it
|
|
5
|
+
* draws. It is the HTML standard's own summary of the events a media element
|
|
6
|
+
* fires, every one of them, so a consumer who listened on a `<video>` listens
|
|
7
|
+
* on the player with the same names and hears the same things. A shorter list
|
|
8
|
+
* would be one more list for a consumer to learn.
|
|
9
|
+
*
|
|
10
|
+
* None of these crosses a shadow boundary on its own. The video is inside the
|
|
11
|
+
* player's shadow root, so a listener on the element a consumer wrote hears
|
|
12
|
+
* nothing at all without the relay.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Every event a media element fires, by the standard's names, sorted.
|
|
16
|
+
*
|
|
17
|
+
* `resize` is on the list because the standard puts it there: it fires when the
|
|
18
|
+
* video's own width or height changes, which is the moment a consumer sizing
|
|
19
|
+
* something to the picture needs.
|
|
20
|
+
*/
|
|
21
|
+
export declare const MEDIA_EVENTS: readonly ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];
|
|
22
|
+
/** One of the media events the player relays. */
|
|
23
|
+
export type MediaEventName = (typeof MEDIA_EVENTS)[number];
|
|
24
|
+
/**
|
|
25
|
+
* The copy the host sends: the same name, neither bubbling nor composed.
|
|
26
|
+
*
|
|
27
|
+
* **As the platform sends it, which is what makes it reach a React consumer at
|
|
28
|
+
* all.** These names are in react-dom's `nonDelegatedEvents`, which React wires
|
|
29
|
+
* on a `<video>` and never on a custom element, so its root listener hears none
|
|
30
|
+
* of them. `bindReactHandler` closes that for an event that does not bubble,
|
|
31
|
+
* and skips one that does, on the grounds that a bubbling relay already reaches
|
|
32
|
+
* React's delegated listener and binding it again would double every call. A
|
|
33
|
+
* copy sent with `bubbles: true` lands in the branch that refuses to bind, and
|
|
34
|
+
* `onPlay` on the player is silent.
|
|
35
|
+
*
|
|
36
|
+
* Not cancelable, as the platform's are not: the media has already moved by the
|
|
37
|
+
* time the event is sent, and a refusal would have nothing to stop.
|
|
38
|
+
*/
|
|
39
|
+
export declare const relayedCopy: (event: Event) => Event;
|
|
40
|
+
/**
|
|
41
|
+
* Sends each media event the video fires on from the host, and returns what
|
|
42
|
+
* stops it.
|
|
43
|
+
*
|
|
44
|
+
* Bound once, after the first render, so the player's own listeners in its
|
|
45
|
+
* template are ahead of it on the same video: what a consumer reads off the
|
|
46
|
+
* player in a handler (`paused`, `volume`, `currentTime`) is already the
|
|
47
|
+
* player's state by the time the copy reaches them.
|
|
48
|
+
*/
|
|
49
|
+
export declare const relayMedia: (video: EventTarget, host: EventTarget) => (() => void);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const MEDIA_EVENTS = [
|
|
2
|
+
'abort',
|
|
3
|
+
'canplay',
|
|
4
|
+
'canplaythrough',
|
|
5
|
+
'durationchange',
|
|
6
|
+
'emptied',
|
|
7
|
+
'ended',
|
|
8
|
+
'error',
|
|
9
|
+
'loadeddata',
|
|
10
|
+
'loadedmetadata',
|
|
11
|
+
'loadstart',
|
|
12
|
+
'pause',
|
|
13
|
+
'play',
|
|
14
|
+
'playing',
|
|
15
|
+
'progress',
|
|
16
|
+
'ratechange',
|
|
17
|
+
'resize',
|
|
18
|
+
'seeked',
|
|
19
|
+
'seeking',
|
|
20
|
+
'stalled',
|
|
21
|
+
'suspend',
|
|
22
|
+
'timeupdate',
|
|
23
|
+
'volumechange',
|
|
24
|
+
'waiting',
|
|
25
|
+
];
|
|
26
|
+
export const relayedCopy = (event) => new Event(event.type, { bubbles: false, cancelable: false, composed: false });
|
|
27
|
+
export const relayMedia = (video, host) => {
|
|
28
|
+
const relay = (event) => {
|
|
29
|
+
host.dispatchEvent(relayedCopy(event));
|
|
30
|
+
};
|
|
31
|
+
for (const name of MEDIA_EVENTS) {
|
|
32
|
+
video.addEventListener(name, relay);
|
|
33
|
+
}
|
|
34
|
+
return () => {
|
|
35
|
+
for (const name of MEDIA_EVENTS) {
|
|
36
|
+
video.removeEventListener(name, relay);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|