@fusion.dev/helix-headless 0.142.1 → 0.143.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 +16710 -707
- package/dist/accordion/item/accordion-item.d.ts +38 -2
- package/dist/accordion/item/accordion-item.js +38 -6
- package/dist/accordion/root/accordion-root.d.ts +23 -1
- package/dist/accordion/root/accordion-root.js +39 -3
- package/dist/announcement/root/announcement-root.d.ts +11 -7
- package/dist/announcement/root/announcement-root.js +1 -1
- package/dist/app-header/root/app-header-root.d.ts +21 -0
- package/dist/app-header/root/app-header-root.js +31 -5
- package/dist/area-chart/root/area-chart-root.js +16 -5
- package/dist/avatar/group/avatar-group.d.ts +24 -3
- package/dist/avatar/group/avatar-group.js +34 -2
- package/dist/avatar/root/avatar-root.d.ts +3 -1
- package/dist/avatar/root/avatar-root.js +8 -1
- package/dist/badge/root/badge-root.d.ts +8 -0
- package/dist/bar-chart/root/bar-chart-root.d.ts +19 -3
- package/dist/bar-chart/root/bar-chart-root.js +43 -13
- package/dist/blockquote/root/blockquote-root.d.ts +12 -7
- package/dist/blockquote/root/blockquote-root.js +6 -4
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
- package/dist/button/root/button-root.d.ts +37 -0
- package/dist/button/root/button-root.js +44 -0
- package/dist/callout/root/callout-root.d.ts +14 -5
- package/dist/callout/root/callout-root.js +11 -3
- package/dist/canvas/root/canvas-root.d.ts +1 -0
- package/dist/canvas/root/canvas-root.js +10 -1
- package/dist/carousel/root/carousel-root.d.ts +47 -5
- package/dist/carousel/root/carousel-root.js +53 -21
- package/dist/chat/composer/chat-composer.d.ts +13 -11
- package/dist/chat/composer/chat-composer.js +6 -12
- package/dist/chat/message/chat-message.js +8 -1
- package/dist/chat/root/chat-root.d.ts +1 -0
- package/dist/chat/root/chat-root.js +2 -1
- package/dist/checkbox/root/checkbox-root.d.ts +7 -0
- package/dist/checkbox/root/checkbox-root.js +7 -3
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +65 -32
- package/dist/checkbox-group/root/checkbox-group-root.js +85 -37
- package/dist/code/root/code-root.d.ts +1 -1
- package/dist/code-block/root/code-block-root.d.ts +19 -0
- package/dist/code-block/root/code-block-root.js +21 -1
- package/dist/color-input/root/color-input-root.d.ts +26 -1
- package/dist/color-input/root/color-input-root.js +32 -3
- package/dist/color-picker/root/color-picker-root.d.ts +37 -7
- package/dist/color-picker/root/color-picker-root.js +83 -6
- package/dist/combobox/root/combobox-root.d.ts +90 -2
- package/dist/combobox/root/combobox-root.js +160 -19
- package/dist/command/root/command-root.d.ts +17 -6
- package/dist/command/root/command-root.js +12 -1
- package/dist/copy-button/root/copy-button-root.d.ts +21 -6
- package/dist/copy-button/root/copy-button-root.js +11 -1
- package/dist/data-table/root/data-table-root.d.ts +164 -10
- package/dist/data-table/root/data-table-root.js +488 -57
- package/dist/date-input/root/date-input-root.d.ts +53 -8
- package/dist/date-input/root/date-input-root.js +70 -18
- package/dist/date-picker/root/date-picker-root.d.ts +84 -17
- package/dist/date-picker/root/date-picker-root.js +125 -20
- package/dist/dialog/root/dialog-root.d.ts +38 -10
- package/dist/dialog/root/dialog-root.js +55 -2
- package/dist/donut-chart/root/donut-chart-root.d.ts +39 -15
- package/dist/donut-chart/root/donut-chart-root.js +30 -10
- package/dist/drawer/root/drawer-root.d.ts +32 -7
- package/dist/drawer/root/drawer-root.js +50 -5
- package/dist/drilldown/item/drilldown-item.d.ts +16 -13
- package/dist/drilldown/item/drilldown-item.js +6 -2
- package/dist/drilldown/root/drilldown-root.d.ts +21 -5
- package/dist/drilldown/root/drilldown-root.js +26 -10
- package/dist/element-events.generated.js +35 -9
- package/dist/file-input/root/file-input-root.d.ts +18 -1
- package/dist/file-input/root/file-input-root.js +34 -8
- package/dist/filter-input/menu/filter-menu.d.ts +9 -0
- package/dist/filter-input/menu/filter-menu.js +8 -0
- package/dist/filter-input/root/filter-input-root.d.ts +5 -2
- package/dist/filter-input/root/filter-input-root.js +22 -7
- package/dist/format-date/root/format-date-root.d.ts +11 -3
- package/dist/format-date/root/format-date-root.js +26 -5
- package/dist/graph/root/graph-root.d.ts +24 -3
- package/dist/graph/root/graph-root.js +66 -12
- package/dist/heatmap/root/buckets.d.ts +2 -1
- package/dist/heatmap/root/buckets.js +5 -1
- package/dist/heatmap/root/heatmap-root.d.ts +27 -6
- package/dist/heatmap/root/heatmap-root.js +23 -6
- package/dist/icon/root/icon-root.d.ts +24 -3
- package/dist/icon/root/icon-root.js +34 -1
- package/dist/icon-button/root/icon-button-root.d.ts +1 -1
- package/dist/image/root/image-root.d.ts +9 -2
- package/dist/image/root/image-root.js +8 -2
- package/dist/input/root/input-root.d.ts +51 -9
- package/dist/input/root/input-root.js +46 -5
- package/dist/kbd/root/kbd-root.d.ts +12 -4
- package/dist/kbd/root/kbd-root.js +10 -11
- package/dist/legend/root/legend-root.d.ts +7 -0
- package/dist/legend/root/legend-root.js +7 -2
- package/dist/lightbox/item/lightbox-item.d.ts +2 -1
- package/dist/lightbox/root/lightbox-root.d.ts +16 -5
- package/dist/lightbox/root/lightbox-root.js +24 -3
- package/dist/line-chart/root/line-chart-root.d.ts +19 -2
- package/dist/line-chart/root/line-chart-root.js +40 -13
- package/dist/list/item/list-item.d.ts +11 -5
- package/dist/list/item/list-item.js +5 -6
- package/dist/listbox/root/listbox-root.d.ts +111 -2
- package/dist/listbox/root/listbox-root.js +144 -16
- package/dist/map/root/map-root.d.ts +19 -4
- package/dist/map/root/map-root.js +36 -7
- package/dist/megamenu/root/megamenu-root.d.ts +10 -1
- package/dist/megamenu/root/megamenu-root.js +10 -1
- package/dist/menu/item/menu-item.d.ts +41 -12
- package/dist/menu/item/menu-item.js +46 -3
- package/dist/menu/root/menu-root.d.ts +32 -2
- package/dist/menu/root/menu-root.js +48 -8
- package/dist/meter/root/meter-root.d.ts +6 -0
- package/dist/meter/root/meter-root.js +18 -2
- package/dist/navigation/root/navigation-root.d.ts +10 -2
- package/dist/navigation/root/navigation-root.js +13 -2
- package/dist/notifications/group/notification-group.d.ts +1 -0
- package/dist/notifications/notification/notification.d.ts +12 -0
- package/dist/notifications/notification/notification.js +31 -2
- package/dist/notifications/root/notifications-root.d.ts +7 -0
- package/dist/notifications/root/notifications-root.js +17 -2
- package/dist/number-input/root/number-input-root.d.ts +62 -7
- package/dist/number-input/root/number-input-root.js +68 -16
- package/dist/object-inspector/root/object-inspector-root.d.ts +48 -5
- package/dist/object-inspector/root/object-inspector-root.js +91 -11
- package/dist/option/root/option-root.d.ts +4 -1
- package/dist/option/root/option-root.js +1 -0
- package/dist/outline/root/outline-root.d.ts +13 -2
- package/dist/outline/root/outline-root.js +4 -2
- package/dist/pagination/root/pagination-root.d.ts +19 -1
- package/dist/pagination/root/pagination-root.js +49 -9
- package/dist/pagination/size/pagination-size.d.ts +13 -3
- package/dist/pagination/size/pagination-size.js +7 -0
- package/dist/pin-input/root/pin-input-root.d.ts +16 -0
- package/dist/pin-input/root/pin-input-root.js +19 -5
- package/dist/popover/root/popover-root.d.ts +19 -2
- package/dist/popover/root/popover-root.js +22 -1
- package/dist/progress/root/progress-root.d.ts +16 -1
- package/dist/progress/root/progress-root.js +31 -7
- package/dist/qr-code/root/qr-code-root.d.ts +19 -0
- package/dist/qr-code/root/qr-code-root.js +29 -1
- package/dist/radio/group/radio-group.d.ts +41 -0
- package/dist/radio/group/radio-group.js +50 -14
- package/dist/radio/root/radio-root.d.ts +8 -5
- package/dist/radio/root/radio-root.js +1 -2
- package/dist/rating/root/rating-root.d.ts +24 -1
- package/dist/rating/root/rating-root.js +24 -7
- package/dist/scatter-chart/root/scatter-chart-root.js +15 -7
- package/dist/select/root/select-root.d.ts +69 -3
- package/dist/select/root/select-root.js +92 -8
- package/dist/skeleton/root/skeleton-root.d.ts +14 -3
- package/dist/skeleton/root/skeleton-root.js +17 -3
- package/dist/skip-link/root/skip-link-root.d.ts +10 -0
- package/dist/skip-link/root/skip-link-root.js +15 -1
- package/dist/slider/root/slider-root.d.ts +20 -2
- package/dist/slider/root/slider-root.js +41 -3
- package/dist/sparkline/root/sparkline-root.d.ts +9 -10
- package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
- package/dist/speed-dial/item/speed-dial-item.js +7 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
- package/dist/speed-dial/root/speed-dial-root.js +19 -5
- package/dist/splitter/root/splitter-root.d.ts +28 -6
- package/dist/splitter/root/splitter-root.js +35 -1
- package/dist/stat/root/stat-root.d.ts +7 -1
- package/dist/stat/root/stat-root.js +14 -1
- package/dist/steps/root/steps-root.js +1 -1
- package/dist/switch/root/switch-root.d.ts +2 -0
- package/dist/switch/root/switch-root.js +1 -0
- package/dist/table/cell/table-cell.d.ts +24 -4
- package/dist/table/cell/table-cell.js +21 -1
- package/dist/table/column/table-column.d.ts +32 -6
- package/dist/table/column/table-column.js +36 -6
- package/dist/table/root/table-root.d.ts +94 -3
- package/dist/table/root/table-root.js +128 -5
- package/dist/table/row/table-row.d.ts +7 -0
- package/dist/table/row/table-row.js +9 -1
- package/dist/tabs/root/tabs-root.d.ts +6 -1
- package/dist/tabs/root/tabs-root.js +6 -2
- package/dist/tag/root/tag-root.d.ts +23 -1
- package/dist/tag/root/tag-root.js +16 -2
- package/dist/textarea/root/textarea-root.d.ts +4 -0
- package/dist/textarea/root/textarea-root.js +1 -1
- package/dist/time-input/root/time-input-root.d.ts +28 -2
- package/dist/time-input/root/time-input-root.js +46 -10
- package/dist/time-picker/root/time-picker-root.d.ts +101 -18
- package/dist/time-picker/root/time-picker-root.js +115 -16
- package/dist/toast/root/toast-root.d.ts +64 -1
- package/dist/toast/root/toast-root.js +147 -2
- package/dist/toggle/group/toggle-group.d.ts +38 -1
- package/dist/toggle/group/toggle-group.js +34 -8
- package/dist/toggle/root/toggle-root.d.ts +14 -10
- package/dist/toggle/root/toggle-root.js +3 -3
- package/dist/toolbar/root/toolbar-root.d.ts +55 -15
- package/dist/toolbar/root/toolbar-root.js +99 -16
- package/dist/tooltip/root/tooltip-root.d.ts +37 -4
- package/dist/tooltip/root/tooltip-root.js +48 -0
- package/dist/tour/root/tour-root.d.ts +34 -5
- package/dist/tour/root/tour-root.js +51 -14
- package/dist/tour/stop/tour-stop.d.ts +18 -1
- package/dist/tour/stop/tour-stop.js +25 -5
- package/dist/tree/item/tree-item.d.ts +21 -5
- package/dist/tree/item/tree-item.js +14 -4
- package/dist/tree/root/tree-root.d.ts +29 -5
- package/dist/tree/root/tree-root.js +64 -8
- package/dist/trend/root/trend-root.d.ts +23 -1
- package/dist/trend/root/trend-root.js +28 -7
- package/dist/video/root/keys.d.ts +5 -0
- package/dist/video/root/keys.js +13 -1
- package/dist/video/root/video-root.d.ts +19 -0
- package/dist/video/root/video-root.js +48 -4
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
- package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
- package/dist/video-playlist/root/video-playlist-root.js +6 -3
- package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
- package/dist/virtual-list/root/virtual-list-root.js +103 -21
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4348 -965
- package/types/vue.d.ts +972 -232
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement, KeyboardNavigationController, type Placement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixElement, KeyboardNavigationController, type Placement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -9,6 +9,12 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
|
|
|
9
9
|
* menu renders its surface in the top layer with the popover API, so an
|
|
10
10
|
* ancestor with `overflow: hidden` does not clip it and it needs no `z-index`.
|
|
11
11
|
*
|
|
12
|
+
* Slot a `helix-button` or `helix-icon-button` as the trigger, and the menu
|
|
13
|
+
* tells it that it opens a menu and whether the menu is open. A plain
|
|
14
|
+
* `<button>` can only be told by writing attributes onto your markup, which
|
|
15
|
+
* the menu does not do, so give it `aria-haspopup="menu"` and set its
|
|
16
|
+
* `aria-expanded` from the `toggle` event.
|
|
17
|
+
*
|
|
12
18
|
* Submenus drill down. A submenu replaces the panel's content, and a back row
|
|
13
19
|
* returns to the previous page. One panel avoids the diagonal pointer path that
|
|
14
20
|
* side-by-side panels need, stays inside a narrow window, and works on touch
|
|
@@ -30,7 +36,7 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
|
|
|
30
36
|
* @event {HelixBeforeCloseEvent} helix-before-close - The menu is about to close. Cancelable: cancel it to keep it open.
|
|
31
37
|
* @event {HelixBeforeOpenEvent} helix-before-open - The menu is about to open. Cancelable: cancel it to keep it closed.
|
|
32
38
|
* @event {HelixSelectEvent} helix-select - An item was chosen. Cancelable: cancel it to keep the menu open.
|
|
33
|
-
* @event {
|
|
39
|
+
* @event {ToggleEvent} toggle - The menu opened or closed. The event carries `newState` and `oldState`.
|
|
34
40
|
*
|
|
35
41
|
* @csspart back - The control that returns from a submenu.
|
|
36
42
|
* @csspart back-mark - The glyph on the back control of a submenu.
|
|
@@ -53,6 +59,10 @@ export declare class HelixHeadlessMenu extends HelixHeadlessMenu_base {
|
|
|
53
59
|
backLabel: string;
|
|
54
60
|
/**
|
|
55
61
|
* Accessible name for the surface.
|
|
62
|
+
*
|
|
63
|
+
* Empty by default, which names the surface by its trigger, so a menu opened
|
|
64
|
+
* from "Actions" is announced as "Actions". An `aria-label` or
|
|
65
|
+
* `aria-labelledby` on the host names it too, and wins over both.
|
|
56
66
|
*/
|
|
57
67
|
label: string;
|
|
58
68
|
/**
|
|
@@ -92,6 +102,8 @@ export declare class HelixHeadlessMenu extends HelixHeadlessMenu_base {
|
|
|
92
102
|
* menu that drills, so those keys are spoken for here rather than unhandled.
|
|
93
103
|
*/
|
|
94
104
|
protected readonly keys: KeyboardNavigationController;
|
|
105
|
+
/** Carries a host `aria-label` and `aria-labelledby` to the surface. */
|
|
106
|
+
protected readonly aria: AriaForwardController;
|
|
95
107
|
private readonly panel;
|
|
96
108
|
/**
|
|
97
109
|
* Tells a slotted trigger the disclosure state, by property.
|
|
@@ -108,6 +120,8 @@ export declare class HelixHeadlessMenu extends HelixHeadlessMenu_base {
|
|
|
108
120
|
private get items();
|
|
109
121
|
/** Opens the menu. */
|
|
110
122
|
show(): void;
|
|
123
|
+
/** Opens the menu with focus on its first or its last row. */
|
|
124
|
+
private openAt;
|
|
111
125
|
/** Closes the menu and returns it to its first page. */
|
|
112
126
|
hide(): void;
|
|
113
127
|
/** Shows an item's submenu in place of the current page. */
|
|
@@ -124,10 +138,26 @@ export declare class HelixHeadlessMenu extends HelixHeadlessMenu_base {
|
|
|
124
138
|
*/
|
|
125
139
|
private readonly handleFocusIn;
|
|
126
140
|
private readonly handleKeydown;
|
|
141
|
+
/**
|
|
142
|
+
* Down and Up on the trigger open the menu on its first and its last row.
|
|
143
|
+
*
|
|
144
|
+
* Everything else passes through. Escape in particular is not this element's
|
|
145
|
+
* while the menu is closed, so a dialog around the menu still closes on it.
|
|
146
|
+
*/
|
|
147
|
+
private handleClosedKeydown;
|
|
127
148
|
private readonly handleTriggerClick;
|
|
128
149
|
connectedCallback(): void;
|
|
129
150
|
disconnectedCallback(): void;
|
|
130
151
|
protected updated(changed: PropertyValues): void;
|
|
152
|
+
/**
|
|
153
|
+
* Names the surface by its trigger, where nothing else names it.
|
|
154
|
+
*
|
|
155
|
+
* By element reference, which is the one direction that crosses: the surface
|
|
156
|
+
* is in this shadow root and the trigger is in the tree around it. A host
|
|
157
|
+
* `aria-labelledby` is carried down by `aria`, and a host `aria-label` or
|
|
158
|
+
* `label` is a name of its own, so each of them clears this reference.
|
|
159
|
+
*/
|
|
160
|
+
private nameSurface;
|
|
131
161
|
/**
|
|
132
162
|
* Says whether the page showing reserves a column either side of its labels.
|
|
133
163
|
*
|
|
@@ -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 { anchorElement, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, MixinCollection, MixinControllerOpen, PopoverController, scrollItemIntoView, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, anchorElement, customElement, DrilldownController, deepActiveElement, deepContains, HelixElement, inlineStep, KeyboardNavigationController, MixinCollection, MixinControllerOpen, PopoverController, scrollItemIntoView, slottedWords, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -13,7 +13,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
15
|
this.backLabel = 'Back';
|
|
16
|
-
this.label = '
|
|
16
|
+
this.label = '';
|
|
17
17
|
this.offset = 4;
|
|
18
18
|
this.placement = 'bottom-start';
|
|
19
19
|
this.drilldown = new DrilldownController(this, {
|
|
@@ -22,9 +22,14 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
22
22
|
slot: 'submenu',
|
|
23
23
|
});
|
|
24
24
|
this.keys = new KeyboardNavigationController(this, {
|
|
25
|
-
items: () => this.items,
|
|
25
|
+
items: () => (this.open ? this.items : []),
|
|
26
26
|
reserved: () => ['ArrowLeft', 'ArrowRight'],
|
|
27
27
|
selects: () => false,
|
|
28
|
+
typeahead: (item) => slottedWords(item, ['']),
|
|
29
|
+
});
|
|
30
|
+
this.aria = new AriaForwardController(this, {
|
|
31
|
+
label: true,
|
|
32
|
+
target: () => this.partNamed('surface'),
|
|
28
33
|
});
|
|
29
34
|
this.panel = new PopoverController(this, {
|
|
30
35
|
anchor: () => this.trigger,
|
|
@@ -61,8 +66,12 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
61
66
|
scrollItemIntoView(item, { padding: 4, ...(surface ? { scroller: surface } : {}) });
|
|
62
67
|
};
|
|
63
68
|
this.handleKeydown = (event) => {
|
|
69
|
+
if (!this.open) {
|
|
70
|
+
this.handleClosedKeydown(event);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
64
73
|
const items = this.items;
|
|
65
|
-
const at = items.
|
|
74
|
+
const at = items.findIndex((item) => item.active);
|
|
66
75
|
const along = inlineStep(this, event.key);
|
|
67
76
|
if (event.key === 'Escape') {
|
|
68
77
|
event.stopPropagation();
|
|
@@ -94,7 +103,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
94
103
|
}
|
|
95
104
|
tellTrigger() {
|
|
96
105
|
const slot = this.renderRoot?.querySelector('slot[name="trigger"]');
|
|
97
|
-
tellDisclosure(slot?.assignedElements({ flatten:
|
|
106
|
+
tellDisclosure(slot?.assignedElements({ flatten: true })[0], this.open, 'menu');
|
|
98
107
|
}
|
|
99
108
|
get trigger() {
|
|
100
109
|
return anchorElement(this.renderRoot?.querySelector('slot[name="trigger"]'), this);
|
|
@@ -103,11 +112,15 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
103
112
|
return this.drilldown.rows.filter((row) => !row.disabled);
|
|
104
113
|
}
|
|
105
114
|
show() {
|
|
115
|
+
this.openAt('first');
|
|
116
|
+
}
|
|
117
|
+
openAt(end) {
|
|
106
118
|
if (this.open || !this.requestOpen(true)) {
|
|
107
119
|
return;
|
|
108
120
|
}
|
|
109
121
|
this.updateComplete.then(() => {
|
|
110
|
-
this.items
|
|
122
|
+
const items = this.items;
|
|
123
|
+
(end === 'first' ? items[0] : items[items.length - 1])?.focus();
|
|
111
124
|
});
|
|
112
125
|
}
|
|
113
126
|
hide() {
|
|
@@ -116,7 +129,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
116
129
|
}
|
|
117
130
|
this.panel.hide();
|
|
118
131
|
this.drilldown.reset();
|
|
119
|
-
if (this
|
|
132
|
+
if (deepContains(this, deepActiveElement())) {
|
|
120
133
|
this.trigger.focus();
|
|
121
134
|
}
|
|
122
135
|
}
|
|
@@ -135,6 +148,18 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
135
148
|
this.drilldown.back();
|
|
136
149
|
this.updateComplete.then(() => leaving?.focus());
|
|
137
150
|
}
|
|
151
|
+
handleClosedKeydown(event) {
|
|
152
|
+
if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const slot = this.renderRoot?.querySelector('slot[name="trigger"]');
|
|
156
|
+
const triggers = slot?.assignedElements({ flatten: true }) ?? [];
|
|
157
|
+
if (!event.composedPath().some((node) => triggers.includes(node))) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
this.openAt(event.key === 'ArrowDown' ? 'first' : 'last');
|
|
162
|
+
}
|
|
138
163
|
connectedCallback() {
|
|
139
164
|
super.connectedCallback();
|
|
140
165
|
this.addEventListener('helix-select', this.handleSelect, true);
|
|
@@ -159,6 +184,21 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
159
184
|
}
|
|
160
185
|
this.toggleState('drilled', !this.drilldown.atRoot);
|
|
161
186
|
this.markColumns();
|
|
187
|
+
this.nameSurface();
|
|
188
|
+
}
|
|
189
|
+
nameSurface() {
|
|
190
|
+
const surface = this.partNamed('surface');
|
|
191
|
+
if (!surface || !('ariaLabelledByElements' in surface)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.hasAttribute('aria-labelledby')) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const trigger = this.renderRoot
|
|
198
|
+
?.querySelector('slot[name="trigger"]')
|
|
199
|
+
?.assignedElements({ flatten: true })[0];
|
|
200
|
+
const named = this.label !== '' || this.hasAttribute('aria-label');
|
|
201
|
+
surface.ariaLabelledByElements = trigger && !named ? [trigger] : null;
|
|
162
202
|
}
|
|
163
203
|
markColumns() {
|
|
164
204
|
const rows = this.drilldown.rows;
|
|
@@ -183,7 +223,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
183
223
|
popover="manual"
|
|
184
224
|
role="menu"
|
|
185
225
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
186
|
-
aria-label=${this.label}
|
|
226
|
+
aria-label=${this.label || nothing}
|
|
187
227
|
data-drilled=${this.drilldown.atRoot ? nothing : ''}
|
|
188
228
|
?hidden=${!this.open}
|
|
189
229
|
>
|
|
@@ -79,6 +79,12 @@ export declare class HelixHeadlessMeter extends HelixElement {
|
|
|
79
79
|
* Accessible name for the reading.
|
|
80
80
|
*/
|
|
81
81
|
label: string;
|
|
82
|
+
/**
|
|
83
|
+
* The locale the percentage is written in, such as `fr` for `72 %`.
|
|
84
|
+
*
|
|
85
|
+
* Absent uses the runtime's own.
|
|
86
|
+
*/
|
|
87
|
+
locale: string;
|
|
82
88
|
/**
|
|
83
89
|
* Top of the low band.
|
|
84
90
|
*
|
|
@@ -7,10 +7,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
const percents = new Map();
|
|
11
|
+
const percent = (share, locale) => {
|
|
12
|
+
let format = percents.get(locale);
|
|
13
|
+
if (!format) {
|
|
14
|
+
format = new Intl.NumberFormat(locale || undefined, {
|
|
15
|
+
maximumFractionDigits: 0,
|
|
16
|
+
style: 'percent',
|
|
17
|
+
});
|
|
18
|
+
percents.set(locale, format);
|
|
19
|
+
}
|
|
20
|
+
return format.format(share);
|
|
21
|
+
};
|
|
10
22
|
let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
11
23
|
constructor() {
|
|
12
24
|
super(...arguments);
|
|
13
25
|
this.label = 'Meter';
|
|
26
|
+
this.locale = '';
|
|
14
27
|
this.max = 100;
|
|
15
28
|
this.min = 0;
|
|
16
29
|
this.showValue = false;
|
|
@@ -64,7 +77,7 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
|
64
77
|
return distance === 0 ? 'good' : distance === 1 ? 'fair' : 'poor';
|
|
65
78
|
}
|
|
66
79
|
get text() {
|
|
67
|
-
return this.valueText ||
|
|
80
|
+
return this.valueText || percent(this.ratio, this.locale);
|
|
68
81
|
}
|
|
69
82
|
willUpdate(changed) {
|
|
70
83
|
super.willUpdate(changed);
|
|
@@ -74,7 +87,7 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
|
|
|
74
87
|
this.internals.ariaValueMax = String(max);
|
|
75
88
|
this.internals.ariaValueNow = String(this.reading);
|
|
76
89
|
this.internals.ariaValueText =
|
|
77
|
-
this.valueText || (this.beyond ?
|
|
90
|
+
this.valueText || (this.beyond ? percent(this.ratio, this.locale) : null);
|
|
78
91
|
}
|
|
79
92
|
renderRound() {
|
|
80
93
|
const bounds = this.thresholds;
|
|
@@ -134,6 +147,9 @@ __decorate([
|
|
|
134
147
|
__decorate([
|
|
135
148
|
property()
|
|
136
149
|
], HelixHeadlessMeter.prototype, "label", void 0);
|
|
150
|
+
__decorate([
|
|
151
|
+
property()
|
|
152
|
+
], HelixHeadlessMeter.prototype, "locale", void 0);
|
|
137
153
|
__decorate([
|
|
138
154
|
property({ type: Number })
|
|
139
155
|
], HelixHeadlessMeter.prototype, "low", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary A set of destinations, with a marker on the current one.
|
|
@@ -15,7 +15,9 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
15
15
|
*
|
|
16
16
|
* The component moves a marker to the current item. It finds the current item
|
|
17
17
|
* by reading `aria-current`, so the attribute that screen readers announce also
|
|
18
|
-
* places the marker.
|
|
18
|
+
* places the marker. Any value but `false` counts, so a sidebar of sections on
|
|
19
|
+
* one page can mark the section in view with `aria-current="location"`. Where
|
|
20
|
+
* several are marked, `page` wins.
|
|
19
21
|
*
|
|
20
22
|
* Set `orientation="vertical"` to stack the destinations in a column, for a
|
|
21
23
|
* sidebar.
|
|
@@ -35,8 +37,14 @@ export declare class HelixHeadlessNavigation extends HelixElement {
|
|
|
35
37
|
private readonly indicator;
|
|
36
38
|
/**
|
|
37
39
|
* The landmark's name, read by screen readers.
|
|
40
|
+
*
|
|
41
|
+
* An `aria-label` or `aria-labelledby` on the host names the landmark too,
|
|
42
|
+
* and wins over this, so a footer navigation written the usual way is not a
|
|
43
|
+
* second "Main".
|
|
38
44
|
*/
|
|
39
45
|
label: string;
|
|
46
|
+
/** Carries a host `aria-label` and `aria-labelledby` to the `<nav>`. */
|
|
47
|
+
protected readonly aria: AriaForwardController;
|
|
40
48
|
/**
|
|
41
49
|
* Stacks the destinations in a column, for a sidebar, where unset is a row
|
|
42
50
|
* for a header or a footer. The marker follows the current destination down
|
|
@@ -4,19 +4,30 @@ 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, HelixElement, IndicatorController } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, HelixElement, IndicatorController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.indicator = new IndicatorController(this, {
|
|
14
|
-
active: () =>
|
|
14
|
+
active: () => {
|
|
15
|
+
const items = this.items;
|
|
16
|
+
const marked = (item) => {
|
|
17
|
+
const current = item.getAttribute('aria-current');
|
|
18
|
+
return current !== null && current !== 'false';
|
|
19
|
+
};
|
|
20
|
+
return (items.find((item) => item.getAttribute('aria-current') === 'page') ?? items.find(marked));
|
|
21
|
+
},
|
|
15
22
|
indicator: () => this.partNamed('indicator'),
|
|
16
23
|
observe: () => this.items,
|
|
17
24
|
surface: () => this.partNamed('nav'),
|
|
18
25
|
});
|
|
19
26
|
this.label = 'Main';
|
|
27
|
+
this.aria = new AriaForwardController(this, {
|
|
28
|
+
label: true,
|
|
29
|
+
target: () => this.partNamed('nav'),
|
|
30
|
+
});
|
|
20
31
|
}
|
|
21
32
|
get items() {
|
|
22
33
|
const slot = this.renderRoot.querySelector('slot');
|
|
@@ -33,6 +33,7 @@ declare const HelixHeadlessNotificationGroup_base: (new (...args: any[]) => impo
|
|
|
33
33
|
*
|
|
34
34
|
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before the group collapses. Cancelable.
|
|
35
35
|
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before the group expands. Cancelable: cancel it to keep the group collapsed.
|
|
36
|
+
* @event {ToggleEvent} toggle - The group expanded or collapsed. The event carries `newState` and `oldState`.
|
|
36
37
|
*
|
|
37
38
|
* @csspart actions - The trailing region of the header.
|
|
38
39
|
* @csspart count - The number of notifications in the group.
|
|
@@ -96,6 +96,13 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
|
|
|
96
96
|
*/
|
|
97
97
|
get read(): boolean;
|
|
98
98
|
set read(next: boolean);
|
|
99
|
+
/**
|
|
100
|
+
* What a screen reader hears before an unread notification's text.
|
|
101
|
+
*
|
|
102
|
+
* The unread mark is drawn, so a reader who cannot see it hears this word in
|
|
103
|
+
* its place. Translate it with the rest of your interface.
|
|
104
|
+
*/
|
|
105
|
+
unreadLabel: string;
|
|
99
106
|
/**
|
|
100
107
|
* @internal Read by the list to identify its children across the light DOM,
|
|
101
108
|
* which is cheaper than `instanceof` and is why this is public rather than
|
|
@@ -192,6 +199,11 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
|
|
|
192
199
|
protected render(): TemplateResult;
|
|
193
200
|
private readonly handleActions;
|
|
194
201
|
private readonly handleDismiss;
|
|
202
|
+
/**
|
|
203
|
+
* Where focus goes when this row leaves: the next row's first control, the
|
|
204
|
+
* one before, then the first control left in the feed.
|
|
205
|
+
*/
|
|
206
|
+
private neighbor;
|
|
195
207
|
}
|
|
196
208
|
declare global {
|
|
197
209
|
interface HTMLElementTagNameMap {
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, HelixReadEvent, hostAria, MixinDismissible, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepActiveElement, deepContains, focusableElements, HelixElement, HelixReadEvent, hostAria, MixinDismissible, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { x } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
@@ -17,6 +17,7 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
17
17
|
this.at = '';
|
|
18
18
|
this.defaultRead = false;
|
|
19
19
|
this.locale = '';
|
|
20
|
+
this.unreadLabel = 'Unread';
|
|
20
21
|
this.isNotification = true;
|
|
21
22
|
this.readState = undefined;
|
|
22
23
|
this.handleActions = () => {
|
|
@@ -25,7 +26,9 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
25
26
|
this.handleDismiss = (event) => {
|
|
26
27
|
event.stopPropagation();
|
|
27
28
|
if (this.dismiss()) {
|
|
29
|
+
const next = deepContains(this, deepActiveElement()) ? this.neighbor() : null;
|
|
28
30
|
this.remove();
|
|
31
|
+
next?.focus();
|
|
29
32
|
}
|
|
30
33
|
};
|
|
31
34
|
}
|
|
@@ -105,7 +108,7 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
105
108
|
return html `<div part="item">
|
|
106
109
|
<span part="media"><slot name="media"></slot></span>
|
|
107
110
|
<div part="body">
|
|
108
|
-
<div part="label"
|
|
111
|
+
<div part="label">${this.read ? nothing : html `<span role="img" aria-label=${this.unreadLabel}></span>`}<slot></slot></div>
|
|
109
112
|
<slot name="description"></slot>
|
|
110
113
|
<slot name="detail"></slot>
|
|
111
114
|
<span part="actions"><slot name="actions" @slotchange=${this.handleActions}></slot></span>
|
|
@@ -116,6 +119,29 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
116
119
|
</div>
|
|
117
120
|
</div>`;
|
|
118
121
|
}
|
|
122
|
+
neighbor() {
|
|
123
|
+
let feed = this.parentElement;
|
|
124
|
+
while (feed && !('markEveryoneRead' in feed)) {
|
|
125
|
+
feed = feed.parentElement;
|
|
126
|
+
}
|
|
127
|
+
const rows = feed
|
|
128
|
+
? feed.items
|
|
129
|
+
: [...(this.parentElement?.children ?? [])].filter((one) => 'isNotification' in one);
|
|
130
|
+
const at = rows.indexOf(this);
|
|
131
|
+
const order = [...rows.slice(at + 1), ...rows.slice(0, Math.max(at, 0)).reverse()];
|
|
132
|
+
for (const row of order) {
|
|
133
|
+
const target = row.shadowRoot?.querySelector('[part="dismiss"]') ?? focusableElements(row)[0];
|
|
134
|
+
if (target) {
|
|
135
|
+
return target;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!feed) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return (feed.shadowRoot?.querySelector('[part="mark-all"]') ??
|
|
142
|
+
focusableElements(feed).find((one) => !this.contains(one)) ??
|
|
143
|
+
null);
|
|
144
|
+
}
|
|
119
145
|
};
|
|
120
146
|
__decorate([
|
|
121
147
|
property()
|
|
@@ -129,6 +155,9 @@ __decorate([
|
|
|
129
155
|
__decorate([
|
|
130
156
|
property({ type: Boolean })
|
|
131
157
|
], HelixHeadlessNotification.prototype, "read", null);
|
|
158
|
+
__decorate([
|
|
159
|
+
property({ attribute: 'unread-label' })
|
|
160
|
+
], HelixHeadlessNotification.prototype, "unreadLabel", void 0);
|
|
132
161
|
HelixHeadlessNotification = __decorate([
|
|
133
162
|
customElement('helix-headless-notification')
|
|
134
163
|
], HelixHeadlessNotification);
|
|
@@ -202,6 +202,13 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
|
|
|
202
202
|
private markEmpty;
|
|
203
203
|
protected updated(changed: PropertyValues): void;
|
|
204
204
|
protected render(): TemplateResult;
|
|
205
|
+
/**
|
|
206
|
+
* Marks everything read, and keeps focus in the feed.
|
|
207
|
+
*
|
|
208
|
+
* The button shows only while something is unread, so the press that
|
|
209
|
+
* succeeds removes the button it was made on. Focus moves to the first row's
|
|
210
|
+
* control, or the first control left in the feed.
|
|
211
|
+
*/
|
|
205
212
|
private readonly handleMarkAll;
|
|
206
213
|
}
|
|
207
214
|
declare global {
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, focusableElements, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinCollection(HelixElement) {
|
|
@@ -20,8 +20,23 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
20
20
|
this.handleRead = () => {
|
|
21
21
|
queueMicrotask(() => this.requestUpdate());
|
|
22
22
|
};
|
|
23
|
-
this.handleMarkAll = () => {
|
|
23
|
+
this.handleMarkAll = (event) => {
|
|
24
|
+
const button = event.currentTarget;
|
|
25
|
+
const focused = this.shadowRoot?.activeElement === button;
|
|
24
26
|
this.markEveryoneRead();
|
|
27
|
+
if (!focused) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
void this.updateComplete.then(() => {
|
|
31
|
+
if (button.isConnected) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const target = this.items
|
|
35
|
+
.map((row) => row.shadowRoot?.querySelector('[part="dismiss"]') ??
|
|
36
|
+
focusableElements(row)[0])
|
|
37
|
+
.find((one) => one !== undefined) ?? focusableElements(this)[0];
|
|
38
|
+
target?.focus();
|
|
39
|
+
});
|
|
25
40
|
};
|
|
26
41
|
}
|
|
27
42
|
static { this.shadowRootOptions = {
|
|
@@ -18,8 +18,9 @@ declare const HelixHeadlessNumberInput_base: (new (...args: any[]) => import("@f
|
|
|
18
18
|
*
|
|
19
19
|
* `inputmode="decimal"` keeps the numeric keypad on phones.
|
|
20
20
|
*
|
|
21
|
-
* Validity
|
|
22
|
-
*
|
|
21
|
+
* Validity follows the platform's rules: `min`, `max`, and `step` are checked
|
|
22
|
+
* and reported through the host's own `setValidity`, under the platform's flag
|
|
23
|
+
* names.
|
|
23
24
|
*
|
|
24
25
|
* Stepping is separate from typing, so a number is not corrected while you type
|
|
25
26
|
* it.
|
|
@@ -31,6 +32,9 @@ declare const HelixHeadlessNumberInput_base: (new (...args: any[]) => import("@f
|
|
|
31
32
|
* @documentation https://fusion.dev/helix/components/number-input
|
|
32
33
|
*
|
|
33
34
|
* @slot end - Content after the number, such as a unit.
|
|
35
|
+
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
36
|
+
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
37
|
+
* @slot label - The label, for content richer than the `label` text.
|
|
34
38
|
* @slot start - Content before the number, such as a unit or an icon.
|
|
35
39
|
*
|
|
36
40
|
* @event {Event} change - The user finished changing the value. Relayed from the native field.
|
|
@@ -88,6 +92,15 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
|
|
|
88
92
|
* what a reader wants from a whole key.
|
|
89
93
|
*/
|
|
90
94
|
largeStep?: number;
|
|
95
|
+
/**
|
|
96
|
+
* The locale a typed number is read in, such as `de-DE`. Empty reads it in
|
|
97
|
+
* the browser's language.
|
|
98
|
+
*
|
|
99
|
+
* Where the locale writes a decimal comma, `1,5` is read as one and a half,
|
|
100
|
+
* which is what the decimal keypad on a phone in that locale types. A dot is
|
|
101
|
+
* read as a decimal point in every locale.
|
|
102
|
+
*/
|
|
103
|
+
locale: string;
|
|
91
104
|
/**
|
|
92
105
|
* The largest value allowed.
|
|
93
106
|
*
|
|
@@ -132,14 +145,29 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
|
|
|
132
145
|
*/
|
|
133
146
|
scrub: boolean;
|
|
134
147
|
/**
|
|
135
|
-
* How far one step moves.
|
|
148
|
+
* How far one step moves. A value off the step grid, counted from `min`, is
|
|
149
|
+
* invalid, as it is in a native number field.
|
|
136
150
|
*/
|
|
137
151
|
step: number;
|
|
138
|
-
/**
|
|
139
|
-
|
|
152
|
+
/**
|
|
153
|
+
* The message the browser shows when the number is off the step grid, with
|
|
154
|
+
* `{below}` and `{above}` filled in with the nearest valid values.
|
|
155
|
+
*/
|
|
156
|
+
stepMismatchMessage?: string;
|
|
157
|
+
/**
|
|
158
|
+
* What a screen reader says for the value, with `{value}` filled in, such as
|
|
159
|
+
* `{value} kilograms`.
|
|
160
|
+
*
|
|
161
|
+
* A unit slotted into `end` is drawn beside the number and is not part of
|
|
162
|
+
* what the spinbutton announces, so it goes here too. Empty announces the
|
|
163
|
+
* number alone.
|
|
164
|
+
*/
|
|
165
|
+
valueText: string;
|
|
140
166
|
private get control();
|
|
141
167
|
/** The value as a number, or `null` where the field holds nothing usable. */
|
|
142
168
|
private get numeric();
|
|
169
|
+
/** Whether `value` is on the step grid, counted from `min`. */
|
|
170
|
+
private onStep;
|
|
143
171
|
/**
|
|
144
172
|
* A value pulled into range and onto the step grid.
|
|
145
173
|
*
|
|
@@ -254,7 +282,19 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
|
|
|
254
282
|
* the same as preventing one.
|
|
255
283
|
*/
|
|
256
284
|
private readonly handleBlur;
|
|
257
|
-
/**
|
|
285
|
+
/**
|
|
286
|
+
* Pulls a typed number into range and onto the step grid, and returns
|
|
287
|
+
* whether that moved the value.
|
|
288
|
+
*/
|
|
289
|
+
private settle;
|
|
290
|
+
/**
|
|
291
|
+
* Relayed, because `change` does not cross a shadow boundary on its own.
|
|
292
|
+
*
|
|
293
|
+
* **Settled first.** The field's `change` arrives before its `blur`, so
|
|
294
|
+
* relaying it as it came announced the number as typed, 150 in a field whose
|
|
295
|
+
* `max` is 100, and the clamp that followed sent `input` alone: a consumer
|
|
296
|
+
* saving on `change` kept 150 while the form submitted 100.
|
|
297
|
+
*/
|
|
258
298
|
private readonly handleChange;
|
|
259
299
|
/**
|
|
260
300
|
* The four keys a spinner answers, which `Input` does not bind.
|
|
@@ -274,7 +314,13 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
|
|
|
274
314
|
* message is what a native spinner would have said.
|
|
275
315
|
*/
|
|
276
316
|
private sync;
|
|
277
|
-
/**
|
|
317
|
+
/**
|
|
318
|
+
* Puts the cursor in the field.
|
|
319
|
+
*
|
|
320
|
+
* **No `delegatesFocus`**, because the platform's delegate is the first
|
|
321
|
+
* focusable element, which is the Decrease stepper: a label pressed for the
|
|
322
|
+
* field landed on it, and the arrows then did nothing.
|
|
323
|
+
*/
|
|
278
324
|
focus(options?: FocusOptions): void;
|
|
279
325
|
/** Selects the number, so typing replaces it. */
|
|
280
326
|
select(): void;
|
|
@@ -287,6 +333,15 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
|
|
|
287
333
|
private releaseCaret;
|
|
288
334
|
protected willUpdate(changed: PropertyValues): void;
|
|
289
335
|
protected updated(changed: PropertyValues): void;
|
|
336
|
+
/**
|
|
337
|
+
* Enter submits the form, as it does in a native text field.
|
|
338
|
+
*
|
|
339
|
+
* On `keypress`, where the platform runs its own implicit submission, so a
|
|
340
|
+
* consumer who prevents the `keydown` for Enter stops this too.
|
|
341
|
+
*/
|
|
342
|
+
private readonly handleKeypress;
|
|
343
|
+
/** @internal A single line of text counts against implicit submission. */
|
|
344
|
+
protected get blocksImplicitSubmission(): boolean;
|
|
290
345
|
protected render(): TemplateResult;
|
|
291
346
|
/**
|
|
292
347
|
* The value as a number, or `NaN` while the control is empty.
|