@fusion.dev/helix-headless 0.58.0 → 0.58.1
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
CHANGED
|
@@ -93971,7 +93971,7 @@
|
|
|
93971
93971
|
}
|
|
93972
93972
|
}
|
|
93973
93973
|
],
|
|
93974
|
-
"description": "Whether a string is a time the rest of this component can reason about."
|
|
93974
|
+
"description": "Whether a string is a time the rest of this component can reason about.\n\n**Narrower than core's `valueAsTime` on purpose, and the difference is\nseconds.** That one takes them because `<input type=\"time\">` does, at a step\nbelow a minute. This library has no such step: `step` here is minutes and is\nfloored at one, so nothing it offers or writes ever carries a second, and\n`toMinutes` below would drop one silently if this let it through. Widening\nthis to the platform's shape would let a value in that the rest of the family\ncannot hold."
|
|
93975
93975
|
},
|
|
93976
93976
|
{
|
|
93977
93977
|
"kind": "function",
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, isDateValue, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { calendarBlank } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -12,7 +12,6 @@ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
|
12
12
|
import { html } from 'lit/static-html.js';
|
|
13
13
|
import '../../date-picker/index.js';
|
|
14
14
|
import '../../tag/index.js';
|
|
15
|
-
const isIso = (value) => /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
16
15
|
const dates = (value) => value
|
|
17
16
|
.replace(/\s+[–-]\s+/g, ',')
|
|
18
17
|
.split(',')
|
|
@@ -47,7 +46,7 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
47
46
|
return;
|
|
48
47
|
}
|
|
49
48
|
const held = dates(typed);
|
|
50
|
-
const whole = held.length > 0 && held.every(
|
|
49
|
+
const whole = held.length > 0 && held.every(isDateValue);
|
|
51
50
|
this.requestValue(whole ? held.join(',') : typed);
|
|
52
51
|
this.restore();
|
|
53
52
|
};
|
|
@@ -56,7 +55,7 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
58
57
|
const held = dates(this.value);
|
|
59
|
-
if (event.key === 'Enter' &&
|
|
58
|
+
if (event.key === 'Enter' && isDateValue(this.draft)) {
|
|
60
59
|
event.preventDefault();
|
|
61
60
|
if (!held.includes(this.draft)) {
|
|
62
61
|
this.requestValue([...held, this.draft].join(','));
|
|
@@ -107,10 +106,10 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
107
106
|
}
|
|
108
107
|
get picked() {
|
|
109
108
|
const held = dates(this.value);
|
|
110
|
-
return held.length > 0 && held.every(
|
|
109
|
+
return held.length > 0 && held.every(isDateValue) ? held.join(',') : '';
|
|
111
110
|
}
|
|
112
111
|
written(date) {
|
|
113
|
-
if (this.dateStyle === 'iso' || !
|
|
112
|
+
if (this.dateStyle === 'iso' || !isDateValue(date)) {
|
|
114
113
|
return date;
|
|
115
114
|
}
|
|
116
115
|
const at = new Date(`${date}T00:00:00Z`);
|
|
@@ -141,7 +140,7 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
|
|
|
141
140
|
}
|
|
142
141
|
validate() {
|
|
143
142
|
const held = dates(this.value);
|
|
144
|
-
if (held.length > 0 && !held.every(
|
|
143
|
+
if (held.length > 0 && !held.every(isDateValue)) {
|
|
145
144
|
return this.mode === undefined
|
|
146
145
|
? 'Enter a date as YYYY-MM-DD.'
|
|
147
146
|
: 'Enter dates as YYYY-MM-DD, separated by commas.';
|
|
@@ -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);
|
|
@@ -2,7 +2,17 @@ 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
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Whether a string is a time the rest of this component can reason about.
|
|
7
|
+
*
|
|
8
|
+
* **Narrower than core's `valueAsTime` on purpose, and the difference is
|
|
9
|
+
* seconds.** That one takes them because `<input type="time">` does, at a step
|
|
10
|
+
* below a minute. This library has no such step: `step` here is minutes and is
|
|
11
|
+
* floored at one, so nothing it offers or writes ever carries a second, and
|
|
12
|
+
* `toMinutes` below would drop one silently if this let it through. Widening
|
|
13
|
+
* this to the platform's shape would let a value in that the rest of the family
|
|
14
|
+
* cannot hold.
|
|
15
|
+
*/
|
|
6
16
|
export declare const isTime: (value: string) => boolean;
|
|
7
17
|
/** Minutes since midnight, or `null` where it is not a time. */
|
|
8
18
|
export declare const toMinutes: (value: string) => number | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-headless",
|
|
3
3
|
"description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
|
|
4
|
-
"version": "0.58.
|
|
4
|
+
"version": "0.58.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
},
|
|
47
47
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@fusion.dev/helix-core": "0.58.
|
|
50
|
-
"@fusion.dev/helix-icons": "0.58.
|
|
49
|
+
"@fusion.dev/helix-core": "0.58.1",
|
|
50
|
+
"@fusion.dev/helix-icons": "0.58.1",
|
|
51
51
|
"uqr": "^0.1.3"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
55
|
-
"@fusion.dev/helix-cem": "0.58.
|
|
56
|
-
"@fusion.dev/helix-testing": "0.58.
|
|
55
|
+
"@fusion.dev/helix-cem": "0.58.1",
|
|
56
|
+
"@fusion.dev/helix-testing": "0.58.1",
|
|
57
57
|
"@fusion.dev/scripts": "0.0.0-dev",
|
|
58
58
|
"@happy-dom/global-registrator": "^20.0.0",
|
|
59
59
|
"@lit-labs/ssr": "^4.1.0",
|