@torpor/ui 1.0.2 → 1.1.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.
Files changed (60) hide show
  1. package/dist/ColorPicker/ColorPicker.torp +36 -75
  2. package/dist/ColorPicker/ColorPickerInput.torp +122 -0
  3. package/dist/ColorPicker/ColorPickerTypes.ts +12 -0
  4. package/dist/ColorPicker/index.d.ts +40 -1
  5. package/dist/ColorPicker/index.js +2 -1
  6. package/dist/CommandPalette/CommandPalette.torp +49 -47
  7. package/dist/CommandPalette/CommandPaletteInput.torp +51 -0
  8. package/dist/CommandPalette/CommandPaletteItem.torp +62 -0
  9. package/dist/CommandPalette/CommandPaletteList.torp +55 -0
  10. package/dist/CommandPalette/CommandPaletteTypes.ts +32 -0
  11. package/dist/CommandPalette/index.d.ts +88 -2
  12. package/dist/CommandPalette/index.js +4 -1
  13. package/dist/DataGrid/DataGrid.torp +22 -22
  14. package/dist/DataGrid/DataGridCell.torp +50 -0
  15. package/dist/DataGrid/DataGridColumnHeader.torp +54 -0
  16. package/dist/DataGrid/DataGridTypes.ts +17 -0
  17. package/dist/DataGrid/index.d.ts +57 -2
  18. package/dist/DataGrid/index.js +3 -2
  19. package/dist/DatePicker/DatePicker.torp +45 -65
  20. package/dist/DatePicker/DatePickerContent.torp +82 -0
  21. package/dist/DatePicker/DatePickerTrigger.torp +56 -0
  22. package/dist/DatePicker/DatePickerTypes.ts +36 -0
  23. package/dist/DatePicker/index.d.ts +61 -2
  24. package/dist/DatePicker/index.js +3 -1
  25. package/dist/DateRangePicker/DateRangePicker.torp +52 -76
  26. package/dist/DateRangePicker/DateRangePickerContent.torp +90 -0
  27. package/dist/DateRangePicker/DateRangePickerTrigger.torp +59 -0
  28. package/dist/DateRangePicker/DateRangePickerTypes.ts +41 -0
  29. package/dist/DateRangePicker/index.d.ts +61 -2
  30. package/dist/DateRangePicker/index.js +3 -1
  31. package/dist/Progress/Progress.torp +24 -14
  32. package/dist/Progress/ProgressIndicator.torp +52 -0
  33. package/dist/Progress/ProgressTypes.ts +8 -0
  34. package/dist/Progress/index.d.ts +34 -1
  35. package/dist/Progress/index.js +2 -1
  36. package/dist/Rating/Rating.torp +41 -37
  37. package/dist/Rating/RatingStar.torp +71 -0
  38. package/dist/Rating/RatingTypes.ts +22 -0
  39. package/dist/Rating/index.d.ts +39 -1
  40. package/dist/Rating/index.js +2 -1
  41. package/dist/Slider/Slider.torp +48 -63
  42. package/dist/Slider/SliderHandle.torp +107 -0
  43. package/dist/Slider/SliderRange.torp +36 -0
  44. package/dist/Slider/SliderTypes.ts +34 -0
  45. package/dist/Slider/index.d.ts +65 -1
  46. package/dist/Slider/index.js +3 -1
  47. package/dist/TagInput/TagInput.torp +63 -84
  48. package/dist/TagInput/TagInputField.torp +68 -0
  49. package/dist/TagInput/TagInputSuggestions.torp +79 -0
  50. package/dist/TagInput/TagInputTag.torp +55 -0
  51. package/dist/TagInput/TagInputTypes.ts +42 -0
  52. package/dist/TagInput/index.d.ts +93 -1
  53. package/dist/TagInput/index.js +4 -1
  54. package/dist/TimePicker/TimePicker.torp +88 -85
  55. package/dist/TimePicker/TimePickerPart.torp +61 -0
  56. package/dist/TimePicker/TimePickerPeriod.torp +48 -0
  57. package/dist/TimePicker/TimePickerTypes.ts +37 -0
  58. package/dist/TimePicker/index.d.ts +61 -1
  59. package/dist/TimePicker/index.js +3 -1
  60. package/package.json +7 -7
@@ -7,6 +7,13 @@ import {
7
7
  } from "../Form/FormTypes";
8
8
  import FormValues from "../Form/FormValues.torp";
9
9
  import createFormField from "../utils/formField";
10
+ import TimePickerPart from "./TimePickerPart.torp";
11
+ import TimePickerPeriod from "./TimePickerPeriod.torp";
12
+ import {
13
+ type Part,
14
+ type TimePickerContext,
15
+ TimePickerContextName,
16
+ } from "./TimePickerTypes";
10
17
 
11
18
  interface TimePickerProps {
12
19
  /** An ID for the root element */
@@ -40,8 +47,6 @@ interface TimePickerProps {
40
47
  onchange?: (value: string | undefined) => void;
41
48
  }
42
49
 
43
- type Part = "hour" | "minute" | "second";
44
-
45
50
  const PAD = [2, 2, 2];
46
51
 
47
52
  /**
@@ -52,12 +57,23 @@ const PAD = [2, 2, 2];
52
57
  *
53
58
  * The value is always the canonical 24-hour form ("HH:mm" or "HH:mm:ss"),
54
59
  * regardless of display format.
60
+ *
61
+ * The structure of a TimePicker is:
62
+ *
63
+ * ```
64
+ * <TimePicker>
65
+ * <TimePickerPart part="hour" />
66
+ * <TimePickerPart part="minute" />
67
+ * <TimePickerPart part="second" /> (optional)
68
+ * <TimePickerPeriod /> (in 12-hour mode)
69
+ * </TimePicker>
70
+ * ```
71
+ *
72
+ * With no children, the segments are rendered automatically.
55
73
  */
56
74
  export default function TimePicker($props: TimePickerProps | undefined) {
57
- let hourInput: HTMLInputElement;
58
- let minuteInput: HTMLInputElement;
59
- let secondInput: HTMLInputElement;
60
- let periodButton: HTMLButtonElement;
75
+ const partInputs = new Map<Part, HTMLInputElement>();
76
+ let periodButton: HTMLButtonElement | undefined;
61
77
 
62
78
  // Wire up the enclosing Form and Field, if any
63
79
  const form = createFormField(
@@ -106,7 +122,9 @@ export default function TimePicker($props: TimePickerProps | undefined) {
106
122
  let $state = $watch({
107
123
  value: undefined as string | undefined,
108
124
 
109
- // The text being typed in each segment; committed on completion
125
+ // The text being typed in each segment; committed on completion.
126
+ // Cleared by every commit, so a non-empty buffer always means
127
+ // uncommitted typing that sync must not overwrite.
110
128
  hourText: "",
111
129
  minuteText: "",
112
130
  secondText: "",
@@ -168,6 +186,13 @@ export default function TimePicker($props: TimePickerProps | undefined) {
168
186
  return format(n);
169
187
  }
170
188
 
189
+ function getPartLabel(part: Part): string {
190
+ if (part === "hour") {
191
+ return $props?.hour12 ? "Hour (12-hour)" : "Hour";
192
+ }
193
+ return part === "minute" ? "Minute" : "Second";
194
+ }
195
+
171
196
  function isPM(): boolean {
172
197
  return parts().h >= 12;
173
198
  }
@@ -224,17 +249,22 @@ export default function TimePicker($props: TimePickerProps | undefined) {
224
249
  if (sync) syncInputs();
225
250
  }
226
251
 
227
- // Keep segment inputs showing the committed values unless typing there
252
+ // Keep segment inputs showing the committed values. A segment with
253
+ // uncommitted typing keeps its text; the rest always sync, even when
254
+ // focused -- so moving between segments never freezes their display.
228
255
  function syncInputs() {
256
+ const hourInput = partInputs.get("hour");
257
+ const minuteInput = partInputs.get("minute");
229
258
  if (!hourInput || !minuteInput) return;
230
259
  const editing = (el: HTMLInputElement, buffer: string) =>
231
- document.activeElement === el && el.value !== buffer;
260
+ document.activeElement === el && buffer !== "";
232
261
  if (!editing(hourInput, $state.hourText)) {
233
262
  hourInput.value = partDisplay("hour");
234
263
  }
235
264
  if (!editing(minuteInput, $state.minuteText)) {
236
265
  minuteInput.value = partDisplay("minute");
237
266
  }
267
+ const secondInput = partInputs.get("second");
238
268
  if (secondInput && !editing(secondInput, $state.secondText)) {
239
269
  secondInput.value = partDisplay("second");
240
270
  }
@@ -257,6 +287,7 @@ export default function TimePicker($props: TimePickerProps | undefined) {
257
287
  // Two digits fills the segment; move on to the next one
258
288
  if (text.length >= (PAD[partIndex(part)] ?? 2)) {
259
289
  commitBuffer(part, text);
290
+ setBuffer(part, "");
260
291
  focusNextSegment(part);
261
292
  }
262
293
  }
@@ -333,9 +364,9 @@ export default function TimePicker($props: TimePickerProps | undefined) {
333
364
 
334
365
  function focusNextSegment(part: Part) {
335
366
  if (part === "hour") {
336
- minuteInput?.focus();
367
+ partInputs.get("minute")?.focus();
337
368
  } else if (part === "minute" && getSeconds()) {
338
- secondInput?.focus();
369
+ partInputs.get("second")?.focus();
339
370
  } else if (part === "minute" && $props?.hour12) {
340
371
  periodButton?.focus();
341
372
  }
@@ -361,18 +392,50 @@ export default function TimePicker($props: TimePickerProps | undefined) {
361
392
  }
362
393
  }
363
394
 
364
- function ariaNow(part: Part): number {
395
+ function getPartValue(part: Part): number {
365
396
  const p = parts();
366
397
  return part === "hour" ? p.h : part === "minute" ? p.m : p.s;
367
398
  }
368
399
 
369
- function ariaText(part: Part): string {
400
+ function getPartText(part: Part): string {
370
401
  if (part === "hour" && $props?.hour12) {
371
402
  return `${partDisplay("hour")} ${isPM() ? "PM" : "AM"}`;
372
403
  }
373
- return String(ariaNow(part));
404
+ return String(getPartValue(part));
374
405
  }
375
406
 
407
+ // Set the context to pass down to the segments and the period toggle
408
+ let context: TimePickerContext = {
409
+ getDisabled,
410
+ getPartLabel,
411
+ getPartValue,
412
+ getPartText,
413
+ partDisplay,
414
+ handleInput,
415
+ handleBlur,
416
+ handleSegmentKey,
417
+ registerPart: (part, el) => {
418
+ partInputs.set(part, el);
419
+ },
420
+ unregisterPart: (part, el) => {
421
+ if (partInputs.get(part) === el) {
422
+ partInputs.delete(part);
423
+ }
424
+ },
425
+ isPM,
426
+ togglePeriod,
427
+ handlePeriodKey,
428
+ registerPeriod: (el) => {
429
+ periodButton = el;
430
+ },
431
+ unregisterPeriod: (el) => {
432
+ if (periodButton === el) {
433
+ periodButton = undefined;
434
+ }
435
+ },
436
+ };
437
+ $context[TimePickerContextName] = context;
438
+
376
439
  @render {
377
440
  <div
378
441
  id={$props?.id}
@@ -383,78 +446,18 @@ export default function TimePicker($props: TimePickerProps | undefined) {
383
446
  data-valid={form.valid ? "valid" : "invalid"}
384
447
  aria-describedby={form.messageId}
385
448
  >
386
- <input
387
- &ref={hourInput}
388
- class="torp-time-picker-part"
389
- type="text"
390
- inputmode="numeric"
391
- role="spinbutton"
392
- value={partDisplay("hour")}
393
- aria-label={$props?.hour12 ? "Hour (12-hour)" : "Hour"}
394
- aria-valuemin={0}
395
- aria-valuemax={23}
396
- aria-valuenow={ariaNow("hour")}
397
- aria-valuetext={ariaText("hour")}
398
- disabled={getDisabled()}
399
- tabindex={getDisabled() ? -1 : 0}
400
- oninput={(e: Event) => handleInput("hour", e)}
401
- onblur={(e: FocusEvent) => handleBlur("hour", e)}
402
- onkeydown={(e: KeyboardEvent) => handleSegmentKey("hour", e)}
403
- />
404
- <span class="torp-time-picker-separator">:</span>
405
- <input
406
- &ref={minuteInput}
407
- class="torp-time-picker-part"
408
- type="text"
409
- inputmode="numeric"
410
- role="spinbutton"
411
- value={partDisplay("minute")}
412
- aria-label="Minute"
413
- aria-valuemin={0}
414
- aria-valuemax={59}
415
- aria-valuenow={ariaNow("minute")}
416
- aria-valuetext={ariaText("minute")}
417
- disabled={getDisabled()}
418
- tabindex={getDisabled() ? -1 : 0}
419
- oninput={(e: Event) => handleInput("minute", e)}
420
- onblur={(e: FocusEvent) => handleBlur("minute", e)}
421
- onkeydown={(e: KeyboardEvent) => handleSegmentKey("minute", e)}
422
- />
423
- @if (getSeconds()) {
449
+ <slot>
450
+ <TimePickerPart part="hour" />
424
451
  <span class="torp-time-picker-separator">:</span>
425
- <input
426
- &ref={secondInput}
427
- class="torp-time-picker-part"
428
- type="text"
429
- inputmode="numeric"
430
- role="spinbutton"
431
- value={partDisplay("second")}
432
- aria-label="Second"
433
- aria-valuemin={0}
434
- aria-valuemax={59}
435
- aria-valuenow={ariaNow("second")}
436
- aria-valuetext={ariaText("second")}
437
- disabled={getDisabled()}
438
- tabindex={getDisabled() ? -1 : 0}
439
- oninput={(e: Event) => handleInput("second", e)}
440
- onblur={(e: FocusEvent) => handleBlur("second", e)}
441
- onkeydown={(e: KeyboardEvent) => handleSegmentKey("second", e)}
442
- />
443
- }
444
- @if ($props?.hour12) {
445
- <button
446
- &ref={periodButton}
447
- type="button"
448
- class="torp-time-picker-period"
449
- disabled={getDisabled()}
450
- tabindex={getDisabled() ? -1 : 0}
451
- aria-label={isPM() ? "PM" : "AM"}
452
- onclick={togglePeriod}
453
- onkeydown={handlePeriodKey}
454
- >
455
- {isPM() ? "PM" : "AM"}
456
- </button>
457
- }
452
+ <TimePickerPart part="minute" />
453
+ @if (getSeconds()) {
454
+ <span class="torp-time-picker-separator">:</span>
455
+ <TimePickerPart part="second" />
456
+ }
457
+ @if ($props?.hour12) {
458
+ <TimePickerPeriod />
459
+ }
460
+ </slot>
458
461
  </div>
459
462
 
460
463
  <FormValues name={form.name} value={$state.value} />
@@ -0,0 +1,61 @@
1
+ import type { ClassValue, StyleValue } from "@torpor/view";
2
+ import { type Part, type TimePickerContext, TimePickerContextName } from "./TimePickerTypes";
3
+
4
+ interface TimePickerPartProps {
5
+ /** An ID for the segment element */
6
+ id?: string;
7
+ /** Classes for the segment element */
8
+ class?: ClassValue;
9
+ /** Styles for the segment element */
10
+ style?: StyleValue;
11
+ /** Which segment this is: the hour, minute or second field */
12
+ part: Part;
13
+ }
14
+
15
+ /**
16
+ * One spinbutton segment of a TimePicker -- the hour, minute or second
17
+ * field. Each segment can be typed into or stepped with the arrow keys.
18
+ */
19
+ export default function TimePickerPart($props: TimePickerPartProps | undefined) {
20
+ // Get stuff out of the TimePicker context
21
+ const context = $context[TimePickerContextName] as TimePickerContext;
22
+ if (!context) {
23
+ throw new Error("TimePickerPart must be contained within a TimePicker");
24
+ }
25
+
26
+ function getPart(): Part {
27
+ return $props?.part ?? "hour";
28
+ }
29
+
30
+ function getDisabled(): boolean {
31
+ return context.getDisabled();
32
+ }
33
+
34
+ @render {
35
+ <input
36
+ {$props?.id}
37
+ class={["torp-time-picker-part", $props?.class]}
38
+ {$props?.style}
39
+ type="text"
40
+ inputmode="numeric"
41
+ role="spinbutton"
42
+ value={context.partDisplay(getPart())}
43
+ aria-label={context.getPartLabel(getPart())}
44
+ aria-valuemin={0}
45
+ aria-valuemax={getPart() === "hour" ? 23 : 59}
46
+ aria-valuenow={context.getPartValue(getPart())}
47
+ aria-valuetext={context.getPartText(getPart())}
48
+ disabled={getDisabled()}
49
+ tabindex={getDisabled() ? -1 : 0}
50
+ oninput={(e: Event) => context.handleInput(getPart(), e)}
51
+ onblur={(e: FocusEvent) => context.handleBlur(getPart(), e)}
52
+ onkeydown={(e: KeyboardEvent) => context.handleSegmentKey(getPart(), e)}
53
+ onmount={(el) => {
54
+ context.registerPart(getPart(), el);
55
+ return () => {
56
+ context.unregisterPart(getPart(), el);
57
+ };
58
+ }}
59
+ />
60
+ }
61
+ }
@@ -0,0 +1,48 @@
1
+ import type { ClassValue, StyleValue } from "@torpor/view";
2
+ import { type TimePickerContext, TimePickerContextName } from "./TimePickerTypes";
3
+
4
+ interface TimePickerPeriodProps {
5
+ /** An ID for the period element */
6
+ id?: string;
7
+ /** Classes for the period element */
8
+ class?: ClassValue;
9
+ /** Styles for the period element */
10
+ style?: StyleValue;
11
+ }
12
+
13
+ /**
14
+ * The AM/PM toggle of a TimePicker, shown in 12-hour mode.
15
+ */
16
+ export default function TimePickerPeriod($props: TimePickerPeriodProps | undefined) {
17
+ // Get stuff out of the TimePicker context
18
+ const context = $context[TimePickerContextName] as TimePickerContext;
19
+ if (!context) {
20
+ throw new Error("TimePickerPeriod must be contained within a TimePicker");
21
+ }
22
+
23
+ function getDisabled(): boolean {
24
+ return context.getDisabled();
25
+ }
26
+
27
+ @render {
28
+ <button
29
+ {$props?.id}
30
+ type="button"
31
+ class={["torp-time-picker-period", $props?.class]}
32
+ {$props?.style}
33
+ disabled={getDisabled()}
34
+ tabindex={getDisabled() ? -1 : 0}
35
+ aria-label={context.isPM() ? "PM" : "AM"}
36
+ onclick={() => context.togglePeriod()}
37
+ onkeydown={context.handlePeriodKey}
38
+ onmount={(el) => {
39
+ context.registerPeriod(el);
40
+ return () => {
41
+ context.unregisterPeriod(el);
42
+ };
43
+ }}
44
+ >
45
+ {context.isPM() ? "PM" : "AM"}
46
+ </button>
47
+ }
48
+ }
@@ -0,0 +1,37 @@
1
+ export const TimePickerContextName: unique symbol = Symbol.for("torp.TimePicker");
2
+
3
+ /** One of the spinbutton segments of a TimePicker */
4
+ export type Part = "hour" | "minute" | "second";
5
+
6
+ export interface TimePickerContext {
7
+ /** Whether the user cannot interact with the time picker */
8
+ getDisabled: () => boolean;
9
+ /** The accessible name for a segment */
10
+ getPartLabel: (part: Part) => string;
11
+ /** A segment's value, for aria-valuenow */
12
+ getPartValue: (part: Part) => number;
13
+ /** A segment's value as announced, for aria-valuetext */
14
+ getPartText: (part: Part) => string;
15
+ /** The text displayed in a segment */
16
+ partDisplay: (part: Part) => string;
17
+ /** Handles typing in a segment */
18
+ handleInput: (part: Part, e: Event) => void;
19
+ /** Handles a segment losing focus */
20
+ handleBlur: (part: Part, e: FocusEvent) => void;
21
+ /** Handles arrow/Home/End/Enter keys in a segment */
22
+ handleSegmentKey: (part: Part, e: KeyboardEvent) => void;
23
+ /** Called from a segment when it is added */
24
+ registerPart: (part: Part, el: HTMLInputElement) => void;
25
+ /** Called from a segment when it is removed */
26
+ unregisterPart: (part: Part, el: HTMLInputElement) => void;
27
+ /** Whether the current time is in the PM half of the day */
28
+ isPM: () => boolean;
29
+ /** Toggles between AM and PM */
30
+ togglePeriod: () => void;
31
+ /** Handles arrow keys on the period toggle */
32
+ handlePeriodKey: (e: KeyboardEvent) => void;
33
+ /** Called from the period toggle when it is added */
34
+ registerPeriod: (el: HTMLButtonElement) => void;
35
+ /** Called from the period toggle when it is removed */
36
+ unregisterPeriod: (el: HTMLButtonElement) => void;
37
+ }
@@ -41,6 +41,19 @@ interface TimePickerProps {
41
41
  *
42
42
  * The value is always the canonical 24-hour form ("HH:mm" or "HH:mm:ss"),
43
43
  * regardless of display format.
44
+ *
45
+ * The structure of a TimePicker is:
46
+ *
47
+ * ```
48
+ * <TimePicker>
49
+ * <TimePickerPart part="hour" />
50
+ * <TimePickerPart part="minute" />
51
+ * <TimePickerPart part="second" /> (optional)
52
+ * <TimePickerPeriod /> (in 12-hour mode)
53
+ * </TimePicker>
54
+ * ```
55
+ *
56
+ * With no children, the segments are rendered automatically.
44
57
  */
45
58
  declare function TimePicker(
46
59
  $parent: ParentNode,
@@ -50,4 +63,51 @@ declare function TimePicker(
50
63
  $slots?: Record<string, SlotRender>,
51
64
  ): void;
52
65
 
53
- export { TimePicker };
66
+
67
+
68
+ interface TimePickerPartProps {
69
+ /** An ID for the segment element */
70
+ id?: string;
71
+ /** Classes for the segment element */
72
+ class?: ClassValue;
73
+ /** Styles for the segment element */
74
+ style?: StyleValue;
75
+ /** Which segment this is: the hour, minute or second field */
76
+ part: Part;
77
+ }
78
+
79
+ /**
80
+ * One spinbutton segment of a TimePicker -- the hour, minute or second
81
+ * field. Each segment can be typed into or stepped with the arrow keys.
82
+ */
83
+ declare function TimePickerPart(
84
+ $parent: ParentNode,
85
+ $anchor: Node | null,
86
+ $props: TimePickerPartProps | undefined,
87
+ $context?: Record<PropertyKey, any>,
88
+ $slots?: Record<string, SlotRender>,
89
+ ): void;
90
+
91
+
92
+
93
+ interface TimePickerPeriodProps {
94
+ /** An ID for the period element */
95
+ id?: string;
96
+ /** Classes for the period element */
97
+ class?: ClassValue;
98
+ /** Styles for the period element */
99
+ style?: StyleValue;
100
+ }
101
+
102
+ /**
103
+ * The AM/PM toggle of a TimePicker, shown in 12-hour mode.
104
+ */
105
+ declare function TimePickerPeriod(
106
+ $parent: ParentNode,
107
+ $anchor: Node | null,
108
+ $props: TimePickerPeriodProps | undefined,
109
+ $context?: Record<PropertyKey, any>,
110
+ $slots?: Record<string, SlotRender>,
111
+ ): void;
112
+
113
+ export { TimePicker, TimePickerPart, TimePickerPeriod };
@@ -1,2 +1,4 @@
1
1
  import TimePicker from "./TimePicker.torp";
2
- export { TimePicker };
2
+ import TimePickerPart from "./TimePickerPart.torp";
3
+ import TimePickerPeriod from "./TimePickerPeriod.torp";
4
+ export { TimePicker, TimePickerPart, TimePickerPeriod };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torpor/ui",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Accessible, unstyled components for use in your Torpor front-end",
5
5
  "type": "module",
6
6
  "exports": {
@@ -179,8 +179,8 @@
179
179
  "author": "",
180
180
  "license": "ISC",
181
181
  "dependencies": {
182
- "@torpor/unplugin": "^1.0.2",
183
- "@torpor/view": "^1.0.2"
182
+ "@torpor/view": "^1.0.3",
183
+ "@torpor/unplugin": "^1.0.3"
184
184
  },
185
185
  "devDependencies": {
186
186
  "@testing-library/dom": "^10.4.1",
@@ -193,11 +193,11 @@
193
193
  "jsdom": "^30.0.1",
194
194
  "tsx": "^4.23.5",
195
195
  "typescript": "^7.0.2",
196
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.7",
197
- "vite-plus": "0.2.7",
196
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
197
+ "vite-plus": "0.3.0",
198
198
  "zod": "^4.4.3",
199
- "@torpor/check": "^1.0.2",
200
- "@torpor/prettier": "^1.0.2"
199
+ "@torpor/prettier": "^1.0.3",
200
+ "@torpor/check": "^1.0.3"
201
201
  },
202
202
  "scripts": {
203
203
  "build": "tsgo --noEmit && vp pack",