iryx-ui 0.6.0 → 0.8.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/README.md +201 -2
- package/dist/component-names.d.ts +1 -1
- package/dist/components/DatePicker.vue.d.ts +52 -0
- package/dist/components/DateRangePicker.vue.d.ts +60 -0
- package/dist/components/FileUpload.vue.d.ts +64 -0
- package/dist/components/Input.vue.d.ts +39 -1
- package/dist/components/Pagination.vue.d.ts +1 -1
- package/dist/components/PasswordInput.vue.d.ts +54 -0
- package/dist/components/Textarea.vue.d.ts +16 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/composables/date.d.ts +21 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +53 -44
- package/dist/node_modules/.pnpm/@hugeicons_core-free-icons@4.2.3/node_modules/@hugeicons/core-free-icons/dist/esm/index.js +170 -8
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js +122 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/DateFormatter.js +84 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +91 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js +107 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js +159 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js +29 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js +37 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js +6 -0
- package/dist/packages/iryx-ui/src/component-names.js +1 -1
- package/dist/packages/iryx-ui/src/components/DatePicker.js +5 -0
- package/dist/packages/iryx-ui/src/components/DatePicker.vue_vue_type_script_setup_true_lang.js +186 -0
- package/dist/packages/iryx-ui/src/components/DateRangePicker.js +5 -0
- package/dist/packages/iryx-ui/src/components/DateRangePicker.vue_vue_type_script_setup_true_lang.js +210 -0
- package/dist/packages/iryx-ui/src/components/FileUpload.js +5 -0
- package/dist/packages/iryx-ui/src/components/FileUpload.vue_vue_type_script_setup_true_lang.js +209 -0
- package/dist/packages/iryx-ui/src/components/Input.vue_vue_type_script_setup_true_lang.js +94 -25
- package/dist/packages/iryx-ui/src/components/PasswordInput.js +5 -0
- package/dist/packages/iryx-ui/src/components/PasswordInput.vue_vue_type_script_setup_true_lang.js +113 -0
- package/dist/packages/iryx-ui/src/components/Textarea.vue_vue_type_script_setup_true_lang.js +47 -21
- package/dist/packages/iryx-ui/src/components/index.js +52 -44
- package/dist/packages/iryx-ui/src/composables/date.js +25 -0
- package/dist/packages/iryx-ui/src/theme/date-picker.js +45 -0
- package/dist/packages/iryx-ui/src/theme/file-upload.js +29 -0
- package/dist/packages/iryx-ui/src/theme/input.js +22 -6
- package/dist/packages/iryx-ui/src/theme/password-input.js +23 -0
- package/dist/theme/date-picker.d.ts +254 -0
- package/dist/theme/file-upload.d.ts +143 -0
- package/dist/theme/form.d.ts +3 -3
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/input.d.ts +94 -15
- package/dist/theme/password-input.d.ts +97 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -288,9 +288,13 @@ 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
|
-
| `
|
|
293
|
+
| `IFileUpload` | Drag-and-drop file field with `accept` / `maxSize` / `maxFiles`, thumbnails and a remove action |
|
|
294
|
+
| `IDatePicker` | Calendar in a popover; the model is an ISO `YYYY-MM-DD` **string** |
|
|
295
|
+
| `IDateRangePicker` | Two-month range calendar; the model is `{ start, end }` ISO strings |
|
|
296
|
+
| `IPasswordInput` | Masked field with a show/hide toggle and an optional strength meter |
|
|
297
|
+
| `ITextarea` | Multi-line field with matching sizes, `invalid` state and optional `autosize` |
|
|
294
298
|
| `ILabel` | Field label with optional `required` asterisk |
|
|
295
299
|
| `ICheckbox` | Tri-state checkbox (`true` / `false` / `'indeterminate'`), optional `label` + `description` |
|
|
296
300
|
| `ISelect` | Listbox with keyboard nav and typeahead, driven by an `items` array, with optional groups |
|
|
@@ -434,6 +438,201 @@ const framework = ref('vue')
|
|
|
434
438
|
</template>
|
|
435
439
|
```
|
|
436
440
|
|
|
441
|
+
#### Input affixes, clearing, loading and debounce
|
|
442
|
+
|
|
443
|
+
`IInput` renders its chrome on a wrapper element, so `leading` and `trailing`
|
|
444
|
+
slot content sits *inside* the field and takes real space — a long value is
|
|
445
|
+
truncated by the affix rather than sliding underneath it.
|
|
446
|
+
|
|
447
|
+
```vue
|
|
448
|
+
<IInput v-model="search" clearable placeholder="Search invoices…">
|
|
449
|
+
<template #leading>
|
|
450
|
+
<HugeiconsIcon :icon="Search01Icon" />
|
|
451
|
+
</template>
|
|
452
|
+
</IInput>
|
|
453
|
+
|
|
454
|
+
<IInput v-model="team" placeholder="your-team">
|
|
455
|
+
<template #trailing>
|
|
456
|
+
<span class="text-sm">.example.com</span>
|
|
457
|
+
</template>
|
|
458
|
+
</IInput>
|
|
459
|
+
|
|
460
|
+
<!-- Spinner in the trailing area; the field stays editable. -->
|
|
461
|
+
<IInput v-model="slug" :loading="checking" />
|
|
462
|
+
|
|
463
|
+
<!-- The model updates 500ms after the last keystroke. -->
|
|
464
|
+
<IInput v-model="query" :debounce="500" clearable />
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
| Prop | Effect |
|
|
468
|
+
| --- | --- |
|
|
469
|
+
| `clearable` | Clear button in the trailing area whenever the field is non-empty |
|
|
470
|
+
| `loading` | Spinner in the trailing area. Does **not** disable the field |
|
|
471
|
+
| `debounce` | Milliseconds to wait after the last keystroke before the model updates. `0` (default) updates on every keystroke |
|
|
472
|
+
| `clearLabel` | Accessible name for the clear button, for non-English apps |
|
|
473
|
+
|
|
474
|
+
The displayed text always updates on the keystroke — only the model lags. Blur
|
|
475
|
+
and Enter flush a pending update immediately, so a submit never reads a stale
|
|
476
|
+
value, and an external write (a reset or prefill) cancels whatever is queued.
|
|
477
|
+
|
|
478
|
+
`class` lands on the wrapper, since that is the element carrying the field
|
|
479
|
+
chrome; use `ui` to reach the parts (`root`, `input`, `leading`, `trailing`,
|
|
480
|
+
`clear`). Stray attributes like `name`, `autocomplete` and `maxlength` are
|
|
481
|
+
forwarded to the `<input>` itself. `ref` exposes the element as `.input` for
|
|
482
|
+
focus management.
|
|
483
|
+
|
|
484
|
+
#### Files
|
|
485
|
+
|
|
486
|
+
```vue
|
|
487
|
+
<script setup lang="ts">
|
|
488
|
+
import { ref } from 'vue'
|
|
489
|
+
|
|
490
|
+
const logo = ref<File[]>([])
|
|
491
|
+
</script>
|
|
492
|
+
|
|
493
|
+
<template>
|
|
494
|
+
<IFileUpload
|
|
495
|
+
v-model="logo"
|
|
496
|
+
accept="image/*"
|
|
497
|
+
:max-size="2 * 1024 * 1024"
|
|
498
|
+
label="Drag your logo here"
|
|
499
|
+
browse-label="Browse images"
|
|
500
|
+
hint="PNG, JPG or SVG up to 2 MB"
|
|
501
|
+
@reject="onReject"
|
|
502
|
+
/>
|
|
503
|
+
</template>
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
The model is **always a `File[]`**, even without `multiple` — a `File | File[]`
|
|
507
|
+
union would make every caller narrow the type before touching it, and the
|
|
508
|
+
single case is just an array holding at most one. Without `multiple`, picking
|
|
509
|
+
again replaces rather than appends.
|
|
510
|
+
|
|
511
|
+
| Prop | Effect |
|
|
512
|
+
| --- | --- |
|
|
513
|
+
| `multiple` | Accept more than one file |
|
|
514
|
+
| `accept` | Native syntax: `image/*`, `.pdf`, `image/png` |
|
|
515
|
+
| `maxSize` | Largest accepted size, in bytes |
|
|
516
|
+
| `maxFiles` | Cap on how many files may be held at once |
|
|
517
|
+
| `label` | Prompt in the zone, above the hint |
|
|
518
|
+
| `browseLabel` | Text on the browse button |
|
|
519
|
+
| `hint` | Fine print under the prompt — the accepted types belong here |
|
|
520
|
+
|
|
521
|
+
Every string is a prop, including `removeLabel` and the three rejection
|
|
522
|
+
messages, so nothing bakes in English.
|
|
523
|
+
|
|
524
|
+
`accept` is enforced in the component as well as on the input, because a
|
|
525
|
+
dragged-in file bypasses the native filter entirely. Refused files raise
|
|
526
|
+
`@reject` with `{ file, reason }` — `'type'`, `'size'` or `'count'` — so you
|
|
527
|
+
can word your own message; the built-in text is available through the
|
|
528
|
+
`tooLargeText`, `wrongTypeText` and `tooManyText` props.
|
|
529
|
+
|
|
530
|
+
Image files get a thumbnail, anything else a placeholder of the same size so
|
|
531
|
+
rows stay aligned. The object URLs behind those thumbnails are revoked as soon
|
|
532
|
+
as a file leaves the list or the component unmounts.
|
|
533
|
+
|
|
534
|
+
#### Dates
|
|
535
|
+
|
|
536
|
+
The model is an ISO `YYYY-MM-DD` **string**, never a `Date`.
|
|
537
|
+
|
|
538
|
+
```vue
|
|
539
|
+
<script setup lang="ts">
|
|
540
|
+
import { ref } from 'vue'
|
|
541
|
+
|
|
542
|
+
const issuedOn = ref<string | null>('2026-08-15')
|
|
543
|
+
const period = ref({ start: '2026-08-01', end: '2026-08-31' })
|
|
544
|
+
</script>
|
|
545
|
+
|
|
546
|
+
<template>
|
|
547
|
+
<IDatePicker v-model="issuedOn" clearable />
|
|
548
|
+
<IDateRangePicker v-model="period" clearable />
|
|
549
|
+
</template>
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
A `Date` is a timestamp, so it always carries a time zone. `new Date('2026-08-15')`
|
|
553
|
+
parses as UTC midnight, and a user west of Greenwich formatting it locally sees
|
|
554
|
+
the 14th — which silently moves a record into the wrong reporting period. A
|
|
555
|
+
calendar date has no zone, so it stays the day you picked. Internally the
|
|
556
|
+
components use `@internationalized/date`; that never reaches your model, so
|
|
557
|
+
formatting the string with `dayjs` or anything else on the way out is fine.
|
|
558
|
+
|
|
559
|
+
| Prop | Effect |
|
|
560
|
+
| --- | --- |
|
|
561
|
+
| `min` / `max` | Selectable bounds, as ISO strings |
|
|
562
|
+
| `locale` | Month names, weekday initials, and the trigger's text |
|
|
563
|
+
| `format` | `Intl.DateTimeFormatOptions` for the trigger, e.g. `{ dateStyle: 'full' }` |
|
|
564
|
+
| `weekStartsOn` | `0` is Sunday. Defaults to the locale's convention |
|
|
565
|
+
| `clearable` | Adds a clear action to the footer |
|
|
566
|
+
| `months` | Range picker only — months side by side, default `2` |
|
|
567
|
+
| `separator` | Range picker only — text between the two dates |
|
|
568
|
+
|
|
569
|
+
Navigation and footer labels (`todayLabel`, `clearLabel`, `previousLabel`,
|
|
570
|
+
`nextLabel`) are all props, so nothing bakes in English.
|
|
571
|
+
|
|
572
|
+
Both render their calendar at a fixed six weeks, so a short month cannot stretch
|
|
573
|
+
its rows to match a taller neighbour and the popover does not resize as you page
|
|
574
|
+
through it. The range picker draws only the committed range — the days between
|
|
575
|
+
the endpoints take a flat tint while the two ends take the solid fill, so a long
|
|
576
|
+
span still shows where it begins and ends.
|
|
577
|
+
|
|
578
|
+
The helpers behind them are exported, for formatting the same values elsewhere:
|
|
579
|
+
|
|
580
|
+
```ts
|
|
581
|
+
import { formatIsoDate, isoToday, toCalendarDate, toIsoDate } from 'iryx-ui'
|
|
582
|
+
|
|
583
|
+
formatIsoDate('2026-08-15', 'en-GB', { dateStyle: 'long' }) // '15 August 2026'
|
|
584
|
+
formatIsoDate('nonsense') // '' — malformed input is "no selection", not a crash
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
#### Passwords
|
|
588
|
+
|
|
589
|
+
`IPasswordInput` is `IInput` with a reveal toggle in the trailing area, plus an
|
|
590
|
+
optional four-segment strength meter.
|
|
591
|
+
|
|
592
|
+
```vue
|
|
593
|
+
<IPasswordInput v-model="password" strength />
|
|
594
|
+
|
|
595
|
+
<!-- Toggle only, no meter -->
|
|
596
|
+
<IPasswordInput v-model="password" />
|
|
597
|
+
|
|
598
|
+
<!-- No toggle either -->
|
|
599
|
+
<IPasswordInput v-model="password" :toggle="false" />
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
The score counts length (8 and 12 characters), mixed case, a digit and a
|
|
603
|
+
symbol, capped at four. It is a deliberately transparent nudge toward better
|
|
604
|
+
passwords, **not** a security control — enforce real policy in the `IForm`
|
|
605
|
+
validator, where it can actually reject a value.
|
|
606
|
+
|
|
607
|
+
Every string is overridable, since components must not bake in English:
|
|
608
|
+
|
|
609
|
+
```vue
|
|
610
|
+
<IPasswordInput
|
|
611
|
+
v-model="password"
|
|
612
|
+
strength
|
|
613
|
+
show-label="Afficher le mot de passe"
|
|
614
|
+
hide-label="Masquer le mot de passe"
|
|
615
|
+
:strength-labels="['Faible', 'Moyen', 'Bon', 'Fort']"
|
|
616
|
+
/>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
`class` lands on the wrapper that stacks the field above the meter; `ui` reaches
|
|
620
|
+
`root`, `input`, `toggle`, `meter`, `track`, `segment` and `label`.
|
|
621
|
+
|
|
622
|
+
#### Autosizing textareas
|
|
623
|
+
|
|
624
|
+
```vue
|
|
625
|
+
<!-- Grows without limit -->
|
|
626
|
+
<ITextarea v-model="note" autosize />
|
|
627
|
+
|
|
628
|
+
<!-- Between 2 and 8 rows, then scrolls -->
|
|
629
|
+
<ITextarea v-model="note" :autosize="{ min: 2, max: 8 }" />
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
`autosize` overrides `rows` and drops the drag handle, since the measured
|
|
633
|
+
height is the point. The field shrinks as well as grows, and re-measures when
|
|
634
|
+
the model changes from outside — a reset or a prefill resizes correctly.
|
|
635
|
+
|
|
437
636
|
`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
637
|
|
|
439
638
|
`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", "FileUpload", "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;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Why a file was turned away, so the caller can word its own message. */
|
|
2
|
+
export interface FileRejection {
|
|
3
|
+
file: File;
|
|
4
|
+
reason: 'type' | 'size' | 'count';
|
|
5
|
+
}
|
|
6
|
+
export interface FileUploadProps {
|
|
7
|
+
/** Accept more than one file. The model is an array either way. */
|
|
8
|
+
multiple?: boolean;
|
|
9
|
+
/** Same syntax as the native attribute: `image/*`, `.pdf`, `image/png`. */
|
|
10
|
+
accept?: string;
|
|
11
|
+
/** Largest accepted size, in bytes. */
|
|
12
|
+
maxSize?: number;
|
|
13
|
+
/** Cap on how many files may be held at once. */
|
|
14
|
+
maxFiles?: number;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Mark the field as invalid — styles the border and ring red. */
|
|
17
|
+
invalid?: boolean;
|
|
18
|
+
id?: string;
|
|
19
|
+
/** Prompt inside the drop zone. */
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Secondary line under the prompt — good place for the accepted types. */
|
|
22
|
+
hint?: string;
|
|
23
|
+
/** Text on the browse button. */
|
|
24
|
+
browseLabel?: string;
|
|
25
|
+
/** Labels and messages — override for non-English apps. */
|
|
26
|
+
removeLabel?: string;
|
|
27
|
+
tooLargeText?: string;
|
|
28
|
+
wrongTypeText?: string;
|
|
29
|
+
tooManyText?: string;
|
|
30
|
+
/** Skip built-in classes; you take over styling entirely. */
|
|
31
|
+
unstyled?: boolean;
|
|
32
|
+
/** Applied to the outer wrapper, which stacks the zone above the list. */
|
|
33
|
+
class?: string;
|
|
34
|
+
/** Override classes per slot, e.g. `{ dropzone: 'py-10' }`. */
|
|
35
|
+
ui?: Partial<Record<'root' | 'dropzone' | 'input' | 'icon' | 'label' | 'browse' | 'hint' | 'list' | 'item' | 'thumbnail' | 'placeholder' | 'details' | 'name' | 'meta' | 'remove' | 'error', string>>;
|
|
36
|
+
}
|
|
37
|
+
type __VLS_Props = FileUploadProps;
|
|
38
|
+
type __VLS_ModelProps = {
|
|
39
|
+
/**
|
|
40
|
+
* Always an array, even when `multiple` is false — a `File | File[]` union
|
|
41
|
+
* would make every caller narrow the type before touching it, and the single
|
|
42
|
+
* case is just an array that holds at most one.
|
|
43
|
+
*/
|
|
44
|
+
modelValue?: File[];
|
|
45
|
+
};
|
|
46
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
47
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
+
"update:modelValue": (value: File[]) => any;
|
|
49
|
+
reject: (rejections: FileRejection[]) => any;
|
|
50
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
|
+
"onUpdate:modelValue"?: ((value: File[]) => any) | undefined;
|
|
52
|
+
onReject?: ((rejections: FileRejection[]) => any) | undefined;
|
|
53
|
+
}>, {
|
|
54
|
+
unstyled: boolean;
|
|
55
|
+
label: string;
|
|
56
|
+
invalid: boolean;
|
|
57
|
+
browseLabel: string;
|
|
58
|
+
removeLabel: string;
|
|
59
|
+
tooLargeText: string;
|
|
60
|
+
wrongTypeText: string;
|
|
61
|
+
tooManyText: string;
|
|
62
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
63
|
+
declare const _default: typeof __VLS_export;
|
|
64
|
+
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
|
|
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, {
|
|
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,15 +9,19 @@ 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';
|
|
17
|
+
export { default as FileUpload } from './FileUpload.vue';
|
|
15
18
|
export { default as Form } from './Form.vue';
|
|
16
19
|
export { default as FormField } from './FormField.vue';
|
|
17
20
|
export { default as Input } from './Input.vue';
|
|
18
21
|
export { default as Label } from './Label.vue';
|
|
19
22
|
export { default as NumberInput } from './NumberInput.vue';
|
|
20
23
|
export { default as Pagination } from './Pagination.vue';
|
|
24
|
+
export { default as PasswordInput } from './PasswordInput.vue';
|
|
21
25
|
export { default as Progress } from './Progress.vue';
|
|
22
26
|
export { default as RadioGroup } from './RadioGroup.vue';
|
|
23
27
|
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,15 +12,19 @@ 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';
|
|
20
|
+
export type { FileRejection, FileUploadProps } from './components/FileUpload.vue';
|
|
18
21
|
export type { FormProps } from './components/Form.vue';
|
|
19
22
|
export type { FormFieldProps } from './components/FormField.vue';
|
|
20
23
|
export type { InputProps } from './components/Input.vue';
|
|
21
24
|
export type { LabelProps } from './components/Label.vue';
|
|
22
25
|
export type { NumberInputProps } from './components/NumberInput.vue';
|
|
23
26
|
export type { PaginationProps } from './components/Pagination.vue';
|
|
27
|
+
export type { PasswordInputProps } from './components/PasswordInput.vue';
|
|
24
28
|
export type { ProgressProps } from './components/Progress.vue';
|
|
25
29
|
export type { RadioGroupItemOption, RadioGroupProps } from './components/RadioGroup.vue';
|
|
26
30
|
export type { SelectItemGroup, SelectItemOption, SelectItems, SelectProps } from './components/Select.vue';
|
|
@@ -38,6 +42,7 @@ export * from './composables/appearance';
|
|
|
38
42
|
export * from './composables/button-group';
|
|
39
43
|
export * from './composables/confirm';
|
|
40
44
|
export * from './composables/data-table';
|
|
45
|
+
export * from './composables/date';
|
|
41
46
|
export * from './composables/decimal';
|
|
42
47
|
export * from './composables/dropdown-menu';
|
|
43
48
|
export * from './composables/form';
|