azamat-ui-kit-cli 0.2.2 → 0.3.4

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 (103) hide show
  1. package/README.md +11 -0
  2. package/dist/index.cjs +452 -0
  3. package/package.json +2 -2
  4. package/vendor/src/components/actions/action-menu.tsx +21 -18
  5. package/vendor/src/components/calendar/calendar.tsx +153 -102
  6. package/vendor/src/components/calendar/date-picker.tsx +24 -14
  7. package/vendor/src/components/calendar/date-range-picker.tsx +137 -58
  8. package/vendor/src/components/charts/charts.tsx +32 -21
  9. package/vendor/src/components/command/command-palette.tsx +68 -57
  10. package/vendor/src/components/data-table/data-table-bulk-actions.tsx +23 -20
  11. package/vendor/src/components/data-table/data-table-column-visibility-menu.tsx +21 -10
  12. package/vendor/src/components/data-table/data-table-pagination.tsx +6 -6
  13. package/vendor/src/components/data-table/data-table-toolbar.tsx +72 -44
  14. package/vendor/src/components/data-table/data-table.tsx +15 -11
  15. package/vendor/src/components/data-table/table-export-menu.tsx +1 -1
  16. package/vendor/src/components/data-table/table-import-button.tsx +1 -1
  17. package/vendor/src/components/display/data-state.tsx +20 -8
  18. package/vendor/src/components/display/index.ts +19 -15
  19. package/vendor/src/components/display/metric-card.tsx +35 -0
  20. package/vendor/src/components/display/progress-circle.tsx +24 -0
  21. package/vendor/src/components/display/smart-card.tsx +49 -27
  22. package/vendor/src/components/display/status-dot.tsx +45 -0
  23. package/vendor/src/components/display/user-card.tsx +30 -0
  24. package/vendor/src/components/feedback/alert.tsx +21 -11
  25. package/vendor/src/components/feedback/empty-state.tsx +2 -2
  26. package/vendor/src/components/feedback/loading-state.tsx +2 -2
  27. package/vendor/src/components/feedback/page-state.tsx +19 -15
  28. package/vendor/src/components/feedback/status-badge.tsx +43 -43
  29. package/vendor/src/components/form/form-app-input.tsx +147 -0
  30. package/vendor/src/components/form/form-date-input.tsx +16 -19
  31. package/vendor/src/components/form/form-field-shell.tsx +11 -8
  32. package/vendor/src/components/form/form-field-utils.ts +76 -0
  33. package/vendor/src/components/form/form-input.tsx +423 -44
  34. package/vendor/src/components/form/form-number-input.tsx +16 -15
  35. package/vendor/src/components/form/form-phone-input.tsx +15 -9
  36. package/vendor/src/components/form/form-search-input.tsx +16 -19
  37. package/vendor/src/components/form/form-select.tsx +4 -3
  38. package/vendor/src/components/form/public.ts +16 -14
  39. package/vendor/src/components/form/smart-form-shell.tsx +13 -12
  40. package/vendor/src/components/inputs/app-input.tsx +27 -0
  41. package/vendor/src/components/inputs/async-select.tsx +113 -84
  42. package/vendor/src/components/inputs/clearable-input.tsx +81 -61
  43. package/vendor/src/components/inputs/date-input.tsx +21 -17
  44. package/vendor/src/components/inputs/date-range-input.tsx +10 -10
  45. package/vendor/src/components/inputs/index.ts +1 -0
  46. package/vendor/src/components/inputs/input-decorator.tsx +101 -57
  47. package/vendor/src/components/inputs/masked-input.tsx +20 -20
  48. package/vendor/src/components/inputs/money-input.tsx +2 -2
  49. package/vendor/src/components/inputs/number-input.tsx +29 -19
  50. package/vendor/src/components/inputs/password-input.tsx +82 -45
  51. package/vendor/src/components/inputs/phone-input.tsx +24 -2
  52. package/vendor/src/components/inputs/quantity-input.tsx +2 -2
  53. package/vendor/src/components/inputs/search-input.tsx +54 -3
  54. package/vendor/src/components/inputs/simple-select.tsx +110 -22
  55. package/vendor/src/components/layout/app-shell.tsx +2 -2
  56. package/vendor/src/components/layout/index.ts +5 -4
  57. package/vendor/src/components/layout/page-header.tsx +79 -35
  58. package/vendor/src/components/layout/public.ts +12 -10
  59. package/vendor/src/components/layout/section-header.tsx +56 -0
  60. package/vendor/src/components/layout/stack.tsx +106 -0
  61. package/vendor/src/components/layout/stat-card.tsx +66 -29
  62. package/vendor/src/components/navigation/index.ts +1 -0
  63. package/vendor/src/components/navigation/nav-tabs.tsx +60 -0
  64. package/vendor/src/components/navigation/page-tabs.tsx +41 -26
  65. package/vendor/src/components/navigation/pagination.tsx +14 -10
  66. package/vendor/src/components/overlay/alert-dialog.tsx +65 -0
  67. package/vendor/src/components/overlay/drawer.tsx +71 -0
  68. package/vendor/src/components/overlay/index.ts +4 -2
  69. package/vendor/src/components/patterns/data-view.tsx +13 -8
  70. package/vendor/src/components/ui/badge.tsx +96 -52
  71. package/vendor/src/components/ui/button.tsx +99 -61
  72. package/vendor/src/components/ui/card.tsx +84 -25
  73. package/vendor/src/components/ui/checkbox.tsx +68 -68
  74. package/vendor/src/components/ui/command.tsx +32 -32
  75. package/vendor/src/components/ui/dialog.tsx +135 -138
  76. package/vendor/src/components/ui/dropdown-menu.tsx +21 -21
  77. package/vendor/src/components/ui/hover-card.tsx +49 -0
  78. package/vendor/src/components/ui/input-primitive.tsx +24 -0
  79. package/vendor/src/components/ui/input.tsx +191 -20
  80. package/vendor/src/components/ui/kbd.tsx +33 -0
  81. package/vendor/src/components/ui/popover.tsx +11 -11
  82. package/vendor/src/components/ui/radio-group.tsx +102 -0
  83. package/vendor/src/components/ui/right-click-menu.tsx +60 -0
  84. package/vendor/src/components/ui/scroll-box.tsx +27 -0
  85. package/vendor/src/components/ui/segmented-control.tsx +21 -17
  86. package/vendor/src/components/ui/select.tsx +187 -189
  87. package/vendor/src/components/ui/skeleton.tsx +2 -2
  88. package/vendor/src/components/ui/switch.tsx +60 -60
  89. package/vendor/src/components/ui/table.tsx +114 -114
  90. package/vendor/src/components/ui/tabs.tsx +2 -2
  91. package/vendor/src/components/ui/textarea.tsx +1 -1
  92. package/vendor/src/components/upload/file-dropzone.tsx +38 -0
  93. package/vendor/src/components/upload/file-upload.tsx +4 -4
  94. package/vendor/src/components/upload/image-upload.tsx +22 -19
  95. package/vendor/src/components/upload/index.ts +2 -0
  96. package/vendor/src/families/catalog.ts +1 -0
  97. package/vendor/src/families/docs-groups.ts +10 -1
  98. package/vendor/src/families/member-metadata.ts +24 -0
  99. package/vendor/src/families/member-snippets.ts +41 -2
  100. package/vendor/src/families/migration-map.ts +3 -0
  101. package/vendor/src/index.ts +23 -18
  102. package/vendor/templates/styles/globals.css +253 -0
  103. package/dist/index.js +0 -432
@@ -1,114 +1,114 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- function Table({ className, ...props }: React.ComponentProps<"table">) {
6
- return (
7
- <div
8
- data-slot="table-container"
9
- className="relative w-full overflow-x-auto"
10
- >
11
- <table
12
- data-slot="table"
13
- className={cn("w-full caption-bottom text-sm", className)}
14
- {...props}
15
- />
16
- </div>
17
- )
18
- }
19
-
20
- function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
21
- return (
22
- <thead
23
- data-slot="table-header"
24
- className={cn("[&_tr]:border-b", className)}
25
- {...props}
26
- />
27
- )
28
- }
29
-
30
- function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
31
- return (
32
- <tbody
33
- data-slot="table-body"
34
- className={cn("[&_tr:last-child]:border-0", className)}
35
- {...props}
36
- />
37
- )
38
- }
39
-
40
- function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
41
- return (
42
- <tfoot
43
- data-slot="table-footer"
44
- className={cn(
45
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
46
- className
47
- )}
48
- {...props}
49
- />
50
- )
51
- }
52
-
53
- function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
54
- return (
55
- <tr
56
- data-slot="table-row"
57
- className={cn(
58
- "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
59
- className
60
- )}
61
- {...props}
62
- />
63
- )
64
- }
65
-
66
- function TableHead({ className, ...props }: React.ComponentProps<"th">) {
67
- return (
68
- <th
69
- data-slot="table-head"
70
- className={cn(
71
- "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
72
- className
73
- )}
74
- {...props}
75
- />
76
- )
77
- }
78
-
79
- function TableCell({ className, ...props }: React.ComponentProps<"td">) {
80
- return (
81
- <td
82
- data-slot="table-cell"
83
- className={cn(
84
- "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
85
- className
86
- )}
87
- {...props}
88
- />
89
- )
90
- }
91
-
92
- function TableCaption({
93
- className,
94
- ...props
95
- }: React.ComponentProps<"caption">) {
96
- return (
97
- <caption
98
- data-slot="table-caption"
99
- className={cn("mt-4 text-sm text-muted-foreground", className)}
100
- {...props}
101
- />
102
- )
103
- }
104
-
105
- export {
106
- Table,
107
- TableHeader,
108
- TableBody,
109
- TableFooter,
110
- TableHead,
111
- TableRow,
112
- TableCell,
113
- TableCaption,
114
- }
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Table({ className, ...props }: React.ComponentProps<"table">) {
6
+ return (
7
+ <div
8
+ data-slot="table-container"
9
+ className="relative w-full overflow-x-auto rounded-[var(--radius-2xl)] border border-border/75 bg-[linear-gradient(180deg,color-mix(in_oklch,var(--card),white_12%),var(--card))] shadow-sm ring-1 ring-foreground/5"
10
+ >
11
+ <table
12
+ data-slot="table"
13
+ className={cn("w-full caption-bottom text-sm", className)}
14
+ {...props}
15
+ />
16
+ </div>
17
+ )
18
+ }
19
+
20
+ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
21
+ return (
22
+ <thead
23
+ data-slot="table-header"
24
+ className={cn("bg-muted/42 [&_tr]:border-b", className)}
25
+ {...props}
26
+ />
27
+ )
28
+ }
29
+
30
+ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
31
+ return (
32
+ <tbody
33
+ data-slot="table-body"
34
+ className={cn("[&_tr:last-child]:border-0", className)}
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
41
+ return (
42
+ <tfoot
43
+ data-slot="table-footer"
44
+ className={cn(
45
+ "border-t bg-muted/58 font-medium [&>tr]:last:border-b-0",
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
54
+ return (
55
+ <tr
56
+ data-slot="table-row"
57
+ className={cn(
58
+ "border-b transition-colors hover:bg-muted/36 has-aria-expanded:bg-muted/36 data-[state=selected]:bg-primary/8",
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
67
+ return (
68
+ <th
69
+ data-slot="table-head"
70
+ className={cn(
71
+ "h-11 px-3 text-left align-middle text-[0.78rem] font-semibold whitespace-nowrap uppercase tracking-[0.14em] text-muted-foreground [&:has([role=checkbox])]:pr-0",
72
+ className
73
+ )}
74
+ {...props}
75
+ />
76
+ )
77
+ }
78
+
79
+ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
80
+ return (
81
+ <td
82
+ data-slot="table-cell"
83
+ className={cn(
84
+ "px-3 py-3 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
85
+ className
86
+ )}
87
+ {...props}
88
+ />
89
+ )
90
+ }
91
+
92
+ function TableCaption({
93
+ className,
94
+ ...props
95
+ }: React.ComponentProps<"caption">) {
96
+ return (
97
+ <caption
98
+ data-slot="table-caption"
99
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ export {
106
+ Table,
107
+ TableHeader,
108
+ TableBody,
109
+ TableFooter,
110
+ TableHead,
111
+ TableRow,
112
+ TableCell,
113
+ TableCaption,
114
+ }
@@ -13,7 +13,7 @@ const TabsList = React.forwardRef<
13
13
  ref={ref}
14
14
  data-slot="tabs-list"
15
15
  className={cn(
16
- "inline-flex min-h-11 items-center justify-center rounded-[var(--radius-2xl)] border border-border/80 bg-muted/80 p-1 text-muted-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.05)] backdrop-blur",
16
+ "inline-flex min-h-11 items-center justify-center gap-1 rounded-[var(--radius-2xl)] border border-border/85 bg-muted/88 p-1 text-muted-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.08),0_10px_30px_rgba(15,23,42,0.06)] backdrop-blur",
17
17
  className
18
18
  )}
19
19
  {...props}
@@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef<
29
29
  ref={ref}
30
30
  data-slot="tabs-trigger"
31
31
  className={cn(
32
- "inline-flex min-h-9 items-center justify-center whitespace-nowrap rounded-[calc(var(--radius-xl)-2px)] border border-transparent px-3.5 py-1.5 text-sm font-medium text-muted-foreground ring-offset-background transition-[background-color,color,box-shadow,border-color,transform] hover:bg-background/55 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[selected]:border-border/80 data-[selected]:bg-background data-[selected]:text-foreground data-[selected]:shadow-[0_1px_0_rgba(255,255,255,0.22),0_10px_24px_rgba(15,23,42,0.12)] dark:data-[selected]:border-white/12 dark:data-[selected]:bg-white/8 dark:data-[selected]:shadow-[0_1px_0_rgba(255,255,255,0.06),0_14px_32px_rgba(0,0,0,0.24)]",
32
+ "inline-flex min-h-9 items-center justify-center whitespace-nowrap rounded-[calc(var(--radius-xl)-2px)] border border-transparent px-3.5 py-1.5 text-sm font-medium text-muted-foreground ring-offset-background transition-[background-color,color,box-shadow,border-color,transform] hover:bg-background/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[selected]:-translate-y-px data-[selected]:border-border/90 data-[selected]:bg-background data-[selected]:text-foreground data-[selected]:shadow-[0_1px_0_rgba(255,255,255,0.32),0_14px_28px_rgba(15,23,42,0.14)] dark:data-[selected]:border-white/12 dark:data-[selected]:bg-white/10 dark:data-[selected]:shadow-[0_1px_0_rgba(255,255,255,0.08),0_14px_32px_rgba(0,0,0,0.24)]",
33
33
  className
34
34
  )}
35
35
  {...props}
@@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
7
7
  <textarea
8
8
  data-slot="textarea"
9
9
  className={cn(
10
- "flex field-sizing-content min-h-24 w-full rounded-[var(--radius-2xl)] border border-input/85 bg-background/92 px-3.5 py-3 text-base shadow-sm transition-[background-color,border-color,box-shadow,color] outline-none placeholder:text-muted-foreground/95 hover:border-border focus-visible:border-ring focus-visible:bg-background focus-visible:ring-3 focus-visible:ring-ring/45 disabled:cursor-not-allowed disabled:bg-input/55 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:hover:bg-input/45 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
10
+ "flex field-sizing-content min-h-28 w-full rounded-[var(--radius-2xl)] border border-input/90 bg-[linear-gradient(180deg,color-mix(in_oklch,var(--background),white_12%),var(--background))] px-4 py-3.5 text-base text-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.18),0_1px_0_rgba(255,255,255,0.06)] transition-[background-color,border-color,box-shadow,color] outline-none placeholder:text-muted-foreground/92 hover:border-ring/30 hover:bg-background focus-visible:border-ring focus-visible:bg-background focus-visible:shadow-[0_0_0_1px_color-mix(in_oklch,var(--ring),transparent_45%),0_10px_24px_rgba(15,23,42,0.08)] focus-visible:ring-3 focus-visible:ring-ring/45 disabled:cursor-not-allowed disabled:bg-input/55 disabled:text-muted-foreground disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:border-white/12 dark:bg-[linear-gradient(180deg,rgba(255,255,255,0.08),rgba(255,255,255,0.05))] dark:hover:bg-white/8 dark:focus-visible:bg-white/8 dark:disabled:bg-white/8 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
11
  className
12
12
  )}
13
13
  {...props}
@@ -0,0 +1,38 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ export type FileDropzoneProps = Omit<React.ComponentProps<"input">, "type" | "onChange"> & {
6
+ label?: React.ReactNode
7
+ description?: React.ReactNode
8
+ value?: File[]
9
+ onFilesChange?: (files: File[]) => void
10
+ containerClassName?: string
11
+ }
12
+
13
+ function FileDropzone({ label = "Drop files here", description, value, onFilesChange, containerClassName, className, multiple = true, ...props }: FileDropzoneProps) {
14
+ const inputId = React.useId()
15
+ const files = value ?? []
16
+
17
+ return (
18
+ <label
19
+ htmlFor={inputId}
20
+ data-slot="file-dropzone"
21
+ className={cn("flex cursor-pointer flex-col items-center justify-center rounded-[var(--radius-2xl)] border border-dashed border-border/80 bg-muted/35 p-6 text-center transition hover:border-ring/45 hover:bg-muted/55", containerClassName)}
22
+ >
23
+ <span className="font-medium text-foreground">{label}</span>
24
+ {description ? <span className="mt-1 text-sm text-muted-foreground">{description}</span> : null}
25
+ {files.length ? <span className="mt-3 text-xs text-muted-foreground">{files.length} file selected</span> : null}
26
+ <input
27
+ id={inputId}
28
+ type="file"
29
+ multiple={multiple}
30
+ className={cn("sr-only", className)}
31
+ onChange={(event) => onFilesChange?.(Array.from(event.currentTarget.files ?? []))}
32
+ {...props}
33
+ />
34
+ </label>
35
+ )
36
+ }
37
+
38
+ export { FileDropzone }
@@ -385,7 +385,7 @@ function FileUpload({
385
385
  aria-label={dropzoneAriaLabel}
386
386
  tabIndex={isDisabled ? -1 : 0}
387
387
  className={cn(
388
- "grid cursor-pointer gap-4 rounded-[var(--radius-2xl)] border border-dashed border-border/75 bg-card/96 p-5 text-center shadow-sm outline-none transition-[background-color,border-color,box-shadow,transform] hover:border-primary/35 hover:bg-muted/25 focus-visible:ring-2 focus-visible:ring-ring data-[dragging=true]:border-primary data-[dragging=true]:bg-primary/6 data-[dragging=true]:shadow-[0_18px_50px_color-mix(in_oklch,var(--primary),transparent_84%)] data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-60",
388
+ "grid cursor-pointer gap-4 rounded-[var(--radius-2xl)] border border-dashed border-border/80 bg-[linear-gradient(180deg,color-mix(in_oklch,var(--card),white_12%),var(--card))] p-6 text-center shadow-sm ring-1 ring-foreground/5 outline-none transition-[background-color,border-color,box-shadow,transform] hover:-translate-y-px hover:border-primary/35 hover:bg-muted/25 hover:shadow-[0_14px_36px_rgba(15,23,42,0.08)] focus-visible:ring-2 focus-visible:ring-ring data-[dragging=true]:border-primary data-[dragging=true]:bg-primary/6 data-[dragging=true]:shadow-[0_18px_50px_color-mix(in_oklch,var(--primary),transparent_84%)] data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-60",
389
389
  dropzoneClassName
390
390
  )}
391
391
  onClick={openFileDialog}
@@ -401,7 +401,7 @@ function FileUpload({
401
401
  onDragOver={handleDragOver}
402
402
  onDrop={handleDrop}
403
403
  >
404
- <div className="mx-auto flex size-12 items-center justify-center rounded-full border border-border/70 bg-background/92 text-muted-foreground shadow-sm">
404
+ <div className="mx-auto flex size-13 items-center justify-center rounded-full border border-border/75 bg-[linear-gradient(180deg,color-mix(in_oklch,var(--background),white_14%),var(--background))] text-muted-foreground shadow-[0_1px_0_rgba(255,255,255,0.12),0_10px_24px_rgba(15,23,42,0.06)]">
405
405
  <UploadCloudIcon className="size-5" />
406
406
  </div>
407
407
  <div className="grid gap-1">
@@ -455,7 +455,7 @@ function FileUpload({
455
455
  <div
456
456
  key={`${file.name}-${file.lastModified}-${index}`}
457
457
  data-slot="file-upload-item"
458
- className={cn("rounded-[min(var(--radius-xl),18px)] border border-border/75 bg-card/96 p-3 shadow-sm", fileItemClassName)}
458
+ className={cn("rounded-[min(var(--radius-xl),18px)] border border-border/80 bg-[linear-gradient(180deg,color-mix(in_oklch,var(--card),white_10%),var(--card))] p-3.5 shadow-sm ring-1 ring-foreground/5", fileItemClassName)}
459
459
  >
460
460
  {renderFile?.(state) ?? defaultRenderFile(state)}
461
461
  </div>
@@ -469,7 +469,7 @@ function FileUpload({
469
469
  {resolvedRejectedFiles.map((rejectedFile, index) => (
470
470
  <div
471
471
  key={`${rejectedFile.file.name}-${index}`}
472
- className="rounded-[min(var(--radius-lg),12px)] border border-destructive/20 bg-destructive/8 px-3 py-2 text-xs leading-5 text-destructive"
472
+ className="rounded-[min(var(--radius-lg),12px)] border border-destructive/22 bg-destructive/8 px-3 py-2.5 text-xs leading-5 text-destructive shadow-[inset_0_1px_0_rgba(255,255,255,0.08)]"
473
473
  >
474
474
  {renderRejectedFile?.({ rejectedFile, index }) ?? <span>{rejectedFile.file.name}: {rejectedFile.message}</span>}
475
475
  </div>
@@ -56,31 +56,34 @@ function defaultRenderImageFile({
56
56
  }) {
57
57
  return (
58
58
  <div className="flex min-w-0 items-center gap-3">
59
- <div
60
- className={cn(
61
- "flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-md border bg-muted text-muted-foreground",
62
- previewClassName
63
- )}
64
- >
59
+ <div
60
+ className={cn(
61
+ "flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-[min(var(--radius-xl),16px)] border border-border/75 bg-muted/45 text-muted-foreground shadow-[0_1px_0_rgba(255,255,255,0.05)]",
62
+ previewClassName
63
+ )}
64
+ >
65
65
  {previewUrl ? (
66
66
  <img src={previewUrl} alt={file.name} className={cn("size-full object-cover", imageClassName)} />
67
67
  ) : (
68
68
  <ImageIcon className="size-5" />
69
69
  )}
70
70
  </div>
71
- <div className="min-w-0 flex-1">
72
- <div className="truncate text-sm font-medium text-foreground">{file.name}</div>
73
- <div className="text-xs text-muted-foreground">{formatBytes(file.size)}</div>
74
- {typeof progress === "number" && (
75
- <div className="mt-1 h-1.5 overflow-hidden rounded-full bg-muted">
76
- <div className="h-full rounded-full bg-primary" style={{ width: `${Math.min(Math.max(progress, 0), 100)}%` }} />
77
- </div>
78
- )}
79
- </div>
80
- <Button type="button" variant="ghost" size="icon-xs" onClick={remove}>
81
- <XIcon />
82
- <span className="sr-only">Remove image</span>
83
- </Button>
71
+ <div className="min-w-0 flex-1">
72
+ <div className="truncate text-sm font-medium text-foreground">{file.name}</div>
73
+ <div className="text-xs text-muted-foreground">{formatBytes(file.size)}</div>
74
+ {typeof progress === "number" && (
75
+ <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-muted/80">
76
+ <div
77
+ className="h-full rounded-full bg-primary shadow-[0_8px_18px_color-mix(in_oklch,var(--primary),transparent_82%)]"
78
+ style={{ width: `${Math.min(Math.max(progress, 0), 100)}%` }}
79
+ />
80
+ </div>
81
+ )}
82
+ </div>
83
+ <Button type="button" variant="ghost" size="icon-xs" className="rounded-full" onClick={remove}>
84
+ <XIcon />
85
+ <span className="sr-only">Remove image</span>
86
+ </Button>
84
87
  </div>
85
88
  )
86
89
  }
@@ -1,2 +1,4 @@
1
1
  export { FileUpload } from "./file-upload"
2
2
  export { ImageUpload } from "./image-upload"
3
+ export { FileDropzone } from "./file-dropzone"
4
+ export type { FileDropzoneProps } from "./file-dropzone"
@@ -36,6 +36,7 @@ export const componentFamilyCatalog: ComponentFamilyCatalogEntry[] = [
36
36
  "ColorInput",
37
37
  ],
38
38
  advanced: ["TagInput", "QuantityStepper"],
39
+ transitional: ["AppInput", "UniversalInput", "FormAppInput"],
39
40
  },
40
41
  {
41
42
  family: "SelectFamily",
@@ -68,7 +68,16 @@ export const componentDocsGroups: ComponentDocsGroupEntry[] = [
68
68
  id: "transitional",
69
69
  label: "Compatibility aliases",
70
70
  description: "Older wrapper names that still work, but new docs and new product work should prefer FormInput with a matching kind.",
71
- components: ["FormSearchInput", "FormPasswordInput", "FormNumberInput", "FormPhoneInput", "FormDateInput"],
71
+ components: [
72
+ "AppInput",
73
+ "UniversalInput",
74
+ "FormAppInput",
75
+ "FormSearchInput",
76
+ "FormPasswordInput",
77
+ "FormNumberInput",
78
+ "FormPhoneInput",
79
+ "FormDateInput",
80
+ ],
72
81
  },
73
82
  {
74
83
  id: "advanced",
@@ -131,6 +131,30 @@ export const componentMemberMetadata: ComponentMemberMetadata[] = [
131
131
  summary: "Universal React Hook Form wrapper for text-like inputs.",
132
132
  useWhen: "Use as the primary RHF entry for text, search, password, number, phone, and date flows by switching the kind prop instead of learning many wrapper names.",
133
133
  },
134
+ {
135
+ component: "AppInput",
136
+ family: "InputFamily",
137
+ section: "transitional",
138
+ maturity: "transitional",
139
+ summary: "Compatibility alias for Input with kind variants.",
140
+ useWhen: "Use only for legacy calls; prefer Input with `kind` in new work.",
141
+ },
142
+ {
143
+ component: "UniversalInput",
144
+ family: "InputFamily",
145
+ section: "transitional",
146
+ maturity: "transitional",
147
+ summary: "Legacy alias for AppInput.",
148
+ useWhen: "Use only for migration; prefer Input with `kind`.",
149
+ },
150
+ {
151
+ component: "FormAppInput",
152
+ family: "InputFamily",
153
+ section: "transitional",
154
+ maturity: "transitional",
155
+ summary: "Legacy RHF wrapper alias for FormInput.",
156
+ useWhen: "Use only for migration; prefer FormInput with matching kind.",
157
+ },
134
158
  {
135
159
  component: "FormSearchInput",
136
160
  family: "InputFamily",
@@ -200,7 +200,33 @@ export const componentSnippetExamples: ComponentSnippetExample[] = [
200
200
  variant: "form",
201
201
  code: `import { FormInput } from "azamat-ui-kit"
202
202
 
203
- <FormInput control={control} name="quantity" kind="number" label="Quantity" min={0} />`,
203
+ <FormInput control={control} name="quantity" kind="number" label="Quantity" min={0} />`,
204
+ },
205
+ {
206
+ component: "AppInput",
207
+ title: "Deprecated alias migration",
208
+ description: "Use this alias only for legacy callers; migrate to Input with kind.",
209
+ language: "tsx",
210
+ variant: "migration",
211
+ code: `import { AppInput } from "azamat-ui-kit"
212
+
213
+ <AppInput placeholder="Email" value={value} onValueChange={setValue} />
214
+
215
+ // New work:
216
+ // <Input placeholder="Email" value={value} onValueChange={setValue} />`,
217
+ },
218
+ {
219
+ component: "UniversalInput",
220
+ title: "Universal alias migration",
221
+ description: "UniversalInput exists for backward compatibility while consolidating variants.",
222
+ language: "tsx",
223
+ variant: "migration",
224
+ code: `import { UniversalInput } from "azamat-ui-kit"
225
+
226
+ <UniversalInput placeholder="Email" kind="search" value={value} onValueChange={setValue} />
227
+
228
+ // New work:
229
+ // <Input kind="search" placeholder="Search" value={value} onValueChange={setValue} />`,
204
230
  },
205
231
  {
206
232
  component: "FormSearchInput",
@@ -266,6 +292,19 @@ export const componentSnippetExamples: ComponentSnippetExample[] = [
266
292
 
267
293
  // New work:
268
294
  // <FormInput control={control} name="startDate" kind="date" label="Start date" />`,
295
+ },
296
+ {
297
+ component: "FormAppInput",
298
+ title: "Form alias migration",
299
+ description: "Use this only for legacy form code; prefer FormInput with kind.",
300
+ language: "tsx",
301
+ variant: "migration",
302
+ code: `import { FormAppInput } from "azamat-ui-kit"
303
+
304
+ <FormAppInput control={control} name="quantity" kind="number" label="Quantity" min={0} />
305
+
306
+ // New work:
307
+ // <FormInput control={control} name="quantity" kind="number" label="Quantity" min={0} />`,
269
308
  },
270
309
  {
271
310
  component: "FormDateRangeInput",
@@ -411,7 +450,7 @@ export const componentSnippetExamples: ComponentSnippetExample[] = [
411
450
  variant: "basic",
412
451
  code: `import { InfoCard } from "azamat-ui-kit"
413
452
 
414
- <InfoCard title="Revenue" description="Current month" value="$48,000" />`,
453
+ <InfoCard title="Revenue" description="Current month" content="$48,000" />`,
415
454
  },
416
455
  {
417
456
  component: "StatCard",
@@ -16,6 +16,9 @@ export type FamilyMigrationEntry = {
16
16
 
17
17
  export const componentFamilyMigrationMap: FamilyMigrationEntry[] = [
18
18
  { component: "Input", family: "InputFamily", member: "Root", status: "canonical" },
19
+ { component: "AppInput", family: "InputFamily", member: "AppInput", status: "transitional" },
20
+ { component: "UniversalInput", family: "InputFamily", member: "UniversalInput", status: "transitional" },
21
+ { component: "FormAppInput", family: "InputFamily", member: "FormAppInput", status: "transitional" },
19
22
  { component: "ClearableInput", family: "InputFamily", member: "Clearable", status: "family-member" },
20
23
  { component: "SearchInput", family: "InputFamily", member: "Search", status: "family-member" },
21
24
  { component: "PasswordInput", family: "InputFamily", member: "Password", status: "family-member" },
@@ -17,22 +17,27 @@ export * from './components/ui/divider'
17
17
  export * from './components/ui/segmented-control'
18
18
  export * from './components/ui/spinner'
19
19
  export * from './components/ui/tooltip'
20
+ export * from './components/ui/radio-group'
21
+ export * from './components/ui/kbd'
22
+ export * from './components/ui/hover-card'
23
+ export * from './components/ui/scroll-box'
24
+ export * from './components/ui/right-click-menu'
20
25
 
21
- export * from './components/actions/public'
22
- export * from './components/layout/public'
23
- export * from './components/filters'
24
- export * from './components/overlay'
25
- export * from './components/navigation'
26
- export * from './components/inputs'
27
- export * from './components/form/public'
28
- export * from './components/feedback'
29
- export * from './components/display'
30
- export * from './components/data-table/public'
31
- export * from './components/notifications'
32
- export * from './components/command'
33
- export * from './components/calendar'
34
- export * from './components/upload'
35
- export * from './components/wizard'
36
- export * from './components/charts/public'
37
- export * from './hooks'
38
- export * from './lib/utils'
26
+ export * from './components/actions/public'
27
+ export * from './components/layout/public'
28
+ export * from './components/filters'
29
+ export * from './components/overlay'
30
+ export * from './components/navigation'
31
+ export * from './components/inputs'
32
+ export * from './components/form/public'
33
+ export * from './components/feedback'
34
+ export * from './components/display'
35
+ export * from './components/data-table/public'
36
+ export * from './components/notifications'
37
+ export * from './components/command'
38
+ export * from './components/calendar'
39
+ export * from './components/upload'
40
+ export * from './components/wizard'
41
+ export * from './components/charts/public'
42
+ export * from './hooks'
43
+ export * from './lib/utils'