@fusion.dev/helix-headless 0.146.0 → 0.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +5266 -785
- package/dist/accordion/item/accordion-item.d.ts +38 -19
- package/dist/accordion/item/accordion-item.js +31 -9
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +13 -4
- package/dist/announcement/root/announcement-root.js +34 -6
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +11 -3
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +88 -5
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/chat/root/chat-root.d.ts +15 -1
- package/dist/chat/root/chat-root.js +11 -2
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.js +4 -3
- package/dist/checkbox-group/select-all.d.ts +0 -6
- package/dist/checkbox-group/select-all.js +0 -5
- package/dist/code-block/root/code-block-root.d.ts +35 -14
- package/dist/code-block/root/code-block-root.js +17 -3
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +101 -51
- package/dist/color-picker/wheel.d.ts +17 -0
- package/dist/color-picker/wheel.js +6 -0
- package/dist/combobox/root/combobox-root.d.ts +13 -0
- package/dist/combobox/root/combobox-root.js +14 -1
- package/dist/command/root/command-root.d.ts +3 -1
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +13 -7
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +18 -4
- package/dist/description-list/item/description-list-item.js +8 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +39 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +4 -1
- package/dist/empty/root/empty-root.d.ts +31 -1
- package/dist/empty/root/empty-root.js +26 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +54 -19
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +10 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +11 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/options.d.ts +3 -4
- package/dist/format-date/options.js +2 -2
- package/dist/format-date/root/format-date-root.d.ts +18 -1
- package/dist/format-date/root/format-date-root.js +19 -23
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +64 -3
- package/dist/heatmap/root/heatmap-root.js +89 -19
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +9 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +24 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +22 -10
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +26 -5
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +9 -5
- package/dist/listbox/root/listbox-root.js +29 -37
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +36 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +3 -0
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/notifications/root/notifications-root.d.ts +10 -1
- package/dist/notifications/root/notifications-root.js +11 -1
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +13 -6
- package/dist/object-inspector/root/object-inspector-root.js +18 -17
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +5 -0
- package/dist/pagination/size/pagination-size.js +4 -2
- package/dist/pin-input/code.d.ts +28 -1
- package/dist/pin-input/code.js +12 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +157 -148
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +17 -6
- package/dist/qr-code/root/qr-code-root.js +10 -12
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +30 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +34 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +59 -3
- package/dist/select/root/select-root.js +72 -12
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
- package/dist/speed-dial/item/speed-dial-item.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
- package/dist/speed-dial/root/speed-dial-root.js +9 -1
- package/dist/splitter/root/splitter-root.d.ts +3 -0
- package/dist/splitter/root/splitter-root.js +2 -0
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/root/table-root.js +13 -6
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +19 -7
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +11 -14
- package/dist/time-picker/root/time-picker-root.js +15 -23
- package/dist/toast/item/toast-item.d.ts +3 -3
- package/dist/toast/item/toast-item.js +0 -1
- package/dist/toast/root/toast-root.d.ts +28 -4
- package/dist/toast/root/toast-root.js +58 -12
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -41
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +21 -5
- package/dist/toolbar/root/toolbar-root.js +52 -8
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -1
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +5 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +48 -24
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2979 -738
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +619 -202
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** Which way a panel moved when another took its place along the bar. */
|
|
2
|
+
export type Motion = 'from-end' | 'from-start' | 'to-end' | 'to-start';
|
|
3
|
+
/** What a hand-over asks of a megamenu. */
|
|
4
|
+
export interface Handed extends Node {
|
|
5
|
+
/** Asks the panel to open or close, and returns whether it did. */
|
|
6
|
+
requestOpen(open: boolean): boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The bar's one open panel, handed from one megamenu to the next.
|
|
10
|
+
*
|
|
11
|
+
* A page has one panel open at a time: a nav bar whose Products panel is still
|
|
12
|
+
* down while Solutions opens is a nav bar with two panels over the page. Module
|
|
13
|
+
* scope rather than a coordinating parent, because there is nothing to
|
|
14
|
+
* coordinate through: megamenus sit in whatever container the consumer used,
|
|
15
|
+
* which is usually `Navigation` and is not required to be. `Video` holds the
|
|
16
|
+
* media session the same way and for the same reason.
|
|
17
|
+
*
|
|
18
|
+
* When one panel opens in place of another, each is told which way the reader
|
|
19
|
+
* moved, as Radix's `data-motion` does: toward the end of the bar where the
|
|
20
|
+
* one opening comes after the one closing in the document. The one opening
|
|
21
|
+
* enters from the side the reader moved toward, and the one closing leaves
|
|
22
|
+
* toward the side they came from. Only the latest move is ever described.
|
|
23
|
+
*/
|
|
24
|
+
export declare class HandOver<T extends Handed> {
|
|
25
|
+
private readonly motion;
|
|
26
|
+
/**
|
|
27
|
+
* Every megamenu on the page, so a press on another one's trigger counts as
|
|
28
|
+
* moving along the bar. Closing on that press would close this panel before
|
|
29
|
+
* the other opens, and the hand-over would have no direction.
|
|
30
|
+
*/
|
|
31
|
+
readonly connected: Set<T>;
|
|
32
|
+
/** The panel showing now, so opening one closes the last. */
|
|
33
|
+
showing: T | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The megamenu a pointer is pressing, from the press until the click that
|
|
36
|
+
* ends it. A press moves focus before the click opens anything, and the open
|
|
37
|
+
* panel must not close on that focus move, or the hand-over has no direction.
|
|
38
|
+
*/
|
|
39
|
+
pressed: T | undefined;
|
|
40
|
+
/** The panels closing because another opened in their place. */
|
|
41
|
+
private readonly handed;
|
|
42
|
+
/** @param motion Writes a megamenu's direction, and clears it for `undefined`. */
|
|
43
|
+
constructor(motion: (megamenu: T, to: Motion | undefined) => void);
|
|
44
|
+
/** Counts a megamenu as part of the bar. */
|
|
45
|
+
add(megamenu: T): void;
|
|
46
|
+
/** Stops counting a megamenu that left the page. */
|
|
47
|
+
remove(megamenu: T): void;
|
|
48
|
+
/**
|
|
49
|
+
* Forgets the press a task after it ends, so the click it makes still finds
|
|
50
|
+
* it. One function for every press, so a listener added again is the same
|
|
51
|
+
* listener and never a second one.
|
|
52
|
+
*/
|
|
53
|
+
private readonly release;
|
|
54
|
+
/**
|
|
55
|
+
* The megamenus that share this one's parent, in document order: the bar it
|
|
56
|
+
* is one trigger of.
|
|
57
|
+
*/
|
|
58
|
+
alongside(megamenu: T): T[];
|
|
59
|
+
/** Notes a press on a megamenu, until the press ends. */
|
|
60
|
+
press(megamenu: T): void;
|
|
61
|
+
/**
|
|
62
|
+
* Opens one panel in place of the one showing, and returns that one, if
|
|
63
|
+
* there was one. The other closes through `requestOpen`, so a consumer
|
|
64
|
+
* holding it open is asked rather than overruled, and a refusal clears its
|
|
65
|
+
* direction again.
|
|
66
|
+
*/
|
|
67
|
+
open(opening: T): T | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Notes a panel closing. One that closed on its own moved nowhere, and
|
|
70
|
+
* neither did any other, so every direction clears.
|
|
71
|
+
*/
|
|
72
|
+
close(closing: T): void;
|
|
73
|
+
/** Clears the direction of every megamenu but the ones moving. */
|
|
74
|
+
private settle;
|
|
75
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export class HandOver {
|
|
2
|
+
constructor(motion) {
|
|
3
|
+
this.motion = motion;
|
|
4
|
+
this.connected = new Set();
|
|
5
|
+
this.handed = new Set();
|
|
6
|
+
this.release = () => {
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
this.pressed = undefined;
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
add(megamenu) {
|
|
13
|
+
this.connected.add(megamenu);
|
|
14
|
+
}
|
|
15
|
+
remove(megamenu) {
|
|
16
|
+
this.connected.delete(megamenu);
|
|
17
|
+
this.handed.delete(megamenu);
|
|
18
|
+
if (this.showing === megamenu) {
|
|
19
|
+
this.showing = undefined;
|
|
20
|
+
}
|
|
21
|
+
if (this.pressed === megamenu) {
|
|
22
|
+
this.pressed = undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
alongside(megamenu) {
|
|
26
|
+
return [...this.connected]
|
|
27
|
+
.filter((other) => other.parentNode === megamenu.parentNode)
|
|
28
|
+
.sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));
|
|
29
|
+
}
|
|
30
|
+
press(megamenu) {
|
|
31
|
+
this.pressed = megamenu;
|
|
32
|
+
window.addEventListener('pointerup', this.release, { capture: true, once: true });
|
|
33
|
+
window.addEventListener('pointercancel', this.release, { capture: true, once: true });
|
|
34
|
+
}
|
|
35
|
+
open(opening) {
|
|
36
|
+
const previous = this.showing !== opening ? this.showing : undefined;
|
|
37
|
+
const forward = previous !== undefined &&
|
|
38
|
+
(previous.compareDocumentPosition(opening) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
|
|
39
|
+
this.motion(opening, previous ? (forward ? 'from-end' : 'from-start') : undefined);
|
|
40
|
+
this.settle(opening, previous);
|
|
41
|
+
if (previous) {
|
|
42
|
+
this.motion(previous, forward ? 'to-start' : 'to-end');
|
|
43
|
+
this.handed.add(previous);
|
|
44
|
+
if (!previous.requestOpen(false)) {
|
|
45
|
+
this.handed.delete(previous);
|
|
46
|
+
this.motion(previous, undefined);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.showing = opening;
|
|
50
|
+
return previous;
|
|
51
|
+
}
|
|
52
|
+
close(closing) {
|
|
53
|
+
if (this.showing === closing) {
|
|
54
|
+
this.showing = undefined;
|
|
55
|
+
}
|
|
56
|
+
if (!this.handed.delete(closing)) {
|
|
57
|
+
this.settle();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
settle(...moving) {
|
|
61
|
+
for (const megamenu of this.connected) {
|
|
62
|
+
if (!moving.includes(megamenu)) {
|
|
63
|
+
this.motion(megamenu, undefined);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HelixElement, PopoverController } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
1
|
+
import { HelixElement, KeyboardNavigationController, PopoverController } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary A section of a navigation with a trigger that opens a panel of links.
|
|
@@ -36,8 +36,17 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
|
|
|
36
36
|
* navigation menu publishes the same pair from its shared viewport, so a
|
|
37
37
|
* stylesheet can grow or shrink one panel into the next.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* The panel's default slot is the `columns` part and draws no box, so a sheet
|
|
40
|
+
* can give the columns one of their own. While a panel is open, an
|
|
41
|
+
* `indicator` slot is rendered beside its trigger, as Radix's indicator
|
|
42
|
+
* marks the open one: slot a mark of your own, such as a bar or an arrow
|
|
43
|
+
* pointing at the panel, and it shows only while the panel is open. The styled
|
|
44
|
+
* tier rests it on the trigger's bottom edge.
|
|
45
|
+
*
|
|
46
|
+
* Left and Right Arrow move between the triggers of the megamenus beside this
|
|
47
|
+
* one, and Home and End go to the first and the last, as Radix's navigation
|
|
48
|
+
* menu does. In a `Navigation`, which holds them in a slot, the arrows are the
|
|
49
|
+
* navigation's, and move between its destinations under its `arrows`. Down Arrow on the trigger of an open panel moves
|
|
41
50
|
* focus to the panel's first link, Escape closes the panel and returns focus
|
|
42
51
|
* to its trigger, and Tab moves through the panel's links and closes it on the
|
|
43
52
|
* way out. The trigger says `aria-expanded`, and the panel is a group named by
|
|
@@ -50,12 +59,15 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
|
|
|
50
59
|
* @documentation https://fusion.dev/helix/components/megamenu
|
|
51
60
|
*
|
|
52
61
|
* @slot - The panel's contents, such as your own lists of links and their headings.
|
|
62
|
+
* @slot indicator - A mark for the open trigger, shown while the panel is open, such as a bar or an arrow pointing at the panel.
|
|
53
63
|
* @slot trigger - The control that opens the panel. When it is empty, a button named by `label` is shown.
|
|
54
64
|
*
|
|
55
65
|
* @event {HelixBeforeCloseEvent} helix-before-close - The panel is about to close. Cancelable.
|
|
56
66
|
* @event {HelixBeforeOpenEvent} helix-before-open - The panel is about to open. Cancelable.
|
|
57
67
|
* @event {ToggleEvent} toggle - The panel opened or closed. Carries `newState` and `oldState`.
|
|
58
68
|
*
|
|
69
|
+
* @csspart columns - The panel's default slot. It draws no box until a sheet gives it a `display`.
|
|
70
|
+
* @csspart indicator - The `indicator` slot, rendered while the panel is open.
|
|
59
71
|
* @csspart surface - The floating panel that opens.
|
|
60
72
|
* @csspart trigger - The default trigger button, shown when the `trigger` slot is empty.
|
|
61
73
|
*
|
|
@@ -73,6 +85,8 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
|
|
|
73
85
|
* @cssstate to-start - The panel closed because one later in the bar opened, so it can leave toward the start.
|
|
74
86
|
*/
|
|
75
87
|
export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
88
|
+
/** The bar's one open panel, shared by every megamenu on the page. */
|
|
89
|
+
private static readonly bar;
|
|
76
90
|
/**
|
|
77
91
|
* The page width, in pixels, below which a card panel is shown as a band. At
|
|
78
92
|
* zero, it never is.
|
|
@@ -155,6 +169,17 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
|
155
169
|
* the consumer slotted, or the button drawn in its place.
|
|
156
170
|
*/
|
|
157
171
|
get navigationControl(): HTMLElement;
|
|
172
|
+
/**
|
|
173
|
+
* The arrows along a bar of megamenus that no component holds in a slot.
|
|
174
|
+
*
|
|
175
|
+
* Each megamenu's trigger is one stop, and a press counts only from a
|
|
176
|
+
* trigger, so an arrow among an open panel's links stays with the panel.
|
|
177
|
+
* Down and Up are reserved: Down enters an open panel. A megamenu whose
|
|
178
|
+
* parent is a component, and so holds it in a slot, passes no stops, so a
|
|
179
|
+
* `Navigation` around it decides the arrows, on or off, for every
|
|
180
|
+
* destination at once.
|
|
181
|
+
*/
|
|
182
|
+
protected readonly keys: KeyboardNavigationController;
|
|
158
183
|
/**
|
|
159
184
|
* Down Arrow on the trigger of an open panel moves focus to the panel's first
|
|
160
185
|
* link or control, as Radix's navigation menu does.
|
|
@@ -277,18 +302,10 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
|
277
302
|
*
|
|
278
303
|
* Before the render rather than after it, because the popover controller
|
|
279
304
|
* raises the panel from its own `hostUpdated`, which runs before `updated`:
|
|
280
|
-
* settled there, the two would be up together for a frame. The
|
|
281
|
-
*
|
|
282
|
-
* overruled.
|
|
305
|
+
* settled there, the two would be up together for a frame. The bookkeeping
|
|
306
|
+
* is `HandOver`'s.
|
|
283
307
|
*/
|
|
284
308
|
protected willUpdate(changed: PropertyValues): void;
|
|
285
|
-
/**
|
|
286
|
-
* Clears the direction of every panel but the two in a hand-over, so only
|
|
287
|
-
* the latest move is ever described.
|
|
288
|
-
*/
|
|
289
|
-
private static settle;
|
|
290
|
-
/** Whether the panel is closing because another one opened in its place. */
|
|
291
|
-
private handedOver;
|
|
292
309
|
/** The panel's size the last time it was open, in pixels. */
|
|
293
310
|
private size;
|
|
294
311
|
/** The size of the panel this one took over from, if it took over. */
|
|
@@ -312,6 +329,13 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
|
|
|
312
329
|
* has one reaches this without reimplementing the panel below it.
|
|
313
330
|
*/
|
|
314
331
|
protected renderTrigger(): TemplateResult;
|
|
332
|
+
/**
|
|
333
|
+
* The mark under the trigger, while the panel is open. Rendered only then,
|
|
334
|
+
* so a mark of your own needs no rule to hide it while the panel is closed,
|
|
335
|
+
* and hidden from the accessibility tree: the trigger's `aria-expanded`
|
|
336
|
+
* already says the panel is open.
|
|
337
|
+
*/
|
|
338
|
+
protected renderIndicator(): TemplateResult | typeof nothing;
|
|
315
339
|
protected render(): TemplateResult;
|
|
316
340
|
}
|
|
317
341
|
declare global {
|
|
@@ -5,17 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessMegamenu_1;
|
|
8
|
-
import { anchorElement, customElement, deepContains, focusableElements, HelixElement, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { anchorElement, customElement, deepContains, focusableElements, HelixElement, KeyboardNavigationController, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
|
-
|
|
12
|
-
const connected = new Set();
|
|
13
|
-
let pressed;
|
|
14
|
-
const release = () => {
|
|
15
|
-
setTimeout(() => {
|
|
16
|
-
pressed = undefined;
|
|
17
|
-
});
|
|
18
|
-
};
|
|
11
|
+
import { HandOver } from '../hand-over.js';
|
|
19
12
|
let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerOpen(HelixElement) {
|
|
20
13
|
constructor() {
|
|
21
14
|
super(...arguments);
|
|
@@ -28,13 +21,31 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
28
21
|
};
|
|
29
22
|
this.panel = new PopoverController(this, {
|
|
30
23
|
anchor: () => this.trigger,
|
|
31
|
-
boundary: () => [...connected],
|
|
24
|
+
boundary: () => [...HelixHeadlessMegamenu_1.bar.connected],
|
|
32
25
|
onDismiss: () => this.close(),
|
|
33
26
|
open: () => this.open,
|
|
34
27
|
place: () => !this.banded,
|
|
35
28
|
placement: () => 'bottom-start',
|
|
36
29
|
surface: () => this.partNamed('surface'),
|
|
37
30
|
});
|
|
31
|
+
this.keys = new KeyboardNavigationController(this, {
|
|
32
|
+
items: () => !this.parentElement?.shadowRoot
|
|
33
|
+
? HelixHeadlessMegamenu_1.bar.alongside(this).map((megamenu) => ({
|
|
34
|
+
contains: (node) => {
|
|
35
|
+
const control = megamenu.trigger;
|
|
36
|
+
return node === control || control.contains(node);
|
|
37
|
+
},
|
|
38
|
+
disabled: false,
|
|
39
|
+
focusItem: () => megamenu.trigger.focus(),
|
|
40
|
+
select: () => { },
|
|
41
|
+
selected: false,
|
|
42
|
+
}))
|
|
43
|
+
: [],
|
|
44
|
+
origin: 'focus',
|
|
45
|
+
reserved: () => ['ArrowDown', 'ArrowUp'],
|
|
46
|
+
selects: () => false,
|
|
47
|
+
wrap: false,
|
|
48
|
+
});
|
|
38
49
|
this.handleKeyDown = (event) => {
|
|
39
50
|
if (event.key !== 'ArrowDown' || !this.open || event.defaultPrevented) {
|
|
40
51
|
return;
|
|
@@ -61,14 +72,13 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
61
72
|
};
|
|
62
73
|
this.handlePointerDown = (event) => {
|
|
63
74
|
this.pointer = event.pointerType;
|
|
64
|
-
|
|
65
|
-
window.addEventListener('pointerup', release, { capture: true, once: true });
|
|
66
|
-
window.addEventListener('pointercancel', release, { capture: true, once: true });
|
|
75
|
+
HelixHeadlessMegamenu_1.bar.press(this);
|
|
67
76
|
};
|
|
68
77
|
this.handlePointerEnter = (event) => {
|
|
69
78
|
if (this.openOn !== 'hover' || event.pointerType !== 'mouse') {
|
|
70
79
|
return;
|
|
71
80
|
}
|
|
81
|
+
const showing = HelixHeadlessMegamenu_1.bar.showing;
|
|
72
82
|
this.schedule(showing && showing !== this ? 0 : HelixHeadlessMegamenu_1.OPEN_DELAY, () => {
|
|
73
83
|
this.requestOpen(true);
|
|
74
84
|
});
|
|
@@ -86,6 +96,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
86
96
|
if (!this.open || next === null || deepContains(this, next)) {
|
|
87
97
|
return;
|
|
88
98
|
}
|
|
99
|
+
const pressed = HelixHeadlessMegamenu_1.bar.pressed;
|
|
89
100
|
if (pressed !== undefined && pressed !== this && deepContains(pressed, next)) {
|
|
90
101
|
return;
|
|
91
102
|
}
|
|
@@ -119,9 +130,9 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
119
130
|
}
|
|
120
131
|
this.requestOpen(false);
|
|
121
132
|
};
|
|
122
|
-
this.handedOver = false;
|
|
123
133
|
}
|
|
124
134
|
static { HelixHeadlessMegamenu_1 = this; }
|
|
135
|
+
static { this.bar = new HandOver((megamenu, to) => megamenu.motion(to)); }
|
|
125
136
|
get banded() {
|
|
126
137
|
return this.variant === 'band' || this.narrow;
|
|
127
138
|
}
|
|
@@ -191,7 +202,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
191
202
|
connectedCallback() {
|
|
192
203
|
super.connectedCallback();
|
|
193
204
|
this.watchWidth();
|
|
194
|
-
|
|
205
|
+
HelixHeadlessMegamenu_1.bar.add(this);
|
|
195
206
|
window.addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
|
|
196
207
|
this.addEventListener('pointerdown', this.handlePointerDown);
|
|
197
208
|
this.addEventListener('click', this.handleContentClick);
|
|
@@ -211,11 +222,8 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
211
222
|
this.removeEventListener('pointerleave', this.handlePointerLeave);
|
|
212
223
|
this.removeEventListener('focusout', this.handleFocusOut);
|
|
213
224
|
this.removeEventListener('keydown', this.handleKeyDown);
|
|
214
|
-
|
|
225
|
+
HelixHeadlessMegamenu_1.bar.remove(this);
|
|
215
226
|
this.stop();
|
|
216
|
-
if (showing === this) {
|
|
217
|
-
showing = undefined;
|
|
218
|
-
}
|
|
219
227
|
}
|
|
220
228
|
willUpdate(changed) {
|
|
221
229
|
super.willUpdate(changed);
|
|
@@ -223,37 +231,10 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
223
231
|
return;
|
|
224
232
|
}
|
|
225
233
|
if (this.open) {
|
|
226
|
-
|
|
227
|
-
const forward = previous !== undefined &&
|
|
228
|
-
(previous.compareDocumentPosition(this) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
|
|
229
|
-
this.motion(previous ? (forward ? 'from-end' : 'from-start') : undefined);
|
|
230
|
-
this.from = previous?.size;
|
|
231
|
-
HelixHeadlessMegamenu_1.settle(this, previous);
|
|
232
|
-
if (previous) {
|
|
233
|
-
previous.motion(forward ? 'to-start' : 'to-end');
|
|
234
|
-
previous.handedOver = true;
|
|
235
|
-
if (!previous.requestOpen(false)) {
|
|
236
|
-
previous.handedOver = false;
|
|
237
|
-
previous.motion(undefined);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
showing = this;
|
|
234
|
+
this.from = HelixHeadlessMegamenu_1.bar.open(this)?.size;
|
|
241
235
|
return;
|
|
242
236
|
}
|
|
243
|
-
|
|
244
|
-
showing = undefined;
|
|
245
|
-
}
|
|
246
|
-
if (!this.handedOver) {
|
|
247
|
-
HelixHeadlessMegamenu_1.settle();
|
|
248
|
-
}
|
|
249
|
-
this.handedOver = false;
|
|
250
|
-
}
|
|
251
|
-
static settle(...moving) {
|
|
252
|
-
for (const megamenu of connected) {
|
|
253
|
-
if (!moving.includes(megamenu)) {
|
|
254
|
-
megamenu.motion(undefined);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
237
|
+
HelixHeadlessMegamenu_1.bar.close(this);
|
|
257
238
|
}
|
|
258
239
|
measure() {
|
|
259
240
|
const surface = this.partNamed('surface');
|
|
@@ -301,8 +282,13 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
301
282
|
</button>
|
|
302
283
|
</slot>`;
|
|
303
284
|
}
|
|
285
|
+
renderIndicator() {
|
|
286
|
+
return this.open
|
|
287
|
+
? html `<slot name="indicator" part="indicator" aria-hidden="true"></slot>`
|
|
288
|
+
: nothing;
|
|
289
|
+
}
|
|
304
290
|
render() {
|
|
305
|
-
return html `${this.renderTrigger()}
|
|
291
|
+
return html `${this.renderTrigger()}${this.renderIndicator()}
|
|
306
292
|
<div
|
|
307
293
|
part="surface"
|
|
308
294
|
id="panel"
|
|
@@ -311,7 +297,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
|
|
|
311
297
|
role="group"
|
|
312
298
|
?hidden=${!this.open}
|
|
313
299
|
>
|
|
314
|
-
<slot></slot>
|
|
300
|
+
<slot part="columns"></slot>
|
|
315
301
|
</div>`;
|
|
316
302
|
}
|
|
317
303
|
};
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { ariaChord, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, onApple, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ariaChord, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, onApple, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight, check } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -33,15 +33,15 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
|
|
|
33
33
|
this.description = false;
|
|
34
34
|
this.readStart = () => {
|
|
35
35
|
const slot = this.renderRoot.querySelector('slot[name="start"]');
|
|
36
|
-
this.start = (slot
|
|
36
|
+
this.start = slotFilled(slot);
|
|
37
37
|
};
|
|
38
38
|
this.readEnd = () => {
|
|
39
39
|
const slot = this.renderRoot.querySelector('slot[name="end"]');
|
|
40
|
-
this.end = (slot
|
|
40
|
+
this.end = slotFilled(slot);
|
|
41
41
|
};
|
|
42
42
|
this.readDescription = () => {
|
|
43
43
|
const slot = this.renderRoot.querySelector('slot[name="description"]');
|
|
44
|
-
this.description = (slot
|
|
44
|
+
this.description = slotFilled(slot);
|
|
45
45
|
};
|
|
46
46
|
this.readSubmenu = () => {
|
|
47
47
|
const slot = this.renderRoot.querySelector('slot[name="submenu"]');
|
|
@@ -71,6 +71,9 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
|
|
|
71
71
|
* @csspart surface - The floating panel the menu is drawn on.
|
|
72
72
|
* @csspart title - The name of the submenu that is showing.
|
|
73
73
|
*
|
|
74
|
+
* @cssproperty --floating-anchor-inline-size - The trigger's width, written on the panel while it is open, as in `min-inline-size: var(--floating-anchor-inline-size)`. Read it; a value set here is written over.
|
|
75
|
+
* @cssproperty --floating-available-block-size - The room between the panel and the edge of the screen it opens toward, written on the panel while it is open. Read it; a value set here is written over.
|
|
76
|
+
*
|
|
74
77
|
* @cssstate drilled - A submenu's page is showing, so content that is not a row can hide with the top page.
|
|
75
78
|
* @cssstate mark - A row on the current page has a checkbox or a link, so every row keeps the trailing column.
|
|
76
79
|
* @cssstate open - While the menu is open.
|
|
@@ -16,6 +16,15 @@ export type MeterBand = 'fair' | 'good' | 'poor';
|
|
|
16
16
|
* band. `optimum` sets the preferred band. The band next to it is fair, and the
|
|
17
17
|
* band two away is poor.
|
|
18
18
|
*
|
|
19
|
+
* The band is a custom state on the meter, `good`, `fair` or `poor`, beside
|
|
20
|
+
* `over` and `under` for a value past an end, so a page styles the meter
|
|
21
|
+
* around the fill as well as the fill.
|
|
22
|
+
*
|
|
23
|
+
* **`live` says the reading when it moves into another band**, such as "92%,
|
|
24
|
+
* Poor", in a polite region, for a meter whose value changes while a reader is
|
|
25
|
+
* on the page: a disk filling or a battery draining. The band's word comes from
|
|
26
|
+
* `band-labels`.
|
|
27
|
+
*
|
|
19
28
|
* @since 0.1.0
|
|
20
29
|
* @status stable
|
|
21
30
|
* @category feedback
|
|
@@ -24,6 +33,8 @@ export type MeterBand = 'fair' | 'good' | 'poor';
|
|
|
24
33
|
*
|
|
25
34
|
* @slot label - A visible label. Its words name the meter in place of `label`.
|
|
26
35
|
*
|
|
36
|
+
* @event {HelixBandEvent} helix-band - Fired when the reading moves into another band, with the band it is in now, or `''` where it is in none. Not sent on the first render, since a meter that arrives in a band has not moved.
|
|
37
|
+
*
|
|
27
38
|
* @csspart groove - The unfilled circle, in `ring` and `arc`.
|
|
28
39
|
* @csspart indicator - The part of the track the value fills.
|
|
29
40
|
* @csspart indicator-fair - The fill while the reading is in a band next to the good band. Set alongside `indicator`.
|
|
@@ -31,6 +42,7 @@ export type MeterBand = 'fair' | 'good' | 'poor';
|
|
|
31
42
|
* @csspart indicator-over - The fill while the value is above `max`. Set alongside `indicator`.
|
|
32
43
|
* @csspart indicator-poor - The fill while the reading is two bands from the good band. Set alongside `indicator`.
|
|
33
44
|
* @csspart indicator-under - The fill while the value is below `min`. Set alongside `indicator`.
|
|
45
|
+
* @csspart live - A polite region that says the reading as it moves into another band, under `live`, rendered from the first time it does. Hide it visually.
|
|
34
46
|
* @csspart tick - A mark at `low` or at `high`.
|
|
35
47
|
* @csspart track - The whole range, or the drawing in `ring` and `arc`.
|
|
36
48
|
* @csspart value - The reading as text, shown when `show-value` is set.
|
|
@@ -39,6 +51,12 @@ export type MeterBand = 'fair' | 'good' | 'poor';
|
|
|
39
51
|
* @cssproperty --meter-at - Where a bound sits on a linear track, as a percentage.
|
|
40
52
|
* @cssproperty --meter-fraction - The value as a fraction of the range, 0 to 1.
|
|
41
53
|
* @cssproperty --meter-sweep - How much of the circle the arc covers, as a path length.
|
|
54
|
+
*
|
|
55
|
+
* @cssstate fair - The reading is in a band next to the good band.
|
|
56
|
+
* @cssstate good - The reading is in the good band.
|
|
57
|
+
* @cssstate over - The value is above `max`.
|
|
58
|
+
* @cssstate poor - The reading is two bands from the good band.
|
|
59
|
+
* @cssstate under - The value is below `min`.
|
|
42
60
|
*/
|
|
43
61
|
export declare class HelixHeadlessMeter extends HelixElement {
|
|
44
62
|
/**
|
|
@@ -71,6 +89,13 @@ export declare class HelixHeadlessMeter extends HelixElement {
|
|
|
71
89
|
* no reader.
|
|
72
90
|
*/
|
|
73
91
|
band?: MeterBand;
|
|
92
|
+
/**
|
|
93
|
+
* The words each band is said with under `live`, by its name, written as
|
|
94
|
+
* JSON in the attribute: `band-labels='{"poor":"Almost full"}'`.
|
|
95
|
+
*
|
|
96
|
+
* A band left out keeps its default: "Good", "Fair" or "Poor".
|
|
97
|
+
*/
|
|
98
|
+
bandLabels: Partial<Record<MeterBand, string>>;
|
|
74
99
|
/**
|
|
75
100
|
* `Intl.NumberFormat` options the reading is written with, as React Aria's
|
|
76
101
|
* Meter and ProgressBar take them: a unit, a currency, or a number of
|
|
@@ -99,6 +124,15 @@ export declare class HelixHeadlessMeter extends HelixElement {
|
|
|
99
124
|
* shows, so the name and the label cannot disagree.
|
|
100
125
|
*/
|
|
101
126
|
label: string;
|
|
127
|
+
/**
|
|
128
|
+
* Says the reading in a polite `live` region each time it moves into
|
|
129
|
+
* another band, with the band's word, such as "92%, Poor".
|
|
130
|
+
*
|
|
131
|
+
* For a meter whose value changes while it is on screen. Off by default,
|
|
132
|
+
* because a meter that reads a fixed level has nothing new to say. A meter
|
|
133
|
+
* with no bands says nothing.
|
|
134
|
+
*/
|
|
135
|
+
live: boolean;
|
|
102
136
|
/**
|
|
103
137
|
* The locale the percentage is written in, such as `fr` for `72 %`.
|
|
104
138
|
*
|
|
@@ -171,6 +205,13 @@ export declare class HelixHeadlessMeter extends HelixElement {
|
|
|
171
205
|
* fair summary of a task and a poor one of a quantity.
|
|
172
206
|
*/
|
|
173
207
|
valueText: string;
|
|
208
|
+
/** The region `live` speaks in, rendered from the first time it does. */
|
|
209
|
+
private readonly status;
|
|
210
|
+
/**
|
|
211
|
+
* The band at the last update, so a move into another one is heard once:
|
|
212
|
+
* an empty string for none, and undefined before the first update.
|
|
213
|
+
*/
|
|
214
|
+
private lastBand;
|
|
174
215
|
/** The range, clamped so `max` is never at or below `min`. */
|
|
175
216
|
private get span();
|
|
176
217
|
/** The reading, pulled into the range. */
|
|
@@ -221,6 +262,7 @@ export declare class HelixHeadlessMeter extends HelixElement {
|
|
|
221
262
|
*/
|
|
222
263
|
private get text();
|
|
223
264
|
protected willUpdate(changed: PropertyValues): void;
|
|
265
|
+
protected updated(changed: PropertyValues): void;
|
|
224
266
|
/**
|
|
225
267
|
* The same reading, drawn round.
|
|
226
268
|
*
|
|
@@ -4,20 +4,23 @@ 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,
|
|
7
|
+
import { customElement, drawStatus, HelixBandEvent, HelixElement, hostAria, readingText, StatusController, slottedWords, wordsConverter, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
-
const
|
|
10
|
+
const BAND_WORDS = { fair: 'Fair', good: 'Good', poor: 'Poor' };
|
|
11
11
|
let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
|
+
this.bandLabels = {};
|
|
14
15
|
this.label = 'Meter';
|
|
16
|
+
this.live = false;
|
|
15
17
|
this.locale = '';
|
|
16
18
|
this.max = 100;
|
|
17
19
|
this.min = 0;
|
|
18
20
|
this.showValue = false;
|
|
19
21
|
this.value = 0;
|
|
20
22
|
this.valueText = '';
|
|
23
|
+
this.status = new StatusController(this);
|
|
21
24
|
this.renamed = () => {
|
|
22
25
|
this.requestUpdate();
|
|
23
26
|
};
|
|
@@ -69,11 +72,8 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
|
69
72
|
return distance === 0 ? 'good' : distance === 1 ? 'fair' : 'poor';
|
|
70
73
|
}
|
|
71
74
|
get text() {
|
|
72
|
-
const options = this.formatOptions;
|
|
73
75
|
return (this.valueText ||
|
|
74
|
-
(
|
|
75
|
-
? formatNumber(Number.isFinite(this.value) ? this.value : this.span.min, this.locale, options)
|
|
76
|
-
: formatNumber(this.ratio, this.locale, options ?? WHOLE_PERCENT)));
|
|
76
|
+
readingText(Number.isFinite(this.value) ? this.value : this.span.min, this.ratio, this.locale, this.formatOptions));
|
|
77
77
|
}
|
|
78
78
|
willUpdate(changed) {
|
|
79
79
|
super.willUpdate(changed);
|
|
@@ -84,6 +84,26 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
|
84
84
|
this.internals.ariaValueNow = String(this.reading);
|
|
85
85
|
this.internals.ariaValueText =
|
|
86
86
|
this.valueText || this.formatOptions !== undefined || this.beyond ? this.text : null;
|
|
87
|
+
const band = this.computedBand;
|
|
88
|
+
const beyond = this.beyond;
|
|
89
|
+
this.toggleState('fair', band === 'fair');
|
|
90
|
+
this.toggleState('good', band === 'good');
|
|
91
|
+
this.toggleState('poor', band === 'poor');
|
|
92
|
+
this.toggleState('over', beyond === 'over');
|
|
93
|
+
this.toggleState('under', beyond === 'under');
|
|
94
|
+
}
|
|
95
|
+
updated(changed) {
|
|
96
|
+
super.updated(changed);
|
|
97
|
+
const band = this.computedBand;
|
|
98
|
+
const moved = this.lastBand !== undefined && (band ?? '') !== this.lastBand;
|
|
99
|
+
this.lastBand = band ?? '';
|
|
100
|
+
if (!moved) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.dispatchEvent(new HelixBandEvent({ band: band ?? '' }));
|
|
104
|
+
if (band && this.live) {
|
|
105
|
+
this.status.say(`${this.text}, ${this.bandLabels[band] ?? BAND_WORDS[band]}`);
|
|
106
|
+
}
|
|
87
107
|
}
|
|
88
108
|
renderRound() {
|
|
89
109
|
const bounds = this.thresholds;
|
|
@@ -131,12 +151,15 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
|
131
151
|
style="--meter-fraction: ${this.fraction}"
|
|
132
152
|
></div>
|
|
133
153
|
</div>`}
|
|
134
|
-
${this.showValue ? html `<span part="value">${this.text}</span>` : nothing}`;
|
|
154
|
+
${this.showValue ? html `<span part="value">${this.text}</span>` : nothing}${drawStatus(this.status)}`;
|
|
135
155
|
}
|
|
136
156
|
};
|
|
137
157
|
__decorate([
|
|
138
158
|
property()
|
|
139
159
|
], HelixHeadlessMeter.prototype, "band", void 0);
|
|
160
|
+
__decorate([
|
|
161
|
+
property({ attribute: 'band-labels', converter: wordsConverter })
|
|
162
|
+
], HelixHeadlessMeter.prototype, "bandLabels", void 0);
|
|
140
163
|
__decorate([
|
|
141
164
|
property({ attribute: 'format-options', type: Object })
|
|
142
165
|
], HelixHeadlessMeter.prototype, "formatOptions", void 0);
|
|
@@ -146,6 +169,9 @@ __decorate([
|
|
|
146
169
|
__decorate([
|
|
147
170
|
property()
|
|
148
171
|
], HelixHeadlessMeter.prototype, "label", void 0);
|
|
172
|
+
__decorate([
|
|
173
|
+
property({ type: Boolean })
|
|
174
|
+
], HelixHeadlessMeter.prototype, "live", void 0);
|
|
149
175
|
__decorate([
|
|
150
176
|
property()
|
|
151
177
|
], HelixHeadlessMeter.prototype, "locale", void 0);
|