@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
|
@@ -97,6 +97,7 @@ declare const HelixHeadlessFilterInput_base: (new (...args: any[]) => import("@f
|
|
|
97
97
|
* @aliases SearchField, FacetInput, TokenInput
|
|
98
98
|
* @documentation https://fusion.dev/helix/components/filter-input
|
|
99
99
|
*
|
|
100
|
+
* @slot clear-icon - Replaces the cross on the clear button, under `clearable`.
|
|
100
101
|
* @slot end - Content after the text, such as a count or a control.
|
|
101
102
|
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
102
103
|
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
@@ -256,6 +257,11 @@ export declare class HelixHeadlessFilterInput extends HelixHeadlessFilterInput_b
|
|
|
256
257
|
* and one that pretends it was never there.
|
|
257
258
|
*/
|
|
258
259
|
private get suggestions();
|
|
260
|
+
/**
|
|
261
|
+
* Every option slotted into `suggestions`, and every option one level inside
|
|
262
|
+
* a group slotted there, hidden or not.
|
|
263
|
+
*/
|
|
264
|
+
private get options();
|
|
259
265
|
/**
|
|
260
266
|
* The direction of the selection, named as on `<input>`.
|
|
261
267
|
*
|
|
@@ -437,6 +443,8 @@ export declare class HelixHeadlessFilterInput extends HelixHeadlessFilterInput_b
|
|
|
437
443
|
private markActive;
|
|
438
444
|
/** Puts the caret in the text field. */
|
|
439
445
|
focus(options?: FocusOptions): void;
|
|
446
|
+
/** The cross on the clear button, behind a seam a tier can move. */
|
|
447
|
+
protected renderClearIcon(): TemplateResult;
|
|
440
448
|
protected render(): TemplateResult;
|
|
441
449
|
}
|
|
442
450
|
declare global {
|
|
@@ -162,22 +162,18 @@ let HelixHeadlessFilterInput = class HelixHeadlessFilterInput extends MixinContr
|
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
narrow() {
|
|
165
|
-
const slot = this.renderRoot?.querySelector('slot[name="suggestions"]');
|
|
166
165
|
const term = this.filterSuggestions
|
|
167
166
|
? currentTerm(this.value, this.control?.selectionStart ?? this.value.length)
|
|
168
167
|
: '';
|
|
169
|
-
for (const
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
option.hidden = false;
|
|
179
|
-
this.narrowed.delete(option);
|
|
180
|
-
}
|
|
168
|
+
for (const option of this.options) {
|
|
169
|
+
const hide = !suggests(option.textContent ?? '', term);
|
|
170
|
+
if (hide && !option.hidden) {
|
|
171
|
+
option.hidden = true;
|
|
172
|
+
this.narrowed.add(option);
|
|
173
|
+
}
|
|
174
|
+
else if (!hide && this.narrowed.has(option)) {
|
|
175
|
+
option.hidden = false;
|
|
176
|
+
this.narrowed.delete(option);
|
|
181
177
|
}
|
|
182
178
|
}
|
|
183
179
|
}
|
|
@@ -220,20 +216,11 @@ let HelixHeadlessFilterInput = class HelixHeadlessFilterInput extends MixinContr
|
|
|
220
216
|
return this.clearable && this.value !== '' && !this.isDisabled;
|
|
221
217
|
}
|
|
222
218
|
get suggestions() {
|
|
219
|
+
return this.options.filter((option) => !option.disabled && !option.hidden);
|
|
220
|
+
}
|
|
221
|
+
get options() {
|
|
223
222
|
const slot = this.renderRoot?.querySelector('slot[name="suggestions"]');
|
|
224
|
-
|
|
225
|
-
for (const node of slot?.assignedElements({ flatten: true }) ?? []) {
|
|
226
|
-
if (isOption(node)) {
|
|
227
|
-
found.push(node);
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
for (const child of node.children) {
|
|
231
|
-
if (isOption(child)) {
|
|
232
|
-
found.push(child);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return found.filter((option) => !option.disabled && !option.hidden);
|
|
223
|
+
return (slot?.assignedElements({ flatten: true }) ?? []).flatMap((node) => isOption(node) ? [node] : [...node.children].filter(isOption));
|
|
237
224
|
}
|
|
238
225
|
get selectionDirection() {
|
|
239
226
|
return this.control?.selectionDirection ?? 'none';
|
|
@@ -392,6 +379,9 @@ let HelixHeadlessFilterInput = class HelixHeadlessFilterInput extends MixinContr
|
|
|
392
379
|
focus(options) {
|
|
393
380
|
this.control?.focus(options);
|
|
394
381
|
}
|
|
382
|
+
renderClearIcon() {
|
|
383
|
+
return html `<slot name="clear-icon">${drawIcon(x)}</slot>`;
|
|
384
|
+
}
|
|
395
385
|
render() {
|
|
396
386
|
return html `${this.renderLabel()}
|
|
397
387
|
<div part="field" @focusin=${this.handleFocusIn} @focusout=${this.handleFocusOut}>
|
|
@@ -426,7 +416,7 @@ let HelixHeadlessFilterInput = class HelixHeadlessFilterInput extends MixinContr
|
|
|
426
416
|
aria-label=${this.clearLabel}
|
|
427
417
|
@click=${this.handleClear}
|
|
428
418
|
>
|
|
429
|
-
${
|
|
419
|
+
${this.renderClearIcon()}
|
|
430
420
|
</button>`
|
|
431
421
|
: nothing}
|
|
432
422
|
</div>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a Format Date was asked for, in its own spelling: the `Intl` options a
|
|
3
|
-
* consumer set
|
|
3
|
+
* consumer set. The element itself is one, so it passes itself.
|
|
4
4
|
*/
|
|
5
5
|
export interface Asked {
|
|
6
|
-
dateOnly: boolean;
|
|
7
6
|
dateStyle?: 'full' | 'long' | 'medium' | 'short' | undefined;
|
|
8
7
|
day?: 'numeric' | '2-digit' | undefined;
|
|
9
8
|
era?: 'long' | 'narrow' | 'short' | undefined;
|
|
@@ -26,8 +25,8 @@ export interface Asked {
|
|
|
26
25
|
* given beside `month` or `hour`, so the fields are left out wherever a style
|
|
27
26
|
* is set. `hourCycle` and `timeZone` go with either.
|
|
28
27
|
*
|
|
29
|
-
* **A day with no time is read in UTC** unless a zone is given. Parsed, it is
|
|
28
|
+
* **A day with no time, `dateOnly`, is read in UTC** unless a zone is given. Parsed, it is
|
|
30
29
|
* midnight UTC, and read in a zone west of it that is the day before: measured
|
|
31
30
|
* before this, `2026-08-04` read "August 3, 2026" in Los Angeles.
|
|
32
31
|
*/
|
|
33
|
-
export declare const formatOptions: (asked: Asked) => Intl.DateTimeFormatOptions;
|
|
32
|
+
export declare const formatOptions: (asked: Asked, dateOnly?: boolean) => Intl.DateTimeFormatOptions;
|
|
@@ -9,7 +9,7 @@ const FIELDS = [
|
|
|
9
9
|
'weekday',
|
|
10
10
|
'year',
|
|
11
11
|
];
|
|
12
|
-
export const formatOptions = (asked) => {
|
|
12
|
+
export const formatOptions = (asked, dateOnly = false) => {
|
|
13
13
|
const options = {};
|
|
14
14
|
const styled = asked.dateStyle !== undefined || asked.timeStyle !== undefined;
|
|
15
15
|
if (styled) {
|
|
@@ -35,7 +35,7 @@ export const formatOptions = (asked) => {
|
|
|
35
35
|
if (asked.timeZone) {
|
|
36
36
|
options.timeZone = asked.timeZone;
|
|
37
37
|
}
|
|
38
|
-
else if (
|
|
38
|
+
else if (dateOnly) {
|
|
39
39
|
options.timeZone = 'UTC';
|
|
40
40
|
}
|
|
41
41
|
return options;
|
|
@@ -25,6 +25,7 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
25
25
|
* **The text refreshes on one timer shared by the page.** Each element
|
|
26
26
|
* schedules an update for when its current reading expires, and an element
|
|
27
27
|
* showing a date schedules none, so a long feed left open costs almost nothing.
|
|
28
|
+
* `frozen` draws the reading once and leaves it.
|
|
28
29
|
*
|
|
29
30
|
* **The output is always `<time datetime>`**, so copy and paste and scripts
|
|
30
31
|
* parsing the page get the exact instant, whatever the visible text says. A
|
|
@@ -85,6 +86,19 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
85
86
|
* How the era is written, such as AD, where a date is shown.
|
|
86
87
|
*/
|
|
87
88
|
era?: 'long' | 'narrow' | 'short';
|
|
89
|
+
/**
|
|
90
|
+
* Draws an `elapsed` or `relative` reading once and leaves it, where it
|
|
91
|
+
* would otherwise move on as it goes stale.
|
|
92
|
+
*
|
|
93
|
+
* For a reading that describes a moment the page itself is about, such as
|
|
94
|
+
* "3 hours ago" in a report generated then, or a list a reader compares
|
|
95
|
+
* line by line while it should not change under them. The reading is taken
|
|
96
|
+
* when the element draws, and again whenever `date` or another option
|
|
97
|
+
* changes. Turned off, the reading catches up and moves on again.
|
|
98
|
+
* `sl-relative-time` and `wa-relative-time` keep still unless `sync` is
|
|
99
|
+
* set; this keeps moving unless `frozen` is.
|
|
100
|
+
*/
|
|
101
|
+
frozen: boolean;
|
|
88
102
|
/**
|
|
89
103
|
* How the hour is written, where a time of day is shown.
|
|
90
104
|
*/
|
|
@@ -100,9 +114,12 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
100
114
|
/**
|
|
101
115
|
* The locale to format the timestamp in.
|
|
102
116
|
*
|
|
103
|
-
*
|
|
117
|
+
* Absent is the page's: the `lang` of the nearest element with one, as
|
|
118
|
+
* Shoelace and Web Awesome read it, then the runtime's own.
|
|
104
119
|
*/
|
|
105
120
|
locale: string;
|
|
121
|
+
/** The locale the words are written in: `locale`, or the page's `lang`. */
|
|
122
|
+
private get language();
|
|
106
123
|
/**
|
|
107
124
|
* How the minute is written, where a time of day is shown.
|
|
108
125
|
*/
|
|
@@ -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, elapsedTime, HelixElement, RelativeClockController, relativeTime, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, elapsedTime, HelixElement, localeOf, RelativeClockController, relativeTime, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { formatOptions } from '../options.js';
|
|
@@ -14,16 +14,23 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
14
14
|
super(...arguments);
|
|
15
15
|
this.date = '';
|
|
16
16
|
this.elapsed = false;
|
|
17
|
+
this.frozen = false;
|
|
17
18
|
this.locale = '';
|
|
18
19
|
this.clock = new RelativeClockController(this, {
|
|
19
20
|
expires: (now) => {
|
|
20
21
|
const moment = this.moment;
|
|
21
|
-
|
|
22
|
+
if (!moment || !this.reading) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return this.frozen ? Number.POSITIVE_INFINITY : this.readingAt(moment, now).next;
|
|
22
26
|
},
|
|
23
27
|
});
|
|
24
28
|
this.written = '';
|
|
25
29
|
this.watching = undefined;
|
|
26
30
|
}
|
|
31
|
+
get language() {
|
|
32
|
+
return localeOf(this, this.locale);
|
|
33
|
+
}
|
|
27
34
|
get dateOnly() {
|
|
28
35
|
return DATE_ONLY.test((this.date || this.written).trim());
|
|
29
36
|
}
|
|
@@ -36,30 +43,15 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
36
43
|
return Number.isNaN(parsed.getTime()) ? undefined : parsed;
|
|
37
44
|
}
|
|
38
45
|
get options() {
|
|
39
|
-
return formatOptions(
|
|
40
|
-
dateOnly: this.dateOnly,
|
|
41
|
-
dateStyle: this.dateStyle,
|
|
42
|
-
day: this.day,
|
|
43
|
-
era: this.era,
|
|
44
|
-
hour: this.hour,
|
|
45
|
-
hourCycle: this.hourCycle,
|
|
46
|
-
minute: this.minute,
|
|
47
|
-
month: this.month,
|
|
48
|
-
second: this.second,
|
|
49
|
-
timeStyle: this.timeStyle,
|
|
50
|
-
timeZone: this.timeZone,
|
|
51
|
-
timeZoneName: this.timeZoneName,
|
|
52
|
-
weekday: this.weekday,
|
|
53
|
-
year: this.year,
|
|
54
|
-
});
|
|
46
|
+
return formatOptions(this, this.dateOnly);
|
|
55
47
|
}
|
|
56
48
|
get reading() {
|
|
57
49
|
return this.elapsed || this.relative !== undefined;
|
|
58
50
|
}
|
|
59
51
|
readingAt(moment, now) {
|
|
60
52
|
return this.elapsed
|
|
61
|
-
? elapsedTime(this.
|
|
62
|
-
: relativeTime(this.
|
|
53
|
+
? elapsedTime(this.language)(moment, now)
|
|
54
|
+
: relativeTime(this.language, {
|
|
63
55
|
numeric: this.numeric ?? 'auto',
|
|
64
56
|
style: this.relative ?? 'long',
|
|
65
57
|
})(moment, now);
|
|
@@ -87,6 +79,7 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
87
79
|
}
|
|
88
80
|
if (changed.has('date') ||
|
|
89
81
|
changed.has('elapsed') ||
|
|
82
|
+
changed.has('frozen') ||
|
|
90
83
|
changed.has('locale') ||
|
|
91
84
|
changed.has('numeric') ||
|
|
92
85
|
changed.has('relative')) {
|
|
@@ -115,18 +108,18 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
115
108
|
}
|
|
116
109
|
const datetime = this.dateOnly ? (this.date || this.written).trim() : moment.toISOString();
|
|
117
110
|
if (!this.reading) {
|
|
118
|
-
const text = new Intl.DateTimeFormat(this.
|
|
111
|
+
const text = new Intl.DateTimeFormat(this.language || undefined, this.options).format(moment);
|
|
119
112
|
return html `<time part="time" datetime=${datetime}>${text}</time>`;
|
|
120
113
|
}
|
|
121
114
|
const now = new Date(this.clock.now);
|
|
122
115
|
const zone = this.timeZone || (this.dateOnly ? 'UTC' : undefined);
|
|
123
|
-
const whole = new Intl.DateTimeFormat(this.
|
|
116
|
+
const whole = new Intl.DateTimeFormat(this.language || undefined, {
|
|
124
117
|
dateStyle: 'long',
|
|
125
118
|
...(this.dateOnly ? {} : { timeStyle: 'short' }),
|
|
126
119
|
...(this.hourCycle ? { hourCycle: this.hourCycle } : {}),
|
|
127
120
|
...(zone ? { timeZone: zone } : {}),
|
|
128
121
|
}).format(moment);
|
|
129
|
-
const spoken = relativeTime(this.
|
|
122
|
+
const spoken = relativeTime(this.language, { numeric: this.numeric ?? 'auto' })(moment, now).text;
|
|
130
123
|
return html `<time
|
|
131
124
|
part="time"
|
|
132
125
|
datetime=${datetime}
|
|
@@ -150,6 +143,9 @@ __decorate([
|
|
|
150
143
|
__decorate([
|
|
151
144
|
property()
|
|
152
145
|
], HelixHeadlessFormatDate.prototype, "era", void 0);
|
|
146
|
+
__decorate([
|
|
147
|
+
property({ type: Boolean })
|
|
148
|
+
], HelixHeadlessFormatDate.prototype, "frozen", void 0);
|
|
153
149
|
__decorate([
|
|
154
150
|
property()
|
|
155
151
|
], HelixHeadlessFormatDate.prototype, "hour", void 0);
|
|
@@ -57,3 +57,24 @@ export declare const toneOf: (reading: Reading, thresholds: readonly number[], t
|
|
|
57
57
|
* the tail slice aligned.
|
|
58
58
|
*/
|
|
59
59
|
export declare const fits: (total: number, width: number, minimum: number, gap: number, rows?: number) => number;
|
|
60
|
+
/** What the drawn readings come to: where the busiest stands, and their total. */
|
|
61
|
+
export interface Overview {
|
|
62
|
+
/** The place of the busiest reading, the first where several tie, or -1 with none. */
|
|
63
|
+
busiest: number;
|
|
64
|
+
/** The sum of every reading, blanks counting nothing. */
|
|
65
|
+
total: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The busiest reading among `cells` and the total of them all, for the
|
|
69
|
+
* strip's `overview`. A blank cell is passed over.
|
|
70
|
+
*/
|
|
71
|
+
export declare const overviewOf: (cells: readonly Reading[]) => Overview;
|
|
72
|
+
/**
|
|
73
|
+
* Where a page of a calendar goes from the reading at `at`: the same day a
|
|
74
|
+
* month on, or a month back, by the dates the readings carry, written
|
|
75
|
+
* `YYYY-MM-DD` as a `<time datetime>` gives them. A day the month lacks,
|
|
76
|
+
* such as the 31st, is the month's last. Where that day has no reading, the
|
|
77
|
+
* nearest one past it in the direction of travel, and the last or the first
|
|
78
|
+
* reading past the end. Undefined where the reading at `at` carries no date.
|
|
79
|
+
*/
|
|
80
|
+
export declare const monthPage: (whens: readonly (string | undefined)[], at: number, forward: boolean) => number | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extremesOf } from '@fusion.dev/helix-core';
|
|
1
2
|
export const toneOf = (reading, thresholds, tones) => {
|
|
2
3
|
if (reading.tone) {
|
|
3
4
|
return reading.tone;
|
|
@@ -24,3 +25,36 @@ export const fits = (total, width, minimum, gap, rows = 1) => {
|
|
|
24
25
|
const columns = Math.max(1, Math.floor((width + gap) / (minimum + gap)));
|
|
25
26
|
return Math.min(total, columns * Math.max(1, rows));
|
|
26
27
|
};
|
|
28
|
+
export const overviewOf = (cells) => {
|
|
29
|
+
const values = cells.map((cell) => cell.value);
|
|
30
|
+
return {
|
|
31
|
+
busiest: extremesOf(values).high ?? -1,
|
|
32
|
+
total: values.reduce((sum, value) => sum + (value ?? 0), 0),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const dayOf = (when) => {
|
|
36
|
+
const found = /^(\d{4})-(\d{2})-(\d{2})/.exec(when ?? '');
|
|
37
|
+
return found
|
|
38
|
+
? Date.UTC(Number(found[1]), Number(found[2]) - 1, Number(found[3])) / 86_400_000
|
|
39
|
+
: undefined;
|
|
40
|
+
};
|
|
41
|
+
export const monthPage = (whens, at, forward) => {
|
|
42
|
+
const from = dayOf(whens[at]);
|
|
43
|
+
if (from === undefined) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const date = new Date(from * 86_400_000);
|
|
47
|
+
const month = date.getUTCMonth() + (forward ? 1 : -1);
|
|
48
|
+
const last = new Date(Date.UTC(date.getUTCFullYear(), month + 1, 0)).getUTCDate();
|
|
49
|
+
const target = Date.UTC(date.getUTCFullYear(), month, Math.min(date.getUTCDate(), last)) / 86_400_000;
|
|
50
|
+
const days = whens.map(dayOf);
|
|
51
|
+
const order = days.map((_, index) => index);
|
|
52
|
+
const past = (forward ? order : order.reverse()).find((index) => {
|
|
53
|
+
const day = days[index];
|
|
54
|
+
return day !== undefined && (forward ? day >= target : day <= target);
|
|
55
|
+
});
|
|
56
|
+
if (past !== undefined) {
|
|
57
|
+
return past;
|
|
58
|
+
}
|
|
59
|
+
return forward ? whens.length - 1 : 0;
|
|
60
|
+
};
|
|
@@ -31,14 +31,24 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
|
|
|
31
31
|
* down arrows move a cell, the left and right arrows move a column, which is a
|
|
32
32
|
* week with `rows="7"`, and Home and End go to the first and the last. The
|
|
33
33
|
* tooltip follows, the `live` part says the cell's row in words, and Escape
|
|
34
|
-
* puts the tooltip away. PageUp and PageDown move
|
|
35
|
-
*
|
|
34
|
+
* puts the tooltip away. PageUp and PageDown move a month, to the same day,
|
|
35
|
+
* where each row's header carries its date as a `<time datetime>`, and four
|
|
36
|
+
* columns otherwise, which is four weeks with `rows="7"`.
|
|
36
37
|
*
|
|
37
38
|
* **The strip describes itself.** The `overview` part says the busiest
|
|
38
|
-
* reading and the total of the readings drawn, "Busiest: 11 Jun 12; Total
|
|
39
|
+
* reading and the total of the readings drawn, "Busiest: 11 Jun, 12; Total
|
|
39
40
|
* 84", and the strip is described by it, as every chart is by its summary.
|
|
40
41
|
* Hide it visually. The `summary` slot is still yours, for words of your own.
|
|
41
42
|
*
|
|
43
|
+
* **`selection-mode` lets a reader select cells**: `single` one at a time and
|
|
44
|
+
* `multiple` any number. Space, Enter or a press selects the cell the keys or
|
|
45
|
+
* the pointer rest on, or lets it go, and under `multiple` Shift with an arrow,
|
|
46
|
+
* Home, End, PageUp or PageDown takes in every cell from the last one pressed
|
|
47
|
+
* to where the key went. `value` holds the selected days, by the names their
|
|
48
|
+
* rows have in the table, separated by commas. A change asks with
|
|
49
|
+
* `helix-before-change` and tells with `change`, and the `selection` part says
|
|
50
|
+
* how many are selected, in `selection-label`.
|
|
51
|
+
*
|
|
42
52
|
* @since 0.1.0
|
|
43
53
|
* @status stable
|
|
44
54
|
* @category charts
|
|
@@ -49,16 +59,20 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
|
|
|
49
59
|
* @slot start - Below the strip, at the leading edge: usually the oldest date.
|
|
50
60
|
* @slot summary - Below the strip, in the middle: a summary of the range shown.
|
|
51
61
|
*
|
|
62
|
+
* @event {Event} change - Fired once a press or a key has changed which cells are selected.
|
|
63
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a press or a key changes which cells are selected, with the `value` it would leave. Cancelable.
|
|
52
64
|
* @event {HelixResizeEvent} helix-resize - Fired when the number of cells drawn changes, with the new number.
|
|
53
65
|
*
|
|
54
66
|
* @csspart cell - One reading.
|
|
55
67
|
* @csspart cell-active - The cell the pointer or the keys rest on. Set alongside `cell`.
|
|
68
|
+
* @csspart cell-selected - A cell that is selected, under `selection-mode`. Set alongside `cell`.
|
|
56
69
|
* @csspart empty - Shown when the table has no readings. It stays hidden until the table can be read: on the server and during hydration, there is no document to resolve `for` in.
|
|
57
70
|
* @csspart end - The trailing slot's box.
|
|
58
71
|
* @csspart footer - The three-slot row under the strip.
|
|
59
72
|
* @csspart live - The readout: a polite live region that says the cell the keys moved to. Hide it visually.
|
|
60
73
|
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
61
74
|
* @csspart overview - The busiest reading and the total of the readings drawn, written as a sentence for screen readers, which describes the strip. Rendered once there are cells. Hide it visually.
|
|
75
|
+
* @csspart selection - A polite region that says how many cells are selected after a change, rendered from the first change. Hide it visually.
|
|
62
76
|
* @csspart start - The leading slot's box.
|
|
63
77
|
* @csspart strip - The grid of cells, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
64
78
|
* @csspart summary - The middle slot's box.
|
|
@@ -141,6 +155,17 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
141
155
|
* days.
|
|
142
156
|
*/
|
|
143
157
|
rows: number;
|
|
158
|
+
/**
|
|
159
|
+
* What the `selection` part says after the selection changes, with `{count}` for
|
|
160
|
+
* how many cells are selected.
|
|
161
|
+
*/
|
|
162
|
+
selectionLabel: string;
|
|
163
|
+
/**
|
|
164
|
+
* How many cells a reader can select: `single` or `multiple`.
|
|
165
|
+
*
|
|
166
|
+
* Absent selects nothing, and a press or Space does what it did.
|
|
167
|
+
*/
|
|
168
|
+
selectionMode?: 'multiple' | 'single';
|
|
144
169
|
/**
|
|
145
170
|
* Lower bounds for the tone buckets, in the order the tones are given.
|
|
146
171
|
*
|
|
@@ -167,6 +192,14 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
167
192
|
* The word the `overview` puts before the total of the readings drawn.
|
|
168
193
|
*/
|
|
169
194
|
totalLabel: string;
|
|
195
|
+
/**
|
|
196
|
+
* The selected cells, by the names their rows have in the table, such as
|
|
197
|
+
* `2026-06-11`, separated by commas.
|
|
198
|
+
*
|
|
199
|
+
* Set it to start with cells selected. Written by a press or a key under
|
|
200
|
+
* `selection-mode`.
|
|
201
|
+
*/
|
|
202
|
+
value: string;
|
|
170
203
|
/**
|
|
171
204
|
* How many cells are actually drawn.
|
|
172
205
|
*
|
|
@@ -215,6 +248,28 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
215
248
|
protected readonly aria: AriaForwardController;
|
|
216
249
|
private observer;
|
|
217
250
|
private announced;
|
|
251
|
+
/** Where a range taken in with Shift starts: the cell last pressed, or none. */
|
|
252
|
+
private anchor;
|
|
253
|
+
/** The region a change of selection is said in, rendered from the first change. */
|
|
254
|
+
private readonly status;
|
|
255
|
+
/** The name each drawn cell stands for in `value`: its row's name in the table. */
|
|
256
|
+
private keysOf;
|
|
257
|
+
/**
|
|
258
|
+
* Moves `value` to `next`, asking first: `helix-before-change` carries it,
|
|
259
|
+
* a listener that refuses keeps the selection, and `change` follows, with
|
|
260
|
+
* the count said in the `selection` part.
|
|
261
|
+
*/
|
|
262
|
+
private choose;
|
|
263
|
+
/** Selects the drawn cell at `index`, or lets it go, as `selection-mode` says. */
|
|
264
|
+
private press;
|
|
265
|
+
/**
|
|
266
|
+
* Space and Enter select the cell the keys rest on, and Shift with a key
|
|
267
|
+
* that moved them takes in the range from the anchor. After the pointer
|
|
268
|
+
* controller, which has already moved `at` for an arrow.
|
|
269
|
+
*/
|
|
270
|
+
private readonly onKeydown;
|
|
271
|
+
/** A press on a cell selects it, under `selection-mode`. */
|
|
272
|
+
private readonly onClick;
|
|
218
273
|
/**
|
|
219
274
|
* Every row in the table, oldest first, as the table is written, with its
|
|
220
275
|
* reading where the row has one.
|
|
@@ -304,6 +359,12 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
304
359
|
* the reason `BarChart` gives: SSR calls this one.
|
|
305
360
|
*/
|
|
306
361
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
362
|
+
/**
|
|
363
|
+
* Where PageUp or PageDown goes from the drawn cell at `at`: the same day a
|
|
364
|
+
* month on or back, by the dates the rows' headers carry. Undefined where
|
|
365
|
+
* they carry none, and the keys move four columns.
|
|
366
|
+
*/
|
|
367
|
+
pageFrom(at: number, forward: boolean): number | undefined;
|
|
307
368
|
connectedCallback(): void;
|
|
308
369
|
disconnectedCallback(): void;
|
|
309
370
|
/**
|