@fusion.dev/helix-headless 0.142.1 → 0.144.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 +25381 -1202
- package/dist/accordion/item/accordion-item.d.ts +38 -2
- package/dist/accordion/item/accordion-item.js +38 -6
- package/dist/accordion/root/accordion-root.d.ts +23 -1
- package/dist/accordion/root/accordion-root.js +39 -3
- package/dist/announcement/root/announcement-root.d.ts +11 -7
- package/dist/announcement/root/announcement-root.js +1 -1
- package/dist/app-header/root/app-header-root.d.ts +21 -0
- package/dist/app-header/root/app-header-root.js +31 -5
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +39 -11
- package/dist/avatar/group/avatar-group.d.ts +24 -3
- package/dist/avatar/group/avatar-group.js +34 -2
- package/dist/avatar/root/avatar-root.d.ts +17 -1
- package/dist/avatar/root/avatar-root.js +31 -10
- package/dist/badge/root/badge-root.d.ts +12 -0
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
- package/dist/bar-chart/root/bar-chart-root.js +58 -21
- package/dist/blockquote/root/blockquote-root.d.ts +12 -7
- package/dist/blockquote/root/blockquote-root.js +6 -4
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
- package/dist/button/root/button-root.d.ts +84 -1
- package/dist/button/root/button-root.js +81 -3
- package/dist/callout/root/callout-root.d.ts +32 -6
- package/dist/callout/root/callout-root.js +26 -7
- package/dist/canvas/root/canvas-root.d.ts +1 -0
- package/dist/canvas/root/canvas-root.js +10 -1
- package/dist/card/root/card-root.d.ts +30 -1
- package/dist/card/root/card-root.js +38 -5
- package/dist/carousel/root/carousel-root.d.ts +47 -5
- package/dist/carousel/root/carousel-root.js +53 -21
- package/dist/chat/composer/chat-composer.d.ts +13 -11
- package/dist/chat/composer/chat-composer.js +6 -12
- package/dist/chat/message/chat-message.js +8 -1
- package/dist/chat/root/chat-root.d.ts +1 -0
- package/dist/chat/root/chat-root.js +2 -1
- package/dist/checkbox/root/checkbox-root.d.ts +7 -0
- package/dist/checkbox/root/checkbox-root.js +9 -3
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
- package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
- package/dist/code/root/code-root.d.ts +1 -1
- package/dist/code-block/lines.d.ts +13 -0
- package/dist/code-block/lines.js +2 -0
- package/dist/code-block/root/code-block-root.d.ts +49 -0
- package/dist/code-block/root/code-block-root.js +44 -3
- package/dist/color-input/root/color-input-root.d.ts +60 -2
- package/dist/color-input/root/color-input-root.js +55 -7
- package/dist/color-picker/channels.d.ts +26 -0
- package/dist/color-picker/channels.js +84 -0
- package/dist/color-picker/root/color-picker-root.d.ts +118 -12
- package/dist/color-picker/root/color-picker-root.js +183 -13
- package/dist/combobox/root/combobox-root.d.ts +126 -3
- package/dist/combobox/root/combobox-root.js +224 -21
- package/dist/command/root/command-root.d.ts +47 -10
- package/dist/command/root/command-root.js +45 -4
- package/dist/copy-button/from.d.ts +22 -0
- package/dist/copy-button/from.js +28 -0
- package/dist/copy-button/root/copy-button-root.d.ts +48 -7
- package/dist/copy-button/root/copy-button-root.js +54 -8
- package/dist/data-table/root/data-table-root.d.ts +164 -10
- package/dist/data-table/root/data-table-root.js +488 -57
- package/dist/date-input/root/date-input-root.d.ts +123 -9
- package/dist/date-input/root/date-input-root.js +147 -45
- package/dist/date-picker/root/date-picker-root.d.ts +229 -18
- package/dist/date-picker/root/date-picker-root.js +342 -46
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +101 -10
- package/dist/dialog/root/dialog-root.js +83 -4
- package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
- package/dist/donut-chart/root/donut-chart-root.js +48 -13
- package/dist/drawer/root/drawer-root.d.ts +93 -7
- package/dist/drawer/root/drawer-root.js +126 -5
- package/dist/drawer/swipe-start.d.ts +9 -0
- package/dist/drawer/swipe-start.js +12 -0
- package/dist/drilldown/item/drilldown-item.d.ts +16 -13
- package/dist/drilldown/item/drilldown-item.js +6 -2
- package/dist/drilldown/root/drilldown-root.d.ts +21 -5
- package/dist/drilldown/root/drilldown-root.js +26 -10
- package/dist/element-events.generated.js +42 -13
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +65 -1
- package/dist/file-input/root/file-input-root.js +76 -12
- package/dist/file-input/screen.d.ts +35 -0
- package/dist/file-input/screen.js +49 -0
- package/dist/filter-input/menu/filter-menu.d.ts +9 -0
- package/dist/filter-input/menu/filter-menu.js +8 -0
- package/dist/filter-input/root/filter-input-root.d.ts +43 -6
- package/dist/filter-input/root/filter-input-root.js +89 -10
- package/dist/filter-input/suggest.d.ts +17 -0
- package/dist/filter-input/suggest.js +23 -0
- package/dist/format-date/options.d.ts +33 -0
- package/dist/format-date/options.js +42 -0
- package/dist/format-date/root/format-date-root.d.ts +62 -3
- package/dist/format-date/root/format-date-root.js +78 -37
- package/dist/graph/root/graph-root.d.ts +24 -3
- package/dist/graph/root/graph-root.js +66 -12
- package/dist/heatmap/root/buckets.d.ts +2 -1
- package/dist/heatmap/root/buckets.js +5 -1
- package/dist/heatmap/root/heatmap-root.d.ts +47 -9
- package/dist/heatmap/root/heatmap-root.js +46 -18
- package/dist/icon/index.d.ts +2 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon/registry.d.ts +37 -0
- package/dist/icon/registry.js +83 -0
- package/dist/icon/root/icon-root.d.ts +53 -6
- package/dist/icon/root/icon-root.js +72 -4
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon/set.d.ts +1 -0
- package/dist/icon/set.js +3 -0
- package/dist/icon-button/root/icon-button-root.d.ts +1 -1
- package/dist/image/root/image-root.d.ts +23 -2
- package/dist/image/root/image-root.js +23 -4
- package/dist/input/root/input-root.d.ts +62 -9
- package/dist/input/root/input-root.js +61 -5
- package/dist/kbd/root/kbd-root.d.ts +26 -11
- package/dist/kbd/root/kbd-root.js +35 -38
- package/dist/kbd/shortcut.d.ts +18 -0
- package/dist/kbd/shortcut.js +35 -0
- package/dist/legend/hidden-series.d.ts +8 -0
- package/dist/legend/hidden-series.js +13 -0
- package/dist/legend/root/legend-root.d.ts +63 -0
- package/dist/legend/root/legend-root.js +61 -7
- package/dist/lightbox/item/lightbox-item.d.ts +17 -1
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +77 -6
- package/dist/lightbox/root/lightbox-root.js +116 -5
- package/dist/line-chart/root/line-chart-root.d.ts +29 -4
- package/dist/line-chart/root/line-chart-root.js +58 -17
- package/dist/list/item/list-item.d.ts +11 -5
- package/dist/list/item/list-item.js +5 -6
- package/dist/listbox/range.d.ts +17 -0
- package/dist/listbox/range.js +5 -0
- package/dist/listbox/root/listbox-root.d.ts +184 -4
- package/dist/listbox/root/listbox-root.js +229 -23
- package/dist/loader/busy.d.ts +17 -0
- package/dist/loader/busy.js +24 -0
- package/dist/loader/root/loader-root.d.ts +37 -0
- package/dist/loader/root/loader-root.js +52 -3
- package/dist/map/root/map-root.d.ts +19 -4
- package/dist/map/root/map-root.js +36 -7
- package/dist/megamenu/root/megamenu-root.d.ts +10 -1
- package/dist/megamenu/root/megamenu-root.js +10 -1
- package/dist/menu/item/menu-item.d.ts +41 -12
- package/dist/menu/item/menu-item.js +46 -3
- package/dist/menu/root/menu-root.d.ts +32 -2
- package/dist/menu/root/menu-root.js +48 -8
- package/dist/meter/root/meter-root.d.ts +13 -0
- package/dist/meter/root/meter-root.js +24 -5
- package/dist/navigation/root/navigation-root.d.ts +10 -2
- package/dist/navigation/root/navigation-root.js +13 -2
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/group/notification-group.d.ts +1 -0
- package/dist/notifications/notification/notification.d.ts +29 -0
- package/dist/notifications/notification/notification.js +51 -3
- package/dist/notifications/root/notifications-root.d.ts +49 -0
- package/dist/notifications/root/notifications-root.js +76 -2
- package/dist/number-input/root/number-input-root.d.ts +109 -7
- package/dist/number-input/root/number-input-root.js +109 -21
- package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
- package/dist/object-inspector/root/object-inspector-root.js +92 -12
- package/dist/option/root/option-root.d.ts +58 -6
- package/dist/option/root/option-root.js +35 -5
- package/dist/outline/root/outline-root.d.ts +13 -2
- package/dist/outline/root/outline-root.js +4 -2
- package/dist/pagination/root/pagination-root.d.ts +19 -1
- package/dist/pagination/root/pagination-root.js +49 -9
- package/dist/pagination/size/pagination-size.d.ts +13 -3
- package/dist/pagination/size/pagination-size.js +7 -0
- package/dist/pin-input/format.d.ts +7 -0
- package/dist/pin-input/format.js +16 -0
- package/dist/pin-input/root/pin-input-root.d.ts +37 -0
- package/dist/pin-input/root/pin-input-root.js +48 -7
- package/dist/popover/root/popover-root.d.ts +78 -3
- package/dist/popover/root/popover-root.js +74 -5
- package/dist/progress/root/progress-root.d.ts +23 -1
- package/dist/progress/root/progress-root.js +40 -10
- package/dist/qr-code/export.d.ts +31 -0
- package/dist/qr-code/export.js +10 -0
- package/dist/qr-code/root/qr-code-root.d.ts +45 -0
- package/dist/qr-code/root/qr-code-root.js +78 -3
- package/dist/radio/group/radio-group.d.ts +64 -0
- package/dist/radio/group/radio-group.js +66 -12
- package/dist/radio/root/radio-root.d.ts +8 -5
- package/dist/radio/root/radio-root.js +1 -2
- package/dist/rating/root/rating-root.d.ts +49 -1
- package/dist/rating/root/rating-root.js +69 -10
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
- package/dist/select/root/select-root.d.ts +93 -3
- package/dist/select/root/select-root.js +111 -13
- package/dist/skeleton/root/skeleton-root.d.ts +39 -3
- package/dist/skeleton/root/skeleton-root.js +33 -4
- package/dist/skip-link/root/skip-link-root.d.ts +10 -0
- package/dist/skip-link/root/skip-link-root.js +15 -1
- package/dist/slider/root/slider-root.d.ts +59 -2
- package/dist/slider/root/slider-root.js +82 -8
- package/dist/sparkline/root/sparkline-root.d.ts +9 -10
- package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
- package/dist/speed-dial/item/speed-dial-item.js +7 -2
- package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
- package/dist/speed-dial/root/speed-dial-root.js +19 -5
- package/dist/splitter/root/splitter-root.d.ts +28 -6
- package/dist/splitter/root/splitter-root.js +35 -1
- package/dist/stat/root/stat-root.d.ts +9 -1
- package/dist/stat/root/stat-root.js +15 -2
- package/dist/steps/root/steps-root.js +1 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/switch/root/switch-root.d.ts +14 -2
- package/dist/switch/root/switch-root.js +7 -1
- package/dist/table/cell/table-cell.d.ts +24 -4
- package/dist/table/cell/table-cell.js +21 -1
- package/dist/table/column/table-column.d.ts +32 -6
- package/dist/table/column/table-column.js +36 -6
- package/dist/table/root/table-root.d.ts +94 -3
- package/dist/table/root/table-root.js +128 -5
- package/dist/table/row/table-row.d.ts +7 -0
- package/dist/table/row/table-row.js +9 -1
- package/dist/tabs/root/tabs-root.d.ts +6 -1
- package/dist/tabs/root/tabs-root.js +6 -2
- package/dist/tag/group/tag-group.d.ts +107 -0
- package/dist/tag/group/tag-group.js +157 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +83 -1
- package/dist/tag/root/tag-root.js +87 -17
- package/dist/tag/selection.d.ts +10 -0
- package/dist/tag/selection.js +12 -0
- package/dist/textarea/grow.d.ts +22 -0
- package/dist/textarea/grow.js +20 -0
- package/dist/textarea/root/textarea-root.d.ts +13 -0
- package/dist/textarea/root/textarea-root.js +10 -2
- package/dist/time-input/root/time-input-root.d.ts +71 -6
- package/dist/time-input/root/time-input-root.js +110 -44
- package/dist/time-picker/root/time-picker-root.d.ts +155 -26
- package/dist/time-picker/root/time-picker-root.js +192 -63
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +16 -1
- package/dist/toast/item/toast-item.js +41 -13
- package/dist/toast/root/toast-root.d.ts +105 -8
- package/dist/toast/root/toast-root.js +209 -4
- package/dist/toggle/group/toggle-group.d.ts +95 -16
- package/dist/toggle/group/toggle-group.js +99 -13
- package/dist/toggle/root/toggle-root.d.ts +26 -11
- package/dist/toggle/root/toggle-root.js +14 -6
- package/dist/toolbar/root/toolbar-root.d.ts +55 -15
- package/dist/toolbar/root/toolbar-root.js +99 -16
- package/dist/tooltip/focus-target.d.ts +6 -0
- package/dist/tooltip/focus-target.js +9 -0
- package/dist/tooltip/root/tooltip-root.d.ts +73 -15
- package/dist/tooltip/root/tooltip-root.js +96 -7
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +67 -3
- package/dist/tour/root/tour-root.js +105 -17
- package/dist/tour/stop/tour-stop.d.ts +65 -3
- package/dist/tour/stop/tour-stop.js +61 -11
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/tree/item/tree-item.d.ts +21 -5
- package/dist/tree/item/tree-item.js +14 -4
- package/dist/tree/root/tree-root.d.ts +29 -5
- package/dist/tree/root/tree-root.js +64 -8
- package/dist/trend/root/trend-root.d.ts +36 -1
- package/dist/trend/root/trend-root.js +41 -15
- package/dist/video/root/keys.d.ts +5 -0
- package/dist/video/root/keys.js +13 -1
- package/dist/video/root/video-root.d.ts +19 -0
- package/dist/video/root/video-root.js +48 -4
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
- package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
- package/dist/video-playlist/root/video-playlist-root.js +6 -3
- package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
- package/dist/virtual-list/root/virtual-list-root.js +103 -21
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +9140 -1149
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +2089 -267
|
@@ -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, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerField, parseColor, toCss, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, colorName, customElement, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerField, parseColor, toCss, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
@@ -17,8 +17,12 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
17
17
|
});
|
|
18
18
|
this.alpha = false;
|
|
19
19
|
this.autocomplete = 'off';
|
|
20
|
+
this.channelFields = false;
|
|
21
|
+
this.colorWords = {};
|
|
20
22
|
this.noFormat = false;
|
|
21
23
|
this.placeholder = '#000000';
|
|
24
|
+
this.readOnly = false;
|
|
25
|
+
this.announcesInput = true;
|
|
22
26
|
this.swatches = '';
|
|
23
27
|
this.triggerLabel = 'Choose a color';
|
|
24
28
|
this.settled = '';
|
|
@@ -32,9 +36,17 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
32
36
|
if (event.composedPath()[0] !== event.currentTarget) {
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
35
|
-
this.requestValue(event.detail.value)
|
|
39
|
+
if (!this.requestValue(event.detail.value)) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
}
|
|
36
42
|
this.restore();
|
|
37
43
|
};
|
|
44
|
+
this.handlePickerSettled = (event) => {
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
if (event.composedPath()[0] === event.currentTarget) {
|
|
47
|
+
this.announceChange();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
38
50
|
this.handleSampleStart = () => {
|
|
39
51
|
this.requestOpen(false);
|
|
40
52
|
};
|
|
@@ -42,12 +54,31 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
42
54
|
this.requestOpen(true);
|
|
43
55
|
};
|
|
44
56
|
}
|
|
57
|
+
requestValue(next) {
|
|
58
|
+
if (this.readOnly) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return super.requestValue(next);
|
|
62
|
+
}
|
|
63
|
+
requestOpen(next) {
|
|
64
|
+
if (next && this.readOnly) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return super.requestOpen(next);
|
|
68
|
+
}
|
|
45
69
|
get anchor() {
|
|
46
70
|
return this.control ?? this.partNamed('trigger');
|
|
47
71
|
}
|
|
48
72
|
get picked() {
|
|
49
73
|
return parseColor(this.value) ? this.value : this.settled;
|
|
50
74
|
}
|
|
75
|
+
get swatchWords() {
|
|
76
|
+
const parsed = parseColor(this.value);
|
|
77
|
+
if (!parsed) {
|
|
78
|
+
return this.value || this.triggerLabel;
|
|
79
|
+
}
|
|
80
|
+
return `${colorName(parsed, this.colorWords, this.lang)} ${this.value}`;
|
|
81
|
+
}
|
|
51
82
|
get painted() {
|
|
52
83
|
const parsed = parseColor(this.value);
|
|
53
84
|
return parsed ? toCss(parsed) : 'transparent';
|
|
@@ -85,21 +116,25 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
85
116
|
channel-marker: picker-channel-marker, channel-marker-label: picker-channel-marker-label,
|
|
86
117
|
channel-markers: picker-channel-markers, channel-output: picker-channel-output,
|
|
87
118
|
channels: picker-channels, controls: picker-controls, eyedropper: picker-eyedropper,
|
|
88
|
-
eyedropper-button: picker-eyedropper-button, eyedropper-
|
|
89
|
-
|
|
119
|
+
eyedropper-button: picker-eyedropper-button, eyedropper-live: picker-eyedropper-live, eyedropper-text: picker-eyedropper-text,
|
|
120
|
+
field: picker-field, field-input: picker-field-input, field-label: picker-field-label,
|
|
121
|
+
fields: picker-fields, footer: picker-footer, format: picker-format,
|
|
122
|
+
format-button: picker-format-button, format-live: picker-format-live, format-text: picker-format-text, grid: picker-grid,
|
|
90
123
|
grid-brightness: picker-grid-brightness, grid-handle: picker-grid-handle,
|
|
91
124
|
grid-saturation: picker-grid-saturation, icon: picker-icon, sample: picker-sample,
|
|
92
125
|
swatch: picker-swatch, swatches: picker-swatches, value: picker-value"
|
|
93
126
|
?invalid=${this.resolvedFeedback !== ''}
|
|
94
127
|
?alpha=${this.alpha}
|
|
128
|
+
?channel-fields=${this.channelFields}
|
|
95
129
|
?no-format=${this.noFormat}
|
|
96
130
|
?no-value=${this.variant !== 'swatch'}
|
|
131
|
+
.colorWords=${this.colorWords}
|
|
97
132
|
.format=${this.format ?? 'hex'}
|
|
98
133
|
.value=${this.picked}
|
|
99
134
|
swatches=${this.swatches || nothing}
|
|
100
135
|
?disabled=${this.isDisabled}
|
|
101
136
|
@helix-before-change=${this.handlePickerChange}
|
|
102
|
-
@change=${this.
|
|
137
|
+
@change=${this.handlePickerSettled}
|
|
103
138
|
@input=${this.stopInner}
|
|
104
139
|
@helix-sample-start=${this.handleSampleStart}
|
|
105
140
|
@helix-sample-end=${this.handleSampleEnd}
|
|
@@ -130,8 +165,11 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
130
165
|
aria-describedby=${this.describedBy ?? nothing}
|
|
131
166
|
aria-invalid=${this.invalidity ?? nothing}
|
|
132
167
|
?disabled=${this.isDisabled}
|
|
168
|
+
?readonly=${this.readOnly}
|
|
133
169
|
?required=${this.required}
|
|
170
|
+
@change=${this.handleCommit}
|
|
134
171
|
@input=${this.handleInput}
|
|
172
|
+
@keypress=${this.handleKeypress}
|
|
135
173
|
/>`}
|
|
136
174
|
<slot name="end"></slot>
|
|
137
175
|
<button
|
|
@@ -139,6 +177,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
139
177
|
id=${this.variant === 'swatch' ? 'control' : nothing}
|
|
140
178
|
type="button"
|
|
141
179
|
aria-controls="surface"
|
|
180
|
+
aria-disabled=${this.readOnly ? 'true' : nothing}
|
|
142
181
|
aria-expanded=${this.open ? 'true' : 'false'}
|
|
143
182
|
aria-haspopup="dialog"
|
|
144
183
|
aria-label=${this.variant === 'swatch' ? nothing : this.triggerLabel}
|
|
@@ -148,7 +187,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
148
187
|
: 'swatch-value'
|
|
149
188
|
: nothing}
|
|
150
189
|
?disabled=${this.isDisabled}
|
|
151
|
-
@click=${
|
|
190
|
+
@click=${this.handleTriggerClick}
|
|
152
191
|
>
|
|
153
192
|
<span
|
|
154
193
|
part="preview"
|
|
@@ -156,7 +195,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
|
|
|
156
195
|
></span>
|
|
157
196
|
<slot name="trigger"></slot>
|
|
158
197
|
${this.variant === 'swatch'
|
|
159
|
-
? html `<span id="swatch-value" hidden>${this.
|
|
198
|
+
? html `<span id="swatch-value" hidden>${this.swatchWords}</span>`
|
|
160
199
|
: nothing}
|
|
161
200
|
</button>
|
|
162
201
|
</div>
|
|
@@ -181,6 +220,12 @@ __decorate([
|
|
|
181
220
|
__decorate([
|
|
182
221
|
property()
|
|
183
222
|
], HelixHeadlessColorInput.prototype, "autocomplete", void 0);
|
|
223
|
+
__decorate([
|
|
224
|
+
property({ attribute: 'channel-fields', type: Boolean })
|
|
225
|
+
], HelixHeadlessColorInput.prototype, "channelFields", void 0);
|
|
226
|
+
__decorate([
|
|
227
|
+
property({ attribute: 'color-words', type: Object })
|
|
228
|
+
], HelixHeadlessColorInput.prototype, "colorWords", void 0);
|
|
184
229
|
__decorate([
|
|
185
230
|
property({ reflect: true })
|
|
186
231
|
], HelixHeadlessColorInput.prototype, "format", void 0);
|
|
@@ -190,6 +235,9 @@ __decorate([
|
|
|
190
235
|
__decorate([
|
|
191
236
|
property()
|
|
192
237
|
], HelixHeadlessColorInput.prototype, "placeholder", void 0);
|
|
238
|
+
__decorate([
|
|
239
|
+
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
240
|
+
], HelixHeadlessColorInput.prototype, "readOnly", void 0);
|
|
193
241
|
__decorate([
|
|
194
242
|
property()
|
|
195
243
|
], HelixHeadlessColorInput.prototype, "swatches", void 0);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Color, type ColorFormat } from '@fusion.dev/helix-core';
|
|
2
|
+
/** One number a color is written with, in the syntax the picker writes. */
|
|
3
|
+
export type ChannelName = 'alpha' | 'blue' | 'green' | 'hue' | 'lightness' | 'red' | 'saturation';
|
|
4
|
+
/** A channel as a field shows it: its number and the range it may take. */
|
|
5
|
+
export interface ChannelField {
|
|
6
|
+
channel: ChannelName;
|
|
7
|
+
max: number;
|
|
8
|
+
min: number;
|
|
9
|
+
value: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The numbers a color is written with in `format`, for a field each, as React
|
|
13
|
+
* Aria's ColorField takes a `channel`: red, green and blue for hex and rgb,
|
|
14
|
+
* hue, saturation and lightness for hsl, and the opacity where the picker
|
|
15
|
+
* carries one.
|
|
16
|
+
*
|
|
17
|
+
* Hex is written as bytes, so its fields are the bytes: a field of two hex
|
|
18
|
+
* digits would ask a reader to count in base sixteen.
|
|
19
|
+
*/
|
|
20
|
+
export declare const channelFields: (value: string, color: Color, format: ColorFormat, alpha: boolean) => ChannelField[];
|
|
21
|
+
/**
|
|
22
|
+
* The value with one channel set, kept inside the channel's range and written
|
|
23
|
+
* in `format` the way the picker writes every value: the comma form, and the
|
|
24
|
+
* opacity only with `alpha`. `null` where the number is no number.
|
|
25
|
+
*/
|
|
26
|
+
export declare const writeChannel: (fields: readonly ChannelField[], format: ColorFormat, alpha: boolean, channel: ChannelName, value: number) => string | null;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { toHsl, toRgb } from '@fusion.dev/helix-core';
|
|
2
|
+
const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
|
|
3
|
+
const percent = (token) => {
|
|
4
|
+
if (token === undefined) {
|
|
5
|
+
return 100;
|
|
6
|
+
}
|
|
7
|
+
const number = Number.parseFloat(token);
|
|
8
|
+
return Number.isNaN(number) ? 100 : clamp(token.includes('%') ? number : number * 100, 0, 100);
|
|
9
|
+
};
|
|
10
|
+
const readWritten = (value, format) => {
|
|
11
|
+
const text = value.trim().toLowerCase();
|
|
12
|
+
if (format !== 'hsl' && /^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/.test(text)) {
|
|
13
|
+
const digits = text.slice(1);
|
|
14
|
+
const width = digits.length <= 4 ? 1 : 2;
|
|
15
|
+
const byte = (index) => {
|
|
16
|
+
const piece = digits.slice(index * width, index * width + width);
|
|
17
|
+
return Number.parseInt(width === 1 ? piece + piece : piece, 16);
|
|
18
|
+
};
|
|
19
|
+
const count = digits.length / width;
|
|
20
|
+
return [byte(0), byte(1), byte(2), count === 4 ? Math.round((byte(3) / 255) * 100) : 100];
|
|
21
|
+
}
|
|
22
|
+
const call = /^(rgba?|hsla?)\(([^)]*)\)$/.exec(text);
|
|
23
|
+
if (!call?.[1] || call[2] === undefined) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (call[1].startsWith('hsl') !== (format === 'hsl')) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const [first, second, third, fourth] = call[2].replace(/[,/]/g, ' ').split(/\s+/).filter(Boolean);
|
|
30
|
+
const numbers = [first, second, third].map((one) => Number.parseFloat(one ?? ''));
|
|
31
|
+
if (numbers.some(Number.isNaN)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return [...numbers, percent(fourth)].map((one) => Math.round(one));
|
|
35
|
+
};
|
|
36
|
+
export const channelFields = (value, color, format, alpha) => {
|
|
37
|
+
const written = readWritten(value, format);
|
|
38
|
+
const fromModel = () => {
|
|
39
|
+
if (format === 'hsl') {
|
|
40
|
+
const { hue, lightness, saturation } = toHsl(color);
|
|
41
|
+
return [Math.round(hue), saturation, lightness, Math.round(color.alpha)];
|
|
42
|
+
}
|
|
43
|
+
const { blue, green, red } = toRgb(color);
|
|
44
|
+
return [red, green, blue, Math.round(color.alpha)];
|
|
45
|
+
};
|
|
46
|
+
const [one = 0, two = 0, three = 0, four = 100] = written ?? fromModel();
|
|
47
|
+
const fields = format === 'hsl'
|
|
48
|
+
? [
|
|
49
|
+
{ channel: 'hue', max: 360, min: 0, value: one },
|
|
50
|
+
{ channel: 'saturation', max: 100, min: 0, value: two },
|
|
51
|
+
{ channel: 'lightness', max: 100, min: 0, value: three },
|
|
52
|
+
]
|
|
53
|
+
: [
|
|
54
|
+
{ channel: 'red', max: 255, min: 0, value: one },
|
|
55
|
+
{ channel: 'green', max: 255, min: 0, value: two },
|
|
56
|
+
{ channel: 'blue', max: 255, min: 0, value: three },
|
|
57
|
+
];
|
|
58
|
+
return alpha ? [...fields, { channel: 'alpha', max: 100, min: 0, value: four }] : fields;
|
|
59
|
+
};
|
|
60
|
+
export const writeChannel = (fields, format, alpha, channel, value) => {
|
|
61
|
+
if (Number.isNaN(value)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const numbers = new Map(fields.map((field) => [field.channel, field.value]));
|
|
65
|
+
const field = fields.find((one) => one.channel === channel);
|
|
66
|
+
if (field === undefined) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
numbers.set(channel, clamp(Math.round(value), field.min, field.max));
|
|
70
|
+
const get = (name, fallback = 0) => numbers.get(name) ?? fallback;
|
|
71
|
+
const opacity = get('alpha', 100);
|
|
72
|
+
const fraction = Number((opacity / 100).toFixed(2));
|
|
73
|
+
if (format === 'hsl') {
|
|
74
|
+
const body = `${get('hue')}, ${get('saturation')}%, ${get('lightness')}%`;
|
|
75
|
+
return alpha ? `hsla(${body}, ${fraction})` : `hsl(${body})`;
|
|
76
|
+
}
|
|
77
|
+
if (format === 'rgb') {
|
|
78
|
+
const body = `${get('red')}, ${get('green')}, ${get('blue')}`;
|
|
79
|
+
return alpha ? `rgba(${body}, ${fraction})` : `rgb(${body})`;
|
|
80
|
+
}
|
|
81
|
+
const byte = (one) => one.toString(16).padStart(2, '0');
|
|
82
|
+
const hex = `#${byte(get('red'))}${byte(get('green'))}${byte(get('blue'))}`;
|
|
83
|
+
return alpha ? hex + byte(Math.round((opacity / 100) * 255)) : hex;
|
|
84
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Color, type ColorFormat, HelixFormElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { type Color, type ColorFormat, type ColorWords, HelixFormElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../button/index.js';
|
|
4
4
|
import '../../button-group/index.js';
|
|
@@ -21,6 +21,17 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
|
|
|
21
21
|
* hue or saturation, so a model read back from the value would turn red into
|
|
22
22
|
* gray after you drag to the bottom of the square and back.
|
|
23
23
|
*
|
|
24
|
+
* The square is one tab stop. In it, the up and down arrows move brightness
|
|
25
|
+
* and the left and right arrows move saturation, and PageUp and PageDown move
|
|
26
|
+
* brightness by ten. The picker sends `input` as the color moves and `change`
|
|
27
|
+
* when a drag, a key, a typed value or a preset settles it, as
|
|
28
|
+
* `<input type="color">` does.
|
|
29
|
+
*
|
|
30
|
+
* A screen reader hears the color's name, such as "vibrant red", after the two
|
|
31
|
+
* numbers on the square and after the number on the hue ramp, and each preset
|
|
32
|
+
* is named by its color. Set `color-words` to speak the names in another
|
|
33
|
+
* language.
|
|
34
|
+
*
|
|
24
35
|
* @since 0.1.0
|
|
25
36
|
* @status stable
|
|
26
37
|
* @category forms
|
|
@@ -51,11 +62,17 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
|
|
|
51
62
|
* @csspart controls - The row under the square.
|
|
52
63
|
* @csspart eyedropper - The control that samples a color from the screen.
|
|
53
64
|
* @csspart eyedropper-button - The button inside `eyedropper`.
|
|
54
|
-
* @csspart eyedropper-
|
|
65
|
+
* @csspart eyedropper-live - The live region of the button inside `eyedropper`, which says its pending label.
|
|
66
|
+
* @csspart eyedropper-text - The words on the button inside `eyedropper`, trimmed to their capitals and baseline.
|
|
67
|
+
* @csspart field - One channel's number field with its label, in `channel-fields`.
|
|
68
|
+
* @csspart field-input - The number input in a channel's field.
|
|
69
|
+
* @csspart field-label - The name above a channel's number input.
|
|
70
|
+
* @csspart fields - The row of channel number fields, in `channel-fields`.
|
|
55
71
|
* @csspart footer - The row holding the value and the tools.
|
|
56
72
|
* @csspart format - The control that changes the syntax the value is written in.
|
|
57
73
|
* @csspart format-button - The button inside `format`.
|
|
58
|
-
* @csspart format-
|
|
74
|
+
* @csspart format-live - The live region of the button inside `format`, which says its pending label.
|
|
75
|
+
* @csspart format-text - The words on the button inside `format`, trimmed to their capitals and baseline.
|
|
59
76
|
* @csspart grid - The saturation and brightness square. Draw the mark that shows
|
|
60
77
|
* where the color sits with `::part(grid)::after` in your stylesheet. The
|
|
61
78
|
* square carries the two channels as `--color-picker-saturation` and
|
|
@@ -89,6 +106,14 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
89
106
|
* ramps. A consumer who wants autofill can still ask.
|
|
90
107
|
*/
|
|
91
108
|
autocomplete: string;
|
|
109
|
+
/**
|
|
110
|
+
* The message shown when the value is text that is not a color.
|
|
111
|
+
*/
|
|
112
|
+
badInputMessage?: string;
|
|
113
|
+
/**
|
|
114
|
+
* What the blue channel's field is called, in `channel-fields`.
|
|
115
|
+
*/
|
|
116
|
+
blueLabel: string;
|
|
92
117
|
/**
|
|
93
118
|
* What the square's vertical ramp is called.
|
|
94
119
|
*
|
|
@@ -96,6 +121,32 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
96
121
|
* language hears its own rather than English between its own labels.
|
|
97
122
|
*/
|
|
98
123
|
brightnessLabel: string;
|
|
124
|
+
/**
|
|
125
|
+
* Whether the picker shows a number field for each channel of the color, as
|
|
126
|
+
* React Aria's ColorField does with `channel`: red, green and blue for hex
|
|
127
|
+
* and rgb, hue, saturation and lightness for hsl, and the opacity with
|
|
128
|
+
* `alpha`.
|
|
129
|
+
*
|
|
130
|
+
* For a reader who has the numbers from a brand guide, and for a keyboard,
|
|
131
|
+
* where typing 128 is quicker than holding an arrow key. The fields follow
|
|
132
|
+
* the syntax the format toggle sets.
|
|
133
|
+
*/
|
|
134
|
+
channelFields: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* The words a color's name is spoken in, as JSON keyed by their English,
|
|
137
|
+
* such as `{"red": "rot", "vibrant": "kräftiges"}`.
|
|
138
|
+
*
|
|
139
|
+
* **A color is named the way React Aria names one**, as "vibrant red" or
|
|
140
|
+
* "dark grayish blue", and the keys are the ones `@react-stately/color`
|
|
141
|
+
* translates, so a table a page already has for it can be handed over whole.
|
|
142
|
+
* `colorName` and `transparentColorName` are the two sentences that put the
|
|
143
|
+
* words together. A word left out is spoken in English.
|
|
144
|
+
*
|
|
145
|
+
* The name follows the numbers on the square, follows the number on the hue
|
|
146
|
+
* ramp, and names each preset, so a reader who cannot see the color hears
|
|
147
|
+
* which one it is.
|
|
148
|
+
*/
|
|
149
|
+
colorWords: Partial<ColorWords>;
|
|
99
150
|
/**
|
|
100
151
|
* The text the sample shows for a moment after it copies the value.
|
|
101
152
|
*/
|
|
@@ -120,6 +171,10 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
120
171
|
* What the syntax toggle is called, with `{format}` filled in.
|
|
121
172
|
*/
|
|
122
173
|
formatLabel: string;
|
|
174
|
+
/**
|
|
175
|
+
* What the green channel's field is called, in `channel-fields`.
|
|
176
|
+
*/
|
|
177
|
+
greenLabel: string;
|
|
123
178
|
/**
|
|
124
179
|
* What the hue channel is called.
|
|
125
180
|
*/
|
|
@@ -134,6 +189,11 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
134
189
|
* thing the field cannot draw from outside, the mark on the answer itself.
|
|
135
190
|
*/
|
|
136
191
|
invalid: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* What the lightness channel's field is called, in `channel-fields` with
|
|
194
|
+
* hsl.
|
|
195
|
+
*/
|
|
196
|
+
lightnessLabel: string;
|
|
137
197
|
/**
|
|
138
198
|
* Hides the eyedropper. Without it, the eyedropper appears in browsers that
|
|
139
199
|
* support one.
|
|
@@ -194,6 +254,10 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
194
254
|
* letting it open would take a color from the reader and drop it.
|
|
195
255
|
*/
|
|
196
256
|
readOnly: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* What the red channel's field is called, in `channel-fields`.
|
|
259
|
+
*/
|
|
260
|
+
redLabel: string;
|
|
197
261
|
/**
|
|
198
262
|
* Requires a color before the form can submit.
|
|
199
263
|
*
|
|
@@ -210,13 +274,11 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
210
274
|
* would give one control two of each. What is left is the validity call and
|
|
211
275
|
* the anchor the browser points its bubble at.
|
|
212
276
|
*
|
|
213
|
-
* **
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* reports it for this family instead, once, against the field the reader
|
|
219
|
-
* typed into.
|
|
277
|
+
* **Text that is not a color is bad input**, so a form does not submit
|
|
278
|
+
* `#00` from a half-typed value. The picker draws no message of its own, so
|
|
279
|
+
* reporting it as each keystroke arrives shows nothing until the form asks;
|
|
280
|
+
* Color Input shows its own message against the field the reader typed
|
|
281
|
+
* into.
|
|
220
282
|
*/
|
|
221
283
|
required: boolean;
|
|
222
284
|
/**
|
|
@@ -268,6 +330,18 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
268
330
|
* which reads back as hue 0 and saturation 0, and the next drag starts gray.
|
|
269
331
|
*/
|
|
270
332
|
private owned;
|
|
333
|
+
/** Dragged and keyed, so a move is announced as `input` alone. See `announcesInput`. */
|
|
334
|
+
protected readonly announcesInput = true;
|
|
335
|
+
/** Whether the value has moved since `change` was last sent. */
|
|
336
|
+
private unsettled;
|
|
337
|
+
/**
|
|
338
|
+
* Sends `change` for a value that has settled, where it moved.
|
|
339
|
+
*
|
|
340
|
+
* Measured before this: a six-step drag sent six `change` events, so a
|
|
341
|
+
* consumer saving on `change`, as they would for `<input type="color">`,
|
|
342
|
+
* saved on every frame.
|
|
343
|
+
*/
|
|
344
|
+
private settle;
|
|
271
345
|
/** The current color: the last one moved to, the value, or the start color. */
|
|
272
346
|
get color(): Color;
|
|
273
347
|
/**
|
|
@@ -365,6 +439,16 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
365
439
|
* `required`.
|
|
366
440
|
*/
|
|
367
441
|
private sync;
|
|
442
|
+
/**
|
|
443
|
+
* Moves the square from the keyboard, both axes from either of its inputs.
|
|
444
|
+
*
|
|
445
|
+
* The square is two native ranges, and a native range maps every arrow to
|
|
446
|
+
* its own one axis: on the saturation input, ArrowUp moved the handle
|
|
447
|
+
* sideways. Here the vertical keys move brightness and the horizontal keys
|
|
448
|
+
* move saturation, turned on a right-to-left page as the pointer is, which is
|
|
449
|
+
* what React Aria's ColorArea does.
|
|
450
|
+
*/
|
|
451
|
+
private readonly handleAreaKeydown;
|
|
368
452
|
/**
|
|
369
453
|
* Reports "required and empty", or clears it.
|
|
370
454
|
*
|
|
@@ -377,13 +461,35 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
377
461
|
protected updated(changed: import('lit').PropertyValues): void;
|
|
378
462
|
/** Moves focus to the square. */
|
|
379
463
|
focus(options?: FocusOptions): void;
|
|
464
|
+
/** What each channel's field is called, from the words a page gives. */
|
|
465
|
+
private channelWord;
|
|
466
|
+
/**
|
|
467
|
+
* Takes a number typed into a channel's field. A field emptied or holding
|
|
468
|
+
* something that is not a number moves nothing, so a reader can clear it to
|
|
469
|
+
* type afresh.
|
|
470
|
+
*/
|
|
471
|
+
private readonly handleField;
|
|
472
|
+
/**
|
|
473
|
+
* Takes a value written out whole, as `move` takes a part of the model: the
|
|
474
|
+
* square follows it, keeping its hue where the value is a gray with none to
|
|
475
|
+
* give, and a refusal puts the square back.
|
|
476
|
+
*/
|
|
477
|
+
private takeWritten;
|
|
478
|
+
/**
|
|
479
|
+
* A number field for each channel, behind a seam the styled tier can move.
|
|
480
|
+
*
|
|
481
|
+
* `live` on the value, so a number put back inside its range, 300 for a byte,
|
|
482
|
+
* is redrawn though the value it settles on is the one drawn before.
|
|
483
|
+
*/
|
|
484
|
+
protected renderFields(color: Color): TemplateResult;
|
|
380
485
|
/**
|
|
381
486
|
* One of the ramps under the square.
|
|
382
487
|
*
|
|
383
488
|
* `protected` rather than `private`, the method being the seam a tier above
|
|
384
|
-
* renders its own ramp through.
|
|
489
|
+
* renders its own ramp through. `spoken` is what a screen reader says for the
|
|
490
|
+
* ramp's value, with `{value}` filled in, and empty says the number alone.
|
|
385
491
|
*/
|
|
386
|
-
protected renderChannel(channel: 'alpha' | 'hue', label: string, max: number, value: number): TemplateResult;
|
|
492
|
+
protected renderChannel(channel: 'alpha' | 'hue', label: string, max: number, value: number, spoken?: string): TemplateResult;
|
|
387
493
|
/**
|
|
388
494
|
* A slider's own request, kept inside.
|
|
389
495
|
*
|