@fusion.dev/helix-headless 0.145.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 +12286 -4281
- package/dist/accordion/item/accordion-item.d.ts +51 -18
- package/dist/accordion/item/accordion-item.js +45 -13
- package/dist/accordion/root/accordion-root.d.ts +16 -7
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +16 -6
- package/dist/announcement/root/announcement-root.js +37 -7
- package/dist/app-header/root/app-header-root.d.ts +7 -2
- package/dist/app-header/root/app-header-root.js +9 -1
- package/dist/app-header/sectioning.d.ts +3 -1
- package/dist/app-header/sectioning.js +3 -2
- 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/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- 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 +60 -7
- package/dist/badge/root/badge-root.js +89 -6
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +48 -20
- package/dist/bar-chart/stack.d.ts +25 -0
- package/dist/bar-chart/stack.js +27 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +51 -4
- package/dist/button/root/button-root.d.ts +50 -38
- package/dist/button/root/button-root.js +42 -53
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/root/button-group-root.d.ts +2 -1
- package/dist/button-group/root/button-group-root.js +5 -1
- package/dist/canvas/node/canvas-node.d.ts +4 -3
- package/dist/canvas/node/canvas-node.js +3 -2
- package/dist/canvas/root/canvas-root.js +2 -2
- package/dist/card/root/card-root.d.ts +36 -4
- package/dist/card/root/card-root.js +29 -10
- package/dist/carousel/root/carousel-root.d.ts +43 -4
- package/dist/carousel/root/carousel-root.js +40 -12
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- package/dist/chat/message/chat-message.js +5 -4
- package/dist/chat/naming.d.ts +5 -1
- package/dist/chat/naming.js +4 -2
- package/dist/chat/root/chat-root.d.ts +40 -4
- package/dist/chat/root/chat-root.js +32 -6
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +18 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +14 -11
- package/dist/checkbox-group/select-all.d.ts +21 -0
- package/dist/checkbox-group/select-all.js +7 -0
- package/dist/code-block/highlight.d.ts +15 -0
- package/dist/code-block/highlight.js +4 -0
- package/dist/code-block/root/code-block-root.d.ts +79 -10
- package/dist/code-block/root/code-block-root.js +74 -5
- package/dist/color-input/root/color-input-root.d.ts +14 -0
- package/dist/color-input/root/color-input-root.js +17 -7
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +53 -16
- package/dist/color-picker/root/color-picker-root.js +155 -46
- 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 +56 -0
- package/dist/combobox/root/combobox-root.js +92 -15
- package/dist/command/root/command-root.d.ts +19 -2
- package/dist/command/root/command-root.js +24 -23
- package/dist/copy-button/root/copy-button-root.d.ts +21 -1
- package/dist/copy-button/root/copy-button-root.js +16 -4
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +6 -0
- package/dist/data-table/keys.js +14 -0
- package/dist/data-table/root/data-table-root.d.ts +27 -18
- package/dist/data-table/root/data-table-root.js +31 -57
- package/dist/data-table/tree.d.ts +16 -1
- package/dist/data-table/tree.js +2 -3
- package/dist/date-input/root/date-input-root.d.ts +11 -2
- package/dist/date-input/root/date-input-root.js +26 -12
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +33 -22
- 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/dialog/description.js +15 -1
- package/dist/dialog/root/dialog-root.d.ts +8 -2
- package/dist/dialog/root/dialog-root.js +16 -1
- package/dist/divider/root/divider-root.d.ts +3 -0
- package/dist/divider/root/divider-root.js +2 -1
- package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
- package/dist/donut-chart/root/donut-chart-root.js +55 -1
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +75 -4
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +40 -5
- package/dist/drilldown/root/drilldown-root.d.ts +21 -3
- package/dist/drilldown/root/drilldown-root.js +22 -3
- package/dist/element-events.generated.js +35 -6
- package/dist/empty/root/empty-root.d.ts +34 -2
- package/dist/empty/root/empty-root.js +26 -4
- package/dist/file-input/root/file-input-root.d.ts +99 -8
- package/dist/file-input/root/file-input-root.js +120 -22
- package/dist/file-input/screen.d.ts +2 -1
- 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/menu/filter-menu.d.ts +2 -0
- package/dist/filter-input/menu/filter-menu.js +12 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -6
- package/dist/filter-input/root/filter-input-root.js +18 -28
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- 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 +27 -17
- package/dist/format-date/root/format-date-root.js +27 -48
- 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 +83 -11
- package/dist/heatmap/root/heatmap-root.js +104 -12
- 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 +25 -1
- package/dist/icon/root/icon-root.js +44 -12
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/icon/settle.d.ts +7 -0
- package/dist/icon/settle.js +10 -0
- package/dist/icon-button/root/icon-button-root.d.ts +2 -0
- package/dist/image/root/image-root.d.ts +14 -1
- package/dist/image/root/image-root.js +7 -2
- package/dist/input/root/input-root.d.ts +34 -3
- package/dist/input/root/input-root.js +17 -4
- package/dist/kbd/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +52 -1
- package/dist/kbd/root/kbd-root.js +40 -47
- 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 +77 -12
- package/dist/legend/root/legend-root.js +71 -17
- package/dist/lightbox/root/lightbox-root.d.ts +98 -10
- package/dist/lightbox/root/lightbox-root.js +153 -18
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +24 -0
- package/dist/lightbox/zoom.js +18 -0
- package/dist/line-chart/root/line-chart-root.d.ts +38 -1
- package/dist/line-chart/root/line-chart-root.js +31 -3
- package/dist/list/item/list-item.d.ts +2 -0
- package/dist/list/item/list-item.js +11 -2
- package/dist/list/root/list-root.d.ts +70 -13
- package/dist/list/root/list-root.js +91 -13
- package/dist/list/selection.d.ts +54 -7
- package/dist/list/selection.js +32 -7
- package/dist/listbox/root/listbox-root.d.ts +44 -4
- package/dist/listbox/root/listbox-root.js +72 -34
- package/dist/loader/busy.d.ts +10 -0
- package/dist/loader/busy.js +11 -0
- package/dist/loader/root/loader-root.d.ts +9 -2
- package/dist/loader/root/loader-root.js +23 -3
- 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 +80 -15
- package/dist/megamenu/root/megamenu-root.js +76 -19
- package/dist/menu/item/menu-item.d.ts +51 -2
- package/dist/menu/item/menu-item.js +50 -26
- package/dist/menu/root/menu-root.d.ts +17 -0
- package/dist/menu/root/menu-root.js +2 -2
- package/dist/meter/root/meter-root.d.ts +62 -1
- package/dist/meter/root/meter-root.js +38 -16
- package/dist/navigation/root/navigation-root.d.ts +2 -1
- package/dist/navigation/root/navigation-root.js +2 -2
- package/dist/notifications/root/notifications-root.d.ts +20 -4
- package/dist/notifications/root/notifications-root.js +30 -8
- 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 +34 -9
- package/dist/number-input/root/number-input-root.js +31 -25
- package/dist/object-inspector/root/object-inspector-root.d.ts +88 -33
- package/dist/object-inspector/root/object-inspector-root.js +134 -92
- package/dist/object-inspector/rows.d.ts +18 -0
- package/dist/object-inspector/rows.js +33 -0
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/root/option-root.d.ts +5 -3
- 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 +30 -0
- package/dist/outline/root/outline-root.js +17 -13
- 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 +37 -0
- package/dist/pin-input/code.js +25 -0
- package/dist/pin-input/root/pin-input-root.d.ts +116 -115
- package/dist/pin-input/root/pin-input-root.js +163 -155
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +34 -0
- package/dist/popover/root/popover-root.d.ts +64 -8
- package/dist/popover/root/popover-root.js +67 -4
- package/dist/progress/root/progress-root.d.ts +47 -0
- package/dist/progress/root/progress-root.js +34 -16
- package/dist/qr-code/export.d.ts +45 -1
- package/dist/qr-code/export.js +28 -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 +36 -11
- package/dist/qr-code/root/qr-code-root.js +58 -11
- package/dist/quote/marks.d.ts +8 -0
- package/dist/quote/marks.js +5 -0
- package/dist/quote/root/quote-root.d.ts +14 -2
- package/dist/quote/root/quote-root.js +23 -1
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +7 -2
- package/dist/rating/root/rating-root.d.ts +30 -12
- package/dist/rating/root/rating-root.js +27 -27
- package/dist/scatter-chart/fit.d.ts +15 -0
- package/dist/scatter-chart/fit.js +35 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +51 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +64 -24
- package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
- package/dist/scroll-area/root/scroll-area-root.js +57 -173
- package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
- package/dist/scroll-area/scrollbar-controller.js +172 -0
- package/dist/scroll-area/scrollbar.d.ts +27 -8
- package/dist/scroll-area/scrollbar.js +10 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +71 -0
- package/dist/select/root/select-root.js +78 -6
- package/dist/skeleton/root/skeleton-root.d.ts +3 -0
- package/dist/skeleton/root/skeleton-root.js +4 -2
- package/dist/skip-link/root/skip-link-root.js +2 -2
- package/dist/slider/root/slider-root.d.ts +59 -5
- package/dist/slider/root/slider-root.js +45 -3
- package/dist/sparkline/readings.d.ts +36 -0
- package/dist/sparkline/readings.js +36 -0
- package/dist/sparkline/root/sparkline-root.d.ts +121 -7
- package/dist/sparkline/root/sparkline-root.js +160 -26
- 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 +11 -3
- package/dist/splitter/root/splitter-root.d.ts +10 -12
- package/dist/splitter/root/splitter-root.js +211 -204
- package/dist/stat/root/stat-root.d.ts +14 -5
- package/dist/stat/root/stat-root.js +21 -5
- package/dist/steps/reach.d.ts +5 -0
- package/dist/steps/reach.js +3 -0
- package/dist/steps/root/steps-root.d.ts +56 -3
- package/dist/steps/root/steps-root.js +50 -6
- package/dist/steps/step/step.d.ts +8 -0
- package/dist/steps/step/step.js +8 -3
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +6 -10
- package/dist/table/column/table-column.js +8 -20
- package/dist/table/root/table-root.d.ts +31 -10
- package/dist/table/root/table-root.js +14 -18
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- package/dist/tabs/panel/tab-panel.d.ts +16 -3
- package/dist/tabs/panel/tab-panel.js +34 -5
- package/dist/tabs/root/tabs-root.d.ts +17 -3
- package/dist/tabs/root/tabs-root.js +1 -1
- package/dist/tabs/tab/tab.d.ts +5 -0
- package/dist/tabs/tab/tab.js +5 -2
- package/dist/tag/group/tag-group.d.ts +44 -5
- package/dist/tag/group/tag-group.js +60 -9
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +41 -2
- package/dist/textarea/root/textarea-root.js +39 -1
- package/dist/time-input/root/time-input-root.d.ts +10 -2
- package/dist/time-input/root/time-input-root.js +24 -13
- package/dist/time-picker/root/time-picker-root.d.ts +28 -17
- package/dist/time-picker/root/time-picker-root.js +18 -29
- package/dist/time-picker/wheel-name.d.ts +9 -0
- package/dist/time-picker/wheel-name.js +15 -0
- package/dist/timeline/group/timeline-group.js +2 -2
- package/dist/toast/item/toast-item.d.ts +16 -3
- package/dist/toast/item/toast-item.js +22 -6
- package/dist/toast/root/toast-root.d.ts +34 -4
- package/dist/toast/root/toast-root.js +74 -13
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +52 -7
- package/dist/toggle/group/toggle-group.js +58 -44
- 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 +20 -3
- package/dist/tooltip/root/tooltip-root.js +18 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +45 -2
- package/dist/tour/root/tour-root.js +53 -8
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/item/tree-item.d.ts +7 -3
- package/dist/tree/item/tree-item.js +3 -0
- package/dist/tree/root/tree-root.d.ts +24 -3
- package/dist/tree/root/tree-root.js +32 -13
- package/dist/tree/selection.js +2 -15
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +83 -19
- package/dist/trend/root/trend-root.js +59 -8
- package/dist/video/media-events.d.ts +13 -18
- package/dist/video/media-events.js +1 -5
- 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 +23 -6
- package/dist/video/root/video-root.js +19 -10
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +17 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -8
- package/dist/virtual-list/fill.js +10 -17
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +65 -0
- package/dist/virtual-list/plan.js +27 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +136 -13
- package/dist/virtual-list/root/virtual-list-root.js +218 -51
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +7441 -1458
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1501 -326
- package/dist/chat/relative-clock.d.ts +0 -39
- package/dist/chat/relative-clock.js +0 -31
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -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
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../tooltip/index.js';
|
|
4
|
+
import { type Reading } from './buckets.js';
|
|
4
5
|
declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartSourceInterface);
|
|
5
6
|
/**
|
|
6
7
|
* @summary A strip of cells, each colored by its reading, for uptime, contributions, or activity.
|
|
@@ -30,7 +31,23 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
|
|
|
30
31
|
* down arrows move a cell, the left and right arrows move a column, which is a
|
|
31
32
|
* week with `rows="7"`, and Home and End go to the first and the last. The
|
|
32
33
|
* tooltip follows, the `live` part says the cell's row in words, and Escape
|
|
33
|
-
* puts the tooltip away.
|
|
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"`.
|
|
37
|
+
*
|
|
38
|
+
* **The strip describes itself.** The `overview` part says the busiest
|
|
39
|
+
* reading and the total of the readings drawn, "Busiest: 11 Jun, 12; Total
|
|
40
|
+
* 84", and the strip is described by it, as every chart is by its summary.
|
|
41
|
+
* Hide it visually. The `summary` slot is still yours, for words of your own.
|
|
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`.
|
|
34
51
|
*
|
|
35
52
|
* @since 0.1.0
|
|
36
53
|
* @status stable
|
|
@@ -42,15 +59,20 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
|
|
|
42
59
|
* @slot start - Below the strip, at the leading edge: usually the oldest date.
|
|
43
60
|
* @slot summary - Below the strip, in the middle: a summary of the range shown.
|
|
44
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.
|
|
45
64
|
* @event {HelixResizeEvent} helix-resize - Fired when the number of cells drawn changes, with the new number.
|
|
46
65
|
*
|
|
47
66
|
* @csspart cell - One reading.
|
|
48
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`.
|
|
49
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.
|
|
50
70
|
* @csspart end - The trailing slot's box.
|
|
51
71
|
* @csspart footer - The three-slot row under the strip.
|
|
52
72
|
* @csspart live - The readout: a polite live region that says the cell the keys moved to. Hide it visually.
|
|
53
73
|
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
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.
|
|
54
76
|
* @csspart start - The leading slot's box.
|
|
55
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.
|
|
56
78
|
* @csspart summary - The middle slot's box.
|
|
@@ -87,6 +109,10 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
|
|
|
87
109
|
* @cssproperty --heatmap-tone-warning - The color of the `warning` tone.
|
|
88
110
|
*/
|
|
89
111
|
export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
112
|
+
/**
|
|
113
|
+
* The word the `overview` puts before the busiest reading.
|
|
114
|
+
*/
|
|
115
|
+
busiestLabel: string;
|
|
90
116
|
/**
|
|
91
117
|
* Shown when the table has no readings in it.
|
|
92
118
|
*
|
|
@@ -129,6 +155,17 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
129
155
|
* days.
|
|
130
156
|
*/
|
|
131
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';
|
|
132
169
|
/**
|
|
133
170
|
* Lower bounds for the tone buckets, in the order the tones are given.
|
|
134
171
|
*
|
|
@@ -151,6 +188,18 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
151
188
|
* no order in it.
|
|
152
189
|
*/
|
|
153
190
|
tones: string;
|
|
191
|
+
/**
|
|
192
|
+
* The word the `overview` puts before the total of the readings drawn.
|
|
193
|
+
*/
|
|
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;
|
|
154
203
|
/**
|
|
155
204
|
* How many cells are actually drawn.
|
|
156
205
|
*
|
|
@@ -197,20 +246,30 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
197
246
|
* image a reader lands on. The host is a generic around it.
|
|
198
247
|
*/
|
|
199
248
|
protected readonly aria: AriaForwardController;
|
|
249
|
+
private observer;
|
|
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;
|
|
200
257
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* belongs to the platform.
|
|
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.
|
|
205
261
|
*/
|
|
206
|
-
|
|
262
|
+
private choose;
|
|
263
|
+
/** Selects the drawn cell at `index`, or lets it go, as `selection-mode` says. */
|
|
264
|
+
private press;
|
|
207
265
|
/**
|
|
208
|
-
*
|
|
209
|
-
*
|
|
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.
|
|
210
269
|
*/
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
private
|
|
270
|
+
private readonly onKeydown;
|
|
271
|
+
/** A press on a cell selects it, under `selection-mode`. */
|
|
272
|
+
private readonly onClick;
|
|
214
273
|
/**
|
|
215
274
|
* Every row in the table, oldest first, as the table is written, with its
|
|
216
275
|
* reading where the row has one.
|
|
@@ -300,6 +359,12 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
300
359
|
* the reason `BarChart` gives: SSR calls this one.
|
|
301
360
|
*/
|
|
302
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;
|
|
303
368
|
connectedCallback(): void;
|
|
304
369
|
disconnectedCallback(): void;
|
|
305
370
|
/**
|
|
@@ -314,6 +379,13 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
314
379
|
private markEmpty;
|
|
315
380
|
protected updated(changed: PropertyValues): void;
|
|
316
381
|
protected render(): TemplateResult;
|
|
382
|
+
/**
|
|
383
|
+
* What the strip shows, in a sentence: the busiest reading drawn, as the
|
|
384
|
+
* table writes it, and the total of them all, in `locale`. The strip is
|
|
385
|
+
* described by it, so a reader landing on the strip hears what it holds
|
|
386
|
+
* before walking it.
|
|
387
|
+
*/
|
|
388
|
+
protected renderOverview(cells: Reading[]): TemplateResult;
|
|
317
389
|
/**
|
|
318
390
|
* The bubble over the cell a pointer is resting on.
|
|
319
391
|
*
|
|
@@ -4,20 +4,24 @@ 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, byRow, CHART_PLOT, customElement, drawTooltip, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, byRow, CHART_PLOT, commaList, customElement, drawTooltip, fillTemplate, formatNumbers, HelixBeforeChangeEvent, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, pressedValue, rangeAdd, requestChange, StatusController, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
11
|
-
import { fits, toneOf } from './buckets.js';
|
|
11
|
+
import { fits, monthPage, overviewOf, toneOf } from './buckets.js';
|
|
12
12
|
let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(HelixElement) {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
|
+
this.busiestLabel = 'Busiest';
|
|
15
16
|
this.emptyText = 'No readings';
|
|
16
17
|
this.gap = 2;
|
|
17
18
|
this.minCell = 8;
|
|
18
19
|
this.rows = 1;
|
|
20
|
+
this.selectionLabel = '{count} selected';
|
|
19
21
|
this.thresholds = '';
|
|
20
22
|
this.tones = '';
|
|
23
|
+
this.totalLabel = 'Total';
|
|
24
|
+
this.value = '';
|
|
21
25
|
this.width = undefined;
|
|
22
26
|
this.metrics = undefined;
|
|
23
27
|
this.aria = new AriaForwardController(this, {
|
|
@@ -25,6 +29,35 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
25
29
|
});
|
|
26
30
|
this.observer = undefined;
|
|
27
31
|
this.announced = undefined;
|
|
32
|
+
this.anchor = -1;
|
|
33
|
+
this.status = new StatusController(this);
|
|
34
|
+
this.onKeydown = (event) => {
|
|
35
|
+
const at = this.pointer.at;
|
|
36
|
+
if (!this.selectionMode || at < 0 || event.altKey || event.ctrlKey || event.metaKey) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
this.press(at);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const moves = /^(Arrow|Page|Home$|End$)/.test(event.key);
|
|
45
|
+
if (!event.shiftKey || !moves || this.selectionMode !== 'multiple') {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const keys = this.keysOf(this.drawn);
|
|
49
|
+
const added = rangeAdd(commaList(this.value), keys, this.anchor < 0 ? at : this.anchor, at);
|
|
50
|
+
if (added) {
|
|
51
|
+
this.choose(added.join(', '));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
this.onClick = (event) => {
|
|
55
|
+
const cell = event.target?.closest?.('[part~="cell"]');
|
|
56
|
+
const index = Number(cell?.getAttribute('data-index') ?? -1);
|
|
57
|
+
if (cell && Number.isInteger(index) && index >= 0) {
|
|
58
|
+
this.press(index);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
28
61
|
this.onPointerOver = (event) => {
|
|
29
62
|
if (!this.pointer.accepts(event)) {
|
|
30
63
|
return;
|
|
@@ -42,14 +75,34 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
42
75
|
get visible() {
|
|
43
76
|
return Math.min(this.points.length, this.room);
|
|
44
77
|
}
|
|
45
|
-
|
|
46
|
-
|
|
78
|
+
keysOf(cells) {
|
|
79
|
+
const offset = this.points.length - cells.length;
|
|
80
|
+
const rows = this.sourceRows;
|
|
81
|
+
return cells.map((_, index) => rows[offset + index]?.label ?? '');
|
|
82
|
+
}
|
|
83
|
+
choose(next) {
|
|
84
|
+
if (next === this.value) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
requestChange({
|
|
88
|
+
apply: (value) => {
|
|
89
|
+
this.value = value;
|
|
90
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
91
|
+
this.status.say(fillTemplate(this.selectionLabel, { count: commaList(value).length }));
|
|
92
|
+
},
|
|
93
|
+
event: (value) => new HelixBeforeChangeEvent({ value }),
|
|
94
|
+
host: this,
|
|
95
|
+
next,
|
|
96
|
+
});
|
|
47
97
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
98
|
+
press(index) {
|
|
99
|
+
const mode = this.selectionMode;
|
|
100
|
+
const key = this.keysOf(this.drawn)[index];
|
|
101
|
+
if (!mode || key === undefined || key === '') {
|
|
102
|
+
return;
|
|
52
103
|
}
|
|
104
|
+
this.anchor = index;
|
|
105
|
+
this.choose(pressedValue(mode, this.value, key));
|
|
53
106
|
}
|
|
54
107
|
get points() {
|
|
55
108
|
const series = this.series[0];
|
|
@@ -106,8 +159,13 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
106
159
|
super.willUpdate(changed);
|
|
107
160
|
this.pointer.grid = this.rowCount;
|
|
108
161
|
}
|
|
162
|
+
pageFrom(at, forward) {
|
|
163
|
+
const offset = this.points.length - this.drawn.length;
|
|
164
|
+
return monthPage(this.sourceRows.slice(offset).map((row) => row.when), at, forward);
|
|
165
|
+
}
|
|
109
166
|
connectedCallback() {
|
|
110
167
|
super.connectedCallback();
|
|
168
|
+
this.addEventListener('keydown', this.onKeydown);
|
|
111
169
|
if (typeof ResizeObserver !== 'undefined') {
|
|
112
170
|
this.observer = new ResizeObserver((entries) => {
|
|
113
171
|
const measured = entries[0]?.contentRect.width;
|
|
@@ -120,6 +178,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
120
178
|
}
|
|
121
179
|
disconnectedCallback() {
|
|
122
180
|
super.disconnectedCallback();
|
|
181
|
+
this.removeEventListener('keydown', this.onKeydown);
|
|
123
182
|
this.observer?.disconnect();
|
|
124
183
|
this.observer = undefined;
|
|
125
184
|
}
|
|
@@ -150,13 +209,17 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
150
209
|
const palette = writtenList(this.tones);
|
|
151
210
|
const cells = this.drawn;
|
|
152
211
|
const readable = cells.length > 0;
|
|
212
|
+
const keys = this.selectionMode ? this.keysOf(cells) : [];
|
|
213
|
+
const chosen = new Set(this.selectionMode ? commaList(this.value) : []);
|
|
153
214
|
return html `<div
|
|
154
|
-
aria-
|
|
215
|
+
aria-describedby=${readable ? 'helix-chart-summary' : nothing}
|
|
216
|
+
aria-label=${this.named || 'Heatmap'}
|
|
155
217
|
part="strip"
|
|
156
218
|
id=${CHART_PLOT}
|
|
157
219
|
role=${readable ? 'application' : 'img'}
|
|
158
220
|
style="--heatmap-rows: ${this.rowCount}"
|
|
159
221
|
tabindex=${readable ? '0' : nothing}
|
|
222
|
+
@click=${this.onClick}
|
|
160
223
|
@pointerover=${this.onPointerOver}
|
|
161
224
|
@pointerleave=${this.onPointerLeave}
|
|
162
225
|
>
|
|
@@ -165,13 +228,14 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
165
228
|
: cells.map((reading, index) => {
|
|
166
229
|
const tone = toneOf(reading, bounds, palette);
|
|
167
230
|
const active = this.pointer.at === index;
|
|
231
|
+
const picked = chosen.has(keys[index] ?? '');
|
|
168
232
|
return tone === undefined
|
|
169
233
|
? html `<span
|
|
170
|
-
part="cell${active ? ' cell-active' : ''}"
|
|
234
|
+
part="cell${active ? ' cell-active' : ''}${picked ? ' cell-selected' : ''}"
|
|
171
235
|
data-index=${index}
|
|
172
236
|
></span>`
|
|
173
237
|
: html `<span
|
|
174
|
-
part="cell${active ? ' cell-active' : ''}"
|
|
238
|
+
part="cell${active ? ' cell-active' : ''}${picked ? ' cell-selected' : ''}"
|
|
175
239
|
data-index=${index}
|
|
176
240
|
data-tone=${tone}
|
|
177
241
|
style="--heatmap-tone: var(--heatmap-tone-${tone})"
|
|
@@ -184,7 +248,20 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
184
248
|
<span part="start"><slot name="start"></slot></span>
|
|
185
249
|
<span part="summary"><slot name="summary"></slot></span>
|
|
186
250
|
<span part="end"><slot name="end"></slot></span>
|
|
187
|
-
</div
|
|
251
|
+
</div>${readable ? this.renderOverview(cells) : nothing}${this.status.spoken
|
|
252
|
+
? html `<span part="selection" role="status">${this.status.said}</span>`
|
|
253
|
+
: nothing}`;
|
|
254
|
+
}
|
|
255
|
+
renderOverview(cells) {
|
|
256
|
+
const rows = this.sourceRows;
|
|
257
|
+
const offset = this.points.length - cells.length;
|
|
258
|
+
const column = this.plottedColumns[0] ?? -1;
|
|
259
|
+
const { busiest, total } = overviewOf(cells);
|
|
260
|
+
const row = rows[offset + busiest];
|
|
261
|
+
const text = row?.cells[column]?.text ?? '';
|
|
262
|
+
const most = row ? `${this.busiestLabel}: ${row.label}${text === '' ? '' : `, ${text}`}` : '';
|
|
263
|
+
const sum = `${this.totalLabel} ${formatNumbers(this.locale)(total)}`;
|
|
264
|
+
return html `<p id="helix-chart-summary" part="overview">${most ? `${most}; ${sum}` : sum}.</p>`;
|
|
188
265
|
}
|
|
189
266
|
renderTooltip() {
|
|
190
267
|
const at = this.pointer.at;
|
|
@@ -203,6 +280,9 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
203
280
|
}, undefined, this.pointer);
|
|
204
281
|
}
|
|
205
282
|
};
|
|
283
|
+
__decorate([
|
|
284
|
+
property({ attribute: 'busiest-label' })
|
|
285
|
+
], HelixHeadlessHeatmap.prototype, "busiestLabel", void 0);
|
|
206
286
|
__decorate([
|
|
207
287
|
property({ attribute: 'empty-text' })
|
|
208
288
|
], HelixHeadlessHeatmap.prototype, "emptyText", void 0);
|
|
@@ -215,12 +295,24 @@ __decorate([
|
|
|
215
295
|
__decorate([
|
|
216
296
|
property({ type: Number })
|
|
217
297
|
], HelixHeadlessHeatmap.prototype, "rows", void 0);
|
|
298
|
+
__decorate([
|
|
299
|
+
property({ attribute: 'selection-label' })
|
|
300
|
+
], HelixHeadlessHeatmap.prototype, "selectionLabel", void 0);
|
|
301
|
+
__decorate([
|
|
302
|
+
property({ attribute: 'selection-mode' })
|
|
303
|
+
], HelixHeadlessHeatmap.prototype, "selectionMode", void 0);
|
|
218
304
|
__decorate([
|
|
219
305
|
property()
|
|
220
306
|
], HelixHeadlessHeatmap.prototype, "thresholds", void 0);
|
|
221
307
|
__decorate([
|
|
222
308
|
property()
|
|
223
309
|
], HelixHeadlessHeatmap.prototype, "tones", void 0);
|
|
310
|
+
__decorate([
|
|
311
|
+
property({ attribute: 'total-label' })
|
|
312
|
+
], HelixHeadlessHeatmap.prototype, "totalLabel", void 0);
|
|
313
|
+
__decorate([
|
|
314
|
+
property()
|
|
315
|
+
], HelixHeadlessHeatmap.prototype, "value", void 0);
|
|
224
316
|
__decorate([
|
|
225
317
|
state()
|
|
226
318
|
], HelixHeadlessHeatmap.prototype, "width", void 0);
|
package/dist/icon/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './set.js';
|
|
2
|
-
export { type IconResolver, registerIconLibrary, registerIcons, resolveIcon } from './registry.js';
|
|
2
|
+
export { type IconLibraryOptions, type IconResolver, registerIconLibrary, registerIcons, resolveIcon, } from './registry.js';
|
|
3
3
|
export * from './root/icon-root.js';
|
package/dist/icon/index.js
CHANGED
package/dist/icon/registry.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { HelixIcon } from '@fusion.dev/helix-icons';
|
|
2
2
|
/** What a library gives for a name: a glyph, a glyph later, or nothing. */
|
|
3
3
|
export type IconResolver = (name: string) => HelixIcon | Promise<HelixIcon | undefined> | undefined;
|
|
4
|
+
/** How a library's glyphs are drawn, beside the names it resolves. */
|
|
5
|
+
export interface IconLibraryOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Changes each drawn `<svg>` of the library's glyphs, as Web Awesome's
|
|
8
|
+
* `mutator` does: a stroke width, a fill, an attribute the set leaves out.
|
|
9
|
+
* Called after every render that draws one of them.
|
|
10
|
+
*/
|
|
11
|
+
mutator?: (svg: SVGSVGElement) => void;
|
|
12
|
+
}
|
|
4
13
|
/**
|
|
5
14
|
* Makes glyphs resolvable by name: a record of names to glyphs, such as the
|
|
6
15
|
* whole set, or a list of glyphs, each under its own `name`.
|
|
@@ -15,14 +24,30 @@ export declare const registerIcons: (glyphs: Record<string, HelixIcon> | readonl
|
|
|
15
24
|
* The resolver may answer at once or with a promise; an element waiting on a
|
|
16
25
|
* promise draws the glyph when it arrives and fires `load`. Each written name
|
|
17
26
|
* is asked once, and a prefix registered again is asked afresh.
|
|
27
|
+
*
|
|
28
|
+
* A sprite sheet is a library whose glyphs point into it, so the sheet is
|
|
29
|
+
* fetched once and cached:
|
|
30
|
+
*
|
|
31
|
+
* ```js
|
|
32
|
+
* registerIconLibrary('sprite', (name) => ({
|
|
33
|
+
* content: `<use href="/icons.svg#${name}"></use>`,
|
|
34
|
+
* name,
|
|
35
|
+
* viewBox: '0 0 24 24',
|
|
36
|
+
* }))
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* `mutator` changes each drawn `<svg>` of the library, such as
|
|
40
|
+
* `(svg) => svg.setAttribute('stroke-width', '1.5')`.
|
|
18
41
|
*/
|
|
19
|
-
export declare const registerIconLibrary: (prefix: string, resolve: IconResolver) => void;
|
|
42
|
+
export declare const registerIconLibrary: (prefix: string, resolve: IconResolver, options?: IconLibraryOptions) => void;
|
|
20
43
|
/**
|
|
21
44
|
* Calls `watcher` whenever a glyph or a library is registered, so an element
|
|
22
45
|
* drawn before its glyph was registered can look again. Returns the function
|
|
23
46
|
* that stops it.
|
|
24
47
|
*/
|
|
25
48
|
export declare const watchIcons: (watcher: () => void) => (() => void);
|
|
49
|
+
/** The mutator of the library a written name asks, or `undefined`. */
|
|
50
|
+
export declare const iconMutator: (name: string) => ((svg: SVGSVGElement) => void) | undefined;
|
|
26
51
|
/** The registered glyph of this name, or `undefined`. */
|
|
27
52
|
export declare const registeredIcon: (name: string) => HelixIcon | undefined;
|
|
28
53
|
/**
|
package/dist/icon/registry.js
CHANGED
|
@@ -24,9 +24,16 @@ export const registerIcons = (glyphs) => {
|
|
|
24
24
|
}
|
|
25
25
|
changed(held);
|
|
26
26
|
};
|
|
27
|
-
export const registerIconLibrary = (prefix, resolve) => {
|
|
27
|
+
export const registerIconLibrary = (prefix, resolve, options = {}) => {
|
|
28
28
|
const held = registry();
|
|
29
29
|
held.libraries.set(prefix, resolve);
|
|
30
|
+
held.mutators ??= new Map();
|
|
31
|
+
if (options.mutator) {
|
|
32
|
+
held.mutators.set(prefix, options.mutator);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
held.mutators.delete(prefix);
|
|
36
|
+
}
|
|
30
37
|
for (const name of held.answers.keys()) {
|
|
31
38
|
if (name.startsWith(`${prefix}:`)) {
|
|
32
39
|
held.answers.delete(name);
|
|
@@ -41,6 +48,10 @@ export const watchIcons = (watcher) => {
|
|
|
41
48
|
held.watchers.delete(watcher);
|
|
42
49
|
};
|
|
43
50
|
};
|
|
51
|
+
export const iconMutator = (name) => {
|
|
52
|
+
const split = name.indexOf(':');
|
|
53
|
+
return split > 0 ? registry().mutators?.get(name.slice(0, split)) : undefined;
|
|
54
|
+
};
|
|
44
55
|
export const registeredIcon = (name) => registry().glyphs.get(name);
|
|
45
56
|
export const resolveIcon = (name) => {
|
|
46
57
|
const registered = registeredIcon(name);
|
|
@@ -28,13 +28,19 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
28
28
|
* rendered is drawn then.
|
|
29
29
|
*
|
|
30
30
|
* A name with no match renders nothing, and the element fires `error`, so a
|
|
31
|
-
* typo in a name can be heard.
|
|
31
|
+
* typo in a name can be heard. It waits until the page has loaded and painted
|
|
32
|
+
* first, so a library a later module registers is not taken for a typo.
|
|
32
33
|
*
|
|
33
34
|
* An icon is decorative by default and hidden from assistive technology. Set
|
|
34
35
|
* `label` only when the icon is the only carrier of meaning, such as in a
|
|
35
36
|
* button with no text. An `aria-label` on the element works too: the element
|
|
36
37
|
* is then an image with that name.
|
|
37
38
|
*
|
|
39
|
+
* **A decorative icon that is all a control holds is reported.** In a
|
|
40
|
+
* development build, a button or a link whose only content is an icon with no
|
|
41
|
+
* `label`, and which has no name of its own, warns `missing-name` once,
|
|
42
|
+
* through the runtime channel every Helix warning uses.
|
|
43
|
+
*
|
|
38
44
|
* @since 0.1.0
|
|
39
45
|
* @status stable
|
|
40
46
|
* @category media
|
|
@@ -120,6 +126,24 @@ export declare class HelixHeadlessIcon extends HelixElement {
|
|
|
120
126
|
private lookup;
|
|
121
127
|
protected willUpdate(changed: PropertyValues): void;
|
|
122
128
|
protected updated(changed: PropertyValues): void;
|
|
129
|
+
/** Hands the drawn `<svg>` to the mutator of the library `name` asks, where it has one. */
|
|
130
|
+
private mutate;
|
|
131
|
+
/**
|
|
132
|
+
* Asks the button or link a decorative icon sits in whether it has a name.
|
|
133
|
+
* Its content is this icon alone where it has none, and the audit says so
|
|
134
|
+
* once, in a development build only. A Helix button reports its own name.
|
|
135
|
+
*/
|
|
136
|
+
private auditControl;
|
|
137
|
+
/** The name a report is waiting on the page to settle for, so it is asked once. */
|
|
138
|
+
private pending;
|
|
139
|
+
/**
|
|
140
|
+
* Says a name drew nothing, once the page has had its chance to register
|
|
141
|
+
* it: a library registered by a module further down the page, or by the
|
|
142
|
+
* page's own script after this element, is not a missing glyph. Asked again
|
|
143
|
+
* then, and said only where the name still draws nothing and nothing is
|
|
144
|
+
* still on its way.
|
|
145
|
+
*/
|
|
146
|
+
private reportMissing;
|
|
123
147
|
protected render(): TemplateResult | typeof nothing;
|
|
124
148
|
}
|
|
125
149
|
declare global {
|