@fusion.dev/helix-headless 0.143.0 → 0.145.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 +16990 -1383
- package/dist/accordion/item/accordion-item.d.ts +48 -12
- package/dist/accordion/item/accordion-item.js +26 -5
- package/dist/accordion/root/accordion-root.d.ts +6 -0
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +21 -1
- package/dist/announcement/root/announcement-root.js +36 -1
- package/dist/app-header/root/app-header-root.d.ts +7 -0
- package/dist/app-header/root/app-header-root.js +5 -1
- package/dist/app-header/sectioning.d.ts +7 -0
- package/dist/app-header/sectioning.js +26 -0
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +24 -7
- package/dist/avatar/root/avatar-root.d.ts +14 -0
- package/dist/avatar/root/avatar-root.js +23 -9
- package/dist/badge/root/badge-root.d.ts +11 -7
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
- package/dist/bar-chart/root/bar-chart-root.js +17 -10
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
- package/dist/button/root/button-root.d.ts +47 -1
- package/dist/button/root/button-root.js +38 -4
- package/dist/callout/root/callout-root.d.ts +18 -1
- package/dist/callout/root/callout-root.js +15 -4
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +121 -40
- package/dist/card/root/card-root.d.ts +30 -1
- package/dist/card/root/card-root.js +38 -5
- package/dist/carousel/root/carousel-root.d.ts +90 -0
- package/dist/carousel/root/carousel-root.js +134 -12
- package/dist/chat/composer/chat-composer.d.ts +38 -6
- package/dist/chat/composer/chat-composer.js +42 -9
- package/dist/chat/message/chat-message.d.ts +32 -1
- package/dist/chat/message/chat-message.js +25 -9
- package/dist/chat/naming.d.ts +22 -0
- package/dist/chat/naming.js +12 -0
- package/dist/chat/relative-clock.d.ts +39 -0
- package/dist/chat/relative-clock.js +31 -0
- package/dist/chat/root/chat-root.d.ts +36 -0
- package/dist/chat/root/chat-root.js +24 -1
- package/dist/checkbox/root/checkbox-root.js +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
- package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
- package/dist/code-block/lines.d.ts +13 -0
- package/dist/code-block/lines.js +2 -0
- package/dist/code-block/root/code-block-root.d.ts +38 -1
- package/dist/code-block/root/code-block-root.js +28 -7
- package/dist/color-input/root/color-input-root.d.ts +34 -1
- package/dist/color-input/root/color-input-root.js +23 -4
- package/dist/color-picker/channels.d.ts +26 -0
- package/dist/color-picker/channels.js +84 -0
- package/dist/color-picker/root/color-picker-root.d.ts +81 -5
- package/dist/color-picker/root/color-picker-root.js +103 -10
- package/dist/combobox/root/combobox-root.d.ts +38 -3
- package/dist/combobox/root/combobox-root.js +64 -2
- package/dist/command/root/command-root.d.ts +30 -4
- package/dist/command/root/command-root.js +33 -3
- package/dist/copy-button/from.d.ts +22 -0
- package/dist/copy-button/from.js +28 -0
- package/dist/copy-button/root/copy-button-root.d.ts +47 -1
- package/dist/copy-button/root/copy-button-root.js +44 -8
- package/dist/data-table/root/data-table-root.d.ts +150 -2
- package/dist/data-table/root/data-table-root.js +303 -29
- package/dist/data-table/tree.d.ts +40 -0
- package/dist/data-table/tree.js +55 -0
- package/dist/date-input/root/date-input-root.d.ts +73 -4
- package/dist/date-input/root/date-input-root.js +93 -43
- package/dist/date-picker/root/date-picker-root.d.ts +145 -1
- package/dist/date-picker/root/date-picker-root.js +239 -48
- package/dist/description-list/item/description-list-item.d.ts +17 -2
- package/dist/description-list/item/description-list-item.js +15 -2
- package/dist/description-list/root/description-list-root.d.ts +27 -1
- package/dist/description-list/root/description-list-root.js +26 -1
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +64 -1
- package/dist/dialog/root/dialog-root.js +49 -23
- package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
- package/dist/donut-chart/root/donut-chart-root.js +21 -6
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +95 -19
- package/dist/drawer/swipe-start.d.ts +9 -0
- package/dist/drawer/swipe-start.js +12 -0
- package/dist/drilldown/item/drilldown-item.d.ts +11 -6
- package/dist/drilldown/item/drilldown-item.js +8 -5
- package/dist/drilldown/root/drilldown-root.d.ts +11 -0
- package/dist/drilldown/root/drilldown-root.js +8 -3
- package/dist/element-events.generated.js +61 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +47 -0
- package/dist/file-input/root/file-input-root.js +60 -22
- package/dist/file-input/screen.d.ts +35 -0
- package/dist/file-input/screen.js +49 -0
- package/dist/filter-input/menu/filter-menu.d.ts +3 -0
- package/dist/filter-input/menu/filter-menu.js +8 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -4
- package/dist/filter-input/root/filter-input-root.js +67 -3
- package/dist/filter-input/suggest.d.ts +17 -0
- package/dist/filter-input/suggest.js +23 -0
- package/dist/format-date/options.d.ts +33 -0
- package/dist/format-date/options.js +42 -0
- package/dist/format-date/root/format-date-root.d.ts +51 -0
- package/dist/format-date/root/format-date-root.js +58 -38
- package/dist/heatmap/root/heatmap-root.d.ts +23 -6
- package/dist/heatmap/root/heatmap-root.js +24 -13
- package/dist/icon/index.d.ts +2 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon/registry.d.ts +37 -0
- package/dist/icon/registry.js +83 -0
- package/dist/icon/root/icon-root.d.ts +30 -4
- package/dist/icon/root/icon-root.js +41 -6
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon/set.d.ts +1 -0
- package/dist/icon/set.js +3 -0
- package/dist/image/root/image-root.d.ts +14 -0
- package/dist/image/root/image-root.js +23 -2
- package/dist/input/root/input-root.d.ts +11 -0
- package/dist/input/root/input-root.js +16 -1
- package/dist/kbd/root/kbd-root.d.ts +20 -13
- package/dist/kbd/root/kbd-root.js +35 -37
- package/dist/kbd/shortcut.d.ts +18 -0
- package/dist/kbd/shortcut.js +35 -0
- package/dist/legend/hidden-series.d.ts +8 -0
- package/dist/legend/hidden-series.js +13 -0
- package/dist/legend/root/legend-root.d.ts +56 -0
- package/dist/legend/root/legend-root.js +54 -5
- package/dist/lightbox/item/lightbox-item.d.ts +15 -0
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +61 -1
- package/dist/lightbox/root/lightbox-root.js +94 -4
- package/dist/line-chart/root/line-chart-root.d.ts +11 -3
- package/dist/line-chart/root/line-chart-root.js +19 -5
- package/dist/list/item/list-item.d.ts +68 -1
- package/dist/list/item/list-item.js +66 -4
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +106 -9
- package/dist/list/root/list-root.js +189 -4
- package/dist/list/selection.d.ts +19 -0
- package/dist/list/selection.js +21 -0
- package/dist/listbox/root/listbox-root.d.ts +74 -3
- package/dist/listbox/root/listbox-root.js +86 -9
- package/dist/loader/busy.d.ts +17 -0
- package/dist/loader/busy.js +24 -0
- package/dist/loader/root/loader-root.d.ts +37 -0
- package/dist/loader/root/loader-root.js +52 -3
- package/dist/map/root/map-root.d.ts +6 -2
- package/dist/map/root/map-root.js +5 -2
- package/dist/megamenu/root/megamenu-root.d.ts +21 -0
- package/dist/megamenu/root/megamenu-root.js +16 -2
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +38 -11
- package/dist/menu/item/menu-item.js +33 -1
- package/dist/menu/root/menu-root.d.ts +25 -1
- package/dist/menu/root/menu-root.js +63 -6
- package/dist/menu/section/menu-section.d.ts +55 -0
- package/dist/menu/section/menu-section.js +60 -0
- package/dist/meter/root/meter-root.d.ts +7 -0
- package/dist/meter/root/meter-root.js +6 -3
- package/dist/navigation/root/navigation-root.d.ts +16 -1
- package/dist/navigation/root/navigation-root.js +27 -1
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/notification/notification.d.ts +17 -0
- package/dist/notifications/notification/notification.js +21 -2
- package/dist/notifications/root/notifications-root.d.ts +60 -0
- package/dist/notifications/root/notifications-root.js +76 -1
- package/dist/number-input/root/number-input-root.d.ts +47 -0
- package/dist/number-input/root/number-input-root.js +58 -22
- package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
- package/dist/object-inspector/root/object-inspector-root.js +180 -80
- package/dist/object-inspector/rows.d.ts +57 -0
- package/dist/object-inspector/rows.js +86 -0
- package/dist/option/root/option-root.d.ts +54 -5
- package/dist/option/root/option-root.js +34 -5
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +68 -3
- package/dist/outline/root/outline-root.js +73 -8
- package/dist/pagination/size/pagination-size.d.ts +11 -2
- package/dist/pagination/size/pagination-size.js +19 -4
- package/dist/pin-input/format.d.ts +7 -0
- package/dist/pin-input/format.js +16 -0
- package/dist/pin-input/root/pin-input-root.d.ts +21 -0
- package/dist/pin-input/root/pin-input-root.js +29 -2
- package/dist/popover/root/popover-root.d.ts +62 -4
- package/dist/popover/root/popover-root.js +53 -5
- package/dist/progress/root/progress-root.d.ts +7 -0
- package/dist/progress/root/progress-root.js +9 -3
- package/dist/qr-code/export.d.ts +31 -0
- package/dist/qr-code/export.js +10 -0
- package/dist/qr-code/root/qr-code-root.d.ts +26 -0
- package/dist/qr-code/root/qr-code-root.js +49 -2
- package/dist/radio/group/radio-group.d.ts +17 -0
- package/dist/radio/group/radio-group.js +14 -1
- package/dist/rating/root/rating-root.d.ts +25 -0
- package/dist/rating/root/rating-root.js +46 -4
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
- package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
- package/dist/scroll-area/root/scroll-area-root.js +218 -3
- package/dist/scroll-area/scrollbar.d.ts +65 -0
- package/dist/scroll-area/scrollbar.js +24 -0
- package/dist/select/root/select-root.d.ts +24 -0
- package/dist/select/root/select-root.js +21 -7
- package/dist/skeleton/root/skeleton-root.d.ts +25 -0
- package/dist/skeleton/root/skeleton-root.js +17 -2
- package/dist/slider/root/slider-root.d.ts +39 -0
- package/dist/slider/root/slider-root.js +45 -9
- package/dist/splitter/root/splitter-root.d.ts +13 -0
- package/dist/splitter/root/splitter-root.js +20 -2
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/stat/root/stat-root.d.ts +2 -0
- package/dist/stat/root/stat-root.js +1 -1
- package/dist/steps/reach.d.ts +15 -0
- package/dist/steps/reach.js +12 -0
- package/dist/steps/root/steps-root.d.ts +30 -0
- package/dist/steps/root/steps-root.js +53 -0
- package/dist/steps/step/step.d.ts +39 -2
- package/dist/steps/step/step.js +29 -7
- package/dist/switch/root/switch-root.d.ts +12 -2
- package/dist/switch/root/switch-root.js +6 -1
- package/dist/table/column/table-column.d.ts +11 -0
- package/dist/table/column/table-column.js +6 -1
- package/dist/table/root/table-root.d.ts +101 -0
- package/dist/table/root/table-root.js +166 -5
- package/dist/table/row/table-row.d.ts +47 -1
- package/dist/table/row/table-row.js +39 -2
- package/dist/tabs/panel/tab-panel.d.ts +9 -5
- package/dist/tabs/panel/tab-panel.js +3 -4
- package/dist/tabs/root/tabs-root.d.ts +25 -1
- package/dist/tabs/root/tabs-root.js +21 -3
- package/dist/tabs/tab/tab.d.ts +36 -4
- package/dist/tabs/tab/tab.js +46 -3
- package/dist/tag/group/tag-group.d.ts +107 -0
- package/dist/tag/group/tag-group.js +157 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +60 -0
- package/dist/tag/root/tag-root.js +74 -18
- package/dist/tag/selection.d.ts +10 -0
- package/dist/tag/selection.js +12 -0
- package/dist/textarea/grow.d.ts +22 -0
- package/dist/textarea/grow.js +20 -0
- package/dist/textarea/root/textarea-root.d.ts +9 -0
- package/dist/textarea/root/textarea-root.js +9 -1
- package/dist/time-input/root/time-input-root.d.ts +44 -5
- package/dist/time-input/root/time-input-root.js +69 -39
- package/dist/time-picker/root/time-picker-root.d.ts +54 -8
- package/dist/time-picker/root/time-picker-root.js +121 -91
- package/dist/timeline/group/timeline-group.d.ts +46 -0
- package/dist/timeline/group/timeline-group.js +37 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +1 -0
- package/dist/timeline/root/timeline-root.d.ts +10 -3
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +26 -18
- package/dist/toast/item/toast-item.js +55 -48
- package/dist/toast/root/toast-root.d.ts +42 -8
- package/dist/toast/root/toast-root.js +64 -4
- package/dist/toggle/group/toggle-group.d.ts +57 -15
- package/dist/toggle/group/toggle-group.js +69 -9
- package/dist/toggle/root/toggle-root.d.ts +12 -1
- package/dist/toggle/root/toggle-root.js +11 -3
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- package/dist/tooltip/focus-target.d.ts +6 -0
- package/dist/tooltip/focus-target.js +9 -0
- package/dist/tooltip/root/tooltip-root.d.ts +42 -17
- package/dist/tooltip/root/tooltip-root.js +50 -9
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +35 -0
- package/dist/tour/root/tour-root.js +56 -5
- package/dist/tour/stop/tour-stop.d.ts +53 -8
- package/dist/tour/stop/tour-stop.js +45 -15
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/tree/item/tree-item.d.ts +54 -1
- package/dist/tree/item/tree-item.js +89 -20
- package/dist/tree/root/tree-root.d.ts +37 -0
- package/dist/tree/root/tree-root.js +51 -6
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +26 -0
- package/dist/trend/root/trend-root.d.ts +13 -0
- package/dist/trend/root/trend-root.js +14 -9
- package/dist/video/media-events.d.ts +49 -0
- package/dist/video/media-events.js +39 -0
- package/dist/video/root/video-root.d.ts +99 -13
- package/dist/video/root/video-root.js +84 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
- package/dist/video-playlist/root/video-playlist-root.js +60 -16
- package/dist/virtual-list/controls.d.ts +4 -0
- package/dist/virtual-list/controls.js +30 -0
- package/dist/virtual-list/fill.d.ts +30 -0
- package/dist/virtual-list/fill.js +39 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
- package/dist/virtual-list/root/virtual-list-root.js +175 -34
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +8871 -1286
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1918 -269
|
@@ -4,19 +4,50 @@ 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, hostAria } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, hostAria, slottedWords } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
const CONTROL = 'a[href], button, input, select, textarea, [tabindex]';
|
|
10
11
|
let HelixHeadlessListItem = class HelixHeadlessListItem extends HelixElement {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
14
|
+
this.disabled = false;
|
|
13
15
|
this.href = '';
|
|
14
16
|
this.rel = '';
|
|
15
17
|
this.target = '';
|
|
18
|
+
this.value = '';
|
|
19
|
+
}
|
|
20
|
+
get words() {
|
|
21
|
+
return this.childrenKnown ? slottedWords(this, ['']) : '';
|
|
22
|
+
}
|
|
23
|
+
get grouped() {
|
|
24
|
+
return this.focusable !== undefined;
|
|
25
|
+
}
|
|
26
|
+
get cell() {
|
|
27
|
+
return this.renderRoot?.querySelector?.('[part~="row"]') ?? null;
|
|
28
|
+
}
|
|
29
|
+
get controls() {
|
|
30
|
+
const slot = this.renderRoot?.querySelector?.('slot[name="end"]');
|
|
31
|
+
return (slot?.assignedElements({ flatten: true }) ?? [])
|
|
32
|
+
.flatMap((element) => [element, ...element.querySelectorAll('*')])
|
|
33
|
+
.filter((element) => element instanceof HTMLElement &&
|
|
34
|
+
element.matches(CONTROL) &&
|
|
35
|
+
!element.matches(':disabled'));
|
|
36
|
+
}
|
|
37
|
+
focusItem() {
|
|
38
|
+
this.cell?.focus();
|
|
39
|
+
}
|
|
40
|
+
follow() {
|
|
41
|
+
this.renderRoot?.querySelector('[part~="link"]')?.click();
|
|
16
42
|
}
|
|
17
43
|
willUpdate(changed) {
|
|
18
44
|
super.willUpdate(changed);
|
|
19
|
-
hostAria(this.internals, { role: 'listitem' });
|
|
45
|
+
hostAria(this.internals, { role: this.grouped ? 'row' : 'listitem' });
|
|
46
|
+
this.internals.ariaSelected = this.selected === undefined ? null : String(this.selected);
|
|
47
|
+
this.internals.ariaDisabled = this.grouped && this.disabled ? 'true' : null;
|
|
48
|
+
this.internals.ariaCurrent =
|
|
49
|
+
this.current !== undefined && this.href === '' ? this.current : null;
|
|
50
|
+
this.toggleState('selected', this.selected === true);
|
|
20
51
|
}
|
|
21
52
|
renderRail() {
|
|
22
53
|
return nothing;
|
|
@@ -25,26 +56,57 @@ let HelixHeadlessListItem = class HelixHeadlessListItem extends HelixElement {
|
|
|
25
56
|
const content = html `${this.renderRail()}<slot name="start"></slot>
|
|
26
57
|
<slot></slot>
|
|
27
58
|
<slot name="description"></slot>`;
|
|
59
|
+
const role = this.grouped ? 'gridcell' : nothing;
|
|
60
|
+
const tabindex = this.grouped ? (this.focusable ? '0' : '-1') : nothing;
|
|
28
61
|
return this.href === ''
|
|
29
|
-
? html `<div
|
|
30
|
-
|
|
62
|
+
? html `<div
|
|
63
|
+
part="row${this.current === undefined ? '' : ' row-current'}"
|
|
64
|
+
role=${role}
|
|
65
|
+
tabindex=${tabindex}
|
|
66
|
+
>${content}<slot name="end"></slot></div>`
|
|
67
|
+
: html `<div
|
|
68
|
+
part="row${this.current === undefined ? '' : ' row-current'}"
|
|
69
|
+
role=${role}
|
|
70
|
+
tabindex=${tabindex}
|
|
71
|
+
><a
|
|
31
72
|
part="link"
|
|
32
73
|
href=${this.href}
|
|
33
74
|
target=${this.target || nothing}
|
|
34
75
|
rel=${this.rel || nothing}
|
|
76
|
+
aria-current=${this.current ?? nothing}
|
|
77
|
+
tabindex=${this.grouped ? '-1' : nothing}
|
|
35
78
|
>${content}</a
|
|
36
79
|
><slot name="end"></slot></div>`;
|
|
37
80
|
}
|
|
38
81
|
};
|
|
82
|
+
__decorate([
|
|
83
|
+
property({
|
|
84
|
+
converter: {
|
|
85
|
+
fromAttribute: (value) => value === null || value === 'false' ? undefined : (value || 'true'),
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
], HelixHeadlessListItem.prototype, "current", void 0);
|
|
89
|
+
__decorate([
|
|
90
|
+
property({ reflect: true, type: Boolean })
|
|
91
|
+
], HelixHeadlessListItem.prototype, "disabled", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
property({ attribute: false })
|
|
94
|
+
], HelixHeadlessListItem.prototype, "focusable", void 0);
|
|
39
95
|
__decorate([
|
|
40
96
|
property()
|
|
41
97
|
], HelixHeadlessListItem.prototype, "href", void 0);
|
|
42
98
|
__decorate([
|
|
43
99
|
property()
|
|
44
100
|
], HelixHeadlessListItem.prototype, "rel", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
property({ attribute: false })
|
|
103
|
+
], HelixHeadlessListItem.prototype, "selected", void 0);
|
|
45
104
|
__decorate([
|
|
46
105
|
property()
|
|
47
106
|
], HelixHeadlessListItem.prototype, "target", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
property()
|
|
109
|
+
], HelixHeadlessListItem.prototype, "value", void 0);
|
|
48
110
|
HelixHeadlessListItem = __decorate([
|
|
49
111
|
customElement('helix-headless-list-item')
|
|
50
112
|
], HelixHeadlessListItem);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The first row's number, and what each row after it adds. */
|
|
2
|
+
export interface Numbering {
|
|
3
|
+
first: number;
|
|
4
|
+
step: -1 | 1;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The numbering `start` and `reversed` ask for, as `<ol>` reads them, or
|
|
8
|
+
* nothing where they ask for the ordinary count from one.
|
|
9
|
+
*
|
|
10
|
+
* Reversed without a start counts down from the number of rows, which is
|
|
11
|
+
* unknown until the rows are: `count` is `undefined` on a server and while
|
|
12
|
+
* hydrating, and the list counts from one until it knows.
|
|
13
|
+
*/
|
|
14
|
+
export declare const numbering: (start: number | undefined, reversed: boolean, count: number | undefined) => Numbering | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const numbering = (start, reversed, count) => {
|
|
2
|
+
const from = start !== undefined && Number.isFinite(start) ? Math.trunc(start) : undefined;
|
|
3
|
+
if (!reversed) {
|
|
4
|
+
return from === undefined ? undefined : { first: from, step: 1 };
|
|
5
|
+
}
|
|
6
|
+
const first = from ?? count;
|
|
7
|
+
return first === undefined ? undefined : { first, step: -1 };
|
|
8
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
import { HelixHeadlessListItem } from '../item/list-item.js';
|
|
4
|
+
import { type ListSelectionMode } from '../selection.js';
|
|
3
5
|
/**
|
|
4
6
|
* @summary A set of rows, announced as a list.
|
|
5
7
|
*
|
|
@@ -7,6 +9,29 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
7
9
|
* Sets `role="list"` on the host, so a screen reader counts the rows and
|
|
8
10
|
* announces each one's position, such as "1 of 7".
|
|
9
11
|
*
|
|
12
|
+
* **`selection-mode` makes the list interactive**, in the way of a grid list:
|
|
13
|
+
* a grid of rows that is one tab stop. Up and Down move between rows, Home
|
|
14
|
+
* and End go to the first and the last, and a typed letter goes to the next
|
|
15
|
+
* row starting with it. Left and Right move between the row and the controls
|
|
16
|
+
* in its `end` slot. `single` selects one row at a time and `multiple` any
|
|
17
|
+
* number, with Space or a press, and `value` holds the selected rows' values,
|
|
18
|
+
* separated by commas. A change asks with `helix-before-change` and tells
|
|
19
|
+
* with `change`. Enter acts on the row: it follows the row's link, or sends
|
|
20
|
+
* `helix-action` from the row. `none` selects nothing, so a press acts too. A
|
|
21
|
+
* `disabled` row is passed over.
|
|
22
|
+
*
|
|
23
|
+
* **Leave `selection-mode` unset for a list a reader reads**, and set it for
|
|
24
|
+
* one a reader chooses from or acts on. The rows of an interactive list are
|
|
25
|
+
* grid rows, which hold controls as a list box option cannot. Give a control
|
|
26
|
+
* in `end` `tabindex="-1"` to leave it to the arrow keys and out of the tab
|
|
27
|
+
* order.
|
|
28
|
+
*
|
|
29
|
+
* `start` and `reversed` number an ordered list as `<ol>` does. The list
|
|
30
|
+
* writes where the numbers start and which way they run as `--list-first` and
|
|
31
|
+
* `--list-step` on its slot, which the styled tier counts from. Reversed with
|
|
32
|
+
* no `start` counts down from the number of rows, which a server cannot know,
|
|
33
|
+
* so served markup counts from one until the list runs.
|
|
34
|
+
*
|
|
10
35
|
* @since 0.1.0
|
|
11
36
|
* @status stable
|
|
12
37
|
* @category data
|
|
@@ -14,6 +39,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
14
39
|
* @documentation https://fusion.dev/helix/components/list
|
|
15
40
|
*
|
|
16
41
|
* @slot - The rows.
|
|
42
|
+
*
|
|
43
|
+
* @event {Event} change - Fired once a press has changed which rows are selected.
|
|
44
|
+
* @event {HelixActionEvent} helix-action - Sent from a row when the reader acts on it: Enter, or a press in a list that selects nothing. Read the row from `target`. A row with `href` follows its link instead.
|
|
45
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a press changes which rows are selected, with the `value` it would leave. Cancelable.
|
|
46
|
+
*
|
|
47
|
+
* @cssproperty --list-first - The number of the first row, written where `start` or `reversed` moves it.
|
|
48
|
+
* @cssproperty --list-step - What each row adds to the number before it: `1`, or `-1` where `reversed`.
|
|
17
49
|
*/
|
|
18
50
|
export declare class HelixHeadlessList extends HelixElement {
|
|
19
51
|
/**
|
|
@@ -43,6 +75,22 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
43
75
|
* The list's name, read by screen readers.
|
|
44
76
|
*/
|
|
45
77
|
label: string;
|
|
78
|
+
/**
|
|
79
|
+
* Numbers an ordered list downward, so the count falls row by row and ends at
|
|
80
|
+
* its last row, as `<ol reversed>` does.
|
|
81
|
+
*/
|
|
82
|
+
reversed: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Makes the list interactive: `single` selects one row, `multiple` any
|
|
85
|
+
* number, and `none` moves and acts without selecting. Unset is a list a
|
|
86
|
+
* reader reads, with no tab stop of its own.
|
|
87
|
+
*/
|
|
88
|
+
selectionMode?: ListSelectionMode;
|
|
89
|
+
/**
|
|
90
|
+
* The number of an ordered list's first row, as `<ol start>` is. Unset counts
|
|
91
|
+
* from one, or down from the number of rows where `reversed`.
|
|
92
|
+
*/
|
|
93
|
+
start?: number;
|
|
46
94
|
/**
|
|
47
95
|
* The markers an ordered list draws. It takes the five values of `<ol type>`.
|
|
48
96
|
*
|
|
@@ -51,18 +99,67 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
51
99
|
* the CSS ones, so `<helix-headless-list kind="ordered" type="i">` is what a
|
|
52
100
|
* consumer would have written on an `<ol>`.
|
|
53
101
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `list-item` counter, and that counter is not author-resettable. Measured in
|
|
57
|
-
* Chrome 148, `counter-reset: list-item 4` moves nothing on a `<div>`, on a
|
|
58
|
-
* `<ul>`, or even on a real `<ol>`, while `<ol start="5">` does and a *named*
|
|
59
|
-
* counter with explicit `::before` content does. So the markers would have to
|
|
60
|
-
* be rebuilt out of generated content to gain a start, which is a different
|
|
61
|
-
* component. `type` is only `list-style-type` and works.
|
|
102
|
+
* `type` is only `list-style-type`. `start` and `reversed` move the count
|
|
103
|
+
* itself.
|
|
62
104
|
*/
|
|
63
105
|
type?: '1' | 'a' | 'A' | 'i' | 'I';
|
|
106
|
+
/**
|
|
107
|
+
* The selected rows' values, separated by commas, in a list that selects.
|
|
108
|
+
*
|
|
109
|
+
* Set it to start with rows selected. A row's value is its `value`, or its
|
|
110
|
+
* words where it has none.
|
|
111
|
+
*/
|
|
112
|
+
value: string;
|
|
113
|
+
/** The row the reader was last on, which keeps the tab stop. */
|
|
114
|
+
private last;
|
|
115
|
+
/**
|
|
116
|
+
* Up, Down, Home, End and typed letters, moving focus and choosing nothing,
|
|
117
|
+
* from the focused row and without wrapping. Left and Right are the row's.
|
|
118
|
+
*/
|
|
119
|
+
protected readonly keys: KeyboardNavigationController;
|
|
120
|
+
/** Whether the list is a grid a reader moves through. */
|
|
121
|
+
private get interactive();
|
|
122
|
+
/** The rows the list holds, in order. */
|
|
123
|
+
get rows(): HelixHeadlessListItem[];
|
|
124
|
+
/** The rows a key can land on, in an interactive list. */
|
|
125
|
+
private get reachable();
|
|
126
|
+
/** A row as the keyboard controller sees it: an item it moves focus to and never chooses. */
|
|
127
|
+
private navigable;
|
|
128
|
+
/** What a row stands for in `value`: its own `value`, or its words. */
|
|
129
|
+
private valueFor;
|
|
130
|
+
/**
|
|
131
|
+
* Tells every row its place: whether it holds the one tab stop and whether
|
|
132
|
+
* it is selected, or that it is a plain row. Through `whenHydrated`, so a
|
|
133
|
+
* row a server rendered draws its served markup first.
|
|
134
|
+
*/
|
|
135
|
+
private sync;
|
|
136
|
+
/** The row a press or a key came from, read off the event's path. */
|
|
137
|
+
private rowOf;
|
|
138
|
+
/**
|
|
139
|
+
* Selects the row, or lets it go, asking first. `helix-before-change`
|
|
140
|
+
* carries the `value` the press would leave, and `change` follows once it
|
|
141
|
+
* has moved.
|
|
142
|
+
*/
|
|
143
|
+
protected press(row: HelixHeadlessListItem): void;
|
|
144
|
+
/** Acts on the row: follows its link, or says it was acted on. */
|
|
145
|
+
protected act(row: HelixHeadlessListItem): void;
|
|
146
|
+
/** Left and Right inside a row: the cell, then each control in `end`, and back. */
|
|
147
|
+
private moveInRow;
|
|
148
|
+
private readonly handleKeydown;
|
|
149
|
+
private readonly handleClick;
|
|
150
|
+
private readonly handleFocusin;
|
|
151
|
+
connectedCallback(): void;
|
|
152
|
+
disconnectedCallback(): void;
|
|
153
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
154
|
+
protected updated(changed: PropertyValues): void;
|
|
64
155
|
protected willUpdate(changed: PropertyValues): void;
|
|
156
|
+
/**
|
|
157
|
+
* Where the numbers start and which way they run, as custom properties on
|
|
158
|
+
* the slot the rows inherit from, or nothing where they count up from one.
|
|
159
|
+
*/
|
|
160
|
+
private get numbers();
|
|
65
161
|
protected render(): TemplateResult;
|
|
162
|
+
private readonly handleSlotChange;
|
|
66
163
|
}
|
|
67
164
|
declare global {
|
|
68
165
|
interface HTMLElementTagNameMap {
|
|
@@ -4,20 +4,193 @@ 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, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
-
import { html } from 'lit';
|
|
7
|
+
import { commaList, customElement, HelixActionEvent, HelixBeforeChangeEvent, HelixElement, hostAria, inlineStep, KeyboardNavigationController, requestChange, rovingStop, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { HelixHeadlessListItem } from '../item/list-item.js';
|
|
11
|
+
import { numbering } from '../numbering.js';
|
|
12
|
+
import { pressedValue, rowStop } from '../selection.js';
|
|
13
|
+
const PRESSABLE = 'a[href], button, input, label, select, textarea, [tabindex]';
|
|
10
14
|
let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
|
|
11
15
|
constructor() {
|
|
12
16
|
super(...arguments);
|
|
13
17
|
this.label = '';
|
|
18
|
+
this.reversed = false;
|
|
19
|
+
this.value = '';
|
|
20
|
+
this.keys = new KeyboardNavigationController(this, {
|
|
21
|
+
items: () => this.reachable.map((row) => this.navigable(row)),
|
|
22
|
+
origin: 'focus',
|
|
23
|
+
reserved: () => ['ArrowLeft', 'ArrowRight'],
|
|
24
|
+
selects: () => false,
|
|
25
|
+
typeahead: (item) => item.words,
|
|
26
|
+
wrap: false,
|
|
27
|
+
});
|
|
28
|
+
this.handleKeydown = (event) => {
|
|
29
|
+
const row = this.interactive ? this.rowOf(event) : undefined;
|
|
30
|
+
if (!row || row.disabled || event.altKey || event.ctrlKey || event.metaKey) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
|
34
|
+
this.moveInRow(row, event);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (event.composedPath()[0] !== row.cell) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (event.key === 'Enter') {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
this.act(row);
|
|
43
|
+
}
|
|
44
|
+
else if (event.key === ' ') {
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
this.press(row);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
this.handleClick = (event) => {
|
|
50
|
+
const row = this.interactive ? this.rowOf(event) : undefined;
|
|
51
|
+
if (!row) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const path = event.composedPath();
|
|
55
|
+
const cell = row.cell;
|
|
56
|
+
const end = cell && path.includes(cell) ? path.indexOf(cell) : path.indexOf(row);
|
|
57
|
+
const inner = path.slice(0, Math.max(0, end));
|
|
58
|
+
if (inner.some((node) => node instanceof HTMLElement && node.matches(PRESSABLE))) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (this.selectionMode === 'none') {
|
|
62
|
+
this.act(row);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.press(row);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
this.handleFocusin = (event) => {
|
|
69
|
+
const row = this.interactive ? this.rowOf(event) : undefined;
|
|
70
|
+
if (row && row !== this.last) {
|
|
71
|
+
this.last = row;
|
|
72
|
+
this.sync();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.handleSlotChange = () => {
|
|
76
|
+
this.requestUpdate();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
get interactive() {
|
|
80
|
+
return this.selectionMode !== undefined;
|
|
81
|
+
}
|
|
82
|
+
get rows() {
|
|
83
|
+
return this.knownChildren.filter((child) => child instanceof HelixHeadlessListItem);
|
|
84
|
+
}
|
|
85
|
+
get reachable() {
|
|
86
|
+
return this.interactive ? this.rows.filter((row) => !row.disabled) : [];
|
|
87
|
+
}
|
|
88
|
+
navigable(row) {
|
|
89
|
+
return {
|
|
90
|
+
contains: (node) => row.contains(node),
|
|
91
|
+
disabled: row.disabled,
|
|
92
|
+
focusItem: () => row.focusItem(),
|
|
93
|
+
select: () => { },
|
|
94
|
+
selected: false,
|
|
95
|
+
words: row.words,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
valueFor(row) {
|
|
99
|
+
return row.value || row.words;
|
|
100
|
+
}
|
|
101
|
+
sync() {
|
|
102
|
+
const mode = this.selectionMode;
|
|
103
|
+
const chosen = new Set(commaList(this.value));
|
|
104
|
+
const rows = this.rows;
|
|
105
|
+
const holder = mode
|
|
106
|
+
? rovingStop(rows, this.last, {
|
|
107
|
+
disabled: (row) => row.disabled,
|
|
108
|
+
selected: (row) => chosen.has(this.valueFor(row)),
|
|
109
|
+
})
|
|
110
|
+
: undefined;
|
|
111
|
+
for (const row of rows) {
|
|
112
|
+
whenHydrated(row, () => {
|
|
113
|
+
row.focusable = mode ? row === holder : undefined;
|
|
114
|
+
row.selected =
|
|
115
|
+
mode === undefined || mode === 'none' ? undefined : chosen.has(this.valueFor(row));
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
rowOf(event) {
|
|
120
|
+
return event
|
|
121
|
+
.composedPath()
|
|
122
|
+
.find((node) => node instanceof HelixHeadlessListItem && node.parentElement === this);
|
|
123
|
+
}
|
|
124
|
+
press(row) {
|
|
125
|
+
const mode = this.selectionMode;
|
|
126
|
+
if (mode === undefined || mode === 'none' || row.disabled) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
requestChange({
|
|
130
|
+
apply: (value) => {
|
|
131
|
+
this.value = value;
|
|
132
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
133
|
+
},
|
|
134
|
+
event: (value) => new HelixBeforeChangeEvent({ value }),
|
|
135
|
+
host: this,
|
|
136
|
+
next: pressedValue(mode, this.value, this.valueFor(row)),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
act(row) {
|
|
140
|
+
if (row.disabled) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (row.href !== '') {
|
|
144
|
+
row.follow();
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
row.dispatchEvent(new HelixActionEvent());
|
|
148
|
+
}
|
|
149
|
+
moveInRow(row, event) {
|
|
150
|
+
const step = inlineStep(this, event.key);
|
|
151
|
+
const cell = row.cell;
|
|
152
|
+
if (step === 0 || !cell) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const stops = [cell, ...row.controls];
|
|
156
|
+
const on = event.composedPath().find((node) => stops.includes(node));
|
|
157
|
+
const at = Math.max(0, stops.indexOf(on));
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
stops[rowStop(stops.length, at, step)]?.focus();
|
|
160
|
+
}
|
|
161
|
+
connectedCallback() {
|
|
162
|
+
super.connectedCallback();
|
|
163
|
+
this.addEventListener('keydown', this.handleKeydown);
|
|
164
|
+
this.addEventListener('click', this.handleClick);
|
|
165
|
+
this.addEventListener('focusin', this.handleFocusin);
|
|
166
|
+
}
|
|
167
|
+
disconnectedCallback() {
|
|
168
|
+
super.disconnectedCallback();
|
|
169
|
+
this.removeEventListener('keydown', this.handleKeydown);
|
|
170
|
+
this.removeEventListener('click', this.handleClick);
|
|
171
|
+
this.removeEventListener('focusin', this.handleFocusin);
|
|
172
|
+
}
|
|
173
|
+
firstUpdated(changed) {
|
|
174
|
+
super.firstUpdated(changed);
|
|
175
|
+
this.finishHydration();
|
|
176
|
+
}
|
|
177
|
+
updated(changed) {
|
|
178
|
+
super.updated(changed);
|
|
179
|
+
if (this.interactive || changed.get('selectionMode') !== undefined) {
|
|
180
|
+
this.sync();
|
|
181
|
+
}
|
|
14
182
|
}
|
|
15
183
|
willUpdate(changed) {
|
|
16
184
|
super.willUpdate(changed);
|
|
17
|
-
hostAria(this.internals, { label: this.label, role: 'list' });
|
|
185
|
+
hostAria(this.internals, { label: this.label, role: this.interactive ? 'grid' : 'list' });
|
|
186
|
+
this.internals.ariaMultiSelectable = this.selectionMode === 'multiple' ? 'true' : null;
|
|
187
|
+
}
|
|
188
|
+
get numbers() {
|
|
189
|
+
const counted = numbering(this.start, this.reversed, this.childrenKnown ? this.knownChildren.length : undefined);
|
|
190
|
+
return counted ? `--list-first: ${counted.first}; --list-step: ${counted.step}` : nothing;
|
|
18
191
|
}
|
|
19
192
|
render() {
|
|
20
|
-
return html `<slot></slot>`;
|
|
193
|
+
return html `<slot style=${this.numbers} @slotchange=${this.handleSlotChange}></slot>`;
|
|
21
194
|
}
|
|
22
195
|
};
|
|
23
196
|
__decorate([
|
|
@@ -26,9 +199,21 @@ __decorate([
|
|
|
26
199
|
__decorate([
|
|
27
200
|
property()
|
|
28
201
|
], HelixHeadlessList.prototype, "label", void 0);
|
|
202
|
+
__decorate([
|
|
203
|
+
property({ type: Boolean })
|
|
204
|
+
], HelixHeadlessList.prototype, "reversed", void 0);
|
|
205
|
+
__decorate([
|
|
206
|
+
property({ attribute: 'selection-mode' })
|
|
207
|
+
], HelixHeadlessList.prototype, "selectionMode", void 0);
|
|
208
|
+
__decorate([
|
|
209
|
+
property({ type: Number })
|
|
210
|
+
], HelixHeadlessList.prototype, "start", void 0);
|
|
29
211
|
__decorate([
|
|
30
212
|
property({ reflect: true })
|
|
31
213
|
], HelixHeadlessList.prototype, "type", void 0);
|
|
214
|
+
__decorate([
|
|
215
|
+
property()
|
|
216
|
+
], HelixHeadlessList.prototype, "value", void 0);
|
|
32
217
|
HelixHeadlessList = __decorate([
|
|
33
218
|
customElement('helix-headless-list')
|
|
34
219
|
], HelixHeadlessList);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** How many rows a reader can select in an interactive list. */
|
|
2
|
+
export type ListSelectionMode = 'multiple' | 'none' | 'single';
|
|
3
|
+
/**
|
|
4
|
+
* The `value` a press on the row carrying `pressed` leaves.
|
|
5
|
+
*
|
|
6
|
+
* `single` selects that row alone, or none where it was the one selected.
|
|
7
|
+
* `multiple` adds it, or takes it out. `none` selects nothing and leaves the
|
|
8
|
+
* value as it was. Tag Group answers the same question for its tags.
|
|
9
|
+
*/
|
|
10
|
+
export declare const pressedValue: (mode: ListSelectionMode, value: string, pressed: string) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Where Left or Right goes inside a row: `at` is the row's place among its
|
|
13
|
+
* `count` stops, the cell first and its controls after it, and `step` is the
|
|
14
|
+
* way the key points along the line.
|
|
15
|
+
*
|
|
16
|
+
* Past either end it comes back to the cell, so the keys never leave the row,
|
|
17
|
+
* and from the cell going back reaches the last control.
|
|
18
|
+
*/
|
|
19
|
+
export declare const rowStop: (count: number, at: number, step: -1 | 1) => number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { commaList, toggleValue } from '@fusion.dev/helix-core';
|
|
2
|
+
export const pressedValue = (mode, value, pressed) => {
|
|
3
|
+
const now = commaList(value);
|
|
4
|
+
if (mode === 'single') {
|
|
5
|
+
return now.includes(pressed) ? '' : pressed;
|
|
6
|
+
}
|
|
7
|
+
if (mode === 'multiple') {
|
|
8
|
+
return toggleValue(now, pressed).join(', ');
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
};
|
|
12
|
+
export const rowStop = (count, at, step) => {
|
|
13
|
+
if (count <= 1) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
const next = at + step;
|
|
17
|
+
if (next >= count) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
return next < 0 ? count - 1 : next;
|
|
21
|
+
};
|