@fusion.dev/helix-headless 0.2.0 → 0.3.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 +234 -234
- package/dist/accordion/item/accordion-item.js +0 -108
- package/dist/accordion/root/accordion-root.js +0 -33
- package/dist/announcement/root/announcement-root.js +1 -76
- package/dist/app-header/root/app-header-root.js +0 -84
- package/dist/avatar/group/avatar-group.js +0 -77
- package/dist/avatar/root/avatar-root.js +0 -72
- package/dist/badge/root/badge-root.js +0 -67
- package/dist/bar-chart/root/bar-chart-root.js +3 -263
- package/dist/blockquote/root/blockquote-root.js +0 -46
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +0 -72
- package/dist/breadcrumbs/root/breadcrumbs-root.js +0 -52
- package/dist/button/root/button-root.js +0 -215
- package/dist/button-group/root/button-group-root.js +0 -30
- package/dist/callout/root/callout-root.js +0 -52
- package/dist/card/root/card-root.js +0 -41
- package/dist/carousel/root/carousel-root.d.ts +2 -2
- package/dist/carousel/root/carousel-root.js +2 -362
- package/dist/chat/composer/chat-composer.js +0 -131
- package/dist/chat/message/chat-message.js +0 -137
- package/dist/chat/root/chat-root.js +0 -193
- package/dist/checkbox/root/checkbox-root.js +0 -113
- package/dist/checkbox-group/root/checkbox-group-root.js +1 -157
- package/dist/code/root/code-root.js +0 -26
- package/dist/code-block/root/code-block-root.js +0 -100
- package/dist/color-input/root/color-input-root.js +0 -217
- package/dist/color-picker/color.js +0 -69
- package/dist/color-picker/root/color-picker-root.js +0 -272
- package/dist/combobox/root/combobox-root.js +0 -428
- package/dist/command/root/command-root.js +0 -177
- package/dist/copy-button/root/copy-button-root.js +0 -134
- package/dist/data-table/root/data-table-root.js +0 -336
- package/dist/data-table/root/order.js +0 -100
- package/dist/date-input/root/date-input-root.js +1 -398
- package/dist/date-picker/root/date-picker-root.js +0 -358
- package/dist/dialog/root/dialog-root.js +0 -189
- package/dist/divider/root/divider-root.js +0 -71
- package/dist/donut-chart/root/donut-chart-root.js +0 -214
- package/dist/drawer/root/drawer-root.js +0 -116
- package/dist/drilldown/item/drilldown-item.js +0 -82
- package/dist/drilldown/root/drilldown-root.js +0 -91
- package/dist/element-events.generated.js +0 -5
- package/dist/empty/root/empty-root.js +0 -35
- package/dist/file-input/root/file-input-root.js +0 -232
- package/dist/format-date/root/format-date-root.js +0 -95
- package/dist/heatmap/root/buckets.js +0 -57
- package/dist/heatmap/root/heatmap-root.js +0 -313
- package/dist/icon/root/icon-root.js +0 -48
- package/dist/icon-button/root/icon-button-root.js +0 -30
- package/dist/image/root/image-root.js +0 -174
- package/dist/index.js +0 -9
- package/dist/input/root/input-root.js +0 -228
- package/dist/kbd/root/kbd-root.js +0 -117
- package/dist/legend/root/legend-root.js +0 -73
- package/dist/line-chart/root/line-chart-root.js +0 -172
- package/dist/list/item/list-item.js +0 -92
- package/dist/list/root/list-root.js +0 -26
- package/dist/listbox/root/listbox-root.js +2 -429
- package/dist/loader/root/loader-root.js +0 -40
- package/dist/megamenu/root/megamenu-root.js +0 -284
- package/dist/menu/item/menu-item.js +1 -221
- package/dist/menu/root/menu-root.js +1 -171
- package/dist/meter/root/meter-root.js +1 -152
- package/dist/navigation/root/navigation-root.js +0 -56
- package/dist/notifications/notification/notification.js +0 -159
- package/dist/notifications/root/notifications-root.js +0 -148
- package/dist/number-input/root/number-input-root.js +1 -263
- package/dist/option/group/option-group.js +0 -26
- package/dist/option/root/option-root.js +0 -157
- package/dist/outline/root/outline-root.js +0 -292
- package/dist/pagination/root/pagination-root.js +0 -361
- package/dist/pagination/size/pagination-size.js +0 -104
- package/dist/pagination/summary/pagination-summary.js +0 -90
- package/dist/pin-input/root/pin-input-root.js +0 -276
- package/dist/popover/root/popover-root.js +0 -103
- package/dist/progress/root/progress-root.js +1 -133
- package/dist/qr-code/root/qr-code-root.js +0 -96
- package/dist/quote/root/quote-root.js +0 -25
- package/dist/radio/group/radio-group.js +0 -81
- package/dist/radio/root/radio-root.js +0 -85
- package/dist/rating/root/rating-root.js +0 -220
- package/dist/scroll-area/root/scroll-area-root.js +0 -100
- package/dist/select/root/select-root.js +2 -218
- package/dist/skeleton/root/skeleton-root.js +0 -20
- package/dist/slider/root/slider-root.js +1 -267
- package/dist/sparkline/root/sparkline-root.js +3 -164
- package/dist/speed-dial/item/speed-dial-item.js +0 -52
- package/dist/speed-dial/root/speed-dial-root.js +1 -116
- package/dist/splitter/root/splitter-root.js +0 -489
- package/dist/stat/group/stat-group.js +0 -18
- package/dist/stat/root/stat-root.js +0 -23
- package/dist/steps/root/steps-root.js +0 -62
- package/dist/steps/step/step.js +0 -131
- package/dist/switch/root/switch-root.js +0 -80
- package/dist/table/cell/table-cell.js +0 -23
- package/dist/table/column/table-column.js +0 -158
- package/dist/table/root/table-root.js +0 -82
- package/dist/table/row/table-row.js +0 -21
- package/dist/tabs/panel/tab-panel.js +0 -49
- package/dist/tabs/root/tabs-root.js +0 -98
- package/dist/tabs/tab/tab.js +0 -59
- package/dist/tag/root/tag-root.js +0 -31
- package/dist/textarea/root/textarea-root.js +0 -162
- package/dist/time-input/root/time-input-root.js +0 -283
- package/dist/time-picker/root/time-picker-root.js +0 -326
- package/dist/timeline/item/timeline-item.js +0 -66
- package/dist/timeline/root/timeline-root.js +0 -41
- package/dist/toast/item/toast-item.js +0 -165
- package/dist/toast/root/toast-root.js +0 -51
- package/dist/toggle/group/toggle-group.js +0 -150
- package/dist/toggle/root/toggle-root.js +0 -78
- package/dist/toolbar/root/toolbar-root.js +0 -116
- package/dist/tooltip/root/tooltip-root.js +0 -427
- package/dist/tour/root/tour-root.js +0 -130
- package/dist/tour/stop/tour-stop.js +1 -127
- package/dist/tree/item/tree-item.js +0 -198
- package/dist/tree/root/tree-root.js +0 -97
- package/dist/trend/root/trend-root.js +0 -53
- package/dist/video/root/video-root.d.ts +8 -12
- package/dist/video/root/video-root.js +5 -756
- package/dist/video-playlist/item/video-playlist-item.js +1 -90
- package/dist/video-playlist/menu/video-playlist-menu.js +1 -132
- package/dist/video-playlist/root/video-playlist-root.js +0 -113
- package/dist/virtual-list/root/virtual-list-root.js +0 -105
- package/jsx.d.ts +1408 -2576
- package/package.json +6 -6
- package/vue.d.ts +1 -1
|
@@ -11,130 +11,20 @@ import { property } from 'lit/decorators.js';
|
|
|
11
11
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
12
|
import { html } from 'lit/static-html.js';
|
|
13
13
|
import '../../listbox/index.js';
|
|
14
|
-
/**
|
|
15
|
-
* @summary A closed list that opens to be chosen from.
|
|
16
|
-
*
|
|
17
|
-
* @description
|
|
18
|
-
* **A trigger and a `Listbox`, not a listbox reimplemented behind a button.**
|
|
19
|
-
* The list this opens is the same element a consumer can use on its own, with
|
|
20
|
-
* the same keyboard, the same filtering and the same multi-select rules. What
|
|
21
|
-
* Select adds is the closing: a trigger that says what is chosen, a surface
|
|
22
|
-
* that floats, and somewhere for focus to go back to.
|
|
23
|
-
*
|
|
24
|
-
* The options are the consumer's, in the consumer's light DOM, slotted through
|
|
25
|
-
* into the listbox. That is why the listbox walks through slots to find them:
|
|
26
|
-
* from its point of view the options belong to something else.
|
|
27
|
-
*
|
|
28
|
-
* **What it does not do is duplicate the value.** `Select` owns it, hands it
|
|
29
|
-
* down, and takes changes back; the listbox is the thing being operated and not
|
|
30
|
-
* a second place the answer lives.
|
|
31
|
-
*
|
|
32
|
-
* @since 0.1.0
|
|
33
|
-
* @status experimental
|
|
34
|
-
* @category forms
|
|
35
|
-
* @aliases Dropdown, Picker
|
|
36
|
-
* @documentation https://helix.fusion.dev/components/select
|
|
37
|
-
*
|
|
38
|
-
* @slot - The options, and any groups of them.
|
|
39
|
-
* @slot end - After it, for a count, a unit, or a clear button.
|
|
40
|
-
* @slot hint - Richer than a string.
|
|
41
|
-
* @slot indicator - The mark on the trigger saying this opens, usually a caret.
|
|
42
|
-
* @slot label - Richer than a string.
|
|
43
|
-
* @slot start - Before the chosen value, for an icon or a prefix.
|
|
44
|
-
*
|
|
45
|
-
* @event {Event} change - Announced once the value has moved.
|
|
46
|
-
* @event {HelixBeforeChangeEvent} helix-before-change - Relayed from the listbox when the answer changes. Cancelable: refusing it takes the decision and nothing moves.
|
|
47
|
-
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before it closes. Cancelable: refusing it takes the decision and nothing moves.
|
|
48
|
-
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before the list opens. Cancelable: refusing it takes the decision and nothing moves.
|
|
49
|
-
* @event {Event} input - Announced once the value has moved.
|
|
50
|
-
* @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
|
|
51
|
-
*
|
|
52
|
-
* @csspart feedback - What is wrong with it.
|
|
53
|
-
* @csspart hint - Help under the trigger.
|
|
54
|
-
* @csspart indicator - The caret saying the control opens. Replaced by slotting one.
|
|
55
|
-
* @csspart label - The question, over the trigger.
|
|
56
|
-
* @csspart listbox - The list inside it.
|
|
57
|
-
* @csspart listbox-empty - Shown when a filter has hidden everything.
|
|
58
|
-
* @csspart listbox-feedback - What is wrong with it.
|
|
59
|
-
* @csspart listbox-filter-icon - The mark beside that field.
|
|
60
|
-
* @csspart listbox-filter-mark - The glyph beside the filter field, where none is slotted.
|
|
61
|
-
* @csspart listbox-hint - Help under the list.
|
|
62
|
-
* @csspart listbox-items - The list itself.
|
|
63
|
-
* @csspart listbox-label - The question, over the list.
|
|
64
|
-
* @csspart listbox-loading - Shown while the options are still on their way.
|
|
65
|
-
* @csspart listbox-search - The region holding the field that narrows the list.
|
|
66
|
-
* @csspart listbox-search-field - The field itself.
|
|
67
|
-
* @csspart surface - The floating panel.
|
|
68
|
-
* @csspart trigger - The closed control, which says what is chosen.
|
|
69
|
-
* @csspart value - The chosen option's text inside the trigger.
|
|
70
|
-
*/
|
|
71
14
|
let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(MixinControllerValue(MixinField(HelixFormElement))) {
|
|
72
15
|
constructor() {
|
|
73
16
|
super(...arguments);
|
|
74
|
-
/* A consumer's `aria-describedby` names ids in their own tree and the control
|
|
75
|
-
is in this shadow root, so the reference has to be carried down as an
|
|
76
|
-
element rather than copied as an id. See `AriaForwardController`: measured
|
|
77
|
-
in Chrome's own tree, the host held the description and the control the
|
|
78
|
-
reader is actually on was exposed without it. */
|
|
79
17
|
this.aria = new AriaForwardController(this, {
|
|
80
18
|
target: () => this.renderRoot?.querySelector('[part="trigger"]') ?? null,
|
|
81
19
|
});
|
|
82
|
-
/**
|
|
83
|
-
* What it says where there are none.
|
|
84
|
-
*/
|
|
85
20
|
this.emptyText = 'No matches';
|
|
86
|
-
/**
|
|
87
|
-
* Whether the list can be narrowed by typing.
|
|
88
|
-
*
|
|
89
|
-
* Passed to the listbox rather than acted on here, because the listbox owns
|
|
90
|
-
* the filtering, the empty state and the keyboard.
|
|
91
|
-
*/
|
|
92
21
|
this.filterable = false;
|
|
93
|
-
/**
|
|
94
|
-
* Whether the options are still on their way.
|
|
95
|
-
*
|
|
96
|
-
* Passed straight to the list, which is where the rows are and so where the
|
|
97
|
-
* message belongs. Two components saying "Loading" about one request is a
|
|
98
|
-
* consumer wiring the same flag twice.
|
|
99
|
-
*/
|
|
100
22
|
this.loading = false;
|
|
101
|
-
/**
|
|
102
|
-
* What the list says while they are on their way.
|
|
103
|
-
*/
|
|
104
23
|
this.loadingText = 'Loading';
|
|
105
|
-
/**
|
|
106
|
-
* Whether more than one option can be the answer.
|
|
107
|
-
*/
|
|
108
24
|
this.multiple = false;
|
|
109
|
-
/**
|
|
110
|
-
* Shown on the trigger while nothing is chosen.
|
|
111
|
-
*/
|
|
112
25
|
this.placeholder = 'Choose';
|
|
113
|
-
/* The surface floats *and is in the top layer*.
|
|
114
|
-
*
|
|
115
|
-
* Without `showPopover` the panel is an ordinary positioned element and the
|
|
116
|
-
* first ancestor with `overflow: hidden` clips it, so a select inside a
|
|
117
|
-
* scrolling card is cut off where a menu in the same place is not. The two
|
|
118
|
-
* are the same shape (floating panel, trigger, dismissal), which is what
|
|
119
|
-
* `PopoverController` is, and having one of them is what stops the third copy
|
|
120
|
-
* being subtly different.
|
|
121
|
-
*
|
|
122
|
-
* Held off the trigger by the controller rather than by a margin on the
|
|
123
|
-
* panel. A margin is inside the box the controller measures, so it would be
|
|
124
|
-
* counted once in the placement and again in the layout, and the gap would
|
|
125
|
-
* change as the panel flipped above the trigger for want of room. */
|
|
126
26
|
this.panel = new PopoverController(this, {
|
|
127
27
|
anchor: () => this.renderRoot?.querySelector('[part="trigger"]'),
|
|
128
|
-
/* The surface *and* the trigger.
|
|
129
|
-
*
|
|
130
|
-
* A control is not always one element: the button that opens this panel is
|
|
131
|
-
* part of it, and a press on it is not a press outside. Scoped to the
|
|
132
|
-
* surface alone, `pointerdown` on the trigger closes the panel and the
|
|
133
|
-
* trigger's own `toggleOpen` reopens it on the `click` that follows, so
|
|
134
|
-
* the panel can never be closed by the button that opened it.
|
|
135
|
-
*
|
|
136
|
-
* `DismissController` documents this exact failure and takes a list for
|
|
137
|
-
* it. */
|
|
138
28
|
boundary: () => [
|
|
139
29
|
this.renderRoot?.querySelector('[part="surface"]'),
|
|
140
30
|
this.renderRoot?.querySelector('[part="trigger"]'),
|
|
@@ -145,44 +35,14 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
145
35
|
surface: () => this.renderRoot?.querySelector('[part="surface"]'),
|
|
146
36
|
});
|
|
147
37
|
this.handleChange = (event) => {
|
|
148
|
-
/* From the event, not from the listbox.
|
|
149
|
-
*
|
|
150
|
-
* The event carries the value being *proposed*, and it is dispatched before
|
|
151
|
-
* it is applied, which is what makes it refusable. Reading the listbox here
|
|
152
|
-
* reads the value it still holds: one choice behind, and on the first
|
|
153
|
-
* choice nothing at all.
|
|
154
|
-
*
|
|
155
|
-
* And the listbox never applies it anyway. The select passes `.value` down,
|
|
156
|
-
* which is a consumer declaring ownership, so the listbox inside the panel
|
|
157
|
-
* is controlled by the select and correctly waits to be told. That is the
|
|
158
|
-
* right arrangement, and it makes reading the listbox's own value the one
|
|
159
|
-
* thing that can never work. */
|
|
160
38
|
const next = event.detail.value;
|
|
161
|
-
/* Nothing happens on a refusal.
|
|
162
|
-
*
|
|
163
|
-
* Without this return the panel closes and a native `change` goes out
|
|
164
|
-
* whether or not the change was taken, so a consumer calling
|
|
165
|
-
* `preventDefault()` on `helix-change` keeps the old value, watches the
|
|
166
|
-
* select shut as though it had been chosen, and tells the form it moved. */
|
|
167
39
|
if (!this.requestValue(next)) {
|
|
168
40
|
event.stopPropagation();
|
|
169
41
|
return;
|
|
170
42
|
}
|
|
171
|
-
/* Closed on a choice, unless more than one can be made: a multi-select that
|
|
172
|
-
shut after each pick would be a control the reader has to reopen to use
|
|
173
|
-
again. */
|
|
174
43
|
if (!this.multiple) {
|
|
175
44
|
this.close();
|
|
176
45
|
}
|
|
177
|
-
/* The listbox's request is stopped and this element's own has already gone
|
|
178
|
-
out, from `requestValue` above: two elements announcing one choice is
|
|
179
|
-
what a consumer would have to deduplicate.
|
|
180
|
-
|
|
181
|
-
And no `change` is dispatched here. `requestValue` announces `input` and
|
|
182
|
-
`change` through the mixin, the way every other discrete control does, so
|
|
183
|
-
a second one from this line is a second `change` per choice: measured on
|
|
184
|
-
the styled tier at three, one from the mixin, one from here, and one from
|
|
185
|
-
the listbox before it was stopped. */
|
|
186
46
|
event.stopPropagation();
|
|
187
47
|
};
|
|
188
48
|
this.handleTriggerKeydown = (event) => {
|
|
@@ -192,14 +52,6 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
192
52
|
}
|
|
193
53
|
};
|
|
194
54
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Which option is chosen, as an index, or `-1` where none is.
|
|
197
|
-
*
|
|
198
|
-
* Read off the listbox this renders, which owns the options and is where the
|
|
199
|
-
* same two properties are implemented. Delegating rather than recomputing is
|
|
200
|
-
* what keeps a composed control and the control inside it from answering
|
|
201
|
-
* differently: they are one chooser to a consumer.
|
|
202
|
-
*/
|
|
203
55
|
get selectedIndex() {
|
|
204
56
|
return this.listbox?.selectedIndex ?? -1;
|
|
205
57
|
}
|
|
@@ -209,32 +61,12 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
209
61
|
listbox.selectedIndex = at;
|
|
210
62
|
}
|
|
211
63
|
}
|
|
212
|
-
/** Which kind of chooser this is, in the platform's two words. */
|
|
213
64
|
get type() {
|
|
214
65
|
return this.multiple ? 'select-multiple' : 'select-one';
|
|
215
66
|
}
|
|
216
|
-
/**
|
|
217
|
-
* The list inside the surface, or nothing where there is no DOM to hold one.
|
|
218
|
-
*
|
|
219
|
-
* The optional chain is the server. `renderRoot` is a property Lit's element
|
|
220
|
-
* shim does not carry, and this getter is reached from `display`, which is
|
|
221
|
-
* read during `render`: without it the select throws on every server render
|
|
222
|
-
* and cannot be served at all.
|
|
223
|
-
*
|
|
224
|
-
* The other reads of `renderRoot` here are inside callbacks the controllers
|
|
225
|
-
* invoke, and a controller only runs on a connected element, so they cannot
|
|
226
|
-
* be reached from the server and are left plain.
|
|
227
|
-
*/
|
|
228
67
|
get listbox() {
|
|
229
68
|
return this.renderRoot?.querySelector('[part="listbox"]') ?? null;
|
|
230
69
|
}
|
|
231
|
-
/**
|
|
232
|
-
* What the trigger says: the chosen options' words, or the placeholder.
|
|
233
|
-
*
|
|
234
|
-
* Read off the options rather than stored, because the words are the
|
|
235
|
-
* consumer's content and storing a copy is storing something that goes stale
|
|
236
|
-
* the moment they change it.
|
|
237
|
-
*/
|
|
238
70
|
get display() {
|
|
239
71
|
const chosen = new Set(this.value === '' ? [] : this.value.split(','));
|
|
240
72
|
const words = (this.listbox?.options ?? [])
|
|
@@ -242,17 +74,13 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
242
74
|
.map((option) => option.text);
|
|
243
75
|
return words.length > 0 ? words.join(', ') : this.placeholder;
|
|
244
76
|
}
|
|
245
|
-
/** Closes the list and puts focus back where it came from. */
|
|
246
77
|
close() {
|
|
247
78
|
if (!this.open) {
|
|
248
79
|
return;
|
|
249
80
|
}
|
|
250
81
|
this.requestOpen(false);
|
|
251
|
-
// Back to the trigger, because focus is inside a panel that is going away
|
|
252
|
-
// and a reader who loses it lands at the top of the document.
|
|
253
82
|
this.renderRoot.querySelector('[part="trigger"]')?.focus();
|
|
254
83
|
}
|
|
255
|
-
/** Reports the answer and the verdict on it. */
|
|
256
84
|
sync() {
|
|
257
85
|
this.internals.setFormValue(this.value === '' ? null : this.value);
|
|
258
86
|
this.reportRequired(this.value === '', 'Choose one to continue.', 'trigger');
|
|
@@ -266,42 +94,16 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
266
94
|
this.sync();
|
|
267
95
|
this.linkHost();
|
|
268
96
|
if (this.open) {
|
|
269
|
-
/* Driven from `updated` rather than from a `show()` method, because the
|
|
270
|
-
open state is the property and a consumer may set it directly. The
|
|
271
|
-
controller is idempotent, so arriving here twice for the same open
|
|
272
|
-
costs nothing. */
|
|
273
97
|
this.panel.show();
|
|
274
|
-
/* Into the list, which is where the keyboard has to be for the arrows to
|
|
275
|
-
mean anything. The listbox delegates focus, so this lands on the list
|
|
276
|
-
inside it rather than stopping at the listbox element, which is not
|
|
277
|
-
itself focusable.
|
|
278
|
-
*
|
|
279
|
-
* Only on the update that opened it. `updated` runs for any change while
|
|
280
|
-
* the panel is up, a filter keystroke or a value arriving, and moving
|
|
281
|
-
* focus on each of those is a focus thief. */
|
|
282
98
|
if (changed.has('open')) {
|
|
283
99
|
this.listbox?.focus();
|
|
284
100
|
}
|
|
285
101
|
}
|
|
286
102
|
else {
|
|
287
103
|
this.panel.hide();
|
|
288
|
-
/* And the filter goes with it. Without this a filterable select reopens
|
|
289
|
-
still narrowed by the old needle, with `hidden` still written on the
|
|
290
|
-
options it ruled out, so the second use of the control starts from the
|
|
291
|
-
first one's leftovers. Closing is where a search ends. */
|
|
292
104
|
this.listbox?.requestFilter('');
|
|
293
105
|
}
|
|
294
106
|
}
|
|
295
|
-
/**
|
|
296
|
-
* The list the trigger opens, behind a seam the styled tier can move.
|
|
297
|
-
*
|
|
298
|
-
* A method rather than a fragment inline, so a tier above can render its own
|
|
299
|
-
* list, wrap this one, or pass it a property the base does not know about,
|
|
300
|
-
* without reimplementing the whole template. The tag is interpolated rather
|
|
301
|
-
* than written, so `tier` resolves it: this renders the base listbox, and a
|
|
302
|
-
* styled subclass that sets `tier` renders the styled one from the same
|
|
303
|
-
* template.
|
|
304
|
-
*/
|
|
305
107
|
renderListbox() {
|
|
306
108
|
return html `<${this.tag('listbox')}
|
|
307
109
|
empty-text=${this.emptyText}
|
|
@@ -328,15 +130,6 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
328
130
|
<slot @slotchange=${() => this.requestUpdate()}></slot>
|
|
329
131
|
</${this.tag('listbox')}>`;
|
|
330
132
|
}
|
|
331
|
-
/**
|
|
332
|
-
* The caret saying the control opens, behind a seam.
|
|
333
|
-
*
|
|
334
|
-
* Slot fallback, so a consumer replaces it by slotting; and a method, so the
|
|
335
|
-
* tier above replaces it by overriding. Those answer different people: the
|
|
336
|
-
* slot is for the page and the method is for whoever is building the styled
|
|
337
|
-
* layer, and a fallback with only the first is one a tier can restyle and
|
|
338
|
-
* cannot change.
|
|
339
|
-
*/
|
|
340
133
|
renderIndicator() {
|
|
341
134
|
return html `<slot name="indicator">
|
|
342
135
|
<svg part="indicator" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
|
|
@@ -359,18 +152,9 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
|
|
|
359
152
|
>
|
|
360
153
|
<slot name="start"></slot>
|
|
361
154
|
<span part="value">${this.display}</span>
|
|
362
|
-
${
|
|
363
|
-
/* Before the indicator, not after it. The caret is the affordance
|
|
364
|
-
saying the control opens, so it stays the last thing in the trigger
|
|
365
|
-
whatever else is put in front of it. */
|
|
366
|
-
''}
|
|
155
|
+
${''}
|
|
367
156
|
<slot name="end"></slot>
|
|
368
|
-
${
|
|
369
|
-
/* The slot has a fallback: without one a select written without a
|
|
370
|
-
hand-slotted icon draws no mark at all saying it opens. A caret is
|
|
371
|
-
the mark, and slotting anything replaces it, which is this
|
|
372
|
-
library's rule for a content property. */
|
|
373
|
-
''}
|
|
157
|
+
${''}
|
|
374
158
|
${this.renderIndicator()}
|
|
375
159
|
</button>
|
|
376
160
|
|
|
@@ -6,26 +6,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { customElement, HelixElement } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
|
-
/**
|
|
10
|
-
* @summary Stands in for content that has not arrived.
|
|
11
|
-
*
|
|
12
|
-
* @description
|
|
13
|
-
* Carries `aria-busy` and a polite live region, so a reader using a screen
|
|
14
|
-
* reader is told the region is filling rather than told nothing and left to
|
|
15
|
-
* wonder. Both go through `ElementInternals`, which writes no attribute.
|
|
16
|
-
*
|
|
17
|
-
* Holds no `shape`. Whether a placeholder is a line, a block or a circle is
|
|
18
|
-
* presentation, and putting it here would give the headless tier an appearance
|
|
19
|
-
* property, which is the one thing that tier is for not having.
|
|
20
|
-
*
|
|
21
|
-
* @since 0.1.0
|
|
22
|
-
* @status stable
|
|
23
|
-
* @category feedback
|
|
24
|
-
* @aliases Placeholder, Shimmer, Ghost
|
|
25
|
-
* @documentation https://helix.fusion.dev/components/skeleton
|
|
26
|
-
*
|
|
27
|
-
* @csspart skeleton - The placeholder surface.
|
|
28
|
-
*/
|
|
29
9
|
let HelixHeadlessSkeleton = class HelixHeadlessSkeleton extends HelixElement {
|
|
30
10
|
willUpdate(changed) {
|
|
31
11
|
super.willUpdate(changed);
|