@fusion.dev/helix-headless 0.154.0 → 0.156.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 +3213 -179
- package/dist/accordion/item/accordion-item.d.ts +15 -0
- package/dist/accordion/item/accordion-item.js +12 -1
- package/dist/accordion/root/accordion-root.d.ts +2 -1
- package/dist/accordion/root/accordion-root.js +1 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +36 -3
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +42 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +15 -5
- package/dist/breadcrumbs/root/breadcrumbs-root.js +29 -4
- package/dist/button-group/root/button-group-root.d.ts +2 -0
- package/dist/button-group/root/button-group-root.js +1 -0
- package/dist/canvas/node/canvas-node.js +1 -1
- package/dist/canvas/root/canvas-root.d.ts +17 -2
- package/dist/canvas/root/canvas-root.js +23 -6
- package/dist/chat/composer/chat-composer.js +1 -1
- package/dist/chat/root/chat-root.d.ts +14 -1
- package/dist/chat/root/chat-root.js +14 -4
- package/dist/color-input/root/color-input-root.d.ts +9 -3
- package/dist/color-input/root/color-input-root.js +3 -1
- package/dist/color-picker/channels.d.ts +5 -3
- package/dist/color-picker/channels.js +79 -21
- package/dist/color-picker/root/color-picker-root.d.ts +58 -5
- package/dist/color-picker/root/color-picker-root.js +75 -13
- package/dist/combobox/root/combobox-root.d.ts +10 -0
- package/dist/combobox/root/combobox-root.js +18 -3
- package/dist/command/root/command-root.d.ts +116 -1
- package/dist/command/root/command-root.js +124 -15
- package/dist/data-table/root/data-table-root.d.ts +25 -0
- package/dist/data-table/root/data-table-root.js +13 -3
- package/dist/date-input/root/date-input-root.d.ts +33 -1
- package/dist/date-input/root/date-input-root.js +9 -2
- package/dist/date-picker/root/date-picker-root.d.ts +43 -13
- package/dist/date-picker/root/date-picker-root.js +54 -31
- package/dist/element-events.generated.js +3 -1
- package/dist/graph/root/graph-root.d.ts +13 -0
- package/dist/graph/root/graph-root.js +16 -0
- package/dist/list/root/list-root.d.ts +74 -1
- package/dist/list/root/list-root.js +92 -4
- package/dist/list/selection.js +3 -3
- package/dist/map/root/map-root.d.ts +6 -0
- package/dist/map/root/map-root.js +8 -1
- package/dist/navigation/root/navigation-root.d.ts +26 -0
- package/dist/navigation/root/navigation-root.js +58 -1
- package/dist/number-input/root/number-input-root.d.ts +63 -6
- package/dist/number-input/root/number-input-root.js +96 -11
- package/dist/object-inspector/root/object-inspector-root.d.ts +36 -1
- package/dist/object-inspector/root/object-inspector-root.js +26 -2
- package/dist/option/root/option-root.d.ts +32 -0
- package/dist/option/root/option-root.js +44 -5
- package/dist/outline/root/outline-root.d.ts +6 -2
- package/dist/outline/root/outline-root.js +7 -3
- package/dist/select/root/select-root.d.ts +29 -3
- package/dist/select/root/select-root.js +34 -9
- package/dist/slider/root/slider-root.d.ts +71 -9
- package/dist/slider/root/slider-root.js +129 -42
- package/dist/speed-dial/item/speed-dial-item.d.ts +29 -1
- package/dist/speed-dial/item/speed-dial-item.js +48 -7
- package/dist/speed-dial/root/speed-dial-root.d.ts +32 -6
- package/dist/speed-dial/root/speed-dial-root.js +50 -5
- package/dist/splitter/root/splitter-root.d.ts +22 -0
- package/dist/splitter/root/splitter-root.js +36 -7
- package/dist/steps/reach.d.ts +5 -1
- package/dist/steps/reach.js +2 -2
- package/dist/steps/root/steps-root.d.ts +37 -2
- package/dist/steps/root/steps-root.js +49 -7
- package/dist/steps/step/step.d.ts +6 -0
- package/dist/steps/step/step.js +4 -0
- package/dist/table/root/table-root.d.ts +20 -0
- package/dist/table/root/table-root.js +13 -3
- package/dist/tabs/root/tabs-root.d.ts +37 -0
- package/dist/tabs/root/tabs-root.js +92 -2
- package/dist/tabs/tab/tab.d.ts +38 -2
- package/dist/tabs/tab/tab.js +45 -4
- package/dist/tag/group/tag-group.d.ts +29 -3
- package/dist/tag/group/tag-group.js +42 -11
- package/dist/time-input/root/time-input-root.d.ts +32 -1
- package/dist/time-input/root/time-input-root.js +9 -2
- package/dist/time-picker/root/time-picker-root.d.ts +63 -1
- package/dist/time-picker/root/time-picker-root.js +58 -7
- package/dist/timeline/item/timeline-item.d.ts +25 -0
- package/dist/timeline/item/timeline-item.js +27 -2
- package/dist/toggle/root/toggle-root.d.ts +2 -0
- package/dist/toggle/root/toggle-root.js +1 -1
- package/dist/tree/item/tree-item.d.ts +10 -0
- package/dist/tree/item/tree-item.js +12 -0
- package/dist/tree/root/tree-root.d.ts +40 -1
- package/dist/tree/root/tree-root.js +120 -4
- package/dist/tree/selection.d.ts +6 -0
- package/dist/tree/selection.js +11 -0
- package/dist/video/root/keys.d.ts +6 -2
- package/dist/video/root/keys.js +18 -1
- package/dist/video/root/video-root.d.ts +60 -1
- package/dist/video/root/video-root.js +70 -2
- package/dist/video-playlist/item/video-playlist-item.d.ts +15 -1
- package/dist/video-playlist/item/video-playlist-item.js +7 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +43 -4
- package/dist/video-playlist/root/video-playlist-root.js +69 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +8 -0
- package/dist/virtual-list/root/virtual-list-root.js +3 -0
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +3885 -383
- package/types/vue.d.ts +1045 -107
- package/types/words.d.ts +146 -1
|
@@ -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,
|
|
7
|
+
import { addDays, addMonths, valueAsDate as asDate, barredBy, calendarLocale, customElement, formatWords, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, handedLocale, hostAria, inlineStep, commaList as list, MixinControllerValue, MixinPickerFeedback, MONTH_CALENDARS, monthOf, 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';
|
|
@@ -46,7 +46,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
46
46
|
this.focused = '';
|
|
47
47
|
this.choosing = false;
|
|
48
48
|
this.handleKeydown = (event) => {
|
|
49
|
-
if (this.view !== 'day') {
|
|
49
|
+
if (this.view !== 'day' && !this.ownMonths) {
|
|
50
50
|
this.handlePeriodKeydown(event);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
@@ -80,7 +80,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
80
80
|
}
|
|
81
81
|
else {
|
|
82
82
|
const step = event.key === 'PageUp' ? -1 : 1;
|
|
83
|
-
this.moveTo(
|
|
83
|
+
this.moveTo(this.system.add(from, event.shiftKey ? step * 12 : step));
|
|
84
84
|
}
|
|
85
85
|
event.preventDefault();
|
|
86
86
|
};
|
|
@@ -105,6 +105,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
105
105
|
this.required = false;
|
|
106
106
|
this.step = 1;
|
|
107
107
|
this.stepMismatchMessage = 'Choose one of the dates the calendar offers.';
|
|
108
|
+
this.timeZone = '';
|
|
108
109
|
this.unavailableMessage = 'Choose a date that is available.';
|
|
109
110
|
this.valueMissingMessage = 'Choose a date.';
|
|
110
111
|
this.view = 'day';
|
|
@@ -115,7 +116,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
115
116
|
return wordsLocale(this);
|
|
116
117
|
}
|
|
117
118
|
get month() {
|
|
118
|
-
return this.monthState ?? (this.defaultMonth ||
|
|
119
|
+
return this.monthState ?? (this.defaultMonth || this.system.key(this.derivedMonth));
|
|
119
120
|
}
|
|
120
121
|
set month(next) {
|
|
121
122
|
const previous = this.month;
|
|
@@ -125,6 +126,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
125
126
|
get selected() {
|
|
126
127
|
return list(this.value);
|
|
127
128
|
}
|
|
129
|
+
get weekend() {
|
|
130
|
+
return handedLocale(this) === '' ? [0, 6] : weekendOf(this.language);
|
|
131
|
+
}
|
|
128
132
|
get weekStart() {
|
|
129
133
|
if (this.firstDayOfWeek !== undefined && Number.isFinite(this.firstDayOfWeek)) {
|
|
130
134
|
return ((Math.floor(this.firstDayOfWeek) % 7) + 7) % 7;
|
|
@@ -147,24 +151,31 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
147
151
|
return this.selected.includes(iso);
|
|
148
152
|
}
|
|
149
153
|
get shown() {
|
|
150
|
-
const explicit = /^(\d{4})-(\d{2})
|
|
154
|
+
const explicit = /^(\d{4})-(\d{2})(?:-(\d{2}))?$/.exec(this.monthState ?? this.defaultMonth);
|
|
151
155
|
if (explicit) {
|
|
152
|
-
|
|
156
|
+
const first = firstOf(Number(explicit[1]), Number(explicit[2]) - 1);
|
|
157
|
+
return this.system.start(explicit[3] ? addDays(first, Number(explicit[3]) - 1) : first);
|
|
153
158
|
}
|
|
154
159
|
return this.derivedMonth;
|
|
155
160
|
}
|
|
161
|
+
get system() {
|
|
162
|
+
return monthSystem(this.calendar);
|
|
163
|
+
}
|
|
164
|
+
get ownMonths() {
|
|
165
|
+
return MONTH_CALENDARS.includes(this.calendar ?? '');
|
|
166
|
+
}
|
|
156
167
|
get derivedMonth() {
|
|
157
|
-
const from = asDate(this.selected[0] ?? '') ?? asDate(
|
|
158
|
-
return
|
|
168
|
+
const from = asDate(this.selected[0] ?? '') ?? asDate(todayIn(this.timeZone)) ?? new Date();
|
|
169
|
+
return this.system.start(from);
|
|
159
170
|
}
|
|
160
171
|
get anchor() {
|
|
161
172
|
const shown = this.shown;
|
|
162
173
|
for (const candidate of [
|
|
163
174
|
asDate(this.focused),
|
|
164
175
|
asDate(this.selected[0] ?? ''),
|
|
165
|
-
asDate(
|
|
176
|
+
asDate(todayIn(this.timeZone)),
|
|
166
177
|
]) {
|
|
167
|
-
if (candidate &&
|
|
178
|
+
if (candidate && this.system.same(candidate, shown)) {
|
|
168
179
|
return candidate;
|
|
169
180
|
}
|
|
170
181
|
}
|
|
@@ -198,17 +209,17 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
198
209
|
return date;
|
|
199
210
|
}
|
|
200
211
|
get atStart() {
|
|
201
|
-
return asDate(this.min) !== null &&
|
|
212
|
+
return asDate(this.min) !== null && fromDate(addDays(this.shown, -1)) < this.min;
|
|
202
213
|
}
|
|
203
214
|
get atEnd() {
|
|
204
215
|
return (asDate(this.max) !== null &&
|
|
205
|
-
|
|
216
|
+
fromDate(this.system.start(this.system.add(this.shown, this.monthCount))) > this.max);
|
|
206
217
|
}
|
|
207
218
|
show(date) {
|
|
208
219
|
if (this.isDisabled) {
|
|
209
220
|
return;
|
|
210
221
|
}
|
|
211
|
-
const next =
|
|
222
|
+
const next = this.system.key(date);
|
|
212
223
|
if (next === this.month) {
|
|
213
224
|
return;
|
|
214
225
|
}
|
|
@@ -437,7 +448,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
437
448
|
return Math.max(1, Math.floor(this.months) || 1);
|
|
438
449
|
}
|
|
439
450
|
get formats() {
|
|
440
|
-
const language =
|
|
451
|
+
const language = this.ownMonths
|
|
452
|
+
? `${new Intl.Locale(this.language || new Intl.DateTimeFormat().resolvedOptions().locale, { calendar: this.calendar ?? 'gregory' })}`
|
|
453
|
+
: calendarLocale(this.language, this.calendar);
|
|
441
454
|
if (this.cachedFormats?.locale === language) {
|
|
442
455
|
return this.cachedFormats;
|
|
443
456
|
}
|
|
@@ -450,6 +463,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
450
463
|
monthName: utc({ month: 'short' }),
|
|
451
464
|
monthYear: utc({ month: 'short', year: 'numeric' }),
|
|
452
465
|
weekday: utc({ weekday: 'short' }),
|
|
466
|
+
weekdayName: utc({ weekday: 'long' }),
|
|
453
467
|
year: utc({ year: 'numeric' }),
|
|
454
468
|
};
|
|
455
469
|
this.cachedFormats = built;
|
|
@@ -470,12 +484,13 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
470
484
|
</slot>`;
|
|
471
485
|
}
|
|
472
486
|
renderMonth(month, index) {
|
|
473
|
-
const { full, heading: named, weekday } = this.formats;
|
|
487
|
+
const { full, heading: named, weekday, weekdayName } = this.formats;
|
|
474
488
|
const heading = named.format(month);
|
|
475
489
|
const weeks = this.weeksOf(month);
|
|
476
490
|
const anchor = fromDate(this.anchor);
|
|
477
|
-
const today =
|
|
491
|
+
const today = todayIn(this.timeZone);
|
|
478
492
|
const range = this.range;
|
|
493
|
+
const weekend = this.weekend;
|
|
479
494
|
const first = index === 0;
|
|
480
495
|
const last = index === this.monthCount - 1;
|
|
481
496
|
return html `<div part="month">
|
|
@@ -486,7 +501,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
486
501
|
type="button"
|
|
487
502
|
aria-label=${this.previousLabel}
|
|
488
503
|
?disabled=${this.isDisabled || this.atStart}
|
|
489
|
-
@click=${() => this.show(
|
|
504
|
+
@click=${() => this.show(this.system.add(this.shown, -1))}
|
|
490
505
|
>
|
|
491
506
|
${this.renderPreviousMark()}
|
|
492
507
|
</button>`
|
|
@@ -501,7 +516,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
501
516
|
type="button"
|
|
502
517
|
aria-label=${this.nextLabel}
|
|
503
518
|
?disabled=${this.isDisabled || this.atEnd}
|
|
504
|
-
@click=${() => this.show(
|
|
519
|
+
@click=${() => this.show(this.system.add(this.shown, 1))}
|
|
505
520
|
>
|
|
506
521
|
${this.renderNextMark()}
|
|
507
522
|
</button>`
|
|
@@ -515,14 +530,16 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
515
530
|
data-unset=${this.value === '' ? '' : nothing}
|
|
516
531
|
>
|
|
517
532
|
<div part="week" role="row">
|
|
518
|
-
${weeks[0]?.map((date) => html `<span part="weekday" role="columnheader"
|
|
533
|
+
${weeks[0]?.map((date) => html `<span part="weekday" role="columnheader" aria-label=${weekdayName.format(date)}
|
|
534
|
+
>${weekday.format(date)}</span
|
|
535
|
+
>`)}
|
|
519
536
|
</div>
|
|
520
537
|
${weeks.map((week) => html `<div part="week" role="row">
|
|
521
538
|
${week.map((date) => {
|
|
522
539
|
const iso = fromDate(date);
|
|
523
540
|
const disabled = this.barred(date);
|
|
524
541
|
const selected = this.isSelected(iso);
|
|
525
|
-
const outside = !
|
|
542
|
+
const outside = !this.system.same(date, month);
|
|
526
543
|
const start = !outside && range !== null && iso === range[0];
|
|
527
544
|
const end = !outside && range !== null && iso === range[1];
|
|
528
545
|
const middle = !outside && range !== null && iso > range[0] && iso < range[1];
|
|
@@ -538,10 +555,11 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
538
555
|
data-range-middle=${middle ? '' : nothing}
|
|
539
556
|
data-range-start=${start ? '' : nothing}
|
|
540
557
|
data-today=${iso === today ? '' : nothing}
|
|
558
|
+
data-weekend=${weekend.includes(date.getUTCDay()) ? '' : nothing}
|
|
541
559
|
tabindex=${!outside && iso === anchor && !this.isDisabled ? '0' : '-1'}
|
|
542
560
|
@click=${outside ? nothing : () => this.select(date)}
|
|
543
561
|
><span
|
|
544
|
-
part="day${!outside && selected && !middle ? ' day-selected' : ''}${iso === today ? ' day-today' : ''}${outside ? ' day-outside' : ''}${disabled ? ' day-disabled' : ''}"
|
|
562
|
+
part="day${!outside && selected && !middle ? ' day-selected' : ''}${iso === today ? ' day-today' : ''}${outside ? ' day-outside' : ''}${disabled ? ' day-disabled' : ''}${weekend.includes(date.getUTCDay()) ? ' day-weekend' : ''}"
|
|
545
563
|
>${this.renderDay(date, outside)}</span
|
|
546
564
|
></span
|
|
547
565
|
>`;
|
|
@@ -551,10 +569,11 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
551
569
|
</div>`;
|
|
552
570
|
}
|
|
553
571
|
renderDay(date, outside) {
|
|
554
|
-
return this.dayContent && !outside ? this.dayContent(fromDate(date)) :
|
|
572
|
+
return this.dayContent && !outside ? this.dayContent(fromDate(date)) : this.system.day(date);
|
|
555
573
|
}
|
|
556
574
|
renderHeadingText(text, label) {
|
|
557
575
|
const steps = this.maxView !== undefined &&
|
|
576
|
+
!this.ownMonths &&
|
|
558
577
|
(this.view === 'day' || (this.view === 'month' && this.maxView === 'year'));
|
|
559
578
|
if (!steps) {
|
|
560
579
|
return text;
|
|
@@ -580,7 +599,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
580
599
|
min: this.min,
|
|
581
600
|
page: this.periodYear,
|
|
582
601
|
shown: this.shown,
|
|
583
|
-
today:
|
|
602
|
+
today: todayIn(this.timeZone),
|
|
584
603
|
view: years ? 'year' : 'month',
|
|
585
604
|
}).map(({ at, chosen, current, first, out }) => {
|
|
586
605
|
const words = years ? yearName.format(first) : monthName.format(first);
|
|
@@ -625,17 +644,18 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinPickerF
|
|
|
625
644
|
</div>`;
|
|
626
645
|
}
|
|
627
646
|
render() {
|
|
628
|
-
if (this.view !== 'day') {
|
|
629
|
-
return html `<
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
${this.renderPickerFeedback()}`;
|
|
647
|
+
if (this.view !== 'day' && !this.ownMonths) {
|
|
648
|
+
return html `<slot name="header"></slot>
|
|
649
|
+
<div part="months" style="--date-picker-column-count: 1">${this.renderPeriods()}</div>
|
|
650
|
+
<slot name="footer"></slot>${this.renderPickerFeedback()}`;
|
|
633
651
|
}
|
|
634
652
|
const shown = this.shown;
|
|
635
653
|
const count = this.monthCount;
|
|
636
|
-
return html `<
|
|
637
|
-
|
|
638
|
-
|
|
654
|
+
return html `<slot name="header"></slot>
|
|
655
|
+
<div part="months" style="--date-picker-column-count: ${Math.min(count, 2)}">
|
|
656
|
+
${Array.from({ length: count }, (_, index) => this.renderMonth(this.system.add(shown, index), index))}
|
|
657
|
+
</div>
|
|
658
|
+
<slot name="footer"></slot>${this.renderPickerFeedback()}`;
|
|
639
659
|
}
|
|
640
660
|
get valueAsDate() {
|
|
641
661
|
return asDate(this.value);
|
|
@@ -758,6 +778,9 @@ __decorate([
|
|
|
758
778
|
words,
|
|
759
779
|
property({ attribute: 'step-mismatch-message' })
|
|
760
780
|
], HelixHeadlessDatePicker.prototype, "stepMismatchMessage", void 0);
|
|
781
|
+
__decorate([
|
|
782
|
+
property({ attribute: 'time-zone' })
|
|
783
|
+
], HelixHeadlessDatePicker.prototype, "timeZone", void 0);
|
|
761
784
|
__decorate([
|
|
762
785
|
words,
|
|
763
786
|
property({ attribute: 'unavailable-message' })
|
|
@@ -6,6 +6,7 @@ registerElementEvents({
|
|
|
6
6
|
'helix-headless-area-chart': ['helix-reading-change', 'helix-reading-press'],
|
|
7
7
|
'helix-headless-avatar': ['error', 'load'],
|
|
8
8
|
'helix-headless-bar-chart': ['helix-reading-change', 'helix-reading-press'],
|
|
9
|
+
'helix-headless-breadcrumb': ['helix-select'],
|
|
9
10
|
'helix-headless-button': ['helix-press'],
|
|
10
11
|
'helix-headless-button-group': ['change', 'helix-before-change'],
|
|
11
12
|
'helix-headless-callout': ['helix-dismiss'],
|
|
@@ -140,6 +141,7 @@ registerElementEvents({
|
|
|
140
141
|
'helix-action',
|
|
141
142
|
'helix-before-change',
|
|
142
143
|
'helix-before-reorder',
|
|
144
|
+
'helix-load-more',
|
|
143
145
|
'helix-reorder',
|
|
144
146
|
],
|
|
145
147
|
'helix-headless-list-item': ['helix-action'],
|
|
@@ -241,7 +243,7 @@ registerElementEvents({
|
|
|
241
243
|
'helix-headless-step': ['helix-select'],
|
|
242
244
|
'helix-headless-steps': ['helix-activate', 'helix-before-activate', 'helix-select'],
|
|
243
245
|
'helix-headless-switch': ['change', 'helix-before-toggle', 'input'],
|
|
244
|
-
'helix-headless-tab': ['helix-select'],
|
|
246
|
+
'helix-headless-tab': ['helix-dismiss', 'helix-select'],
|
|
245
247
|
'helix-headless-table': [
|
|
246
248
|
'helix-before-reorder',
|
|
247
249
|
'helix-reorder',
|
|
@@ -39,6 +39,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
39
39
|
* @documentation https://fusion.dev/helix/components/graph
|
|
40
40
|
*
|
|
41
41
|
* @slot - The renderer's box, which the drawing is made in.
|
|
42
|
+
* @slot empty - What the panel shows when the list holds no notes. Defaults to `empty-label`.
|
|
42
43
|
* @slot filter-icon - The icon in the search field. Defaults to a magnifying glass.
|
|
43
44
|
* @slot footer - Content below the graph.
|
|
44
45
|
* @slot fullscreen-icon - Replaces the glyph inside the fullscreen button.
|
|
@@ -65,6 +66,7 @@ declare const HelixHeadlessGraph_base: (new (...args: any[]) => import("@fusion.
|
|
|
65
66
|
* @csspart body - The drawing beside the list, or above it where the frame is narrow.
|
|
66
67
|
* @csspart controls - The group the pan and zoom buttons sit in.
|
|
67
68
|
* @csspart count - How many notes the list holds, which a search narrows, at the end of the search bar.
|
|
69
|
+
* @csspart empty - The box in place of the list when it holds no notes, holding the `empty` slot.
|
|
68
70
|
* @csspart filter-icon - The icon beside the search field.
|
|
69
71
|
* @csspart filter-mark - The default icon beside the search field, shown when none is slotted.
|
|
70
72
|
* @csspart footer - The strip below the graph.
|
|
@@ -135,6 +137,11 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
135
137
|
* shows every note. The list holds what the drawing shows.
|
|
136
138
|
*/
|
|
137
139
|
depth?: number;
|
|
140
|
+
/**
|
|
141
|
+
* What the panel shows when the list holds no notes: the graph has none, or
|
|
142
|
+
* a search or the legend hid them all. A slotted `empty` replaces it.
|
|
143
|
+
*/
|
|
144
|
+
emptyLabel: string;
|
|
138
145
|
/**
|
|
139
146
|
* The graph's name where `label` is empty and the host has no
|
|
140
147
|
* `aria-label`.
|
|
@@ -180,6 +187,12 @@ export declare class HelixHeadlessGraph extends HelixHeadlessGraph_base {
|
|
|
180
187
|
noPanel: boolean;
|
|
181
188
|
/** The list's name, read by screen readers, and the name of the button that opens it with `no-panel`. */
|
|
182
189
|
notesLabel: string;
|
|
190
|
+
/**
|
|
191
|
+
* What a screen reader calls the graph in place of its role, after its
|
|
192
|
+
* name: "Research notes, graph". Said only where the graph has a name of its
|
|
193
|
+
* own, since the fallback name is the same word. Empty leaves the role.
|
|
194
|
+
*/
|
|
195
|
+
roleLabel: string;
|
|
183
196
|
/** The search field's name. */
|
|
184
197
|
searchLabel: string;
|
|
185
198
|
/** How the selected note is described in the list. */
|
|
@@ -17,6 +17,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
17
17
|
this.activateHintLabel = 'Press the graph to use it';
|
|
18
18
|
this.controlsLabel = 'Graph controls';
|
|
19
19
|
this.countLabel = '{count, plural, one {# note} other {# notes}}';
|
|
20
|
+
this.emptyLabel = 'No notes';
|
|
20
21
|
this.fallbackLabel = 'Graph';
|
|
21
22
|
this.hiddenGroups = [];
|
|
22
23
|
this.label = '';
|
|
@@ -33,6 +34,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
33
34
|
this.nodes = [];
|
|
34
35
|
this.noPanel = false;
|
|
35
36
|
this.notesLabel = 'Notes';
|
|
37
|
+
this.roleLabel = 'graph';
|
|
36
38
|
this.searchLabel = 'Find a note';
|
|
37
39
|
this.selectedLabel = 'Selected';
|
|
38
40
|
this.twoFingerHintLabel = 'Use two fingers to move the graph';
|
|
@@ -409,6 +411,8 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
409
411
|
part="region"
|
|
410
412
|
role="group"
|
|
411
413
|
aria-label=${this.label || this.getAttribute?.('aria-label') || this.fallbackLabel}
|
|
414
|
+
aria-roledescription=${(this.label || this.getAttribute?.('aria-label')) && this.roleLabel ? this.roleLabel : nothing}
|
|
415
|
+
aria-keyshortcuts="ArrowUp ArrowDown ArrowLeft ArrowRight Plus Minus"
|
|
412
416
|
tabindex="0"
|
|
413
417
|
@focusin=${this.idle.stir}
|
|
414
418
|
@keydown=${this.handleKeydown}
|
|
@@ -454,6 +458,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
454
458
|
data-scroller
|
|
455
459
|
aria-label=${this.notesLabel}
|
|
456
460
|
aria-activedescendant=${cursor}
|
|
461
|
+
aria-keyshortcuts="ArrowUp ArrowDown Home End PageUp PageDown Enter Space"
|
|
457
462
|
@keydown=${this.handleListKeydown}
|
|
458
463
|
@scroll=${() => this.virtualize.measure()}
|
|
459
464
|
>
|
|
@@ -461,6 +466,9 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
|
|
|
461
466
|
${this.renderRows()}
|
|
462
467
|
<div part="after" role="presentation" style="block-size: ${after}px"></div>
|
|
463
468
|
</div>
|
|
469
|
+
${this.entries.length === 0
|
|
470
|
+
? html `<div part="empty"><slot name="empty">${this.emptyLabel}</slot></div>`
|
|
471
|
+
: nothing}
|
|
464
472
|
</div>
|
|
465
473
|
</div>
|
|
466
474
|
<div part="footer">
|
|
@@ -485,6 +493,10 @@ __decorate([
|
|
|
485
493
|
__decorate([
|
|
486
494
|
property({ type: Number })
|
|
487
495
|
], HelixHeadlessGraph.prototype, "depth", void 0);
|
|
496
|
+
__decorate([
|
|
497
|
+
words,
|
|
498
|
+
property({ attribute: 'empty-label' })
|
|
499
|
+
], HelixHeadlessGraph.prototype, "emptyLabel", void 0);
|
|
488
500
|
__decorate([
|
|
489
501
|
words,
|
|
490
502
|
property({ attribute: 'fallback-label' })
|
|
@@ -543,6 +555,10 @@ __decorate([
|
|
|
543
555
|
words,
|
|
544
556
|
property({ attribute: 'notes-label' })
|
|
545
557
|
], HelixHeadlessGraph.prototype, "notesLabel", void 0);
|
|
558
|
+
__decorate([
|
|
559
|
+
words,
|
|
560
|
+
property({ attribute: 'role-label' })
|
|
561
|
+
], HelixHeadlessGraph.prototype, "roleLabel", void 0);
|
|
546
562
|
__decorate([
|
|
547
563
|
words,
|
|
548
564
|
property({ attribute: 'search-label' })
|
|
@@ -69,6 +69,23 @@ import { type ListSelectionBehavior, type ListSelectionMode } from '../selection
|
|
|
69
69
|
* no `start` counts down from the number of rows, which a server cannot know,
|
|
70
70
|
* so served markup counts from one until the list runs.
|
|
71
71
|
*
|
|
72
|
+
* **An empty list.** Set `empty-label`, or put your own content in the `empty`
|
|
73
|
+
* slot, for a row shown while the list has no rows and none are loading, such
|
|
74
|
+
* as "No files yet" and a link to add one. Without either, an empty list shows
|
|
75
|
+
* nothing. The list takes the `empty` state while it has no rows, whatever it
|
|
76
|
+
* shows.
|
|
77
|
+
*
|
|
78
|
+
* **Loading more.** `load-more` sends `helix-load-more` once the end of the
|
|
79
|
+
* list comes within a screen of view, in the box that scrolls it or the page,
|
|
80
|
+
* once for each number of rows: add rows and it can send it again. While you
|
|
81
|
+
* fetch, set `loading`: the list is busy, and a row after the last says
|
|
82
|
+
* "Loading more" (`loading-label`, or your own content in the `loading`
|
|
83
|
+
* slot). The list asks for nothing while `loading` is set.
|
|
84
|
+
*
|
|
85
|
+
* An interactive list with no name is reported once in a development build,
|
|
86
|
+
* since a screen reader announces it as a grid and nothing more. Name it with
|
|
87
|
+
* `label` or `aria-label`.
|
|
88
|
+
*
|
|
72
89
|
* @since 0.1.0
|
|
73
90
|
* @status stable
|
|
74
91
|
* @category data
|
|
@@ -76,18 +93,26 @@ import { type ListSelectionBehavior, type ListSelectionMode } from '../selection
|
|
|
76
93
|
* @documentation https://fusion.dev/helix/components/list
|
|
77
94
|
*
|
|
78
95
|
* @slot - The rows.
|
|
96
|
+
* @slot empty - Content for the row shown while the list has no rows and none are loading. Falls back to `empty-label`.
|
|
97
|
+
* @slot loading - Content for the row after the last while `loading` is set. Falls back to `loading-label`.
|
|
79
98
|
*
|
|
80
99
|
* @event {Event} change - Fired once a press has changed which rows are selected.
|
|
81
100
|
* @event {HelixActionEvent} helix-action - Sent from a row when the reader acts on it: Enter, or a press in a list that selects nothing. Read the row from `target`. A row with `href` follows its link instead.
|
|
82
101
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a press changes which rows are selected, with the `value` it would leave. Cancelable.
|
|
83
102
|
* @event {HelixBeforeReorderEvent} helix-before-reorder - Fired when a row is dropped at a new place, in a `reorderable` list, with every row's value in the new order. Cancelable: cancel it to keep the row where it is.
|
|
103
|
+
* @event {HelixLoadMoreEvent} helix-load-more - Fired, in a list with `load-more`, when the end of the list comes within a screen of view, once for each number of rows.
|
|
84
104
|
* @event {HelixReorderEvent} helix-reorder - Fired after `helix-before-reorder` when nobody canceled it. Move your rows to the order in `keys`. Cancelable: cancel it to say the move did not happen.
|
|
85
105
|
*
|
|
86
106
|
* @csspart drag-preview - A copy of the row a pointer drags, which follows the pointer in the top layer until the row is let go, in a `reorderable` list. Hidden from assistive technology.
|
|
107
|
+
* @csspart empty - The row shown while the list has no rows and none are loading, where `empty-label` or the `empty` slot gives it content. A grid row with one cell in a list that selects.
|
|
87
108
|
* @csspart live - The region that says each step of a move to screen readers, in a `reorderable` list. Drawn from the first move. Visually hidden in the styled tier.
|
|
109
|
+
* @csspart loading - The row after the last while `loading` is set. A grid row with one cell in a list that selects.
|
|
88
110
|
*
|
|
89
111
|
* @cssproperty --list-first - The number of the first row, written where `start` or `reversed` moves it.
|
|
90
112
|
* @cssproperty --list-step - What each row adds to the number before it: `1`, or `-1` where `reversed`.
|
|
113
|
+
*
|
|
114
|
+
* @cssstate empty - While the list has no rows.
|
|
115
|
+
* @cssstate loading - While `loading` is set.
|
|
91
116
|
*/
|
|
92
117
|
export declare class HelixHeadlessList extends HelixElement {
|
|
93
118
|
/**
|
|
@@ -102,6 +127,11 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
102
127
|
canceledLabel: string;
|
|
103
128
|
/** What screen readers hear when a row is dropped, in a `reorderable` list. */
|
|
104
129
|
droppedLabel: string;
|
|
130
|
+
/**
|
|
131
|
+
* The text of the row shown while the list has no rows, where the `empty`
|
|
132
|
+
* slot is empty. Empty, the default, shows no row.
|
|
133
|
+
*/
|
|
134
|
+
emptyLabel: string;
|
|
105
135
|
/**
|
|
106
136
|
* The kind of list, which follows from the content.
|
|
107
137
|
*
|
|
@@ -129,6 +159,18 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
129
159
|
* The list's name, read by screen readers.
|
|
130
160
|
*/
|
|
131
161
|
label: string;
|
|
162
|
+
/**
|
|
163
|
+
* Marks the list as busy fetching more rows, and draws a row after the last
|
|
164
|
+
* that says so. The list asks for no more while it is set.
|
|
165
|
+
*/
|
|
166
|
+
loading: boolean;
|
|
167
|
+
/** The text of the row drawn while `loading` is set, where the `loading` slot is empty. */
|
|
168
|
+
loadingLabel: string;
|
|
169
|
+
/**
|
|
170
|
+
* Sends `helix-load-more` once the end of the list comes within a screen of
|
|
171
|
+
* view, so you can add the next rows as a reader nears them.
|
|
172
|
+
*/
|
|
173
|
+
loadMore: boolean;
|
|
132
174
|
/**
|
|
133
175
|
* What screen readers hear each time an arrow key moves a held row, in a
|
|
134
176
|
* `reorderable` list. `{name}` is the row's words, `{position}` the place it
|
|
@@ -185,7 +227,7 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
185
227
|
*/
|
|
186
228
|
type?: '1' | 'a' | 'A' | 'i' | 'I';
|
|
187
229
|
/**
|
|
188
|
-
* The selected rows' values, separated by commas, in a list that selects.
|
|
230
|
+
* The selected rows' values, separated by commas with no spaces, such as `a,c`, in a list that selects.
|
|
189
231
|
*
|
|
190
232
|
* Set it to start with rows selected. A row's value is its `value`, or its
|
|
191
233
|
* words where it has none.
|
|
@@ -303,6 +345,37 @@ export declare class HelixHeadlessList extends HelixElement {
|
|
|
303
345
|
*/
|
|
304
346
|
private get numbers();
|
|
305
347
|
protected render(): TemplateResult;
|
|
348
|
+
/**
|
|
349
|
+
* The row shown while the list has no rows: a list item, or a grid row with
|
|
350
|
+
* one cell in a list that selects. Drawn only once the children are known,
|
|
351
|
+
* so a server and a hydrating render never claim an empty list, and hidden
|
|
352
|
+
* while it has neither `empty-label` nor content in the `empty` slot.
|
|
353
|
+
*/
|
|
354
|
+
private drawEmpty;
|
|
355
|
+
/**
|
|
356
|
+
* The row after the last while `loading` is set: a list item, or a grid row
|
|
357
|
+
* with one cell in a list that selects. It is not one of the rows, so it
|
|
358
|
+
* carries no value and a key never lands on it.
|
|
359
|
+
*/
|
|
360
|
+
private drawLoading;
|
|
361
|
+
/** Watches the end of a `load-more` list coming near the box that scrolls it. */
|
|
362
|
+
private endWatcher;
|
|
363
|
+
/** The end being watched, so a new one is watched again. */
|
|
364
|
+
private watchedEnd;
|
|
365
|
+
/** Whether the end of the list was in reach when last measured. */
|
|
366
|
+
private endInView;
|
|
367
|
+
/** The number of rows `helix-load-more` was last sent for. */
|
|
368
|
+
private askedAt;
|
|
369
|
+
/**
|
|
370
|
+
* Starts or stops watching the end of the list. The box it is measured
|
|
371
|
+
* against is the one that scrolls the list, or the page, and a screen of
|
|
372
|
+
* room is added below it, so the next rows are asked for before a reader
|
|
373
|
+
* reaches the last.
|
|
374
|
+
*/
|
|
375
|
+
private watchEnd;
|
|
376
|
+
/** Sends `helix-load-more`, once for each number of rows, and never while loading. */
|
|
377
|
+
private askForMore;
|
|
378
|
+
private readonly handleEmptyChange;
|
|
306
379
|
private readonly handleSlotChange;
|
|
307
380
|
}
|
|
308
381
|
declare global {
|