@fusion.dev/helix-headless 0.146.0 → 0.147.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 +5266 -785
- package/dist/accordion/item/accordion-item.d.ts +38 -19
- package/dist/accordion/item/accordion-item.js +31 -9
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +13 -4
- package/dist/announcement/root/announcement-root.js +34 -6
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +11 -3
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +88 -5
- 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/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/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/chat/root/chat-root.d.ts +15 -1
- package/dist/chat/root/chat-root.js +11 -2
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.js +4 -3
- package/dist/checkbox-group/select-all.d.ts +0 -6
- package/dist/checkbox-group/select-all.js +0 -5
- package/dist/code-block/root/code-block-root.d.ts +35 -14
- package/dist/code-block/root/code-block-root.js +17 -3
- 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 +101 -51
- package/dist/color-picker/wheel.d.ts +17 -0
- package/dist/color-picker/wheel.js +6 -0
- package/dist/combobox/root/combobox-root.d.ts +13 -0
- package/dist/combobox/root/combobox-root.js +14 -1
- package/dist/command/root/command-root.d.ts +3 -1
- 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 +13 -7
- 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 +18 -4
- package/dist/description-list/item/description-list-item.js +8 -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 +39 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +4 -1
- package/dist/empty/root/empty-root.d.ts +31 -1
- package/dist/empty/root/empty-root.js +26 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +54 -19
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +10 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +11 -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/options.d.ts +3 -4
- package/dist/format-date/options.js +2 -2
- package/dist/format-date/root/format-date-root.d.ts +18 -1
- package/dist/format-date/root/format-date-root.js +19 -23
- 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 +64 -3
- package/dist/heatmap/root/heatmap-root.js +89 -19
- 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 +9 -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/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +24 -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 +22 -10
- 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 +26 -5
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +9 -5
- package/dist/listbox/root/listbox-root.js +29 -37
- 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 +36 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +3 -0
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/notifications/root/notifications-root.d.ts +10 -1
- package/dist/notifications/root/notifications-root.js +11 -1
- 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 +13 -6
- package/dist/object-inspector/root/object-inspector-root.js +18 -17
- 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 +5 -0
- package/dist/pagination/size/pagination-size.js +4 -2
- package/dist/pin-input/code.d.ts +28 -1
- package/dist/pin-input/code.js +12 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +157 -148
- 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 +17 -6
- package/dist/qr-code/root/qr-code-root.js +10 -12
- 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/root/scatter-chart-root.d.ts +30 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +34 -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 +59 -3
- package/dist/select/root/select-root.js +72 -12
- 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/item/speed-dial-item.d.ts +1 -1
- package/dist/speed-dial/item/speed-dial-item.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
- package/dist/speed-dial/root/speed-dial-root.js +9 -1
- package/dist/splitter/root/splitter-root.d.ts +3 -0
- package/dist/splitter/root/splitter-root.js +2 -0
- 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/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/root/table-root.js +13 -6
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- 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 +19 -7
- 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 +11 -14
- package/dist/time-picker/root/time-picker-root.js +15 -23
- package/dist/toast/item/toast-item.d.ts +3 -3
- package/dist/toast/item/toast-item.js +0 -1
- package/dist/toast/root/toast-root.d.ts +28 -4
- package/dist/toast/root/toast-root.js +58 -12
- 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 -41
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +21 -5
- package/dist/toolbar/root/toolbar-root.js +52 -8
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -1
- 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 +5 -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 +48 -24
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2979 -738
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +619 -202
- 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
|
@@ -4,14 +4,18 @@ 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, fillTemplate, HelixElement } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, fillTemplate, formatNumber, HelixElement } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.label = '';
|
|
14
|
+
this.locale = '';
|
|
14
15
|
this.value = '';
|
|
16
|
+
this.handleSlotchange = () => {
|
|
17
|
+
this.describe();
|
|
18
|
+
};
|
|
15
19
|
}
|
|
16
20
|
get given() {
|
|
17
21
|
return String(this.value ?? '');
|
|
@@ -19,18 +23,91 @@ let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
|
|
|
19
23
|
get blank() {
|
|
20
24
|
return this.given.trim() !== '' && Number(this.given) === 0;
|
|
21
25
|
}
|
|
26
|
+
get capped() {
|
|
27
|
+
const count = Number(this.given);
|
|
28
|
+
return this.max !== undefined && Number.isFinite(count) && count > this.max;
|
|
29
|
+
}
|
|
22
30
|
get text() {
|
|
31
|
+
const write = (count) => this.formatOptions ? formatNumber(count, this.locale, this.formatOptions) : String(count);
|
|
32
|
+
if (this.capped) {
|
|
33
|
+
return `${write(this.max)}+`;
|
|
34
|
+
}
|
|
23
35
|
const count = Number(this.given);
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
return this.formatOptions && this.given.trim() !== '' && Number.isFinite(count)
|
|
37
|
+
? write(count)
|
|
38
|
+
: this.given;
|
|
39
|
+
}
|
|
40
|
+
get words() {
|
|
41
|
+
const text = this.text;
|
|
42
|
+
if (this.blank || (text === '' && this.label === '')) {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
return fillTemplate(this.label, { count: text }) || text;
|
|
46
|
+
}
|
|
47
|
+
wrapped() {
|
|
48
|
+
const found = this.renderRoot
|
|
49
|
+
.querySelector('slot:not([name])')
|
|
50
|
+
?.assignedElements({ flatten: true })
|
|
51
|
+
.find((element) => element instanceof HTMLElement &&
|
|
52
|
+
(element.tabIndex >= 0 || element.shadowRoot?.delegatesFocus === true));
|
|
53
|
+
const inner = found?.shadowRoot?.delegatesFocus
|
|
54
|
+
? found.shadowRoot.querySelector('a[href], button, input, select, textarea')
|
|
55
|
+
: null;
|
|
56
|
+
return inner ?? found;
|
|
57
|
+
}
|
|
58
|
+
firstUpdated(changed) {
|
|
59
|
+
super.firstUpdated(changed);
|
|
60
|
+
requestAnimationFrame(() => this.describe());
|
|
61
|
+
}
|
|
62
|
+
describe() {
|
|
63
|
+
const words = this.words;
|
|
64
|
+
const control = words === '' ? undefined : this.wrapped();
|
|
65
|
+
if (this.described && this.described !== control) {
|
|
66
|
+
this.undescribe();
|
|
67
|
+
}
|
|
68
|
+
if (!control || !('ariaDescribedByElements' in control)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const own = control.getAttribute('aria-describedby') || control.ariaDescribedByElements?.length;
|
|
72
|
+
if (control !== this.described && own) {
|
|
73
|
+
return;
|
|
26
74
|
}
|
|
27
|
-
|
|
75
|
+
this.internals.ariaLabel = words;
|
|
76
|
+
control.ariaDescribedByElements = [this];
|
|
77
|
+
this.described = control;
|
|
78
|
+
}
|
|
79
|
+
undescribe() {
|
|
80
|
+
if (this.described?.ariaDescribedByElements?.includes(this)) {
|
|
81
|
+
this.described.ariaDescribedByElements = null;
|
|
82
|
+
}
|
|
83
|
+
this.described = undefined;
|
|
84
|
+
this.internals.ariaLabel = null;
|
|
85
|
+
}
|
|
86
|
+
disconnectedCallback() {
|
|
87
|
+
super.disconnectedCallback();
|
|
88
|
+
this.undescribe();
|
|
89
|
+
}
|
|
90
|
+
connectedCallback() {
|
|
91
|
+
super.connectedCallback();
|
|
92
|
+
if (this.hasUpdated) {
|
|
93
|
+
this.describe();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
willUpdate(changed) {
|
|
97
|
+
super.willUpdate(changed);
|
|
98
|
+
this.toggleState('capped', this.capped);
|
|
99
|
+
this.toggleState('dot', this.given.trim() === '');
|
|
100
|
+
this.toggleState('blank', this.blank);
|
|
101
|
+
}
|
|
102
|
+
updated(changed) {
|
|
103
|
+
super.updated(changed);
|
|
104
|
+
this.describe();
|
|
28
105
|
}
|
|
29
106
|
render() {
|
|
30
107
|
const blank = this.blank;
|
|
31
108
|
const text = this.text;
|
|
32
109
|
const announced = !blank && (text !== '' || this.label !== '');
|
|
33
|
-
return html `<slot></slot>
|
|
110
|
+
return html `<slot @slotchange=${this.handleSlotchange}></slot>
|
|
34
111
|
<span
|
|
35
112
|
part="indicator"
|
|
36
113
|
data-blank=${blank ? '' : nothing}
|
|
@@ -41,9 +118,15 @@ let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
|
|
|
41
118
|
>`;
|
|
42
119
|
}
|
|
43
120
|
};
|
|
121
|
+
__decorate([
|
|
122
|
+
property({ attribute: 'format-options', type: Object })
|
|
123
|
+
], HelixHeadlessBadge.prototype, "formatOptions", void 0);
|
|
44
124
|
__decorate([
|
|
45
125
|
property()
|
|
46
126
|
], HelixHeadlessBadge.prototype, "label", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
property()
|
|
129
|
+
], HelixHeadlessBadge.prototype, "locale", void 0);
|
|
47
130
|
__decorate([
|
|
48
131
|
property({ type: Number })
|
|
49
132
|
], HelixHeadlessBadge.prototype, "max", void 0);
|
|
@@ -4,10 +4,10 @@ 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 { byRow, CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesNames, ticks, unbroken, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { byRow, CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesKey, seriesNames, ticks, unbroken, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
-
import { stackEnds, stackSpans } from '../stack.js';
|
|
10
|
+
import { stackEnds, stackedReadings, stackSpans } from '../stack.js';
|
|
11
11
|
import '../../tooltip/index.js';
|
|
12
12
|
let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource(HelixElement) {
|
|
13
13
|
constructor() {
|
|
@@ -38,23 +38,13 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
38
38
|
return html `<div id=${CHART_PLOT} part="plot"></div>`;
|
|
39
39
|
}
|
|
40
40
|
const scaled = this.scaled;
|
|
41
|
-
const own = (one) => scaled.has(one.name
|
|
41
|
+
const own = (one) => scaled.has(seriesKey(one.name));
|
|
42
42
|
const shown = series.filter((one) => this.showsSeries(one.name));
|
|
43
43
|
const values = shown.flatMap((one) => one.points.map((point) => point.value));
|
|
44
44
|
const lined = this.lined;
|
|
45
|
-
const readingsOf = (group) =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const columns = group.filter((one) => !lined.has(one.name.trim().toLowerCase()));
|
|
50
|
-
const slots = columns.map((one) => byRow(one, categories.length));
|
|
51
|
-
return [
|
|
52
|
-
...group
|
|
53
|
-
.filter((one) => lined.has(one.name.trim().toLowerCase()))
|
|
54
|
-
.flatMap((one) => one.points.map((point) => point.value)),
|
|
55
|
-
...stackEnds(categories.map((_, at) => slots.map((one) => one[at]?.value))),
|
|
56
|
-
];
|
|
57
|
-
};
|
|
45
|
+
const readingsOf = (group) => this.stacked
|
|
46
|
+
? stackedReadings(group, categories.length, (one) => lined.has(seriesKey(one.name)))
|
|
47
|
+
: group.flatMap((one) => one.points.map((point) => point.value));
|
|
58
48
|
const on = (which) => {
|
|
59
49
|
const found = readingsOf(shown.filter(which));
|
|
60
50
|
return found.length > 0 ? found : values.length > 0 ? values : [0];
|
|
@@ -96,11 +86,11 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
96
86
|
const slot = 100 / categories.length;
|
|
97
87
|
const lined = this.lined;
|
|
98
88
|
const scaled = this.scaled;
|
|
99
|
-
const own = (one) => scaled.has(one.name
|
|
89
|
+
const own = (one) => scaled.has(seriesKey(one.name));
|
|
100
90
|
const against = (one) => z !== undefined && own(one) ? z : y;
|
|
101
91
|
const columns = series
|
|
102
92
|
.map((one, index) => ({ one, slots: byRow(one, categories.length), tone: index }))
|
|
103
|
-
.filter(({ one }) => !lined.has(one.name
|
|
93
|
+
.filter(({ one }) => !lined.has(seriesKey(one.name)) && this.showsSeries(one.name));
|
|
104
94
|
const abreast = this.stacked ? 1 : columns.length;
|
|
105
95
|
const stride = (slot * 0.72) / Math.max(abreast, 1);
|
|
106
96
|
const gap = abreast > 1 ? stride * 0.08 : 0;
|
|
@@ -178,7 +168,7 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
178
168
|
: bar(point.value, index, depth, tone, against(one));
|
|
179
169
|
})}
|
|
180
170
|
</g>`)}
|
|
181
|
-
${series.map((one) => lined.has(one.name
|
|
171
|
+
${series.map((one) => lined.has(seriesKey(one.name)) && this.showsSeries(one.name)
|
|
182
172
|
? this.renderLine(one, series.indexOf(one), slot, against(one), sideways)
|
|
183
173
|
: nothing)}
|
|
184
174
|
</svg>
|
|
@@ -269,8 +259,9 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
269
259
|
.map((one) => byRow(one, this.readings)[at]?.value)
|
|
270
260
|
.filter((one) => one !== undefined);
|
|
271
261
|
const values = this.stacked ? stackEnds([reached]) : reached;
|
|
262
|
+
const lined = this.lined;
|
|
272
263
|
const all = this.stacked
|
|
273
|
-
?
|
|
264
|
+
? stackedReadings(shown, this.readings, (one) => lined.has(seriesKey(one.name)))
|
|
274
265
|
: shown.flatMap((one) => one.points.map((point) => point.value));
|
|
275
266
|
const [low, high] = extent(all.length > 0 ? all : [0]);
|
|
276
267
|
const domain = [Math.min(0, low), Math.max(0, high)];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Series } from '@fusion.dev/helix-core';
|
|
1
2
|
/** Where a column starts and ends along the measure, in the data's own units. */
|
|
2
3
|
export type Span = readonly [from: number, to: number];
|
|
3
4
|
/**
|
|
@@ -13,3 +14,12 @@ export declare const stackSpans: (values: readonly (number | undefined)[]) => (S
|
|
|
13
14
|
* of negatives. `categories` holds each category's readings, one per column.
|
|
14
15
|
*/
|
|
15
16
|
export declare const stackEnds: (categories: readonly (readonly (number | undefined)[])[]) => number[];
|
|
17
|
+
/**
|
|
18
|
+
* The readings a stacked scale has to hold, over `count` categories: every
|
|
19
|
+
* reading of a series drawn as a line, which `lined` says, and the top and
|
|
20
|
+
* foot of each category's stack of the others.
|
|
21
|
+
*
|
|
22
|
+
* The plot's scale and the tooltip's placing ask the same question, and
|
|
23
|
+
* answered apart they disagreed about the lines.
|
|
24
|
+
*/
|
|
25
|
+
export declare const stackedReadings: (group: readonly Series[], count: number, lined: (one: Series) => boolean) => number[];
|
package/dist/bar-chart/stack.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { byRow } from '@fusion.dev/helix-core';
|
|
1
2
|
export const stackSpans = (values) => {
|
|
2
3
|
let up = 0;
|
|
3
4
|
let down = 0;
|
|
@@ -17,3 +18,10 @@ export const stackSpans = (values) => {
|
|
|
17
18
|
});
|
|
18
19
|
};
|
|
19
20
|
export const stackEnds = (categories) => categories.flatMap((values) => stackSpans(values).flatMap((span) => (span === undefined ? [] : [span[1]])));
|
|
21
|
+
export const stackedReadings = (group, count, lined) => {
|
|
22
|
+
const slots = group.filter((one) => !lined(one)).map((one) => byRow(one, count));
|
|
23
|
+
return [
|
|
24
|
+
...group.filter(lined).flatMap((one) => one.points.map((point) => point.value)),
|
|
25
|
+
...stackEnds(Array.from({ length: count }, (_, at) => slots.map((one) => one[at]?.value))),
|
|
26
|
+
];
|
|
27
|
+
};
|
|
@@ -37,6 +37,9 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
37
37
|
* @csspart link - The crumb itself, which is an `<a>` where `href` is set.
|
|
38
38
|
* @csspart separator - The separator preceding the item.
|
|
39
39
|
* @csspart separator-mark - The chevron between crumbs, shown when no separator is slotted.
|
|
40
|
+
*
|
|
41
|
+
* @cssstate end - While the `end` slot holds something, so a stylesheet can join
|
|
42
|
+
* the label and what follows it into one control.
|
|
40
43
|
*/
|
|
41
44
|
export declare class HelixHeadlessBreadcrumb extends HelixElement {
|
|
42
45
|
/**
|
|
@@ -74,6 +77,17 @@ export declare class HelixHeadlessBreadcrumb extends HelixElement {
|
|
|
74
77
|
*/
|
|
75
78
|
target: string;
|
|
76
79
|
protected willUpdate(changed: PropertyValues): void;
|
|
80
|
+
protected updated(changed: PropertyValues): void;
|
|
81
|
+
/**
|
|
82
|
+
* Says whether anything sits after the label.
|
|
83
|
+
*
|
|
84
|
+
* A switcher's trigger in `end` makes the crumb a split control, and its
|
|
85
|
+
* label is drawn as the first half of it. No selector can ask a slot what was
|
|
86
|
+
* assigned to it, so this is script. Answered from a DOM, so the server
|
|
87
|
+
* writes the resting answer and the first client update corrects it.
|
|
88
|
+
*/
|
|
89
|
+
private markEnd;
|
|
90
|
+
private readonly handleEnd;
|
|
77
91
|
/**
|
|
78
92
|
* The mark between one crumb and the next.
|
|
79
93
|
*
|
|
@@ -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, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, hostAria, slotFilled } 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 } from 'lit/decorators.js';
|
|
@@ -15,12 +15,22 @@ let HelixHeadlessBreadcrumb = class HelixHeadlessBreadcrumb extends HelixElement
|
|
|
15
15
|
this.current = false;
|
|
16
16
|
this.rel = '';
|
|
17
17
|
this.target = '';
|
|
18
|
+
this.handleEnd = () => {
|
|
19
|
+
this.markEnd();
|
|
20
|
+
};
|
|
18
21
|
}
|
|
19
22
|
willUpdate(changed) {
|
|
20
23
|
super.willUpdate(changed);
|
|
21
24
|
hostAria(this.internals, { role: 'listitem' });
|
|
22
25
|
this.internals.ariaCurrent = this.current ? 'page' : null;
|
|
23
26
|
}
|
|
27
|
+
updated(changed) {
|
|
28
|
+
super.updated(changed);
|
|
29
|
+
this.markEnd();
|
|
30
|
+
}
|
|
31
|
+
markEnd() {
|
|
32
|
+
this.toggleState('end', slotFilled(this.renderRoot?.querySelector('slot[name="end"]')));
|
|
33
|
+
}
|
|
24
34
|
renderSeparator() {
|
|
25
35
|
return html `<slot name="separator"
|
|
26
36
|
><svg part="separator-mark" data-mirror fill="currentColor" viewBox=${caretRight.viewBox}>
|
|
@@ -41,7 +51,7 @@ let HelixHeadlessBreadcrumb = class HelixHeadlessBreadcrumb extends HelixElement
|
|
|
41
51
|
rel=${this.rel || nothing}
|
|
42
52
|
>${label}</a
|
|
43
53
|
>`
|
|
44
|
-
: html `<span part="link">${label}</span>`}<slot name="end"></slot>`;
|
|
54
|
+
: html `<span part="link">${label}</span>`}<slot name="end" @slotchange=${this.handleEnd}></slot>`;
|
|
45
55
|
}
|
|
46
56
|
};
|
|
47
57
|
__decorate([
|
|
@@ -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, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, fillTemplate, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { repeat } from 'lit/directives/repeat.js';
|
|
@@ -55,7 +55,7 @@ let HelixHeadlessBreadcrumbs = class HelixHeadlessBreadcrumbs extends HelixEleme
|
|
|
55
55
|
><button
|
|
56
56
|
part="expand"
|
|
57
57
|
type="button"
|
|
58
|
-
aria-label=${this.expandLabel
|
|
58
|
+
aria-label=${fillTemplate(this.expandLabel, { count: String(folded) })}
|
|
59
59
|
@click=${this.expand}
|
|
60
60
|
>
|
|
61
61
|
…
|
|
@@ -18,13 +18,12 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
18
18
|
*
|
|
19
19
|
* The inner control is always `type="button"`, because a
|
|
20
20
|
* `<button type="submit">` inside a shadow root cannot submit a form outside
|
|
21
|
-
* it. To submit, the button
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* submit buttons apart.
|
|
21
|
+
* it. To submit, the button puts a hidden native submit button carrying its
|
|
22
|
+
* `name`, `value` and `form*` overrides into the form, calls
|
|
23
|
+
* `requestSubmit()` with it, which runs validation, unlike `submit()`, and
|
|
24
|
+
* takes it out again, as Shoelace and Web Awesome do. A `submit` listener
|
|
25
|
+
* reads that button as `event.submitter`, so `event.submitter.value` and
|
|
26
|
+
* `new FormData(form, event.submitter)` tell two submit buttons apart.
|
|
28
27
|
*
|
|
29
28
|
* As the first submit button in its form, it is the form's default button:
|
|
30
29
|
* Enter in a text field of the form presses it, as it presses a native one.
|
|
@@ -54,6 +53,7 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
54
53
|
*
|
|
55
54
|
* @csspart button - The inner control.
|
|
56
55
|
* @csspart live - The live region that says `pending-label` when the button becomes pending under focus. It is rendered from the first time the button is pending, and the styled button clips it out of view.
|
|
56
|
+
* @csspart spinner - The ring a pending button turns, an empty element the styled button draws over the words. It is rendered only while the button is pending.
|
|
57
57
|
* @csspart text - The button's words, which the styled button trims to their capitals and baseline so the letters sit at the middle in any font.
|
|
58
58
|
*
|
|
59
59
|
* @cssstate pending - The button is pending: `pending` is set.
|
|
@@ -135,18 +135,13 @@ export declare class HelixHeadlessButton extends HelixFormElement {
|
|
|
135
135
|
/**
|
|
136
136
|
* Where this button's submission goes, overriding the form's own.
|
|
137
137
|
*
|
|
138
|
-
* **The five `form*` overrides
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* The whole submit algorithm runs synchronously inside `requestSubmit()`, so
|
|
147
|
-
* the window is one call and a `finally` closes it whether or not a listener
|
|
148
|
-
* refused. What a `submit` handler observes during that window is the form a
|
|
149
|
-
* native submitter would have given it, which is the point.
|
|
138
|
+
* **The five `form*` overrides ride on a native submit button that stands in
|
|
139
|
+
* for this one**, because `requestSubmit(submitter)` refuses the inner
|
|
140
|
+
* `<button>` twice over: it is `type="button"`, and it sits in this shadow
|
|
141
|
+
* root, so its form owner is not the consumer's form. The stand-in is a
|
|
142
|
+
* hidden `<button type="submit">` in the form for the one synchronous call,
|
|
143
|
+
* so the platform applies the overrides to that submission alone and leaves
|
|
144
|
+
* the form as it was. See `submitAs`.
|
|
150
145
|
*/
|
|
151
146
|
formAction: string;
|
|
152
147
|
/**
|
|
@@ -249,13 +244,10 @@ export declare class HelixHeadlessButton extends HelixFormElement {
|
|
|
249
244
|
* The value this button submits under its own `name`, as a native submit
|
|
250
245
|
* button does.
|
|
251
246
|
*
|
|
252
|
-
* **
|
|
247
|
+
* **Sent with exactly the submission this button starts and not otherwise.**
|
|
253
248
|
* A native submit button contributes `name=value` only when it is the one
|
|
254
|
-
* that submitted, and every other button on the form contributes nothing
|
|
255
|
-
*
|
|
256
|
-
* every submission whoever started it, which is a different feature wearing
|
|
257
|
-
* the same name, so `submit` below sets it, submits, and clears it inside one
|
|
258
|
-
* synchronous call.
|
|
249
|
+
* that submitted, and every other button on the form contributes nothing,
|
|
250
|
+
* which is what the native button standing in for this one at submit does.
|
|
259
251
|
*
|
|
260
252
|
* `CopyButton` has a `value` of its own meaning the text to put on the
|
|
261
253
|
* clipboard, which is not this and is why it is declared there rather than
|
|
@@ -263,19 +255,8 @@ export declare class HelixHeadlessButton extends HelixFormElement {
|
|
|
263
255
|
*/
|
|
264
256
|
value: string;
|
|
265
257
|
/**
|
|
266
|
-
* Submits the form as this button,
|
|
267
|
-
*
|
|
268
|
-
* Everything a native submitter carries is written onto the form, the
|
|
269
|
-
* submission is started, and everything is put back. See `formAction` for why
|
|
270
|
-
* `requestSubmit(submitter)` is not available to a control inside a shadow
|
|
271
|
-
* root.
|
|
272
|
-
*
|
|
273
|
-
* `novalidate` is in the same list rather than reached by `form.submit()`,
|
|
274
|
-
* which looks like the shortcut and is not: `submit()` skips the `submit`
|
|
275
|
-
* event as well as the validation, so a consumer's handler would stop running
|
|
276
|
-
* the moment somebody wrote `formnovalidate`. Turning the flag on and calling
|
|
277
|
-
* `requestSubmit()` skips the validation alone, which is what the attribute
|
|
278
|
-
* means.
|
|
258
|
+
* Submits the form as this button, through a native submit button carrying
|
|
259
|
+
* its name, value and overrides. See `formAction`.
|
|
279
260
|
*/
|
|
280
261
|
private submit;
|
|
281
262
|
/**
|
|
@@ -346,6 +327,11 @@ export declare class HelixHeadlessButton extends HelixFormElement {
|
|
|
346
327
|
/** Called by the browser when the button's form changes. */
|
|
347
328
|
formAssociatedCallback(form: HTMLFormElement | null): void;
|
|
348
329
|
protected render(): TemplateResult;
|
|
330
|
+
/**
|
|
331
|
+
* The ring a pending button turns, behind a seam a tier can move: an empty
|
|
332
|
+
* element, hidden from a screen reader, which hears `pending-label` instead.
|
|
333
|
+
*/
|
|
334
|
+
protected renderSpinner(): TemplateResult | typeof nothing;
|
|
349
335
|
}
|
|
350
336
|
declare global {
|
|
351
337
|
interface HTMLElementTagNameMap {
|
|
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { AriaForwardController, customElement, defaultButton, drawStatus, elementById, HelixFallbackCommandEvent, HelixFormElement, HelixPressEvent, pressType, StatusController, submitsOnEnter, supportsInvokers, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { submitAs } from '../submitter.js';
|
|
10
11
|
let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
@@ -103,42 +104,7 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
submit(form) {
|
|
106
|
-
|
|
107
|
-
const override = (attribute, value) => {
|
|
108
|
-
if (value === null) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const had = form.getAttribute(attribute);
|
|
112
|
-
form.setAttribute(attribute, value);
|
|
113
|
-
undo.push(() => {
|
|
114
|
-
if (had === null) {
|
|
115
|
-
form.removeAttribute(attribute);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
form.setAttribute(attribute, had);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
};
|
|
122
|
-
override('action', this.formAction || null);
|
|
123
|
-
override('enctype', this.formEnctype || null);
|
|
124
|
-
override('method', this.formMethod || null);
|
|
125
|
-
override('novalidate', this.formNoValidate ? '' : null);
|
|
126
|
-
override('target', this.formTarget || null);
|
|
127
|
-
const reports = this.name !== '';
|
|
128
|
-
if (reports) {
|
|
129
|
-
this.internals.setFormValue(this.value);
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
form.requestSubmit();
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
for (const put of undo) {
|
|
136
|
-
put();
|
|
137
|
-
}
|
|
138
|
-
if (reports) {
|
|
139
|
-
this.internals.setFormValue(null);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
107
|
+
submitAs(form, this);
|
|
142
108
|
}
|
|
143
109
|
get commandForElement() {
|
|
144
110
|
const button = this.renderRoot?.querySelector('button');
|
|
@@ -222,9 +188,12 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
|
|
|
222
188
|
@keydown=${this.notePress}
|
|
223
189
|
@pointerdown=${this.notePress}
|
|
224
190
|
>
|
|
225
|
-
${label}
|
|
191
|
+
${label}${this.renderSpinner()}
|
|
226
192
|
</button>${this.renderLive()}`;
|
|
227
193
|
}
|
|
194
|
+
renderSpinner() {
|
|
195
|
+
return this.pending ? html `<span part="spinner" aria-hidden="true"></span>` : nothing;
|
|
196
|
+
}
|
|
228
197
|
};
|
|
229
198
|
__decorate([
|
|
230
199
|
property()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Submitting a form through a native submit button that stands in for one in a
|
|
3
|
+
* shadow root.
|
|
4
|
+
*
|
|
5
|
+
* `requestSubmit(submitter)` takes only a native submit button whose form is
|
|
6
|
+
* the form, and a button inside a shadow root is neither. A hidden native
|
|
7
|
+
* `<button type="submit">` carrying the same name, value and `form*`
|
|
8
|
+
* overrides is put into the form for the one synchronous call, as Shoelace and
|
|
9
|
+
* Web Awesome do, so the platform does the rest: `event.submitter` is a
|
|
10
|
+
* button with the name and value, `new FormData(form, event.submitter)`
|
|
11
|
+
* includes them, and the overrides apply to that submission alone.
|
|
12
|
+
*/
|
|
13
|
+
/** What a submit button carries into the submission it starts. */
|
|
14
|
+
export interface Carried {
|
|
15
|
+
formAction: string;
|
|
16
|
+
formEnctype: string;
|
|
17
|
+
formMethod: string;
|
|
18
|
+
formNoValidate: boolean;
|
|
19
|
+
formTarget: string;
|
|
20
|
+
name: string;
|
|
21
|
+
value: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Submits `form` as a native submit button carrying `carried` would, and takes
|
|
25
|
+
* that button out again whether or not a listener refused the submission.
|
|
26
|
+
*/
|
|
27
|
+
export declare const submitAs: (form: HTMLFormElement, carried: Carried) => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const submitAs = (form, carried) => {
|
|
2
|
+
const stand = form.ownerDocument.createElement('button');
|
|
3
|
+
stand.type = 'submit';
|
|
4
|
+
stand.hidden = true;
|
|
5
|
+
for (const [attribute, value] of [
|
|
6
|
+
['formaction', carried.formAction],
|
|
7
|
+
['formenctype', carried.formEnctype],
|
|
8
|
+
['formmethod', carried.formMethod],
|
|
9
|
+
['formtarget', carried.formTarget],
|
|
10
|
+
['name', carried.name],
|
|
11
|
+
]) {
|
|
12
|
+
if (value !== '') {
|
|
13
|
+
stand.setAttribute(attribute, value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
stand.value = carried.value;
|
|
17
|
+
stand.formNoValidate = carried.formNoValidate;
|
|
18
|
+
form.append(stand);
|
|
19
|
+
try {
|
|
20
|
+
form.requestSubmit(stand);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
stand.remove();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -31,6 +31,12 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
31
31
|
* is no wrapper and every region is a bare slot. A server cannot see slotted
|
|
32
32
|
* content, so served actions sit on their own line until the script runs.
|
|
33
33
|
*
|
|
34
|
+
* **The card says which regions it holds**, as `:state(has-media)`,
|
|
35
|
+
* `:state(has-header)` and `:state(has-footer)`, so a sheet can draw a card
|
|
36
|
+
* with a header differently, as Web Awesome's `with-header` does, with no
|
|
37
|
+
* attribute written onto the card. Read in the browser, so a served card
|
|
38
|
+
* carries none until the script runs.
|
|
39
|
+
*
|
|
34
40
|
* @since 0.1.0
|
|
35
41
|
* @status stable
|
|
36
42
|
* @category layout
|
|
@@ -52,6 +58,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
52
58
|
* @csspart header-actions - The slot the header's controls arrive through, drawing no box, as `body` does.
|
|
53
59
|
* @csspart header-row - The line holding `header` and `header-actions`, drawn only while `header-actions` holds something.
|
|
54
60
|
* @csspart media - The slot the media arrives through, drawing no box, as `body` does.
|
|
61
|
+
*
|
|
62
|
+
* @cssstate has-footer - Something is slotted into `footer` or `footer-actions`.
|
|
63
|
+
* @cssstate has-header - Something is slotted into `header` or `header-actions`.
|
|
64
|
+
* @cssstate has-media - Something is slotted into `media`.
|
|
55
65
|
*/
|
|
56
66
|
export declare class HelixHeadlessCard extends HelixElement {
|
|
57
67
|
/**
|
|
@@ -92,7 +102,8 @@ export declare class HelixHeadlessCard extends HelixElement {
|
|
|
92
102
|
private headerActions;
|
|
93
103
|
protected willUpdate(changed: PropertyValues): void;
|
|
94
104
|
protected updated(changed: PropertyValues): void;
|
|
95
|
-
|
|
105
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
106
|
+
private readonly readRegions;
|
|
96
107
|
protected render(): TemplateResult;
|
|
97
108
|
}
|
|
98
109
|
declare global {
|
|
@@ -15,10 +15,13 @@ let HelixHeadlessCard = class HelixHeadlessCard extends HelixElement {
|
|
|
15
15
|
this.namedBy = null;
|
|
16
16
|
this.footerActions = false;
|
|
17
17
|
this.headerActions = false;
|
|
18
|
-
this.
|
|
18
|
+
this.readRegions = () => {
|
|
19
19
|
const filled = (name) => slotFilled(this.renderRoot?.querySelector(`slot[name="${name}"]`));
|
|
20
20
|
this.headerActions = filled('header-actions');
|
|
21
21
|
this.footerActions = filled('footer-actions');
|
|
22
|
+
this.toggleState('has-media', filled('media'));
|
|
23
|
+
this.toggleState('has-header', this.headerActions || filled('header'));
|
|
24
|
+
this.toggleState('has-footer', this.footerActions || filled('footer'));
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
willUpdate(changed) {
|
|
@@ -28,20 +31,24 @@ let HelixHeadlessCard = class HelixHeadlessCard extends HelixElement {
|
|
|
28
31
|
}
|
|
29
32
|
updated(changed) {
|
|
30
33
|
super.updated(changed);
|
|
31
|
-
this.
|
|
34
|
+
this.readRegions();
|
|
35
|
+
}
|
|
36
|
+
firstUpdated(changed) {
|
|
37
|
+
super.firstUpdated(changed);
|
|
38
|
+
this.renderRoot.addEventListener('slotchange', this.readRegions);
|
|
32
39
|
}
|
|
33
40
|
render() {
|
|
34
41
|
const header = html `<slot name="header" part="header"></slot
|
|
35
42
|
><slot
|
|
36
43
|
name="header-actions"
|
|
37
44
|
part="header-actions"
|
|
38
|
-
@slotchange=${this.
|
|
45
|
+
@slotchange=${this.readRegions}
|
|
39
46
|
></slot>`;
|
|
40
47
|
const footer = html `<slot name="footer" part="footer"></slot
|
|
41
48
|
><slot
|
|
42
49
|
name="footer-actions"
|
|
43
50
|
part="footer-actions"
|
|
44
|
-
@slotchange=${this.
|
|
51
|
+
@slotchange=${this.readRegions}
|
|
45
52
|
></slot>`;
|
|
46
53
|
return html `
|
|
47
54
|
<slot name="media" part="media"></slot>
|