@fusion.dev/helix-headless 0.159.0 → 0.161.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 +2980 -189
- package/dist/canvas/root/canvas-root.d.ts +59 -2
- package/dist/canvas/root/canvas-root.js +123 -8
- package/dist/chat/message/chat-message.d.ts +8 -0
- package/dist/chat/message/chat-message.js +11 -0
- package/dist/chat/root/chat-root.d.ts +47 -1
- package/dist/chat/root/chat-root.js +130 -4
- package/dist/code-block/lines.d.ts +12 -0
- package/dist/code-block/lines.js +41 -0
- package/dist/code-block/root/code-block-root.d.ts +88 -5
- package/dist/code-block/root/code-block-root.js +154 -10
- package/dist/date-input/root/date-input-root.d.ts +108 -19
- package/dist/date-input/root/date-input-root.js +112 -13
- package/dist/date-picker/root/date-picker-root.d.ts +81 -16
- package/dist/date-picker/root/date-picker-root.js +140 -36
- package/dist/element-events.generated.js +6 -0
- package/dist/format-date/fields.js +1 -0
- package/dist/format-date/options.d.ts +3 -1
- package/dist/format-date/options.js +4 -1
- package/dist/format-date/root/format-date-root.d.ts +27 -11
- package/dist/format-date/root/format-date-root.js +6 -0
- package/dist/listbox/root/listbox-root.js +5 -0
- package/dist/notifications/notification/notification.d.ts +1 -0
- package/dist/notifications/notification/notification.js +2 -1
- package/dist/slider/root/slider-root.d.ts +54 -3
- package/dist/slider/root/slider-root.js +124 -2
- package/dist/splitter/root/splitter-root.d.ts +15 -0
- package/dist/splitter/root/splitter-root.js +16 -2
- package/dist/table/grid-controller.d.ts +7 -1
- package/dist/table/grid-controller.js +9 -1
- package/dist/table/root/table-root.d.ts +122 -0
- package/dist/table/root/table-root.js +293 -17
- package/dist/table/row/table-row.d.ts +41 -0
- package/dist/table/row/table-row.js +56 -2
- package/dist/time-input/root/time-input-root.d.ts +55 -7
- package/dist/time-input/root/time-input-root.js +70 -10
- package/dist/time-picker/root/time-picker-root.d.ts +27 -5
- package/dist/time-picker/root/time-picker-root.js +52 -13
- package/dist/timeline/item/timeline-item.d.ts +47 -10
- package/dist/timeline/item/timeline-item.js +36 -4
- package/dist/toggle/group/toggle-group.d.ts +18 -1
- package/dist/toggle/group/toggle-group.js +8 -2
- package/dist/toggle/root/toggle-root.d.ts +2 -2
- package/dist/toggle/root/toggle-root.js +2 -1
- package/dist/video-playlist/item/video-playlist-item.d.ts +11 -0
- package/dist/video-playlist/item/video-playlist-item.js +5 -0
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +6 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +11 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +59 -5
- package/dist/video-playlist/root/video-playlist-root.js +82 -10
- package/dist/virtual-list/fill.d.ts +6 -1
- package/dist/virtual-list/fill.js +1 -1
- package/dist/virtual-list/keys.d.ts +8 -0
- package/dist/virtual-list/keys.js +20 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +98 -13
- package/dist/virtual-list/root/virtual-list-root.js +195 -20
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +1596 -224
- package/types/vue.d.ts +404 -49
- package/types/words.d.ts +151 -0
|
@@ -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 { addDays, addMonths, valueAsDate as asDate, barredBy, calendarLocale, customElement, formatWords, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, handedLocale, hostAria, inlineStep, commaList as list, MixinControllerValue, MixinPickerFeedback,
|
|
7
|
+
import { addDays, addMonths, valueAsDate as asDate, barredBy, calendarLocale, customElement, formatWords, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, handedLocale, hostAria, inlineStep, commaList as list, MixinControllerValue, MixinPickerFeedback, monthOut, monthSystem, periodCells, periodKey, reportValues, requestChange, todayIn, weekendOf, weekStartOf, words, wordsLocale, YEARS_SHOWN, yearOut, yearPageOf, } 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';
|
|
@@ -34,6 +34,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
34
34
|
this.max = '';
|
|
35
35
|
this.min = '';
|
|
36
36
|
this.monthState = undefined;
|
|
37
|
+
this.browsed = false;
|
|
37
38
|
this.months = 1;
|
|
38
39
|
this.monthViewLabel = '{heading}. Choose a month';
|
|
39
40
|
this.nextLabel = 'Next month';
|
|
@@ -45,8 +46,12 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
45
46
|
this.rangeOverflowMessage = 'Choose a date on or before {max}.';
|
|
46
47
|
this.focused = '';
|
|
47
48
|
this.choosing = false;
|
|
49
|
+
this.previewed = '';
|
|
50
|
+
this.handleGridLeave = () => {
|
|
51
|
+
this.previewed = '';
|
|
52
|
+
};
|
|
48
53
|
this.handleKeydown = (event) => {
|
|
49
|
-
if (this.view !== 'day'
|
|
54
|
+
if (this.view !== 'day') {
|
|
50
55
|
this.handlePeriodKeydown(event);
|
|
51
56
|
return;
|
|
52
57
|
}
|
|
@@ -80,7 +85,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
80
85
|
}
|
|
81
86
|
else {
|
|
82
87
|
const step = event.key === 'PageUp' ? -1 : 1;
|
|
83
|
-
this.moveTo(this.system.
|
|
88
|
+
this.moveTo(event.shiftKey ? this.system.addYears(from, step) : this.system.add(from, step));
|
|
84
89
|
}
|
|
85
90
|
event.preventDefault();
|
|
86
91
|
};
|
|
@@ -91,8 +96,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
91
96
|
return;
|
|
92
97
|
}
|
|
93
98
|
if (this.view === 'day') {
|
|
94
|
-
|
|
95
|
-
this.
|
|
99
|
+
const { month, year } = this.system.parts(this.shown);
|
|
100
|
+
this.pageYear = year;
|
|
101
|
+
this.periodFocus = month - 1;
|
|
96
102
|
this.zoom('month');
|
|
97
103
|
}
|
|
98
104
|
else if (this.view === 'month' && this.maxView === 'year') {
|
|
@@ -103,6 +109,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
103
109
|
this.rangeUnderflowMessage = 'Choose a date on or after {min}.';
|
|
104
110
|
this.readOnly = false;
|
|
105
111
|
this.required = false;
|
|
112
|
+
this.selectionLabel = '{kind, select, date {Selected date: {start}} start {Range starts {start}. Choose the day it ends.} range {Selected range: {start} to {end}} other {{count, plural, one {# date selected} other {# dates selected}}}}';
|
|
106
113
|
this.step = 1;
|
|
107
114
|
this.stepMismatchMessage = 'Choose one of the dates the calendar offers.';
|
|
108
115
|
this.timeZone = '';
|
|
@@ -120,6 +127,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
120
127
|
}
|
|
121
128
|
set month(next) {
|
|
122
129
|
const previous = this.month;
|
|
130
|
+
this.browsed = false;
|
|
123
131
|
this.monthState = next;
|
|
124
132
|
this.requestUpdate('month', previous);
|
|
125
133
|
}
|
|
@@ -143,6 +151,30 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
143
151
|
const [first, second] = [dates[0], dates[1]];
|
|
144
152
|
return first <= second ? [first, second] : [second, first];
|
|
145
153
|
}
|
|
154
|
+
get pending() {
|
|
155
|
+
return this.mode === 'range' && this.selected.length === 1;
|
|
156
|
+
}
|
|
157
|
+
get drawnRange() {
|
|
158
|
+
const range = this.range;
|
|
159
|
+
if (range) {
|
|
160
|
+
return { ends: range, preview: false };
|
|
161
|
+
}
|
|
162
|
+
const end = this.previewed || this.focused;
|
|
163
|
+
const start = this.selected[0];
|
|
164
|
+
if (!this.pending ||
|
|
165
|
+
start === undefined ||
|
|
166
|
+
end === '' ||
|
|
167
|
+
end === start ||
|
|
168
|
+
asDate(end) === null) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return { ends: start <= end ? [start, end] : [end, start], preview: true };
|
|
172
|
+
}
|
|
173
|
+
preview(iso) {
|
|
174
|
+
if (this.pending && iso !== this.previewed) {
|
|
175
|
+
this.previewed = iso;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
146
178
|
isSelected(iso) {
|
|
147
179
|
const range = this.range;
|
|
148
180
|
if (range) {
|
|
@@ -161,9 +193,6 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
161
193
|
get system() {
|
|
162
194
|
return monthSystem(this.calendar);
|
|
163
195
|
}
|
|
164
|
-
get ownMonths() {
|
|
165
|
-
return MONTH_CALENDARS.includes(this.calendar ?? '');
|
|
166
|
-
}
|
|
167
196
|
get derivedMonth() {
|
|
168
197
|
const from = asDate(this.selected[0] ?? '') ?? asDate(todayIn(this.timeZone)) ?? new Date();
|
|
169
198
|
return this.system.start(from);
|
|
@@ -226,6 +255,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
226
255
|
requestChange({
|
|
227
256
|
apply: (month) => {
|
|
228
257
|
const previous = this.month;
|
|
258
|
+
this.browsed = true;
|
|
229
259
|
this.monthState = month;
|
|
230
260
|
this.requestUpdate('month', previous);
|
|
231
261
|
},
|
|
@@ -237,6 +267,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
237
267
|
moveTo(wanted) {
|
|
238
268
|
const date = this.clamp(wanted);
|
|
239
269
|
this.focused = fromDate(date);
|
|
270
|
+
this.previewed = '';
|
|
240
271
|
this.show(date);
|
|
241
272
|
this.updateComplete.then(() => {
|
|
242
273
|
this.renderRoot.querySelector('[part~="cell"][tabindex="0"]')?.focus();
|
|
@@ -262,23 +293,25 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
262
293
|
next = [iso];
|
|
263
294
|
}
|
|
264
295
|
this.focused = iso;
|
|
296
|
+
this.previewed = '';
|
|
265
297
|
this.choosing = true;
|
|
266
298
|
this.requestValue(next.join(','));
|
|
267
299
|
}
|
|
268
300
|
get periodYear() {
|
|
269
|
-
return this.pageYear ?? this.
|
|
301
|
+
return this.pageYear ?? this.system.parts(this.shown).year;
|
|
270
302
|
}
|
|
271
303
|
get periodStop() {
|
|
272
|
-
if (this.
|
|
273
|
-
return this.periodFocus;
|
|
304
|
+
if (this.view === 'year') {
|
|
305
|
+
return this.periodFocus ?? this.periodYear;
|
|
274
306
|
}
|
|
275
|
-
|
|
307
|
+
const index = this.periodFocus ?? this.system.parts(this.shown).month - 1;
|
|
308
|
+
return Math.min(index, this.system.months(this.periodYear) - 1);
|
|
276
309
|
}
|
|
277
310
|
monthOut(first) {
|
|
278
|
-
return monthOut(first, this.min, this.max);
|
|
311
|
+
return monthOut(first, this.min, this.max, this.system);
|
|
279
312
|
}
|
|
280
313
|
yearOut(year) {
|
|
281
|
-
return yearOut(year, this.min, this.max);
|
|
314
|
+
return yearOut(year, this.min, this.max, this.system);
|
|
282
315
|
}
|
|
283
316
|
zoom(view) {
|
|
284
317
|
this.view = view;
|
|
@@ -293,8 +326,8 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
293
326
|
return;
|
|
294
327
|
}
|
|
295
328
|
this.pageYear = at;
|
|
296
|
-
const month = this.
|
|
297
|
-
const open = Array.from({ length:
|
|
329
|
+
const month = this.system.parts(this.shown).month - 1;
|
|
330
|
+
const open = Array.from({ length: this.system.months(at) }, (_, index) => index).filter((index) => !this.monthOut(this.system.from(at, index + 1, 1)));
|
|
298
331
|
this.periodFocus = open.includes(month)
|
|
299
332
|
? month
|
|
300
333
|
: ([...open].sort((left, right) => Math.abs(left - month) - Math.abs(right - month))[0] ??
|
|
@@ -302,12 +335,12 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
302
335
|
this.zoom('month');
|
|
303
336
|
return;
|
|
304
337
|
}
|
|
305
|
-
const first =
|
|
338
|
+
const first = this.system.from(this.periodYear, at + 1, 1);
|
|
306
339
|
if (this.monthOut(first)) {
|
|
307
340
|
return;
|
|
308
341
|
}
|
|
309
342
|
this.show(first);
|
|
310
|
-
if (this.month !==
|
|
343
|
+
if (this.month !== this.system.key(first)) {
|
|
311
344
|
return;
|
|
312
345
|
}
|
|
313
346
|
this.pageYear = undefined;
|
|
@@ -344,7 +377,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
344
377
|
this.choosePeriod(stop);
|
|
345
378
|
return;
|
|
346
379
|
}
|
|
347
|
-
const moved = periodKey(this.view === 'year' ? 'year' : 'month', stop, this.periodYear, event.key, inlineStep(this, event.key));
|
|
380
|
+
const moved = periodKey(this.view === 'year' ? 'year' : 'month', stop, this.periodYear, event.key, inlineStep(this, event.key), (year) => this.system.months(year));
|
|
348
381
|
if (moved === null) {
|
|
349
382
|
return;
|
|
350
383
|
}
|
|
@@ -354,10 +387,26 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
354
387
|
void this.updateComplete.then(() => this.focus());
|
|
355
388
|
}
|
|
356
389
|
focus(options) {
|
|
390
|
+
if (this.isUpdatePending) {
|
|
391
|
+
void this.updateComplete.then(() => this.focus(options));
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
357
394
|
this.renderRoot
|
|
358
395
|
?.querySelector('[part~="cell"][tabindex="0"], [part~="period"][tabindex="0"]')
|
|
359
396
|
?.focus(options);
|
|
360
397
|
}
|
|
398
|
+
showChosen() {
|
|
399
|
+
this.focused = '';
|
|
400
|
+
this.pageYear = undefined;
|
|
401
|
+
this.periodFocus = undefined;
|
|
402
|
+
this.view = 'day';
|
|
403
|
+
if (this.browsed) {
|
|
404
|
+
this.browsed = false;
|
|
405
|
+
const previous = this.month;
|
|
406
|
+
this.monthState = undefined;
|
|
407
|
+
this.requestUpdate('month', previous);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
361
410
|
connectedCallback() {
|
|
362
411
|
super.connectedCallback();
|
|
363
412
|
this.addEventListener('keydown', this.handleKeydown);
|
|
@@ -372,6 +421,28 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
372
421
|
}
|
|
373
422
|
return super.requestValue(next);
|
|
374
423
|
}
|
|
424
|
+
get selectionWords() {
|
|
425
|
+
const dates = this.selected.map((one) => asDate(one));
|
|
426
|
+
const first = dates[0];
|
|
427
|
+
if (!first || dates.some((one) => one === null)) {
|
|
428
|
+
return '';
|
|
429
|
+
}
|
|
430
|
+
const { long } = this.formats;
|
|
431
|
+
const range = this.range;
|
|
432
|
+
const kind = range
|
|
433
|
+
? 'range'
|
|
434
|
+
: this.pending
|
|
435
|
+
? 'start'
|
|
436
|
+
: this.mode === 'multiple'
|
|
437
|
+
? 'dates'
|
|
438
|
+
: 'date';
|
|
439
|
+
return formatWords(this, 'selectionLabel', {
|
|
440
|
+
count: dates.length,
|
|
441
|
+
end: range ? long.format(asDate(range[1])) : '',
|
|
442
|
+
kind,
|
|
443
|
+
start: long.format(range ? asDate(range[0]) : first),
|
|
444
|
+
});
|
|
445
|
+
}
|
|
375
446
|
spoken(iso) {
|
|
376
447
|
const date = asDate(iso);
|
|
377
448
|
return date ? this.formats.long.format(date) : iso;
|
|
@@ -399,24 +470,38 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
399
470
|
: ['stepMismatch', this.stepMismatchMessage];
|
|
400
471
|
}
|
|
401
472
|
reportRequired() {
|
|
402
|
-
const
|
|
403
|
-
if (
|
|
404
|
-
this.internals.setValidity(
|
|
473
|
+
const problem = this.problem;
|
|
474
|
+
if (problem) {
|
|
475
|
+
this.internals.setValidity(problem[0], problem[1], this.partNamed('grid') ?? undefined);
|
|
405
476
|
return;
|
|
406
477
|
}
|
|
478
|
+
this.internals.setValidity({});
|
|
479
|
+
}
|
|
480
|
+
get problem() {
|
|
481
|
+
if (this.required && this.value === '') {
|
|
482
|
+
return [{ valueMissing: true }, this.valueMissingMessage];
|
|
483
|
+
}
|
|
407
484
|
const held = this.selected;
|
|
408
485
|
if (held.length > 0 && held.some((one) => asDate(one) === null)) {
|
|
409
|
-
|
|
410
|
-
|
|
486
|
+
return [
|
|
487
|
+
{ badInput: true },
|
|
488
|
+
formatWords(this, 'badInputMessage', { mode: this.mode ?? 'single' }),
|
|
489
|
+
];
|
|
411
490
|
}
|
|
412
491
|
for (const one of held) {
|
|
413
492
|
const fault = this.fault(one);
|
|
414
493
|
if (fault) {
|
|
415
|
-
|
|
416
|
-
return;
|
|
494
|
+
return [{ [fault[0]]: true }, fault[1]];
|
|
417
495
|
}
|
|
418
496
|
}
|
|
419
|
-
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
get failure() {
|
|
500
|
+
const problem = this.problem;
|
|
501
|
+
if (!problem) {
|
|
502
|
+
return undefined;
|
|
503
|
+
}
|
|
504
|
+
return problem[0].valueMissing ? 'missing' : 'refused';
|
|
420
505
|
}
|
|
421
506
|
willUpdate(changed) {
|
|
422
507
|
super.willUpdate(changed);
|
|
@@ -431,6 +516,10 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
431
516
|
role: 'group',
|
|
432
517
|
});
|
|
433
518
|
this.internals.ariaDisabled = this.isDisabled ? 'true' : null;
|
|
519
|
+
this.toggleState('blank', this.value === '');
|
|
520
|
+
this.toggleState('range-pending', this.pending);
|
|
521
|
+
this.toggleState('month-view', this.view === 'month');
|
|
522
|
+
this.toggleState('year-view', this.view === 'year');
|
|
434
523
|
this.report();
|
|
435
524
|
}
|
|
436
525
|
updated(changed) {
|
|
@@ -448,9 +537,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
448
537
|
return Math.max(1, Math.floor(this.months) || 1);
|
|
449
538
|
}
|
|
450
539
|
get formats() {
|
|
451
|
-
const language = this.
|
|
452
|
-
? `${new Intl.Locale(this.language || new Intl.DateTimeFormat().resolvedOptions().locale, { calendar: this.calendar ?? 'gregory' })}`
|
|
453
|
-
: calendarLocale(this.language, this.calendar);
|
|
540
|
+
const language = calendarLocale(this.language, this.calendar);
|
|
454
541
|
if (this.cachedFormats?.locale === language) {
|
|
455
542
|
return this.cachedFormats;
|
|
456
543
|
}
|
|
@@ -489,7 +576,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
489
576
|
const weeks = this.weeksOf(month);
|
|
490
577
|
const anchor = fromDate(this.anchor);
|
|
491
578
|
const today = todayIn(this.timeZone);
|
|
492
|
-
const
|
|
579
|
+
const drawn = this.drawnRange;
|
|
580
|
+
const range = drawn?.ends ?? null;
|
|
581
|
+
const preview = drawn?.preview === true;
|
|
493
582
|
const weekend = this.weekend;
|
|
494
583
|
const first = index === 0;
|
|
495
584
|
const last = index === this.monthCount - 1;
|
|
@@ -526,8 +615,11 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
526
615
|
part="grid"
|
|
527
616
|
role="grid"
|
|
528
617
|
aria-label=${heading}
|
|
618
|
+
aria-describedby=${this.selectionWords === '' ? nothing : 'selection'}
|
|
619
|
+
aria-multiselectable=${this.mode === undefined ? nothing : 'true'}
|
|
529
620
|
aria-readonly=${this.readOnly ? 'true' : nothing}
|
|
530
621
|
data-unset=${this.value === '' ? '' : nothing}
|
|
622
|
+
@pointerleave=${this.handleGridLeave}
|
|
531
623
|
>
|
|
532
624
|
<div part="week" role="row">
|
|
533
625
|
${weeks[0]?.map((date) => html `<span part="weekday" role="columnheader" aria-label=${weekdayName.format(date)}
|
|
@@ -553,11 +645,13 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
553
645
|
data-outside=${outside ? '' : nothing}
|
|
554
646
|
data-range-end=${end ? '' : nothing}
|
|
555
647
|
data-range-middle=${middle ? '' : nothing}
|
|
648
|
+
data-range-preview=${preview && (start || middle || end) ? '' : nothing}
|
|
556
649
|
data-range-start=${start ? '' : nothing}
|
|
557
650
|
data-today=${iso === today ? '' : nothing}
|
|
558
651
|
data-weekend=${weekend.includes(date.getUTCDay()) ? '' : nothing}
|
|
559
652
|
tabindex=${!outside && iso === anchor && !this.isDisabled ? '0' : '-1'}
|
|
560
653
|
@click=${outside ? nothing : () => this.select(date)}
|
|
654
|
+
@pointerenter=${outside ? nothing : () => this.preview(iso)}
|
|
561
655
|
><span
|
|
562
656
|
part="day${!outside && selected && !middle ? ' day-selected' : ''}${iso === today ? ' day-today' : ''}${outside ? ' day-outside' : ''}${disabled ? ' day-disabled' : ''}${weekend.includes(date.getUTCDay()) ? ' day-weekend' : ''}"
|
|
563
657
|
>${this.renderDay(date, outside)}</span
|
|
@@ -573,7 +667,6 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
573
667
|
}
|
|
574
668
|
renderHeadingText(text, label) {
|
|
575
669
|
const steps = this.maxView !== undefined &&
|
|
576
|
-
!this.ownMonths &&
|
|
577
670
|
(this.view === 'day' || (this.view === 'month' && this.maxView === 'year'));
|
|
578
671
|
if (!steps) {
|
|
579
672
|
return text;
|
|
@@ -591,14 +684,15 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
591
684
|
const years = this.view === 'year';
|
|
592
685
|
const page = years ? yearPageOf(this.periodYear) : this.periodYear;
|
|
593
686
|
const heading = years
|
|
594
|
-
? `${yearName.format(
|
|
595
|
-
: yearName.format(
|
|
687
|
+
? `${yearName.format(this.system.from(page, 1, 1))} – ${yearName.format(this.system.from(page + YEARS_SHOWN - 1, 1, 1))}`
|
|
688
|
+
: yearName.format(this.system.from(page, 1, 1));
|
|
596
689
|
const stop = this.periodStop;
|
|
597
690
|
const cells = periodCells({
|
|
598
691
|
max: this.max,
|
|
599
692
|
min: this.min,
|
|
600
693
|
page: this.periodYear,
|
|
601
694
|
shown: this.shown,
|
|
695
|
+
system: this.system,
|
|
602
696
|
today: todayIn(this.timeZone),
|
|
603
697
|
view: years ? 'year' : 'month',
|
|
604
698
|
}).map(({ at, chosen, current, first, out }) => {
|
|
@@ -615,7 +709,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
615
709
|
>${words}</span
|
|
616
710
|
>`;
|
|
617
711
|
});
|
|
618
|
-
const rows =
|
|
712
|
+
const rows = Array.from({ length: Math.ceil(cells.length / 3) }, (_, row) => row * 3).map((from) => html `<div part="period-row" role="row">${cells.slice(from, from + 3)}</div>`);
|
|
619
713
|
return html `<div part="month">
|
|
620
714
|
<div part="header">
|
|
621
715
|
<button
|
|
@@ -644,7 +738,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
644
738
|
</div>`;
|
|
645
739
|
}
|
|
646
740
|
render() {
|
|
647
|
-
if (this.view !== 'day'
|
|
741
|
+
if (this.view !== 'day') {
|
|
648
742
|
return html `<slot name="header"></slot>
|
|
649
743
|
<div part="months" style="--date-picker-column-count: 1">${this.renderPeriods()}</div>
|
|
650
744
|
<slot name="footer"></slot>${this.renderPickerFeedback()}`;
|
|
@@ -655,6 +749,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
655
749
|
<div part="months" style="--date-picker-column-count: ${Math.min(count, 2)}">
|
|
656
750
|
${Array.from({ length: count }, (_, index) => this.renderMonth(this.system.add(shown, index), index))}
|
|
657
751
|
</div>
|
|
752
|
+
<span part="selection" id="selection" data-spoken aria-live="polite"
|
|
753
|
+
>${this.selectionWords}</span
|
|
754
|
+
>
|
|
658
755
|
<slot name="footer"></slot>${this.renderPickerFeedback()}`;
|
|
659
756
|
}
|
|
660
757
|
get valueAsDate() {
|
|
@@ -755,6 +852,9 @@ __decorate([
|
|
|
755
852
|
__decorate([
|
|
756
853
|
state()
|
|
757
854
|
], HelixHeadlessDatePicker.prototype, "focused", void 0);
|
|
855
|
+
__decorate([
|
|
856
|
+
state()
|
|
857
|
+
], HelixHeadlessDatePicker.prototype, "previewed", void 0);
|
|
758
858
|
__decorate([
|
|
759
859
|
state()
|
|
760
860
|
], HelixHeadlessDatePicker.prototype, "pageYear", void 0);
|
|
@@ -771,6 +871,10 @@ __decorate([
|
|
|
771
871
|
__decorate([
|
|
772
872
|
property({ reflect: true, type: Boolean })
|
|
773
873
|
], HelixHeadlessDatePicker.prototype, "required", void 0);
|
|
874
|
+
__decorate([
|
|
875
|
+
words,
|
|
876
|
+
property({ attribute: 'selection-label' })
|
|
877
|
+
], HelixHeadlessDatePicker.prototype, "selectionLabel", void 0);
|
|
774
878
|
__decorate([
|
|
775
879
|
property({ type: Number })
|
|
776
880
|
], HelixHeadlessDatePicker.prototype, "step", void 0);
|
|
@@ -36,6 +36,7 @@ registerElementEvents({
|
|
|
36
36
|
'helix-headless-chat-message': ['helix-send'],
|
|
37
37
|
'helix-headless-checkbox': ['change', 'helix-before-toggle', 'input'],
|
|
38
38
|
'helix-headless-checkbox-group': ['change', 'helix-before-change', 'input'],
|
|
39
|
+
'helix-headless-code-block': ['helix-before-toggle', 'helix-toggle'],
|
|
39
40
|
'helix-headless-color-input': [
|
|
40
41
|
'change',
|
|
41
42
|
'helix-before-change',
|
|
@@ -92,6 +93,7 @@ registerElementEvents({
|
|
|
92
93
|
'helix-before-change',
|
|
93
94
|
'helix-before-close',
|
|
94
95
|
'helix-before-open',
|
|
96
|
+
'helix-clear',
|
|
95
97
|
'input',
|
|
96
98
|
'toggle',
|
|
97
99
|
],
|
|
@@ -252,11 +254,14 @@ registerElementEvents({
|
|
|
252
254
|
'helix-headless-tab-panel': ['helix-load'],
|
|
253
255
|
'helix-headless-table': [
|
|
254
256
|
'helix-before-reorder',
|
|
257
|
+
'helix-before-toggle',
|
|
258
|
+
'helix-load-more',
|
|
255
259
|
'helix-reorder',
|
|
256
260
|
'helix-select',
|
|
257
261
|
'helix-selected',
|
|
258
262
|
'helix-sort',
|
|
259
263
|
'helix-sorted',
|
|
264
|
+
'helix-toggle',
|
|
260
265
|
],
|
|
261
266
|
'helix-headless-table-column': ['helix-before-resize', 'helix-resized'],
|
|
262
267
|
'helix-headless-tabs': ['helix-activate', 'helix-before-activate', 'helix-select'],
|
|
@@ -268,6 +273,7 @@ registerElementEvents({
|
|
|
268
273
|
'helix-before-change',
|
|
269
274
|
'helix-before-close',
|
|
270
275
|
'helix-before-open',
|
|
276
|
+
'helix-clear',
|
|
271
277
|
'input',
|
|
272
278
|
'toggle',
|
|
273
279
|
],
|
|
@@ -3,6 +3,7 @@ export const FIELD = {
|
|
|
3
3
|
day: (value) => html `<span part="day">${value}</span>`,
|
|
4
4
|
dayPeriod: (value) => html `<span part="day-period">${value}</span>`,
|
|
5
5
|
era: (value) => html `<span part="era">${value}</span>`,
|
|
6
|
+
fractionalSecond: (value) => html `<span part="fractional-second">${value}</span>`,
|
|
6
7
|
hour: (value) => html `<span part="hour">${value}</span>`,
|
|
7
8
|
minute: (value) => html `<span part="minute">${value}</span>`,
|
|
8
9
|
month: (value) => html `<span part="month">${value}</span>`,
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
export interface Asked {
|
|
6
6
|
dateStyle?: 'full' | 'long' | 'medium' | 'short' | undefined;
|
|
7
7
|
day?: 'numeric' | '2-digit' | undefined;
|
|
8
|
+
dayPeriod?: 'long' | 'narrow' | 'short' | undefined;
|
|
8
9
|
era?: 'long' | 'narrow' | 'short' | undefined;
|
|
10
|
+
fractionalSecondDigits?: 1 | 2 | 3 | undefined;
|
|
9
11
|
hour?: 'numeric' | '2-digit' | undefined;
|
|
10
12
|
hourCycle?: 'h11' | 'h12' | 'h23' | 'h24' | undefined;
|
|
11
13
|
minute?: 'numeric' | '2-digit' | undefined;
|
|
@@ -13,7 +15,7 @@ export interface Asked {
|
|
|
13
15
|
second?: 'numeric' | '2-digit' | undefined;
|
|
14
16
|
timeStyle?: 'full' | 'long' | 'medium' | 'short' | undefined;
|
|
15
17
|
timeZone?: string | undefined;
|
|
16
|
-
timeZoneName?: 'long' | 'short' | undefined;
|
|
18
|
+
timeZoneName?: 'long' | 'longGeneric' | 'longOffset' | 'short' | 'shortGeneric' | 'shortOffset' | undefined;
|
|
17
19
|
weekday?: 'long' | 'short' | 'narrow' | undefined;
|
|
18
20
|
year?: 'numeric' | '2-digit' | undefined;
|
|
19
21
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { FIELD } from './fields.js';
|
|
2
|
-
const FIELDS =
|
|
2
|
+
const FIELDS = [
|
|
3
|
+
...Object.keys(FIELD).filter((one) => one !== 'fractionalSecond'),
|
|
4
|
+
'fractionalSecondDigits',
|
|
5
|
+
];
|
|
3
6
|
export const formatOptions = (asked, dateOnly = false) => {
|
|
4
7
|
const options = {
|
|
5
8
|
hourCycle: asked.hourCycle,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DateCalendar, HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { type DateCalendar, HelixElement, type MonthCalendar } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary A timestamp, formatted for the user's locale.
|
|
@@ -45,8 +45,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
45
45
|
*
|
|
46
46
|
* **A date is written in a calendar Date Picker draws**: the locale's own
|
|
47
47
|
* where its months are the Gregorian months, as `th-TH` writes 2569 for 2026,
|
|
48
|
-
* and `gregory` where they are not, as for `fa-IR`. `calendar` picks
|
|
49
|
-
*
|
|
48
|
+
* and `gregory` where they are not, as for `fa-IR`. `calendar` picks any of
|
|
49
|
+
* them, `persian` and `hebrew` included.
|
|
50
50
|
*
|
|
51
51
|
* @since 0.1.0
|
|
52
52
|
* @status stable
|
|
@@ -57,6 +57,7 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
57
57
|
* @csspart day - The day of the month, with `fields`.
|
|
58
58
|
* @csspart day-period - AM or PM, or the locale's word for the part of the day, with `fields`.
|
|
59
59
|
* @csspart era - The era, such as AD, with `fields` and `era`.
|
|
60
|
+
* @csspart fractional-second - The fraction of a second, with `fields` and `fractional-second-digits`.
|
|
60
61
|
* @csspart hour - The hour, with `fields`.
|
|
61
62
|
* @csspart minute - The minute, with `fields`.
|
|
62
63
|
* @csspart month - The month, with `fields`.
|
|
@@ -72,14 +73,16 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
72
73
|
export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
73
74
|
/**
|
|
74
75
|
* The calendar a date is written in: `gregory`, `buddhist`, `japanese`,
|
|
75
|
-
* `roc`, or `iso8601`,
|
|
76
|
+
* `roc`, or `iso8601`, or a calendar with months of its own, such as
|
|
77
|
+
* `persian`, `hebrew`, `islamic-umalqura`, `ethiopic`, or `chinese`: every
|
|
78
|
+
* calendar Date Picker and Date Input draw.
|
|
76
79
|
*
|
|
77
|
-
* Absent is the locale's own where
|
|
78
|
-
* `buddhist` for `th-TH`, and `gregory` for every other, such as
|
|
79
|
-
* for `fa-IR`, so a date written here reads as the same date a
|
|
80
|
-
* beside it shows.
|
|
80
|
+
* Absent is the locale's own where its months are the Gregorian months,
|
|
81
|
+
* such as `buddhist` for `th-TH`, and `gregory` for every other, such as
|
|
82
|
+
* `persian` for `fa-IR`, so a date written here reads as the same date a
|
|
83
|
+
* Date Picker beside it shows. Write `calendar="persian"` for Mehr 14, 1405.
|
|
81
84
|
*/
|
|
82
|
-
calendar?: DateCalendar;
|
|
85
|
+
calendar?: DateCalendar | MonthCalendar;
|
|
83
86
|
/**
|
|
84
87
|
* The timestamp, in any format `Date` can parse.
|
|
85
88
|
*
|
|
@@ -107,6 +110,12 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
107
110
|
* How the day of the month is written, where a date is shown.
|
|
108
111
|
*/
|
|
109
112
|
day?: 'numeric' | '2-digit';
|
|
113
|
+
/**
|
|
114
|
+
* Writes the part of the day in words, such as "in the morning" or "at
|
|
115
|
+
* night", in its `long`, `short`, or `narrow` form, where `hour` is on a
|
|
116
|
+
* twelve-hour clock.
|
|
117
|
+
*/
|
|
118
|
+
dayPeriod?: 'long' | 'narrow' | 'short';
|
|
110
119
|
/**
|
|
111
120
|
* Shows how long ago the timestamp was, in a compact form such as "3h", in
|
|
112
121
|
* place of the date.
|
|
@@ -130,6 +139,11 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
130
139
|
* way.
|
|
131
140
|
*/
|
|
132
141
|
fields?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* How many digits of a fraction of a second to write after `second`: 1, 2,
|
|
144
|
+
* or 3, as in 09:41:07.250.
|
|
145
|
+
*/
|
|
146
|
+
fractionalSecondDigits?: 1 | 2 | 3;
|
|
133
147
|
/**
|
|
134
148
|
* Draws an `elapsed` or `relative` reading once and leaves it, where it
|
|
135
149
|
* would otherwise move on as it goes stale.
|
|
@@ -206,9 +220,11 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
|
|
|
206
220
|
*/
|
|
207
221
|
timeZone?: string;
|
|
208
222
|
/**
|
|
209
|
-
* Shows the name of the time zone
|
|
223
|
+
* Shows the name of the time zone: `long` or `short`, as Pacific Daylight
|
|
224
|
+
* Time or PDT, `longOffset` or `shortOffset`, as GMT-07:00 or GMT-7, or
|
|
225
|
+
* `longGeneric` or `shortGeneric`, as Pacific Time or PT.
|
|
210
226
|
*/
|
|
211
|
-
timeZoneName?: 'long' | 'short';
|
|
227
|
+
timeZoneName?: 'long' | 'longGeneric' | 'longOffset' | 'short' | 'shortGeneric' | 'shortOffset';
|
|
212
228
|
/**
|
|
213
229
|
* How the weekday is written, where one is shown.
|
|
214
230
|
*/
|
|
@@ -132,6 +132,9 @@ __decorate([
|
|
|
132
132
|
__decorate([
|
|
133
133
|
property()
|
|
134
134
|
], HelixHeadlessFormatDate.prototype, "day", void 0);
|
|
135
|
+
__decorate([
|
|
136
|
+
property({ attribute: 'day-period' })
|
|
137
|
+
], HelixHeadlessFormatDate.prototype, "dayPeriod", void 0);
|
|
135
138
|
__decorate([
|
|
136
139
|
property({ reflect: true, type: Boolean })
|
|
137
140
|
], HelixHeadlessFormatDate.prototype, "elapsed", void 0);
|
|
@@ -141,6 +144,9 @@ __decorate([
|
|
|
141
144
|
__decorate([
|
|
142
145
|
property({ type: Boolean })
|
|
143
146
|
], HelixHeadlessFormatDate.prototype, "fields", void 0);
|
|
147
|
+
__decorate([
|
|
148
|
+
property({ attribute: 'fractional-second-digits', type: Number })
|
|
149
|
+
], HelixHeadlessFormatDate.prototype, "fractionalSecondDigits", void 0);
|
|
144
150
|
__decorate([
|
|
145
151
|
property({ type: Boolean })
|
|
146
152
|
], HelixHeadlessFormatDate.prototype, "frozen", void 0);
|
|
@@ -98,6 +98,11 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
98
98
|
}
|
|
99
99
|
else if (event.key === ' ') {
|
|
100
100
|
event.preventDefault();
|
|
101
|
+
const at = this.currentValue || shown.find((option) => !option.disabled)?.value;
|
|
102
|
+
if (at) {
|
|
103
|
+
this.activeValue = at;
|
|
104
|
+
this.choose(at);
|
|
105
|
+
}
|
|
101
106
|
}
|
|
102
107
|
return;
|
|
103
108
|
}
|
|
@@ -56,6 +56,7 @@ declare const HelixHeadlessNotification_base: (new (...args: any[]) => import("@
|
|
|
56
56
|
* @csspart time-day - Format Date's `day`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
57
57
|
* @csspart time-day-period - Format Date's `day-period`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
58
58
|
* @csspart time-era - Format Date's `era`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
59
|
+
* @csspart time-fractional-second - Format Date's `fractional-second`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
59
60
|
* @csspart time-hour - Format Date's `hour`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
60
61
|
* @csspart time-minute - Format Date's `minute`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
61
62
|
* @csspart time-month - Format Date's `month`, forwarded for a time drawn as fields. An elapsed time draws none.
|
|
@@ -104,7 +104,8 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
104
104
|
renderTime() {
|
|
105
105
|
const stamp = this.tag('format-date');
|
|
106
106
|
return html `<${stamp}
|
|
107
|
-
exportparts="time, day: time-day, day-period: time-day-period, era: time-era,
|
|
107
|
+
exportparts="time, day: time-day, day-period: time-day-period, era: time-era,
|
|
108
|
+
fractional-second: time-fractional-second, hour: time-hour,
|
|
108
109
|
minute: time-minute, month: time-month, second: time-second,
|
|
109
110
|
time-zone-name: time-time-zone-name, weekday: time-weekday, year: time-year"
|
|
110
111
|
elapsed
|