@fusion.dev/helix-headless 0.0.0-dev → 0.0.3
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 +4513 -4483
- package/dist/accordion/item/accordion-item.d.ts +13 -15
- package/dist/accordion/item/accordion-item.js +15 -17
- package/dist/announcement/root/announcement-root.d.ts +7 -25
- package/dist/announcement/root/announcement-root.js +7 -20
- package/dist/app-header/root/app-header-root.d.ts +10 -17
- package/dist/app-header/root/app-header-root.js +9 -18
- package/dist/avatar/group/avatar-group.d.ts +10 -19
- package/dist/avatar/group/avatar-group.js +12 -17
- package/dist/avatar/root/avatar-root.d.ts +8 -8
- package/dist/avatar/root/avatar-root.js +19 -20
- package/dist/badge/root/badge-root.d.ts +6 -6
- package/dist/badge/root/badge-root.js +13 -13
- package/dist/bar-chart/root/bar-chart-root.d.ts +21 -29
- package/dist/bar-chart/root/bar-chart-root.js +42 -57
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +12 -18
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +13 -16
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -28
- package/dist/button/root/button-root.d.ts +84 -94
- package/dist/button/root/button-root.js +82 -92
- package/dist/callout/root/callout-root.d.ts +4 -5
- package/dist/carousel/root/carousel-root.d.ts +59 -71
- package/dist/carousel/root/carousel-root.js +73 -101
- package/dist/chat/composer/chat-composer.d.ts +29 -33
- package/dist/chat/composer/chat-composer.js +40 -44
- package/dist/chat/message/chat-message.d.ts +25 -25
- package/dist/chat/message/chat-message.js +26 -26
- package/dist/chat/root/chat-root.d.ts +28 -41
- package/dist/chat/root/chat-root.js +27 -40
- package/dist/checkbox/root/checkbox-root.d.ts +10 -12
- package/dist/checkbox/root/checkbox-root.js +29 -35
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +32 -45
- package/dist/checkbox-group/root/checkbox-group-root.js +53 -79
- package/dist/code-block/root/code-block-root.d.ts +3 -4
- package/dist/code-block/root/code-block-root.js +8 -12
- package/dist/color-input/root/color-input-root.d.ts +36 -37
- package/dist/color-input/root/color-input-root.js +29 -34
- package/dist/color-picker/color.d.ts +7 -8
- package/dist/color-picker/color.js +7 -8
- package/dist/color-picker/root/color-picker-root.d.ts +55 -57
- package/dist/color-picker/root/color-picker-root.js +60 -64
- package/dist/combobox/root/combobox-root.d.ts +53 -58
- package/dist/combobox/root/combobox-root.js +85 -94
- package/dist/command/root/command-root.d.ts +8 -8
- package/dist/command/root/command-root.js +29 -33
- package/dist/copy-button/root/copy-button-root.d.ts +21 -24
- package/dist/copy-button/root/copy-button-root.js +25 -35
- package/dist/data-table/root/data-table-root.d.ts +77 -76
- package/dist/data-table/root/data-table-root.js +95 -84
- package/dist/data-table/root/order.d.ts +2 -2
- package/dist/data-table/root/order.js +1 -3
- package/dist/date-input/root/date-input-root.d.ts +88 -93
- package/dist/date-input/root/date-input-root.js +147 -158
- package/dist/date-picker/root/date-picker-root.d.ts +75 -83
- package/dist/date-picker/root/date-picker-root.js +120 -143
- package/dist/dialog/root/dialog-root.d.ts +41 -24
- package/dist/dialog/root/dialog-root.js +47 -24
- package/dist/divider/root/divider-root.d.ts +5 -6
- package/dist/divider/root/divider-root.js +4 -5
- package/dist/donut-chart/root/donut-chart-root.d.ts +22 -25
- package/dist/donut-chart/root/donut-chart-root.js +37 -51
- package/dist/drawer/root/drawer-root.d.ts +24 -29
- package/dist/drawer/root/drawer-root.js +15 -22
- package/dist/drilldown/item/drilldown-item.d.ts +14 -14
- package/dist/drilldown/item/drilldown-item.js +24 -26
- package/dist/drilldown/root/drilldown-root.d.ts +8 -10
- package/dist/drilldown/root/drilldown-root.js +6 -7
- package/dist/element-events.generated.js +1 -1
- package/dist/file-input/root/file-input-root.d.ts +20 -24
- package/dist/file-input/root/file-input-root.js +42 -57
- package/dist/format-date/root/format-date-root.js +1 -1
- package/dist/heatmap/root/buckets.d.ts +8 -8
- package/dist/heatmap/root/buckets.js +8 -8
- package/dist/heatmap/root/heatmap-root.d.ts +57 -63
- package/dist/heatmap/root/heatmap-root.js +72 -83
- package/dist/icon/root/icon-root.d.ts +4 -4
- package/dist/icon/root/icon-root.js +9 -9
- package/dist/icon-button/root/icon-button-root.d.ts +4 -6
- package/dist/icon-button/root/icon-button-root.js +4 -6
- package/dist/image/root/image-root.d.ts +49 -59
- package/dist/image/root/image-root.js +55 -65
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/input/root/input-root.d.ts +61 -85
- package/dist/input/root/input-root.js +79 -106
- package/dist/kbd/root/kbd-root.d.ts +8 -7
- package/dist/kbd/root/kbd-root.js +71 -11
- package/dist/legend/root/legend-root.d.ts +1 -1
- package/dist/legend/root/legend-root.js +4 -5
- package/dist/line-chart/root/line-chart-root.d.ts +26 -30
- package/dist/line-chart/root/line-chart-root.js +10 -10
- package/dist/list/item/list-item.d.ts +14 -18
- package/dist/list/item/list-item.js +18 -22
- package/dist/list/root/list-root.d.ts +4 -4
- package/dist/list/root/list-root.js +3 -3
- package/dist/listbox/root/listbox-root.d.ts +31 -58
- package/dist/listbox/root/listbox-root.js +66 -109
- package/dist/megamenu/root/megamenu-root.d.ts +34 -35
- package/dist/megamenu/root/megamenu-root.js +53 -58
- package/dist/menu/item/menu-item.d.ts +39 -53
- package/dist/menu/item/menu-item.js +50 -64
- package/dist/menu/root/menu-root.d.ts +30 -40
- package/dist/menu/root/menu-root.js +49 -82
- package/dist/meter/root/meter-root.d.ts +49 -53
- package/dist/meter/root/meter-root.js +22 -27
- package/dist/navigation/root/navigation-root.js +11 -19
- package/dist/notifications/notification/notification.d.ts +16 -22
- package/dist/notifications/notification/notification.js +21 -27
- package/dist/notifications/root/notifications-root.d.ts +31 -39
- package/dist/notifications/root/notifications-root.js +41 -52
- package/dist/number-input/root/number-input-root.d.ts +31 -33
- package/dist/number-input/root/number-input-root.js +37 -39
- package/dist/option/root/option-root.d.ts +73 -74
- package/dist/option/root/option-root.js +62 -64
- package/dist/outline/root/outline-root.d.ts +38 -44
- package/dist/outline/root/outline-root.js +66 -82
- package/dist/pagination/root/pagination-root.d.ts +87 -92
- package/dist/pagination/root/pagination-root.js +116 -123
- package/dist/pagination/size/pagination-size.d.ts +31 -50
- package/dist/pagination/size/pagination-size.js +35 -55
- package/dist/pagination/summary/pagination-summary.d.ts +12 -12
- package/dist/pagination/summary/pagination-summary.js +18 -18
- package/dist/pin-input/root/pin-input-root.d.ts +53 -70
- package/dist/pin-input/root/pin-input-root.js +74 -94
- package/dist/popover/root/popover-root.d.ts +15 -20
- package/dist/popover/root/popover-root.js +19 -36
- package/dist/progress/root/progress-root.d.ts +12 -14
- package/dist/progress/root/progress-root.js +22 -25
- package/dist/qr-code/root/qr-code-root.d.ts +11 -11
- package/dist/qr-code/root/qr-code-root.js +12 -14
- package/dist/radio/group/radio-group.js +19 -26
- package/dist/radio/root/radio-root.d.ts +12 -13
- package/dist/radio/root/radio-root.js +12 -13
- package/dist/rating/root/rating-root.d.ts +25 -30
- package/dist/rating/root/rating-root.js +43 -50
- package/dist/scroll-area/root/scroll-area-root.d.ts +11 -14
- package/dist/scroll-area/root/scroll-area-root.js +39 -33
- package/dist/select/root/select-root.d.ts +7 -12
- package/dist/select/root/select-root.js +40 -55
- package/dist/slider/root/slider-root.d.ts +53 -60
- package/dist/slider/root/slider-root.js +74 -85
- package/dist/sparkline/root/sparkline-root.d.ts +43 -47
- package/dist/sparkline/root/sparkline-root.js +23 -32
- package/dist/speed-dial/item/speed-dial-item.d.ts +6 -6
- package/dist/speed-dial/item/speed-dial-item.js +9 -9
- package/dist/speed-dial/root/speed-dial-root.d.ts +21 -25
- package/dist/speed-dial/root/speed-dial-root.js +32 -40
- package/dist/splitter/root/splitter-root.d.ts +98 -111
- package/dist/splitter/root/splitter-root.js +96 -123
- package/dist/stat/root/stat-root.d.ts +2 -7
- package/dist/stat/root/stat-root.js +0 -5
- package/dist/steps/step/step.d.ts +19 -24
- package/dist/steps/step/step.js +27 -32
- package/dist/switch/root/switch-root.js +2 -2
- package/dist/table/column/table-column.d.ts +54 -60
- package/dist/table/column/table-column.js +95 -68
- package/dist/table/root/table-root.d.ts +5 -6
- package/dist/table/root/table-root.js +7 -10
- package/dist/tabs/panel/tab-panel.d.ts +21 -25
- package/dist/tabs/panel/tab-panel.js +25 -29
- package/dist/tabs/root/tabs-root.d.ts +25 -34
- package/dist/tabs/root/tabs-root.js +22 -28
- package/dist/tabs/tab/tab.d.ts +12 -12
- package/dist/tabs/tab/tab.js +19 -20
- package/dist/textarea/root/textarea-root.d.ts +36 -36
- package/dist/textarea/root/textarea-root.js +43 -47
- package/dist/time-input/root/time-input-root.d.ts +58 -68
- package/dist/time-input/root/time-input-root.js +62 -77
- package/dist/time-picker/root/time-picker-root.d.ts +73 -79
- package/dist/time-picker/root/time-picker-root.js +72 -84
- package/dist/timeline/item/timeline-item.d.ts +8 -11
- package/dist/timeline/item/timeline-item.js +8 -11
- package/dist/timeline/root/timeline-root.d.ts +5 -7
- package/dist/timeline/root/timeline-root.js +5 -7
- package/dist/toast/item/toast-item.d.ts +9 -27
- package/dist/toast/item/toast-item.js +19 -41
- package/dist/toast/root/toast-root.d.ts +10 -14
- package/dist/toast/root/toast-root.js +4 -5
- package/dist/toggle/group/toggle-group.d.ts +6 -15
- package/dist/toggle/group/toggle-group.js +21 -36
- package/dist/toggle/root/toggle-root.d.ts +26 -27
- package/dist/toggle/root/toggle-root.js +30 -31
- package/dist/toolbar/root/toolbar-root.d.ts +7 -10
- package/dist/toolbar/root/toolbar-root.js +10 -14
- package/dist/tooltip/root/tooltip-root.d.ts +52 -59
- package/dist/tooltip/root/tooltip-root.js +98 -93
- package/dist/tour/root/tour-root.d.ts +19 -23
- package/dist/tour/root/tour-root.js +31 -41
- package/dist/tour/stop/tour-stop.d.ts +14 -15
- package/dist/tour/stop/tour-stop.js +31 -34
- package/dist/tree/item/tree-item.d.ts +30 -35
- package/dist/tree/item/tree-item.js +43 -55
- package/dist/tree/root/tree-root.d.ts +7 -10
- package/dist/tree/root/tree-root.js +33 -42
- package/dist/trend/root/trend-root.d.ts +3 -5
- package/dist/trend/root/trend-root.js +5 -9
- package/dist/video/root/video-root.d.ts +100 -124
- package/dist/video/root/video-root.js +142 -176
- package/dist/video-playlist/item/video-playlist-item.d.ts +16 -16
- package/dist/video-playlist/item/video-playlist-item.js +24 -24
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -8
- package/dist/video-playlist/menu/video-playlist-menu.js +20 -29
- package/dist/video-playlist/root/video-playlist-root.d.ts +16 -11
- package/dist/video-playlist/root/video-playlist-root.js +21 -25
- package/dist/virtual-list/root/virtual-list-root.d.ts +8 -12
- package/dist/virtual-list/root/virtual-list-root.js +11 -16
- package/jsx.d.ts +9797 -12561
- package/package.json +6 -6
- package/vue.d.ts +2684 -3228
|
@@ -60,30 +60,27 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
60
60
|
this.aria = new AriaForwardController(this, {
|
|
61
61
|
target: () => this.renderRoot?.querySelector('[part="control"]') ?? null,
|
|
62
62
|
});
|
|
63
|
-
/**
|
|
64
|
-
* Value submitted when the box is checked.
|
|
65
|
-
*/
|
|
66
|
-
this.value = 'on';
|
|
67
63
|
/**
|
|
68
64
|
* Whether the box shows as neither checked nor unchecked.
|
|
69
65
|
*
|
|
70
66
|
* Presentation only. It never submits, and the first change resolves it.
|
|
71
67
|
*/
|
|
72
68
|
this.indeterminate = false;
|
|
69
|
+
/**
|
|
70
|
+
* Value submitted when the box is checked.
|
|
71
|
+
*/
|
|
72
|
+
this.value = 'on';
|
|
73
73
|
this.handleChange = (event) => {
|
|
74
74
|
const input = event.target;
|
|
75
|
-
// The input has already flipped itself. Where the change is refused
|
|
76
|
-
//
|
|
77
|
-
//
|
|
75
|
+
// The input has already flipped itself. Where the change is refused it is
|
|
76
|
+
// put back to whatever the element resolves to, so the box never shows a
|
|
77
|
+
// state the element does not hold.
|
|
78
78
|
const next = input.checked;
|
|
79
|
-
/* The dash goes only where the change is taken.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* nobody asked for and the element did not hold. Refusing a change should
|
|
85
|
-
* leave everything as it was, which is the argument the line below already
|
|
86
|
-
* makes for `checked`. */
|
|
79
|
+
/* The dash goes only where the change is taken. Clearing it
|
|
80
|
+
* unconditionally leaves a refused change holding the checked state and
|
|
81
|
+
* losing the third one: a box neither ticked nor dashed, which is a state
|
|
82
|
+
* nobody asked for. Refusing leaves everything as it was, which is the
|
|
83
|
+
* argument the line below already makes for `checked`. */
|
|
87
84
|
if (this.requestChecked(next)) {
|
|
88
85
|
this.indeterminate = false;
|
|
89
86
|
}
|
|
@@ -124,8 +121,8 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
124
121
|
/** Returns the box to the state its markup declared. */
|
|
125
122
|
formResetCallback() {
|
|
126
123
|
this.indeterminate = false;
|
|
127
|
-
// `resetChecked` drops both halves
|
|
128
|
-
//
|
|
124
|
+
// `resetChecked` drops both halves, the consumer's and the element's, so
|
|
125
|
+
// there is nothing to clear before it.
|
|
129
126
|
this.resetChecked();
|
|
130
127
|
}
|
|
131
128
|
willUpdate(changed) {
|
|
@@ -142,37 +139,34 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
142
139
|
*
|
|
143
140
|
* Called on `slotchange` and after every update, and the second is not
|
|
144
141
|
* belt-and-braces: **`slotchange` does not fire when nothing is assigned.**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* asks a labeled row to be wider than a bare one.
|
|
142
|
+
* Without it a checkbox labeled only by its property, which is most of them,
|
|
143
|
+
* never hears about its own label and renders without one.
|
|
148
144
|
*
|
|
149
|
-
* **`:state(has-label)` and not `data-has-label
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* upgraded and on none that any server sent. See `HelixElement.toggleState`.
|
|
145
|
+
* **`:state(has-label)` and not `data-has-label`.** The answer comes from
|
|
146
|
+
* `assignedNodes` and a server has no tree to ask, so an attribute would
|
|
147
|
+
* appear on every labeled checkbox the instant it upgraded and on none that
|
|
148
|
+
* any server sent. See `HelixElement.toggleState`.
|
|
154
149
|
*/
|
|
155
150
|
syncLabelPresence() {
|
|
156
151
|
const slot = this.renderRoot.querySelector('[part="label"] slot');
|
|
157
152
|
const filled = (slot?.assignedNodes({ flatten: true }) ?? []).some((node) => node.textContent?.trim() !== '' || node.nodeType === Node.ELEMENT_NODE);
|
|
158
153
|
this.toggleState('has-label', filled);
|
|
159
154
|
/* And `hidden` on the region itself, because the state is on the host and
|
|
160
|
-
this tier has no sheet to turn one into the other
|
|
161
|
-
label
|
|
162
|
-
hides through a descendant selector this cannot replace. */
|
|
155
|
+
this tier has no sheet to turn one into the other, so a checkbox with no
|
|
156
|
+
label would keep an empty label box beside it. The styled rule stays,
|
|
157
|
+
since it hides through a descendant selector this cannot replace. */
|
|
163
158
|
this.renderRoot.querySelector('[part="label"]')?.toggleAttribute('hidden', !filled);
|
|
164
159
|
}
|
|
165
160
|
render() {
|
|
166
161
|
/* A real `<label>` around both, which is the whole of what makes the text a
|
|
167
|
-
target.
|
|
168
|
-
nothing
|
|
169
|
-
a native label wrapping a checkbox, and nothing was doing that work.
|
|
162
|
+
target. A `<span>` beside the input leaves pressing the words doing
|
|
163
|
+
nothing.
|
|
170
164
|
|
|
171
165
|
Labeling is behavior, which is what earns an element here rather than a
|
|
172
166
|
bare slot: the wrapper is not decoration and there is no other way to get
|
|
173
167
|
it. The browser handles the forwarding, so there is no click handler to
|
|
174
168
|
write and none to get wrong.
|
|
175
|
-
|
|
169
|
+
|
|
176
170
|
The one line of description goes under that row, which is where a field
|
|
177
171
|
puts it too. */
|
|
178
172
|
return html `<label part="field">
|
|
@@ -195,12 +189,12 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
|
|
|
195
189
|
${this.renderHint()}${this.renderFeedback()}`;
|
|
196
190
|
}
|
|
197
191
|
};
|
|
198
|
-
__decorate([
|
|
199
|
-
property()
|
|
200
|
-
], HelixHeadlessCheckbox.prototype, "value", void 0);
|
|
201
192
|
__decorate([
|
|
202
193
|
property({ reflect: true, type: Boolean })
|
|
203
194
|
], HelixHeadlessCheckbox.prototype, "indeterminate", void 0);
|
|
195
|
+
__decorate([
|
|
196
|
+
property()
|
|
197
|
+
], HelixHeadlessCheckbox.prototype, "value", void 0);
|
|
204
198
|
HelixHeadlessCheckbox = __decorate([
|
|
205
199
|
customElement('helix-headless-checkbox')
|
|
206
200
|
], HelixHeadlessCheckbox);
|
|
@@ -19,11 +19,9 @@ declare const HelixHeadlessCheckboxGroup_base: (new (...args: any[]) => import("
|
|
|
19
19
|
* `value` is the checked values, comma separated, in the order the boxes are
|
|
20
20
|
* written. Setting it ticks exactly those and unticks the rest.
|
|
21
21
|
*
|
|
22
|
-
* **Its message is always given, never derived.**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* shows here, and the browser has nothing to say about a set it does not know
|
|
26
|
-
* is a set.
|
|
22
|
+
* **Its message is always given, never derived.** The group is form-associated
|
|
23
|
+
* for validity alone and never calls `setFormValue`, so `feedback` is what shows
|
|
24
|
+
* here: the browser has nothing to say about a set it does not submit.
|
|
27
25
|
*
|
|
28
26
|
* @since 0.1.0
|
|
29
27
|
* @status stable
|
|
@@ -63,18 +61,17 @@ export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGro
|
|
|
63
61
|
/**
|
|
64
62
|
* Reads the boxes' own state into `value`, once, before anything is pushed.
|
|
65
63
|
*
|
|
66
|
-
* `sync`
|
|
67
|
-
* guard
|
|
68
|
-
* declare their own `checked`
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
64
|
+
* Seeding, and never a guard in `sync` refusing to write while `value` is
|
|
65
|
+
* empty. The guard would answer the same case, a group written with no `value`
|
|
66
|
+
* whose boxes declare their own `checked` being cleared on the first update,
|
|
67
|
+
* and it also makes `group.value = ''` do nothing at all: the obvious way to
|
|
68
|
+
* clear a group would silently not, and the last box could not be unticked
|
|
69
|
+
* through the group either.
|
|
72
70
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* start is what it already means.
|
|
71
|
+
* The markup decides the starting set, and from then on `value` is what the
|
|
72
|
+
* boxes follow, including when it is empty. The group's `value` is a derived
|
|
73
|
+
* read of the boxes rather than state it owns, so reading it out of them at
|
|
74
|
+
* the start is what it already means.
|
|
78
75
|
*/
|
|
79
76
|
private seed;
|
|
80
77
|
/**
|
|
@@ -95,18 +92,16 @@ export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGro
|
|
|
95
92
|
/**
|
|
96
93
|
* Stops a box's own announcement, for the reason the request above is stopped.
|
|
97
94
|
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* group: measured, one click produced `change` from the group and `input` and
|
|
95
|
+
* A box announces `input` and `change` from its own host, which is what makes
|
|
96
|
+
* `onChange` work on a checkbox, and both bubble up through this group:
|
|
97
|
+
* measured, one click produced `change` from the group and `input` and
|
|
102
98
|
* `change` from the box, all three at a consumer listening here, two of them
|
|
103
|
-
* describing one box rather than the set.
|
|
104
|
-
* comment on `handleToggle` describes, arriving by the other route.
|
|
99
|
+
* describing one box rather than the set.
|
|
105
100
|
*
|
|
106
|
-
* `stopImmediatePropagation` and not `stopPropagation
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
101
|
+
* `stopImmediatePropagation` and not `stopPropagation`: the box's event and
|
|
102
|
+
* this group's own carry one name from what a consumer sees as one element,
|
|
103
|
+
* so stopping propagation alone still leaves every other listener on this
|
|
104
|
+
* host receiving both.
|
|
110
105
|
*
|
|
111
106
|
* A listener on the box itself is unaffected, which is where per-box handling
|
|
112
107
|
* belongs. Each box is form-associated and submits itself; what this stops is
|
|
@@ -118,27 +113,19 @@ export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGro
|
|
|
118
113
|
protected willUpdate(changed: PropertyValues): void;
|
|
119
114
|
protected firstUpdated(changed: PropertyValues): void;
|
|
120
115
|
/**
|
|
121
|
-
* Refuses an empty set where one was required
|
|
116
|
+
* Refuses an empty set where one was required.
|
|
122
117
|
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
118
|
+
* **The group is form-associated, and submits nothing.** Nothing here calls
|
|
119
|
+
* `setFormValue`, so the set that reaches the server is exactly the boxes,
|
|
120
|
+
* each of which submits itself. What form association buys is the other half
|
|
121
|
+
* of participation, validity, and there is no other mechanism for it:
|
|
122
|
+
* `setValidity` throws `NotSupportedError` on an element the platform does not
|
|
123
|
+
* know is a control. happy-dom's shim does not throw, so a spec passes against
|
|
124
|
+
* code that fails on every update in Chromium.
|
|
127
125
|
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* server is exactly the boxes it always was. What form association buys is the
|
|
132
|
-
* other half of participation, validity, and there is no other mechanism for
|
|
133
|
-
* it: `setValidity` throws `NotSupportedError` on an element the platform does
|
|
134
|
-
* not know is a control.
|
|
135
|
-
*
|
|
136
|
-
* So the fix that was written for "a group marked required submitted empty"
|
|
137
|
-
* threw on every update in a real browser, and happy-dom's shim does not
|
|
138
|
-
* throw, so the specs passed and the behavior never worked. Eleven of them
|
|
139
|
-
* failed the moment they were run in Chromium. It is also what makes the rest
|
|
140
|
-
* work: the form now refuses to submit, which fires `invalid`, which is what
|
|
141
|
-
* marks the field touched and puts the message on screen.
|
|
126
|
+
* It is also what makes the rest work: the form refuses to submit, which fires
|
|
127
|
+
* `invalid`, which is what marks the field touched and puts the message on
|
|
128
|
+
* screen.
|
|
142
129
|
*
|
|
143
130
|
* Anchored on the list, because the browser needs somewhere to point the
|
|
144
131
|
* bubble.
|
|
@@ -25,11 +25,9 @@ import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
|
|
|
25
25
|
* `value` is the checked values, comma separated, in the order the boxes are
|
|
26
26
|
* written. Setting it ticks exactly those and unticks the rest.
|
|
27
27
|
*
|
|
28
|
-
* **Its message is always given, never derived.**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* shows here, and the browser has nothing to say about a set it does not know
|
|
32
|
-
* is a set.
|
|
28
|
+
* **Its message is always given, never derived.** The group is form-associated
|
|
29
|
+
* for validity alone and never calls `setFormValue`, so `feedback` is what shows
|
|
30
|
+
* here: the browser has nothing to say about a set it does not submit.
|
|
33
31
|
*
|
|
34
32
|
* @since 0.1.0
|
|
35
33
|
* @status stable
|
|
@@ -52,20 +50,18 @@ import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
|
|
|
52
50
|
*/
|
|
53
51
|
let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
|
|
54
52
|
constructor() {
|
|
55
|
-
/* `name` is inherited
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
every box that has none. */
|
|
53
|
+
/* `name` is inherited from `HelixFormElement`, reflected and with the
|
|
54
|
+
converter that makes an empty one absent rather than `name=""`. What it
|
|
55
|
+
means differs slightly and the property does not: the group submits nothing
|
|
56
|
+
under it, and hands it to every box that has none. */
|
|
60
57
|
super(...arguments);
|
|
61
58
|
/**
|
|
62
59
|
* The checked values, comma separated.
|
|
63
60
|
*/
|
|
64
61
|
this.value = '';
|
|
65
|
-
/* Stated once, and the group never thinks about it again.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
group would have got none at all. */
|
|
62
|
+
/* Stated once, and the group never thinks about it again. The controller is
|
|
63
|
+
what stops the cascade being hand-called from whichever methods a component
|
|
64
|
+
happens to have. */
|
|
69
65
|
this.cascade = new DisabledCascadeController(this, {
|
|
70
66
|
items: () => this.boxes,
|
|
71
67
|
});
|
|
@@ -89,30 +85,22 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
|
|
|
89
85
|
if (!changed) {
|
|
90
86
|
return;
|
|
91
87
|
}
|
|
92
|
-
/*
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
the split this had to be `stopImmediatePropagation` rather than
|
|
96
|
-
`stopPropagation`, because the box's event and the group's own carried
|
|
97
|
-
the same name from the same host and the other listeners on it would have
|
|
98
|
-
received both. */
|
|
88
|
+
/* A box's `helix-before-toggle` bubbles, and the group is the single voice
|
|
89
|
+
for the set: a consumer listening here wants the whole answer, not one
|
|
90
|
+
box's half of it. */
|
|
99
91
|
event.stopImmediatePropagation();
|
|
100
92
|
const wanted = event.detail.checked;
|
|
101
|
-
/* Announced before it is written,
|
|
102
|
-
|
|
103
|
-
|
|
93
|
+
/* Announced before it is written, never after: dispatching once the group's
|
|
94
|
+
value has moved leaves `preventDefault()` refusing a set that has already
|
|
95
|
+
changed.
|
|
104
96
|
|
|
105
|
-
Hand-rolled rather than through `MixinControllerValue`, and that is
|
|
106
|
-
decision rather than an omission. The group is
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
to it. Its `value` is a derived read of the boxes rather than state it
|
|
110
|
-
owns, which is also why it is not controllable and why that is written
|
|
111
|
-
down rather than fixed.
|
|
97
|
+
Hand-rolled rather than through `MixinControllerValue`, and that is a
|
|
98
|
+
decision rather than an omission. The group's `value` is a derived read of
|
|
99
|
+
the boxes rather than state it owns, so there is nothing for the mixin to
|
|
100
|
+
control.
|
|
112
101
|
|
|
113
102
|
The boxes have already moved either way. Each answered the reader before
|
|
114
|
-
this ran, so refusing here stops the group's value from following
|
|
115
|
-
the honest limit of that is recorded with the decision. */
|
|
103
|
+
this ran, so refusing here stops only the group's value from following. */
|
|
116
104
|
const next = this.boxes
|
|
117
105
|
.filter((box) => (box === changed ? wanted : box.checked))
|
|
118
106
|
.map((box) => box.value)
|
|
@@ -126,27 +114,23 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
|
|
|
126
114
|
|
|
127
115
|
`input` beside it, because this is a discrete control and that is the
|
|
128
116
|
pair a native `<select>` sends and the pair every other discrete control
|
|
129
|
-
here sends through `MixinControllerValue`.
|
|
130
|
-
so a consumer binding `onInput` on the set heard the boxes and never the
|
|
131
|
-
group. */
|
|
117
|
+
here sends through `MixinControllerValue`. */
|
|
132
118
|
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
133
119
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: false }));
|
|
134
120
|
};
|
|
135
121
|
/**
|
|
136
122
|
* Stops a box's own announcement, for the reason the request above is stopped.
|
|
137
123
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* group: measured, one click produced `change` from the group and `input` and
|
|
124
|
+
* A box announces `input` and `change` from its own host, which is what makes
|
|
125
|
+
* `onChange` work on a checkbox, and both bubble up through this group:
|
|
126
|
+
* measured, one click produced `change` from the group and `input` and
|
|
142
127
|
* `change` from the box, all three at a consumer listening here, two of them
|
|
143
|
-
* describing one box rather than the set.
|
|
144
|
-
* comment on `handleToggle` describes, arriving by the other route.
|
|
128
|
+
* describing one box rather than the set.
|
|
145
129
|
*
|
|
146
|
-
* `stopImmediatePropagation` and not `stopPropagation
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
130
|
+
* `stopImmediatePropagation` and not `stopPropagation`: the box's event and
|
|
131
|
+
* this group's own carry one name from what a consumer sees as one element,
|
|
132
|
+
* so stopping propagation alone still leaves every other listener on this
|
|
133
|
+
* host receiving both.
|
|
150
134
|
*
|
|
151
135
|
* A listener on the box itself is unaffected, which is where per-box handling
|
|
152
136
|
* belongs. Each box is form-associated and submits itself; what this stops is
|
|
@@ -184,18 +168,17 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
|
|
|
184
168
|
/**
|
|
185
169
|
* Reads the boxes' own state into `value`, once, before anything is pushed.
|
|
186
170
|
*
|
|
187
|
-
* `sync`
|
|
188
|
-
* guard
|
|
189
|
-
* declare their own `checked`
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
171
|
+
* Seeding, and never a guard in `sync` refusing to write while `value` is
|
|
172
|
+
* empty. The guard would answer the same case, a group written with no `value`
|
|
173
|
+
* whose boxes declare their own `checked` being cleared on the first update,
|
|
174
|
+
* and it also makes `group.value = ''` do nothing at all: the obvious way to
|
|
175
|
+
* clear a group would silently not, and the last box could not be unticked
|
|
176
|
+
* through the group either.
|
|
193
177
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* start is what it already means.
|
|
178
|
+
* The markup decides the starting set, and from then on `value` is what the
|
|
179
|
+
* boxes follow, including when it is empty. The group's `value` is a derived
|
|
180
|
+
* read of the boxes rather than state it owns, so reading it out of them at
|
|
181
|
+
* the start is what it already means.
|
|
199
182
|
*/
|
|
200
183
|
seed() {
|
|
201
184
|
const checked = this.boxes.filter((box) => box.checked).map((box) => box.value);
|
|
@@ -233,27 +216,19 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
|
|
|
233
216
|
}
|
|
234
217
|
}
|
|
235
218
|
/**
|
|
236
|
-
* Refuses an empty set where one was required
|
|
219
|
+
* Refuses an empty set where one was required.
|
|
237
220
|
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
221
|
+
* **The group is form-associated, and submits nothing.** Nothing here calls
|
|
222
|
+
* `setFormValue`, so the set that reaches the server is exactly the boxes,
|
|
223
|
+
* each of which submits itself. What form association buys is the other half
|
|
224
|
+
* of participation, validity, and there is no other mechanism for it:
|
|
225
|
+
* `setValidity` throws `NotSupportedError` on an element the platform does not
|
|
226
|
+
* know is a control. happy-dom's shim does not throw, so a spec passes against
|
|
227
|
+
* code that fails on every update in Chromium.
|
|
242
228
|
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* server is exactly the boxes it always was. What form association buys is the
|
|
247
|
-
* other half of participation, validity, and there is no other mechanism for
|
|
248
|
-
* it: `setValidity` throws `NotSupportedError` on an element the platform does
|
|
249
|
-
* not know is a control.
|
|
250
|
-
*
|
|
251
|
-
* So the fix that was written for "a group marked required submitted empty"
|
|
252
|
-
* threw on every update in a real browser, and happy-dom's shim does not
|
|
253
|
-
* throw, so the specs passed and the behavior never worked. Eleven of them
|
|
254
|
-
* failed the moment they were run in Chromium. It is also what makes the rest
|
|
255
|
-
* work: the form now refuses to submit, which fires `invalid`, which is what
|
|
256
|
-
* marks the field touched and puts the message on screen.
|
|
229
|
+
* It is also what makes the rest work: the form refuses to submit, which fires
|
|
230
|
+
* `invalid`, which is what marks the field touched and puts the message on
|
|
231
|
+
* screen.
|
|
257
232
|
*
|
|
258
233
|
* Anchored on the list, because the browser needs somewhere to point the
|
|
259
234
|
* bubble.
|
|
@@ -275,9 +250,8 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
|
|
|
275
250
|
return html `${this.renderGroupLabel()}
|
|
276
251
|
<div part="items">
|
|
277
252
|
${
|
|
278
|
-
/* A box arriving after first render
|
|
279
|
-
the value's checked state
|
|
280
|
-
sibling groups wire this and this one did not. */
|
|
253
|
+
/* A box arriving after first render has neither the shared name nor
|
|
254
|
+
the value's checked state until something pushes them onto it. */
|
|
281
255
|
''}
|
|
282
256
|
<slot @slotchange=${() => this.requestUpdate()}></slot>
|
|
283
257
|
</div>
|
|
@@ -59,10 +59,9 @@ export declare class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
59
59
|
*
|
|
60
60
|
* **Reflected, because the gutter is a stylesheet rule.** `code-block.css`
|
|
61
61
|
* reserves the copy button's width with `:host(:not([no-copy]))`, so the
|
|
62
|
-
* attribute is what decides whether the block pays for a control.
|
|
63
|
-
* script the button
|
|
64
|
-
*
|
|
65
|
-
* arrived at from the other side.
|
|
62
|
+
* attribute is what decides whether the block pays for a control. Unreflected,
|
|
63
|
+
* setting it from script takes the button away (`render` reads the property)
|
|
64
|
+
* and leaves the 40px it stood in reserved.
|
|
66
65
|
*
|
|
67
66
|
* A false boolean reflects as the attribute's absence, so this costs no
|
|
68
67
|
* `no-copy=""` on hosts that never asked for one, and the rule about a
|
|
@@ -69,10 +69,9 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
69
69
|
*
|
|
70
70
|
* **Reflected, because the gutter is a stylesheet rule.** `code-block.css`
|
|
71
71
|
* reserves the copy button's width with `:host(:not([no-copy]))`, so the
|
|
72
|
-
* attribute is what decides whether the block pays for a control.
|
|
73
|
-
* script the button
|
|
74
|
-
*
|
|
75
|
-
* arrived at from the other side.
|
|
72
|
+
* attribute is what decides whether the block pays for a control. Unreflected,
|
|
73
|
+
* setting it from script takes the button away (`render` reads the property)
|
|
74
|
+
* and leaves the 40px it stood in reserved.
|
|
76
75
|
*
|
|
77
76
|
* A false boolean reflects as the attribute's absence, so this costs no
|
|
78
77
|
* `no-copy=""` on hosts that never asked for one, and the rule about a
|
|
@@ -109,14 +108,11 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
|
|
|
109
108
|
this.requestUpdate();
|
|
110
109
|
}
|
|
111
110
|
render() {
|
|
112
|
-
/* The copy button sits beside the code, not in a bar above it.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* like. Beside the code it needs no bar at all, so a block with no `label`
|
|
118
|
-
* is just the code and a way to take it, and the header exists only when
|
|
119
|
-
* there is a name to put in it. One less appearance to choose between. */
|
|
111
|
+
/* The copy button sits beside the code, not in a bar above it. In the
|
|
112
|
+
header, a block with nothing to call itself still draws a full-width bar
|
|
113
|
+
to hold one button, so a `Usage` section of one-line imports is a run of
|
|
114
|
+
empty strips. Beside the code, the header exists only when there is a
|
|
115
|
+
name to put in it. */
|
|
120
116
|
return html `${this.label ? html `<div part="header"><span part="label">${this.label}</span></div>` : nothing}
|
|
121
117
|
<div part="frame">
|
|
122
118
|
<pre part="block"><code part="code"><slot @slotchange=${() => this.requestUpdate()}></slot></code></pre>
|
|
@@ -27,10 +27,10 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
|
|
|
27
27
|
* the value itself, for the reason Date Input gives about its dates: half-typed
|
|
28
28
|
* input does not survive a round trip through a formatter.
|
|
29
29
|
*
|
|
30
|
-
* The
|
|
31
|
-
* it
|
|
32
|
-
*
|
|
33
|
-
*
|
|
30
|
+
* The custom property below is written by this component and never set by a
|
|
31
|
+
* consumer: it carries a value this element resolved and CSS cannot, which is
|
|
32
|
+
* what lets a stylesheet on this tier paint the swatch without parsing anything
|
|
33
|
+
* itself.
|
|
34
34
|
*
|
|
35
35
|
* @since 0.1.0
|
|
36
36
|
* @status experimental
|
|
@@ -92,48 +92,29 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
|
|
|
92
92
|
*/
|
|
93
93
|
export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_base {
|
|
94
94
|
protected readonly aria: AriaForwardController;
|
|
95
|
+
/**
|
|
96
|
+
* Whether the color carries an alpha channel.
|
|
97
|
+
*/
|
|
98
|
+
alpha: boolean;
|
|
95
99
|
/**
|
|
96
100
|
* What the browser may autofill in the text field, as a platform token.
|
|
97
101
|
*
|
|
98
102
|
* **Defaults to `off`, which is not the platform's default and is the
|
|
99
|
-
* point.** The field
|
|
100
|
-
*
|
|
101
|
-
*
|
|
103
|
+
* point.** The field holds a color, so a browser offering to fill it with a
|
|
104
|
+
* saved address is competing for the same keystrokes as the picker. A
|
|
105
|
+
* consumer who wants autofill can still ask.
|
|
102
106
|
*/
|
|
103
107
|
autocomplete: string;
|
|
104
|
-
/**
|
|
105
|
-
* Whether the field is a text box with a swatch on it, or only the swatch.
|
|
106
|
-
*
|
|
107
|
-
* `swatch` is the native control's shape: a block of color that opens a
|
|
108
|
-
* picker, with no text beside it. It is what a toolbar wants, and a form that
|
|
109
|
-
* asks for a color among twenty other questions, where a hex in a box is
|
|
110
|
-
* eleven characters of noise next to the thing itself.
|
|
111
|
-
*
|
|
112
|
-
* It also settles where the value is stated. The default field *is* the input,
|
|
113
|
-
* so the panel is told `no-value` and would otherwise show a second one. A
|
|
114
|
-
* swatch states nothing, so the panel keeps its own row and the value is
|
|
115
|
-
* readable and typeable exactly once, in whichever of the two is present.
|
|
116
|
-
*
|
|
117
|
-
* The trade is real and is the reason this is not the default: a swatch cannot
|
|
118
|
-
* be read or pasted into without opening the panel, which is worse for a form
|
|
119
|
-
* where the color is the answer rather than a setting.
|
|
120
|
-
*/
|
|
121
|
-
variant?: 'swatch';
|
|
122
|
-
/**
|
|
123
|
-
* Whether the color carries an alpha channel.
|
|
124
|
-
*/
|
|
125
|
-
alpha: boolean;
|
|
126
108
|
/**
|
|
127
109
|
* The syntax the value is written in: `hex`, `rgb` or `hsl`.
|
|
128
110
|
*
|
|
129
|
-
* **Undefaulted, because it reflects.** The two together
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* attribute's absence rather than a value spelled out.
|
|
111
|
+
* **Undefaulted, because it reflects.** The two together stamp an attribute
|
|
112
|
+
* onto every host anybody renders, including the ones nobody configured: the
|
|
113
|
+
* server writes `format="hex"` on every color input on the page, and React,
|
|
114
|
+
* holding no such prop, reports a hydration mismatch for each one.
|
|
115
|
+
* `helix component`'s `reflected-defaults` holds it. Hex is still what an unset one
|
|
116
|
+
* writes; the resting arrangement is the attribute's absence rather than a
|
|
117
|
+
* value spelled out.
|
|
137
118
|
*/
|
|
138
119
|
format?: ColorFormat;
|
|
139
120
|
/**
|
|
@@ -152,6 +133,24 @@ export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_bas
|
|
|
152
133
|
* Accessible name for the control that opens the panel.
|
|
153
134
|
*/
|
|
154
135
|
triggerLabel: string;
|
|
136
|
+
/**
|
|
137
|
+
* Whether the field is a text box with a swatch on it, or only the swatch.
|
|
138
|
+
*
|
|
139
|
+
* `swatch` is the native control's shape: a block of color that opens a
|
|
140
|
+
* picker, with no text beside it. It is what a toolbar wants, and a form that
|
|
141
|
+
* asks for a color among twenty other questions, where a hex in a box is
|
|
142
|
+
* eleven characters of noise next to the thing itself.
|
|
143
|
+
*
|
|
144
|
+
* It also settles where the value is stated. The default field *is* the input,
|
|
145
|
+
* so the panel is told `no-value` and would otherwise show a second one. A
|
|
146
|
+
* swatch states nothing, so the panel keeps its own row and the value is
|
|
147
|
+
* readable and typeable exactly once, in whichever of the two is present.
|
|
148
|
+
*
|
|
149
|
+
* The trade is real and is the reason this is not the default: a swatch cannot
|
|
150
|
+
* be read or pasted into without opening the panel, which is worse for a form
|
|
151
|
+
* where the color is the answer rather than a setting.
|
|
152
|
+
*/
|
|
153
|
+
variant?: 'swatch';
|
|
155
154
|
/** The overlay, placed against the field for the reason Date Input gives. */
|
|
156
155
|
protected readonly panel: PopoverController;
|
|
157
156
|
/**
|