@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,11 +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 { AriaForwardController, byRow, CHART_PLOT, customElement, drawTooltip, formatNumbers, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, byRow, CHART_PLOT, commaList, customElement, drawTooltip, fillTemplate, formatNumbers, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, pressedValue, rangeAdd, requestValue, StatusController, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
11
|
-
import { fits, toneOf } from './buckets.js';
|
|
11
|
+
import { fits, monthPage, overviewOf, toneOf } from './buckets.js';
|
|
12
12
|
let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(HelixElement) {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
@@ -17,9 +17,12 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
17
17
|
this.gap = 2;
|
|
18
18
|
this.minCell = 8;
|
|
19
19
|
this.rows = 1;
|
|
20
|
+
this.selectedLabel = 'selected';
|
|
21
|
+
this.selectionLabel = '{count} selected';
|
|
20
22
|
this.thresholds = '';
|
|
21
23
|
this.tones = '';
|
|
22
24
|
this.totalLabel = 'Total';
|
|
25
|
+
this.value = '';
|
|
23
26
|
this.width = undefined;
|
|
24
27
|
this.metrics = undefined;
|
|
25
28
|
this.aria = new AriaForwardController(this, {
|
|
@@ -27,6 +30,35 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
27
30
|
});
|
|
28
31
|
this.observer = undefined;
|
|
29
32
|
this.announced = undefined;
|
|
33
|
+
this.anchor = -1;
|
|
34
|
+
this.status = new StatusController(this);
|
|
35
|
+
this.onKeydown = (event) => {
|
|
36
|
+
const at = this.pointer.at;
|
|
37
|
+
if (!this.selectionMode || at < 0 || event.altKey || event.ctrlKey || event.metaKey) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
this.press(at);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const moves = /^(Arrow|Page|Home$|End$)/.test(event.key);
|
|
46
|
+
if (!event.shiftKey || !moves || this.selectionMode !== 'multiple') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const keys = this.keysOf(this.drawn);
|
|
50
|
+
const added = rangeAdd(commaList(this.value), keys, this.anchor < 0 ? at : this.anchor, at);
|
|
51
|
+
if (added) {
|
|
52
|
+
this.choose(added.join(', '));
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
this.onClick = (event) => {
|
|
56
|
+
const cell = event.target?.closest?.('[part~="cell"]');
|
|
57
|
+
const index = Number(cell?.getAttribute('data-index') ?? -1);
|
|
58
|
+
if (cell && Number.isInteger(index) && index >= 0) {
|
|
59
|
+
this.press(index);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
30
62
|
this.onPointerOver = (event) => {
|
|
31
63
|
if (!this.pointer.accepts(event)) {
|
|
32
64
|
return;
|
|
@@ -44,6 +76,29 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
44
76
|
get visible() {
|
|
45
77
|
return Math.min(this.points.length, this.room);
|
|
46
78
|
}
|
|
79
|
+
keysOf(cells) {
|
|
80
|
+
const offset = this.points.length - cells.length;
|
|
81
|
+
const rows = this.sourceRows;
|
|
82
|
+
return cells.map((_, index) => rows[offset + index]?.label ?? '');
|
|
83
|
+
}
|
|
84
|
+
choose(next) {
|
|
85
|
+
if (next === this.value) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
requestValue(this, next, (value) => {
|
|
89
|
+
this.value = value;
|
|
90
|
+
this.status.say(fillTemplate(this.selectionLabel, { count: commaList(value).length }));
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
press(index) {
|
|
94
|
+
const mode = this.selectionMode;
|
|
95
|
+
const key = this.keysOf(this.drawn)[index];
|
|
96
|
+
if (!mode || key === undefined || key === '') {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.anchor = index;
|
|
100
|
+
this.choose(pressedValue(mode, this.value, key));
|
|
101
|
+
}
|
|
47
102
|
get points() {
|
|
48
103
|
const series = this.series[0];
|
|
49
104
|
if (!series) {
|
|
@@ -99,8 +154,13 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
99
154
|
super.willUpdate(changed);
|
|
100
155
|
this.pointer.grid = this.rowCount;
|
|
101
156
|
}
|
|
157
|
+
pageFrom(at, forward) {
|
|
158
|
+
const offset = this.points.length - this.drawn.length;
|
|
159
|
+
return monthPage(this.sourceRows.slice(offset).map((row) => row.when), at, forward);
|
|
160
|
+
}
|
|
102
161
|
connectedCallback() {
|
|
103
162
|
super.connectedCallback();
|
|
163
|
+
this.addEventListener('keydown', this.onKeydown);
|
|
104
164
|
if (typeof ResizeObserver !== 'undefined') {
|
|
105
165
|
this.observer = new ResizeObserver((entries) => {
|
|
106
166
|
const measured = entries[0]?.contentRect.width;
|
|
@@ -113,6 +173,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
113
173
|
}
|
|
114
174
|
disconnectedCallback() {
|
|
115
175
|
super.disconnectedCallback();
|
|
176
|
+
this.removeEventListener('keydown', this.onKeydown);
|
|
116
177
|
this.observer?.disconnect();
|
|
117
178
|
this.observer = undefined;
|
|
118
179
|
}
|
|
@@ -143,6 +204,8 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
143
204
|
const palette = writtenList(this.tones);
|
|
144
205
|
const cells = this.drawn;
|
|
145
206
|
const readable = cells.length > 0;
|
|
207
|
+
const keys = this.selectionMode ? this.keysOf(cells) : [];
|
|
208
|
+
const chosen = new Set(this.selectionMode ? commaList(this.value) : []);
|
|
146
209
|
return html `<div
|
|
147
210
|
aria-describedby=${readable ? 'helix-chart-summary' : nothing}
|
|
148
211
|
aria-label=${this.named || 'Heatmap'}
|
|
@@ -151,6 +214,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
151
214
|
role=${readable ? 'application' : 'img'}
|
|
152
215
|
style="--heatmap-rows: ${this.rowCount}"
|
|
153
216
|
tabindex=${readable ? '0' : nothing}
|
|
217
|
+
@click=${this.onClick}
|
|
154
218
|
@pointerover=${this.onPointerOver}
|
|
155
219
|
@pointerleave=${this.onPointerLeave}
|
|
156
220
|
>
|
|
@@ -159,13 +223,14 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
159
223
|
: cells.map((reading, index) => {
|
|
160
224
|
const tone = toneOf(reading, bounds, palette);
|
|
161
225
|
const active = this.pointer.at === index;
|
|
226
|
+
const picked = chosen.has(keys[index] ?? '');
|
|
162
227
|
return tone === undefined
|
|
163
228
|
? html `<span
|
|
164
|
-
part="cell${active ? ' cell-active' : ''}"
|
|
229
|
+
part="cell${active ? ' cell-active' : ''}${picked ? ' cell-selected' : ''}"
|
|
165
230
|
data-index=${index}
|
|
166
231
|
></span>`
|
|
167
232
|
: html `<span
|
|
168
|
-
part="cell${active ? ' cell-active' : ''}"
|
|
233
|
+
part="cell${active ? ' cell-active' : ''}${picked ? ' cell-selected' : ''}"
|
|
169
234
|
data-index=${index}
|
|
170
235
|
data-tone=${tone}
|
|
171
236
|
style="--heatmap-tone: var(--heatmap-tone-${tone})"
|
|
@@ -178,27 +243,18 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
178
243
|
<span part="start"><slot name="start"></slot></span>
|
|
179
244
|
<span part="summary"><slot name="summary"></slot></span>
|
|
180
245
|
<span part="end"><slot name="end"></slot></span>
|
|
181
|
-
</div>${readable ? this.renderOverview(cells) : nothing}
|
|
246
|
+
</div>${readable ? this.renderOverview(cells) : nothing}${this.status.spoken
|
|
247
|
+
? html `<span part="selection" role="status">${this.status.said}</span>`
|
|
248
|
+
: nothing}`;
|
|
182
249
|
}
|
|
183
250
|
renderOverview(cells) {
|
|
184
251
|
const rows = this.sourceRows;
|
|
185
252
|
const offset = this.points.length - cells.length;
|
|
186
253
|
const column = this.plottedColumns[0] ?? -1;
|
|
187
|
-
|
|
188
|
-
let total = 0;
|
|
189
|
-
cells.forEach((cell, index) => {
|
|
190
|
-
if (cell.value === undefined) {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
total += cell.value;
|
|
194
|
-
if (busiest < 0 || cell.value > (cells[busiest]?.value ?? 0)) {
|
|
195
|
-
busiest = index;
|
|
196
|
-
}
|
|
197
|
-
});
|
|
254
|
+
const { busiest, total } = overviewOf(cells);
|
|
198
255
|
const row = rows[offset + busiest];
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
: '';
|
|
256
|
+
const text = row?.cells[column]?.text ?? '';
|
|
257
|
+
const most = row ? `${this.busiestLabel}: ${row.label}${text === '' ? '' : `, ${text}`}` : '';
|
|
202
258
|
const sum = `${this.totalLabel} ${formatNumbers(this.locale)(total)}`;
|
|
203
259
|
return html `<p id="helix-chart-summary" part="overview">${most ? `${most}; ${sum}` : sum}.</p>`;
|
|
204
260
|
}
|
|
@@ -216,7 +272,24 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
216
272
|
placement: 'top',
|
|
217
273
|
x: `${column * (cell + gap) + cell / 2}px`,
|
|
218
274
|
y: `${row * (cell + gap)}px`,
|
|
219
|
-
}, undefined, this.
|
|
275
|
+
}, undefined, this.reading(at));
|
|
276
|
+
}
|
|
277
|
+
reading(at) {
|
|
278
|
+
const pointer = this.pointer;
|
|
279
|
+
const key = this.keysOf(this.drawn)[at] ?? '';
|
|
280
|
+
if (!this.selectionMode || key === '' || this.selectedLabel === '') {
|
|
281
|
+
return pointer;
|
|
282
|
+
}
|
|
283
|
+
if (!commaList(this.value).includes(key)) {
|
|
284
|
+
return pointer;
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
column: pointer.column,
|
|
288
|
+
keyed: pointer.keyed,
|
|
289
|
+
position: pointer.position,
|
|
290
|
+
shows: (cell) => pointer.shows(cell),
|
|
291
|
+
state: this.selectedLabel,
|
|
292
|
+
};
|
|
220
293
|
}
|
|
221
294
|
};
|
|
222
295
|
__decorate([
|
|
@@ -234,6 +307,15 @@ __decorate([
|
|
|
234
307
|
__decorate([
|
|
235
308
|
property({ type: Number })
|
|
236
309
|
], HelixHeadlessHeatmap.prototype, "rows", void 0);
|
|
310
|
+
__decorate([
|
|
311
|
+
property({ attribute: 'selected-label' })
|
|
312
|
+
], HelixHeadlessHeatmap.prototype, "selectedLabel", void 0);
|
|
313
|
+
__decorate([
|
|
314
|
+
property({ attribute: 'selection-label' })
|
|
315
|
+
], HelixHeadlessHeatmap.prototype, "selectionLabel", void 0);
|
|
316
|
+
__decorate([
|
|
317
|
+
property({ attribute: 'selection-mode' })
|
|
318
|
+
], HelixHeadlessHeatmap.prototype, "selectionMode", void 0);
|
|
237
319
|
__decorate([
|
|
238
320
|
property()
|
|
239
321
|
], HelixHeadlessHeatmap.prototype, "thresholds", void 0);
|
|
@@ -243,6 +325,9 @@ __decorate([
|
|
|
243
325
|
__decorate([
|
|
244
326
|
property({ attribute: 'total-label' })
|
|
245
327
|
], HelixHeadlessHeatmap.prototype, "totalLabel", void 0);
|
|
328
|
+
__decorate([
|
|
329
|
+
property()
|
|
330
|
+
], HelixHeadlessHeatmap.prototype, "value", void 0);
|
|
246
331
|
__decorate([
|
|
247
332
|
state()
|
|
248
333
|
], HelixHeadlessHeatmap.prototype, "width", void 0);
|
package/dist/icon/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './set.js';
|
|
2
|
-
export { type IconResolver, registerIconLibrary, registerIcons, resolveIcon } from './registry.js';
|
|
2
|
+
export { type IconLibraryOptions, type IconResolver, registerIconLibrary, registerIcons, resolveIcon, } from './registry.js';
|
|
3
3
|
export * from './root/icon-root.js';
|
package/dist/icon/index.js
CHANGED
package/dist/icon/registry.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { HelixIcon } from '@fusion.dev/helix-icons';
|
|
2
2
|
/** What a library gives for a name: a glyph, a glyph later, or nothing. */
|
|
3
3
|
export type IconResolver = (name: string) => HelixIcon | Promise<HelixIcon | undefined> | undefined;
|
|
4
|
+
/** How a library's glyphs are drawn, beside the names it resolves. */
|
|
5
|
+
export interface IconLibraryOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Changes each drawn `<svg>` of the library's glyphs, as Web Awesome's
|
|
8
|
+
* `mutator` does: a stroke width, a fill, an attribute the set leaves out.
|
|
9
|
+
* Called after every render that draws one of them.
|
|
10
|
+
*/
|
|
11
|
+
mutator?: (svg: SVGSVGElement) => void;
|
|
12
|
+
}
|
|
4
13
|
/**
|
|
5
14
|
* Makes glyphs resolvable by name: a record of names to glyphs, such as the
|
|
6
15
|
* whole set, or a list of glyphs, each under its own `name`.
|
|
@@ -15,14 +24,30 @@ export declare const registerIcons: (glyphs: Record<string, HelixIcon> | readonl
|
|
|
15
24
|
* The resolver may answer at once or with a promise; an element waiting on a
|
|
16
25
|
* promise draws the glyph when it arrives and fires `load`. Each written name
|
|
17
26
|
* is asked once, and a prefix registered again is asked afresh.
|
|
27
|
+
*
|
|
28
|
+
* A sprite sheet is a library whose glyphs point into it, so the sheet is
|
|
29
|
+
* fetched once and cached:
|
|
30
|
+
*
|
|
31
|
+
* ```js
|
|
32
|
+
* registerIconLibrary('sprite', (name) => ({
|
|
33
|
+
* content: `<use href="/icons.svg#${name}"></use>`,
|
|
34
|
+
* name,
|
|
35
|
+
* viewBox: '0 0 24 24',
|
|
36
|
+
* }))
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* `mutator` changes each drawn `<svg>` of the library, such as
|
|
40
|
+
* `(svg) => svg.setAttribute('stroke-width', '1.5')`.
|
|
18
41
|
*/
|
|
19
|
-
export declare const registerIconLibrary: (prefix: string, resolve: IconResolver) => void;
|
|
42
|
+
export declare const registerIconLibrary: (prefix: string, resolve: IconResolver, options?: IconLibraryOptions) => void;
|
|
20
43
|
/**
|
|
21
44
|
* Calls `watcher` whenever a glyph or a library is registered, so an element
|
|
22
45
|
* drawn before its glyph was registered can look again. Returns the function
|
|
23
46
|
* that stops it.
|
|
24
47
|
*/
|
|
25
48
|
export declare const watchIcons: (watcher: () => void) => (() => void);
|
|
49
|
+
/** The mutator of the library a written name asks, or `undefined`. */
|
|
50
|
+
export declare const iconMutator: (name: string) => ((svg: SVGSVGElement) => void) | undefined;
|
|
26
51
|
/** The registered glyph of this name, or `undefined`. */
|
|
27
52
|
export declare const registeredIcon: (name: string) => HelixIcon | undefined;
|
|
28
53
|
/**
|
package/dist/icon/registry.js
CHANGED
|
@@ -24,9 +24,16 @@ export const registerIcons = (glyphs) => {
|
|
|
24
24
|
}
|
|
25
25
|
changed(held);
|
|
26
26
|
};
|
|
27
|
-
export const registerIconLibrary = (prefix, resolve) => {
|
|
27
|
+
export const registerIconLibrary = (prefix, resolve, options = {}) => {
|
|
28
28
|
const held = registry();
|
|
29
29
|
held.libraries.set(prefix, resolve);
|
|
30
|
+
held.mutators ??= new Map();
|
|
31
|
+
if (options.mutator) {
|
|
32
|
+
held.mutators.set(prefix, options.mutator);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
held.mutators.delete(prefix);
|
|
36
|
+
}
|
|
30
37
|
for (const name of held.answers.keys()) {
|
|
31
38
|
if (name.startsWith(`${prefix}:`)) {
|
|
32
39
|
held.answers.delete(name);
|
|
@@ -41,6 +48,10 @@ export const watchIcons = (watcher) => {
|
|
|
41
48
|
held.watchers.delete(watcher);
|
|
42
49
|
};
|
|
43
50
|
};
|
|
51
|
+
export const iconMutator = (name) => {
|
|
52
|
+
const split = name.indexOf(':');
|
|
53
|
+
return split > 0 ? registry().mutators?.get(name.slice(0, split)) : undefined;
|
|
54
|
+
};
|
|
44
55
|
export const registeredIcon = (name) => registry().glyphs.get(name);
|
|
45
56
|
export const resolveIcon = (name) => {
|
|
46
57
|
const registered = registeredIcon(name);
|
|
@@ -36,6 +36,11 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
36
36
|
* button with no text. An `aria-label` on the element works too: the element
|
|
37
37
|
* is then an image with that name.
|
|
38
38
|
*
|
|
39
|
+
* **A decorative icon that is all a control holds is reported.** In a
|
|
40
|
+
* development build, a button or a link whose only content is an icon with no
|
|
41
|
+
* `label`, and which has no name of its own, warns `missing-name` once,
|
|
42
|
+
* through the runtime channel every Helix warning uses.
|
|
43
|
+
*
|
|
39
44
|
* @since 0.1.0
|
|
40
45
|
* @status stable
|
|
41
46
|
* @category media
|
|
@@ -121,6 +126,14 @@ export declare class HelixHeadlessIcon extends HelixElement {
|
|
|
121
126
|
private lookup;
|
|
122
127
|
protected willUpdate(changed: PropertyValues): void;
|
|
123
128
|
protected updated(changed: PropertyValues): void;
|
|
129
|
+
/** Hands the drawn `<svg>` to the mutator of the library `name` asks, where it has one. */
|
|
130
|
+
private mutate;
|
|
131
|
+
/**
|
|
132
|
+
* Asks the button or link a decorative icon sits in whether it has a name.
|
|
133
|
+
* Its content is this icon alone where it has none, and the audit says so
|
|
134
|
+
* once, in a development build only. A Helix button reports its own name.
|
|
135
|
+
*/
|
|
136
|
+
private auditControl;
|
|
124
137
|
/** The name a report is waiting on the page to settle for, so it is asked once. */
|
|
125
138
|
private pending;
|
|
126
139
|
/**
|
|
@@ -4,11 +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, hostAria, reportRuntime } from '@fusion.dev/helix-core';
|
|
7
|
+
import { auditName, customElement, HelixElement, hostAria, reportRuntime, } 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
|
-
import { resolveIcon, watchIcons } from '../registry.js';
|
|
11
|
+
import { iconMutator, resolveIcon, watchIcons } from '../registry.js';
|
|
12
12
|
import { afterPageSettles } from '../settle.js';
|
|
13
13
|
let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
14
14
|
constructor() {
|
|
@@ -66,6 +66,10 @@ let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
|
66
66
|
}
|
|
67
67
|
updated(changed) {
|
|
68
68
|
super.updated(changed);
|
|
69
|
+
if (this.drawn !== undefined) {
|
|
70
|
+
this.mutate();
|
|
71
|
+
this.auditControl();
|
|
72
|
+
}
|
|
69
73
|
if (this.arrived === this.name && this.drawn !== undefined) {
|
|
70
74
|
this.dispatchEvent(new Event('load', { bubbles: false, cancelable: false, composed: false }));
|
|
71
75
|
}
|
|
@@ -80,6 +84,23 @@ let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
|
80
84
|
this.missed = '';
|
|
81
85
|
}
|
|
82
86
|
}
|
|
87
|
+
mutate() {
|
|
88
|
+
const svg = this.renderRoot.querySelector('svg');
|
|
89
|
+
const mutator = this.icon === undefined ? iconMutator(this.name) : undefined;
|
|
90
|
+
if (svg && mutator) {
|
|
91
|
+
mutator(svg);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
auditControl() {
|
|
95
|
+
if (this.label !== '' || this.hasAttribute('aria-label')) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const control = this.closest('a[href], button, summary, [role="button"], [role="link"]');
|
|
99
|
+
if (control) {
|
|
100
|
+
auditName(control, () => null, `Its only content is <${this.localName}>, which is decorative: give the icon a \`label\`, or the control an \`aria-label\`.`, () => (control.textContent ?? '').trim() !== '' ||
|
|
101
|
+
control.querySelector('[alt]:not([alt=""]), [aria-label]:not([aria-label=""])') !== null);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
83
104
|
reportMissing() {
|
|
84
105
|
const name = this.pending;
|
|
85
106
|
this.pending = '';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { type IconResolver, registerIconLibrary, registerIcons, resolveIcon } from '../registry.js';
|
|
1
|
+
export { type IconLibraryOptions, type IconResolver, registerIconLibrary, registerIcons, resolveIcon, } from '../registry.js';
|
|
2
2
|
export * from './icon-root.js';
|
package/dist/icon/root/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { registerIconLibrary, registerIcons, resolveIcon } from '../registry.js';
|
|
1
|
+
export { registerIconLibrary, registerIcons, resolveIcon, } from '../registry.js';
|
|
2
2
|
export * from './icon-root.js';
|
|
@@ -16,6 +16,17 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
16
16
|
* its own. The fallback is read once the picture fails, after the picture's
|
|
17
17
|
* `alt`, so a reader hears that it did not load, as a sighted reader sees.
|
|
18
18
|
*
|
|
19
|
+
* **An image with no `alt` says so.** At its first render it reports a
|
|
20
|
+
* `missing-alt` warning, printed in the console and counted by
|
|
21
|
+
* `@fusion.dev/helix-diagnostics`, which names the fix: describe the picture
|
|
22
|
+
* in `alt`, or write `alt=""` for one that is decoration. An image hidden with
|
|
23
|
+
* `aria-hidden="true"` needs neither and is not reported.
|
|
24
|
+
*
|
|
25
|
+
* A sheet of yours reads the state as `:state(loading)`, `:state(loaded)`,
|
|
26
|
+
* `:state(error)`, and `:state(waiting)`, the last while `placeholder-delay`
|
|
27
|
+
* holds the placeholder back. It can also read `data-status` on the host once
|
|
28
|
+
* the picture has loaded or failed.
|
|
29
|
+
*
|
|
19
30
|
* @since 0.1.0
|
|
20
31
|
* @status stable
|
|
21
32
|
* @category media
|
|
@@ -34,6 +45,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
34
45
|
*
|
|
35
46
|
* @cssstate error - The image failed to load, and the fallback shows.
|
|
36
47
|
* @cssstate loaded - The image loaded.
|
|
48
|
+
* @cssstate loading - The image is on its way, so neither `loaded` nor `error` is true yet.
|
|
49
|
+
* @cssstate waiting - The image is on its way and `placeholder-delay` still holds the placeholder back.
|
|
37
50
|
*/
|
|
38
51
|
export declare class HelixHeadlessImage extends HelixElement {
|
|
39
52
|
/**
|
|
@@ -121,6 +134,11 @@ export declare class HelixHeadlessImage extends HelixElement {
|
|
|
121
134
|
*
|
|
122
135
|
* `loading` writes nothing, because it is where every image starts and the
|
|
123
136
|
* resting state of a mirror is the attribute's absence.
|
|
137
|
+
*
|
|
138
|
+
* **Kept beside the custom states, and what the styled tier draws from.** An
|
|
139
|
+
* engine without `CustomStateSet`, Safari before 17.4 and Firefox before
|
|
140
|
+
* 126, records no state, and a picture faded in by `:state(loaded)` alone
|
|
141
|
+
* would stay transparent there for good. A sheet of your own can read either.
|
|
124
142
|
*/
|
|
125
143
|
status: 'error' | 'loaded' | 'loading';
|
|
126
144
|
/**
|
|
@@ -194,6 +212,8 @@ export declare class HelixHeadlessImage extends HelixElement {
|
|
|
194
212
|
private settle;
|
|
195
213
|
protected willUpdate(changed: PropertyValues): void;
|
|
196
214
|
protected updated(changed: PropertyValues): void;
|
|
215
|
+
/** Whether the picture is on its way and the wait still holds the placeholder back. */
|
|
216
|
+
private get waiting();
|
|
197
217
|
private startWait;
|
|
198
218
|
protected firstUpdated(changed: PropertyValues): void;
|
|
199
219
|
/**
|
|
@@ -92,7 +92,12 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
92
92
|
}
|
|
93
93
|
this.toggleState('loaded', this.status === 'loaded');
|
|
94
94
|
this.toggleState('error', this.status === 'error');
|
|
95
|
+
this.toggleState('loading', this.status === 'loading');
|
|
95
96
|
}
|
|
97
|
+
this.toggleState('waiting', this.waiting);
|
|
98
|
+
}
|
|
99
|
+
get waiting() {
|
|
100
|
+
return this.status === 'loading' && this.placeholderDelay > 0 && !this.wait.elapsed;
|
|
96
101
|
}
|
|
97
102
|
startWait() {
|
|
98
103
|
this.wait.start(this.placeholderDelay > 0 ? this.placeholderDelay : undefined);
|
|
@@ -142,7 +147,7 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
142
147
|
<span
|
|
143
148
|
part="placeholder"
|
|
144
149
|
aria-hidden="true"
|
|
145
|
-
?hidden=${this.status !== 'loading' ||
|
|
150
|
+
?hidden=${this.status !== 'loading' || this.waiting}
|
|
146
151
|
><slot name="placeholder"></slot
|
|
147
152
|
></span>
|
|
148
153
|
<span
|
|
@@ -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
|
/** What the control accepts, which is text of one kind or another. */
|
|
4
4
|
export type InputType = 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url';
|
|
@@ -25,16 +25,30 @@ declare const HelixHeadlessInput_base: (new (...args: any[]) => import("@fusion.
|
|
|
25
25
|
* Aria's TextField `validate` does. What it returns is the message the field
|
|
26
26
|
* shows once the user has edited it, and the message a submit raises.
|
|
27
27
|
*
|
|
28
|
+
* **Keyboard.** The field's own keys are the platform's. Enter submits the
|
|
29
|
+
* form through its default button, as in a native field. The clear button
|
|
30
|
+
* under `clearable` and the reveal button under `reveal` are tab stops of
|
|
31
|
+
* their own after the field, so a keyboard reaches them.
|
|
32
|
+
*
|
|
33
|
+
* The inner input is named by `label`, or by a host `aria-label`,
|
|
34
|
+
* `aria-labelledby` or `<label for>`, and is described by the hint and the
|
|
35
|
+
* message, with `aria-invalid` while a message shows. The clear button is
|
|
36
|
+
* named `clear-label`, and the reveal button `reveal-label` with
|
|
37
|
+
* `aria-pressed` while the password shows.
|
|
38
|
+
*
|
|
28
39
|
* @since 0.1.0
|
|
29
40
|
* @status stable
|
|
30
41
|
* @category forms
|
|
31
42
|
* @aliases TextField, Field, TextInput
|
|
32
43
|
* @documentation https://fusion.dev/helix/components/input
|
|
33
44
|
*
|
|
45
|
+
* @slot clear-icon - Replaces the cross on the clear button, under `clearable`.
|
|
46
|
+
* @slot conceal-icon - Replaces the crossed-out eye on the reveal button while the password shows, under `reveal`.
|
|
34
47
|
* @slot end - After the text, for an icon or a unit.
|
|
35
48
|
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
36
49
|
* @slot hint - Help under the control, for content richer than the `hint` text.
|
|
37
50
|
* @slot label - The label, for content richer than the `label` text.
|
|
51
|
+
* @slot reveal-icon - Replaces the eye on the reveal button while the password is hidden, under `reveal`.
|
|
38
52
|
* @slot start - Before the text, for an icon or a prefix.
|
|
39
53
|
*
|
|
40
54
|
* @event {Event} change - Sent when the user finishes changing the value. Relayed from the native input.
|
|
@@ -290,7 +304,14 @@ export declare class HelixHeadlessInput extends HelixHeadlessInput_base {
|
|
|
290
304
|
* nothing wrong. Return a message, or a list of them, to mark the field
|
|
291
305
|
* invalid, and `true`, `null`, or nothing to accept the value.
|
|
292
306
|
*/
|
|
293
|
-
validate?:
|
|
307
|
+
validate?: OwnRule;
|
|
308
|
+
/** The cross on the clear button, behind a seam a tier can move. */
|
|
309
|
+
protected renderClearIcon(): TemplateResult;
|
|
310
|
+
/**
|
|
311
|
+
* The eye on the reveal button, behind a seam a tier can move: open while
|
|
312
|
+
* the password is hidden, and crossed out while it shows.
|
|
313
|
+
*/
|
|
314
|
+
protected renderRevealIcon(): TemplateResult;
|
|
294
315
|
protected render(): TemplateResult;
|
|
295
316
|
}
|
|
296
317
|
declare global {
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, MixinControllerValue, MixinField, restoreValue, submitImplicitly, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, applyOwnRule, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, MixinControllerValue, MixinField, restoreValue, submitImplicitly, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { eye, eyeSlash, x } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -112,11 +112,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
this.copyValidity(control);
|
|
115
|
-
|
|
116
|
-
const message = Array.isArray(own) ? own.join(' ') : typeof own === 'string' ? own : '';
|
|
117
|
-
if (message !== '') {
|
|
118
|
-
this.internals.setValidity({ customError: true }, message, control);
|
|
119
|
-
}
|
|
115
|
+
applyOwnRule(this.internals, control, this.validate, this.value);
|
|
120
116
|
this.refreshFeedback();
|
|
121
117
|
}
|
|
122
118
|
focus(options) {
|
|
@@ -156,6 +152,14 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
156
152
|
this.releaseCaret = undefined;
|
|
157
153
|
this.sync();
|
|
158
154
|
}
|
|
155
|
+
renderClearIcon() {
|
|
156
|
+
return html `<slot name="clear-icon">${drawIcon(x)}</slot>`;
|
|
157
|
+
}
|
|
158
|
+
renderRevealIcon() {
|
|
159
|
+
return this.revealed
|
|
160
|
+
? html `<slot name="conceal-icon">${drawIcon(eyeSlash)}</slot>`
|
|
161
|
+
: html `<slot name="reveal-icon">${drawIcon(eye)}</slot>`;
|
|
162
|
+
}
|
|
159
163
|
render() {
|
|
160
164
|
return html `${this.renderLabel()}
|
|
161
165
|
<div part="field">
|
|
@@ -199,7 +203,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
199
203
|
aria-label=${this.clearLabel}
|
|
200
204
|
@click=${this.handleClear}
|
|
201
205
|
>
|
|
202
|
-
${
|
|
206
|
+
${this.renderClearIcon()}
|
|
203
207
|
</button>`
|
|
204
208
|
: nothing}
|
|
205
209
|
${this.reveal && this.type === 'password'
|
|
@@ -213,7 +217,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
213
217
|
this.revealed = !this.revealed;
|
|
214
218
|
}}
|
|
215
219
|
>
|
|
216
|
-
${
|
|
220
|
+
${this.renderRevealIcon()}
|
|
217
221
|
</button>`
|
|
218
222
|
: nothing}
|
|
219
223
|
</div>
|
|
@@ -26,7 +26,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
26
26
|
* `caps` draws a chord as a key per key: each is a `key` part and the `+`
|
|
27
27
|
* between two a `separator` part, so a sheet can draw a cap for each.
|
|
28
28
|
* `key-labels` renames any key, on every platform, such as
|
|
29
|
-
* `key-labels='{"mod":"Command"}'`.
|
|
29
|
+
* `key-labels='{"mod":"Command"}'`. On an Apple keyboard a word joins the
|
|
30
|
+
* next key with a hyphen, as in `Command-K`.
|
|
31
|
+
*
|
|
32
|
+
* **`activate` makes the shortcut work the control `for` names**, with no
|
|
33
|
+
* script: `activate="focus"` moves focus to it, as `/` does to a search
|
|
34
|
+
* field, and `activate="click"` presses it. It acts once `helix-shortcut` has
|
|
35
|
+
* gone out and no listener canceled it, and only where `within` listens.
|
|
30
36
|
*
|
|
31
37
|
* @since 0.1.0
|
|
32
38
|
* @status stable
|
|
@@ -40,9 +46,18 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
40
46
|
*
|
|
41
47
|
* @csspart kbd - The key, or the chord under `keys`.
|
|
42
48
|
* @csspart key - One key of a chord under `keys` and `caps`, such as `Ctrl` in `Ctrl+K`.
|
|
43
|
-
* @csspart separator - The `+` between two keys of a chord under `keys` and `caps`, drawn where the platform writes one: on Windows and Linux. An Apple keyboard writes none
|
|
49
|
+
* @csspart separator - The `+` between two keys of a chord under `keys` and `caps`, drawn where the platform writes one: on Windows and Linux. An Apple keyboard writes none between glyphs, and a hyphen between words from `key-labels`.
|
|
44
50
|
*/
|
|
45
51
|
export declare class HelixHeadlessKbd extends HelixElement {
|
|
52
|
+
/**
|
|
53
|
+
* What the chord does to the control `for` names once it is pressed:
|
|
54
|
+
* `focus` moves focus to the control and `click` presses it.
|
|
55
|
+
*
|
|
56
|
+
* Unset, the chord sends `helix-shortcut` and does nothing else, for a page
|
|
57
|
+
* that acts on the event itself. It acts only where `within` listens, after
|
|
58
|
+
* `helix-shortcut`, and not when a listener cancels that event.
|
|
59
|
+
*/
|
|
60
|
+
activate?: 'click' | 'focus';
|
|
46
61
|
/**
|
|
47
62
|
* Draws a chord under `keys` as one key per key, each a `key` part with a
|
|
48
63
|
* `separator` part between two where the platform writes a `+`, as GitHub
|
|
@@ -72,7 +87,7 @@ export declare class HelixHeadlessKbd extends HelixElement {
|
|
|
72
87
|
* changes: the chord written onto `aria-keyshortcuts` keeps the names a
|
|
73
88
|
* screen reader knows.
|
|
74
89
|
*/
|
|
75
|
-
keyLabels
|
|
90
|
+
keyLabels: Record<string, string>;
|
|
76
91
|
/**
|
|
77
92
|
* The key or chord to show, such as `mod+k`, `?`, or `/`.
|
|
78
93
|
*
|
|
@@ -119,6 +134,8 @@ export declare class HelixHeadlessKbd extends HelixElement {
|
|
|
119
134
|
private listen;
|
|
120
135
|
private deafen;
|
|
121
136
|
private readonly handleKeydown;
|
|
137
|
+
/** Focuses or presses the control `for` names, as `activate` says. */
|
|
138
|
+
private act;
|
|
122
139
|
protected firstUpdated(changed: PropertyValues): void;
|
|
123
140
|
protected render(): TemplateResult;
|
|
124
141
|
/**
|