@fusion.dev/helix-headless 0.103.3 → 0.104.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 +9253 -880
- package/dist/announcement/root/announcement-root.d.ts +9 -2
- package/dist/announcement/root/announcement-root.js +9 -6
- package/dist/badge/root/badge-root.js +2 -3
- package/dist/canvas/edge/canvas-edge.d.ts +112 -0
- package/dist/canvas/edge/canvas-edge.js +66 -0
- package/dist/canvas/index.d.ts +4 -0
- package/dist/canvas/index.js +3 -0
- package/dist/canvas/node/canvas-node.d.ts +211 -0
- package/dist/canvas/node/canvas-node.js +148 -0
- package/dist/canvas/root/canvas-document.d.ts +215 -0
- package/dist/canvas/root/canvas-document.js +284 -0
- package/dist/canvas/root/canvas-root.d.ts +912 -0
- package/dist/canvas/root/canvas-root.js +1814 -0
- package/dist/carousel/root/carousel-root.d.ts +53 -16
- package/dist/carousel/root/carousel-root.js +46 -11
- package/dist/chat/root/chat-root.d.ts +4 -0
- package/dist/chat/root/chat-root.js +11 -7
- package/dist/checkbox/root/checkbox-root.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +10 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +5 -0
- package/dist/color-input/root/color-input-root.js +21 -5
- package/dist/color-picker/root/color-picker-root.d.ts +55 -0
- package/dist/color-picker/root/color-picker-root.js +61 -12
- package/dist/combobox/root/combobox-root.d.ts +21 -2
- package/dist/combobox/root/combobox-root.js +23 -9
- package/dist/command/root/command-root.d.ts +1 -0
- package/dist/command/root/command-root.js +1 -1
- package/dist/data-table/root/data-table-root.d.ts +43 -42
- package/dist/data-table/root/data-table-root.js +35 -34
- package/dist/date-input/root/date-input-root.d.ts +27 -0
- package/dist/date-input/root/date-input-root.js +38 -9
- package/dist/date-picker/root/date-picker-root.d.ts +28 -16
- package/dist/date-picker/root/date-picker-root.js +17 -15
- package/dist/drilldown/root/drilldown-root.d.ts +1 -0
- package/dist/drilldown/root/drilldown-root.js +5 -2
- package/dist/element-events.generated.js +15 -0
- package/dist/empty/root/empty-root.d.ts +12 -7
- package/dist/empty/root/empty-root.js +13 -10
- package/dist/file-input/root/file-input-root.d.ts +5 -1
- package/dist/file-input/root/file-input-root.js +6 -4
- package/dist/filter-input/menu/filter-menu.d.ts +1 -0
- package/dist/filter-input/menu/filter-menu.js +1 -1
- package/dist/filter-input/root/filter-input-root.js +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/input/root/input-root.js +1 -1
- package/dist/lightbox/root/lightbox-root.d.ts +9 -1
- package/dist/lightbox/root/lightbox-root.js +17 -7
- package/dist/listbox/root/listbox-root.d.ts +16 -14
- package/dist/listbox/root/listbox-root.js +24 -15
- package/dist/map/root/map-root.d.ts +6 -3
- package/dist/map/root/map-root.js +8 -2
- package/dist/menu/root/menu-root.d.ts +1 -0
- package/dist/menu/root/menu-root.js +1 -1
- package/dist/notifications/group/notification-group.js +5 -4
- package/dist/notifications/notification/notification.d.ts +10 -10
- package/dist/notifications/notification/notification.js +3 -3
- package/dist/notifications/root/notifications-root.d.ts +1 -0
- package/dist/notifications/root/notifications-root.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -0
- package/dist/number-input/root/number-input-root.js +22 -6
- package/dist/object-inspector/root/object-inspector-root.d.ts +10 -0
- package/dist/object-inspector/root/object-inspector-root.js +10 -2
- package/dist/outline/root/outline-root.d.ts +15 -0
- package/dist/outline/root/outline-root.js +12 -7
- package/dist/pagination/root/pagination-root.d.ts +18 -18
- package/dist/pagination/root/pagination-root.js +5 -5
- package/dist/pagination/size/pagination-size.d.ts +10 -9
- package/dist/pagination/size/pagination-size.js +4 -4
- package/dist/pagination/summary/pagination-summary.js +6 -5
- package/dist/pin-input/root/pin-input-root.d.ts +5 -0
- package/dist/pin-input/root/pin-input-root.js +10 -6
- package/dist/rating/root/rating-root.js +3 -2
- package/dist/select/root/select-root.d.ts +1 -0
- package/dist/select/root/select-root.js +8 -3
- package/dist/slider/root/slider-root.d.ts +12 -0
- package/dist/slider/root/slider-root.js +13 -1
- package/dist/splitter/root/splitter-root.d.ts +44 -35
- package/dist/splitter/root/splitter-root.js +27 -22
- package/dist/switch/root/switch-root.js +1 -0
- package/dist/table/column/table-column.d.ts +17 -0
- package/dist/table/column/table-column.js +16 -4
- package/dist/table/root/table-root.d.ts +1 -0
- package/dist/table/root/table-root.js +1 -1
- package/dist/textarea/root/textarea-root.js +1 -1
- package/dist/time-input/root/time-input-root.d.ts +29 -0
- package/dist/time-input/root/time-input-root.js +31 -10
- package/dist/time-picker/root/time-picker-root.d.ts +14 -0
- package/dist/time-picker/root/time-picker-root.js +16 -14
- package/dist/toast/item/toast-item.d.ts +12 -11
- package/dist/toast/item/toast-item.js +11 -5
- package/dist/toolbar/root/toolbar-root.js +2 -16
- package/dist/tooltip/root/tooltip-root.d.ts +1 -0
- package/dist/tooltip/root/tooltip-root.js +6 -0
- package/dist/tour/root/tour-root.d.ts +10 -10
- package/dist/tour/root/tour-root.js +5 -5
- package/dist/tree/root/tree-root.d.ts +1 -0
- package/dist/tree/root/tree-root.js +1 -1
- package/dist/video/root/video-root.d.ts +84 -0
- package/dist/video/root/video-root.js +116 -41
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +1 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +4 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +5419 -716
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1607 -213
|
@@ -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, valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, isDateValue, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, valueAsDate as asDate, customElement, fillTemplate, dateAsValue as fromDate, HelixFormElement, isDateValue, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { calendarBlank } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -35,6 +35,7 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
35
35
|
this.fitted = undefined;
|
|
36
36
|
this.wide = undefined;
|
|
37
37
|
this.placeholder = 'YYYY-MM-DD';
|
|
38
|
+
this.removeLabel = 'Remove {name}';
|
|
38
39
|
this.step = 1;
|
|
39
40
|
this.draft = '';
|
|
40
41
|
this.handleInput = (event) => {
|
|
@@ -138,21 +139,29 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
138
139
|
get restCount() {
|
|
139
140
|
return Math.max(0, dates(this.value).length - this.shownDates.length);
|
|
140
141
|
}
|
|
142
|
+
get answers() {
|
|
143
|
+
return this.mode === undefined ? undefined : dates(this.value);
|
|
144
|
+
}
|
|
141
145
|
validate() {
|
|
142
146
|
const held = dates(this.value);
|
|
143
147
|
if (held.length > 0 && !held.every(isDateValue)) {
|
|
144
|
-
return this.
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
return (this.badInputMessage ||
|
|
149
|
+
(this.mode === undefined
|
|
150
|
+
? 'Enter a date as YYYY-MM-DD.'
|
|
151
|
+
: 'Enter dates as YYYY-MM-DD, separated by commas.'));
|
|
147
152
|
}
|
|
148
153
|
if (this.min !== '' && held.some((one) => one < this.min)) {
|
|
149
|
-
return
|
|
154
|
+
return fillTemplate(this.rangeUnderflowMessage || 'Choose a date on or after {min}.', {
|
|
155
|
+
min: this.written(this.min),
|
|
156
|
+
});
|
|
150
157
|
}
|
|
151
158
|
if (this.max !== '' && held.some((one) => one > this.max)) {
|
|
152
|
-
return
|
|
159
|
+
return fillTemplate(this.rangeOverflowMessage || 'Choose a date on or before {max}.', {
|
|
160
|
+
max: this.written(this.max),
|
|
161
|
+
});
|
|
153
162
|
}
|
|
154
163
|
if (this.mode === 'range' && held.length > 2) {
|
|
155
|
-
return 'A range is two dates.';
|
|
164
|
+
return this.rangeLengthMessage || 'A range is two dates.';
|
|
156
165
|
}
|
|
157
166
|
return '';
|
|
158
167
|
}
|
|
@@ -194,7 +203,7 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
194
203
|
part="date"
|
|
195
204
|
exportparts="dismiss: date-dismiss, dismiss-mark: date-dismiss-mark, start: date-start"
|
|
196
205
|
dismissible
|
|
197
|
-
dismiss-label=${
|
|
206
|
+
dismiss-label=${fillTemplate(this.removeLabel, { name: this.written(date) })}
|
|
198
207
|
?disabled=${this.isDisabled}
|
|
199
208
|
@helix-dismiss=${(event) => {
|
|
200
209
|
event.stopPropagation();
|
|
@@ -248,7 +257,15 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
248
257
|
</button>
|
|
249
258
|
</div>
|
|
250
259
|
|
|
251
|
-
|
|
260
|
+
${''}
|
|
261
|
+
<div
|
|
262
|
+
part="surface"
|
|
263
|
+
id="surface"
|
|
264
|
+
role="dialog"
|
|
265
|
+
aria-label=${this.triggerLabel}
|
|
266
|
+
popover="manual"
|
|
267
|
+
?hidden=${!this.open}
|
|
268
|
+
>
|
|
252
269
|
${this.renderPicker()}
|
|
253
270
|
</div>
|
|
254
271
|
${this.renderHint()}${this.renderFeedback()}`;
|
|
@@ -302,6 +319,18 @@ __decorate([
|
|
|
302
319
|
__decorate([
|
|
303
320
|
property()
|
|
304
321
|
], HelixHeadlessDateInput.prototype, "placeholder", void 0);
|
|
322
|
+
__decorate([
|
|
323
|
+
property({ attribute: 'range-length-message' })
|
|
324
|
+
], HelixHeadlessDateInput.prototype, "rangeLengthMessage", void 0);
|
|
325
|
+
__decorate([
|
|
326
|
+
property({ attribute: 'range-overflow-message' })
|
|
327
|
+
], HelixHeadlessDateInput.prototype, "rangeOverflowMessage", void 0);
|
|
328
|
+
__decorate([
|
|
329
|
+
property({ attribute: 'range-underflow-message' })
|
|
330
|
+
], HelixHeadlessDateInput.prototype, "rangeUnderflowMessage", void 0);
|
|
331
|
+
__decorate([
|
|
332
|
+
property({ attribute: 'remove-label' })
|
|
333
|
+
], HelixHeadlessDateInput.prototype, "removeLabel", void 0);
|
|
305
334
|
__decorate([
|
|
306
335
|
property({ type: Number })
|
|
307
336
|
], HelixHeadlessDateInput.prototype, "step", void 0);
|
|
@@ -58,6 +58,14 @@ declare const HelixHeadlessDatePicker_base: (new (...args: any[]) => import("@fu
|
|
|
58
58
|
* @cssproperty --date-picker-column-count - How many month columns are drawn, capped at two. `--date-picker-columns` overrides it.
|
|
59
59
|
*/
|
|
60
60
|
export declare class HelixHeadlessDatePicker extends HelixHeadlessDatePicker_base {
|
|
61
|
+
/**
|
|
62
|
+
* What a reader is told when the value holds something that is not a date.
|
|
63
|
+
*
|
|
64
|
+
* **Every sentence a control raises in the browser's bubble is a property**,
|
|
65
|
+
* named for the validity flag it reports, so a form in another language
|
|
66
|
+
* speaks it. Absent is the control's own sentence, in English.
|
|
67
|
+
*/
|
|
68
|
+
badInputMessage?: string;
|
|
61
69
|
/**
|
|
62
70
|
* Month to open on, where nothing declared one.
|
|
63
71
|
*/
|
|
@@ -82,15 +90,6 @@ export declare class HelixHeadlessDatePicker extends HelixHeadlessDatePicker_bas
|
|
|
82
90
|
* Accessible name for the grid.
|
|
83
91
|
*/
|
|
84
92
|
label: string;
|
|
85
|
-
/**
|
|
86
|
-
* The month on show, as `YYYY-MM`. Follows `value`, then the current month.
|
|
87
|
-
*
|
|
88
|
-
* Separate from `value` on purpose, so paging selects nothing and a consumer
|
|
89
|
-
* can drive the view. Reading gives the month on show; writing sets it, and
|
|
90
|
-
* `default-month` seeds one the calendar keeps until somebody does.
|
|
91
|
-
*/
|
|
92
|
-
get month(): string;
|
|
93
|
-
set month(next: string);
|
|
94
93
|
/**
|
|
95
94
|
* Locale for month and day names.
|
|
96
95
|
*
|
|
@@ -105,12 +104,21 @@ export declare class HelixHeadlessDatePicker extends HelixHeadlessDatePicker_bas
|
|
|
105
104
|
* Earliest selectable date, as `YYYY-MM-DD`.
|
|
106
105
|
*/
|
|
107
106
|
min: string;
|
|
108
|
-
/** The month on show, whoever set it, and `undefined` until somebody has. */
|
|
109
|
-
private monthState;
|
|
110
107
|
/**
|
|
111
108
|
* How many dates can be held at once.
|
|
112
109
|
*/
|
|
113
110
|
mode?: 'range' | 'multiple';
|
|
111
|
+
/** The month on show, whoever set it, and `undefined` until somebody has. */
|
|
112
|
+
private monthState;
|
|
113
|
+
/**
|
|
114
|
+
* The month on show, as `YYYY-MM`. Follows `value`, then the current month.
|
|
115
|
+
*
|
|
116
|
+
* Separate from `value` on purpose, so paging selects nothing and a consumer
|
|
117
|
+
* can drive the view. Reading gives the month on show; writing sets it, and
|
|
118
|
+
* `default-month` seeds one the calendar keeps until somebody does.
|
|
119
|
+
*/
|
|
120
|
+
get month(): string;
|
|
121
|
+
set month(next: string);
|
|
114
122
|
/**
|
|
115
123
|
* How many months to show, side by side.
|
|
116
124
|
*/
|
|
@@ -229,6 +237,10 @@ export declare class HelixHeadlessDatePicker extends HelixHeadlessDatePicker_bas
|
|
|
229
237
|
* date including the one already chosen.
|
|
230
238
|
*/
|
|
231
239
|
step: number;
|
|
240
|
+
/**
|
|
241
|
+
* What a reader is told when a date is required and none is chosen.
|
|
242
|
+
*/
|
|
243
|
+
valueMissingMessage?: string;
|
|
232
244
|
/**
|
|
233
245
|
* Reports "required and empty", or clears it.
|
|
234
246
|
*
|
|
@@ -261,11 +273,11 @@ export declare class HelixHeadlessDatePicker extends HelixHeadlessDatePicker_bas
|
|
|
261
273
|
*
|
|
262
274
|
* **Nothing at all without a `name`, and that is the mechanism rather than a
|
|
263
275
|
* detail.** It is what lets a calendar sit inside something that owns the
|
|
264
|
-
* form value, which is how `
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
276
|
+
* form value, which is how `Date Input` holds one. `reportValues` keeps the
|
|
277
|
+
* guard, for every control that sends several answers: a plain string is
|
|
278
|
+
* skipped by the form when its control has no name, but a `FormData` carries
|
|
279
|
+
* its own names and its entries are appended whatever the element is called,
|
|
280
|
+
* so an unnamed calendar would submit empty-named dates.
|
|
269
281
|
*/
|
|
270
282
|
private report;
|
|
271
283
|
/**
|
|
@@ -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 { valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, hostAria, inlineStep, MixinControllerValue, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, hostAria, inlineStep, MixinControllerValue, reportValues, requestChange, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft, caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -231,14 +231,15 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
231
231
|
reportRequired() {
|
|
232
232
|
const anchor = this.partNamed('grid') ?? undefined;
|
|
233
233
|
if (this.required && this.value === '') {
|
|
234
|
-
this.internals.setValidity({ valueMissing: true }, 'Choose a date.', anchor);
|
|
234
|
+
this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage || 'Choose a date.', anchor);
|
|
235
235
|
return;
|
|
236
236
|
}
|
|
237
237
|
const held = this.selected;
|
|
238
238
|
if (held.length > 0 && held.some((one) => asDate(one) === null)) {
|
|
239
|
-
this.internals.setValidity({ badInput: true }, this.
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
this.internals.setValidity({ badInput: true }, this.badInputMessage ||
|
|
240
|
+
(this.mode === undefined
|
|
241
|
+
? 'Enter a date as YYYY-MM-DD.'
|
|
242
|
+
: 'Enter dates as YYYY-MM-DD, separated by commas.'), anchor);
|
|
242
243
|
return;
|
|
243
244
|
}
|
|
244
245
|
this.internals.setValidity({});
|
|
@@ -255,16 +256,11 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
255
256
|
this.reportRequired();
|
|
256
257
|
}
|
|
257
258
|
report() {
|
|
258
|
-
|
|
259
|
-
if (this.name === '' || this.disabled || dates.length === 0) {
|
|
259
|
+
if (this.disabled) {
|
|
260
260
|
this.internals.setFormValue(null);
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
|
-
|
|
264
|
-
for (const date of dates) {
|
|
265
|
-
data.append(this.name, date);
|
|
266
|
-
}
|
|
267
|
-
this.internals.setFormValue(data);
|
|
263
|
+
reportValues(this.internals, this.name, this.selected);
|
|
268
264
|
}
|
|
269
265
|
get monthCount() {
|
|
270
266
|
return Math.max(1, Math.floor(this.months) || 1);
|
|
@@ -391,6 +387,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
391
387
|
this.value = Number.isNaN(ms) ? '' : fromDate(new Date(ms));
|
|
392
388
|
}
|
|
393
389
|
};
|
|
390
|
+
__decorate([
|
|
391
|
+
property({ attribute: 'bad-input-message' })
|
|
392
|
+
], HelixHeadlessDatePicker.prototype, "badInputMessage", void 0);
|
|
394
393
|
__decorate([
|
|
395
394
|
property({ attribute: 'default-month' })
|
|
396
395
|
], HelixHeadlessDatePicker.prototype, "defaultMonth", void 0);
|
|
@@ -409,9 +408,6 @@ __decorate([
|
|
|
409
408
|
__decorate([
|
|
410
409
|
property()
|
|
411
410
|
], HelixHeadlessDatePicker.prototype, "label", void 0);
|
|
412
|
-
__decorate([
|
|
413
|
-
property()
|
|
414
|
-
], HelixHeadlessDatePicker.prototype, "month", null);
|
|
415
411
|
__decorate([
|
|
416
412
|
property()
|
|
417
413
|
], HelixHeadlessDatePicker.prototype, "locale", void 0);
|
|
@@ -424,6 +420,9 @@ __decorate([
|
|
|
424
420
|
__decorate([
|
|
425
421
|
property({ reflect: true })
|
|
426
422
|
], HelixHeadlessDatePicker.prototype, "mode", void 0);
|
|
423
|
+
__decorate([
|
|
424
|
+
property()
|
|
425
|
+
], HelixHeadlessDatePicker.prototype, "month", null);
|
|
427
426
|
__decorate([
|
|
428
427
|
property({ type: Number })
|
|
429
428
|
], HelixHeadlessDatePicker.prototype, "months", void 0);
|
|
@@ -445,6 +444,9 @@ __decorate([
|
|
|
445
444
|
__decorate([
|
|
446
445
|
property({ type: Number })
|
|
447
446
|
], HelixHeadlessDatePicker.prototype, "step", void 0);
|
|
447
|
+
__decorate([
|
|
448
|
+
property({ attribute: 'value-missing-message' })
|
|
449
|
+
], HelixHeadlessDatePicker.prototype, "valueMissingMessage", void 0);
|
|
448
450
|
HelixHeadlessDatePicker = __decorate([
|
|
449
451
|
customElement('helix-headless-date-picker')
|
|
450
452
|
], HelixHeadlessDatePicker);
|
|
@@ -40,6 +40,7 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
|
|
|
40
40
|
* @csspart back-mark - The glyph on the back control.
|
|
41
41
|
* @csspart empty - Shown when there are no entries to show.
|
|
42
42
|
* @csspart header - The bar above a page, holding the way back and its name.
|
|
43
|
+
* @csspart live - The empty and loading lines again, in a region a screen reader hears when they change. Visually hidden in the styled tier.
|
|
43
44
|
* @csspart loading - Shown while the entries are still on their way.
|
|
44
45
|
* @csspart page - The region the rows are in.
|
|
45
46
|
* @csspart title - The name of the page showing.
|
|
@@ -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 { customElement, DrilldownController, HelixElement, hostAria, inlineStep, KeyboardNavigationController, MixinCollection, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, DrilldownController, HelixElement, hostAria, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretLeft } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -48,6 +48,9 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
this.handleKeydown = (event) => {
|
|
51
|
+
if (event.defaultPrevented || (event.key !== 'Escape' && keyClaimed(event))) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
51
54
|
const items = this.items;
|
|
52
55
|
const current = items.findIndex((item) => item.matches(':focus-within'));
|
|
53
56
|
const along = inlineStep(this, event.key);
|
|
@@ -151,7 +154,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
|
|
|
151
154
|
<div aria-busy=${this.loading ? 'true' : nothing} part="page">
|
|
152
155
|
<slot @slotchange=${(event) => this.countRows(event)}></slot>
|
|
153
156
|
${this.renderStatus(this.hasRows)}
|
|
154
|
-
</div
|
|
157
|
+
</div>${this.renderLive(this.hasRows)}`;
|
|
155
158
|
}
|
|
156
159
|
};
|
|
157
160
|
__decorate([
|
|
@@ -4,6 +4,21 @@ registerElementEvents({
|
|
|
4
4
|
'helix-headless-announcement': ['helix-dismiss'],
|
|
5
5
|
'helix-headless-app-header': ['helix-scrolled'],
|
|
6
6
|
'helix-headless-avatar': ['error', 'load'],
|
|
7
|
+
'helix-headless-canvas': [
|
|
8
|
+
'helix-before-move',
|
|
9
|
+
'helix-before-reconnect',
|
|
10
|
+
'helix-before-relabel',
|
|
11
|
+
'helix-canvas-edit',
|
|
12
|
+
'helix-canvas-pan',
|
|
13
|
+
'helix-canvas-view',
|
|
14
|
+
'helix-canvas-zoom',
|
|
15
|
+
'helix-connect',
|
|
16
|
+
'helix-move',
|
|
17
|
+
'helix-reconnect',
|
|
18
|
+
'helix-relabel',
|
|
19
|
+
'helix-remove',
|
|
20
|
+
'helix-select',
|
|
21
|
+
],
|
|
7
22
|
'helix-headless-carousel': ['helix-select'],
|
|
8
23
|
'helix-headless-chat': ['helix-before-pin', 'helix-history', 'helix-send'],
|
|
9
24
|
'helix-headless-chat-composer': ['helix-send'],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type
|
|
1
|
+
import { ArrivalController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary Says that a region has nothing in it, and what to do about it.
|
|
5
5
|
*
|
|
@@ -8,10 +8,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
8
8
|
* to load, so this exists to tell the difference: what would be here, and the
|
|
9
9
|
* one action that would put something here.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Announced, because an empty view usually arrives in place of content that was
|
|
12
|
+
* being fetched: saying so is the only way a screen-reader user learns the
|
|
13
|
+
* search returned nothing, rather than being left waiting. **From a region of
|
|
14
|
+
* its own that is there before its words are**, filled a frame after the view
|
|
15
|
+
* appears. The host was the region, and a page inserts an empty state with its
|
|
16
|
+
* message already in it, which is a region arriving with its words: read
|
|
17
|
+
* inconsistently at best.
|
|
15
18
|
*
|
|
16
19
|
* Every region is a bare slot. The reference ships an `empty-state-heading` and
|
|
17
20
|
* an `empty-state-actions` whose only job is to assign themselves a slot on
|
|
@@ -27,6 +30,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
27
30
|
* @slot actions - The way out.
|
|
28
31
|
* @slot heading - What is missing.
|
|
29
32
|
* @slot icon - A mark above the heading.
|
|
33
|
+
*
|
|
34
|
+
* @csspart live - The heading and the message again, in a region a screen reader hears when the view appears. Visually hidden in the styled tier.
|
|
30
35
|
*/
|
|
31
36
|
export declare class HelixHeadlessEmpty extends HelixElement {
|
|
32
37
|
/**
|
|
@@ -37,7 +42,7 @@ export declare class HelixHeadlessEmpty extends HelixElement {
|
|
|
37
42
|
* has nothing to announce because nothing changed.
|
|
38
43
|
*/
|
|
39
44
|
noAnnounce: boolean;
|
|
40
|
-
protected
|
|
45
|
+
protected readonly arrival: ArrivalController;
|
|
41
46
|
protected render(): TemplateResult;
|
|
42
47
|
}
|
|
43
48
|
declare global {
|
|
@@ -4,24 +4,27 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixElement,
|
|
8
|
-
import { html } from 'lit';
|
|
7
|
+
import { ArrivalController, customElement, HelixElement, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.noAnnounce = false;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.internals.ariaLive = this.noAnnounce ? null : 'polite';
|
|
14
|
+
this.arrival = new ArrivalController(this, {
|
|
15
|
+
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
16
|
+
text: () => slottedWords(this, ['heading', '']),
|
|
17
|
+
});
|
|
19
18
|
}
|
|
20
19
|
render() {
|
|
20
|
+
const say = () => this.arrival.say();
|
|
21
21
|
return html `<slot name="icon"></slot>
|
|
22
|
-
<slot name="heading"></slot>
|
|
23
|
-
<slot></slot>
|
|
24
|
-
<slot name="actions"></slot
|
|
22
|
+
<slot name="heading" @slotchange=${say}></slot>
|
|
23
|
+
<slot @slotchange=${say}></slot>
|
|
24
|
+
<slot name="actions"></slot>
|
|
25
|
+
${this.noAnnounce
|
|
26
|
+
? nothing
|
|
27
|
+
: html `<span part="live" role="status">${this.arrival.said}</span>`}`;
|
|
25
28
|
}
|
|
26
29
|
};
|
|
27
30
|
__decorate([
|
|
@@ -75,7 +75,11 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
|
|
|
75
75
|
*/
|
|
76
76
|
multiple: boolean;
|
|
77
77
|
/**
|
|
78
|
-
* What the control removing one file is called,
|
|
78
|
+
* What the control removing one file is called, with `{name}` filled in.
|
|
79
|
+
*
|
|
80
|
+
* **The name goes in**, so a row of them is heard as which one each
|
|
81
|
+
* removes rather than as "Remove" said once per file. A label with no
|
|
82
|
+
* `{name}` has it added after it.
|
|
79
83
|
*/
|
|
80
84
|
removeLabel: string;
|
|
81
85
|
/**
|
|
@@ -4,12 +4,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, customElement, drawIcon, HelixBeforeChangeEvent, HelixFormElement, MixinField, requestChange, restoreValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, drawIcon, fillTemplate, HelixBeforeChangeEvent, HelixFormElement, MixinField, requestChange, restoreValue, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { trash } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { html } from 'lit/static-html.js';
|
|
12
12
|
import '../../tag/index.js';
|
|
13
|
+
const named = (label, name) => label.includes('{name}') ? fillTemplate(label, { name }) : `${label} ${name}`;
|
|
13
14
|
const size = (bytes, locale) => {
|
|
14
15
|
const units = ['bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
15
16
|
let value = bytes;
|
|
@@ -41,7 +42,7 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
41
42
|
this.accept = '';
|
|
42
43
|
this.locale = '';
|
|
43
44
|
this.multiple = false;
|
|
44
|
-
this.removeLabel = 'Remove';
|
|
45
|
+
this.removeLabel = 'Remove {name}';
|
|
45
46
|
this.triggerLabel = 'Choose files';
|
|
46
47
|
this.dropping = false;
|
|
47
48
|
this.committed = [];
|
|
@@ -143,7 +144,7 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
143
144
|
if (!control) {
|
|
144
145
|
return;
|
|
145
146
|
}
|
|
146
|
-
this.
|
|
147
|
+
this.copyValidity(control);
|
|
147
148
|
this.refreshFeedback();
|
|
148
149
|
}
|
|
149
150
|
firstUpdated(changed) {
|
|
@@ -155,6 +156,7 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
155
156
|
this.control?.focus(options);
|
|
156
157
|
}
|
|
157
158
|
formResetCallback() {
|
|
159
|
+
super.formResetCallback();
|
|
158
160
|
if (this.control) {
|
|
159
161
|
restoreValue(this.control, '');
|
|
160
162
|
}
|
|
@@ -212,7 +214,7 @@ let HelixHeadlessFileInput = class HelixHeadlessFileInput extends MixinField(Hel
|
|
|
212
214
|
<button
|
|
213
215
|
part="remove"
|
|
214
216
|
type="button"
|
|
215
|
-
aria-label=${
|
|
217
|
+
aria-label=${named(this.removeLabel, file.name)}
|
|
216
218
|
data-at=${at}
|
|
217
219
|
?disabled=${this.isDisabled}
|
|
218
220
|
@click=${this.handleRemove}
|
|
@@ -72,6 +72,7 @@ import '../../menu/index.js';
|
|
|
72
72
|
* @csspart menu-back-mark - The glyph on the back control.
|
|
73
73
|
* @csspart menu-empty - Shown when there are no fields to offer.
|
|
74
74
|
* @csspart menu-header - The bar above a field's page, holding the way back and its name.
|
|
75
|
+
* @csspart menu-live - The inner menu's `live`, the region a screen reader hears its empty and loading lines from.
|
|
75
76
|
* @csspart menu-loading - Shown while the fields are still on their way.
|
|
76
77
|
* @csspart menu-surface - The floating panel the menu is drawn on.
|
|
77
78
|
* @csspart menu-title - The name of the field whose page is showing.
|
|
@@ -119,7 +119,7 @@ let HelixHeadlessFilterMenu = class HelixHeadlessFilterMenu extends HelixElement
|
|
|
119
119
|
return html `<${menu}
|
|
120
120
|
part="menu"
|
|
121
121
|
exportparts="back: menu-back, back-mark: menu-back-mark, empty: menu-empty, header: menu-header,
|
|
122
|
-
loading: menu-loading, surface: menu-surface, title: menu-title"
|
|
122
|
+
live: menu-live, loading: menu-loading, surface: menu-surface, title: menu-title"
|
|
123
123
|
label=${this.label}
|
|
124
124
|
@helix-select=${this.handleSelect}
|
|
125
125
|
>
|
|
@@ -304,6 +304,11 @@ let HelixHeadlessFilterInput = class HelixHeadlessFilterInput extends MixinContr
|
|
|
304
304
|
this.releaseCaret?.();
|
|
305
305
|
this.releaseCaret = undefined;
|
|
306
306
|
this.internals.setFormValue(this.value);
|
|
307
|
+
const control = this.control;
|
|
308
|
+
if (control) {
|
|
309
|
+
this.copyValidity(control);
|
|
310
|
+
this.refreshFeedback();
|
|
311
|
+
}
|
|
307
312
|
this.markActive();
|
|
308
313
|
this.settleOpen();
|
|
309
314
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export * from './breadcrumbs/index.js';
|
|
|
21
21
|
export * from './button/index.js';
|
|
22
22
|
export * from './button-group/index.js';
|
|
23
23
|
export * from './callout/index.js';
|
|
24
|
+
export * from './canvas/index.js';
|
|
24
25
|
export * from './card/index.js';
|
|
25
26
|
export * from './carousel/index.js';
|
|
26
27
|
export * from './chat/index.js';
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from './breadcrumbs/index.js';
|
|
|
12
12
|
export * from './button/index.js';
|
|
13
13
|
export * from './button-group/index.js';
|
|
14
14
|
export * from './callout/index.js';
|
|
15
|
+
export * from './canvas/index.js';
|
|
15
16
|
export * from './card/index.js';
|
|
16
17
|
export * from './carousel/index.js';
|
|
17
18
|
export * from './chat/index.js';
|
|
@@ -94,7 +94,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
94
94
|
if (!control) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
this.
|
|
97
|
+
this.copyValidity(control);
|
|
98
98
|
this.refreshFeedback();
|
|
99
99
|
}
|
|
100
100
|
focus(options) {
|
|
@@ -90,7 +90,13 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
|
|
|
90
90
|
private readonly fullscreen;
|
|
91
91
|
private readonly idle;
|
|
92
92
|
protected readonly commands: CommandController;
|
|
93
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* The items, read from the host.
|
|
95
|
+
*
|
|
96
|
+
* **`knownChildren` and not `children`**, which is undefined on the server:
|
|
97
|
+
* spreading it threw the first time a lightbox was rendered there open,
|
|
98
|
+
* which is the first time anything asked it for its items on a server.
|
|
99
|
+
*/
|
|
94
100
|
private get items();
|
|
95
101
|
/** The native dialog, or nothing where there is no DOM to hold one. */
|
|
96
102
|
private get dialog();
|
|
@@ -139,6 +145,8 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
|
|
|
139
145
|
private readonly handleKeydown;
|
|
140
146
|
/** Home and End, which are an index rather than a step. */
|
|
141
147
|
private toEnd;
|
|
148
|
+
/** The item on screen: the one `active` names, or the first where it names none. */
|
|
149
|
+
private get shown();
|
|
142
150
|
/**
|
|
143
151
|
* A press on the backdrop, which lands on the dialog element itself.
|
|
144
152
|
*
|
|
@@ -4,11 +4,10 @@ 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 { CommandController, customElement, FullscreenController, HelixElement, hostAria, IdleController, inlineStep, MixinControllerActive, MixinControllerOpen, resolveActiveItem, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CommandController, customElement, FullscreenController, fillTemplate, HelixElement, hostAria, IdleController, inlineStep, keyClaimed, MixinControllerActive, MixinControllerOpen, resolveActiveItem, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { HelixHeadlessLightboxItem } from '../item/lightbox-item.js';
|
|
11
|
-
const fill = (template, index, count) => template.replaceAll('{index}', String(index)).replaceAll('{count}', String(count));
|
|
12
11
|
let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerActive(MixinControllerOpen(HelixElement)) {
|
|
13
12
|
constructor() {
|
|
14
13
|
super(...arguments);
|
|
@@ -46,6 +45,9 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
46
45
|
this.relayNativeEvent(event);
|
|
47
46
|
};
|
|
48
47
|
this.handleKeydown = (event) => {
|
|
48
|
+
if (keyClaimed(event) || event.altKey || event.ctrlKey || event.metaKey) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
49
51
|
const along = inlineStep(this, event.key);
|
|
50
52
|
if (along === 1 || event.key === 'ArrowDown') {
|
|
51
53
|
event.preventDefault();
|
|
@@ -80,7 +82,7 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
84
|
get items() {
|
|
83
|
-
return
|
|
85
|
+
return this.knownChildren.filter((child) => child instanceof HelixHeadlessLightboxItem);
|
|
84
86
|
}
|
|
85
87
|
get dialog() {
|
|
86
88
|
return this.renderRoot?.querySelector('dialog') ?? null;
|
|
@@ -105,23 +107,27 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
105
107
|
if (items.length === 0) {
|
|
106
108
|
return;
|
|
107
109
|
}
|
|
108
|
-
const
|
|
110
|
+
const shown = this.shown;
|
|
111
|
+
const current = shown ? items.indexOf(shown) : -1;
|
|
109
112
|
const from = current === -1 ? 0 : current;
|
|
110
113
|
const last = items.length - 1;
|
|
111
114
|
const next = this.loop
|
|
112
115
|
? (from + by + items.length) % items.length
|
|
113
116
|
: Math.min(Math.max(from + by, 0), last);
|
|
114
117
|
const target = items[next];
|
|
115
|
-
if (target && target
|
|
118
|
+
if (target && target !== shown) {
|
|
116
119
|
this.requestActive(target.value);
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
toEnd(at) {
|
|
120
123
|
const target = this.items[at];
|
|
121
|
-
if (target && target
|
|
124
|
+
if (target && target !== this.shown) {
|
|
122
125
|
this.requestActive(target.value);
|
|
123
126
|
}
|
|
124
127
|
}
|
|
128
|
+
get shown() {
|
|
129
|
+
return resolveActiveItem(this.active ?? '', this.items);
|
|
130
|
+
}
|
|
125
131
|
willUpdate(changed) {
|
|
126
132
|
super.willUpdate(changed);
|
|
127
133
|
hostAria(this.internals, { label: this.label });
|
|
@@ -138,6 +144,7 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
138
144
|
}
|
|
139
145
|
if (this.open && !dialog.open) {
|
|
140
146
|
dialog.showModal();
|
|
147
|
+
dialog.focus({ preventScroll: true });
|
|
141
148
|
this.idle.stir();
|
|
142
149
|
}
|
|
143
150
|
else if (!this.open && dialog.open) {
|
|
@@ -162,12 +169,15 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
162
169
|
const items = this.items;
|
|
163
170
|
const current = resolveActiveItem(this.active, items);
|
|
164
171
|
const at = current ? items.indexOf(current) : -1;
|
|
165
|
-
this.announcement =
|
|
172
|
+
this.announcement =
|
|
173
|
+
at === -1 ? '' : fillTemplate(this.statusLabel, { count: items.length, index: at + 1 });
|
|
166
174
|
}
|
|
167
175
|
render() {
|
|
168
176
|
return html `<dialog
|
|
169
177
|
part="dialog"
|
|
170
178
|
aria-label=${this.label || 'Lightbox'}
|
|
179
|
+
autofocus
|
|
180
|
+
tabindex="-1"
|
|
171
181
|
@cancel=${this.handleCancel}
|
|
172
182
|
@click=${this.handleBackdrop}
|
|
173
183
|
@close=${this.handleClose}
|