@fusion.dev/helix-headless 0.145.0 → 0.146.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 +7373 -3849
- package/dist/accordion/item/accordion-item.d.ts +14 -0
- package/dist/accordion/item/accordion-item.js +16 -6
- package/dist/accordion/root/accordion-root.d.ts +8 -5
- package/dist/announcement/root/announcement-root.d.ts +3 -2
- package/dist/announcement/root/announcement-root.js +3 -1
- 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/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/badge/root/badge-root.d.ts +3 -1
- package/dist/badge/root/badge-root.js +2 -2
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +52 -15
- package/dist/bar-chart/stack.d.ts +15 -0
- package/dist/bar-chart/stack.js +19 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +50 -3
- package/dist/button/root/button-root.d.ts +26 -0
- package/dist/button/root/button-root.js +38 -18
- 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 +24 -3
- package/dist/card/root/card-root.js +20 -8
- 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 +25 -3
- package/dist/chat/root/chat-root.js +22 -5
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +14 -1
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
- package/dist/checkbox-group/select-all.d.ts +27 -0
- package/dist/checkbox-group/select-all.js +12 -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 +49 -1
- package/dist/code-block/root/code-block-root.js +58 -3
- package/dist/color-input/root/color-input-root.d.ts +3 -0
- package/dist/color-input/root/color-input-root.js +6 -3
- package/dist/color-picker/root/color-picker-root.d.ts +33 -4
- package/dist/color-picker/root/color-picker-root.js +80 -21
- package/dist/color-picker/swatches.d.ts +12 -0
- package/dist/color-picker/swatches.js +26 -0
- package/dist/combobox/root/combobox-root.d.ts +43 -0
- package/dist/combobox/root/combobox-root.js +79 -15
- package/dist/command/root/command-root.d.ts +16 -1
- package/dist/command/root/command-root.js +22 -4
- package/dist/copy-button/root/copy-button-root.d.ts +5 -0
- package/dist/copy-button/root/copy-button-root.js +10 -3
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +24 -0
- package/dist/data-table/keys.js +24 -0
- package/dist/data-table/root/data-table-root.d.ts +27 -18
- package/dist/data-table/root/data-table-root.js +20 -52
- 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 +3 -1
- package/dist/date-input/root/date-input-root.js +18 -7
- package/dist/date-picker/root/date-picker-root.js +12 -6
- 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 +48 -1
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +59 -0
- package/dist/drawer/root/drawer-root.js +63 -4
- package/dist/drilldown/item/drilldown-item.js +1 -1
- package/dist/drilldown/root/drilldown-root.d.ts +21 -3
- package/dist/drilldown/root/drilldown-root.js +21 -3
- package/dist/element-events.generated.js +31 -5
- package/dist/empty/root/empty-root.d.ts +3 -1
- package/dist/empty/root/empty-root.js +3 -2
- package/dist/file-input/root/file-input-root.d.ts +69 -6
- package/dist/file-input/root/file-input-root.js +82 -19
- package/dist/file-input/screen.d.ts +2 -1
- 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 +30 -6
- package/dist/filter-input/root/filter-input-root.js +1 -1
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/root/format-date-root.d.ts +9 -16
- package/dist/format-date/root/format-date-root.js +10 -27
- package/dist/heatmap/root/heatmap-root.d.ts +24 -13
- package/dist/heatmap/root/heatmap-root.js +34 -12
- package/dist/icon/root/icon-root.d.ts +12 -1
- package/dist/icon/root/icon-root.js +21 -10
- 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 +5 -1
- package/dist/image/root/image-root.js +1 -1
- package/dist/input/root/input-root.d.ts +12 -2
- package/dist/input/root/input-root.js +11 -2
- package/dist/kbd/root/kbd-root.d.ts +35 -1
- package/dist/kbd/root/kbd-root.js +23 -4
- package/dist/legend/root/legend-root.d.ts +55 -8
- package/dist/legend/root/legend-root.js +55 -13
- package/dist/lightbox/root/lightbox-root.d.ts +49 -6
- package/dist/lightbox/root/lightbox-root.js +86 -19
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +22 -0
- package/dist/lightbox/zoom.js +16 -0
- package/dist/line-chart/root/line-chart-root.d.ts +22 -1
- package/dist/line-chart/root/line-chart-root.js +21 -1
- 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 +62 -13
- package/dist/list/root/list-root.js +70 -13
- package/dist/list/selection.d.ts +37 -7
- package/dist/list/selection.js +16 -7
- package/dist/listbox/root/listbox-root.d.ts +37 -1
- package/dist/listbox/root/listbox-root.js +49 -3
- 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/root/megamenu-root.d.ts +51 -10
- package/dist/megamenu/root/megamenu-root.js +76 -5
- package/dist/menu/item/menu-item.d.ts +51 -2
- package/dist/menu/item/menu-item.js +47 -23
- package/dist/menu/root/menu-root.d.ts +14 -0
- package/dist/menu/root/menu-root.js +2 -2
- package/dist/meter/root/meter-root.d.ts +20 -1
- package/dist/meter/root/meter-root.js +11 -15
- 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 +10 -3
- package/dist/notifications/root/notifications-root.js +19 -7
- package/dist/number-input/root/number-input-root.d.ts +17 -8
- package/dist/number-input/root/number-input-root.js +2 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +75 -27
- package/dist/object-inspector/root/object-inspector-root.js +117 -76
- package/dist/object-inspector/rows.d.ts +18 -0
- package/dist/object-inspector/rows.js +33 -0
- package/dist/option/root/option-root.d.ts +5 -3
- package/dist/outline/root/outline-root.d.ts +18 -0
- package/dist/outline/root/outline-root.js +23 -5
- package/dist/pagination/size/pagination-size.d.ts +1 -0
- package/dist/pagination/size/pagination-size.js +1 -1
- package/dist/pin-input/code.d.ts +10 -0
- package/dist/pin-input/code.js +13 -0
- package/dist/pin-input/root/pin-input-root.d.ts +25 -1
- package/dist/pin-input/root/pin-input-root.js +10 -11
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +41 -0
- package/dist/popover/root/popover-root.d.ts +57 -7
- package/dist/popover/root/popover-root.js +58 -3
- package/dist/progress/root/progress-root.d.ts +20 -0
- package/dist/progress/root/progress-root.js +15 -15
- package/dist/qr-code/export.d.ts +26 -1
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/root/qr-code-root.d.ts +19 -5
- package/dist/qr-code/root/qr-code-root.js +58 -9
- 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/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +6 -1
- package/dist/rating/root/rating-root.d.ts +9 -4
- package/dist/rating/root/rating-root.js +31 -7
- package/dist/rating/steps.d.ts +7 -0
- package/dist/rating/steps.js +9 -0
- 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 +21 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
- 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 -0
- package/dist/scroll-area/scrollbar.js +9 -0
- package/dist/select/root/select-root.d.ts +15 -0
- package/dist/select/root/select-root.js +18 -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 +41 -4
- package/dist/slider/root/slider-root.js +23 -3
- package/dist/sparkline/readings.d.ts +18 -0
- package/dist/sparkline/readings.js +19 -0
- package/dist/sparkline/root/sparkline-root.d.ts +78 -7
- package/dist/sparkline/root/sparkline-root.js +118 -23
- package/dist/speed-dial/root/speed-dial-root.js +2 -2
- package/dist/splitter/root/splitter-root.d.ts +7 -12
- package/dist/splitter/root/splitter-root.js +209 -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 +49 -3
- package/dist/steps/root/steps-root.js +44 -5
- package/dist/steps/step/step.d.ts +7 -0
- package/dist/steps/step/step.js +7 -2
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +0 -10
- package/dist/table/column/table-column.js +3 -19
- package/dist/table/root/table-root.d.ts +31 -10
- package/dist/table/root/table-root.js +2 -13
- 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 +12 -0
- 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 +31 -4
- package/dist/tag/group/tag-group.js +46 -7
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +28 -1
- package/dist/textarea/root/textarea-root.js +40 -1
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +16 -8
- package/dist/time-picker/root/time-picker-root.d.ts +18 -4
- package/dist/time-picker/root/time-picker-root.js +7 -10
- 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 +14 -1
- package/dist/toast/item/toast-item.js +22 -5
- package/dist/toast/root/toast-root.d.ts +6 -0
- package/dist/toast/root/toast-root.js +16 -1
- package/dist/toggle/group/toggle-group.d.ts +24 -3
- package/dist/toggle/group/toggle-group.js +34 -5
- package/dist/tooltip/root/tooltip-root.d.ts +13 -2
- package/dist/tooltip/root/tooltip-root.js +9 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +30 -2
- package/dist/tour/root/tour-root.js +34 -8
- 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/root/trend-root.d.ts +43 -18
- package/dist/trend/root/trend-root.js +31 -6
- package/dist/video/media-events.d.ts +13 -18
- package/dist/video/media-events.js +1 -5
- package/dist/video/root/video-root.d.ts +18 -5
- 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 +7 -1
- package/dist/virtual-list/fill.d.ts +0 -8
- package/dist/virtual-list/fill.js +1 -17
- package/dist/virtual-list/plan.d.ts +49 -0
- package/dist/virtual-list/plan.js +16 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +114 -13
- package/dist/virtual-list/root/virtual-list-root.js +183 -40
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +4577 -835
- package/types/vue.d.ts +926 -168
- 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
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary An indicator that shows which way a measurement moved, and whether the change is good.
|
|
5
5
|
*
|
|
6
6
|
* @description
|
|
7
|
-
* A trend has three parts: a
|
|
8
|
-
* moved, and a label for the period it moved over. The arrow shows the
|
|
9
|
-
*
|
|
7
|
+
* A trend has three parts: a `movement` of up, down, or neutral, the metric
|
|
8
|
+
* that moved, and a label for the period it moved over. The arrow shows the
|
|
9
|
+
* movement and its color shows whether the change is good. Movement and
|
|
10
10
|
* judgment are separate properties because they are separate facts.
|
|
11
11
|
*
|
|
12
12
|
* `good` is unset by default, so a trend with no judgment is gray. For churn,
|
|
13
13
|
* latency, error rate, cost, and bounce rate, up is bad. Set the metric's
|
|
14
14
|
* polarity once with `good`, and the component picks the color from the
|
|
15
|
-
*
|
|
15
|
+
* movement. The judgment is also a custom state, `better` or `worse`, for a
|
|
16
|
+
* sheet of your own.
|
|
16
17
|
*
|
|
17
|
-
* The
|
|
18
|
+
* The movement is also written as a word, so a screen reader reads it. The
|
|
18
19
|
* styled tier hides `part="direction"` visually and keeps it in the
|
|
19
20
|
* accessibility tree. The words are properties, `up-label` through
|
|
20
|
-
* `worse-label`, so a page in another language can set its own.
|
|
21
|
+
* `worse-label`, so a page in another language can set its own. The arrow and
|
|
22
|
+
* any glyph slotted in its place are hidden from screen readers.
|
|
23
|
+
*
|
|
24
|
+
* Slot one glyph per movement into `up-icon`, `down-icon` and `neutral-icon`,
|
|
25
|
+
* and the trend shows the one that matches; a glyph in `icon` stands in for
|
|
26
|
+
* all three. Inside a `Stat`, put the trend in the stat's `trend` slot so it is
|
|
27
|
+
* read with the figure it qualifies.
|
|
21
28
|
*
|
|
22
29
|
* The metric and the label are bare slots. An element that assigned its own
|
|
23
30
|
* slot on connect would add an attribute to its host after upgrade, which the
|
|
@@ -30,11 +37,17 @@ import { type TemplateResult } from 'lit';
|
|
|
30
37
|
* @documentation https://fusion.dev/helix/components/trend
|
|
31
38
|
*
|
|
32
39
|
* @slot - The metric that moved.
|
|
33
|
-
* @slot icon - Replaces the arrow
|
|
40
|
+
* @slot down-icon - Replaces the arrow while `movement` is `down`. Hidden from screen readers.
|
|
41
|
+
* @slot icon - Replaces the arrow for every movement, such as with a glyph of your own set. Hidden from screen readers, since the movement is also a word.
|
|
34
42
|
* @slot label - The period the metric moved over.
|
|
43
|
+
* @slot neutral-icon - Replaces the bar while the trend has not moved. Hidden from screen readers.
|
|
44
|
+
* @slot up-icon - Replaces the arrow while `movement` is `up`. Hidden from screen readers.
|
|
35
45
|
*
|
|
36
|
-
* @csspart direction - The
|
|
46
|
+
* @csspart direction - The movement as a word, for people who cannot see the arrow.
|
|
37
47
|
* @csspart icon - The arrow.
|
|
48
|
+
*
|
|
49
|
+
* @cssstate better - The trend moved the way `good` names.
|
|
50
|
+
* @cssstate worse - The trend moved against the way `good` names.
|
|
38
51
|
*/
|
|
39
52
|
export declare class HelixHeadlessTrend extends HelixElement {
|
|
40
53
|
/**
|
|
@@ -42,14 +55,11 @@ export declare class HelixHeadlessTrend extends HelixElement {
|
|
|
42
55
|
*/
|
|
43
56
|
betterLabel: string;
|
|
44
57
|
/**
|
|
45
|
-
* Which way the measurement moved.
|
|
58
|
+
* Which way the measurement moved, as `movement` says it.
|
|
46
59
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* `
|
|
50
|
-
* attribute onto the host the moment the element upgrades, and the host is
|
|
51
|
-
* markup the consumer rendered, which React compares against what it rendered
|
|
52
|
-
* and reports as a hydration mismatch.
|
|
60
|
+
* @deprecated Use `movement`. `direction` is a layout on `Stat` and `Flex`,
|
|
61
|
+
* which are written beside a trend, so one word meant two things. Still read
|
|
62
|
+
* when `movement` is absent.
|
|
53
63
|
*/
|
|
54
64
|
direction?: 'down' | 'neutral' | 'up';
|
|
55
65
|
/**
|
|
@@ -57,14 +67,24 @@ export declare class HelixHeadlessTrend extends HelixElement {
|
|
|
57
67
|
*/
|
|
58
68
|
downLabel: string;
|
|
59
69
|
/**
|
|
60
|
-
* Which
|
|
70
|
+
* Which movement counts as an improvement for this metric.
|
|
61
71
|
*
|
|
62
72
|
* Absent states the movement without judging it, which is the honest default:
|
|
63
73
|
* revenue up is good news and latency up is bad news, and only the consumer
|
|
64
74
|
* knows which one this is. Set it once per metric and it holds while the
|
|
65
|
-
*
|
|
75
|
+
* movement changes underneath.
|
|
66
76
|
*/
|
|
67
77
|
good?: 'down' | 'up';
|
|
78
|
+
/**
|
|
79
|
+
* Which way the measurement moved.
|
|
80
|
+
*
|
|
81
|
+
* Absent is neutral, so a trend with nothing to report draws a bar rather
|
|
82
|
+
* than picking a direction. Optional rather than defaulted: a reflecting
|
|
83
|
+
* property with a default writes its attribute onto the host the moment the
|
|
84
|
+
* element upgrades, and the host is markup the consumer rendered, which React
|
|
85
|
+
* compares against what it rendered and reports as a hydration mismatch.
|
|
86
|
+
*/
|
|
87
|
+
movement?: 'down' | 'neutral' | 'up';
|
|
68
88
|
/**
|
|
69
89
|
* The word read out for no move, or for a direction that is not one of the
|
|
70
90
|
* three.
|
|
@@ -90,6 +110,11 @@ export declare class HelixHeadlessTrend extends HelixElement {
|
|
|
90
110
|
content: string;
|
|
91
111
|
viewBox: string;
|
|
92
112
|
}): TemplateResult;
|
|
113
|
+
/** The movement, read from `movement` and then from the old `direction`. */
|
|
114
|
+
private get moved();
|
|
115
|
+
/** Better or worse, or neither when `good` is unset or nothing moved. */
|
|
116
|
+
private get judged();
|
|
117
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
93
118
|
protected render(): TemplateResult;
|
|
94
119
|
}
|
|
95
120
|
declare global {
|
|
@@ -25,7 +25,7 @@ let HelixHeadlessTrend = class HelixHeadlessTrend extends HelixElement {
|
|
|
25
25
|
this.worseLabel = 'worse';
|
|
26
26
|
}
|
|
27
27
|
renderIcon(icon) {
|
|
28
|
-
return html `<slot name="icon"
|
|
28
|
+
return html `<slot aria-hidden="true" name="icon"
|
|
29
29
|
><svg
|
|
30
30
|
aria-hidden="true"
|
|
31
31
|
data-glyph
|
|
@@ -37,12 +37,34 @@ let HelixHeadlessTrend = class HelixHeadlessTrend extends HelixElement {
|
|
|
37
37
|
</svg></slot
|
|
38
38
|
>`;
|
|
39
39
|
}
|
|
40
|
+
get moved() {
|
|
41
|
+
return this.movement ?? this.direction;
|
|
42
|
+
}
|
|
43
|
+
get judged() {
|
|
44
|
+
const moved = this.moved;
|
|
45
|
+
if (!this.good || !moved || !(moved in DIRECTIONS) || moved === 'neutral') {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return this.good === moved ? 'better' : 'worse';
|
|
49
|
+
}
|
|
50
|
+
willUpdate(changed) {
|
|
51
|
+
super.willUpdate(changed);
|
|
52
|
+
const judged = this.judged;
|
|
53
|
+
this.toggleState('better', judged === 'better');
|
|
54
|
+
this.toggleState('worse', judged === 'worse');
|
|
55
|
+
}
|
|
40
56
|
render() {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
const moved = this.moved;
|
|
58
|
+
const direction = readDirection(moved);
|
|
59
|
+
const judged = this.judged;
|
|
60
|
+
const judgment = judged ? `, ${judged === 'better' ? this.betterLabel : this.worseLabel}` : '';
|
|
61
|
+
const icon = this.renderIcon(direction.icon);
|
|
62
|
+
const glyph = moved === 'up'
|
|
63
|
+
? html `<slot aria-hidden="true" name="up-icon">${icon}</slot>`
|
|
64
|
+
: moved === 'down'
|
|
65
|
+
? html `<slot aria-hidden="true" name="down-icon">${icon}</slot>`
|
|
66
|
+
: html `<slot aria-hidden="true" name="neutral-icon">${icon}</slot>`;
|
|
67
|
+
return html `${glyph}
|
|
46
68
|
<span part="direction">${`${this[direction.word]}${judgment}`}</span>
|
|
47
69
|
<slot></slot>
|
|
48
70
|
<slot name="label"></slot>`;
|
|
@@ -60,6 +82,9 @@ __decorate([
|
|
|
60
82
|
__decorate([
|
|
61
83
|
property({ reflect: true })
|
|
62
84
|
], HelixHeadlessTrend.prototype, "good", void 0);
|
|
85
|
+
__decorate([
|
|
86
|
+
property({ reflect: true })
|
|
87
|
+
], HelixHeadlessTrend.prototype, "movement", void 0);
|
|
63
88
|
__decorate([
|
|
64
89
|
property({ attribute: 'unchanged-label' })
|
|
65
90
|
], HelixHeadlessTrend.prototype, "unchangedLabel", void 0);
|
|
@@ -22,28 +22,23 @@ export declare const MEDIA_EVENTS: readonly ['abort', 'canplay', 'canplaythrough
|
|
|
22
22
|
/** One of the media events the player relays. */
|
|
23
23
|
export type MediaEventName = (typeof MEDIA_EVENTS)[number];
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* Hands each media event the video fires to `relay`, and returns what stops
|
|
26
|
+
* it. The player relays through `relayNativeEvent`, which sends the same name
|
|
27
|
+
* with the same `bubbles`, `cancelable` and `composed`.
|
|
26
28
|
*
|
|
27
|
-
* **As the platform sends it,
|
|
28
|
-
* all.** These names are in react-dom's
|
|
29
|
-
* on a `<video>` and never on a custom
|
|
30
|
-
* of them. `bindReactHandler` closes
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* copy sent with `bubbles: true`
|
|
34
|
-
* `onPlay` on the player
|
|
35
|
-
*
|
|
36
|
-
* Not cancelable, as the platform's are not: the media has already moved by the
|
|
37
|
-
* time the event is sent, and a refusal would have nothing to stop.
|
|
38
|
-
*/
|
|
39
|
-
export declare const relayedCopy: (event: Event) => Event;
|
|
40
|
-
/**
|
|
41
|
-
* Sends each media event the video fires on from the host, and returns what
|
|
42
|
-
* stops it.
|
|
29
|
+
* **As the platform sends it, neither bubbling nor composed, which is what
|
|
30
|
+
* makes it reach a React consumer at all.** These names are in react-dom's
|
|
31
|
+
* `nonDelegatedEvents`, which React wires on a `<video>` and never on a custom
|
|
32
|
+
* element, so its root listener hears none of them. `bindReactHandler` closes
|
|
33
|
+
* that for an event that does not bubble, and skips one that does, on the
|
|
34
|
+
* grounds that a bubbling relay already reaches React's delegated listener and
|
|
35
|
+
* binding it again would double every call. A copy sent with `bubbles: true`
|
|
36
|
+
* would land in the branch that refuses to bind, and `onPlay` on the player
|
|
37
|
+
* would be silent.
|
|
43
38
|
*
|
|
44
39
|
* Bound once, after the first render, so the player's own listeners in its
|
|
45
40
|
* template are ahead of it on the same video: what a consumer reads off the
|
|
46
41
|
* player in a handler (`paused`, `volume`, `currentTime`) is already the
|
|
47
42
|
* player's state by the time the copy reaches them.
|
|
48
43
|
*/
|
|
49
|
-
export declare const relayMedia: (video: EventTarget,
|
|
44
|
+
export declare const relayMedia: (video: EventTarget, relay: (event: Event) => void) => (() => void);
|
|
@@ -23,11 +23,7 @@ export const MEDIA_EVENTS = [
|
|
|
23
23
|
'volumechange',
|
|
24
24
|
'waiting',
|
|
25
25
|
];
|
|
26
|
-
export const
|
|
27
|
-
export const relayMedia = (video, host) => {
|
|
28
|
-
const relay = (event) => {
|
|
29
|
-
host.dispatchEvent(relayedCopy(event));
|
|
30
|
-
};
|
|
26
|
+
export const relayMedia = (video, relay) => {
|
|
31
27
|
for (const name of MEDIA_EVENTS) {
|
|
32
28
|
video.addEventListener(name, relay);
|
|
33
29
|
}
|
|
@@ -17,11 +17,22 @@ import '../../menu/index.js';
|
|
|
17
17
|
* not drawn, and the keys below are not bound, so a key press does not seek
|
|
18
18
|
* twice.
|
|
19
19
|
*
|
|
20
|
-
* The keys match other players, and they are bound on the
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* **Keyboard.** The keys match other players, and they are bound on the
|
|
21
|
+
* element only, so they work while focus is on the player.
|
|
22
|
+
*
|
|
23
|
+
* | Key | What it does |
|
|
24
|
+
* |---|---|
|
|
25
|
+
* | Space, `k` | Plays or pauses. Space on a button presses the button. |
|
|
26
|
+
* | Right, Left | Moves 5 seconds forward or back. |
|
|
27
|
+
* | Shift with Right or Left | Moves 10 seconds forward or back. |
|
|
28
|
+
* | `l`, `j` | Moves 10 seconds forward or back, as the skip buttons do. |
|
|
29
|
+
* | Up, Down | Raises or lowers the volume by a tenth. |
|
|
30
|
+
* | `m` | Mutes or unmutes. |
|
|
31
|
+
* | `f` | Enters or leaves fullscreen. |
|
|
32
|
+
* | Tab | Moves through the controls on the bar. |
|
|
33
|
+
*
|
|
34
|
+
* On the scrubber and the volume slider, the arrow keys, Page Up, Page Down,
|
|
35
|
+
* Home, and End move the slider, as on any range input.
|
|
25
36
|
*
|
|
26
37
|
* `<source>` and `<track>` children are copied into the video. A media element
|
|
27
38
|
* selects resources from its own child nodes, and a slot is one node, so
|
|
@@ -107,6 +118,8 @@ import '../../menu/index.js';
|
|
|
107
118
|
* @csspart entry-mark - The trailing mark: a check mark when the row is checked, or a caret when it opens a submenu.
|
|
108
119
|
* @csspart entry-shortcut - The key drawn for a row's shortcut. The player's rows set none.
|
|
109
120
|
* @csspart entry-shortcut-kbd - The key inside `entry-shortcut`.
|
|
121
|
+
* @csspart entry-shortcut-key - One key of a row's shortcut chord, inside `entry-shortcut`. The player's rows set none.
|
|
122
|
+
* @csspart entry-shortcut-separator - The `+` between two keys of a row's shortcut, where the platform writes one.
|
|
110
123
|
* @csspart entry-start - The leading column that holds the `start` slot. It is always rendered.
|
|
111
124
|
* @csspart failure - The message shown when the source cannot be played.
|
|
112
125
|
* @csspart forward - The button that skips forward ten seconds.
|
|
@@ -431,7 +431,7 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
431
431
|
this.silent = video.muted;
|
|
432
432
|
this.loudness = video.volume;
|
|
433
433
|
void this.remote.attach(video);
|
|
434
|
-
relayMedia(video, this);
|
|
434
|
+
relayMedia(video, (event) => this.relayNativeEvent(event));
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
updated(changed) {
|
|
@@ -560,7 +560,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
560
560
|
<${this.tag('menu-item')}
|
|
561
561
|
part="entry"
|
|
562
562
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
563
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
563
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
564
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
564
565
|
value="off"
|
|
565
566
|
checkable
|
|
566
567
|
exclusive
|
|
@@ -572,7 +573,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
572
573
|
</${this.tag('menu-item')}>
|
|
573
574
|
${tracks.map((track, at) => html `<${this.tag('menu-item')} part="entry"
|
|
574
575
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
575
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
576
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
577
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
576
578
|
value=${track.language || String(at)}
|
|
577
579
|
checkable
|
|
578
580
|
exclusive
|
|
@@ -600,7 +602,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
600
602
|
if (one === 'remote') {
|
|
601
603
|
return html `<${this.tag('menu-item')} part="entry"
|
|
602
604
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
603
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
605
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
606
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
604
607
|
value="remote"
|
|
605
608
|
@helix-select=${() => void this.remote.prompt()}
|
|
606
609
|
>
|
|
@@ -611,7 +614,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
611
614
|
if (one === 'speed') {
|
|
612
615
|
return html `<${this.tag('menu-item')} part="entry"
|
|
613
616
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
614
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
617
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
618
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start" value="speed" @helix-select=${() => this.cycleSpeed()}>
|
|
615
619
|
<slot name="speed-icon" slot="start">${drawIcon(gauge)}</slot>
|
|
616
620
|
${this.speedLabel}: ${this.rate}x
|
|
617
621
|
</${this.tag('menu-item')}>`;
|
|
@@ -620,7 +624,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
620
624
|
const back = one === 'rewind';
|
|
621
625
|
return html `<${this.tag('menu-item')} part="entry"
|
|
622
626
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
623
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
627
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
628
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
624
629
|
value=${one}
|
|
625
630
|
@helix-select=${() => this.skipBy(back ? -SKIP_SECONDS : SKIP_SECONDS)}
|
|
626
631
|
>
|
|
@@ -633,7 +638,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
633
638
|
if (one === 'previous') {
|
|
634
639
|
return html `<${this.tag('menu-item')} part="entry"
|
|
635
640
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
636
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
641
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
642
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start" value="previous" @helix-select=${() => this.skip(true)}>
|
|
637
643
|
<slot name="previous-icon" slot="start">${drawIcon(skipBack)}</slot>
|
|
638
644
|
${this.previousLabel}
|
|
639
645
|
</${this.tag('menu-item')}>`;
|
|
@@ -641,7 +647,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
641
647
|
if (one === 'next') {
|
|
642
648
|
return html `<${this.tag('menu-item')} part="entry"
|
|
643
649
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
644
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
650
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
651
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start" value="next" @helix-select=${() => this.skip(false)}>
|
|
645
652
|
<slot name="next-icon" slot="start">${drawIcon(skipForward)}</slot>
|
|
646
653
|
${this.nextLabel}
|
|
647
654
|
</${this.tag('menu-item')}>`;
|
|
@@ -650,7 +657,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
650
657
|
const local = ownFile(this.src);
|
|
651
658
|
return html `<${this.tag('menu-item')} part="entry"
|
|
652
659
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
653
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
660
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
661
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
654
662
|
?download=${local}
|
|
655
663
|
href=${this.src}
|
|
656
664
|
rel=${local ? nothing : 'noreferrer'}
|
|
@@ -663,7 +671,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
663
671
|
}
|
|
664
672
|
return html `<${this.tag('menu-item')} part="entry"
|
|
665
673
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
666
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
674
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
675
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start" value="pip" @helix-select=${() => void this.togglePip()}>
|
|
667
676
|
<slot name="pip-icon" slot="start">${drawIcon(pictureInPicture)}</slot>
|
|
668
677
|
${this.pipLabel}
|
|
669
678
|
</${this.tag('menu-item')}>`;
|
|
@@ -27,6 +27,8 @@ import '../../menu/index.js';
|
|
|
27
27
|
* @csspart entry-mark - The mark at the end of an entry: a check mark when it is checked, or a caret when it opens a submenu.
|
|
28
28
|
* @csspart entry-shortcut - The key drawn for an entry's shortcut. The playlist's entries set none.
|
|
29
29
|
* @csspart entry-shortcut-kbd - The key inside `entry-shortcut`.
|
|
30
|
+
* @csspart entry-shortcut-key - One key of an entry's shortcut chord, inside `entry-shortcut`. The playlist's entries set none.
|
|
31
|
+
* @csspart entry-shortcut-separator - The `+` between two keys of an entry's shortcut, where the platform writes one.
|
|
30
32
|
* @csspart entry-start - The column at the start of an entry. It is a slot and is always present.
|
|
31
33
|
* @csspart menu - The menu that holds the entries.
|
|
32
34
|
* @csspart menu-back - The button that goes back from a submenu.
|
|
@@ -86,7 +86,8 @@ let HelixHeadlessVideoPlaylistMenu = class HelixHeadlessVideoPlaylistMenu extend
|
|
|
86
86
|
${this.entries.map((entry) => html `<${this.tag('menu-item')}
|
|
87
87
|
part="entry"
|
|
88
88
|
exportparts="end: entry-end, item: entry-item, mark: entry-mark, shortcut: entry-shortcut,
|
|
89
|
-
shortcut-kbd: entry-shortcut-kbd,
|
|
89
|
+
shortcut-kbd: entry-shortcut-kbd, shortcut-key: entry-shortcut-key,
|
|
90
|
+
shortcut-separator: entry-shortcut-separator, start: entry-start"
|
|
90
91
|
value=${entry.value}
|
|
91
92
|
checkable
|
|
92
93
|
?checked=${entry.current}
|
|
@@ -29,6 +29,12 @@ declare const HelixHeadlessVideoPlaylist_base: (new (...args: any[]) => import("
|
|
|
29
29
|
* sends `helix-end`. `shuffle` plays the entries in a random order, starting
|
|
30
30
|
* from the one that is current, and `previous` retraces that order.
|
|
31
31
|
*
|
|
32
|
+
* **Keyboard.** Each entry is a button in the tab order, and Enter or Space
|
|
33
|
+
* plays it. The current entry carries `aria-current`. While focus is on the
|
|
34
|
+
* player, the player's own keys work, and `Video` lists them. Its previous
|
|
35
|
+
* and next controls move through the entries in the same order the playlist
|
|
36
|
+
* does.
|
|
37
|
+
*
|
|
32
38
|
* @since 0.1.0
|
|
33
39
|
* @status stable
|
|
34
40
|
* @category media
|
|
@@ -38,7 +44,7 @@ declare const HelixHeadlessVideoPlaylist_base: (new (...args: any[]) => import("
|
|
|
38
44
|
* @slot - The entries.
|
|
39
45
|
* @slot player - The player that plays the entries.
|
|
40
46
|
*
|
|
41
|
-
* @event {HelixActivateEvent} helix-activate - The current entry changed. The playlist already holds the new entry when this is sent.
|
|
47
|
+
* @event {HelixActivateEvent} helix-activate - The current entry changed. The playlist already holds the new entry when this is sent, and `detail.previous` is the entry it left.
|
|
42
48
|
* @event {HelixBeforeActivateEvent} helix-before-activate - The current entry is about to change. Cancelable: cancel it to keep the current entry.
|
|
43
49
|
* @event {HelixEndEvent} helix-end - The last entry finished playing, and the playlist stopped there. Not sent while `repeat` is set.
|
|
44
50
|
*
|
|
@@ -11,14 +11,6 @@
|
|
|
11
11
|
*
|
|
12
12
|
* A field is a key, or a path of keys joined by dots (`author.name`).
|
|
13
13
|
*/
|
|
14
|
-
/**
|
|
15
|
-
* The value at `path` in `item`, or `undefined` where the path leads nowhere.
|
|
16
|
-
*
|
|
17
|
-
* A dot separates keys, so `author.name` reads `item.author.name`. A key that
|
|
18
|
-
* holds a dot itself is read whole first, which keeps a flat record with a key
|
|
19
|
-
* such as `"v1.2"` working.
|
|
20
|
-
*/
|
|
21
|
-
export declare const valueAt: (item: unknown, path: string) => unknown;
|
|
22
14
|
/**
|
|
23
15
|
* The text a value takes in a row.
|
|
24
16
|
*
|
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
if (item === null || typeof item !== 'object') {
|
|
3
|
-
return undefined;
|
|
4
|
-
}
|
|
5
|
-
const record = item;
|
|
6
|
-
if (path in record) {
|
|
7
|
-
return record[path];
|
|
8
|
-
}
|
|
9
|
-
let value = record;
|
|
10
|
-
for (const key of path.split('.')) {
|
|
11
|
-
if (value === null || typeof value !== 'object') {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
value = value[key];
|
|
15
|
-
}
|
|
16
|
-
return value;
|
|
17
|
-
};
|
|
1
|
+
import { valueAt } from '@fusion.dev/helix-core';
|
|
18
2
|
export const textOf = (value) => value === undefined || value === null || typeof value === 'object' ? '' : String(value);
|
|
19
3
|
const ATTRIBUTE = 'data-field-';
|
|
20
4
|
const writeAttribute = (element, name, value) => {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one pass of a virtual list draws, worked out before any element moves.
|
|
3
|
+
*
|
|
4
|
+
* The list keeps the element of a row that stays in the window, so a pass
|
|
5
|
+
* compares what is drawn with what is wanted and changes only the difference.
|
|
6
|
+
* These are that comparison and the tab-stop rule that follows it, as
|
|
7
|
+
* arithmetic over item indices.
|
|
8
|
+
*/
|
|
9
|
+
/** What a pass does to the rows in the tree. */
|
|
10
|
+
export interface DrawPlan {
|
|
11
|
+
/** The items the pass draws, in order: the window, and a kept item outside it. */
|
|
12
|
+
wanted: number[];
|
|
13
|
+
/** The items whose rows leave the tree. */
|
|
14
|
+
remove: Set<number>;
|
|
15
|
+
}
|
|
16
|
+
/** The window, the set's length, the item kept outside the window, and the rows drawn. */
|
|
17
|
+
export interface DrawInput {
|
|
18
|
+
/** The first item of the window. */
|
|
19
|
+
first: number;
|
|
20
|
+
/** One past the last item of the window. */
|
|
21
|
+
last: number;
|
|
22
|
+
/** How many items the set holds. */
|
|
23
|
+
count: number;
|
|
24
|
+
/** The item drawn outside the window to keep or take focus, where there is one. */
|
|
25
|
+
kept?: number | undefined;
|
|
26
|
+
/** The item each drawn row element holds, `NaN` for an element that holds none. */
|
|
27
|
+
drawn: readonly number[];
|
|
28
|
+
/** Whether every drawn row is drawn again from nothing, as for a new way of drawing. */
|
|
29
|
+
redraw?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Which items a pass draws, and which drawn rows leave.
|
|
33
|
+
*
|
|
34
|
+
* A drawn row leaves when its item is not wanted, when it holds no item, or
|
|
35
|
+
* when everything is drawn again. A wanted item with no row left is drawn new.
|
|
36
|
+
*/
|
|
37
|
+
export declare const drawPlan: ({ count, drawn, first, kept, last, redraw, }: DrawInput) => DrawPlan;
|
|
38
|
+
/**
|
|
39
|
+
* Which item holds the list's tab stop after a pass.
|
|
40
|
+
*
|
|
41
|
+
* The item that held it, while its row is drawn. Otherwise the first item on
|
|
42
|
+
* screen, held inside the window and the set.
|
|
43
|
+
*/
|
|
44
|
+
export declare const stopAfter: (active: number, wanted: readonly number[], { count, first, last, onScreen, }: {
|
|
45
|
+
count: number;
|
|
46
|
+
first: number;
|
|
47
|
+
last: number;
|
|
48
|
+
onScreen: number;
|
|
49
|
+
}) => number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const drawPlan = ({ count, drawn, first, kept, last, redraw = false, }) => {
|
|
2
|
+
const wanted = [];
|
|
3
|
+
for (let at = first; at < Math.min(last, count); at += 1) {
|
|
4
|
+
wanted.push(at);
|
|
5
|
+
}
|
|
6
|
+
if (kept !== undefined && !wanted.includes(kept)) {
|
|
7
|
+
wanted.push(kept);
|
|
8
|
+
wanted.sort((a, b) => a - b);
|
|
9
|
+
}
|
|
10
|
+
const keep = new Set(wanted);
|
|
11
|
+
const remove = new Set(drawn.filter((index) => redraw || !Number.isInteger(index) || !keep.has(index)));
|
|
12
|
+
return { remove, wanted };
|
|
13
|
+
};
|
|
14
|
+
export const stopAfter = (active, wanted, { count, first, last, onScreen, }) => wanted.includes(active)
|
|
15
|
+
? active
|
|
16
|
+
: Math.max(Math.min(onScreen, Math.min(last, count) - 1), first, 0);
|