iryx-ui 0.6.0 → 0.7.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 (40) hide show
  1. package/README.md +150 -2
  2. package/dist/component-names.d.ts +1 -1
  3. package/dist/components/DatePicker.vue.d.ts +52 -0
  4. package/dist/components/DateRangePicker.vue.d.ts +60 -0
  5. package/dist/components/Input.vue.d.ts +39 -1
  6. package/dist/components/Pagination.vue.d.ts +1 -1
  7. package/dist/components/PasswordInput.vue.d.ts +54 -0
  8. package/dist/components/Textarea.vue.d.ts +16 -1
  9. package/dist/components/index.d.ts +3 -0
  10. package/dist/composables/date.d.ts +21 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +51 -44
  13. package/dist/node_modules/.pnpm/@hugeicons_core-free-icons@4.2.3/node_modules/@hugeicons/core-free-icons/dist/esm/index.js +91 -8
  14. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js +122 -0
  15. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/DateFormatter.js +84 -0
  16. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +91 -0
  17. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js +107 -0
  18. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js +159 -0
  19. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js +29 -0
  20. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js +37 -0
  21. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js +6 -0
  22. package/dist/packages/iryx-ui/src/component-names.js +1 -1
  23. package/dist/packages/iryx-ui/src/components/DatePicker.js +5 -0
  24. package/dist/packages/iryx-ui/src/components/DatePicker.vue_vue_type_script_setup_true_lang.js +186 -0
  25. package/dist/packages/iryx-ui/src/components/DateRangePicker.js +5 -0
  26. package/dist/packages/iryx-ui/src/components/DateRangePicker.vue_vue_type_script_setup_true_lang.js +210 -0
  27. package/dist/packages/iryx-ui/src/components/Input.vue_vue_type_script_setup_true_lang.js +94 -25
  28. package/dist/packages/iryx-ui/src/components/PasswordInput.js +5 -0
  29. package/dist/packages/iryx-ui/src/components/PasswordInput.vue_vue_type_script_setup_true_lang.js +113 -0
  30. package/dist/packages/iryx-ui/src/components/Textarea.vue_vue_type_script_setup_true_lang.js +47 -21
  31. package/dist/packages/iryx-ui/src/components/index.js +50 -44
  32. package/dist/packages/iryx-ui/src/composables/date.js +25 -0
  33. package/dist/packages/iryx-ui/src/theme/date-picker.js +45 -0
  34. package/dist/packages/iryx-ui/src/theme/input.js +22 -6
  35. package/dist/packages/iryx-ui/src/theme/password-input.js +22 -0
  36. package/dist/theme/date-picker.d.ts +254 -0
  37. package/dist/theme/index.d.ts +2 -0
  38. package/dist/theme/input.d.ts +94 -15
  39. package/dist/theme/password-input.d.ts +79 -0
  40. package/package.json +2 -1
package/README.md CHANGED
@@ -288,9 +288,12 @@ app.use(createIryxUi({ unstyled: true }))
288
288
  | --- | --- |
289
289
  | `IForm` | Validating form wrapper — any Standard Schema validator, or your own function |
290
290
  | `IFormField` | Label, description, hint, help and error text around a control |
291
- | `IInput` | Text field with `sm`/`md`/`lg` sizes, `invalid` state, `v-model` |
291
+ | `IInput` | Text field with `sm`/`md`/`lg` sizes, `invalid` state, `v-model`, `leading`/`trailing` slots, `clearable`, `loading`, `debounce` |
292
292
  | `INumberInput` | Decimal-safe numeric field — the model is a **string**, with `min`/`max`/`step`, `precision` and locale-aware display |
293
- | `ITextarea` | Multi-line field with matching sizes and `invalid` state |
293
+ | `IDatePicker` | Calendar in a popover; the model is an ISO `YYYY-MM-DD` **string** |
294
+ | `IDateRangePicker` | Two-month range calendar; the model is `{ start, end }` ISO strings |
295
+ | `IPasswordInput` | Masked field with a show/hide toggle and an optional strength meter |
296
+ | `ITextarea` | Multi-line field with matching sizes, `invalid` state and optional `autosize` |
294
297
  | `ILabel` | Field label with optional `required` asterisk |
295
298
  | `ICheckbox` | Tri-state checkbox (`true` / `false` / `'indeterminate'`), optional `label` + `description` |
296
299
  | `ISelect` | Listbox with keyboard nav and typeahead, driven by an `items` array, with optional groups |
@@ -434,6 +437,151 @@ const framework = ref('vue')
434
437
  </template>
435
438
  ```
436
439
 
440
+ #### Input affixes, clearing, loading and debounce
441
+
442
+ `IInput` renders its chrome on a wrapper element, so `leading` and `trailing`
443
+ slot content sits *inside* the field and takes real space — a long value is
444
+ truncated by the affix rather than sliding underneath it.
445
+
446
+ ```vue
447
+ <IInput v-model="search" clearable placeholder="Search invoices…">
448
+ <template #leading>
449
+ <HugeiconsIcon :icon="Search01Icon" />
450
+ </template>
451
+ </IInput>
452
+
453
+ <IInput v-model="team" placeholder="your-team">
454
+ <template #trailing>
455
+ <span class="text-sm">.example.com</span>
456
+ </template>
457
+ </IInput>
458
+
459
+ <!-- Spinner in the trailing area; the field stays editable. -->
460
+ <IInput v-model="slug" :loading="checking" />
461
+
462
+ <!-- The model updates 500ms after the last keystroke. -->
463
+ <IInput v-model="query" :debounce="500" clearable />
464
+ ```
465
+
466
+ | Prop | Effect |
467
+ | --- | --- |
468
+ | `clearable` | Clear button in the trailing area whenever the field is non-empty |
469
+ | `loading` | Spinner in the trailing area. Does **not** disable the field |
470
+ | `debounce` | Milliseconds to wait after the last keystroke before the model updates. `0` (default) updates on every keystroke |
471
+ | `clearLabel` | Accessible name for the clear button, for non-English apps |
472
+
473
+ The displayed text always updates on the keystroke — only the model lags. Blur
474
+ and Enter flush a pending update immediately, so a submit never reads a stale
475
+ value, and an external write (a reset or prefill) cancels whatever is queued.
476
+
477
+ `class` lands on the wrapper, since that is the element carrying the field
478
+ chrome; use `ui` to reach the parts (`root`, `input`, `leading`, `trailing`,
479
+ `clear`). Stray attributes like `name`, `autocomplete` and `maxlength` are
480
+ forwarded to the `<input>` itself. `ref` exposes the element as `.input` for
481
+ focus management.
482
+
483
+ #### Dates
484
+
485
+ The model is an ISO `YYYY-MM-DD` **string**, never a `Date`.
486
+
487
+ ```vue
488
+ <script setup lang="ts">
489
+ import { ref } from 'vue'
490
+
491
+ const issuedOn = ref<string | null>('2026-08-15')
492
+ const period = ref({ start: '2026-08-01', end: '2026-08-31' })
493
+ </script>
494
+
495
+ <template>
496
+ <IDatePicker v-model="issuedOn" clearable />
497
+ <IDateRangePicker v-model="period" clearable />
498
+ </template>
499
+ ```
500
+
501
+ A `Date` is a timestamp, so it always carries a time zone. `new Date('2026-08-15')`
502
+ parses as UTC midnight, and a user west of Greenwich formatting it locally sees
503
+ the 14th — which silently moves a record into the wrong reporting period. A
504
+ calendar date has no zone, so it stays the day you picked. Internally the
505
+ components use `@internationalized/date`; that never reaches your model, so
506
+ formatting the string with `dayjs` or anything else on the way out is fine.
507
+
508
+ | Prop | Effect |
509
+ | --- | --- |
510
+ | `min` / `max` | Selectable bounds, as ISO strings |
511
+ | `locale` | Month names, weekday initials, and the trigger's text |
512
+ | `format` | `Intl.DateTimeFormatOptions` for the trigger, e.g. `{ dateStyle: 'full' }` |
513
+ | `weekStartsOn` | `0` is Sunday. Defaults to the locale's convention |
514
+ | `clearable` | Adds a clear action to the footer |
515
+ | `months` | Range picker only — months side by side, default `2` |
516
+ | `separator` | Range picker only — text between the two dates |
517
+
518
+ Navigation and footer labels (`todayLabel`, `clearLabel`, `previousLabel`,
519
+ `nextLabel`) are all props, so nothing bakes in English.
520
+
521
+ Both render their calendar at a fixed six weeks, so a short month cannot stretch
522
+ its rows to match a taller neighbour and the popover does not resize as you page
523
+ through it. The range picker draws only the committed range — the days between
524
+ the endpoints take a flat tint while the two ends take the solid fill, so a long
525
+ span still shows where it begins and ends.
526
+
527
+ The helpers behind them are exported, for formatting the same values elsewhere:
528
+
529
+ ```ts
530
+ import { formatIsoDate, isoToday, toCalendarDate, toIsoDate } from 'iryx-ui'
531
+
532
+ formatIsoDate('2026-08-15', 'en-GB', { dateStyle: 'long' }) // '15 August 2026'
533
+ formatIsoDate('nonsense') // '' — malformed input is "no selection", not a crash
534
+ ```
535
+
536
+ #### Passwords
537
+
538
+ `IPasswordInput` is `IInput` with a reveal toggle in the trailing area, plus an
539
+ optional four-segment strength meter.
540
+
541
+ ```vue
542
+ <IPasswordInput v-model="password" strength />
543
+
544
+ <!-- Toggle only, no meter -->
545
+ <IPasswordInput v-model="password" />
546
+
547
+ <!-- No toggle either -->
548
+ <IPasswordInput v-model="password" :toggle="false" />
549
+ ```
550
+
551
+ The score counts length (8 and 12 characters), mixed case, a digit and a
552
+ symbol, capped at four. It is a deliberately transparent nudge toward better
553
+ passwords, **not** a security control — enforce real policy in the `IForm`
554
+ validator, where it can actually reject a value.
555
+
556
+ Every string is overridable, since components must not bake in English:
557
+
558
+ ```vue
559
+ <IPasswordInput
560
+ v-model="password"
561
+ strength
562
+ show-label="Afficher le mot de passe"
563
+ hide-label="Masquer le mot de passe"
564
+ :strength-labels="['Faible', 'Moyen', 'Bon', 'Fort']"
565
+ />
566
+ ```
567
+
568
+ `class` lands on the wrapper that stacks the field above the meter; `ui` reaches
569
+ `root`, `input`, `toggle`, `meter`, `track`, `segment` and `label`.
570
+
571
+ #### Autosizing textareas
572
+
573
+ ```vue
574
+ <!-- Grows without limit -->
575
+ <ITextarea v-model="note" autosize />
576
+
577
+ <!-- Between 2 and 8 rows, then scrolls -->
578
+ <ITextarea v-model="note" :autosize="{ min: 2, max: 8 }" />
579
+ ```
580
+
581
+ `autosize` overrides `rows` and drops the drag handle, since the measured
582
+ height is the point. The field shrinks as well as grows, and re-measures when
583
+ the model changes from outside — a reset or a prefill resizes correctly.
584
+
437
585
  `ISelect` and `IRadioGroup` accept plain strings or `{ label, value, disabled }` objects. Both also take a default slot if you'd rather compose the Reka primitives yourself.
438
586
 
439
587
  `ISelect` also takes groups — an entry with its own `items` becomes a labelled
@@ -3,5 +3,5 @@
3
3
  * Consumed by the Vue plugin (global registration) and the Nuxt module
4
4
  * (auto-imports). Keep in sync with `src/components/index.ts`.
5
5
  */
6
- export declare const componentNames: readonly ["Alert", "App", "Badge", "Banner", "Breadcrumb", "Button", "ButtonGroup", "Card", "Checkbox", "Combobox", "ConfirmDialog", "Dialog", "DropdownMenu", "EmptyState", "Form", "FormField", "Input", "Label", "NumberInput", "Pagination", "Progress", "RadioGroup", "Select", "Separator", "Skeleton", "Stat", "Stepper", "Switch", "Table", "Tabs", "Textarea", "Toaster", "Tooltip"];
6
+ export declare const componentNames: readonly ["Alert", "App", "Badge", "Banner", "Breadcrumb", "Button", "ButtonGroup", "Card", "Checkbox", "Combobox", "ConfirmDialog", "DatePicker", "DateRangePicker", "Dialog", "DropdownMenu", "EmptyState", "Form", "FormField", "Input", "Label", "NumberInput", "Pagination", "PasswordInput", "Progress", "RadioGroup", "Select", "Separator", "Skeleton", "Stat", "Stepper", "Switch", "Table", "Tabs", "Textarea", "Toaster", "Tooltip"];
7
7
  export type ComponentName = (typeof componentNames)[number];
@@ -0,0 +1,52 @@
1
+ export interface DatePickerProps {
2
+ size?: 'sm' | 'md' | 'lg';
3
+ placeholder?: string;
4
+ disabled?: boolean;
5
+ /** Mark the field as invalid — styles the border and ring red. */
6
+ invalid?: boolean;
7
+ id?: string;
8
+ /** Earliest selectable date, as an ISO `YYYY-MM-DD` string. */
9
+ min?: string;
10
+ /** Latest selectable date, as an ISO `YYYY-MM-DD` string. */
11
+ max?: string;
12
+ /** Locale for the month names, weekday initials and the trigger's text. */
13
+ locale?: string;
14
+ /** How the selected date reads on the trigger. */
15
+ format?: Intl.DateTimeFormatOptions;
16
+ /** 0 is Sunday. Defaults to the locale's own convention. */
17
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
18
+ /** Offer a "clear" action in the footer. */
19
+ clearable?: boolean;
20
+ /** Footer and navigation labels — override for non-English apps. */
21
+ todayLabel?: string;
22
+ clearLabel?: string;
23
+ previousLabel?: string;
24
+ nextLabel?: string;
25
+ /** Skip built-in classes; you take over styling entirely. */
26
+ unstyled?: boolean;
27
+ /** Applied to the trigger, which is the element carrying the field chrome. */
28
+ class?: string;
29
+ /** Override classes per slot, e.g. `{ content: 'p-4' }`. */
30
+ ui?: Partial<Record<'trigger' | 'placeholder' | 'content' | 'header' | 'heading' | 'nav' | 'months' | 'grid' | 'headCell' | 'cell' | 'cellTrigger' | 'footer' | 'action', string>>;
31
+ }
32
+ type __VLS_Props = DatePickerProps;
33
+ type __VLS_ModelProps = {
34
+ /** ISO `YYYY-MM-DD`, never a `Date`. See `composables/date.ts` for why. */
35
+ modelValue?: string | null;
36
+ };
37
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
38
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
39
+ "update:modelValue": (value: string | null) => any;
40
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
41
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
42
+ }>, {
43
+ unstyled: boolean;
44
+ placeholder: string;
45
+ invalid: boolean;
46
+ todayLabel: string;
47
+ clearLabel: string;
48
+ previousLabel: string;
49
+ nextLabel: string;
50
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
51
+ declare const _default: typeof __VLS_export;
52
+ export default _default;
@@ -0,0 +1,60 @@
1
+ /** Both ends are ISO `YYYY-MM-DD` strings, and either may be absent. */
2
+ export interface DateRange {
3
+ start: string | null;
4
+ end: string | null;
5
+ }
6
+ export interface DateRangePickerProps {
7
+ size?: 'sm' | 'md' | 'lg';
8
+ placeholder?: string;
9
+ disabled?: boolean;
10
+ /** Mark the field as invalid — styles the border and ring red. */
11
+ invalid?: boolean;
12
+ id?: string;
13
+ /** Earliest selectable date, as an ISO `YYYY-MM-DD` string. */
14
+ min?: string;
15
+ /** Latest selectable date, as an ISO `YYYY-MM-DD` string. */
16
+ max?: string;
17
+ /** Locale for the month names, weekday initials and the trigger's text. */
18
+ locale?: string;
19
+ /** How each end of the range reads on the trigger. */
20
+ format?: Intl.DateTimeFormatOptions;
21
+ /** 0 is Sunday. Defaults to the locale's own convention. */
22
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
23
+ /** Months shown side by side. Two makes picking a span across a boundary sane. */
24
+ months?: number;
25
+ /** Offer a "clear" action in the footer. */
26
+ clearable?: boolean;
27
+ /** Separator between the two dates on the trigger. */
28
+ separator?: string;
29
+ /** Footer and navigation labels — override for non-English apps. */
30
+ clearLabel?: string;
31
+ previousLabel?: string;
32
+ nextLabel?: string;
33
+ /** Skip built-in classes; you take over styling entirely. */
34
+ unstyled?: boolean;
35
+ /** Applied to the trigger, which is the element carrying the field chrome. */
36
+ class?: string;
37
+ /** Override classes per slot, e.g. `{ content: 'p-4' }`. */
38
+ ui?: Partial<Record<'trigger' | 'placeholder' | 'content' | 'header' | 'heading' | 'nav' | 'months' | 'grid' | 'headCell' | 'cell' | 'cellTrigger' | 'footer' | 'action', string>>;
39
+ }
40
+ type __VLS_Props = DateRangePickerProps;
41
+ type __VLS_ModelProps = {
42
+ modelValue?: DateRange;
43
+ };
44
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
45
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
46
+ "update:modelValue": (value: DateRange) => any;
47
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
48
+ "onUpdate:modelValue"?: ((value: DateRange) => any) | undefined;
49
+ }>, {
50
+ unstyled: boolean;
51
+ separator: string;
52
+ placeholder: string;
53
+ invalid: boolean;
54
+ months: number;
55
+ clearLabel: string;
56
+ previousLabel: string;
57
+ nextLabel: string;
58
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
59
+ declare const _default: typeof __VLS_export;
60
+ export default _default;
@@ -7,16 +7,46 @@ export interface InputProps {
7
7
  /** Mark the field as invalid — styles the border and ring red. */
8
8
  invalid?: boolean;
9
9
  id?: string;
10
+ /** Show a clear button in the trailing area while the field has a value. */
11
+ clearable?: boolean;
12
+ /** Show a spinner in the trailing area. Does not disable the field. */
13
+ loading?: boolean;
14
+ /**
15
+ * Milliseconds to wait after the last keystroke before the model updates.
16
+ * `0` (the default) updates on every keystroke. Blur and Enter flush a
17
+ * pending update immediately, so a submit never reads a stale value.
18
+ */
19
+ debounce?: number;
20
+ /** Accessible name for the clear button — override for non-English apps. */
21
+ clearLabel?: string;
10
22
  /** Skip built-in classes; you take over styling entirely. */
11
23
  unstyled?: boolean;
24
+ /** Applied to the outer field, which is the element carrying the chrome. */
12
25
  class?: string;
26
+ /** Override classes per slot, e.g. `{ input: 'text-right' }`. */
27
+ ui?: {
28
+ root?: string;
29
+ input?: string;
30
+ leading?: string;
31
+ trailing?: string;
32
+ clear?: string;
33
+ };
13
34
  }
14
35
  type __VLS_Props = InputProps;
15
36
  type __VLS_ModelProps = {
16
37
  modelValue?: string | number | null;
17
38
  };
18
39
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
40
+ declare var __VLS_1: {}, __VLS_3: {};
41
+ type __VLS_Slots = {} & {
42
+ leading?: (props: typeof __VLS_1) => any;
43
+ } & {
44
+ trailing?: (props: typeof __VLS_3) => any;
45
+ };
46
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
47
+ /** The underlying element, for focus management by the caller. */
48
+ input: import("vue").Ref<HTMLInputElement | undefined, HTMLInputElement | undefined>;
49
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
50
  "update:modelValue": (value: string | number | null | undefined) => any;
21
51
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
52
  "onUpdate:modelValue"?: ((value: string | number | null | undefined) => any) | undefined;
@@ -24,6 +54,14 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
24
54
  unstyled: boolean;
25
55
  type: string;
26
56
  invalid: boolean;
57
+ clearLabel: string;
58
+ debounce: number;
27
59
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
60
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
28
61
  declare const _default: typeof __VLS_export;
29
62
  export default _default;
63
+ type __VLS_WithSlots<T, S> = T & {
64
+ new (): {
65
+ $slots: S;
66
+ };
67
+ };
@@ -42,12 +42,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
42
42
  }>, {
43
43
  unstyled: boolean;
44
44
  label: string;
45
+ nextLabel: string;
45
46
  total: number;
46
47
  itemsPerPage: number;
47
48
  siblingCount: number;
48
49
  showEdges: boolean;
49
50
  prevLabel: string;
50
- nextLabel: string;
51
51
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
52
52
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
53
53
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,54 @@
1
+ export interface PasswordInputProps {
2
+ size?: 'sm' | 'md' | 'lg';
3
+ placeholder?: string;
4
+ disabled?: boolean;
5
+ required?: boolean;
6
+ /** Mark the field as invalid — styles the border and ring red. */
7
+ invalid?: boolean;
8
+ id?: string;
9
+ /** Show the reveal toggle in the trailing area. */
10
+ toggle?: boolean;
11
+ /** Render a four-segment strength meter under the field. */
12
+ strength?: boolean;
13
+ /** Accessible names for the reveal toggle — override for non-English apps. */
14
+ showLabel?: string;
15
+ hideLabel?: string;
16
+ /**
17
+ * Words for scores 1–4, weakest first. Score 0 shows nothing, so this takes
18
+ * exactly four entries. Override for non-English apps.
19
+ */
20
+ strengthLabels?: [string, string, string, string];
21
+ /** Skip built-in classes; you take over styling entirely. */
22
+ unstyled?: boolean;
23
+ /** Applied to the outer wrapper, which stacks the field above the meter. */
24
+ class?: string;
25
+ /** Override classes per slot, e.g. `{ meter: 'mt-1' }`. */
26
+ ui?: {
27
+ root?: string;
28
+ input?: string;
29
+ toggle?: string;
30
+ meter?: string;
31
+ track?: string;
32
+ segment?: string;
33
+ label?: string;
34
+ };
35
+ }
36
+ type __VLS_Props = PasswordInputProps;
37
+ type __VLS_ModelProps = {
38
+ modelValue?: string;
39
+ };
40
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
41
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
42
+ "update:modelValue": (value: string) => any;
43
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
44
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
45
+ }>, {
46
+ unstyled: boolean;
47
+ invalid: boolean;
48
+ toggle: boolean;
49
+ showLabel: string;
50
+ hideLabel: string;
51
+ strengthLabels: [string, string, string, string];
52
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
53
+ declare const _default: typeof __VLS_export;
54
+ export default _default;
@@ -1,6 +1,18 @@
1
1
  export interface TextareaProps {
2
2
  size?: 'sm' | 'md' | 'lg';
3
+ /**
4
+ * Fixed height in rows. Ignored when `autosize` is set — pass the bounds
5
+ * through `autosize` instead.
6
+ */
3
7
  rows?: number;
8
+ /**
9
+ * Grow with the content. `true` grows without limit; `{ min, max }` bounds
10
+ * it in rows, and the field scrolls once it hits `max`.
11
+ */
12
+ autosize?: boolean | {
13
+ min?: number;
14
+ max?: number;
15
+ };
4
16
  placeholder?: string;
5
17
  disabled?: boolean;
6
18
  required?: boolean;
@@ -16,7 +28,10 @@ type __VLS_ModelProps = {
16
28
  modelValue?: string | null;
17
29
  };
18
30
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
32
+ /** The underlying element, for focus management by the caller. */
33
+ textarea: import("vue").Ref<HTMLTextAreaElement | undefined, HTMLTextAreaElement | undefined>;
34
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
35
  "update:modelValue": (value: string | null | undefined) => any;
21
36
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
37
  "onUpdate:modelValue"?: ((value: string | null | undefined) => any) | undefined;
@@ -9,6 +9,8 @@ export { default as Card } from './Card.vue';
9
9
  export { default as Checkbox } from './Checkbox.vue';
10
10
  export { default as Combobox } from './Combobox.vue';
11
11
  export { default as ConfirmDialog } from './ConfirmDialog.vue';
12
+ export { default as DatePicker } from './DatePicker.vue';
13
+ export { default as DateRangePicker } from './DateRangePicker.vue';
12
14
  export { default as Dialog } from './Dialog.vue';
13
15
  export { default as DropdownMenu } from './DropdownMenu.vue';
14
16
  export { default as EmptyState } from './EmptyState.vue';
@@ -18,6 +20,7 @@ export { default as Input } from './Input.vue';
18
20
  export { default as Label } from './Label.vue';
19
21
  export { default as NumberInput } from './NumberInput.vue';
20
22
  export { default as Pagination } from './Pagination.vue';
23
+ export { default as PasswordInput } from './PasswordInput.vue';
21
24
  export { default as Progress } from './Progress.vue';
22
25
  export { default as RadioGroup } from './RadioGroup.vue';
23
26
  export { default as Select } from './Select.vue';
@@ -0,0 +1,21 @@
1
+ import type { DateValue } from '@internationalized/date';
2
+ import { CalendarDate } from '@internationalized/date';
3
+ /**
4
+ * Parse an ISO date, or `undefined` if it is absent or malformed.
5
+ *
6
+ * Malformed input resolves to "no selection" rather than throwing: the value
7
+ * often comes from a URL or a stale draft, and a blank calendar is a better
8
+ * outcome for the user than a crashed render.
9
+ */
10
+ export declare function toCalendarDate(iso: string | null | undefined): CalendarDate | undefined;
11
+ /** Back to the canonical `YYYY-MM-DD`. */
12
+ export declare function toIsoDate(date: DateValue | null | undefined): string | null;
13
+ /** Today in the viewer's own zone, as an ISO date string. */
14
+ export declare function isoToday(): string;
15
+ /**
16
+ * Render an ISO date for display. Returns `''` for absent or malformed input
17
+ * so a caller can fall back to a placeholder.
18
+ */
19
+ export declare function formatIsoDate(iso: string | null | undefined, locale?: string, options?: Intl.DateTimeFormatOptions): string;
20
+ export { CalendarDate };
21
+ export type { DateValue };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,8 @@ export type { CardProps } from './components/Card.vue';
12
12
  export type { CheckboxProps } from './components/Checkbox.vue';
13
13
  export type { ComboboxItemGroup, ComboboxItemOption, ComboboxItems, ComboboxProps } from './components/Combobox.vue';
14
14
  export type { ConfirmDialogProps } from './components/ConfirmDialog.vue';
15
+ export type { DatePickerProps } from './components/DatePicker.vue';
16
+ export type { DateRange, DateRangePickerProps } from './components/DateRangePicker.vue';
15
17
  export type { DialogProps } from './components/Dialog.vue';
16
18
  export type { DropdownMenuProps } from './components/DropdownMenu.vue';
17
19
  export type { EmptyStateProps } from './components/EmptyState.vue';
@@ -21,6 +23,7 @@ export type { InputProps } from './components/Input.vue';
21
23
  export type { LabelProps } from './components/Label.vue';
22
24
  export type { NumberInputProps } from './components/NumberInput.vue';
23
25
  export type { PaginationProps } from './components/Pagination.vue';
26
+ export type { PasswordInputProps } from './components/PasswordInput.vue';
24
27
  export type { ProgressProps } from './components/Progress.vue';
25
28
  export type { RadioGroupItemOption, RadioGroupProps } from './components/RadioGroup.vue';
26
29
  export type { SelectItemGroup, SelectItemOption, SelectItems, SelectProps } from './components/Select.vue';
@@ -38,6 +41,7 @@ export * from './composables/appearance';
38
41
  export * from './composables/button-group';
39
42
  export * from './composables/confirm';
40
43
  export * from './composables/data-table';
44
+ export * from './composables/date';
41
45
  export * from './composables/decimal';
42
46
  export * from './composables/dropdown-menu';
43
47
  export * from './composables/form';
package/dist/index.js CHANGED
@@ -28,47 +28,54 @@ import { resolveConfirm as B, useConfirm as V, useConfirmState as H } from "./pa
28
28
  import { dialogTheme as U } from "./packages/iryx-ui/src/theme/dialog.js";
29
29
  import W from "./packages/iryx-ui/src/components/Dialog.js";
30
30
  import G from "./packages/iryx-ui/src/components/ConfirmDialog.js";
31
- import { dropdownMenuTheme as K } from "./packages/iryx-ui/src/theme/dropdown-menu.js";
32
- import { isSeparator as q, isSubmenu as J } from "./packages/iryx-ui/src/composables/dropdown-menu.js";
33
- import Y from "./packages/iryx-ui/src/components/DropdownMenu.js";
34
- import { emptyStateTheme as X } from "./packages/iryx-ui/src/theme/empty-state.js";
35
- import Z from "./packages/iryx-ui/src/components/EmptyState.js";
36
- import Q from "./packages/iryx-ui/src/components/Form.js";
37
- import { labelTheme as $ } from "./packages/iryx-ui/src/theme/label.js";
38
- import ee from "./packages/iryx-ui/src/components/Label.js";
39
- import te from "./packages/iryx-ui/src/components/FormField.js";
40
- import ne from "./packages/iryx-ui/src/components/Input.js";
41
- import { addDecimals as re, clampDecimal as ie, compareDecimals as ae, formatDecimal as oe, formatForLocale as se, isDecimal as ce, localeSeparators as le, parseDecimal as ue, parseFromLocale as de, roundDecimal as fe, toEditable as pe } from "./packages/iryx-ui/src/composables/decimal.js";
42
- import { numberInputTheme as me } from "./packages/iryx-ui/src/theme/number-input.js";
43
- import he from "./packages/iryx-ui/src/components/NumberInput.js";
44
- import { paginationTheme as ge } from "./packages/iryx-ui/src/theme/pagination.js";
45
- import _e from "./packages/iryx-ui/src/components/Pagination.js";
46
- import { progressTheme as ve } from "./packages/iryx-ui/src/theme/progress.js";
47
- import ye from "./packages/iryx-ui/src/components/Progress.js";
48
- import { radioGroupTheme as be } from "./packages/iryx-ui/src/theme/radio-group.js";
49
- import xe from "./packages/iryx-ui/src/components/RadioGroup.js";
50
- import { selectTheme as Se } from "./packages/iryx-ui/src/theme/select.js";
51
- import Ce from "./packages/iryx-ui/src/components/Select.js";
52
- import { separatorTheme as we } from "./packages/iryx-ui/src/theme/separator.js";
53
- import Te from "./packages/iryx-ui/src/components/Separator.js";
54
- import { skeletonTheme as Ee } from "./packages/iryx-ui/src/theme/skeleton.js";
55
- import De from "./packages/iryx-ui/src/components/Skeleton.js";
56
- import { statTheme as Oe } from "./packages/iryx-ui/src/theme/stat.js";
57
- import ke from "./packages/iryx-ui/src/components/Stat.js";
58
- import { stepperTheme as Ae } from "./packages/iryx-ui/src/theme/stepper.js";
59
- import je from "./packages/iryx-ui/src/components/Stepper.js";
60
- import { switchTheme as Me } from "./packages/iryx-ui/src/theme/switch.js";
61
- import Ne from "./packages/iryx-ui/src/components/Switch.js";
62
- import { getRowValue as Pe, useDataTable as Fe } from "./packages/iryx-ui/src/composables/data-table.js";
63
- import { tableTheme as Ie } from "./packages/iryx-ui/src/theme/table.js";
64
- import Le from "./packages/iryx-ui/src/components/Table.js";
65
- import { tabsTheme as Re } from "./packages/iryx-ui/src/theme/tabs.js";
66
- import ze from "./packages/iryx-ui/src/components/Tabs.js";
67
- import Be from "./packages/iryx-ui/src/components/Textarea.js";
68
- import { useToast as Ve, useToastState as He } from "./packages/iryx-ui/src/composables/toast.js";
69
- import { toastTheme as Ue } from "./packages/iryx-ui/src/theme/toast.js";
70
- import We from "./packages/iryx-ui/src/components/Toaster.js";
71
- import { tooltipTheme as Ge } from "./packages/iryx-ui/src/theme/tooltip.js";
72
- import Ke from "./packages/iryx-ui/src/components/Tooltip.js";
73
- import { IryxUi as qe, createIryxUi as Je } from "./packages/iryx-ui/src/plugin.js";
74
- export { a as Alert, d as App, p as Badge, h as Banner, _ as Breadcrumb, x as Button, C as ButtonGroup, T as Card, D as Checkbox, z as Combobox, G as ConfirmDialog, W as Dialog, Y as DropdownMenu, Z as EmptyState, Q as Form, te as FormField, ne as Input, qe as IryxUi, ee as Label, he as NumberInput, _e as Pagination, ye as Progress, xe as RadioGroup, Ce as Select, Te as Separator, De as Skeleton, ke as Stat, je as Stepper, Ne as Switch, Le as Table, ze as Tabs, Be as Textarea, We as Toaster, Ke as Tooltip, re as addDecimals, i as alertTheme, c as applyTheme, f as badgeTheme, m as bannerTheme, g as breadcrumbTheme, v as buttonGroupContextKey, S as buttonGroupTheme, b as buttonTheme, w as cardTheme, E as checkboxTheme, ie as clampDecimal, l as clearTheme, R as comboboxTheme, ae as compareDecimals, e as componentNames, Je as createIryxUi, t as defaultConfig, U as dialogTheme, K as dropdownMenuTheme, X as emptyStateTheme, F as fieldBase, O as formContextKey, k as formFieldContextKey, oe as formatDecimal, se as formatForLocale, A as getByPath, Pe as getRowValue, o as initAppearance, I as inputTheme, n as iryxUiConfigKey, ce as isDecimal, q as isSeparator, j as isStandardSchema, J as isSubmenu, M as issuePath, $ as labelTheme, le as localeSeparators, me as numberInputTheme, ge as paginationTheme, ue as parseDecimal, de as parseFromLocale, ve as progressTheme, be as radioGroupTheme, B as resolveConfirm, fe as roundDecimal, Se as selectTheme, we as separatorTheme, Ee as skeletonTheme, Oe as statTheme, Ae as stepperTheme, Me as switchTheme, Ie as tableTheme, Re as tabsTheme, L as textareaTheme, u as themes, pe as toEditable, Ue as toastTheme, Ge as tooltipTheme, s as useAppearance, y as useButtonGroup, V as useConfirm, H as useConfirmState, Fe as useDataTable, N as useForm, P as useFormField, r as useIryxUiConfig, Ve as useToast, He as useToastState };
31
+ import { $2aaf608024c21ca1$export$99faa760c7908e4f as K } from "./node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js";
32
+ import { formatIsoDate as q, isoToday as J, toCalendarDate as Y, toIsoDate as X } from "./packages/iryx-ui/src/composables/date.js";
33
+ import { datePickerTheme as Z } from "./packages/iryx-ui/src/theme/date-picker.js";
34
+ import Q from "./packages/iryx-ui/src/components/DatePicker.js";
35
+ import $ from "./packages/iryx-ui/src/components/DateRangePicker.js";
36
+ import { dropdownMenuTheme as ee } from "./packages/iryx-ui/src/theme/dropdown-menu.js";
37
+ import { isSeparator as te, isSubmenu as ne } from "./packages/iryx-ui/src/composables/dropdown-menu.js";
38
+ import re from "./packages/iryx-ui/src/components/DropdownMenu.js";
39
+ import { emptyStateTheme as ie } from "./packages/iryx-ui/src/theme/empty-state.js";
40
+ import ae from "./packages/iryx-ui/src/components/EmptyState.js";
41
+ import oe from "./packages/iryx-ui/src/components/Form.js";
42
+ import { labelTheme as se } from "./packages/iryx-ui/src/theme/label.js";
43
+ import ce from "./packages/iryx-ui/src/components/Label.js";
44
+ import le from "./packages/iryx-ui/src/components/FormField.js";
45
+ import ue from "./packages/iryx-ui/src/components/Input.js";
46
+ import { addDecimals as de, clampDecimal as fe, compareDecimals as pe, formatDecimal as me, formatForLocale as he, isDecimal as ge, localeSeparators as _e, parseDecimal as ve, parseFromLocale as ye, roundDecimal as be, toEditable as xe } from "./packages/iryx-ui/src/composables/decimal.js";
47
+ import { numberInputTheme as Se } from "./packages/iryx-ui/src/theme/number-input.js";
48
+ import Ce from "./packages/iryx-ui/src/components/NumberInput.js";
49
+ import { paginationTheme as we } from "./packages/iryx-ui/src/theme/pagination.js";
50
+ import Te from "./packages/iryx-ui/src/components/Pagination.js";
51
+ import { passwordInputTheme as Ee } from "./packages/iryx-ui/src/theme/password-input.js";
52
+ import De from "./packages/iryx-ui/src/components/PasswordInput.js";
53
+ import { progressTheme as Oe } from "./packages/iryx-ui/src/theme/progress.js";
54
+ import ke from "./packages/iryx-ui/src/components/Progress.js";
55
+ import { radioGroupTheme as Ae } from "./packages/iryx-ui/src/theme/radio-group.js";
56
+ import je from "./packages/iryx-ui/src/components/RadioGroup.js";
57
+ import { selectTheme as Me } from "./packages/iryx-ui/src/theme/select.js";
58
+ import Ne from "./packages/iryx-ui/src/components/Select.js";
59
+ import { separatorTheme as Pe } from "./packages/iryx-ui/src/theme/separator.js";
60
+ import Fe from "./packages/iryx-ui/src/components/Separator.js";
61
+ import { skeletonTheme as Ie } from "./packages/iryx-ui/src/theme/skeleton.js";
62
+ import Le from "./packages/iryx-ui/src/components/Skeleton.js";
63
+ import { statTheme as Re } from "./packages/iryx-ui/src/theme/stat.js";
64
+ import ze from "./packages/iryx-ui/src/components/Stat.js";
65
+ import { stepperTheme as Be } from "./packages/iryx-ui/src/theme/stepper.js";
66
+ import Ve from "./packages/iryx-ui/src/components/Stepper.js";
67
+ import { switchTheme as He } from "./packages/iryx-ui/src/theme/switch.js";
68
+ import Ue from "./packages/iryx-ui/src/components/Switch.js";
69
+ import { getRowValue as We, useDataTable as Ge } from "./packages/iryx-ui/src/composables/data-table.js";
70
+ import { tableTheme as Ke } from "./packages/iryx-ui/src/theme/table.js";
71
+ import qe from "./packages/iryx-ui/src/components/Table.js";
72
+ import { tabsTheme as Je } from "./packages/iryx-ui/src/theme/tabs.js";
73
+ import Ye from "./packages/iryx-ui/src/components/Tabs.js";
74
+ import Xe from "./packages/iryx-ui/src/components/Textarea.js";
75
+ import { useToast as Ze, useToastState as Qe } from "./packages/iryx-ui/src/composables/toast.js";
76
+ import { toastTheme as $e } from "./packages/iryx-ui/src/theme/toast.js";
77
+ import et from "./packages/iryx-ui/src/components/Toaster.js";
78
+ import { tooltipTheme as tt } from "./packages/iryx-ui/src/theme/tooltip.js";
79
+ import nt from "./packages/iryx-ui/src/components/Tooltip.js";
80
+ import { IryxUi as rt, createIryxUi as it } from "./packages/iryx-ui/src/plugin.js";
81
+ export { a as Alert, d as App, p as Badge, h as Banner, _ as Breadcrumb, x as Button, C as ButtonGroup, K as CalendarDate, T as Card, D as Checkbox, z as Combobox, G as ConfirmDialog, Q as DatePicker, $ as DateRangePicker, W as Dialog, re as DropdownMenu, ae as EmptyState, oe as Form, le as FormField, ue as Input, rt as IryxUi, ce as Label, Ce as NumberInput, Te as Pagination, De as PasswordInput, ke as Progress, je as RadioGroup, Ne as Select, Fe as Separator, Le as Skeleton, ze as Stat, Ve as Stepper, Ue as Switch, qe as Table, Ye as Tabs, Xe as Textarea, et as Toaster, nt as Tooltip, de as addDecimals, i as alertTheme, c as applyTheme, f as badgeTheme, m as bannerTheme, g as breadcrumbTheme, v as buttonGroupContextKey, S as buttonGroupTheme, b as buttonTheme, w as cardTheme, E as checkboxTheme, fe as clampDecimal, l as clearTheme, R as comboboxTheme, pe as compareDecimals, e as componentNames, it as createIryxUi, Z as datePickerTheme, t as defaultConfig, U as dialogTheme, ee as dropdownMenuTheme, ie as emptyStateTheme, F as fieldBase, O as formContextKey, k as formFieldContextKey, me as formatDecimal, he as formatForLocale, q as formatIsoDate, A as getByPath, We as getRowValue, o as initAppearance, I as inputTheme, n as iryxUiConfigKey, ge as isDecimal, te as isSeparator, j as isStandardSchema, ne as isSubmenu, J as isoToday, M as issuePath, se as labelTheme, _e as localeSeparators, Se as numberInputTheme, we as paginationTheme, ve as parseDecimal, ye as parseFromLocale, Ee as passwordInputTheme, Oe as progressTheme, Ae as radioGroupTheme, B as resolveConfirm, be as roundDecimal, Me as selectTheme, Pe as separatorTheme, Ie as skeletonTheme, Re as statTheme, Be as stepperTheme, He as switchTheme, Ke as tableTheme, Je as tabsTheme, L as textareaTheme, u as themes, Y as toCalendarDate, xe as toEditable, X as toIsoDate, $e as toastTheme, tt as tooltipTheme, s as useAppearance, y as useButtonGroup, V as useConfirm, H as useConfirmState, Ge as useDataTable, N as useForm, P as useFormField, r as useIryxUiConfig, Ze as useToast, Qe as useToastState };