@fusion.dev/helix-headless 0.145.0 → 0.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +12286 -4281
- package/dist/accordion/item/accordion-item.d.ts +51 -18
- package/dist/accordion/item/accordion-item.js +45 -13
- package/dist/accordion/root/accordion-root.d.ts +16 -7
- package/dist/accordion/root/accordion-root.js +3 -3
- package/dist/announcement/root/announcement-root.d.ts +16 -6
- package/dist/announcement/root/announcement-root.js +37 -7
- package/dist/app-header/root/app-header-root.d.ts +7 -2
- package/dist/app-header/root/app-header-root.js +9 -1
- package/dist/app-header/sectioning.d.ts +3 -1
- package/dist/app-header/sectioning.js +3 -2
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +11 -3
- package/dist/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/root/badge-root.d.ts +60 -7
- package/dist/badge/root/badge-root.js +89 -6
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +48 -20
- package/dist/bar-chart/stack.d.ts +25 -0
- package/dist/bar-chart/stack.js +27 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +51 -4
- package/dist/button/root/button-root.d.ts +50 -38
- package/dist/button/root/button-root.js +42 -53
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/root/button-group-root.d.ts +2 -1
- package/dist/button-group/root/button-group-root.js +5 -1
- package/dist/canvas/node/canvas-node.d.ts +4 -3
- package/dist/canvas/node/canvas-node.js +3 -2
- package/dist/canvas/root/canvas-root.js +2 -2
- package/dist/card/root/card-root.d.ts +36 -4
- package/dist/card/root/card-root.js +29 -10
- package/dist/carousel/root/carousel-root.d.ts +43 -4
- package/dist/carousel/root/carousel-root.js +40 -12
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- package/dist/chat/message/chat-message.js +5 -4
- package/dist/chat/naming.d.ts +5 -1
- package/dist/chat/naming.js +4 -2
- package/dist/chat/root/chat-root.d.ts +40 -4
- package/dist/chat/root/chat-root.js +32 -6
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +18 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +14 -11
- package/dist/checkbox-group/select-all.d.ts +21 -0
- package/dist/checkbox-group/select-all.js +7 -0
- package/dist/code-block/highlight.d.ts +15 -0
- package/dist/code-block/highlight.js +4 -0
- package/dist/code-block/root/code-block-root.d.ts +79 -10
- package/dist/code-block/root/code-block-root.js +74 -5
- package/dist/color-input/root/color-input-root.d.ts +14 -0
- package/dist/color-input/root/color-input-root.js +17 -7
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +53 -16
- package/dist/color-picker/root/color-picker-root.js +155 -46
- package/dist/color-picker/wheel.d.ts +17 -0
- package/dist/color-picker/wheel.js +6 -0
- package/dist/combobox/root/combobox-root.d.ts +56 -0
- package/dist/combobox/root/combobox-root.js +92 -15
- package/dist/command/root/command-root.d.ts +19 -2
- package/dist/command/root/command-root.js +24 -23
- package/dist/copy-button/root/copy-button-root.d.ts +21 -1
- package/dist/copy-button/root/copy-button-root.js +16 -4
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +6 -0
- package/dist/data-table/keys.js +14 -0
- package/dist/data-table/root/data-table-root.d.ts +27 -18
- package/dist/data-table/root/data-table-root.js +31 -57
- package/dist/data-table/tree.d.ts +16 -1
- package/dist/data-table/tree.js +2 -3
- package/dist/date-input/root/date-input-root.d.ts +11 -2
- package/dist/date-input/root/date-input-root.js +26 -12
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +33 -22
- package/dist/description-list/item/description-list-item.d.ts +18 -4
- package/dist/description-list/item/description-list-item.js +8 -4
- package/dist/dialog/description.js +15 -1
- package/dist/dialog/root/dialog-root.d.ts +8 -2
- package/dist/dialog/root/dialog-root.js +16 -1
- package/dist/divider/root/divider-root.d.ts +3 -0
- package/dist/divider/root/divider-root.js +2 -1
- package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
- package/dist/donut-chart/root/donut-chart-root.js +55 -1
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +75 -4
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +40 -5
- package/dist/drilldown/root/drilldown-root.d.ts +21 -3
- package/dist/drilldown/root/drilldown-root.js +22 -3
- package/dist/element-events.generated.js +35 -6
- package/dist/empty/root/empty-root.d.ts +34 -2
- package/dist/empty/root/empty-root.js +26 -4
- package/dist/file-input/root/file-input-root.d.ts +99 -8
- package/dist/file-input/root/file-input-root.js +120 -22
- package/dist/file-input/screen.d.ts +2 -1
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +10 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +11 -2
- package/dist/filter-input/menu/filter-menu.d.ts +2 -0
- package/dist/filter-input/menu/filter-menu.js +12 -4
- package/dist/filter-input/root/filter-input-root.d.ts +38 -6
- package/dist/filter-input/root/filter-input-root.js +18 -28
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/options.d.ts +3 -4
- package/dist/format-date/options.js +2 -2
- package/dist/format-date/root/format-date-root.d.ts +27 -17
- package/dist/format-date/root/format-date-root.js +27 -48
- 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 +83 -11
- package/dist/heatmap/root/heatmap-root.js +104 -12
- 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 +25 -1
- package/dist/icon/root/icon-root.js +44 -12
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/icon/settle.d.ts +7 -0
- package/dist/icon/settle.js +10 -0
- package/dist/icon-button/root/icon-button-root.d.ts +2 -0
- package/dist/image/root/image-root.d.ts +14 -1
- package/dist/image/root/image-root.js +7 -2
- package/dist/input/root/input-root.d.ts +34 -3
- package/dist/input/root/input-root.js +17 -4
- package/dist/kbd/keys.d.ts +29 -0
- package/dist/kbd/keys.js +52 -0
- package/dist/kbd/root/kbd-root.d.ts +52 -1
- package/dist/kbd/root/kbd-root.js +40 -47
- 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 +77 -12
- package/dist/legend/root/legend-root.js +71 -17
- package/dist/lightbox/root/lightbox-root.d.ts +98 -10
- package/dist/lightbox/root/lightbox-root.js +153 -18
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +24 -0
- package/dist/lightbox/zoom.js +18 -0
- package/dist/line-chart/root/line-chart-root.d.ts +38 -1
- package/dist/line-chart/root/line-chart-root.js +31 -3
- package/dist/list/item/list-item.d.ts +2 -0
- package/dist/list/item/list-item.js +11 -2
- package/dist/list/root/list-root.d.ts +70 -13
- package/dist/list/root/list-root.js +91 -13
- package/dist/list/selection.d.ts +54 -7
- package/dist/list/selection.js +32 -7
- package/dist/listbox/root/listbox-root.d.ts +44 -4
- package/dist/listbox/root/listbox-root.js +72 -34
- package/dist/loader/busy.d.ts +10 -0
- package/dist/loader/busy.js +11 -0
- package/dist/loader/root/loader-root.d.ts +9 -2
- package/dist/loader/root/loader-root.js +23 -3
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +80 -15
- package/dist/megamenu/root/megamenu-root.js +76 -19
- package/dist/menu/item/menu-item.d.ts +51 -2
- package/dist/menu/item/menu-item.js +50 -26
- package/dist/menu/root/menu-root.d.ts +17 -0
- package/dist/menu/root/menu-root.js +2 -2
- package/dist/meter/root/meter-root.d.ts +62 -1
- package/dist/meter/root/meter-root.js +38 -16
- package/dist/navigation/root/navigation-root.d.ts +2 -1
- package/dist/navigation/root/navigation-root.js +2 -2
- package/dist/notifications/root/notifications-root.d.ts +20 -4
- package/dist/notifications/root/notifications-root.js +30 -8
- 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 +34 -9
- package/dist/number-input/root/number-input-root.js +31 -25
- package/dist/object-inspector/root/object-inspector-root.d.ts +88 -33
- package/dist/object-inspector/root/object-inspector-root.js +134 -92
- package/dist/object-inspector/rows.d.ts +18 -0
- package/dist/object-inspector/rows.js +33 -0
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/root/option-root.d.ts +5 -3
- 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 +30 -0
- package/dist/outline/root/outline-root.js +17 -13
- 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 +37 -0
- package/dist/pin-input/code.js +25 -0
- package/dist/pin-input/root/pin-input-root.d.ts +116 -115
- package/dist/pin-input/root/pin-input-root.js +163 -155
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +34 -0
- package/dist/popover/root/popover-root.d.ts +64 -8
- package/dist/popover/root/popover-root.js +67 -4
- package/dist/progress/root/progress-root.d.ts +47 -0
- package/dist/progress/root/progress-root.js +34 -16
- package/dist/qr-code/export.d.ts +45 -1
- package/dist/qr-code/export.js +28 -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 +36 -11
- package/dist/qr-code/root/qr-code-root.js +58 -11
- package/dist/quote/marks.d.ts +8 -0
- package/dist/quote/marks.js +5 -0
- package/dist/quote/root/quote-root.d.ts +14 -2
- package/dist/quote/root/quote-root.js +23 -1
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +7 -2
- package/dist/rating/root/rating-root.d.ts +30 -12
- package/dist/rating/root/rating-root.js +27 -27
- package/dist/scatter-chart/fit.d.ts +15 -0
- package/dist/scatter-chart/fit.js +35 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +51 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +64 -24
- package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
- package/dist/scroll-area/root/scroll-area-root.js +57 -173
- package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
- package/dist/scroll-area/scrollbar-controller.js +172 -0
- package/dist/scroll-area/scrollbar.d.ts +27 -8
- package/dist/scroll-area/scrollbar.js +10 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +71 -0
- package/dist/select/root/select-root.js +78 -6
- package/dist/skeleton/root/skeleton-root.d.ts +3 -0
- package/dist/skeleton/root/skeleton-root.js +4 -2
- package/dist/skip-link/root/skip-link-root.js +2 -2
- package/dist/slider/root/slider-root.d.ts +59 -5
- package/dist/slider/root/slider-root.js +45 -3
- package/dist/sparkline/readings.d.ts +36 -0
- package/dist/sparkline/readings.js +36 -0
- package/dist/sparkline/root/sparkline-root.d.ts +121 -7
- package/dist/sparkline/root/sparkline-root.js +160 -26
- package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
- package/dist/speed-dial/item/speed-dial-item.js +2 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
- package/dist/speed-dial/root/speed-dial-root.js +11 -3
- package/dist/splitter/root/splitter-root.d.ts +10 -12
- package/dist/splitter/root/splitter-root.js +211 -204
- package/dist/stat/root/stat-root.d.ts +14 -5
- package/dist/stat/root/stat-root.js +21 -5
- package/dist/steps/reach.d.ts +5 -0
- package/dist/steps/reach.js +3 -0
- package/dist/steps/root/steps-root.d.ts +56 -3
- package/dist/steps/root/steps-root.js +50 -6
- package/dist/steps/step/step.d.ts +8 -0
- package/dist/steps/step/step.js +8 -3
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +6 -10
- package/dist/table/column/table-column.js +8 -20
- package/dist/table/root/table-root.d.ts +31 -10
- package/dist/table/root/table-root.js +14 -18
- package/dist/table/row/table-row.d.ts +24 -0
- package/dist/table/row/table-row.js +37 -1
- package/dist/tabs/panel/tab-panel.d.ts +16 -3
- package/dist/tabs/panel/tab-panel.js +34 -5
- package/dist/tabs/root/tabs-root.d.ts +17 -3
- package/dist/tabs/root/tabs-root.js +1 -1
- package/dist/tabs/tab/tab.d.ts +5 -0
- package/dist/tabs/tab/tab.js +5 -2
- package/dist/tag/group/tag-group.d.ts +44 -5
- package/dist/tag/group/tag-group.js +60 -9
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +41 -2
- package/dist/textarea/root/textarea-root.js +39 -1
- package/dist/time-input/root/time-input-root.d.ts +10 -2
- package/dist/time-input/root/time-input-root.js +24 -13
- package/dist/time-picker/root/time-picker-root.d.ts +28 -17
- package/dist/time-picker/root/time-picker-root.js +18 -29
- package/dist/time-picker/wheel-name.d.ts +9 -0
- package/dist/time-picker/wheel-name.js +15 -0
- package/dist/timeline/group/timeline-group.js +2 -2
- package/dist/toast/item/toast-item.d.ts +16 -3
- package/dist/toast/item/toast-item.js +22 -6
- package/dist/toast/root/toast-root.d.ts +34 -4
- package/dist/toast/root/toast-root.js +74 -13
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +52 -7
- package/dist/toggle/group/toggle-group.js +58 -44
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +21 -5
- package/dist/toolbar/root/toolbar-root.js +52 -8
- package/dist/tooltip/root/tooltip-root.d.ts +20 -3
- package/dist/tooltip/root/tooltip-root.js +18 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +45 -2
- package/dist/tour/root/tour-root.js +53 -8
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/item/tree-item.d.ts +7 -3
- package/dist/tree/item/tree-item.js +3 -0
- package/dist/tree/root/tree-root.d.ts +24 -3
- package/dist/tree/root/tree-root.js +32 -13
- package/dist/tree/selection.js +2 -15
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +83 -19
- package/dist/trend/root/trend-root.js +59 -8
- package/dist/video/media-events.d.ts +13 -18
- package/dist/video/media-events.js +1 -5
- 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 +23 -6
- package/dist/video/root/video-root.js +19 -10
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +17 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -8
- package/dist/virtual-list/fill.js +10 -17
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +65 -0
- package/dist/virtual-list/plan.js +27 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +136 -13
- package/dist/virtual-list/root/virtual-list-root.js +218 -51
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +7441 -1458
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1501 -326
- package/dist/chat/relative-clock.d.ts +0 -39
- package/dist/chat/relative-clock.js +0 -31
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -9,6 +9,7 @@ import { caretLeft, caretRight, play, stop } from '@fusion.dev/helix-icons';
|
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
|
+
import { stepStop, stopFor, stopsOf } from '../stops.js';
|
|
12
13
|
const COUNT_OR_AUTO = {
|
|
13
14
|
fromAttribute: (value) => {
|
|
14
15
|
if (value === null) {
|
|
@@ -59,7 +60,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
59
60
|
? -1
|
|
60
61
|
: 0
|
|
61
62
|
: inlineStep(this, event.key);
|
|
62
|
-
let to
|
|
63
|
+
let to;
|
|
63
64
|
if (event.key === 'Home') {
|
|
64
65
|
to = 0;
|
|
65
66
|
}
|
|
@@ -69,6 +70,9 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
69
70
|
else if (step === 0) {
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
73
|
+
else {
|
|
74
|
+
to = this.move(step);
|
|
75
|
+
}
|
|
72
76
|
event.preventDefault();
|
|
73
77
|
this.goTo(to);
|
|
74
78
|
this.updateComplete.then(() => {
|
|
@@ -213,6 +217,9 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
213
217
|
get positions() {
|
|
214
218
|
return Math.max(1, this.slides.length - (this.across ?? 1) + 1);
|
|
215
219
|
}
|
|
220
|
+
get stops() {
|
|
221
|
+
return stopsOf(this.positions, this.slidesPerMove);
|
|
222
|
+
}
|
|
216
223
|
measure() {
|
|
217
224
|
const track = this.partNamed('track');
|
|
218
225
|
const pane = this.panes[0]?.getBoundingClientRect().width;
|
|
@@ -281,6 +288,9 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
281
288
|
this.requestUpdate('index', previous);
|
|
282
289
|
this.dispatchEvent(new HelixActivateEvent({ value: String(value) }));
|
|
283
290
|
}
|
|
291
|
+
move(step) {
|
|
292
|
+
return stepStop(this.stops, this.index, step < 0 ? -1 : 1, this.loop);
|
|
293
|
+
}
|
|
284
294
|
goTo(index) {
|
|
285
295
|
if (this.slides.length === 0) {
|
|
286
296
|
return;
|
|
@@ -357,7 +367,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
357
367
|
if (!this.rotating || this.slides.length < 2) {
|
|
358
368
|
return;
|
|
359
369
|
}
|
|
360
|
-
this.timer = setInterval(() => this.goTo(this.index >= this.positions - 1 ? 0 : this.
|
|
370
|
+
this.timer = setInterval(() => this.goTo(this.index >= this.positions - 1 ? 0 : this.move(1)), this.interval);
|
|
361
371
|
}
|
|
362
372
|
nearest() {
|
|
363
373
|
const track = this.partNamed('track');
|
|
@@ -366,8 +376,11 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
366
376
|
}
|
|
367
377
|
const bleed = this.bleed(track);
|
|
368
378
|
const at = this.orientation === 'vertical' ? track.scrollTop : track.scrollLeft;
|
|
369
|
-
return this.
|
|
370
|
-
const
|
|
379
|
+
return this.stops.reduce((best, index) => {
|
|
380
|
+
const slide = this.panes[index];
|
|
381
|
+
const distance = slide
|
|
382
|
+
? Math.abs(this.edgeOf(slide, track, bleed) - at)
|
|
383
|
+
: Number.POSITIVE_INFINITY;
|
|
371
384
|
return distance < best.distance ? { distance, index } : best;
|
|
372
385
|
}, { distance: Number.POSITIVE_INFINITY, index: this.index }).index;
|
|
373
386
|
}
|
|
@@ -484,9 +497,21 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
484
497
|
</svg></slot
|
|
485
498
|
>`;
|
|
486
499
|
}
|
|
500
|
+
paneStyle(index, last, stops) {
|
|
501
|
+
const declared = [
|
|
502
|
+
index === last ? this.runEnd() : nothing,
|
|
503
|
+
(this.slidesPerMove ?? 1) > 1 && !stops.includes(index)
|
|
504
|
+
? 'scroll-snap-align: none !important'
|
|
505
|
+
: nothing,
|
|
506
|
+
].filter((one) => one !== nothing);
|
|
507
|
+
return declared.length > 0 ? declared.join('; ') : nothing;
|
|
508
|
+
}
|
|
487
509
|
render() {
|
|
488
510
|
const rotating = this.rotating;
|
|
489
511
|
const last = this.slides.length - 1;
|
|
512
|
+
const stops = this.stops;
|
|
513
|
+
const place = stopFor(stops, this.index);
|
|
514
|
+
const showing = stopFor(stops, this.showing ?? this.index);
|
|
490
515
|
return html `<div part="controls">
|
|
491
516
|
${this.autoplay
|
|
492
517
|
? html `<button
|
|
@@ -511,7 +536,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
511
536
|
type="button"
|
|
512
537
|
aria-label=${this.previousLabel}
|
|
513
538
|
aria-disabled=${this.atEnd('start') ? 'true' : nothing}
|
|
514
|
-
@click=${() => this.goTo(this.
|
|
539
|
+
@click=${() => this.goTo(this.move(-1))}
|
|
515
540
|
>
|
|
516
541
|
${this.renderPreviousMark()}
|
|
517
542
|
</button>
|
|
@@ -520,7 +545,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
520
545
|
type="button"
|
|
521
546
|
aria-label=${this.nextLabel}
|
|
522
547
|
aria-disabled=${this.atEnd('end') ? 'true' : nothing}
|
|
523
|
-
@click=${() => this.goTo(this.
|
|
548
|
+
@click=${() => this.goTo(this.move(1))}
|
|
524
549
|
>
|
|
525
550
|
${this.renderNextMark()}
|
|
526
551
|
</button>`}
|
|
@@ -545,7 +570,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
545
570
|
role="group"
|
|
546
571
|
aria-roledescription=${this.slideRoleLabel || nothing}
|
|
547
572
|
aria-label=${fillTemplate(this.slideLabel, { count: this.slides.length, index: index + 1 })}
|
|
548
|
-
style=${index
|
|
573
|
+
style=${this.paneStyle(index, last, stops)}
|
|
549
574
|
>
|
|
550
575
|
<slot
|
|
551
576
|
name=${this.assignsByName ? `slide-${index + 1}` : nothing}
|
|
@@ -557,17 +582,17 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
557
582
|
${this.slides.length > 1 && this.across !== undefined
|
|
558
583
|
? html `<div part="indicators" role="group" aria-label=${fillTemplate(this.indicatorsLabel, { label: this.label })}>
|
|
559
584
|
${''}
|
|
560
|
-
${
|
|
561
|
-
const current = at ===
|
|
585
|
+
${stops.map((stop, at) => {
|
|
586
|
+
const current = at === showing;
|
|
562
587
|
return html `<button
|
|
563
588
|
part="indicator${current ? ' indicator-current' : ''}"
|
|
564
589
|
type="button"
|
|
565
590
|
aria-label=${fillTemplate(this.indicatorLabel, { index: at + 1 })}
|
|
566
|
-
aria-current=${at ===
|
|
567
|
-
tabindex=${at ===
|
|
591
|
+
aria-current=${at === place ? 'true' : nothing}
|
|
592
|
+
tabindex=${at === place ? '0' : '-1'}
|
|
568
593
|
?data-current=${current}
|
|
569
594
|
@keydown=${this.handleIndicatorKeydown}
|
|
570
|
-
@click=${() => this.goTo(
|
|
595
|
+
@click=${() => this.goTo(stop)}
|
|
571
596
|
></button>`;
|
|
572
597
|
})}
|
|
573
598
|
</div>`
|
|
@@ -628,6 +653,9 @@ __decorate([
|
|
|
628
653
|
__decorate([
|
|
629
654
|
property({ attribute: 'slide-role-label' })
|
|
630
655
|
], HelixHeadlessCarousel.prototype, "slideRoleLabel", void 0);
|
|
656
|
+
__decorate([
|
|
657
|
+
property({ attribute: 'slides-per-move', type: Number })
|
|
658
|
+
], HelixHeadlessCarousel.prototype, "slidesPerMove", void 0);
|
|
631
659
|
__decorate([
|
|
632
660
|
property({ attribute: 'start-label' })
|
|
633
661
|
], HelixHeadlessCarousel.prototype, "startLabel", void 0);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a carousel's track stops when it moves several slides at a time, as
|
|
3
|
+
* arithmetic over its positions.
|
|
4
|
+
*
|
|
5
|
+
* A position is a slide the track can start at: six slides four across have
|
|
6
|
+
* three, 0, 1 and 2. Moving `perMove` slides at a time stops at every
|
|
7
|
+
* `perMove`th of them from the first, and always at the last, so the end of
|
|
8
|
+
* the run is reachable whatever the count.
|
|
9
|
+
*/
|
|
10
|
+
/** The positions the track stops at, in order: every `perMove`th from 0, and the last. */
|
|
11
|
+
export declare const stopsOf: (positions: number, perMove?: number) => number[];
|
|
12
|
+
/** Which stop a position is at or past: the last stop at or before it, as an index into `stops`. */
|
|
13
|
+
export declare const stopFor: (stops: readonly number[], position: number) => number;
|
|
14
|
+
/**
|
|
15
|
+
* The position a move of one stop forward (`1`) or back (`-1`) lands on.
|
|
16
|
+
*
|
|
17
|
+
* From a position between two stops, back goes to the stop before it. Past
|
|
18
|
+
* either end it wraps where `loop` says so, and stays at the end otherwise.
|
|
19
|
+
*/
|
|
20
|
+
export declare const stepStop: (stops: readonly number[], position: number, step: -1 | 1, loop: boolean) => number;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const stopsOf = (positions, perMove = 1) => {
|
|
2
|
+
const step = Number.isFinite(perMove) ? Math.max(1, Math.floor(perMove)) : 1;
|
|
3
|
+
const last = Math.max(0, positions - 1);
|
|
4
|
+
const stops = [];
|
|
5
|
+
for (let at = 0; at < last; at += step) {
|
|
6
|
+
stops.push(at);
|
|
7
|
+
}
|
|
8
|
+
stops.push(last);
|
|
9
|
+
return stops;
|
|
10
|
+
};
|
|
11
|
+
export const stopFor = (stops, position) => {
|
|
12
|
+
let found = 0;
|
|
13
|
+
stops.forEach((stop, at) => {
|
|
14
|
+
if (stop <= position) {
|
|
15
|
+
found = at;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return found;
|
|
19
|
+
};
|
|
20
|
+
export const stepStop = (stops, position, step, loop) => {
|
|
21
|
+
const at = stopFor(stops, position);
|
|
22
|
+
let next = step < 0 && stops[at] !== position ? at : at + step;
|
|
23
|
+
if (loop) {
|
|
24
|
+
next = (next + stops.length) % stops.length;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
next = Math.min(Math.max(next, 0), stops.length - 1);
|
|
28
|
+
}
|
|
29
|
+
return stops[next] ?? 0;
|
|
30
|
+
};
|
|
@@ -4,12 +4,11 @@ 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, HelixSendEvent, hostAria, markRegion, relativeTime, requestChange, TONE_MARKS, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, HelixSendEvent, hostAria, markRegion, RelativeClockController, relativeTime, requestChange, TONE_MARKS, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
11
11
|
import { authorWords, TURN_WORDS, turnName } from '../naming.js';
|
|
12
|
-
import { RelativeClockController } from '../relative-clock.js';
|
|
13
12
|
export const FAILED_LABEL = 'Not sent';
|
|
14
13
|
let HelixHeadlessChatMessage = class HelixHeadlessChatMessage extends HelixElement {
|
|
15
14
|
constructor() {
|
|
@@ -23,8 +22,10 @@ let HelixHeadlessChatMessage = class HelixHeadlessChatMessage extends HelixEleme
|
|
|
23
22
|
this.turnWords = TURN_WORDS;
|
|
24
23
|
this.isChatMessage = true;
|
|
25
24
|
this.clock = new RelativeClockController(this, {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
expires: (now) => {
|
|
26
|
+
const moment = this.moment;
|
|
27
|
+
return moment ? relativeTime(this.locale)(moment, now).next : undefined;
|
|
28
|
+
},
|
|
28
29
|
});
|
|
29
30
|
this.handleFill = () => {
|
|
30
31
|
this.markEmpty();
|
package/dist/chat/naming.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface TurnWords {
|
|
|
4
4
|
me: string;
|
|
5
5
|
/** The sentence for a turn with an author and a time, with `{author}` and `{time}`. */
|
|
6
6
|
sentence: string;
|
|
7
|
+
/** The name of a turn with neither an author a reader can be told nor a time. */
|
|
8
|
+
turn: string;
|
|
7
9
|
}
|
|
8
10
|
/** The words a chat says its turns with, where nobody said otherwise. */
|
|
9
11
|
export declare const TURN_WORDS: TurnWords;
|
|
@@ -17,6 +19,8 @@ export declare const TURN_WORDS: TurnWords;
|
|
|
17
19
|
export declare const authorWords: (author: string | undefined, authorLabel: string, words: TurnWords) => string;
|
|
18
20
|
/**
|
|
19
21
|
* The turn's accessible name: the sentence where it has an author and a time,
|
|
20
|
-
* and whichever of the two it has otherwise.
|
|
22
|
+
* and whichever of the two it has otherwise. Where it has neither, a turn by
|
|
23
|
+
* `them` with no `author-label` and no time, the chat's word for a turn, so
|
|
24
|
+
* no turn is an `article` with no name.
|
|
21
25
|
*/
|
|
22
26
|
export declare const turnName: (author: string, time: string, words: TurnWords) => string;
|
package/dist/chat/naming.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fillTemplate } from '@fusion.dev/helix-core';
|
|
2
|
-
export const TURN_WORDS = { me: 'You', sentence: '{author}, {time}' };
|
|
2
|
+
export const TURN_WORDS = { me: 'You', sentence: '{author}, {time}', turn: 'Message' };
|
|
3
3
|
export const authorWords = (author, authorLabel, words) => {
|
|
4
4
|
if (authorLabel !== '') {
|
|
5
5
|
return authorLabel;
|
|
@@ -9,4 +9,6 @@ export const authorWords = (author, authorLabel, words) => {
|
|
|
9
9
|
}
|
|
10
10
|
return author === undefined || author === 'them' ? '' : author;
|
|
11
11
|
};
|
|
12
|
-
export const turnName = (author, time, words) => author !== '' && time !== ''
|
|
12
|
+
export const turnName = (author, time, words) => author !== '' && time !== ''
|
|
13
|
+
? fillTemplate(words.sentence, { author, time })
|
|
14
|
+
: author || time || words.turn;
|
|
@@ -53,18 +53,25 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
|
|
|
53
53
|
* `sent` or `failed` when your server answers. Add the reply as a turn with
|
|
54
54
|
* `state="streaming"`, write its text as it arrives, and set `state` to `sent`
|
|
55
55
|
* when it is complete. While the user types, the composer sends
|
|
56
|
-
* `helix-typing`, which you can pass on to the other side.
|
|
57
|
-
*
|
|
56
|
+
* `helix-typing`, which you can pass on to the other side. When the other side
|
|
57
|
+
* types, set `typing` to their name: the status band draws three dots and
|
|
58
|
+
* "Ada is typing" (`typing-label`), which a screen reader hears, and clearing
|
|
59
|
+
* it takes them away. Anything slotted into `status` is drawn first.
|
|
58
60
|
*
|
|
59
61
|
* A screen reader names each turn by its author and its time, such as "You, 2
|
|
60
62
|
* minutes ago". Set `me-label` and `message-label` to say it in your language,
|
|
61
|
-
* and give each turn by `them` an `author-label`.
|
|
63
|
+
* and give each turn by `them` an `author-label`. A turn with neither an author
|
|
64
|
+
* label nor a time is named by `turn-label`, "Message".
|
|
62
65
|
*
|
|
63
66
|
* A turn from `turns` is drawn in the chat's shadow root, so style it through
|
|
64
67
|
* the forwarded `message-*` parts. A turn by `me` also gets each part with
|
|
65
68
|
* `-mine` added, and the turn's state adds `message-meta-failed`,
|
|
66
69
|
* `message-content-sending`, and `message-content-streaming`. To style each
|
|
67
|
-
* participant differently,
|
|
70
|
+
* participant differently, give `author-styles` the declarations for each
|
|
71
|
+
* author, such as `{"ada": "--chat-message-background-color: …"}`: the message
|
|
72
|
+
* drawn for each of their turns takes them as its `style`, so the message's
|
|
73
|
+
* custom properties change for that author alone. Turns passed as children are
|
|
74
|
+
* styled by their `author`, such as `helix-chat-message[author="ada"]`.
|
|
68
75
|
*
|
|
69
76
|
* @since 0.1.0
|
|
70
77
|
* @status stable
|
|
@@ -91,6 +98,7 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
|
|
|
91
98
|
* @csspart empty - Shown when the conversation has no turns.
|
|
92
99
|
* @csspart header - The region above the transcript.
|
|
93
100
|
* @csspart history - Shown at the top of the transcript while older turns load.
|
|
101
|
+
* @csspart indicator - The three dots before the words that say who is typing, which the styled tier animates as a message's are. Hidden from screen readers.
|
|
94
102
|
* @csspart live - The region where screen readers announce each turn once it has arrived.
|
|
95
103
|
* @csspart loading - Shown while the history loads.
|
|
96
104
|
* @csspart log - The transcript, which scrolls.
|
|
@@ -117,6 +125,7 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
|
|
|
117
125
|
* @csspart resume - The control shown while the user is scrolled away from the bottom.
|
|
118
126
|
* @csspart status - The status region, outside the log.
|
|
119
127
|
* @csspart turn - The wrapper around the message drawn for one turn from `turns`.
|
|
128
|
+
* @csspart typing - The words that say who is typing, in the status band, while `typing` names someone.
|
|
120
129
|
*/
|
|
121
130
|
export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
122
131
|
/**
|
|
@@ -131,6 +140,16 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
|
131
140
|
static shadowRootOptions: ShadowRootInit;
|
|
132
141
|
/** How tall a turn is assumed to be before it has been drawn, in pixels. */
|
|
133
142
|
static readonly ESTIMATE = 72;
|
|
143
|
+
/**
|
|
144
|
+
* Declarations for the turns from `turns` by each author, keyed by `author`,
|
|
145
|
+
* as JSON in the attribute: `{"ada": "--chat-message-background-color: …"}`.
|
|
146
|
+
*
|
|
147
|
+
* The message drawn for each turn by that author takes them as its `style`,
|
|
148
|
+
* so the custom properties a message reads, its fill, text color, radius and
|
|
149
|
+
* padding, change for that author alone. A turn by an author with no entry
|
|
150
|
+
* takes none, and looks as it did. JSON that does not parse is no entries.
|
|
151
|
+
*/
|
|
152
|
+
authorStyles: Record<string, string>;
|
|
134
153
|
/**
|
|
135
154
|
* Whether the transcript opens pinned to the bottom, when `pinned` is not
|
|
136
155
|
* set.
|
|
@@ -197,6 +216,11 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
|
197
216
|
* history.
|
|
198
217
|
*/
|
|
199
218
|
threshold: number;
|
|
219
|
+
/**
|
|
220
|
+
* The name a screen reader gives a turn with neither an author it can say
|
|
221
|
+
* nor a time: a turn by `them` with no `author-label`, say.
|
|
222
|
+
*/
|
|
223
|
+
turnLabel: string;
|
|
200
224
|
/**
|
|
201
225
|
* The turns as data, for a transcript too long to hold as elements.
|
|
202
226
|
*
|
|
@@ -208,6 +232,18 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
|
208
232
|
* element to look again.
|
|
209
233
|
*/
|
|
210
234
|
turns: readonly ChatTurn[];
|
|
235
|
+
/**
|
|
236
|
+
* Who on the other side is typing, by name, or empty while nobody is.
|
|
237
|
+
*
|
|
238
|
+
* Set it from your connection, and clear it when they stop or send. The
|
|
239
|
+
* status band says it with `typing-label`.
|
|
240
|
+
*/
|
|
241
|
+
typing: string;
|
|
242
|
+
/**
|
|
243
|
+
* What the status band says while someone is typing. `{author}` is the
|
|
244
|
+
* name in `typing`.
|
|
245
|
+
*/
|
|
246
|
+
typingLabel: string;
|
|
211
247
|
private pinnedState;
|
|
212
248
|
/** The last thing said, and how many times something has been. */
|
|
213
249
|
private announcement;
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessChat_1;
|
|
8
|
-
import { customElement, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { customElement, fillTemplate, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, wordsConverter, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { keyed } from 'lit/directives/keyed.js';
|
|
@@ -24,7 +24,11 @@ const SECOND_NAMES = {
|
|
|
24
24
|
streaming: 'content: message-content-streaming',
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
|
-
const
|
|
27
|
+
const ownEntry = (table, key) => (key !== undefined && Object.hasOwn(table, key) ? table[key] : undefined);
|
|
28
|
+
const secondNames = (table, key) => {
|
|
29
|
+
const names = ownEntry(table, key);
|
|
30
|
+
return names === undefined ? '' : `, ${names}`;
|
|
31
|
+
};
|
|
28
32
|
const settled = (turn) => turn.state !== 'sending' && turn.state !== 'streaming';
|
|
29
33
|
const newsworthy = (turn) => turn.author !== 'me' || turn.state === 'failed';
|
|
30
34
|
const spoken = (message) => [...message.childNodes]
|
|
@@ -36,6 +40,7 @@ const spoken = (message) => [...message.childNodes]
|
|
|
36
40
|
let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixElement) {
|
|
37
41
|
constructor() {
|
|
38
42
|
super(...arguments);
|
|
43
|
+
this.authorStyles = {};
|
|
39
44
|
this.defaultPinned = true;
|
|
40
45
|
this.history = '';
|
|
41
46
|
this.historyText = 'Loading earlier messages';
|
|
@@ -43,7 +48,10 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
43
48
|
this.meLabel = 'You';
|
|
44
49
|
this.messageLabel = '{author}, {time}';
|
|
45
50
|
this.threshold = 48;
|
|
51
|
+
this.turnLabel = 'Message';
|
|
46
52
|
this.turns = [];
|
|
53
|
+
this.typing = '';
|
|
54
|
+
this.typingLabel = '{author} is typing';
|
|
47
55
|
this.pinnedState = undefined;
|
|
48
56
|
this.announcement = '';
|
|
49
57
|
this.said = 0;
|
|
@@ -365,8 +373,8 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
365
373
|
willUpdate(changed) {
|
|
366
374
|
super.willUpdate(changed);
|
|
367
375
|
hostAria(this.internals, { label: this.label || 'Conversation', role: 'region' });
|
|
368
|
-
if (changed.has('meLabel') || changed.has('messageLabel')) {
|
|
369
|
-
this.words = { me: this.meLabel, sentence: this.messageLabel };
|
|
376
|
+
if (changed.has('meLabel') || changed.has('messageLabel') || changed.has('turnLabel')) {
|
|
377
|
+
this.words = { me: this.meLabel, sentence: this.messageLabel, turn: this.turnLabel };
|
|
370
378
|
}
|
|
371
379
|
this.countRegions();
|
|
372
380
|
if (changed.has('history')) {
|
|
@@ -431,6 +439,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
431
439
|
author=${turn.author ?? nothing}
|
|
432
440
|
author-label=${turn.authorLabel ?? nothing}
|
|
433
441
|
at=${turn.at ?? nothing}
|
|
442
|
+
style=${ownEntry(this.authorStyles, turn.author) ?? nothing}
|
|
434
443
|
.turnWords=${this.words}
|
|
435
444
|
state=${turn.state ?? nothing}
|
|
436
445
|
>${turn.text}</${message}>
|
|
@@ -466,14 +475,22 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
466
475
|
<div part="resume" ?hidden=${!away || !this.has('resume')} @click=${this.handleResume}>
|
|
467
476
|
<slot name="resume"></slot>
|
|
468
477
|
</div>
|
|
469
|
-
<div part="status" role="status" ?data-empty=${!this.has('status')}>
|
|
470
|
-
<slot name="status"></slot
|
|
478
|
+
<div part="status" role="status" ?data-empty=${!this.has('status') && this.typing === ''}>
|
|
479
|
+
<slot name="status"></slot>${this.typing === ''
|
|
480
|
+
? nothing
|
|
481
|
+
: html `<span part="typing"
|
|
482
|
+
><span part="indicator" aria-hidden="true"></span
|
|
483
|
+
>${fillTemplate(this.typingLabel, { author: this.typing })}</span
|
|
484
|
+
>`}
|
|
471
485
|
</div>
|
|
472
486
|
<div part="composer" ?hidden=${!this.has('composer')}>
|
|
473
487
|
<slot name="composer"></slot>
|
|
474
488
|
</div>`;
|
|
475
489
|
}
|
|
476
490
|
};
|
|
491
|
+
__decorate([
|
|
492
|
+
property({ attribute: 'author-styles', converter: wordsConverter })
|
|
493
|
+
], HelixHeadlessChat.prototype, "authorStyles", void 0);
|
|
477
494
|
__decorate([
|
|
478
495
|
property({ attribute: 'default-pinned', converter: onUnlessFalse })
|
|
479
496
|
], HelixHeadlessChat.prototype, "defaultPinned", void 0);
|
|
@@ -498,9 +515,18 @@ __decorate([
|
|
|
498
515
|
__decorate([
|
|
499
516
|
property({ type: Number })
|
|
500
517
|
], HelixHeadlessChat.prototype, "threshold", void 0);
|
|
518
|
+
__decorate([
|
|
519
|
+
property({ attribute: 'turn-label' })
|
|
520
|
+
], HelixHeadlessChat.prototype, "turnLabel", void 0);
|
|
501
521
|
__decorate([
|
|
502
522
|
property({ attribute: false })
|
|
503
523
|
], HelixHeadlessChat.prototype, "turns", void 0);
|
|
524
|
+
__decorate([
|
|
525
|
+
property()
|
|
526
|
+
], HelixHeadlessChat.prototype, "typing", void 0);
|
|
527
|
+
__decorate([
|
|
528
|
+
property({ attribute: 'typing-label' })
|
|
529
|
+
], HelixHeadlessChat.prototype, "typingLabel", void 0);
|
|
504
530
|
__decorate([
|
|
505
531
|
state()
|
|
506
532
|
], HelixHeadlessChat.prototype, "pinnedState", void 0);
|
|
@@ -21,6 +21,16 @@ declare const HelixHeadlessCheckbox_base: (new (...args: any[]) => import("@fusi
|
|
|
21
21
|
* it as neither checked nor unchecked, it never submits, and the first click
|
|
22
22
|
* resolves it.
|
|
23
23
|
*
|
|
24
|
+
* **Keyboard.** The box is one tab stop.
|
|
25
|
+
*
|
|
26
|
+
* | Key | What it does |
|
|
27
|
+
* |---|---|
|
|
28
|
+
* | Space | Checks or unchecks the box, and resolves `indeterminate`. |
|
|
29
|
+
*
|
|
30
|
+
* The native input reports checked, unchecked, or mixed. `aria-readonly` is set
|
|
31
|
+
* under `readonly`, and `aria-invalid` and `aria-describedby` point at the
|
|
32
|
+
* message while one shows.
|
|
33
|
+
*
|
|
24
34
|
* @since 0.1.0
|
|
25
35
|
* @status stable
|
|
26
36
|
* @category forms
|
|
@@ -28,6 +38,8 @@ declare const HelixHeadlessCheckbox_base: (new (...args: any[]) => import("@fusi
|
|
|
28
38
|
* @documentation https://fusion.dev/helix/components/checkbox
|
|
29
39
|
*
|
|
30
40
|
* @slot - The label.
|
|
41
|
+
* @slot check - An icon drawn as the mark while the box is checked, in place of the tick.
|
|
42
|
+
* @slot dash - An icon drawn as the mark while the box is indeterminate, in place of the dash.
|
|
31
43
|
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
32
44
|
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
33
45
|
*
|
|
@@ -47,6 +59,8 @@ declare const HelixHeadlessCheckbox_base: (new (...args: any[]) => import("@fusi
|
|
|
47
59
|
* @csspart mark-indeterminate - Added to `mark` while the box is indeterminate.
|
|
48
60
|
*
|
|
49
61
|
* @cssstate checked - While the box is checked.
|
|
62
|
+
* @cssstate has-check - An icon is slotted into `check`.
|
|
63
|
+
* @cssstate has-dash - An icon is slotted into `dash`.
|
|
50
64
|
* @cssstate has-label - The label slot has content, so the label is drawn.
|
|
51
65
|
* @cssstate indeterminate - While the box shows the dash, neither checked nor unchecked.
|
|
52
66
|
* @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
|
|
@@ -107,6 +121,12 @@ export declare class HelixHeadlessCheckbox extends HelixHeadlessCheckbox_base {
|
|
|
107
121
|
* worse problem than its spacing.
|
|
108
122
|
*/
|
|
109
123
|
private readonly handleLabelChange;
|
|
124
|
+
/**
|
|
125
|
+
* Records which of the mark's slots hold an icon, as `:state(has-check)` and
|
|
126
|
+
* `:state(has-dash)`, so a stylesheet drops its own drawing of that shape.
|
|
127
|
+
* A state, for the reason `:state(has-label)` is one.
|
|
128
|
+
*/
|
|
129
|
+
private readonly handleMarkChange;
|
|
110
130
|
/**
|
|
111
131
|
* Asks the slot, and records the answer as a state.
|
|
112
132
|
*
|
|
@@ -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 { AriaForwardController, customElement, HelixFormElement, HostClickController, MixinControllerChecked, MixinField, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, HelixFormElement, HostClickController, MixinControllerChecked, MixinField, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerChecked(MixinField(HelixFormElement)) {
|
|
@@ -32,6 +32,16 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
32
32
|
this.handleLabelChange = () => {
|
|
33
33
|
this.syncLabelPresence();
|
|
34
34
|
};
|
|
35
|
+
this.handleMarkChange = (event) => {
|
|
36
|
+
const slot = event.target;
|
|
37
|
+
const filled = slotFilled(slot);
|
|
38
|
+
if (slot.name === 'dash') {
|
|
39
|
+
this.toggleState('has-dash', filled);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.toggleState('has-check', filled);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
35
45
|
}
|
|
36
46
|
static { this.shadowRootOptions = {
|
|
37
47
|
...HelixFormElement.shadowRootOptions,
|
|
@@ -64,11 +74,9 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
64
74
|
}
|
|
65
75
|
syncLabelPresence() {
|
|
66
76
|
const slot = this.renderRoot.querySelector('[part="label"] slot');
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
const hidden = this.label === '' &&
|
|
70
|
-
Boolean(this.getAttribute('aria-label')) &&
|
|
71
|
-
!(slot?.assignedNodes() ?? []).some(meaningful);
|
|
77
|
+
const filled = slotFilled(slot);
|
|
78
|
+
const written = (slot?.assignedNodes() ?? []).some((node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim() !== '');
|
|
79
|
+
const hidden = this.label === '' && Boolean(this.getAttribute('aria-label')) && !written;
|
|
72
80
|
this.partNamed('label')?.toggleAttribute('data-hidden', hidden);
|
|
73
81
|
this.toggleState('has-label', filled && !hidden);
|
|
74
82
|
this.partNamed('label')?.toggleAttribute('hidden', !filled);
|
|
@@ -94,7 +102,10 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
94
102
|
<span
|
|
95
103
|
part="mark${this.checked ? ' mark-checked' : ''}${this.indeterminate ? ' mark-indeterminate' : ''}${this.dashed ? ' mark-dash' : ''}"
|
|
96
104
|
aria-hidden="true"
|
|
97
|
-
|
|
105
|
+
>${this.dashed
|
|
106
|
+
? html `<slot name="dash" @slotchange=${this.handleMarkChange}></slot>`
|
|
107
|
+
: html `<slot name="check" @slotchange=${this.handleMarkChange}></slot>`}</span
|
|
108
|
+
>
|
|
98
109
|
</span>
|
|
99
110
|
<span part="label" ?data-hidden=${named !== null}
|
|
100
111
|
><slot @slotchange=${this.handleLabelChange}>${this.label || named}</slot></span
|
|
@@ -34,6 +34,9 @@ declare const HelixHeadlessCheckboxGroup_base: (new (...args: any[]) => import("
|
|
|
34
34
|
* only for validity and never calls `setFormValue`, so the browser does not
|
|
35
35
|
* generate a message for it.
|
|
36
36
|
*
|
|
37
|
+
* **Keyboard.** Each box is its own tab stop, as a set of native checkboxes
|
|
38
|
+
* is, and Space checks the focused one. The select-all box comes first.
|
|
39
|
+
*
|
|
37
40
|
* @since 0.1.0
|
|
38
41
|
* @status stable
|
|
39
42
|
* @category forms
|
|
@@ -221,12 +224,15 @@ export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGro
|
|
|
221
224
|
* for the whole set, as a box moves it.
|
|
222
225
|
*/
|
|
223
226
|
private readonly handleSelectAll;
|
|
227
|
+
/** The set as the select-all helper reads it. */
|
|
228
|
+
private setBoxes;
|
|
224
229
|
/**
|
|
225
230
|
* The box above the set that checks or unchecks every box, under
|
|
226
231
|
* `select-all`, behind a seam a tier can move.
|
|
227
232
|
*
|
|
228
|
-
* Checked while every box is, and showing a dash while only some
|
|
229
|
-
*
|
|
233
|
+
* Checked while every enabled box is, and showing a dash while only some
|
|
234
|
+
* are, so its state says what a press does. It is in this shadow root, so
|
|
235
|
+
* it is no member of the set and submits nothing.
|
|
230
236
|
*/
|
|
231
237
|
protected renderSelectAll(): TemplateResult | typeof nothing;
|
|
232
238
|
protected render(): TemplateResult;
|
|
@@ -5,12 +5,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessCheckboxGroup_1;
|
|
8
|
-
import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, toggleEvery, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
11
|
import { html } from 'lit/static-html.js';
|
|
12
12
|
import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
|
|
13
13
|
import '../../checkbox/index.js';
|
|
14
|
+
import { selectAllState } from '../select-all.js';
|
|
14
15
|
let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
|
|
15
16
|
constructor() {
|
|
16
17
|
super(...arguments);
|
|
@@ -59,11 +60,8 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
59
60
|
this.handleSelectAll = (event) => {
|
|
60
61
|
event.preventDefault();
|
|
61
62
|
event.stopPropagation();
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const next = this.boxes
|
|
65
|
-
.filter((box) => (enabled.includes(box) ? !every : box.checked))
|
|
66
|
-
.map((box) => box.value);
|
|
63
|
+
const boxes = this.setBoxes();
|
|
64
|
+
const next = toggleEvery(boxes.filter((box) => box.checked).map((box) => box.value), boxes.filter((box) => !box.disabled).map((box) => box.value), boxes.map((box) => box.value));
|
|
67
65
|
if (!this.dispatchEvent(new HelixBeforeChangeEvent({ value: next.join(',') }))) {
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
@@ -177,13 +175,18 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
177
175
|
this.validate();
|
|
178
176
|
this.linkHost();
|
|
179
177
|
}
|
|
178
|
+
setBoxes() {
|
|
179
|
+
return this.boxes.map((box) => ({
|
|
180
|
+
checked: box.checked,
|
|
181
|
+
disabled: box.isDisabled,
|
|
182
|
+
value: box.value,
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
180
185
|
renderSelectAll() {
|
|
181
186
|
if (!this.selectAll) {
|
|
182
187
|
return nothing;
|
|
183
188
|
}
|
|
184
|
-
const
|
|
185
|
-
const ticked = boxes.filter((box) => box.checked).length;
|
|
186
|
-
const every = boxes.length > 0 && ticked === boxes.length;
|
|
189
|
+
const { checked, indeterminate } = selectAllState(this.childrenKnown ? this.setBoxes() : []);
|
|
187
190
|
const box = this.tag('checkbox');
|
|
188
191
|
return html `<${box}
|
|
189
192
|
part="select-all"
|
|
@@ -191,8 +194,8 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
|
|
|
191
194
|
feedback: select-all-feedback, field: select-all-field, hint: select-all-hint,
|
|
192
195
|
label: select-all-label, mark: select-all-mark, mark-checked: select-all-mark-checked,
|
|
193
196
|
mark-dash: select-all-mark-dash, mark-indeterminate: select-all-mark-indeterminate"
|
|
194
|
-
.checked=${
|
|
195
|
-
.indeterminate=${
|
|
197
|
+
.checked=${checked}
|
|
198
|
+
.indeterminate=${indeterminate}
|
|
196
199
|
?disabled=${this.isDisabled}
|
|
197
200
|
label=${this.selectAllLabel}
|
|
198
201
|
@helix-before-toggle=${this.handleSelectAll}
|