@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.
@@ -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(isIso);
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' && isIso(this.draft)) {
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(isIso) ? held.join(',') : '';
109
+ return held.length > 0 && held.every(isDateValue) ? held.join(',') : '';
111
110
  }
112
111
  written(date) {
113
- if (this.dateStyle === 'iso' || !isIso(date)) {
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(isIso)) {
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 || toIso(this.derivedMonth).slice(0, 7));
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 = toUtc(this.selected[0] ?? '') ?? new Date();
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 [toUtc(this.focused), toUtc(this.selected[0] ?? '')]) {
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 = toIso(date);
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 = toIso(date);
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 = toIso(date);
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 = toIso(this.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 = toIso(date);
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
- /** Whether a string is a time the rest of this component can reason about. */
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.0",
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.0",
50
- "@fusion.dev/helix-icons": "0.58.0",
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.0",
56
- "@fusion.dev/helix-testing": "0.58.0",
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",