@fusion.dev/helix-headless 0.146.0 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +9287 -1084
- package/dist/accordion/item/accordion-item.d.ts +43 -21
- package/dist/accordion/item/accordion-item.js +37 -11
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +6 -8
- package/dist/announcement/root/announcement-root.d.ts +66 -6
- package/dist/announcement/root/announcement-root.js +144 -13
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +14 -7
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +77 -8
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +28 -4
- package/dist/chat/root/chat-root.js +12 -7
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
- package/dist/checkbox-group/select-all.d.ts +9 -4
- package/dist/checkbox-group/select-all.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +41 -18
- package/dist/code-block/root/code-block-root.js +21 -6
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +99 -55
- package/dist/color-picker/wheel.d.ts +28 -0
- package/dist/color-picker/wheel.js +15 -0
- package/dist/combobox/root/combobox-root.d.ts +83 -11
- package/dist/combobox/root/combobox-root.js +81 -18
- package/dist/command/root/command-root.d.ts +7 -4
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +29 -50
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +22 -4
- package/dist/description-list/item/description-list-item.js +14 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +38 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/empty/root/empty-root.d.ts +46 -2
- package/dist/empty/root/empty-root.js +50 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +55 -21
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +11 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +10 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +5 -5
- package/dist/format-date/options.js +10 -39
- package/dist/format-date/root/format-date-root.d.ts +53 -4
- package/dist/format-date/root/format-date-root.js +38 -50
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +76 -3
- package/dist/heatmap/root/heatmap-root.js +105 -20
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +20 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +23 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +25 -26
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +31 -24
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +125 -26
- package/dist/listbox/root/listbox-root.js +156 -166
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +29 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +5 -2
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +48 -3
- package/dist/notifications/root/notifications-root.js +36 -6
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
- package/dist/object-inspector/root/object-inspector-root.js +31 -20
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +51 -1
- package/dist/pin-input/code.js +37 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +151 -156
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +31 -9
- package/dist/qr-code/root/qr-code-root.js +29 -17
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +115 -11
- package/dist/select/root/select-root.js +104 -20
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
- package/dist/speed-dial/item/speed-dial-item.js +43 -5
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
- package/dist/speed-dial/root/speed-dial-root.js +123 -6
- package/dist/splitter/root/splitter-root.d.ts +9 -2
- package/dist/splitter/root/splitter-root.js +18 -3
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +93 -29
- package/dist/table/row/table-row.d.ts +36 -0
- package/dist/table/row/table-row.js +52 -2
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +23 -20
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +12 -14
- package/dist/time-picker/root/time-picker-root.js +18 -23
- package/dist/toast/item/toast-item.d.ts +9 -6
- package/dist/toast/item/toast-item.js +1 -1
- package/dist/toast/root/toast-root.d.ts +40 -4
- package/dist/toast/root/toast-root.js +68 -16
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -43
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +52 -5
- package/dist/toolbar/root/toolbar-root.js +88 -13
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -2
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +16 -1
- package/dist/video/root/video-root.js +15 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +53 -41
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4934 -954
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +946 -253
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -4,12 +4,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, commaList, customElement, cycle, fillTemplate, format, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, MixinCollection, parse, reflectElements, requestChange, sort, splitValues, toggleEvery, whenHydrated, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, assignSlots, commaList, customElement, cycle, everyState, fillTemplate, followLink, format, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, inRowOrder, MixinCollection, onAndroid, parse, reflectElements, requestChange, sort, splitValues, toggleEvery, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
11
11
|
import '../../checkbox/index.js';
|
|
12
12
|
import { edgeOf } from '../column/table-column.js';
|
|
13
|
+
import { TableGridController } from '../grid-controller.js';
|
|
13
14
|
const tracksOf = (list, wanted) => {
|
|
14
15
|
const words = splitValues(list, ' ');
|
|
15
16
|
const valid = (track) => typeof CSS === 'undefined' || CSS.supports('grid-template-columns', track);
|
|
@@ -51,6 +52,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
51
52
|
this.defaultSelected = '';
|
|
52
53
|
this.defaultSort = '';
|
|
53
54
|
this.descendingLabel = 'descending';
|
|
55
|
+
this.grid = false;
|
|
54
56
|
this.label = '';
|
|
55
57
|
this.selectable = false;
|
|
56
58
|
this.selectAllLabel = 'Select every row';
|
|
@@ -65,6 +67,15 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
65
67
|
label: true,
|
|
66
68
|
target: () => this.partNamed('table'),
|
|
67
69
|
});
|
|
70
|
+
this.gridKeys = new TableGridController(this, {
|
|
71
|
+
activate: (place, event) => this.activate(place, event),
|
|
72
|
+
columns: () => this.tableColumns.filter((column) => column.shown),
|
|
73
|
+
on: () => this.grid,
|
|
74
|
+
part: (name) => this.partNamed(name),
|
|
75
|
+
rows: () => (this.childrenKnown ? this.arrangedRows : []),
|
|
76
|
+
selectAll: () => this.selectable && this.requestSelected(new Set(this.everyKey)),
|
|
77
|
+
selectable: () => this.selectable,
|
|
78
|
+
});
|
|
68
79
|
this.heardSort = undefined;
|
|
69
80
|
this.heardSortBefore = undefined;
|
|
70
81
|
this.heardSelected = undefined;
|
|
@@ -74,10 +85,9 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
74
85
|
return;
|
|
75
86
|
}
|
|
76
87
|
const root = origin.getRootNode();
|
|
77
|
-
const keys = this.chosen;
|
|
78
88
|
if (root === this.renderRoot) {
|
|
79
89
|
event.preventDefault();
|
|
80
|
-
this.
|
|
90
|
+
this.chooseAll();
|
|
81
91
|
return;
|
|
82
92
|
}
|
|
83
93
|
const found = this.keyed.find(({ row }) => row.shadowRoot === root);
|
|
@@ -85,13 +95,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
85
95
|
return;
|
|
86
96
|
}
|
|
87
97
|
event.preventDefault();
|
|
88
|
-
|
|
89
|
-
keys.add(found.key);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
keys.delete(found.key);
|
|
93
|
-
}
|
|
94
|
-
this.requestSelected(keys);
|
|
98
|
+
this.chooseRow(found.key, event.detail.checked);
|
|
95
99
|
};
|
|
96
100
|
this.handleHeadClick = (event) => {
|
|
97
101
|
const path = event.composedPath();
|
|
@@ -204,9 +208,55 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
204
208
|
},
|
|
205
209
|
event: (value) => new HelixSelectEvent({ value }),
|
|
206
210
|
host: this,
|
|
207
|
-
next:
|
|
211
|
+
next: inRowOrder(keys, this.keyed.map(({ key }) => key)).join(','),
|
|
208
212
|
});
|
|
209
213
|
}
|
|
214
|
+
get everyKey() {
|
|
215
|
+
return this.keyed.map(({ key }) => key);
|
|
216
|
+
}
|
|
217
|
+
chooseAll() {
|
|
218
|
+
this.requestSelected(new Set(toggleEvery(this.chosen, this.everyKey)));
|
|
219
|
+
}
|
|
220
|
+
chooseRow(key, on) {
|
|
221
|
+
const keys = this.chosen;
|
|
222
|
+
if (on) {
|
|
223
|
+
keys.add(key);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
keys.delete(key);
|
|
227
|
+
}
|
|
228
|
+
this.requestSelected(keys);
|
|
229
|
+
}
|
|
230
|
+
activate(place, event) {
|
|
231
|
+
const lead = this.selectable && place.column === 0;
|
|
232
|
+
if (event.key === 'F2') {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
if (place.row === -1) {
|
|
236
|
+
if (lead) {
|
|
237
|
+
this.chooseAll();
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
const shown = this.tableColumns.filter((one) => one.shown);
|
|
241
|
+
const column = shown[place.column - (this.selectable ? 1 : 0)];
|
|
242
|
+
if (column?.canSort) {
|
|
243
|
+
this.toggleSort(column.field);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
const row = this.arrangedRows[place.row];
|
|
249
|
+
const found = this.keyed.find((one) => one.row === row);
|
|
250
|
+
if (this.selectable && found && (event.key === ' ' || lead)) {
|
|
251
|
+
this.chooseRow(found.key, !this.chosen.has(found.key));
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
if (event.key === 'Enter' && row?.href) {
|
|
255
|
+
followLink(this.ownerDocument, { href: row.href, rel: row.rel, target: row.target }, event);
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
210
260
|
markSelected() {
|
|
211
261
|
const keys = this.chosen;
|
|
212
262
|
for (const { key, row } of this.keyed) {
|
|
@@ -230,6 +280,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
230
280
|
}
|
|
231
281
|
markSorted() {
|
|
232
282
|
const current = parse(this.sort);
|
|
283
|
+
const android = onAndroid();
|
|
233
284
|
for (const column of this.tableColumns) {
|
|
234
285
|
column.sorted =
|
|
235
286
|
current && column.canSort && column.field === current.field
|
|
@@ -237,6 +288,13 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
237
288
|
? 'ascending'
|
|
238
289
|
: 'descending'
|
|
239
290
|
: undefined;
|
|
291
|
+
column.sortWords =
|
|
292
|
+
android && column.sorted
|
|
293
|
+
? fillTemplate(this.sortedLabel, {
|
|
294
|
+
column: column.textContent?.trim() || column.field,
|
|
295
|
+
order: column.sorted === 'ascending' ? this.ascendingLabel : this.descendingLabel,
|
|
296
|
+
})
|
|
297
|
+
: '';
|
|
240
298
|
}
|
|
241
299
|
}
|
|
242
300
|
get tableColumns() {
|
|
@@ -317,16 +375,9 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
317
375
|
}
|
|
318
376
|
return;
|
|
319
377
|
}
|
|
320
|
-
const
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
head.assign(...this.tableColumns);
|
|
326
|
-
body.assign(...this.arrangedRows);
|
|
327
|
-
this.renderRoot
|
|
328
|
-
?.querySelector('slot[name="heading"]')
|
|
329
|
-
?.assign(...this.headings);
|
|
378
|
+
const columns = new Set(this.tableColumns);
|
|
379
|
+
const headings = new Set(this.headings);
|
|
380
|
+
assignSlots(this.renderRoot, [...columns, ...headings, ...this.arrangedRows], (child) => (columns.has(child) ? 'columns' : headings.has(child) ? 'heading' : ''));
|
|
330
381
|
}
|
|
331
382
|
alignCells() {
|
|
332
383
|
if (typeof CSSStyleSheet === 'undefined' || !('replaceSync' in CSSStyleSheet.prototype)) {
|
|
@@ -360,33 +411,43 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
360
411
|
this.markSorted();
|
|
361
412
|
this.markSelected();
|
|
362
413
|
this.nameByHeading();
|
|
414
|
+
if (this.childrenKnown) {
|
|
415
|
+
this.gridKeys.mark();
|
|
416
|
+
this.gridKeys.place();
|
|
417
|
+
}
|
|
363
418
|
}
|
|
364
419
|
renderSelectAll() {
|
|
365
420
|
if (!this.selectable) {
|
|
366
421
|
return nothing;
|
|
367
422
|
}
|
|
368
423
|
const every = this.childrenKnown ? this.keyed.map(({ key }) => key) : [];
|
|
369
|
-
const
|
|
370
|
-
const count = every.filter((key) => keys.has(key)).length;
|
|
424
|
+
const { checked, indeterminate } = everyState(this.chosen, every);
|
|
371
425
|
const checkbox = this.tag('checkbox');
|
|
426
|
+
const grid = this.grid;
|
|
372
427
|
return html `<span part="select-all" role="columnheader"
|
|
428
|
+
tabindex=${grid ? (this.gridKeys.isStop({ column: 0, row: -1 }) ? '0' : '-1') : nothing}
|
|
373
429
|
><${checkbox}
|
|
374
430
|
part="checkbox"
|
|
431
|
+
tabindex=${grid ? '-1' : nothing}
|
|
375
432
|
exportparts="box: checkbox-box, control: checkbox-control, feedback: checkbox-feedback,
|
|
376
433
|
field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark,
|
|
377
434
|
mark-checked: checkbox-mark-checked, mark-dash: checkbox-mark-dash,
|
|
378
435
|
mark-indeterminate: checkbox-mark-indeterminate"
|
|
379
436
|
aria-label=${this.selectAllLabel}
|
|
380
|
-
.checked=${
|
|
381
|
-
.indeterminate=${
|
|
437
|
+
.checked=${checked}
|
|
438
|
+
.indeterminate=${indeterminate}
|
|
382
439
|
></${checkbox}
|
|
383
440
|
></span>`;
|
|
384
441
|
}
|
|
385
442
|
render() {
|
|
386
443
|
const template = this.template;
|
|
387
|
-
|
|
444
|
+
const grid = this.grid;
|
|
445
|
+
const start = grid ? html `<span part="grid-start" tabindex="-1"></span>` : nothing;
|
|
446
|
+
const end = grid ? html `<span part="grid-end" tabindex="-1"></span>` : nothing;
|
|
447
|
+
return html `<slot name="heading"></slot>${start}<div
|
|
388
448
|
part="table"
|
|
389
|
-
role
|
|
449
|
+
role=${grid ? 'grid' : 'table'}
|
|
450
|
+
aria-multiselectable=${grid && this.selectable ? 'true' : nothing}
|
|
390
451
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
391
452
|
aria-label=${this.label || 'Table'}
|
|
392
453
|
style=${template ? `--table-template: ${template}` : ''}
|
|
@@ -398,8 +459,8 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
|
|
|
398
459
|
this.handleSlotChange();
|
|
399
460
|
}}
|
|
400
461
|
></slot>
|
|
401
|
-
${this.renderStatus(this.hasRows, 'cell')}
|
|
402
|
-
</div>${this.renderLive(this.hasRows)}`;
|
|
462
|
+
${this.renderStatus(this.hasRows, grid ? 'gridcell' : 'cell')}
|
|
463
|
+
</div>${end}${this.renderLive(this.hasRows)}`;
|
|
403
464
|
}
|
|
404
465
|
};
|
|
405
466
|
__decorate([
|
|
@@ -417,6 +478,9 @@ __decorate([
|
|
|
417
478
|
__decorate([
|
|
418
479
|
property({ attribute: 'descending-label' })
|
|
419
480
|
], HelixHeadlessTable.prototype, "descendingLabel", void 0);
|
|
481
|
+
__decorate([
|
|
482
|
+
property({ type: Boolean })
|
|
483
|
+
], HelixHeadlessTable.prototype, "grid", void 0);
|
|
420
484
|
__decorate([
|
|
421
485
|
property()
|
|
422
486
|
], HelixHeadlessTable.prototype, "label", void 0);
|
|
@@ -13,6 +13,14 @@ import '../../checkbox/index.js';
|
|
|
13
13
|
* In a `selectable` table the row draws a checkbox cell before its own cells,
|
|
14
14
|
* and `value` is the key the table's `selected` lists it by.
|
|
15
15
|
*
|
|
16
|
+
* **`href` makes the whole row a link**, as a row action does in React Aria's
|
|
17
|
+
* table: a press anywhere on the row follows it, except on a link or a control
|
|
18
|
+
* of the row's own, and Control, Command or Shift open it the way they open a
|
|
19
|
+
* link. A drag that selects text follows nothing. A row in a table is not a
|
|
20
|
+
* stop of its own, so put the same link in a cell, usually the row header,
|
|
21
|
+
* which is what the keyboard and a screen reader reach. In a `grid` table,
|
|
22
|
+
* Enter on any cell of the row follows it as well.
|
|
23
|
+
*
|
|
16
24
|
* @since 0.1.0
|
|
17
25
|
* @status stable
|
|
18
26
|
* @aliases Row, TableRow
|
|
@@ -34,6 +42,7 @@ import '../../checkbox/index.js';
|
|
|
34
42
|
* @csspart select - The cell that holds the row's checkbox, in a `selectable` table.
|
|
35
43
|
* @csspart select-selected - Added to `select` while the row is selected.
|
|
36
44
|
*
|
|
45
|
+
* @cssstate link - While the row has `href`, so a press on it follows the link.
|
|
37
46
|
* @cssstate selected - While the row is selected, in a `selectable` table.
|
|
38
47
|
*/
|
|
39
48
|
export declare class HelixHeadlessTableRow extends HelixElement {
|
|
@@ -42,6 +51,15 @@ export declare class HelixHeadlessTableRow extends HelixElement {
|
|
|
42
51
|
* finds its columns. Not a consumer's to read or set.
|
|
43
52
|
*/
|
|
44
53
|
readonly isTableRow = true;
|
|
54
|
+
/**
|
|
55
|
+
* The URL a press on the row follows, which makes the whole row a link.
|
|
56
|
+
* Empty, the default, leaves presses to the row's cells.
|
|
57
|
+
*/
|
|
58
|
+
href: string;
|
|
59
|
+
/** The `rel` of the row's link. You set it yourself, as on an anchor. */
|
|
60
|
+
rel: string;
|
|
61
|
+
/** Where the row's link opens, such as `_blank`. */
|
|
62
|
+
target: string;
|
|
45
63
|
/**
|
|
46
64
|
* The key the table's `selected` lists this row by. Left empty, the row is
|
|
47
65
|
* known by its place among the rows as written.
|
|
@@ -59,6 +77,17 @@ export declare class HelixHeadlessTableRow extends HelixElement {
|
|
|
59
77
|
selected: boolean;
|
|
60
78
|
/** @internal The name of the row's checkbox, written by the table. Not a consumer's to set. */
|
|
61
79
|
selectLabel: string;
|
|
80
|
+
/**
|
|
81
|
+
* @internal Whether the row is a row of a `grid` table, written by that
|
|
82
|
+
* table. Not a consumer's to set. The checkbox cell is then a `gridcell`
|
|
83
|
+
* that takes focus, and the row says whether it is selected.
|
|
84
|
+
*/
|
|
85
|
+
gridCell: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* @internal Whether the checkbox cell holds the grid's one tab stop, written
|
|
88
|
+
* by the table that sets `gridCell`. Not a consumer's to set.
|
|
89
|
+
*/
|
|
90
|
+
selectStop: boolean;
|
|
62
91
|
/** The table's rules this row holds, so the next ones replace them rather than pile up. */
|
|
63
92
|
private columnRules;
|
|
64
93
|
/**
|
|
@@ -69,6 +98,13 @@ export declare class HelixHeadlessTableRow extends HelixElement {
|
|
|
69
98
|
*/
|
|
70
99
|
alignCells(rules: CSSStyleSheet): void;
|
|
71
100
|
protected willUpdate(changed: PropertyValues): void;
|
|
101
|
+
connectedCallback(): void;
|
|
102
|
+
disconnectedCallback(): void;
|
|
103
|
+
/**
|
|
104
|
+
* A press on the row follows `href`, unless it landed on a link or control
|
|
105
|
+
* of the row's own, or ended a drag that selected text.
|
|
106
|
+
*/
|
|
107
|
+
private readonly handleClick;
|
|
72
108
|
/**
|
|
73
109
|
* Asks each cell to read its role again once the cells change.
|
|
74
110
|
*
|
|
@@ -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, hostAria } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, followLink, HelixElement, hostAria, pressedOwnControl, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
@@ -13,11 +13,31 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
|
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
15
|
this.isTableRow = true;
|
|
16
|
+
this.href = '';
|
|
17
|
+
this.rel = '';
|
|
18
|
+
this.target = '';
|
|
16
19
|
this.value = '';
|
|
17
20
|
this.selectable = false;
|
|
18
21
|
this.selected = false;
|
|
19
22
|
this.selectLabel = '';
|
|
23
|
+
this.gridCell = false;
|
|
24
|
+
this.selectStop = false;
|
|
20
25
|
this.columnRules = undefined;
|
|
26
|
+
this.handleClick = (event) => {
|
|
27
|
+
if (this.href === '' || event.button !== 0 || event.defaultPrevented) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const cell = event
|
|
31
|
+
.composedPath()
|
|
32
|
+
.find((node) => node instanceof Element && node.parentElement === this && 'isTableCell' in node);
|
|
33
|
+
if (pressedOwnControl(event, cell ?? this)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (globalThis.getSelection?.()?.toString()) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
followLink(this.ownerDocument, { href: this.href, rel: this.rel, target: this.target }, event);
|
|
40
|
+
};
|
|
21
41
|
this.handleSlotChange = () => {
|
|
22
42
|
for (const cell of this.children) {
|
|
23
43
|
if ('isTableCell' in cell) {
|
|
@@ -41,15 +61,30 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
|
|
|
41
61
|
willUpdate(changed) {
|
|
42
62
|
super.willUpdate(changed);
|
|
43
63
|
hostAria(this.internals, { role: 'row' });
|
|
64
|
+
this.internals.ariaSelected = this.gridCell && this.selectable ? String(this.selected) : null;
|
|
44
65
|
this.toggleState('selected', this.selectable && this.selected);
|
|
66
|
+
this.toggleState('link', this.href !== '');
|
|
67
|
+
}
|
|
68
|
+
connectedCallback() {
|
|
69
|
+
super.connectedCallback();
|
|
70
|
+
this.addEventListener('click', this.handleClick);
|
|
71
|
+
}
|
|
72
|
+
disconnectedCallback() {
|
|
73
|
+
super.disconnectedCallback();
|
|
74
|
+
this.removeEventListener('click', this.handleClick);
|
|
45
75
|
}
|
|
46
76
|
renderSelect() {
|
|
47
77
|
if (!this.selectable) {
|
|
48
78
|
return nothing;
|
|
49
79
|
}
|
|
50
80
|
const checkbox = this.tag('checkbox');
|
|
51
|
-
|
|
81
|
+
const grid = this.gridCell;
|
|
82
|
+
return html `<span
|
|
83
|
+
part="select${this.selected ? ' select-selected' : ''}"
|
|
84
|
+
role=${grid ? 'gridcell' : 'cell'}
|
|
85
|
+
tabindex=${grid ? (this.selectStop ? '0' : '-1') : nothing}
|
|
52
86
|
><${checkbox}
|
|
87
|
+
tabindex=${grid ? '-1' : nothing}
|
|
53
88
|
part="checkbox"
|
|
54
89
|
exportparts="box: checkbox-box, control: checkbox-control, feedback: checkbox-feedback,
|
|
55
90
|
field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark,
|
|
@@ -64,6 +99,15 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
|
|
|
64
99
|
return html `${this.renderSelect()}<slot @slotchange=${this.handleSlotChange}></slot>`;
|
|
65
100
|
}
|
|
66
101
|
};
|
|
102
|
+
__decorate([
|
|
103
|
+
property()
|
|
104
|
+
], HelixHeadlessTableRow.prototype, "href", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
property()
|
|
107
|
+
], HelixHeadlessTableRow.prototype, "rel", void 0);
|
|
108
|
+
__decorate([
|
|
109
|
+
property()
|
|
110
|
+
], HelixHeadlessTableRow.prototype, "target", void 0);
|
|
67
111
|
__decorate([
|
|
68
112
|
property()
|
|
69
113
|
], HelixHeadlessTableRow.prototype, "value", void 0);
|
|
@@ -76,6 +120,12 @@ __decorate([
|
|
|
76
120
|
__decorate([
|
|
77
121
|
state()
|
|
78
122
|
], HelixHeadlessTableRow.prototype, "selectLabel", void 0);
|
|
123
|
+
__decorate([
|
|
124
|
+
state()
|
|
125
|
+
], HelixHeadlessTableRow.prototype, "gridCell", void 0);
|
|
126
|
+
__decorate([
|
|
127
|
+
state()
|
|
128
|
+
], HelixHeadlessTableRow.prototype, "selectStop", void 0);
|
|
79
129
|
HelixHeadlessTableRow = __decorate([
|
|
80
130
|
customElement('helix-headless-table-row')
|
|
81
131
|
], HelixHeadlessTableRow);
|
|
@@ -21,9 +21,11 @@ declare const HelixHeadlessTabs_base: (new (...args: any[]) => import("@fusion.d
|
|
|
21
21
|
* between tabs either way.
|
|
22
22
|
*
|
|
23
23
|
* A tab with an `href` is a link, for tabs that are pages of a site. Pressing
|
|
24
|
-
* it follows the link,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* it follows the link. Where any tab is a link, the arrow keys move focus
|
|
25
|
+
* without choosing on every tab of the list, as under `manual`, so arrowing
|
|
26
|
+
* past a tab never leaves the page and the list answers the keys one way.
|
|
27
|
+
* Mark the tab of the page you are on with `selected`, or set `active` to its
|
|
28
|
+
* value.
|
|
27
29
|
*
|
|
28
30
|
* Each tab says which panel it controls through `aria-controls`, set as an
|
|
29
31
|
* element reference to the panel's host, where the engine has reflection.
|
|
@@ -22,12 +22,14 @@ export type TagSelectionMode = SelectionMode;
|
|
|
22
22
|
* that is removed leaves `value`, which then sends `change`.
|
|
23
23
|
*
|
|
24
24
|
* Name the set with `label`. Each tag is named by its words alone, without
|
|
25
|
-
* its remove button.
|
|
25
|
+
* its remove button. `value` takes an array of values on the property as
|
|
26
|
+
* well, as React sets `value={['Apple']}`; a press writes it back as a
|
|
27
|
+
* string.
|
|
26
28
|
*
|
|
27
29
|
* **Removing the last tag keeps focus in the group.** With no tags left the
|
|
28
30
|
* set is a `group`, and focus moves to its `empty` part,
|
|
29
31
|
* which holds the `empty` slot: put words there such as "No filters" for a
|
|
30
|
-
* reader to hear.
|
|
32
|
+
* reader to hear. With nothing slotted it says `empty-label`, "No tags".
|
|
31
33
|
*
|
|
32
34
|
* @since 0.1.0
|
|
33
35
|
* @status stable
|
|
@@ -35,7 +37,7 @@ export type TagSelectionMode = SelectionMode;
|
|
|
35
37
|
* @documentation https://fusion.dev/helix/components/tag
|
|
36
38
|
*
|
|
37
39
|
* @slot - The tags, in the order they are read.
|
|
38
|
-
* @slot empty - Shown in place of the tags while there are none, such as "No filters".
|
|
40
|
+
* @slot empty - Shown in place of the tags while there are none, such as "No filters". Its fallback is `empty-label`.
|
|
39
41
|
*
|
|
40
42
|
* @event {Event} change - Fired once a press has changed which tags are selected.
|
|
41
43
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a press changes which tags are selected, with the `value` it would leave. Cancelable.
|
|
@@ -44,6 +46,11 @@ export type TagSelectionMode = SelectionMode;
|
|
|
44
46
|
* @csspart empty - Holds the `empty` slot while the group has no tags, rendered only then. Takes focus when the last tag is removed.
|
|
45
47
|
*/
|
|
46
48
|
export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
49
|
+
/**
|
|
50
|
+
* The words the group shows and says once its last tag is removed, where
|
|
51
|
+
* nothing is in the `empty` slot.
|
|
52
|
+
*/
|
|
53
|
+
emptyLabel: string;
|
|
47
54
|
/**
|
|
48
55
|
* The name of the set, such as "Filters", which a screen reader announces
|
|
49
56
|
* before its tags.
|
|
@@ -62,7 +69,7 @@ export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
|
62
69
|
* Set it to start with tags selected. A tag's value is its `value`, or its
|
|
63
70
|
* words where it has none.
|
|
64
71
|
*/
|
|
65
|
-
value: string;
|
|
72
|
+
value: string | readonly string[];
|
|
66
73
|
/** The tag the reader was last on, which keeps the tab stop. */
|
|
67
74
|
private last;
|
|
68
75
|
/**
|
|
@@ -72,6 +79,11 @@ export declare class HelixHeadlessTagGroup extends HelixElement {
|
|
|
72
79
|
* a list of tags has a first and a last.
|
|
73
80
|
*/
|
|
74
81
|
protected readonly keys: KeyboardNavigationController;
|
|
82
|
+
/**
|
|
83
|
+
* `value` as one written list, separated by commas, however it was set:
|
|
84
|
+
* an array of values is joined.
|
|
85
|
+
*/
|
|
86
|
+
private get written();
|
|
75
87
|
/** The tags the group holds, in order. */
|
|
76
88
|
get tags(): HelixHeadlessTag[];
|
|
77
89
|
/** The tags a key can land on, which are the ones that are not disabled. */
|
|
@@ -4,20 +4,21 @@ 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 { commaList, customElement, deepActiveElement, deepContains,
|
|
7
|
+
import { commaList, customElement, deepActiveElement, deepContains, focusItemOf, HelixElement, hostAria, KeyboardNavigationController, pressedValue, prunedValue, requestValue, rovingStop, slottedWords, typeaheadByWords, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessTag } from '../root/tag-root.js';
|
|
11
11
|
let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
|
+
this.emptyLabel = 'No tags';
|
|
14
15
|
this.label = '';
|
|
15
16
|
this.value = '';
|
|
16
17
|
this.keys = new KeyboardNavigationController(this, {
|
|
17
18
|
items: () => this.reachable.map((tag) => this.navigable(tag)),
|
|
18
19
|
origin: 'focus',
|
|
19
20
|
selects: () => false,
|
|
20
|
-
typeahead:
|
|
21
|
+
typeahead: typeaheadByWords(),
|
|
21
22
|
wrap: false,
|
|
22
23
|
});
|
|
23
24
|
this.handleKeydown = (event) => {
|
|
@@ -63,8 +64,8 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
66
|
const left = this.tags.map((one) => this.valueFor(one));
|
|
66
|
-
const pruned = prunedValue(this.
|
|
67
|
-
if (pruned !== this.
|
|
67
|
+
const pruned = prunedValue(this.written, this.valueFor(tag), left);
|
|
68
|
+
if (pruned !== this.written) {
|
|
68
69
|
this.value = pruned;
|
|
69
70
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
70
71
|
}
|
|
@@ -91,6 +92,14 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
91
92
|
}
|
|
92
93
|
};
|
|
93
94
|
}
|
|
95
|
+
get written() {
|
|
96
|
+
return typeof this.value === 'string'
|
|
97
|
+
? this.value
|
|
98
|
+
: this.value
|
|
99
|
+
.map((one) => String(one).trim())
|
|
100
|
+
.filter((one) => one !== '')
|
|
101
|
+
.join(', ');
|
|
102
|
+
}
|
|
94
103
|
get tags() {
|
|
95
104
|
return [...(this.children ?? [])].filter((child) => child instanceof HelixHeadlessTag);
|
|
96
105
|
}
|
|
@@ -98,21 +107,18 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
98
107
|
return this.tags.filter((tag) => !tag.disabled);
|
|
99
108
|
}
|
|
100
109
|
navigable(tag) {
|
|
101
|
-
return {
|
|
102
|
-
contains: (node) => tag.contains(node),
|
|
110
|
+
return focusItemOf(tag, {
|
|
103
111
|
disabled: tag.disabled,
|
|
104
|
-
|
|
105
|
-
select: () => { },
|
|
106
|
-
selected: false,
|
|
112
|
+
focus: () => tag.focusItem(),
|
|
107
113
|
words: tag.words,
|
|
108
|
-
};
|
|
114
|
+
});
|
|
109
115
|
}
|
|
110
116
|
valueFor(tag) {
|
|
111
117
|
return tag.value || slottedWords(tag, ['start', '']);
|
|
112
118
|
}
|
|
113
119
|
sync() {
|
|
114
120
|
const mode = this.selectionMode ?? 'none';
|
|
115
|
-
const chosen = new Set(commaList(this.
|
|
121
|
+
const chosen = new Set(commaList(this.written));
|
|
116
122
|
const tags = this.tags;
|
|
117
123
|
const items = tags.map((tag) => ({
|
|
118
124
|
disabled: tag.disabled,
|
|
@@ -137,14 +143,8 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
137
143
|
if (mode === 'none' || tag.disabled) {
|
|
138
144
|
return;
|
|
139
145
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.value = value;
|
|
143
|
-
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
144
|
-
},
|
|
145
|
-
event: (value) => new HelixBeforeChangeEvent({ value }),
|
|
146
|
-
host: this,
|
|
147
|
-
next: pressedValue(mode, this.value, this.valueFor(tag)),
|
|
146
|
+
requestValue(this, pressedValue(mode, this.written, this.valueFor(tag)), (value) => {
|
|
147
|
+
this.value = value;
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
connectedCallback() {
|
|
@@ -176,11 +176,14 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
|
|
|
176
176
|
}
|
|
177
177
|
render() {
|
|
178
178
|
const empty = this.empty
|
|
179
|
-
? html `<div part="empty" tabindex="-1"><slot name="empty"
|
|
179
|
+
? html `<div part="empty" tabindex="-1"><slot name="empty">${this.emptyLabel}</slot></div>`
|
|
180
180
|
: nothing;
|
|
181
181
|
return html `<slot @slotchange=${this.handleSlotchange}></slot>${empty}`;
|
|
182
182
|
}
|
|
183
183
|
};
|
|
184
|
+
__decorate([
|
|
185
|
+
property({ attribute: 'empty-label' })
|
|
186
|
+
], HelixHeadlessTagGroup.prototype, "emptyLabel", void 0);
|
|
184
187
|
__decorate([
|
|
185
188
|
property()
|
|
186
189
|
], HelixHeadlessTagGroup.prototype, "label", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, type OwnRule } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
@@ -22,12 +22,22 @@ declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusi
|
|
|
22
22
|
* every change once the browser finds nothing wrong, as React Aria's
|
|
23
23
|
* TextField `validate` does.
|
|
24
24
|
*
|
|
25
|
+
* **Keyboard.** The field's own keys are the platform's, and Enter starts a
|
|
26
|
+
* new line. The clear button under `clearable` is a tab stop of its own after
|
|
27
|
+
* the field.
|
|
28
|
+
*
|
|
29
|
+
* The inner textarea is named by `label`, or by a host `aria-label`,
|
|
30
|
+
* `aria-labelledby` or `<label for>`, and is described by the hint and the
|
|
31
|
+
* message, with `aria-invalid` while a message shows. The clear button is
|
|
32
|
+
* named `clear-label`.
|
|
33
|
+
*
|
|
25
34
|
* @since 0.1.0
|
|
26
35
|
* @status stable
|
|
27
36
|
* @category forms
|
|
28
37
|
* @aliases Multiline, TextArea
|
|
29
38
|
* @documentation https://fusion.dev/helix/components/textarea
|
|
30
39
|
*
|
|
40
|
+
* @slot clear-icon - Replaces the cross on the clear button, under `clearable`.
|
|
31
41
|
* @slot end - After the text, for an icon or an action beside it.
|
|
32
42
|
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
33
43
|
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
@@ -238,12 +248,14 @@ export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
|
|
|
238
248
|
* nothing wrong. Return a message, or a list of them, to mark the field
|
|
239
249
|
* invalid, and `true`, `null`, or nothing to accept the value.
|
|
240
250
|
*/
|
|
241
|
-
validate?:
|
|
251
|
+
validate?: OwnRule;
|
|
242
252
|
/**
|
|
243
253
|
* How the browser wraps the text, and whether the breaks are submitted with
|
|
244
254
|
* it.
|
|
245
255
|
*/
|
|
246
256
|
wrap: 'hard' | 'off' | 'soft';
|
|
257
|
+
/** The cross on the clear button, behind a seam a tier can move. */
|
|
258
|
+
protected renderClearIcon(): TemplateResult;
|
|
247
259
|
protected render(): TemplateResult;
|
|
248
260
|
}
|
|
249
261
|
declare global {
|