@fusion.dev/helix-headless 0.146.0 → 0.148.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 +9287 -1084
- package/dist/accordion/item/accordion-item.d.ts +43 -21
- package/dist/accordion/item/accordion-item.js +37 -11
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +6 -8
- package/dist/announcement/root/announcement-root.d.ts +66 -6
- package/dist/announcement/root/announcement-root.js +144 -13
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +14 -7
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +77 -8
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +28 -4
- package/dist/chat/root/chat-root.js +12 -7
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
- package/dist/checkbox-group/select-all.d.ts +9 -4
- package/dist/checkbox-group/select-all.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +41 -18
- package/dist/code-block/root/code-block-root.js +21 -6
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +99 -55
- package/dist/color-picker/wheel.d.ts +28 -0
- package/dist/color-picker/wheel.js +15 -0
- package/dist/combobox/root/combobox-root.d.ts +83 -11
- package/dist/combobox/root/combobox-root.js +81 -18
- package/dist/command/root/command-root.d.ts +7 -4
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +29 -50
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +22 -4
- package/dist/description-list/item/description-list-item.js +14 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +38 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/empty/root/empty-root.d.ts +46 -2
- package/dist/empty/root/empty-root.js +50 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +55 -21
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +11 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +10 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +5 -5
- package/dist/format-date/options.js +10 -39
- package/dist/format-date/root/format-date-root.d.ts +53 -4
- package/dist/format-date/root/format-date-root.js +38 -50
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +76 -3
- package/dist/heatmap/root/heatmap-root.js +105 -20
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +20 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +23 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +25 -26
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +31 -24
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +125 -26
- package/dist/listbox/root/listbox-root.js +156 -166
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +29 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +5 -2
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +48 -3
- package/dist/notifications/root/notifications-root.js +36 -6
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
- package/dist/object-inspector/root/object-inspector-root.js +31 -20
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +51 -1
- package/dist/pin-input/code.js +37 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +151 -156
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +31 -9
- package/dist/qr-code/root/qr-code-root.js +29 -17
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +115 -11
- package/dist/select/root/select-root.js +104 -20
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
- package/dist/speed-dial/item/speed-dial-item.js +43 -5
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
- package/dist/speed-dial/root/speed-dial-root.js +123 -6
- package/dist/splitter/root/splitter-root.d.ts +9 -2
- package/dist/splitter/root/splitter-root.js +18 -3
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +93 -29
- package/dist/table/row/table-row.d.ts +36 -0
- package/dist/table/row/table-row.js +52 -2
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +23 -20
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +12 -14
- package/dist/time-picker/root/time-picker-root.js +18 -23
- package/dist/toast/item/toast-item.d.ts +9 -6
- package/dist/toast/item/toast-item.js +1 -1
- package/dist/toast/root/toast-root.d.ts +40 -4
- package/dist/toast/root/toast-root.js +68 -16
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -43
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +52 -5
- package/dist/toolbar/root/toolbar-root.js +88 -13
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -2
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +16 -1
- package/dist/video/root/video-root.js +15 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +53 -41
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4934 -954
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +946 -253
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -4,27 +4,48 @@ 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, markRegion } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, markRegion, toolbarAround, toolbarAxis, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.announced = false;
|
|
14
|
+
this.decorative = false;
|
|
15
|
+
}
|
|
16
|
+
get drawn() {
|
|
17
|
+
const toolbar = this.orientation || this.hydrating ? null : toolbarAround(this);
|
|
18
|
+
if (toolbar) {
|
|
19
|
+
return toolbarAxis(toolbar) === 'vertical' ? 'horizontal' : 'vertical';
|
|
20
|
+
}
|
|
21
|
+
return this.orientation ?? 'horizontal';
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
super.connectedCallback();
|
|
25
|
+
this.requestUpdate();
|
|
14
26
|
}
|
|
15
27
|
markEmpty() {
|
|
16
28
|
markRegion(this.renderRoot, 'content', ['']);
|
|
17
29
|
}
|
|
30
|
+
willUpdate(changed) {
|
|
31
|
+
super.willUpdate(changed);
|
|
32
|
+
this.toggleState('vertical', this.drawn === 'vertical');
|
|
33
|
+
}
|
|
34
|
+
firstUpdated(changed) {
|
|
35
|
+
super.firstUpdated(changed);
|
|
36
|
+
this.finishHydration();
|
|
37
|
+
}
|
|
18
38
|
updated(changed) {
|
|
19
39
|
super.updated(changed);
|
|
20
40
|
this.markEmpty();
|
|
21
41
|
}
|
|
22
42
|
render() {
|
|
43
|
+
const separator = this.announced || !this.decorative;
|
|
23
44
|
return html `<div
|
|
24
45
|
part="line"
|
|
25
|
-
role=${
|
|
26
|
-
aria-labelledby=${
|
|
27
|
-
aria-orientation=${
|
|
46
|
+
role=${separator ? 'separator' : 'presentation'}
|
|
47
|
+
aria-labelledby=${separator ? 'content' : nothing}
|
|
48
|
+
aria-orientation=${separator ? this.drawn : nothing}
|
|
28
49
|
></div>
|
|
29
50
|
<span id="content" part="content"><slot @slotchange=${() => this.markEmpty()}></slot></span>
|
|
30
51
|
<div part="line" role="presentation"></div>`;
|
|
@@ -33,6 +54,9 @@ let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
|
|
|
33
54
|
__decorate([
|
|
34
55
|
property({ reflect: true, type: Boolean })
|
|
35
56
|
], HelixHeadlessDivider.prototype, "announced", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
property({ reflect: true, type: Boolean })
|
|
59
|
+
], HelixHeadlessDivider.prototype, "decorative", void 0);
|
|
36
60
|
__decorate([
|
|
37
61
|
property({ reflect: true })
|
|
38
62
|
], HelixHeadlessDivider.prototype, "orientation", void 0);
|
|
@@ -8,6 +8,7 @@ import { CHART_PLOT, customElement, drawTooltip, HelixElement, MixinChartSource,
|
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
11
|
+
import { sliceLabelAt } from '../slice-label.js';
|
|
11
12
|
const PERCENTS = new Map();
|
|
12
13
|
const percentIn = (locale) => {
|
|
13
14
|
let found = PERCENTS.get(locale);
|
|
@@ -124,16 +125,22 @@ let HelixHeadlessDonutChart = class HelixHeadlessDonutChart extends MixinChartSo
|
|
|
124
125
|
}
|
|
125
126
|
renderSliceLabels(shares) {
|
|
126
127
|
const half = this.sweep === 'half';
|
|
127
|
-
const
|
|
128
|
-
|
|
128
|
+
const ring = {
|
|
129
|
+
center: CENTER,
|
|
130
|
+
origin: this.origin,
|
|
131
|
+
radius: this.radius,
|
|
132
|
+
span: this.span,
|
|
133
|
+
tall: half ? EDGE + this.thickness / 2 : PLOT_HEIGHT,
|
|
134
|
+
top: half ? CENTER - EDGE : 0,
|
|
135
|
+
width: PLOT_WIDTH,
|
|
136
|
+
};
|
|
129
137
|
const format = percentIn(this.locale);
|
|
130
138
|
return html `${shares.map((share, index) => {
|
|
131
|
-
|
|
139
|
+
const place = sliceLabelAt(share, ring);
|
|
140
|
+
if (!place) {
|
|
132
141
|
return nothing;
|
|
133
142
|
}
|
|
134
|
-
const
|
|
135
|
-
const x = ((CENTER + Math.cos(angle) * this.radius) / PLOT_WIDTH) * 100;
|
|
136
|
-
const y = ((CENTER + Math.sin(angle) * this.radius - top) / tall) * 100;
|
|
143
|
+
const { x, y } = place;
|
|
137
144
|
return html `<span
|
|
138
145
|
aria-hidden="true"
|
|
139
146
|
data-series=${seriesIndex(index)}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** A slice's place on the ring, as shares of the whole from 0 to 1. */
|
|
2
|
+
export interface SliceShare {
|
|
3
|
+
/** How much of the ring the slice takes. */
|
|
4
|
+
fraction: number;
|
|
5
|
+
/** Where the slice starts, as the share of the ring before it. */
|
|
6
|
+
start: number;
|
|
7
|
+
}
|
|
8
|
+
/** The ring a slice label is placed on, in the drawing's own units. */
|
|
9
|
+
export interface RingGeometry {
|
|
10
|
+
/** The center, on both axes. */
|
|
11
|
+
center: number;
|
|
12
|
+
/** Where the ring's turn starts, in radians: a quarter turn back is twelve o'clock. */
|
|
13
|
+
origin: number;
|
|
14
|
+
/** The radius of the band's middle, where a label sits. */
|
|
15
|
+
radius: number;
|
|
16
|
+
/** How much of a turn the ring takes: 1 for a ring, a half for an arc. */
|
|
17
|
+
span: number;
|
|
18
|
+
/** How tall the box the labels are placed in is. */
|
|
19
|
+
tall: number;
|
|
20
|
+
/** Where the top of that box is. */
|
|
21
|
+
top: number;
|
|
22
|
+
/** How wide the drawing is. */
|
|
23
|
+
width: number;
|
|
24
|
+
}
|
|
25
|
+
/** The smallest share that takes a label: a twentieth of the ring. */
|
|
26
|
+
export declare const SMALLEST_LABELED = 0.05;
|
|
27
|
+
/**
|
|
28
|
+
* Where a slice's label goes, as percentages of the box from the left and the
|
|
29
|
+
* top: the middle of its band at its mid-angle. Nothing for a slice under a
|
|
30
|
+
* twentieth, whose label would not fit on it.
|
|
31
|
+
*/
|
|
32
|
+
export declare const sliceLabelAt: (share: SliceShare, ring: RingGeometry) => {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
} | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const SMALLEST_LABELED = 0.05;
|
|
2
|
+
export const sliceLabelAt = (share, ring) => {
|
|
3
|
+
if (share.fraction < SMALLEST_LABELED) {
|
|
4
|
+
return undefined;
|
|
5
|
+
}
|
|
6
|
+
const angle = (share.start + share.fraction / 2) * 2 * Math.PI * ring.span + ring.origin;
|
|
7
|
+
return {
|
|
8
|
+
x: ((ring.center + Math.cos(angle) * ring.radius) / ring.width) * 100,
|
|
9
|
+
y: ((ring.center + Math.sin(angle) * ring.radius - ring.top) / ring.tall) * 100,
|
|
10
|
+
};
|
|
11
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, CommandController, HelixElement, OpenPhaseController, SwipeController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, CommandController, FocusScopeController, HelixElement, OpenPhaseController, SwipeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -11,7 +11,8 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
|
|
|
11
11
|
*
|
|
12
12
|
* The drawer is modal by default, which means four things:
|
|
13
13
|
*
|
|
14
|
-
* - focus is trapped inside
|
|
14
|
+
* - focus is trapped inside: `Tab` from the last control goes to the first,
|
|
15
|
+
* and `Shift+Tab` from the first to the last, as in `Dialog`
|
|
15
16
|
* - Escape and a press outside close it
|
|
16
17
|
* - the page behind is covered
|
|
17
18
|
* - the page behind does not scroll
|
|
@@ -233,6 +234,7 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
|
|
|
233
234
|
* key is read here, and comes through the same request.
|
|
234
235
|
*/
|
|
235
236
|
private readonly handleKeydown;
|
|
237
|
+
protected readonly scope: FocusScopeController;
|
|
236
238
|
/** The panel, which is a real `<dialog>`. */
|
|
237
239
|
private get panel();
|
|
238
240
|
/**
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, CommandController, customElement, drawDismiss, drawDismissGlyph, edgeOffset, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, CommandController, customElement, drawDismiss, drawDismissGlyph, edgeOffset, FocusScopeController, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, nearest, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { beyondWindow } from '../reveal.js';
|
|
@@ -64,6 +64,16 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
|
|
|
64
64
|
event.preventDefault();
|
|
65
65
|
this.requestOpen(false);
|
|
66
66
|
};
|
|
67
|
+
this.scope = new FocusScopeController(this, {
|
|
68
|
+
contain: () => this.open && this.modal,
|
|
69
|
+
contents: () => [
|
|
70
|
+
...['header', '', 'footer'].flatMap((name) => this.renderRoot
|
|
71
|
+
?.querySelector(name ? `slot[name="${name}"]` : 'slot:not([name])')
|
|
72
|
+
?.assignedElements({ flatten: true }) ?? []),
|
|
73
|
+
...[...(this.panel?.children ?? [])].filter((one) => one.localName === 'button'),
|
|
74
|
+
],
|
|
75
|
+
surface: () => this.panel,
|
|
76
|
+
});
|
|
67
77
|
this.handleCancel = (event) => {
|
|
68
78
|
event.preventDefault();
|
|
69
79
|
this.requestOpen(false);
|
|
@@ -153,8 +163,10 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
|
|
|
153
163
|
return;
|
|
154
164
|
}
|
|
155
165
|
const points = parseSnapPoints(this.snapPoints);
|
|
156
|
-
const
|
|
157
|
-
|
|
166
|
+
const at = nearest(points, point);
|
|
167
|
+
if (at !== undefined) {
|
|
168
|
+
this.restAt(at);
|
|
169
|
+
}
|
|
158
170
|
}
|
|
159
171
|
show() {
|
|
160
172
|
this.requestOpen(true);
|
|
@@ -13,6 +13,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
13
13
|
* - On the page that is showing, it renders its row.
|
|
14
14
|
* - When its own page is showing, it renders only that page's rows. Its row
|
|
15
15
|
* belongs to the page above.
|
|
16
|
+
* - When a page further down its own is showing, it renders its page's slot
|
|
17
|
+
* alone, so the rows below reach the page.
|
|
16
18
|
* - Otherwise it renders nothing. The rows stay in the light DOM untouched, so
|
|
17
19
|
* there is no state to keep.
|
|
18
20
|
*
|
|
@@ -23,6 +25,10 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
23
25
|
* `aria-haspopup`, the same way `Menu` marks a row with a submenu. The server
|
|
24
26
|
* render leaves both out, because the server cannot see the children.
|
|
25
27
|
*
|
|
28
|
+
* The row is named by its label alone. Words in `description`, a line under
|
|
29
|
+
* the label, and in `end` describe it instead, through `aria-describedby`, as
|
|
30
|
+
* `Menu.Item` does: a reader hears "Theme", then "Dark".
|
|
31
|
+
*
|
|
26
32
|
* @since 0.1.0
|
|
27
33
|
* @status stable
|
|
28
34
|
* @aliases Panel item, Drill row
|
|
@@ -30,7 +36,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
30
36
|
*
|
|
31
37
|
* @slot - The row's label.
|
|
32
38
|
* @slot chevron - Replaces the caret of a row that opens a page, such as with your own icon.
|
|
33
|
-
* @slot
|
|
39
|
+
* @slot description - A line under the label that describes the row. It describes the row to a screen reader and is not part of its name.
|
|
40
|
+
* @slot end - Content after the label, such as the setting a page holds or a count. It describes the row and is not part of its name.
|
|
34
41
|
* @slot page - The rows of the page this row opens.
|
|
35
42
|
* @slot start - Content before the label, usually an icon.
|
|
36
43
|
*
|
|
@@ -71,6 +78,11 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
|
|
|
71
78
|
* event handler is why it is kept off the typings.
|
|
72
79
|
*/
|
|
73
80
|
onPage: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* @internal Whether the page showing is below this row's own, deeper than one
|
|
83
|
+
* level. Written by the stack.
|
|
84
|
+
*/
|
|
85
|
+
onPath: boolean;
|
|
74
86
|
/**
|
|
75
87
|
* @internal Whether this row's own page is the one showing. Written by the
|
|
76
88
|
* stack.
|
|
@@ -89,6 +101,10 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
|
|
|
89
101
|
* render would open with no caret on the row that leads to it.
|
|
90
102
|
*/
|
|
91
103
|
private page;
|
|
104
|
+
/** Whether anything is slotted under the label, read the way `page` is. */
|
|
105
|
+
private description;
|
|
106
|
+
/** Whether anything is slotted after the label, read the way `page` is. */
|
|
107
|
+
private end;
|
|
92
108
|
/**
|
|
93
109
|
* Reads the children before each render, where they can be known.
|
|
94
110
|
*
|
|
@@ -109,6 +125,10 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
|
|
|
109
125
|
* the same note.
|
|
110
126
|
*/
|
|
111
127
|
private readonly readPage;
|
|
128
|
+
/** Re-reads whether the line under the label or the words after it are filled. */
|
|
129
|
+
private readonly readWords;
|
|
130
|
+
/** What describes the row: the line under its label and the words after it. */
|
|
131
|
+
private get describedBy();
|
|
112
132
|
/** Moves focus onto the row itself. */
|
|
113
133
|
focusItem(): void;
|
|
114
134
|
/**
|
|
@@ -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, deepActiveElement, HelixElement, HelixSelectEvent, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, slotNamed, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -16,24 +16,40 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
16
16
|
this.focusable = false;
|
|
17
17
|
this.isDrilldownItem = true;
|
|
18
18
|
this.onPage = true;
|
|
19
|
+
this.onPath = false;
|
|
19
20
|
this.showingPage = false;
|
|
20
21
|
this.value = '';
|
|
21
22
|
this.page = false;
|
|
23
|
+
this.description = false;
|
|
24
|
+
this.end = false;
|
|
22
25
|
this.readPage = () => {
|
|
23
26
|
const slot = this.renderRoot.querySelector('slot[name="page"]');
|
|
24
27
|
this.page = (slot?.assignedElements().length ?? 0) > 0;
|
|
25
28
|
};
|
|
29
|
+
this.readWords = () => {
|
|
30
|
+
this.description = slotFilled(slotNamed(this.renderRoot, 'description'));
|
|
31
|
+
this.end = slotFilled(slotNamed(this.renderRoot, 'end'));
|
|
32
|
+
};
|
|
26
33
|
}
|
|
27
34
|
willUpdate(changed) {
|
|
28
35
|
super.willUpdate(changed);
|
|
29
36
|
if (this.childrenKnown) {
|
|
30
|
-
|
|
37
|
+
const named = (name) => this.knownChildren.some((child) => child.slot === name);
|
|
38
|
+
this.page = named('page');
|
|
39
|
+
this.description = named('description');
|
|
40
|
+
this.end = named('end');
|
|
31
41
|
}
|
|
32
42
|
}
|
|
33
43
|
firstUpdated(changed) {
|
|
34
44
|
super.firstUpdated(changed);
|
|
35
45
|
this.finishHydration();
|
|
36
46
|
}
|
|
47
|
+
get describedBy() {
|
|
48
|
+
const ids = [this.description ? 'description' : '', this.end ? 'end' : '']
|
|
49
|
+
.filter((id) => id !== '')
|
|
50
|
+
.join(' ');
|
|
51
|
+
return ids === '' ? nothing : ids;
|
|
52
|
+
}
|
|
37
53
|
focusItem() {
|
|
38
54
|
this.partNamed('item')?.focus();
|
|
39
55
|
}
|
|
@@ -58,7 +74,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
58
74
|
>`;
|
|
59
75
|
}
|
|
60
76
|
render() {
|
|
61
|
-
if (this.showingPage) {
|
|
77
|
+
if (this.showingPage || this.onPath) {
|
|
62
78
|
return html `<slot name="page" @slotchange=${this.readPage}></slot>`;
|
|
63
79
|
}
|
|
64
80
|
if (!this.onPage) {
|
|
@@ -68,14 +84,23 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
68
84
|
part="item"
|
|
69
85
|
type="button"
|
|
70
86
|
role="menuitem"
|
|
87
|
+
aria-describedby=${this.describedBy}
|
|
71
88
|
aria-disabled=${this.disabled ? 'true' : nothing}
|
|
72
89
|
aria-haspopup=${this.page ? 'menu' : nothing}
|
|
73
90
|
tabindex=${this.focusable ? '0' : '-1'}
|
|
91
|
+
?data-described=${this.description}
|
|
74
92
|
@click=${() => this.select()}
|
|
75
93
|
>
|
|
76
94
|
<slot name="start"></slot>
|
|
77
95
|
<span part="label"><slot></slot></span>
|
|
78
|
-
<slot
|
|
96
|
+
<slot
|
|
97
|
+
id="description"
|
|
98
|
+
name="description"
|
|
99
|
+
aria-hidden="true"
|
|
100
|
+
?data-empty=${!this.description}
|
|
101
|
+
@slotchange=${this.readWords}
|
|
102
|
+
></slot>
|
|
103
|
+
<slot id="end" name="end" aria-hidden="true" @slotchange=${this.readWords}></slot>
|
|
79
104
|
${this.page ? this.renderMark() : nothing}
|
|
80
105
|
</button>
|
|
81
106
|
<div hidden><slot name="page" @slotchange=${this.readPage}></slot></div>`;
|
|
@@ -90,6 +115,9 @@ __decorate([
|
|
|
90
115
|
__decorate([
|
|
91
116
|
property({ attribute: false })
|
|
92
117
|
], HelixHeadlessDrilldownItem.prototype, "onPage", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
property({ attribute: false })
|
|
120
|
+
], HelixHeadlessDrilldownItem.prototype, "onPath", void 0);
|
|
93
121
|
__decorate([
|
|
94
122
|
property({ attribute: false })
|
|
95
123
|
], HelixHeadlessDrilldownItem.prototype, "showingPage", void 0);
|
|
@@ -99,6 +127,12 @@ __decorate([
|
|
|
99
127
|
__decorate([
|
|
100
128
|
state()
|
|
101
129
|
], HelixHeadlessDrilldownItem.prototype, "page", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
state()
|
|
132
|
+
], HelixHeadlessDrilldownItem.prototype, "description", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
state()
|
|
135
|
+
], HelixHeadlessDrilldownItem.prototype, "end", void 0);
|
|
102
136
|
HelixHeadlessDrilldownItem = __decorate([
|
|
103
137
|
customElement('helix-headless-drilldown-item')
|
|
104
138
|
], HelixHeadlessDrilldownItem);
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords,
|
|
7
|
+
import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadByWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -38,7 +38,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
38
38
|
})),
|
|
39
39
|
reserved: () => ['ArrowLeft', 'ArrowRight'],
|
|
40
40
|
selects: () => false,
|
|
41
|
-
typeahead:
|
|
41
|
+
typeahead: typeaheadByWords(),
|
|
42
42
|
});
|
|
43
43
|
this.handleFocusIn = (event) => {
|
|
44
44
|
const item = this.drilldown.rows.find((row) => row.contains(event.target));
|
|
@@ -162,6 +162,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
162
162
|
mark(item, page, onPage) {
|
|
163
163
|
item.onPage = onPage;
|
|
164
164
|
item.showingPage = item === page;
|
|
165
|
+
item.onPath = page !== null && item !== page && item.contains(page);
|
|
165
166
|
for (const child of item.children) {
|
|
166
167
|
if (child instanceof HelixHeadlessDrilldownItem && child.slot === 'page') {
|
|
167
168
|
this.mark(child, page, item === page);
|
|
@@ -5,6 +5,7 @@ registerElementEvents({
|
|
|
5
5
|
'helix-headless-app-header': ['helix-scrolled'],
|
|
6
6
|
'helix-headless-avatar': ['error', 'load'],
|
|
7
7
|
'helix-headless-button': ['helix-press'],
|
|
8
|
+
'helix-headless-button-group': ['change', 'helix-before-change'],
|
|
8
9
|
'helix-headless-callout': ['helix-dismiss'],
|
|
9
10
|
'helix-headless-canvas': [
|
|
10
11
|
'helix-before-move',
|
|
@@ -115,7 +116,7 @@ registerElementEvents({
|
|
|
115
116
|
'helix-graph-signal',
|
|
116
117
|
'helix-graph-zoom',
|
|
117
118
|
],
|
|
118
|
-
'helix-headless-heatmap': ['helix-resize'],
|
|
119
|
+
'helix-headless-heatmap': ['change', 'helix-before-change', 'helix-resize'],
|
|
119
120
|
'helix-headless-icon': ['error', 'load'],
|
|
120
121
|
'helix-headless-icon-button': ['helix-press'],
|
|
121
122
|
'helix-headless-image': ['error', 'load'],
|
|
@@ -166,6 +167,7 @@ registerElementEvents({
|
|
|
166
167
|
'helix-headless-megamenu': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
167
168
|
'helix-headless-menu': ['helix-before-close', 'helix-before-open', 'helix-select', 'toggle'],
|
|
168
169
|
'helix-headless-menu-item': ['helix-before-toggle', 'helix-select'],
|
|
170
|
+
'helix-headless-meter': ['helix-band'],
|
|
169
171
|
'helix-headless-notification': ['helix-dismiss', 'helix-read'],
|
|
170
172
|
'helix-headless-notification-group': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
171
173
|
'helix-headless-notifications': ['helix-dismiss', 'helix-load-more', 'helix-read'],
|
|
@@ -186,6 +188,7 @@ registerElementEvents({
|
|
|
186
188
|
'helix-headless-pagination-size': ['change', 'helix-before-change', 'input'],
|
|
187
189
|
'helix-headless-pin-input': ['change', 'helix-before-change', 'helix-complete', 'input'],
|
|
188
190
|
'helix-headless-popover': ['helix-before-close', 'helix-before-open', 'toggle'],
|
|
191
|
+
'helix-headless-progress': ['helix-complete'],
|
|
189
192
|
'helix-headless-qr-code': ['error'],
|
|
190
193
|
'helix-headless-radio': ['helix-select'],
|
|
191
194
|
'helix-headless-radio-group': ['change', 'helix-before-change', 'helix-select', 'input'],
|
|
@@ -220,6 +223,7 @@ registerElementEvents({
|
|
|
220
223
|
'helix-before-resize',
|
|
221
224
|
'helix-collapse',
|
|
222
225
|
'helix-resized',
|
|
226
|
+
'input',
|
|
223
227
|
],
|
|
224
228
|
'helix-headless-step': ['helix-select'],
|
|
225
229
|
'helix-headless-steps': ['helix-activate', 'helix-before-activate', 'helix-select'],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArrivalController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary A message that a region has nothing in it, and the next step to take.
|
|
5
5
|
*
|
|
@@ -19,6 +19,18 @@ import { type TemplateResult } from 'lit';
|
|
|
19
19
|
* `empty-state-actions` element: assign your own heading and actions to the
|
|
20
20
|
* slots.
|
|
21
21
|
*
|
|
22
|
+
* **Or give the heading as words.** `heading` draws them in a `heading` part
|
|
23
|
+
* that is a heading at `heading-level`, 3 where it is not set, so a page
|
|
24
|
+
* rendering from data or on a server gets a heading a reader finds in the
|
|
25
|
+
* outline without writing the element. A heading slotted in replaces it.
|
|
26
|
+
*
|
|
27
|
+
* **Whatever is slotted into `heading` is read as a heading.** An element that
|
|
28
|
+
* is no heading, such as a `<span>` or a `<p>`, is set inside the `heading`
|
|
29
|
+
* part at `heading-level`, so a screen reader still finds it in the outline.
|
|
30
|
+
* A heading element, or an element holding one, keeps its own level. A server
|
|
31
|
+
* cannot see the slotted element, so a served `<span>` becomes a heading once
|
|
32
|
+
* the script runs.
|
|
33
|
+
*
|
|
22
34
|
* @since 0.1.0
|
|
23
35
|
* @status stable
|
|
24
36
|
* @category feedback
|
|
@@ -27,12 +39,27 @@ import { type TemplateResult } from 'lit';
|
|
|
27
39
|
*
|
|
28
40
|
* @slot - The message: why the region is empty, and what to do about it.
|
|
29
41
|
* @slot actions - The action that would put something in the region.
|
|
30
|
-
* @slot heading - The heading, which names what is missing.
|
|
42
|
+
* @slot heading - The heading, which names what is missing. A heading element, such as an `<h3>`, keeps its level; any other element is read as a heading at `heading-level`. Replaces the one `heading` draws.
|
|
31
43
|
* @slot icon - An icon above the heading.
|
|
32
44
|
*
|
|
45
|
+
* @csspart heading - The heading at `heading-level`: the one `heading` draws while nothing is slotted into `heading`, or the one around a slotted element that is no heading.
|
|
33
46
|
* @csspart live - A copy of the heading and the message, in a live region that screen readers announce when the view appears. Visually hidden in the styled tier.
|
|
34
47
|
*/
|
|
35
48
|
export declare class HelixHeadlessEmpty extends HelixElement {
|
|
49
|
+
/**
|
|
50
|
+
* The heading as words, such as "No results", drawn as a heading when
|
|
51
|
+
* nothing is slotted into `heading`.
|
|
52
|
+
*
|
|
53
|
+
* Absent draws none, and the `heading` slot is the only heading.
|
|
54
|
+
*/
|
|
55
|
+
heading: string;
|
|
56
|
+
/**
|
|
57
|
+
* The level of the heading `heading` draws, from 1 to 6.
|
|
58
|
+
*
|
|
59
|
+
* Absent is 3, the level of a heading inside a page's section. Set it to fit
|
|
60
|
+
* the outline the empty view sits in. A slotted heading keeps its own.
|
|
61
|
+
*/
|
|
62
|
+
headingLevel?: number;
|
|
36
63
|
/**
|
|
37
64
|
* Whether the state is announced when it appears.
|
|
38
65
|
*
|
|
@@ -41,7 +68,24 @@ export declare class HelixHeadlessEmpty extends HelixElement {
|
|
|
41
68
|
* has nothing to announce because nothing changed.
|
|
42
69
|
*/
|
|
43
70
|
noAnnounce: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the `heading` slot holds elements and none of them is or holds a
|
|
73
|
+
* heading, read from the children before each render.
|
|
74
|
+
*/
|
|
75
|
+
private looseHeading;
|
|
76
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
77
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
44
78
|
protected readonly arrival: ArrivalController;
|
|
79
|
+
/**
|
|
80
|
+
* The `heading` slot, with the heading `heading` draws as its fallback, so
|
|
81
|
+
* one slotted in replaces it; no fallback while `heading` holds no words.
|
|
82
|
+
*
|
|
83
|
+
* A method, so a tier above can draw its own, as the slot lets a page.
|
|
84
|
+
*
|
|
85
|
+
* @param hidden Whether the live copy holds the heading's words, which
|
|
86
|
+
* hides them from readers until it empties.
|
|
87
|
+
*/
|
|
88
|
+
protected renderHeading(hidden: boolean): TemplateResult;
|
|
45
89
|
protected render(): TemplateResult;
|
|
46
90
|
}
|
|
47
91
|
declare global {
|
|
@@ -4,30 +4,75 @@ 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 { ArrivalController, customElement, HelixElement, slottedWords, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ArrivalController, customElement, HelixElement, headingIn, headingLevel, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
|
+
this.heading = '';
|
|
13
14
|
this.noAnnounce = false;
|
|
15
|
+
this.looseHeading = false;
|
|
14
16
|
this.arrival = new ArrivalController(this, {
|
|
15
17
|
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
16
|
-
text: () => slottedWords(this, ['heading', ''])
|
|
18
|
+
text: () => [slottedWords(this, ['heading']) || this.heading.trim(), slottedWords(this, [''])]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' '),
|
|
17
21
|
});
|
|
18
22
|
}
|
|
23
|
+
willUpdate(changed) {
|
|
24
|
+
super.willUpdate(changed);
|
|
25
|
+
if (this.childrenKnown) {
|
|
26
|
+
const slotted = this.knownChildren.filter((child) => child.slot === 'heading');
|
|
27
|
+
this.looseHeading = slotted.length > 0 && headingIn(slotted) === null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
firstUpdated(changed) {
|
|
31
|
+
super.firstUpdated(changed);
|
|
32
|
+
this.finishHydration();
|
|
33
|
+
}
|
|
34
|
+
renderHeading(hidden) {
|
|
35
|
+
const level = headingLevel(this.headingLevel);
|
|
36
|
+
const slot = html `<slot
|
|
37
|
+
aria-hidden=${hidden && !this.looseHeading ? 'true' : nothing}
|
|
38
|
+
name="heading"
|
|
39
|
+
@slotchange=${() => {
|
|
40
|
+
this.arrival.say();
|
|
41
|
+
this.requestUpdate();
|
|
42
|
+
}}
|
|
43
|
+
>${this.heading.trim()
|
|
44
|
+
? html `<div aria-level=${level} part="heading" role="heading">
|
|
45
|
+
${this.heading}
|
|
46
|
+
</div>`
|
|
47
|
+
: nothing}</slot
|
|
48
|
+
>`;
|
|
49
|
+
return this.looseHeading
|
|
50
|
+
? html `<div
|
|
51
|
+
aria-hidden=${hidden ? 'true' : nothing}
|
|
52
|
+
aria-level=${level}
|
|
53
|
+
part="heading"
|
|
54
|
+
role="heading"
|
|
55
|
+
>${slot}</div>`
|
|
56
|
+
: slot;
|
|
57
|
+
}
|
|
19
58
|
render() {
|
|
20
59
|
const say = () => this.arrival.say();
|
|
21
|
-
const
|
|
60
|
+
const held = this.arrival.said !== '' && !this.noAnnounce;
|
|
22
61
|
return html `<slot name="icon"></slot>
|
|
23
|
-
|
|
24
|
-
<slot aria-hidden=${
|
|
62
|
+
${this.renderHeading(held)}
|
|
63
|
+
<slot aria-hidden=${held ? 'true' : nothing} @slotchange=${say}></slot>
|
|
25
64
|
<slot name="actions"></slot>
|
|
26
65
|
${this.noAnnounce
|
|
27
66
|
? nothing
|
|
28
67
|
: html `<span part="live" role="status">${this.arrival.said}</span>`}`;
|
|
29
68
|
}
|
|
30
69
|
};
|
|
70
|
+
__decorate([
|
|
71
|
+
property()
|
|
72
|
+
], HelixHeadlessEmpty.prototype, "heading", void 0);
|
|
73
|
+
__decorate([
|
|
74
|
+
property({ attribute: 'heading-level', type: Number })
|
|
75
|
+
], HelixHeadlessEmpty.prototype, "headingLevel", void 0);
|
|
31
76
|
__decorate([
|
|
32
77
|
property({ attribute: 'no-announce', reflect: true, type: Boolean })
|
|
33
78
|
], HelixHeadlessEmpty.prototype, "noAnnounce", void 0);
|