@fusion.dev/helix-headless 0.146.0 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +9287 -1084
- package/dist/accordion/item/accordion-item.d.ts +43 -21
- package/dist/accordion/item/accordion-item.js +37 -11
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +6 -8
- package/dist/announcement/root/announcement-root.d.ts +66 -6
- package/dist/announcement/root/announcement-root.js +144 -13
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +14 -7
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +77 -8
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +28 -4
- package/dist/chat/root/chat-root.js +12 -7
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
- package/dist/checkbox-group/select-all.d.ts +9 -4
- package/dist/checkbox-group/select-all.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +41 -18
- package/dist/code-block/root/code-block-root.js +21 -6
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +99 -55
- package/dist/color-picker/wheel.d.ts +28 -0
- package/dist/color-picker/wheel.js +15 -0
- package/dist/combobox/root/combobox-root.d.ts +83 -11
- package/dist/combobox/root/combobox-root.js +81 -18
- package/dist/command/root/command-root.d.ts +7 -4
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +29 -50
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +22 -4
- package/dist/description-list/item/description-list-item.js +14 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +38 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/empty/root/empty-root.d.ts +46 -2
- package/dist/empty/root/empty-root.js +50 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +55 -21
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +11 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +10 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +5 -5
- package/dist/format-date/options.js +10 -39
- package/dist/format-date/root/format-date-root.d.ts +53 -4
- package/dist/format-date/root/format-date-root.js +38 -50
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +76 -3
- package/dist/heatmap/root/heatmap-root.js +105 -20
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +20 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +23 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +25 -26
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +31 -24
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +125 -26
- package/dist/listbox/root/listbox-root.js +156 -166
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +29 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +5 -2
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +48 -3
- package/dist/notifications/root/notifications-root.js +36 -6
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
- package/dist/object-inspector/root/object-inspector-root.js +31 -20
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +51 -1
- package/dist/pin-input/code.js +37 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +151 -156
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +31 -9
- package/dist/qr-code/root/qr-code-root.js +29 -17
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +115 -11
- package/dist/select/root/select-root.js +104 -20
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
- package/dist/speed-dial/item/speed-dial-item.js +43 -5
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
- package/dist/speed-dial/root/speed-dial-root.js +123 -6
- package/dist/splitter/root/splitter-root.d.ts +9 -2
- package/dist/splitter/root/splitter-root.js +18 -3
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +93 -29
- package/dist/table/row/table-row.d.ts +36 -0
- package/dist/table/row/table-row.js +52 -2
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +23 -20
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +12 -14
- package/dist/time-picker/root/time-picker-root.js +18 -23
- package/dist/toast/item/toast-item.d.ts +9 -6
- package/dist/toast/item/toast-item.js +1 -1
- package/dist/toast/root/toast-root.d.ts +40 -4
- package/dist/toast/root/toast-root.js +68 -16
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -43
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +52 -5
- package/dist/toolbar/root/toolbar-root.js +88 -13
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -2
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +16 -1
- package/dist/video/root/video-root.js +15 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +53 -41
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4934 -954
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +946 -253
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -25,6 +25,13 @@ 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.
|
|
29
|
+
*
|
|
30
|
+
* **`fields` draws each field of a date as a part of its own**, such as
|
|
31
|
+
* `day`, `month` and `year`, so a stylesheet can set the year in a lighter ink
|
|
32
|
+
* or the weekday in capitals with `::part()`. The text between the fields is
|
|
33
|
+
* the locale's own and has no part. An `elapsed` or `relative` reading is one
|
|
34
|
+
* phrase, with no parts inside it.
|
|
28
35
|
*
|
|
29
36
|
* **The output is always `<time datetime>`**, so copy and paste and scripts
|
|
30
37
|
* parsing the page get the exact instant, whatever the visible text says. A
|
|
@@ -42,7 +49,20 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
42
49
|
* @aliases RelativeTime, Timestamp, TimeAgo
|
|
43
50
|
* @documentation https://fusion.dev/helix/components/format-date
|
|
44
51
|
*
|
|
52
|
+
* @csspart day - The day of the month, with `fields`.
|
|
53
|
+
* @csspart day-period - AM or PM, or the locale's word for the part of the day, with `fields`.
|
|
54
|
+
* @csspart era - The era, such as AD, with `fields` and `era`.
|
|
55
|
+
* @csspart hour - The hour, with `fields`.
|
|
56
|
+
* @csspart minute - The minute, with `fields`.
|
|
57
|
+
* @csspart month - The month, with `fields`.
|
|
58
|
+
* @csspart second - The second, with `fields`.
|
|
45
59
|
* @csspart time - The `<time>` element that holds the formatted text.
|
|
60
|
+
* @csspart time-zone-name - The time zone's name, with `fields`, where `time-zone-name` or a `long` or `full` `time-style` shows it.
|
|
61
|
+
* @csspart weekday - The day of the week, with `fields`.
|
|
62
|
+
* @csspart year - The year, with `fields`.
|
|
63
|
+
*
|
|
64
|
+
* @cssstate future - An `elapsed` or `relative` reading of a moment still to come, such as "in 3 hours".
|
|
65
|
+
* @cssstate past - An `elapsed` or `relative` reading of a moment gone, such as "3 hours ago".
|
|
46
66
|
*/
|
|
47
67
|
export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
48
68
|
/**
|
|
@@ -85,6 +105,29 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
85
105
|
* How the era is written, such as AD, where a date is shown.
|
|
86
106
|
*/
|
|
87
107
|
era?: 'long' | 'narrow' | 'short';
|
|
108
|
+
/**
|
|
109
|
+
* Draws each field of a date in a part of its own: `weekday`, `day`,
|
|
110
|
+
* `month`, `year`, `era`, `hour`, `minute`, `second`, `day-period` and
|
|
111
|
+
* `time-zone-name`, so `::part(year)` can set the year apart.
|
|
112
|
+
*
|
|
113
|
+
* Off by default, which draws the date as one run of text, as Shoelace and
|
|
114
|
+
* Web Awesome do. An `elapsed` or `relative` reading is one phrase either
|
|
115
|
+
* way.
|
|
116
|
+
*/
|
|
117
|
+
fields?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Draws an `elapsed` or `relative` reading once and leaves it, where it
|
|
120
|
+
* would otherwise move on as it goes stale.
|
|
121
|
+
*
|
|
122
|
+
* For a reading that describes a moment the page itself is about, such as
|
|
123
|
+
* "3 hours ago" in a report generated then, or a list a reader compares
|
|
124
|
+
* line by line while it should not change under them. The reading is taken
|
|
125
|
+
* when the element draws, and again whenever `date` or another option
|
|
126
|
+
* changes. Turned off, the reading catches up and moves on again.
|
|
127
|
+
* `sl-relative-time` and `wa-relative-time` keep still unless `sync` is
|
|
128
|
+
* set; this keeps moving unless `frozen` is.
|
|
129
|
+
*/
|
|
130
|
+
frozen: boolean;
|
|
88
131
|
/**
|
|
89
132
|
* How the hour is written, where a time of day is shown.
|
|
90
133
|
*/
|
|
@@ -100,9 +143,12 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
100
143
|
/**
|
|
101
144
|
* The locale to format the timestamp in.
|
|
102
145
|
*
|
|
103
|
-
*
|
|
146
|
+
* Absent is the page's: the `lang` of the nearest element with one, as
|
|
147
|
+
* Shoelace and Web Awesome read it, then the runtime's own.
|
|
104
148
|
*/
|
|
105
149
|
locale: string;
|
|
150
|
+
/** The locale the words are written in: `locale`, or the page's `lang`. */
|
|
151
|
+
private get language();
|
|
106
152
|
/**
|
|
107
153
|
* How the minute is written, where a time of day is shown.
|
|
108
154
|
*/
|
|
@@ -167,15 +213,18 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
167
213
|
private readonly clock;
|
|
168
214
|
/**
|
|
169
215
|
* The date read out of the light DOM, where no attribute carried one.
|
|
216
|
+
*
|
|
217
|
+
* Not a reactive state: `read` asks for the update itself, which keeps the
|
|
218
|
+
* `state` decorator out of this element's bundle.
|
|
170
219
|
*/
|
|
171
220
|
private written;
|
|
172
|
-
private watching
|
|
221
|
+
private watching?;
|
|
173
222
|
/** Whether the timestamp is a day with no time, which is formatted in UTC. */
|
|
174
223
|
private get dateOnly();
|
|
175
224
|
/** The timestamp, or nothing where there is not one to read. */
|
|
176
225
|
private get moment();
|
|
177
|
-
/**
|
|
178
|
-
private get
|
|
226
|
+
/** The timestamp as written, in the attribute or in the light DOM. */
|
|
227
|
+
private get source();
|
|
179
228
|
/** Whether the reading is how long ago rather than the date. */
|
|
180
229
|
private get reading();
|
|
181
230
|
/** What the reading says now, and when it stops being true. */
|
|
@@ -4,9 +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 { 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
|
-
import { property
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { drawFields } from '../fields.js';
|
|
10
11
|
import { formatOptions } from '../options.js';
|
|
11
12
|
const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
|
|
12
13
|
let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement {
|
|
@@ -14,52 +15,43 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
14
15
|
super(...arguments);
|
|
15
16
|
this.date = '';
|
|
16
17
|
this.elapsed = false;
|
|
18
|
+
this.frozen = false;
|
|
17
19
|
this.locale = '';
|
|
18
20
|
this.clock = new RelativeClockController(this, {
|
|
19
21
|
expires: (now) => {
|
|
20
22
|
const moment = this.moment;
|
|
21
|
-
|
|
23
|
+
if (!moment || !this.reading) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return this.frozen ? Infinity : this.readingAt(moment, now).next;
|
|
22
27
|
},
|
|
23
28
|
});
|
|
24
29
|
this.written = '';
|
|
25
|
-
|
|
30
|
+
}
|
|
31
|
+
get language() {
|
|
32
|
+
return localeOf(this, this.locale);
|
|
26
33
|
}
|
|
27
34
|
get dateOnly() {
|
|
28
|
-
return DATE_ONLY.test(
|
|
35
|
+
return DATE_ONLY.test(this.source);
|
|
29
36
|
}
|
|
30
37
|
get moment() {
|
|
31
|
-
const source = this.
|
|
38
|
+
const source = this.source;
|
|
32
39
|
if (source === '') {
|
|
33
40
|
return undefined;
|
|
34
41
|
}
|
|
35
42
|
const parsed = new Date(source);
|
|
36
43
|
return Number.isNaN(parsed.getTime()) ? undefined : parsed;
|
|
37
44
|
}
|
|
38
|
-
get
|
|
39
|
-
return
|
|
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
|
-
});
|
|
45
|
+
get source() {
|
|
46
|
+
return (this.date || this.written).trim();
|
|
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);
|
|
@@ -73,7 +65,6 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
73
65
|
disconnectedCallback() {
|
|
74
66
|
super.disconnectedCallback();
|
|
75
67
|
this.watching?.disconnect();
|
|
76
|
-
this.watching = undefined;
|
|
77
68
|
}
|
|
78
69
|
firstUpdated(changed) {
|
|
79
70
|
super.firstUpdated(changed);
|
|
@@ -85,13 +76,12 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
85
76
|
if (this.childrenKnown) {
|
|
86
77
|
this.read();
|
|
87
78
|
}
|
|
88
|
-
if (changed.has(
|
|
89
|
-
changed.has('elapsed') ||
|
|
90
|
-
changed.has('locale') ||
|
|
91
|
-
changed.has('numeric') ||
|
|
92
|
-
changed.has('relative')) {
|
|
79
|
+
if (['date', 'elapsed', 'frozen', 'locale', 'numeric', 'relative'].some((key) => changed.has(key))) {
|
|
93
80
|
this.clock.tick();
|
|
94
81
|
}
|
|
82
|
+
const ahead = this.reading ? (this.moment?.getTime() ?? NaN) - this.clock.now : NaN;
|
|
83
|
+
this.toggleState('past', ahead <= 0);
|
|
84
|
+
this.toggleState('future', ahead > 0);
|
|
95
85
|
}
|
|
96
86
|
read() {
|
|
97
87
|
if (this.date !== '') {
|
|
@@ -100,6 +90,7 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
100
90
|
const written = this.textContent?.trim() ?? '';
|
|
101
91
|
if (written !== this.written) {
|
|
102
92
|
this.written = written;
|
|
93
|
+
this.requestUpdate();
|
|
103
94
|
this.clock.tick();
|
|
104
95
|
}
|
|
105
96
|
}
|
|
@@ -113,26 +104,20 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
|
|
|
113
104
|
if (!moment) {
|
|
114
105
|
return nothing;
|
|
115
106
|
}
|
|
116
|
-
const datetime = this.dateOnly ?
|
|
107
|
+
const datetime = this.dateOnly ? this.source : moment.toISOString();
|
|
117
108
|
if (!this.reading) {
|
|
118
|
-
const
|
|
119
|
-
return html `<time part="time" datetime=${datetime}>${
|
|
109
|
+
const format = new Intl.DateTimeFormat(this.language || undefined, formatOptions(this, this.dateOnly));
|
|
110
|
+
return html `<time part="time" datetime=${datetime}>${this.fields ? drawFields(format.formatToParts(moment)) : format.format(moment)}</time>`;
|
|
120
111
|
}
|
|
121
112
|
const now = new Date(this.clock.now);
|
|
122
|
-
const
|
|
123
|
-
const whole = new Intl.DateTimeFormat(this.locale || undefined, {
|
|
113
|
+
const whole = new Intl.DateTimeFormat(this.language || undefined, formatOptions({
|
|
124
114
|
dateStyle: 'long',
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}).format(moment);
|
|
129
|
-
const spoken = relativeTime(this.
|
|
130
|
-
return html `<time
|
|
131
|
-
part="time"
|
|
132
|
-
datetime=${datetime}
|
|
133
|
-
aria-label=${spoken}
|
|
134
|
-
title=${whole}
|
|
135
|
-
>${this.readingAt(moment, now).text}</time>`;
|
|
115
|
+
hourCycle: this.hourCycle,
|
|
116
|
+
timeStyle: this.dateOnly ? undefined : 'short',
|
|
117
|
+
timeZone: this.timeZone,
|
|
118
|
+
}, this.dateOnly)).format(moment);
|
|
119
|
+
const spoken = relativeTime(this.language, { numeric: this.numeric ?? 'auto' })(moment, now).text;
|
|
120
|
+
return html `<time part="time" datetime=${datetime} aria-label=${spoken} title=${whole}>${this.readingAt(moment, now).text}</time>`;
|
|
136
121
|
}
|
|
137
122
|
};
|
|
138
123
|
__decorate([
|
|
@@ -150,6 +135,12 @@ __decorate([
|
|
|
150
135
|
__decorate([
|
|
151
136
|
property()
|
|
152
137
|
], HelixHeadlessFormatDate.prototype, "era", void 0);
|
|
138
|
+
__decorate([
|
|
139
|
+
property({ type: Boolean })
|
|
140
|
+
], HelixHeadlessFormatDate.prototype, "fields", void 0);
|
|
141
|
+
__decorate([
|
|
142
|
+
property({ type: Boolean })
|
|
143
|
+
], HelixHeadlessFormatDate.prototype, "frozen", void 0);
|
|
153
144
|
__decorate([
|
|
154
145
|
property()
|
|
155
146
|
], HelixHeadlessFormatDate.prototype, "hour", void 0);
|
|
@@ -189,9 +180,6 @@ __decorate([
|
|
|
189
180
|
__decorate([
|
|
190
181
|
property()
|
|
191
182
|
], HelixHeadlessFormatDate.prototype, "year", void 0);
|
|
192
|
-
__decorate([
|
|
193
|
-
state()
|
|
194
|
-
], HelixHeadlessFormatDate.prototype, "written", void 0);
|
|
195
183
|
HelixHeadlessFormatDate = __decorate([
|
|
196
184
|
customElement('helix-headless-format-date')
|
|
197
185
|
], HelixHeadlessFormatDate);
|
|
@@ -41,7 +41,14 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
41
41
|
* @slot - The renderer's box, which the drawing is made in.
|
|
42
42
|
* @slot filter-icon - The icon in the search field. Defaults to a magnifying glass.
|
|
43
43
|
* @slot footer - Content below the graph.
|
|
44
|
+
* @slot fullscreen-icon - Replaces the glyph inside the fullscreen button.
|
|
44
45
|
* @slot header - Content above the graph.
|
|
46
|
+
* @slot pan-down-icon - Replaces the glyph inside the pan down button.
|
|
47
|
+
* @slot pan-end-icon - Replaces the glyph inside the button that pans toward the end of a line of text.
|
|
48
|
+
* @slot pan-start-icon - Replaces the glyph inside the button that pans toward the start of a line of text.
|
|
49
|
+
* @slot pan-up-icon - Replaces the glyph inside the pan up button.
|
|
50
|
+
* @slot zoom-in-icon - Replaces the glyph inside the zoom-in button.
|
|
51
|
+
* @slot zoom-out-icon - Replaces the glyph inside the zoom-out button.
|
|
45
52
|
*
|
|
46
53
|
* @event {HelixActivateEvent} helix-activate - A note was selected, in the list or in the drawing. The detail's `value` is its `id`.
|
|
47
54
|
* @event {HelixBeforeActivateEvent} helix-before-activate - A note is about to be selected. Cancelable: cancel it to keep the selection in your own state.
|
|
@@ -91,9 +98,14 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
91
98
|
* @csspart zoom-in - The zoom in button.
|
|
92
99
|
* @csspart zoom-out - The zoom out button.
|
|
93
100
|
*
|
|
101
|
+
* @cssstate empty - The list holds no notes: the graph has none, or a search or the groups hid them all.
|
|
94
102
|
* @cssstate fullscreen - The graph fills the screen.
|
|
95
103
|
* @cssstate idle - The user has been still long enough for the header and footer to fade.
|
|
104
|
+
* @cssstate local - The drawing shows the selected note's local graph, with `depth`.
|
|
105
|
+
* @cssstate panel-open - A graph with `no-panel` has the search and the list open over the drawing.
|
|
96
106
|
* @cssstate ready - The graph has been drawn whole, after `helix-graph-ready`.
|
|
107
|
+
* @cssstate searching - The search field holds words, and the list holds only the notes they find.
|
|
108
|
+
* @cssstate selected - A note is selected, in the list or in the drawing.
|
|
97
109
|
* @cssstate sharing - The page keeps the plain wheel and one finger, with `gestures="cooperative"` or while a graph with `gestures="activate"` waits to be pressed.
|
|
98
110
|
* @cssstate using - A graph with `gestures="activate"` has been pressed and has the gestures.
|
|
99
111
|
*/
|
|
@@ -255,14 +267,20 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
255
267
|
* drawing: a reader moving through the list was moving the graph under it.
|
|
256
268
|
*/
|
|
257
269
|
private readonly handleListKeydown;
|
|
258
|
-
/** What has been typed toward a note's name
|
|
259
|
-
private typed;
|
|
270
|
+
/** What has been typed toward a note's name. */
|
|
271
|
+
private readonly typed;
|
|
260
272
|
/**
|
|
261
|
-
* Moves to the next note whose name starts with what was typed,
|
|
262
|
-
* listbox does
|
|
263
|
-
* and a repeated letter steps through the names that start with it.
|
|
273
|
+
* Moves to the next note whose name starts with what was typed, through
|
|
274
|
+
* core's `Typeahead`, as a listbox does: letters within half a second run
|
|
275
|
+
* together, and a repeated letter steps through the names that start with it.
|
|
264
276
|
*/
|
|
265
277
|
private typeahead;
|
|
278
|
+
/**
|
|
279
|
+
* How many rows Page Down and Page Up move: the rows that fit in the list's
|
|
280
|
+
* box, or in the window where the list does not scroll, less one, so the
|
|
281
|
+
* row at one edge lands at the other.
|
|
282
|
+
*/
|
|
283
|
+
private pageRows;
|
|
266
284
|
/**
|
|
267
285
|
* The search field's keys, which belong to the field and never pan the
|
|
268
286
|
* graph. Escape empties a search that has words in it, and passes through
|
|
@@ -4,14 +4,13 @@ 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, formatNumbers, HelixElement, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, scrollItemIntoView, VirtualizeController, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, fillTemplate, formatNumbers, HelixElement, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, scrollItemIntoView, scrollRoom, Typeahead, VirtualizeController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { list, magnifyingGlass } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { repeat } from 'lit/directives/repeat.js';
|
|
12
12
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
13
13
|
import { adjacencyOf, entriesOf, groupsOf, nameOf, sortedOf, within, withoutGroups, } from './graph-model.js';
|
|
14
|
-
const PAGE = 10;
|
|
15
14
|
let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinControllerActive(HelixElement)) {
|
|
16
15
|
constructor() {
|
|
17
16
|
super(...arguments);
|
|
@@ -53,8 +52,8 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
53
52
|
ArrowUp: this.cursor - 1,
|
|
54
53
|
End: this.entries.length - 1,
|
|
55
54
|
Home: 0,
|
|
56
|
-
PageDown: this.cursor +
|
|
57
|
-
PageUp: this.cursor -
|
|
55
|
+
PageDown: this.cursor + this.pageRows(),
|
|
56
|
+
PageUp: this.cursor - this.pageRows(),
|
|
58
57
|
};
|
|
59
58
|
if (event.key in moves) {
|
|
60
59
|
event.preventDefault();
|
|
@@ -74,7 +73,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
74
73
|
this.typeahead(event.key);
|
|
75
74
|
}
|
|
76
75
|
};
|
|
77
|
-
this.typed =
|
|
76
|
+
this.typed = new Typeahead();
|
|
78
77
|
this.handleSearchKeydown = (event) => {
|
|
79
78
|
if (event.key === 'ArrowDown') {
|
|
80
79
|
event.preventDefault();
|
|
@@ -126,6 +125,9 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
126
125
|
super.willUpdate(changed);
|
|
127
126
|
this.toggleState('fullscreen', this.filled);
|
|
128
127
|
this.toggleState('idle', this.resting);
|
|
128
|
+
this.toggleState('panel-open', this.noPanel && this.panelOpen);
|
|
129
|
+
this.toggleState('searching', this.query.trim() !== '');
|
|
130
|
+
this.toggleState('selected', this.active !== '');
|
|
129
131
|
if (changed.has('links')) {
|
|
130
132
|
this.adjacency = adjacencyOf(this.links);
|
|
131
133
|
}
|
|
@@ -141,9 +143,11 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
141
143
|
? within(this.adjacency, this.active, Math.max(0, this.depth))
|
|
142
144
|
: undefined;
|
|
143
145
|
this.kept = withoutGroups(this.nodes, local, this.hiddenGroups);
|
|
146
|
+
this.toggleState('local', local !== undefined);
|
|
144
147
|
}
|
|
145
148
|
if (['nodes', 'links', 'active', 'depth', 'hiddenGroups', 'query'].some((name) => changed.has(name))) {
|
|
146
149
|
this.entries = entriesOf(this.sorted, this.adjacency, this.active, this.query, this.kept);
|
|
150
|
+
this.toggleState('empty', this.entries.length === 0);
|
|
147
151
|
this.cursor = 0;
|
|
148
152
|
const list = this.partNamed('list');
|
|
149
153
|
if (list) {
|
|
@@ -272,23 +276,16 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
272
276
|
return this.entries.length > 0 && (cursor < first || cursor >= last) ? cursor : undefined;
|
|
273
277
|
}
|
|
274
278
|
typeahead(letter) {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const wanted = text.toLocaleLowerCase();
|
|
279
|
-
const repeated = [...wanted].every((one) => one === wanted[0]);
|
|
280
|
-
const prefix = repeated ? (wanted[0] ?? '') : wanted;
|
|
281
|
-
const entries = this.entries;
|
|
282
|
-
const start = repeated ? this.cursor + 1 : this.cursor;
|
|
283
|
-
for (let step = 0; step < entries.length; step += 1) {
|
|
284
|
-
const at = (start + step) % entries.length;
|
|
285
|
-
const entry = entries[at];
|
|
286
|
-
if (entry && nameOf(entry.node).toLocaleLowerCase().startsWith(prefix)) {
|
|
287
|
-
this.moveTo(at);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
279
|
+
const at = this.typed.match(letter, this.entries.map((entry) => nameOf(entry.node)), this.cursor);
|
|
280
|
+
if (at >= 0) {
|
|
281
|
+
this.moveTo(at);
|
|
290
282
|
}
|
|
291
283
|
}
|
|
284
|
+
pageRows() {
|
|
285
|
+
const room = scrollRoom(this.partNamed('list'));
|
|
286
|
+
const tall = this.virtualize.sizeOf(this.cursor) || 32;
|
|
287
|
+
return Math.max(1, Math.floor(room / tall) - 1);
|
|
288
|
+
}
|
|
292
289
|
togglePanel(open = !this.panelOpen) {
|
|
293
290
|
const inside = this.panelOpen && this.partNamed('panel')?.contains(this.shadowRoot?.activeElement ?? null);
|
|
294
291
|
this.panelOpen = open;
|
|
@@ -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,23 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
141
155
|
* days.
|
|
142
156
|
*/
|
|
143
157
|
rows: number;
|
|
158
|
+
/**
|
|
159
|
+
* What the readout adds for a selected cell, under `selection-mode`, after
|
|
160
|
+
* where the cell stands: "Day 1: 0 (1 of 14, selected)". Empty adds
|
|
161
|
+
* nothing.
|
|
162
|
+
*/
|
|
163
|
+
selectedLabel: string;
|
|
164
|
+
/**
|
|
165
|
+
* What the `selection` part says after the selection changes, with `{count}` for
|
|
166
|
+
* how many cells are selected.
|
|
167
|
+
*/
|
|
168
|
+
selectionLabel: string;
|
|
169
|
+
/**
|
|
170
|
+
* How many cells a reader can select: `single` or `multiple`.
|
|
171
|
+
*
|
|
172
|
+
* Absent selects nothing, and a press or Space does what it did.
|
|
173
|
+
*/
|
|
174
|
+
selectionMode?: 'multiple' | 'single';
|
|
144
175
|
/**
|
|
145
176
|
* Lower bounds for the tone buckets, in the order the tones are given.
|
|
146
177
|
*
|
|
@@ -167,6 +198,14 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
167
198
|
* The word the `overview` puts before the total of the readings drawn.
|
|
168
199
|
*/
|
|
169
200
|
totalLabel: string;
|
|
201
|
+
/**
|
|
202
|
+
* The selected cells, by the names their rows have in the table, such as
|
|
203
|
+
* `2026-06-11`, separated by commas.
|
|
204
|
+
*
|
|
205
|
+
* Set it to start with cells selected. Written by a press or a key under
|
|
206
|
+
* `selection-mode`.
|
|
207
|
+
*/
|
|
208
|
+
value: string;
|
|
170
209
|
/**
|
|
171
210
|
* How many cells are actually drawn.
|
|
172
211
|
*
|
|
@@ -215,6 +254,28 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
215
254
|
protected readonly aria: AriaForwardController;
|
|
216
255
|
private observer;
|
|
217
256
|
private announced;
|
|
257
|
+
/** Where a range taken in with Shift starts: the cell last pressed, or none. */
|
|
258
|
+
private anchor;
|
|
259
|
+
/** The region a change of selection is said in, rendered from the first change. */
|
|
260
|
+
private readonly status;
|
|
261
|
+
/** The name each drawn cell stands for in `value`: its row's name in the table. */
|
|
262
|
+
private keysOf;
|
|
263
|
+
/**
|
|
264
|
+
* Moves `value` to `next`, asking first: `helix-before-change` carries it,
|
|
265
|
+
* a listener that refuses keeps the selection, and `change` follows, with
|
|
266
|
+
* the count said in the `selection` part.
|
|
267
|
+
*/
|
|
268
|
+
private choose;
|
|
269
|
+
/** Selects the drawn cell at `index`, or lets it go, as `selection-mode` says. */
|
|
270
|
+
private press;
|
|
271
|
+
/**
|
|
272
|
+
* Space and Enter select the cell the keys rest on, and Shift with a key
|
|
273
|
+
* that moved them takes in the range from the anchor. After the pointer
|
|
274
|
+
* controller, which has already moved `at` for an arrow.
|
|
275
|
+
*/
|
|
276
|
+
private readonly onKeydown;
|
|
277
|
+
/** A press on a cell selects it, under `selection-mode`. */
|
|
278
|
+
private readonly onClick;
|
|
218
279
|
/**
|
|
219
280
|
* Every row in the table, oldest first, as the table is written, with its
|
|
220
281
|
* reading where the row has one.
|
|
@@ -304,6 +365,12 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
304
365
|
* the reason `BarChart` gives: SSR calls this one.
|
|
305
366
|
*/
|
|
306
367
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
368
|
+
/**
|
|
369
|
+
* Where PageUp or PageDown goes from the drawn cell at `at`: the same day a
|
|
370
|
+
* month on or back, by the dates the rows' headers carry. Undefined where
|
|
371
|
+
* they carry none, and the keys move four columns.
|
|
372
|
+
*/
|
|
373
|
+
pageFrom(at: number, forward: boolean): number | undefined;
|
|
307
374
|
connectedCallback(): void;
|
|
308
375
|
disconnectedCallback(): void;
|
|
309
376
|
/**
|
|
@@ -348,6 +415,12 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
348
415
|
* pitch is `cell + gap` and both are measured.
|
|
349
416
|
*/
|
|
350
417
|
protected renderTooltip(): TemplateResult | typeof nothing;
|
|
418
|
+
/**
|
|
419
|
+
* The readout's cursor: the pointer, with the selected word after where a
|
|
420
|
+
* selected cell stands, so a reader moving through the strip hears which
|
|
421
|
+
* cells are in the selection and not only how many.
|
|
422
|
+
*/
|
|
423
|
+
private reading;
|
|
351
424
|
/**
|
|
352
425
|
* Which drawn cell the pointer is over, or -1.
|
|
353
426
|
*
|