@fusion.dev/helix-headless 0.58.0 → 0.59.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 +24 -203
- package/dist/button/root/button-root.d.ts +1 -7
- package/dist/button/root/button-root.js +2 -3
- package/dist/carousel/root/carousel-root.js +2 -2
- package/dist/color-picker/root/color-picker-root.d.ts +7 -1
- package/dist/color-picker/root/color-picker-root.js +3 -3
- package/dist/data-table/root/data-table-root.js +2 -2
- package/dist/date-input/root/date-input-root.js +6 -7
- package/dist/date-picker/root/date-picker-root.js +8 -17
- package/dist/heatmap/index.d.ts +1 -1
- package/dist/heatmap/index.js +1 -1
- package/dist/heatmap/root/buckets.d.ts +0 -4
- package/dist/heatmap/root/buckets.js +0 -5
- package/dist/heatmap/root/heatmap-root.d.ts +5 -3
- package/dist/heatmap/root/heatmap-root.js +5 -6
- package/dist/legend/root/legend-root.d.ts +2 -2
- package/dist/outline/root/outline-root.d.ts +8 -1
- package/dist/outline/root/outline-root.js +2 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +2 -2
- package/dist/skip-link/root/skip-link-root.d.ts +11 -1
- package/dist/skip-link/root/skip-link-root.js +2 -4
- package/dist/sparkline/root/sparkline-root.js +2 -5
- package/dist/splitter/root/splitter-root.js +3 -3
- package/dist/table/column/table-column.js +2 -2
- package/dist/table/root/table-root.js +2 -24
- package/dist/textarea/root/textarea-root.js +2 -2
- package/dist/time-input/root/time-input-root.js +10 -11
- package/dist/time-picker/root/time-picker-root.d.ts +0 -17
- package/dist/time-picker/root/time-picker-root.js +9 -32
- package/dist/tooltip/root/tooltip-root.d.ts +3 -10
- package/dist/tooltip/root/tooltip-root.js +3 -13
- package/dist/tour/stop/tour-stop.js +2 -3
- package/dist/video/root/video-root.js +2 -4
- package/package.json +5 -5
- package/types/jsx.d.ts +64 -68
- package/types/vue.d.ts +16 -20
|
@@ -21,15 +21,6 @@ const KEYS = new Set([
|
|
|
21
21
|
'PageUp',
|
|
22
22
|
' ',
|
|
23
23
|
]);
|
|
24
|
-
const toUtc = (iso) => {
|
|
25
|
-
const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
|
|
26
|
-
if (!parts) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
const date = new Date(Date.UTC(Number(parts[1]), Number(parts[2]) - 1, Number(parts[3])));
|
|
30
|
-
return Number.isNaN(date.getTime()) ? null : date;
|
|
31
|
-
};
|
|
32
|
-
const toIso = (date) => date.toISOString().slice(0, 10);
|
|
33
24
|
const localToday = () => {
|
|
34
25
|
const now = new Date();
|
|
35
26
|
const month = `${now.getMonth() + 1}`.padStart(2, '0');
|
|
@@ -104,7 +95,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
104
95
|
this.step = 1;
|
|
105
96
|
}
|
|
106
97
|
get month() {
|
|
107
|
-
return this.monthState ?? (this.defaultMonth ||
|
|
98
|
+
return this.monthState ?? (this.defaultMonth || fromDate(this.derivedMonth).slice(0, 7));
|
|
108
99
|
}
|
|
109
100
|
set month(next) {
|
|
110
101
|
const previous = this.month;
|
|
@@ -137,12 +128,12 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
137
128
|
return this.derivedMonth;
|
|
138
129
|
}
|
|
139
130
|
get derivedMonth() {
|
|
140
|
-
const from =
|
|
131
|
+
const from = asDate(this.selected[0] ?? '') ?? new Date();
|
|
141
132
|
return new Date(Date.UTC(from.getUTCFullYear(), from.getUTCMonth(), 1));
|
|
142
133
|
}
|
|
143
134
|
get anchor() {
|
|
144
135
|
const shown = this.shown;
|
|
145
|
-
for (const candidate of [
|
|
136
|
+
for (const candidate of [asDate(this.focused), asDate(this.selected[0] ?? '')]) {
|
|
146
137
|
if (candidate && sameMonth(candidate, shown)) {
|
|
147
138
|
return candidate;
|
|
148
139
|
}
|
|
@@ -155,7 +146,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
155
146
|
return Array.from({ length: 6 }, (_, week) => Array.from({ length: 7 }, (_, day) => addDays(start, week * 7 + day)));
|
|
156
147
|
}
|
|
157
148
|
barred(date) {
|
|
158
|
-
const iso =
|
|
149
|
+
const iso = fromDate(date);
|
|
159
150
|
if (this.min !== '' && iso < this.min) {
|
|
160
151
|
return true;
|
|
161
152
|
}
|
|
@@ -195,7 +186,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
195
186
|
});
|
|
196
187
|
}
|
|
197
188
|
moveTo(date) {
|
|
198
|
-
this.focused =
|
|
189
|
+
this.focused = fromDate(date);
|
|
199
190
|
this.show(date);
|
|
200
191
|
this.updateComplete.then(() => {
|
|
201
192
|
this.renderRoot.querySelector('[part~="cell"][tabindex="0"]')?.focus();
|
|
@@ -208,7 +199,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
208
199
|
if (this.barred(date)) {
|
|
209
200
|
return;
|
|
210
201
|
}
|
|
211
|
-
const iso =
|
|
202
|
+
const iso = fromDate(date);
|
|
212
203
|
const held = this.selected;
|
|
213
204
|
let next;
|
|
214
205
|
if (this.mode === 'range') {
|
|
@@ -309,7 +300,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
309
300
|
renderMonth(month, index) {
|
|
310
301
|
const { full, heading, weekday } = this.formats;
|
|
311
302
|
const weeks = this.weeksOf(month);
|
|
312
|
-
const anchor =
|
|
303
|
+
const anchor = fromDate(this.anchor);
|
|
313
304
|
const today = localToday();
|
|
314
305
|
const range = this.range;
|
|
315
306
|
const first = index === 0;
|
|
@@ -349,7 +340,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
|
|
|
349
340
|
</div>
|
|
350
341
|
${weeks.map((week) => html `<div part="week" role="row">
|
|
351
342
|
${week.map((date) => {
|
|
352
|
-
const iso =
|
|
343
|
+
const iso = fromDate(date);
|
|
353
344
|
const disabled = this.barred(date);
|
|
354
345
|
const selected = this.isSelected(iso);
|
|
355
346
|
const outside = !sameMonth(date, month);
|
package/dist/heatmap/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { fits,
|
|
1
|
+
export { fits, type Reading, toneOf } from './root/buckets.js';
|
|
2
2
|
export { HelixHeadlessHeatmap } from './root/heatmap-root.js';
|
package/dist/heatmap/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { fits,
|
|
1
|
+
export { fits, toneOf } from './root/buckets.js';
|
|
2
2
|
export { HelixHeadlessHeatmap } from './root/heatmap-root.js';
|
|
@@ -29,10 +29,6 @@ export interface Reading {
|
|
|
29
29
|
* painting it as the lowest bucket claims a reading that does not exist.
|
|
30
30
|
*/
|
|
31
31
|
export declare const toneOf: (reading: Reading, thresholds: readonly number[], tones: readonly string[]) => string | undefined;
|
|
32
|
-
/** A consumer's list of numbers, in the order written, with the rest dropped. */
|
|
33
|
-
export declare const numbers: (source: string) => number[];
|
|
34
|
-
/** A consumer's list of names, in the order written. */
|
|
35
|
-
export declare const words: (source: string) => string[];
|
|
36
32
|
/**
|
|
37
33
|
* How many readings fit across a given width, and which ones they are.
|
|
38
34
|
*
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { writtenList } from '@fusion.dev/helix-core';
|
|
2
1
|
export const toneOf = (reading, thresholds, tones) => {
|
|
3
2
|
if (reading.tone) {
|
|
4
3
|
return reading.tone;
|
|
@@ -14,10 +13,6 @@ export const toneOf = (reading, thresholds, tones) => {
|
|
|
14
13
|
}
|
|
15
14
|
return chosen;
|
|
16
15
|
};
|
|
17
|
-
export const numbers = (source) => writtenList(source)
|
|
18
|
-
.map(Number)
|
|
19
|
-
.filter((one) => Number.isFinite(one));
|
|
20
|
-
export const words = (source) => writtenList(source);
|
|
21
16
|
export const fits = (total, width, minimum, gap, rows = 1) => {
|
|
22
17
|
if (!Number.isFinite(width) || width <= 0 || minimum <= 0) {
|
|
23
18
|
return total;
|
|
@@ -211,9 +211,11 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
|
|
|
211
211
|
* `MixinCollection` names for a slotted collection, arriving through the one
|
|
212
212
|
* channel that mixin cannot see.
|
|
213
213
|
*
|
|
214
|
-
* The same shape as `childrenKnown`, asked of a
|
|
215
|
-
*
|
|
216
|
-
* empty: a `for` naming no table
|
|
214
|
+
* The same shape as `childrenKnown`, asked of a tree that can answer about
|
|
215
|
+
* ids rather than of one that holds children. An id that resolves to nothing
|
|
216
|
+
* in a browser is still known, and still empty: a `for` naming no table
|
|
217
|
+
* should say so rather than sit blank, which is why this asks
|
|
218
|
+
* `searchableById` and not `elementById`.
|
|
217
219
|
*/
|
|
218
220
|
private get sourceKnown();
|
|
219
221
|
/**
|
|
@@ -4,11 +4,11 @@ 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 { CHART_PLOT, customElement, drawTooltip, HelixElement, HelixResizeEvent, hostAria, MixinChartSource, markRegion, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CHART_PLOT, customElement, drawTooltip, HelixElement, HelixResizeEvent, hostAria, MixinChartSource, markRegion, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
11
|
-
import { fits,
|
|
11
|
+
import { fits, toneOf } from './buckets.js';
|
|
12
12
|
let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(HelixElement) {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
@@ -45,8 +45,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
45
45
|
if (this.hydrating) {
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
return typeof root.getElementById === 'function';
|
|
48
|
+
return searchableById(this);
|
|
50
49
|
}
|
|
51
50
|
get rowCount() {
|
|
52
51
|
return Math.max(1, Math.floor(this.rows) || 1);
|
|
@@ -124,8 +123,8 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
|
|
|
124
123
|
this.announced = showing;
|
|
125
124
|
}
|
|
126
125
|
render() {
|
|
127
|
-
const bounds =
|
|
128
|
-
const palette =
|
|
126
|
+
const bounds = writtenNumbers(this.thresholds);
|
|
127
|
+
const palette = writtenList(this.tones);
|
|
129
128
|
const cells = this.drawn;
|
|
130
129
|
return html `<div
|
|
131
130
|
part="strip"
|
|
@@ -53,8 +53,8 @@ export declare class HelixHeadlessLegend extends HelixElement {
|
|
|
53
53
|
/**
|
|
54
54
|
* The id of the table to take the names from.
|
|
55
55
|
*
|
|
56
|
-
*
|
|
57
|
-
* shadow root
|
|
56
|
+
* Names a table in the same tree, so a legend inside another component's
|
|
57
|
+
* shadow root reads a table in that root rather than one in the document.
|
|
58
58
|
*
|
|
59
59
|
* **In React this arrives as a property and not as an attribute**, the way
|
|
60
60
|
* `Tooltip.for` does, so it does not reflect and nothing styles on it.
|
|
@@ -84,7 +84,14 @@ export declare class HelixHeadlessOutline extends HelixElement {
|
|
|
84
84
|
private observer;
|
|
85
85
|
/** The links, in document order. Empty on the server, which has no tree. */
|
|
86
86
|
private get links();
|
|
87
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* What each link points at, paired with the link, skipping anything missing.
|
|
89
|
+
*
|
|
90
|
+
* The fragment is decoded first because these are `href`s and not ids. The
|
|
91
|
+
* lookup is the tree's alone: this intercepts no press, so it has no
|
|
92
|
+
* navigation to agree with, and a section it cannot see is one it is not
|
|
93
|
+
* describing.
|
|
94
|
+
*/
|
|
88
95
|
private get sections();
|
|
89
96
|
/**
|
|
90
97
|
* Works out which section is being read, and marks its link.
|
|
@@ -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, HelixActivateEvent, HelixElement, IndicatorController, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, elementById, HelixActivateEvent, HelixElement, IndicatorController, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
@@ -82,10 +82,9 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
|
|
|
82
82
|
element.getAttribute('href')?.startsWith('#') === true);
|
|
83
83
|
}
|
|
84
84
|
get sections() {
|
|
85
|
-
const root = this.getRootNode();
|
|
86
85
|
return this.links.flatMap((link) => {
|
|
87
86
|
const id = decodeURIComponent(link.getAttribute('href')?.slice(1) ?? '');
|
|
88
|
-
const target =
|
|
87
|
+
const target = elementById(this, id);
|
|
89
88
|
return target && target.getClientRects().length > 0 ? [{ link, target }] : [];
|
|
90
89
|
});
|
|
91
90
|
}
|
|
@@ -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 { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, isRtl, linear, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import '../../tooltip/index.js';
|
|
@@ -190,7 +190,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
|
|
|
190
190
|
return drawTooltip(this.sourceRows, -1, this.tag('tooltip'));
|
|
191
191
|
}
|
|
192
192
|
return drawTooltip(this.sourceRows, at, this.tag('tooltip'), {
|
|
193
|
-
dir:
|
|
193
|
+
dir: isRtl(this) ? 'rtl' : 'ltr',
|
|
194
194
|
fixed: true,
|
|
195
195
|
placement: 'top',
|
|
196
196
|
x: `${point.x}%`,
|
|
@@ -60,7 +60,17 @@ export declare class HelixHeadlessSkipLink extends HelixElement {
|
|
|
60
60
|
* appearing beside it.
|
|
61
61
|
*/
|
|
62
62
|
label: string;
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* The element `href` names, looked up the way the browser would.
|
|
65
|
+
*
|
|
66
|
+
* `orDocument`, which no other caller of `elementById` passes and which that
|
|
67
|
+
* option is written for: a press handled here has to land where following the
|
|
68
|
+
* anchor would, and the platform resolves a fragment against the document
|
|
69
|
+
* whatever tree the anchor is in. A skip link inside an app shell's shadow
|
|
70
|
+
* root pointing at the page's `#main` is the arrangement that needs it.
|
|
71
|
+
*
|
|
72
|
+
* The fragment is decoded first because this is an `href` and not an id.
|
|
73
|
+
*/
|
|
64
74
|
private get target();
|
|
65
75
|
/**
|
|
66
76
|
* Focuses the target, lending it a `tabindex` only if it needs one.
|
|
@@ -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, HelixElement } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, elementById, HelixElement } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessSkipLink = class HelixHeadlessSkipLink extends HelixElement {
|
|
@@ -38,9 +38,7 @@ let HelixHeadlessSkipLink = class HelixHeadlessSkipLink extends HelixElement {
|
|
|
38
38
|
if (!this.href.startsWith('#') || this.href.length < 2) {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
const root = this.getRootNode();
|
|
43
|
-
return (root.getElementById?.(id) ?? document.getElementById(id));
|
|
41
|
+
return elementById(this, decodeURIComponent(this.href.slice(1)), { orDocument: true });
|
|
44
42
|
}
|
|
45
43
|
render() {
|
|
46
44
|
return html `<a part="link" href=${this.href} @click=${this.skip}><slot>${this.label}</slot></a>`;
|
|
@@ -4,13 +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 { customElement, extent, HelixElement, linear, linePath, PLOT_WIDTH, SourceController,
|
|
7
|
+
import { customElement, extent, HelixElement, linear, linePath, PLOT_WIDTH, SourceController, writtenNumbers, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing, svg } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
const STRIP_HEIGHT = 32;
|
|
11
|
-
const readValues = (input) => writtenList(input)
|
|
12
|
-
.map(Number)
|
|
13
|
-
.filter((one) => Number.isFinite(one));
|
|
14
11
|
let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
|
|
15
12
|
constructor() {
|
|
16
13
|
super(...arguments);
|
|
@@ -28,7 +25,7 @@ let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
|
|
|
28
25
|
const series = this.source.series;
|
|
29
26
|
return series.length > 0
|
|
30
27
|
? (series[0]?.points.map((point) => point.value) ?? [])
|
|
31
|
-
:
|
|
28
|
+
: writtenNumbers(this.values);
|
|
32
29
|
}
|
|
33
30
|
render() {
|
|
34
31
|
const points = this.points();
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessSplitter_1;
|
|
8
|
-
import { capturePointer, closestInstance, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixElement, inlineStep, requestChange, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { capturePointer, closestInstance, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixElement, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { html } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
const STACK_BELOW = 512;
|
|
@@ -51,7 +51,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
51
51
|
}
|
|
52
52
|
const along = this.vertical ? event.clientY : event.clientX;
|
|
53
53
|
const raw = ((along - origin.start) / origin.length) * 100;
|
|
54
|
-
const rtl = !this.vertical &&
|
|
54
|
+
const rtl = !this.vertical && isRtl(this);
|
|
55
55
|
this.move(rtl ? 100 - raw : raw);
|
|
56
56
|
};
|
|
57
57
|
this.handlePointerUp = (event) => {
|
|
@@ -129,7 +129,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
|
|
|
129
129
|
if (!origin) {
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
-
const rtl =
|
|
132
|
+
const rtl = isRtl(this);
|
|
133
133
|
const along = (box, at, inline) => {
|
|
134
134
|
if (box.length === 0) {
|
|
135
135
|
return undefined;
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HelixHeadlessTableColumn_1;
|
|
8
|
-
import { customElement, HelixBeforeResizeEvent, HelixElement, hostAria, inlineStep, requestChange, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { customElement, HelixBeforeResizeEvent, HelixElement, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { dotsThreeVertical } from '@fusion.dev/helix-icons';
|
|
10
10
|
import { html, nothing } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -160,7 +160,7 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
|
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
162
|
get forward() {
|
|
163
|
-
return
|
|
163
|
+
return isRtl(this) ? -1 : 1;
|
|
164
164
|
}
|
|
165
165
|
render() {
|
|
166
166
|
const name = this.name;
|
|
@@ -4,34 +4,12 @@ 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, MixinCollection } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, MixinCollection, splitValues } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { edgeOf } from '../column/table-column.js';
|
|
11
11
|
const tracksOf = (list, wanted) => {
|
|
12
|
-
const words =
|
|
13
|
-
let depth = 0;
|
|
14
|
-
let word = '';
|
|
15
|
-
for (const char of list.trim()) {
|
|
16
|
-
if (char === '(' || char === '[') {
|
|
17
|
-
depth += 1;
|
|
18
|
-
}
|
|
19
|
-
else if (char === ')' || char === ']') {
|
|
20
|
-
depth -= 1;
|
|
21
|
-
}
|
|
22
|
-
if (depth === 0 && /\s/.test(char)) {
|
|
23
|
-
if (word) {
|
|
24
|
-
words.push(word);
|
|
25
|
-
}
|
|
26
|
-
word = '';
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
word += char;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (word) {
|
|
33
|
-
words.push(word);
|
|
34
|
-
}
|
|
12
|
+
const words = splitValues(list, ' ');
|
|
35
13
|
const valid = (track) => typeof CSS === 'undefined' || CSS.supports('grid-template-columns', track);
|
|
36
14
|
const tracks = [];
|
|
37
15
|
let names = '';
|
|
@@ -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, customElement, HelixFormElement, holdCaret, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, HelixFormElement, holdCaret, isRtl, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
@@ -60,7 +60,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
60
60
|
}
|
|
61
61
|
const data = new FormData();
|
|
62
62
|
data.append(this.name, this.value);
|
|
63
|
-
data.append(this.dirName,
|
|
63
|
+
data.append(this.dirName, isRtl(control) ? 'rtl' : 'ltr');
|
|
64
64
|
return data;
|
|
65
65
|
}
|
|
66
66
|
get selectionDirection() {
|
|
@@ -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, valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, isTimeValue, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, valueAsMinutes, writeTime, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { clock } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -13,7 +13,6 @@ import { html } from 'lit/static-html.js';
|
|
|
13
13
|
import '../../icon/index.js';
|
|
14
14
|
import '../../tag/index.js';
|
|
15
15
|
import '../../time-picker/index.js';
|
|
16
|
-
import { isTime, toMinutes, writeTime } from '../../time-picker/root/time-picker-root.js';
|
|
17
16
|
let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEditing(MixinPickerField(MixinControllerOpen(MixinTokens(MixinControllerValue(MixinField(HelixFormElement)))))) {
|
|
18
17
|
constructor() {
|
|
19
18
|
super(...arguments);
|
|
@@ -34,7 +33,7 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEdi
|
|
|
34
33
|
return;
|
|
35
34
|
}
|
|
36
35
|
const held = this.held;
|
|
37
|
-
if (event.key === 'Enter' &&
|
|
36
|
+
if (event.key === 'Enter' && isTimeValue(this.draft)) {
|
|
38
37
|
event.preventDefault();
|
|
39
38
|
if (!held.includes(this.draft)) {
|
|
40
39
|
this.requestValue([...held, this.draft].sort().join(','));
|
|
@@ -61,7 +60,7 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEdi
|
|
|
61
60
|
.split(',')
|
|
62
61
|
.map((one) => one.trim())
|
|
63
62
|
.filter(Boolean);
|
|
64
|
-
const whole = held.length > 0 && held.every(
|
|
63
|
+
const whole = held.length > 0 && held.every(isTimeValue);
|
|
65
64
|
this.requestValue(whole ? held.join(',') : typed);
|
|
66
65
|
this.restore();
|
|
67
66
|
};
|
|
@@ -83,7 +82,7 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEdi
|
|
|
83
82
|
.filter(Boolean);
|
|
84
83
|
}
|
|
85
84
|
written(at) {
|
|
86
|
-
return this.timeStyle === 'iso' || !
|
|
85
|
+
return this.timeStyle === 'iso' || !isTimeValue(at) ? at : writeTime(at, this.locale);
|
|
87
86
|
}
|
|
88
87
|
get display() {
|
|
89
88
|
if (this.mode === 'multiple') {
|
|
@@ -105,21 +104,21 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEdi
|
|
|
105
104
|
}
|
|
106
105
|
get picked() {
|
|
107
106
|
const held = this.held;
|
|
108
|
-
return held.length > 0 && held.every(
|
|
107
|
+
return held.length > 0 && held.every(isTimeValue) ? held.join(',') : '';
|
|
109
108
|
}
|
|
110
109
|
validate() {
|
|
111
110
|
const held = this.held;
|
|
112
|
-
const floor =
|
|
113
|
-
const ceiling =
|
|
114
|
-
if (held.length > 0 && !held.every(
|
|
111
|
+
const floor = valueAsMinutes(this.min) ?? 0;
|
|
112
|
+
const ceiling = valueAsMinutes(this.max) ?? 1439;
|
|
113
|
+
if (held.length > 0 && !held.every(isTimeValue)) {
|
|
115
114
|
return this.mode === undefined
|
|
116
115
|
? 'Enter a time as HH:mm.'
|
|
117
116
|
: 'Enter times as HH:mm, separated by commas.';
|
|
118
117
|
}
|
|
119
|
-
if (held.some((one) => (
|
|
118
|
+
if (held.some((one) => (valueAsMinutes(one) ?? 0) < floor)) {
|
|
120
119
|
return `Choose a time at or after ${writeTime(this.min, this.locale)}.`;
|
|
121
120
|
}
|
|
122
|
-
if (held.some((one) => (
|
|
121
|
+
if (held.some((one) => (valueAsMinutes(one) ?? 0) > ceiling)) {
|
|
123
122
|
return `Choose a time at or before ${writeTime(this.max, this.locale)}.`;
|
|
124
123
|
}
|
|
125
124
|
if (this.mode === 'range' && held.length > 2) {
|
|
@@ -2,23 +2,6 @@ import { HelixFormElement } from '@fusion.dev/helix-core';
|
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../listbox/index.js';
|
|
4
4
|
import '../../option/index.js';
|
|
5
|
-
/** Whether a string is a time the rest of this component can reason about. */
|
|
6
|
-
export declare const isTime: (value: string) => boolean;
|
|
7
|
-
/** Minutes since midnight, or `null` where it is not a time. */
|
|
8
|
-
export declare const toMinutes: (value: string) => number | null;
|
|
9
|
-
/** Minutes since midnight back to `HH:mm`, which is the value shape throughout. */
|
|
10
|
-
export declare const fromMinutes: (minutes: number) => string;
|
|
11
|
-
/**
|
|
12
|
-
* A time written the way the reader's locale writes one.
|
|
13
|
-
*
|
|
14
|
-
* `Intl` decides between a twelve and a twenty-four hour clock, because that is
|
|
15
|
-
* a property of the locale rather than of this component: `en-US` gets
|
|
16
|
-
* `2:30 PM` and `en-GB` gets `14:30` without either being configured. There is
|
|
17
|
-
* no flag to force one, deliberately. A product that needs to override its
|
|
18
|
-
* reader's own convention has a locale problem rather than a component one, and
|
|
19
|
-
* the value is 24 hour regardless.
|
|
20
|
-
*/
|
|
21
|
-
export declare const writeTime: (value: string, locale?: string) => string;
|
|
22
5
|
declare const HelixHeadlessTimePicker_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & typeof HelixFormElement;
|
|
23
6
|
/**
|
|
24
7
|
* @summary Picks a time, from a list of them.
|
|
@@ -4,35 +4,12 @@ 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 { valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, MixinControllerValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, MixinControllerValue, minutesAsValue, valueAsMinutes, writeTime, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { html } from 'lit/static-html.js';
|
|
11
11
|
import '../../listbox/index.js';
|
|
12
12
|
import '../../option/index.js';
|
|
13
|
-
export const isTime = (value) => /^([01]\d|2[0-3]):[0-5]\d$/.test(value);
|
|
14
|
-
export const toMinutes = (value) => {
|
|
15
|
-
if (!isTime(value)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const [hours = '0', minutes = '0'] = value.split(':');
|
|
19
|
-
return Number(hours) * 60 + Number(minutes);
|
|
20
|
-
};
|
|
21
|
-
export const fromMinutes = (minutes) => {
|
|
22
|
-
const whole = ((Math.round(minutes) % 1440) + 1440) % 1440;
|
|
23
|
-
return `${String(Math.floor(whole / 60)).padStart(2, '0')}:${String(whole % 60).padStart(2, '0')}`;
|
|
24
|
-
};
|
|
25
|
-
export const writeTime = (value, locale) => {
|
|
26
|
-
const minutes = toMinutes(value);
|
|
27
|
-
if (minutes === null) {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
const at = new Date(Date.UTC(2000, 0, 1, Math.floor(minutes / 60), minutes % 60));
|
|
31
|
-
return new Intl.DateTimeFormat(locale || undefined, {
|
|
32
|
-
timeStyle: 'short',
|
|
33
|
-
timeZone: 'UTC',
|
|
34
|
-
}).format(at);
|
|
35
|
-
};
|
|
36
13
|
const isTwelveHour = (locale) => new Intl.DateTimeFormat(locale || undefined, { timeStyle: 'short' }).resolvedOptions().hour12 ===
|
|
37
14
|
true;
|
|
38
15
|
let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControllerValue(HelixFormElement) {
|
|
@@ -92,7 +69,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
92
69
|
const half = hour % 12;
|
|
93
70
|
next = (half + (to === 'PM' ? 12 : 0)) * 60 + minute;
|
|
94
71
|
}
|
|
95
|
-
const whole =
|
|
72
|
+
const whole = minutesAsValue(next);
|
|
96
73
|
if (this.barred(whole)) {
|
|
97
74
|
return;
|
|
98
75
|
}
|
|
@@ -102,8 +79,8 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
102
79
|
this.listRevealed = false;
|
|
103
80
|
}
|
|
104
81
|
get times() {
|
|
105
|
-
const from =
|
|
106
|
-
const to =
|
|
82
|
+
const from = valueAsMinutes(this.min) ?? 0;
|
|
83
|
+
const to = valueAsMinutes(this.max) ?? 1439;
|
|
107
84
|
const step = Math.max(1, Math.round(this.step));
|
|
108
85
|
const found = [];
|
|
109
86
|
for (let at = from; at <= to; at += step) {
|
|
@@ -121,11 +98,11 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
121
98
|
wholeHourBarred(shown, half) {
|
|
122
99
|
const whole = half === undefined ? shown : (shown % 12) + (half === 'PM' ? 12 : 0);
|
|
123
100
|
const within = this.times.filter((at) => Math.floor(at / 60) === whole);
|
|
124
|
-
return within.length > 0 && within.every((at) => this.barred(
|
|
101
|
+
return within.length > 0 && within.every((at) => this.barred(minutesAsValue(at)));
|
|
125
102
|
}
|
|
126
103
|
halfBarred(half) {
|
|
127
104
|
const within = this.times.filter((at) => (half === 'PM') === at >= 720);
|
|
128
|
-
return within.length > 0 && within.every((at) => this.barred(
|
|
105
|
+
return within.length > 0 && within.every((at) => this.barred(minutesAsValue(at)));
|
|
129
106
|
}
|
|
130
107
|
get held() {
|
|
131
108
|
return this.value
|
|
@@ -141,7 +118,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
141
118
|
return from !== undefined && to !== undefined && at > from && at < to;
|
|
142
119
|
}
|
|
143
120
|
get parts() {
|
|
144
|
-
const at =
|
|
121
|
+
const at = valueAsMinutes(this.value) ?? valueAsMinutes(this.min) ?? 0;
|
|
145
122
|
const hour = Math.floor(at / 60);
|
|
146
123
|
return { hour, meridiem: hour < 12 ? 'AM' : 'PM', minute: at % 60 };
|
|
147
124
|
}
|
|
@@ -262,7 +239,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
262
239
|
: this.hours;
|
|
263
240
|
return html `<div part="columns" data-unset=${this.value === '' ? '' : nothing}>
|
|
264
241
|
${this.renderColumn('hour', 'Hour', hours.map(String), (one) => (twelve ? one : one.padStart(2, '0')), shownHour, (one) => this.wholeHourBarred(Number(one), twelve ? meridiem : undefined))}
|
|
265
|
-
${this.renderColumn('minute', 'Minute', this.minutes.map(String), (one) => one.padStart(2, '0'), String(minute), (one) => this.barred(
|
|
242
|
+
${this.renderColumn('minute', 'Minute', this.minutes.map(String), (one) => one.padStart(2, '0'), String(minute), (one) => this.barred(minutesAsValue(hour * 60 + Number(one))))}
|
|
266
243
|
${twelve
|
|
267
244
|
? this.renderColumn('meridiem', 'Before or after noon', ['AM', 'PM'], (one) => one, meridiem, (one) => this.halfBarred(one))
|
|
268
245
|
: nothing}
|
|
@@ -283,7 +260,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
283
260
|
@input=${this.handleListInput}
|
|
284
261
|
>
|
|
285
262
|
${this.times.map((minutes) => {
|
|
286
|
-
const at =
|
|
263
|
+
const at = minutesAsValue(minutes);
|
|
287
264
|
const between = this.between(at);
|
|
288
265
|
return html `<${this.tag('option')}
|
|
289
266
|
part="option${between ? ' option-between' : ''}"
|
|
@@ -100,8 +100,8 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
100
100
|
* the element it names, and points its bubble there. Leave it unset and the
|
|
101
101
|
* default slot is the trigger, which is the older form.
|
|
102
102
|
*
|
|
103
|
-
*
|
|
104
|
-
* shadow root
|
|
103
|
+
* Names an element in the same tree, so a tooltip inside another component's
|
|
104
|
+
* shadow root points at one in that root rather than one in the document.
|
|
105
105
|
*
|
|
106
106
|
* **In React this arrives as a property and not as an attribute**, which is
|
|
107
107
|
* worth knowing before someone reads the DOM and thinks it did not take.
|
|
@@ -199,14 +199,7 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
199
199
|
* until a chart did.
|
|
200
200
|
*/
|
|
201
201
|
reposition(): void;
|
|
202
|
-
/**
|
|
203
|
-
* The element `for` names, or null.
|
|
204
|
-
*
|
|
205
|
-
* `getRootNode()` rather than `document`, which is what makes this work inside
|
|
206
|
-
* another component: an id is unique to a tree, and a tooltip in a shadow root
|
|
207
|
-
* names an element in that root. Client only, since the server has no tree to
|
|
208
|
-
* search.
|
|
209
|
-
*/
|
|
202
|
+
/** The element `for` names, or null. */
|
|
210
203
|
private get named();
|
|
211
204
|
private readonly bubbleLayer;
|
|
212
205
|
/**
|