@lerianstudio/sindarian-ui 2.0.0-beta.2 → 2.0.0-beta.21

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 (227) hide show
  1. package/LICENSE +93 -0
  2. package/README.md +52 -1
  3. package/dist/components/breadcrumb/index.d.ts.map +1 -1
  4. package/dist/components/breadcrumb/index.js +25 -1
  5. package/dist/components/card/account-card/index.js +5 -5
  6. package/dist/components/card/basic-card/index.d.ts.map +1 -1
  7. package/dist/components/card/basic-card/index.js +2 -2
  8. package/dist/components/card/entity-card/index.js +1 -1
  9. package/dist/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  10. package/dist/components/dialog/confirmation-dialog/index.js +4 -1
  11. package/dist/components/entity-box/index.d.ts +18 -2
  12. package/dist/components/entity-box/index.d.ts.map +1 -1
  13. package/dist/components/entity-box/index.js +32 -4
  14. package/dist/components/form/date-picker-field/index.js +1 -1
  15. package/dist/components/form/date-range-field/index.js +1 -1
  16. package/dist/components/form/date-time-picker-field/index.js +1 -1
  17. package/dist/components/form/password-field/index.d.ts +5 -1
  18. package/dist/components/form/password-field/index.d.ts.map +1 -1
  19. package/dist/components/form/password-field/index.js +2 -2
  20. package/dist/components/form/select-field/index.d.ts +15 -1
  21. package/dist/components/form/select-field/index.d.ts.map +1 -1
  22. package/dist/components/form/select-field/index.js +28 -3
  23. package/dist/components/form/switch-field/index.d.ts.map +1 -1
  24. package/dist/components/form/switch-field/index.js +6 -1
  25. package/dist/components/page/index.d.ts +35 -1
  26. package/dist/components/page/index.d.ts.map +1 -1
  27. package/dist/components/page/index.js +6 -2
  28. package/dist/components/page-header/index.js +1 -1
  29. package/dist/components/table/id-table-cell.d.ts +13 -1
  30. package/dist/components/table/id-table-cell.d.ts.map +1 -1
  31. package/dist/components/table/id-table-cell.js +99 -9
  32. package/dist/components/table/index.d.ts +1 -0
  33. package/dist/components/table/index.d.ts.map +1 -1
  34. package/dist/components/table/index.js +1 -0
  35. package/dist/components/table/locked-table-actions.d.ts +24 -0
  36. package/dist/components/table/locked-table-actions.d.ts.map +1 -1
  37. package/dist/components/table/locked-table-actions.js +31 -1
  38. package/dist/components/table/name-table-cell.d.ts +57 -4
  39. package/dist/components/table/name-table-cell.d.ts.map +1 -1
  40. package/dist/components/table/name-table-cell.js +50 -2
  41. package/dist/components/ui/autocomplete/index.d.ts +24 -0
  42. package/dist/components/ui/autocomplete/index.d.ts.map +1 -1
  43. package/dist/components/ui/autocomplete/index.js +24 -0
  44. package/dist/components/ui/badge/index.d.ts +11 -7
  45. package/dist/components/ui/badge/index.d.ts.map +1 -1
  46. package/dist/components/ui/badge/index.js +20 -8
  47. package/dist/components/ui/button/index.d.ts +3 -3
  48. package/dist/components/ui/copy-field/index.d.ts +25 -1
  49. package/dist/components/ui/copy-field/index.d.ts.map +1 -1
  50. package/dist/components/ui/copy-field/index.js +16 -8
  51. package/dist/components/ui/dialog/index.d.ts +1 -1
  52. package/dist/components/ui/dialog/index.d.ts.map +1 -1
  53. package/dist/components/ui/dialog/index.js +2 -2
  54. package/dist/components/ui/file-upload/index.d.ts +159 -0
  55. package/dist/components/ui/file-upload/index.d.ts.map +1 -1
  56. package/dist/components/ui/file-upload/index.js +308 -6
  57. package/dist/components/ui/icon-button/index.d.ts +1 -1
  58. package/dist/components/ui/icon-button/styles.css +42 -0
  59. package/dist/components/ui/input/styles.css +79 -4
  60. package/dist/components/ui/lerian-wordmark/index.d.ts +6 -0
  61. package/dist/components/ui/lerian-wordmark/index.d.ts.map +1 -0
  62. package/dist/components/ui/lerian-wordmark/index.js +7 -0
  63. package/dist/components/ui/otp-input/index.js +1 -1
  64. package/dist/components/ui/radio-group/index.js +1 -1
  65. package/dist/components/ui/select/index.d.ts.map +1 -1
  66. package/dist/components/ui/select/index.js +8 -4
  67. package/dist/components/ui/select/styles.css +1 -1
  68. package/dist/components/ui/sheet/index.d.ts +42 -0
  69. package/dist/components/ui/sheet/index.d.ts.map +1 -1
  70. package/dist/components/ui/sheet/index.js +47 -14
  71. package/dist/components/ui/sidebar/index.d.ts +1 -0
  72. package/dist/components/ui/sidebar/index.d.ts.map +1 -1
  73. package/dist/components/ui/sidebar/index.js +1 -0
  74. package/dist/components/ui/sidebar/sidebar-expand-button.d.ts +1 -1
  75. package/dist/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
  76. package/dist/components/ui/sidebar/sidebar-expand-button.js +15 -1
  77. package/dist/components/ui/sidebar/sidebar-item.d.ts +1 -1
  78. package/dist/components/ui/sidebar/sidebar-item.d.ts.map +1 -1
  79. package/dist/components/ui/sidebar/sidebar-item.js +28 -4
  80. package/dist/components/ui/sidebar/sidebar-provider.d.ts +58 -0
  81. package/dist/components/ui/sidebar/sidebar-provider.d.ts.map +1 -1
  82. package/dist/components/ui/sidebar/sidebar-provider.js +146 -4
  83. package/dist/components/ui/sidebar/sidebar-root.d.ts +38 -1
  84. package/dist/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
  85. package/dist/components/ui/sidebar/sidebar-root.js +111 -5
  86. package/dist/components/ui/sidebar/sidebar-trigger.d.ts +45 -0
  87. package/dist/components/ui/sidebar/sidebar-trigger.d.ts.map +1 -0
  88. package/dist/components/ui/sidebar/sidebar-trigger.js +57 -0
  89. package/dist/components/ui/textarea/index.js +1 -1
  90. package/dist/components/ui/toast/toaster.d.ts +5 -1
  91. package/dist/components/ui/toast/toaster.d.ts.map +1 -1
  92. package/dist/components/ui/toast/toaster.js +3 -2
  93. package/dist/enterprise/data-table/index.d.ts +77 -7
  94. package/dist/enterprise/data-table/index.d.ts.map +1 -1
  95. package/dist/enterprise/data-table/index.js +56 -11
  96. package/dist/enterprise/date-range-picker/index.js +4 -4
  97. package/dist/enterprise/number-input/index.d.ts.map +1 -1
  98. package/dist/enterprise/number-input/index.js +1 -1
  99. package/dist/esm/components/breadcrumb/index.d.ts.map +1 -1
  100. package/dist/esm/components/breadcrumb/index.js +25 -1
  101. package/dist/esm/components/card/account-card/index.js +5 -5
  102. package/dist/esm/components/card/basic-card/index.d.ts.map +1 -1
  103. package/dist/esm/components/card/basic-card/index.js +2 -2
  104. package/dist/esm/components/card/entity-card/index.js +1 -1
  105. package/dist/esm/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  106. package/dist/esm/components/dialog/confirmation-dialog/index.js +4 -1
  107. package/dist/esm/components/entity-box/index.d.ts +18 -2
  108. package/dist/esm/components/entity-box/index.d.ts.map +1 -1
  109. package/dist/esm/components/entity-box/index.js +29 -4
  110. package/dist/esm/components/form/date-picker-field/index.js +1 -1
  111. package/dist/esm/components/form/date-range-field/index.js +1 -1
  112. package/dist/esm/components/form/date-time-picker-field/index.js +1 -1
  113. package/dist/esm/components/form/password-field/index.d.ts +5 -1
  114. package/dist/esm/components/form/password-field/index.d.ts.map +1 -1
  115. package/dist/esm/components/form/password-field/index.js +2 -2
  116. package/dist/esm/components/form/select-field/index.d.ts +15 -1
  117. package/dist/esm/components/form/select-field/index.d.ts.map +1 -1
  118. package/dist/esm/components/form/select-field/index.js +29 -4
  119. package/dist/esm/components/form/switch-field/index.d.ts.map +1 -1
  120. package/dist/esm/components/form/switch-field/index.js +7 -2
  121. package/dist/esm/components/page/index.d.ts +35 -1
  122. package/dist/esm/components/page/index.d.ts.map +1 -1
  123. package/dist/esm/components/page/index.js +6 -2
  124. package/dist/esm/components/page-header/index.js +1 -1
  125. package/dist/esm/components/table/id-table-cell.d.ts +13 -1
  126. package/dist/esm/components/table/id-table-cell.d.ts.map +1 -1
  127. package/dist/esm/components/table/id-table-cell.js +100 -7
  128. package/dist/esm/components/table/index.d.ts +1 -0
  129. package/dist/esm/components/table/index.d.ts.map +1 -1
  130. package/dist/esm/components/table/index.js +1 -0
  131. package/dist/esm/components/table/locked-table-actions.d.ts +24 -0
  132. package/dist/esm/components/table/locked-table-actions.d.ts.map +1 -1
  133. package/dist/esm/components/table/locked-table-actions.js +31 -1
  134. package/dist/esm/components/table/name-table-cell.d.ts +57 -4
  135. package/dist/esm/components/table/name-table-cell.d.ts.map +1 -1
  136. package/dist/esm/components/table/name-table-cell.js +50 -2
  137. package/dist/esm/components/ui/autocomplete/index.d.ts +24 -0
  138. package/dist/esm/components/ui/autocomplete/index.d.ts.map +1 -1
  139. package/dist/esm/components/ui/autocomplete/index.js +24 -0
  140. package/dist/esm/components/ui/badge/index.d.ts +11 -7
  141. package/dist/esm/components/ui/badge/index.d.ts.map +1 -1
  142. package/dist/esm/components/ui/badge/index.js +20 -8
  143. package/dist/esm/components/ui/button/index.d.ts +3 -3
  144. package/dist/esm/components/ui/copy-field/index.d.ts +25 -1
  145. package/dist/esm/components/ui/copy-field/index.d.ts.map +1 -1
  146. package/dist/esm/components/ui/copy-field/index.js +16 -8
  147. package/dist/esm/components/ui/dialog/index.d.ts +1 -1
  148. package/dist/esm/components/ui/dialog/index.d.ts.map +1 -1
  149. package/dist/esm/components/ui/dialog/index.js +3 -3
  150. package/dist/esm/components/ui/file-upload/index.d.ts +159 -0
  151. package/dist/esm/components/ui/file-upload/index.d.ts.map +1 -1
  152. package/dist/esm/components/ui/file-upload/index.js +307 -5
  153. package/dist/esm/components/ui/icon-button/index.d.ts +1 -1
  154. package/dist/esm/components/ui/lerian-wordmark/index.d.ts +6 -0
  155. package/dist/esm/components/ui/lerian-wordmark/index.d.ts.map +1 -0
  156. package/dist/esm/components/ui/lerian-wordmark/index.js +4 -0
  157. package/dist/esm/components/ui/otp-input/index.js +1 -1
  158. package/dist/esm/components/ui/radio-group/index.js +1 -1
  159. package/dist/esm/components/ui/select/index.d.ts.map +1 -1
  160. package/dist/esm/components/ui/select/index.js +8 -4
  161. package/dist/esm/components/ui/sheet/index.d.ts +42 -0
  162. package/dist/esm/components/ui/sheet/index.d.ts.map +1 -1
  163. package/dist/esm/components/ui/sheet/index.js +48 -15
  164. package/dist/esm/components/ui/sidebar/index.d.ts +1 -0
  165. package/dist/esm/components/ui/sidebar/index.d.ts.map +1 -1
  166. package/dist/esm/components/ui/sidebar/index.js +1 -0
  167. package/dist/esm/components/ui/sidebar/sidebar-expand-button.d.ts +1 -1
  168. package/dist/esm/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
  169. package/dist/esm/components/ui/sidebar/sidebar-expand-button.js +15 -1
  170. package/dist/esm/components/ui/sidebar/sidebar-item.d.ts +1 -1
  171. package/dist/esm/components/ui/sidebar/sidebar-item.d.ts.map +1 -1
  172. package/dist/esm/components/ui/sidebar/sidebar-item.js +28 -4
  173. package/dist/esm/components/ui/sidebar/sidebar-provider.d.ts +58 -0
  174. package/dist/esm/components/ui/sidebar/sidebar-provider.d.ts.map +1 -1
  175. package/dist/esm/components/ui/sidebar/sidebar-provider.js +143 -1
  176. package/dist/esm/components/ui/sidebar/sidebar-root.d.ts +38 -1
  177. package/dist/esm/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
  178. package/dist/esm/components/ui/sidebar/sidebar-root.js +113 -7
  179. package/dist/esm/components/ui/sidebar/sidebar-trigger.d.ts +45 -0
  180. package/dist/esm/components/ui/sidebar/sidebar-trigger.d.ts.map +1 -0
  181. package/dist/esm/components/ui/sidebar/sidebar-trigger.js +53 -0
  182. package/dist/esm/components/ui/textarea/index.js +1 -1
  183. package/dist/esm/components/ui/toast/toaster.d.ts +5 -1
  184. package/dist/esm/components/ui/toast/toaster.d.ts.map +1 -1
  185. package/dist/esm/components/ui/toast/toaster.js +3 -2
  186. package/dist/esm/enterprise/data-table/index.d.ts +77 -7
  187. package/dist/esm/enterprise/data-table/index.d.ts.map +1 -1
  188. package/dist/esm/enterprise/data-table/index.js +57 -12
  189. package/dist/esm/enterprise/date-range-picker/index.js +4 -4
  190. package/dist/esm/enterprise/number-input/index.d.ts.map +1 -1
  191. package/dist/esm/enterprise/number-input/index.js +1 -1
  192. package/dist/esm/hooks/use-toast.d.ts +18 -2
  193. package/dist/esm/hooks/use-toast.d.ts.map +1 -1
  194. package/dist/esm/hooks/use-toast.js +60 -16
  195. package/dist/esm/index.d.ts +3 -0
  196. package/dist/esm/index.d.ts.map +1 -1
  197. package/dist/esm/index.js +3 -0
  198. package/dist/esm/lib/utils.d.ts +2 -0
  199. package/dist/esm/lib/utils.d.ts.map +1 -1
  200. package/dist/esm/lib/utils.js +10 -0
  201. package/dist/esm/toast/helpers.d.ts +13 -0
  202. package/dist/esm/toast/helpers.d.ts.map +1 -1
  203. package/dist/esm/toast/helpers.js +8 -1
  204. package/dist/fonts/OFL.txt +96 -0
  205. package/dist/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
  206. package/dist/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
  207. package/dist/fonts/ibm-plex-serif-latin-400.woff2 +0 -0
  208. package/dist/fonts/ibm-plex-serif-latin-500.woff2 +0 -0
  209. package/dist/fonts/inter-latin.woff2 +0 -0
  210. package/dist/fonts.css +46 -0
  211. package/dist/globals.css +62 -362
  212. package/dist/hooks/use-toast.d.ts +18 -2
  213. package/dist/hooks/use-toast.d.ts.map +1 -1
  214. package/dist/hooks/use-toast.js +61 -16
  215. package/dist/index.d.ts +3 -0
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js +3 -0
  218. package/dist/lib/utils.d.ts +2 -0
  219. package/dist/lib/utils.d.ts.map +1 -1
  220. package/dist/lib/utils.js +11 -0
  221. package/dist/public/wordmark.svg +1 -0
  222. package/dist/standalone.css +10 -0
  223. package/dist/toast/helpers.d.ts +13 -0
  224. package/dist/toast/helpers.d.ts.map +1 -1
  225. package/dist/toast/helpers.js +8 -1
  226. package/dist/tokens.css +367 -0
  227. package/package.json +9 -6
@@ -6,13 +6,6 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const class_variance_authority_1 = require("class-variance-authority");
7
7
  const utils_1 = require("../../../lib/utils");
8
8
  const react_slot_1 = require("@radix-ui/react-slot");
9
- /**
10
- * `credit` is the accounting reading of a credit amount, NOT an alias of
11
- * `destructive` (an error/alarm). The credit role is a tint-and-ink pair:
12
- * `--credit-foreground` mirrors `--credit` by contract, so the red carries the
13
- * role as text over a tinted surface. Do not "fix" this into a solid
14
- * `bg-credit` fill — that renders red-on-red and is invisible.
15
- */
16
9
  /**
17
10
  * `gap-1` is load-bearing, not decoration: a badge holding a label AND an
18
11
  * element child (`ID<code>ctx-123</code>`) has nothing between them otherwise —
@@ -20,8 +13,19 @@ const react_slot_1 = require("@radix-ui/react-slot");
20
13
  * anonymous flex item — so the screen reads `IDctx-123`. Consumers were pasting
21
14
  * `className="gap-1"` per call site; `cn` runs tailwind-merge, so an explicit
22
15
  * `gap-2` still wins. Single-child badges are unaffected: gap needs two items.
16
+ *
17
+ * `whitespace-nowrap` keeps the pill a pill. `rounded-full` draws the ends as
18
+ * semicircles sized to ONE line box, so a label that wraps stretches those caps
19
+ * over two lines and the shape reads as a rounded blob, not a token. It bit a
20
+ * consumer table whose column was sized to its content: `min-content` on
21
+ * wrappable text resolves to the WIDEST WORD, so a three-word group name landed
22
+ * at 112px wide and 46px tall against the 26px of a single-line badge. Nowrap
23
+ * also pins `min-content` to the full label, which is what lets a caller cap the
24
+ * box with `max-w-*` plus a truncating child and get an ellipsis. A caller that
25
+ * genuinely wants a wrapping badge passes `whitespace-normal`; tailwind-merge
26
+ * lets it win.
23
27
  */
24
- const badgeVariants = (0, class_variance_authority_1.cva)('inline-flex items-center gap-1 rounded-full border border-border px-2.5 py-0.5 text-sm font-medium transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2', {
28
+ const badgeVariants = (0, class_variance_authority_1.cva)('inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-border px-2.5 py-0.5 text-sm font-medium transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2', {
25
29
  variants: {
26
30
  variant: {
27
31
  default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
@@ -29,6 +33,14 @@ const badgeVariants = (0, class_variance_authority_1.cva)('inline-flex items-cen
29
33
  inactive: 'bg-muted text-foreground border-muted-foreground/40 py-[2px] px-3',
30
34
  secondary: 'border-transparent bg-muted-foreground text-white dark:text-black',
31
35
  destructive: 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
36
+ /**
37
+ * The accounting reading of a credit amount, NOT an alias of
38
+ * `destructive` (an error/alarm). The credit role is a tint-and-ink
39
+ * pair: `--credit-foreground` mirrors `--credit` by contract, so the
40
+ * red carries the role as text over a tinted surface. Do not "fix"
41
+ * this into a solid `bg-credit` fill — that renders red-on-red and is
42
+ * invisible.
43
+ */
32
44
  credit: 'border-credit/30 bg-credit/10 text-credit-foreground px-[10px] py-1',
33
45
  error: 'border-system-error-border bg-system-error-surface text-system-error-text px-[10px] py-1',
34
46
  success: 'border-system-success-border bg-system-success-surface text-system-success-text px-[10px] py-1',
@@ -1,13 +1,13 @@
1
1
  import * as React from 'react';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
3
  declare const buttonVariants: (props?: ({
4
- variant?: "default" | "plain" | "hoverLink" | "primary" | "secondary" | "tertiary" | "outline" | "link" | "destructive" | null | undefined;
4
+ variant?: "link" | "default" | "plain" | "hoverLink" | "primary" | "secondary" | "tertiary" | "outline" | "destructive" | null | undefined;
5
5
  fullWidth?: boolean | null | undefined;
6
- size?: "default" | "small" | null | undefined;
6
+ size?: "small" | "default" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  declare const iconVariants: (props?: ({
9
9
  position?: "end" | "start" | "far-end" | null | undefined;
10
- size?: "default" | "small" | null | undefined;
10
+ size?: "small" | "default" | null | undefined;
11
11
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
12
  export type ButtonProps = React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
13
13
  asChild?: boolean;
@@ -39,6 +39,30 @@ export type CopyFieldProps = {
39
39
  * @defaultValue 'Value to copy'
40
40
  */
41
41
  valueLabel?: string;
42
+ /**
43
+ * Accessible name for the copy button. Override for localization. Defaults to
44
+ * English, derived from `label` when there is one.
45
+ * @defaultValue `Copy ${label}`, or 'Copy value' without a label
46
+ */
47
+ copyLabel?: string;
48
+ /**
49
+ * Toast text on the fallback path, when the clipboard API is unavailable or
50
+ * refuses the write and the value is selected for a manual Ctrl/Cmd+C
51
+ * instead. Override for localization. Defaults to English.
52
+ * @defaultValue 'Copy not available — text selected, press Ctrl/Cmd+C'
53
+ */
54
+ fallbackLabel?: string;
55
+ /**
56
+ * Renders the value in the monospace face. For identifiers, tokens and
57
+ * recovery codes, where character shapes must be told apart.
58
+ * @defaultValue false
59
+ */
60
+ mono?: boolean;
61
+ /**
62
+ * One-line hint rendered under the field and announced with the input via
63
+ * `aria-describedby`. Omit for no element and no attribute.
64
+ */
65
+ description?: React.ReactNode;
42
66
  /**
43
67
  * Milliseconds after a *successful* copy before the clipboard is wiped, for
44
68
  * sensitive values that shouldn't linger there (TOTP secrets, recovery
@@ -52,5 +76,5 @@ export type CopyFieldProps = {
52
76
  */
53
77
  clearClipboardAfter?: number;
54
78
  };
55
- export declare function CopyField({ value, label, masked, onCopyLabel, revealLabel, hideLabel, valueLabel, clearClipboardAfter }: CopyFieldProps): React.JSX.Element;
79
+ export declare function CopyField({ value, label, masked, onCopyLabel, revealLabel, hideLabel, valueLabel, copyLabel, fallbackLabel, mono, description, clearClipboardAfter }: CopyFieldProps): React.JSX.Element;
56
80
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/copy-field/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,MAAM,cAAc,GAAG;IAC3B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AAmCD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAc,EACd,WAAW,EACX,WAA0B,EAC1B,SAAwB,EACxB,UAA4B,EAC5B,mBAAmB,EACpB,EAAE,cAAc,qBA6JhB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/copy-field/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,MAAM,MAAM,cAAc,GAAG;IAC3B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AAmCD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,MAAc,EACd,WAAW,EACX,WAA0B,EAC1B,SAAwB,EACxB,UAA4B,EAC5B,SAAS,EACT,aAAa,EACb,IAAY,EACZ,WAAW,EACX,mBAAmB,EACpB,EAAE,cAAc,qBAwLhB"}
@@ -40,6 +40,7 @@ const React = __importStar(require("react"));
40
40
  const lucide_react_1 = require("lucide-react");
41
41
  const icon_button_1 = require("../../../components/ui/icon-button");
42
42
  const use_toast_1 = require("../../../hooks/use-toast");
43
+ const utils_1 = require("../../../lib/utils");
43
44
  const DEFAULT_COPY_LABEL = 'Copied to clipboard!';
44
45
  const FALLBACK_COPY_LABEL = 'Copy not available — text selected, press Ctrl/Cmd+C';
45
46
  const COPIED_ICON_TIMEOUT = 1500;
@@ -67,17 +68,18 @@ const clearClipboardIfUnchanged = async (copiedValue) => {
67
68
  // Read or write refused; the clipboard stays as-is.
68
69
  }
69
70
  };
70
- function CopyField({ value, label, masked = false, onCopyLabel, revealLabel = 'Show value', hideLabel = 'Hide value', valueLabel = 'Value to copy', clearClipboardAfter }) {
71
+ function CopyField({ value, label, masked = false, onCopyLabel, revealLabel = 'Show value', hideLabel = 'Hide value', valueLabel = 'Value to copy', copyLabel, fallbackLabel, mono = false, description, clearClipboardAfter }) {
71
72
  const { toast } = (0, use_toast_1.useToast)();
72
73
  const generatedId = React.useId();
73
74
  const inputId = `${generatedId}-copy-field`;
75
+ const descriptionId = `${inputId}-description`;
74
76
  const inputRef = React.useRef(null);
75
77
  const copiedTimerRef = React.useRef(null);
76
78
  const clearTimerRef = React.useRef(null);
77
79
  const [revealed, setRevealed] = React.useState(false);
78
80
  const [copied, setCopied] = React.useState(false);
79
81
  const showAsText = !masked || revealed;
80
- const copyAccessibleName = label ? `Copy ${label}` : 'Copy value';
82
+ const copyAccessibleName = copyLabel ?? (label ? `Copy ${label}` : 'Copy value');
81
83
  React.useEffect(() => {
82
84
  return () => {
83
85
  if (copiedTimerRef.current) {
@@ -109,7 +111,10 @@ function CopyField({ value, label, masked = false, onCopyLabel, revealLabel = 'S
109
111
  };
110
112
  const handleFallback = () => {
111
113
  selectFieldText();
112
- toast({ title: FALLBACK_COPY_LABEL });
114
+ toast({
115
+ variant: 'destructive',
116
+ title: fallbackLabel ?? FALLBACK_COPY_LABEL
117
+ });
113
118
  };
114
119
  const handleCopy = async () => {
115
120
  if (!isClipboardAvailable()) {
@@ -141,15 +146,18 @@ function CopyField({ value, label, masked = false, onCopyLabel, revealLabel = 'S
141
146
  handleFallback();
142
147
  }
143
148
  };
144
- return ((0, jsx_runtime_1.jsxs)("div", { "data-slot": "copy-field", className: "flex w-full flex-col gap-2", children: [label ? ((0, jsx_runtime_1.jsx)("label", { htmlFor: inputId, className: "text-muted-foreground text-sm font-semibold", children: label })) : null, (0, jsx_runtime_1.jsxs)("div", { "data-slot": "input-wrapper", className: "border-input-border focus-within:border-ring flex h-10 w-full cursor-text items-center gap-1 rounded-md border pr-1 pl-4 transition-[color,box-shadow]", children: [(0, jsx_runtime_1.jsx)("input", { ref: inputRef, id: inputId, "data-slot": "input", "data-testid": "copy-field-input", type: showAsText ? 'text' : 'password', value: value, readOnly: true,
149
+ return ((0, jsx_runtime_1.jsxs)("div", { "data-slot": "copy-field", className: "flex w-full flex-col gap-2", children: [label ? ((0, jsx_runtime_1.jsx)("label", { htmlFor: inputId, className: "text-muted-foreground text-sm font-semibold", children: label })) : null, (0, jsx_runtime_1.jsxs)("div", { "data-slot": "input-wrapper", className: "border-input-border focus-within:border-ring has-[input:focus]:ring-ring flex h-10 w-full cursor-text items-center gap-1 rounded-md border pr-1 pl-4 transition-[color,box-shadow] has-[input:focus]:ring-2", children: [(0, jsx_runtime_1.jsx)("input", { ref: inputRef, id: inputId, "data-slot": "input", "data-testid": "copy-field-input", type: showAsText ? 'text' : 'password', value: value, readOnly: true,
145
150
  // This field holds secrets: TOTP manual-entry secrets, recovery
146
151
  // codes. While masked it renders as type="password", which invites
147
152
  // browsers and password managers to autofill it or offer to SAVE its
148
153
  // value, and spellcheck can ship the text to a remote service.
149
- autoComplete: "off", spellCheck: false, "aria-label": label ? undefined : valueLabel,
154
+ autoComplete: "off", spellCheck: false, "aria-label": label ? undefined : valueLabel, "aria-describedby": description ? descriptionId : undefined,
150
155
  // `min-w-0` lets this flex item shrink below its content width so a
151
156
  // long value (e.g. a UUID recovery code) scrolls inside the field
152
- // instead of overflowing its container. No `font-mono`: the value
153
- // inherits the app sans font (Inter) so it matches every other field.
154
- className: "text-input-foreground h-full min-w-0 flex-1 cursor-text border-none bg-transparent text-sm outline-none select-text focus:ring-0 focus:ring-offset-0" }), masked ? ((0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", size: "small", rounded: true, "aria-pressed": revealed, "aria-label": revealed ? hideLabel : revealLabel, onClick: () => setRevealed((prev) => !prev), children: revealed ? (0, jsx_runtime_1.jsx)(lucide_react_1.EyeOff, {}) : (0, jsx_runtime_1.jsx)(lucide_react_1.Eye, {}) })) : null, (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", size: "small", rounded: true, "aria-label": copyAccessibleName, onClick: handleCopy, children: copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, {}) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, {}) })] })] }));
157
+ // instead of overflowing its container. Sans by default, inheriting
158
+ // the app font (Inter) so the field matches every other input;
159
+ // `mono` opts identifiers, tokens and recovery codes into the
160
+ // monospace face, where telling 0 from O decides whether the value
161
+ // read back is the value.
162
+ className: (0, utils_1.cn)('text-input-foreground h-full min-w-0 flex-1 cursor-text border-none bg-transparent text-sm outline-none select-text focus:ring-0 focus:ring-offset-0', mono && 'font-mono') }), masked ? ((0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", size: "small", rounded: true, "aria-label": revealed ? hideLabel : revealLabel, onClick: () => setRevealed((prev) => !prev), children: revealed ? (0, jsx_runtime_1.jsx)(lucide_react_1.EyeOff, {}) : (0, jsx_runtime_1.jsx)(lucide_react_1.Eye, {}) })) : null, (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { type: "button", variant: "outline", size: "small", rounded: true, "aria-label": copyAccessibleName, onClick: handleCopy, children: copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, {}) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, {}) })] }), description ? ((0, jsx_runtime_1.jsx)("p", { "data-slot": "copy-field-description", id: descriptionId, className: "text-muted-foreground text-xs", children: description })) : null] }));
155
163
  }
@@ -5,7 +5,7 @@ declare function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogP
5
5
  declare function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
6
6
  declare function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element;
7
7
  declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element;
8
- declare function DialogContent({ className, children, showCloseButton, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
8
+ declare function DialogContent({ className, children, showCloseButton, onInteractOutside, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
9
9
  showCloseButton?: boolean;
10
10
  }): React.JSX.Element;
11
11
  declare function DialogHeader({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAA;AAKzD,iBAAS,MAAM,CAAC,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAEnD;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,qBAEtD;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,qBAErD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAEpD;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,qBAQtD;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG;IACxD,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAwBA;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAQpD;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,WAAW,CAAC,qBAQ1D;AAED,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,EAClB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAA;AAKzD,iBAAS,MAAM,CAAC,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAEnD;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,qBAEtD;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,qBAErD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAEpD;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,qBAQtD;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,iBAAiB,EACjB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG;IACxD,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAyBA;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAQpD;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,WAAW,CAAC,qBAQ1D;AAED,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,EAClB,CAAA"}
@@ -63,8 +63,8 @@ function DialogClose({ ...props }) {
63
63
  function DialogOverlay({ className, ...props }) {
64
64
  return ((0, jsx_runtime_1.jsx)(DialogPrimitive.Overlay, { "data-slot": "dialog-overlay", className: (0, utils_1.cn)('dialog-overlay', className), ...props }));
65
65
  }
66
- function DialogContent({ className, children, showCloseButton = true, ...props }) {
67
- return ((0, jsx_runtime_1.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [(0, jsx_runtime_1.jsx)(DialogOverlay, {}), (0, jsx_runtime_1.jsxs)(DialogPrimitive.Content, { "data-slot": "dialog-content", className: (0, utils_1.cn)('dialog-content', !showCloseButton && '*:data-radix-dialog-close:hidden', className), ...props, children: [children, (0, jsx_runtime_1.jsxs)(DialogPrimitive.Close, { "data-slot": "dialog-close", className: "dialog-close", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "size-4" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] })] })] }));
66
+ function DialogContent({ className, children, showCloseButton = true, onInteractOutside, ...props }) {
67
+ return ((0, jsx_runtime_1.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [(0, jsx_runtime_1.jsx)(DialogOverlay, {}), (0, jsx_runtime_1.jsxs)(DialogPrimitive.Content, { "data-slot": "dialog-content", className: (0, utils_1.cn)('dialog-content', !showCloseButton && '*:data-radix-dialog-close:hidden', className), onInteractOutside: (0, utils_1.keepOpenOnToast)(onInteractOutside), ...props, children: [children, (0, jsx_runtime_1.jsxs)(DialogPrimitive.Close, { "data-slot": "dialog-close", className: "dialog-close", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "size-4" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] })] })] }));
68
68
  }
69
69
  function DialogHeader({ className, ...props }) {
70
70
  return ((0, jsx_runtime_1.jsx)("div", { "data-slot": "dialog-header", className: (0, utils_1.cn)('dialog-header', className), ...props }));
@@ -158,4 +158,163 @@ export declare const FileUpload: React.ForwardRefExoticComponent<{
158
158
  'aria-describedby'?: string;
159
159
  'aria-label'?: string;
160
160
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "className" | "disabled" | "type" | "value" | "onChange" | "onError" | "onSelect" | "accept" | "multiple"> & React.RefAttributes<HTMLInputElement>>;
161
+ /**
162
+ * A rejection from `MultipleFileUpload`: every rejection the single-file
163
+ * sibling can produce, plus the one only a plural selection has — the cap.
164
+ */
165
+ export type MultipleFileUploadError = FileUploadError | {
166
+ kind: 'too-many';
167
+ file: File;
168
+ maxFiles: number;
169
+ };
170
+ /** Overrides for the fixed English copy. Every field is optional. */
171
+ export interface MultipleFileUploadLabels {
172
+ /** Emphasised call to action in the empty zone. Defaults to "Choose files". */
173
+ action?: string;
174
+ /** Trailing hint after the action. Defaults to "or drag and drop". */
175
+ hint?: string;
176
+ /** Zone copy once `maxFiles` is reached. Receives the cap to interpolate. */
177
+ full?: (maxFiles: number) => string;
178
+ /**
179
+ * Accessible name of a row's remove control. Receives that row's file, so the
180
+ * name identifies it. Defaults to `Remove <filename>`.
181
+ */
182
+ remove?: (file: File) => string;
183
+ /**
184
+ * Copy for one rejection. Called once per rejection in a batch; use the
185
+ * exported `humanizeSize` to format `maxSizeBytes`. Return `null`,
186
+ * `undefined` or `''` to stay SILENT and leave the announcement to the host's
187
+ * own `onError` handling. A batch whose every message is silent renders no
188
+ * alert at all.
189
+ */
190
+ error?: (error: MultipleFileUploadError) => string | null | undefined;
191
+ }
192
+ export type MultipleFileUploadProps = {
193
+ /** Comma-separated accept filter. Applied to every file, extension or MIME. */
194
+ accept?: string;
195
+ /** Inclusive per-file byte ceiling. Applied to each file independently. */
196
+ maxSizeBytes?: number;
197
+ /** Ceiling on the TOTAL selection. Omitted means unbounded. */
198
+ maxFiles?: number;
199
+ /** Controlled selection. The host owns state; defaults to empty. */
200
+ value?: FileUploadResult[];
201
+ /**
202
+ * How each accepted file is handed over. `'text'` (default) decodes UTF-8
203
+ * and populates `text`; `'none'` skips decoding entirely and is the mode
204
+ * BINARY files need. See FileUpload's `readAs` for why.
205
+ */
206
+ readAs?: FileUploadReadAs;
207
+ /** Override the fixed English copy. Omitted fields keep their defaults. */
208
+ labels?: MultipleFileUploadLabels;
209
+ /** Fires with the WHOLE next selection whenever files are added or removed. */
210
+ onValueChange: (values: FileUploadResult[]) => void;
211
+ /** Fires once per rejected file. A batch can produce several. */
212
+ onError?: (error: MultipleFileUploadError) => void;
213
+ disabled?: boolean;
214
+ id?: string;
215
+ className?: string;
216
+ 'aria-invalid'?: boolean;
217
+ 'aria-required'?: boolean;
218
+ 'aria-describedby'?: string;
219
+ 'aria-label'?: string;
220
+ } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'accept' | 'value' | 'disabled' | 'onChange' | 'onSelect' | 'className' | 'multiple' | 'onError'>;
221
+ /**
222
+ * MultipleFileUpload: the plural sibling of FileUpload. Pick SEVERAL files,
223
+ * accumulate them across repeated picks, validate each one, cap the total, and
224
+ * hand back `FileUploadResult[]`.
225
+ *
226
+ * A SIBLING COMPONENT, not a `multiple` flag. This library already answers
227
+ * "this one takes many" that way (`Select` / `MultipleSelect`), and FileUpload
228
+ * strips `'multiple'` from its props on purpose: single-file is its contract,
229
+ * not a default it happens to have. A boolean would have forced every prop
230
+ * here into a union that means one thing when the flag is set and another when
231
+ * it is not: `value` as `Result | Result[] | null`, a `maxFiles` that is
232
+ * meaningless in half the configurations, and a remove control whose
233
+ * accessible name is fixed copy in one mode and per-file in the other. The
234
+ * plural props follow the house shape for plural components: `value?: T[]`
235
+ * with `onValueChange?: (values: T[]) => void`.
236
+ *
237
+ * WHERE THE LINE SITS: this component owns SELECTION and nothing after it.
238
+ * Choosing, validating, capping, listing and removing are its job; uploading
239
+ * is not. That split is not squeamishness about scope, it is where the
240
+ * knowledge actually lives. An upload needs an endpoint, an auth scheme, a
241
+ * concurrency policy, a retry policy and, very often, a parent id that does
242
+ * not exist yet when the files are chosen: the motivating host stages evidence
243
+ * files while a form is being filled and can only upload them against the id
244
+ * that its create call returns afterwards. None of that is knowable from
245
+ * inside a library primitive, and a component that guessed would have to be
246
+ * fought rather than used. So the host keeps its own per-file record with
247
+ * status and retry, and this component keeps the part a form can hold and
248
+ * validate: the chosen files. `FileUploadResult[]` is a value; an upload state
249
+ * machine is not.
250
+ *
251
+ * ACCUMULATION is the defining behaviour. A second pick ADDS to the selection
252
+ * rather than replacing it, because a user assembling five documents does it
253
+ * in two or three trips to the file dialog, not one. Everything else follows
254
+ * from that: room is measured against what is already selected, and the batch
255
+ * that overflows the cap still contributes the files that fit.
256
+ *
257
+ * A BATCH SURVIVES ITS OWN CASUALTIES. One file rejected for type, size or a
258
+ * failed read does not discard the rest of the batch, and it does not consume
259
+ * a slot either: validation runs over the WHOLE batch before the cap is
260
+ * applied, so a file that was never eligible cannot cost an eligible one its
261
+ * place, and `'too-many'` always names a file a slot would genuinely have
262
+ * taken. The alternative punishes
263
+ * a user for a mistake in one file by throwing away four good ones, and hands
264
+ * back no way to tell which was which. Every rejection is reported through
265
+ * `onError` and announced together in one `role="alert"`.
266
+ *
267
+ * Accessibility follows the sibling BELOW THE CAP: the real `<input
268
+ * type="file">` is `sr-only` but focusable and labelable, and never
269
+ * `aria-hidden`, so FormControl-injected ARIA and react-hook-form's focus on
270
+ * error both work while the picker is enabled. At the cap that changes, and
271
+ * the paragraph below says how.
272
+ * The file list sits OUTSIDE the click zone, so activating a remove control
273
+ * cannot also reopen the picker, and each remove control is named after its
274
+ * own file: a column of identical "Remove file" buttons tells a screen-reader
275
+ * user nothing about which row they are on.
276
+ *
277
+ * AT THE CAP the picker takes the native `disabled` attribute, and that DOES
278
+ * take it out of the tab order. This is the one state in which the input is
279
+ * not a focus target, and the one state in which focus-on-error cannot land on
280
+ * it, so it is a real cost rather than a free win. The cap has no counterpart
281
+ * in the single-file sibling, so the precedent followed here is
282
+ * `DateRangePicker`'s trigger: a control whose only job is to open a dialog has
283
+ * no state worth keeping focusable, and native `disabled` is what both removes
284
+ * it from the tab order and keeps the dialog shut. The alternative, an enabled
285
+ * picker that opens the file dialog and then refuses every file with
286
+ * `too-many`, is a control that lies about being available. What keeps the cap
287
+ * from being a dead end is the escape hatch: the remove controls answer to
288
+ * `disabled` alone and NEVER to the cap, so they stay focusable and removing
289
+ * one file reopens the picker.
290
+ */
291
+ export declare const MultipleFileUpload: React.ForwardRefExoticComponent<{
292
+ /** Comma-separated accept filter. Applied to every file, extension or MIME. */
293
+ accept?: string;
294
+ /** Inclusive per-file byte ceiling. Applied to each file independently. */
295
+ maxSizeBytes?: number;
296
+ /** Ceiling on the TOTAL selection. Omitted means unbounded. */
297
+ maxFiles?: number;
298
+ /** Controlled selection. The host owns state; defaults to empty. */
299
+ value?: FileUploadResult[];
300
+ /**
301
+ * How each accepted file is handed over. `'text'` (default) decodes UTF-8
302
+ * and populates `text`; `'none'` skips decoding entirely and is the mode
303
+ * BINARY files need. See FileUpload's `readAs` for why.
304
+ */
305
+ readAs?: FileUploadReadAs;
306
+ /** Override the fixed English copy. Omitted fields keep their defaults. */
307
+ labels?: MultipleFileUploadLabels;
308
+ /** Fires with the WHOLE next selection whenever files are added or removed. */
309
+ onValueChange: (values: FileUploadResult[]) => void;
310
+ /** Fires once per rejected file. A batch can produce several. */
311
+ onError?: (error: MultipleFileUploadError) => void;
312
+ disabled?: boolean;
313
+ id?: string;
314
+ className?: string;
315
+ 'aria-invalid'?: boolean;
316
+ 'aria-required'?: boolean;
317
+ 'aria-describedby'?: string;
318
+ 'aria-label'?: string;
319
+ } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "className" | "disabled" | "type" | "value" | "onChange" | "onError" | "onSelect" | "accept" | "multiple"> & React.RefAttributes<HTMLInputElement>>;
161
320
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/file-upload/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/file-upload/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3D,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAA;AAEvC,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAC9D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,wGAAwG;IACxG,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iEAAiE;IACjE,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,uGAAuG;IACvG,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAA;IACnD,gHAAgH;IAChH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,IAAI,CACN,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAEzC,MAAM,GACN,QAAQ,GACR,OAAO,GACP,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GAQX,SAAS,GAET,UAAU,CACb,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,eAAe,GAAG,IAAI,CASxB;AAqBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUlD;AAcD,eAAO,MAAM,UAAU;IAvHrB,wGAAwG;aAC/F,MAAM;IACf,0FAA0F;mBAC3E,MAAM;IACrB,iEAAiE;YACzD,gBAAgB,GAAG,IAAI;IAC/B;;;;;;;OAOG;aACM,gBAAgB;IACzB,2EAA2E;aAClE,gBAAgB;IACzB,uGAAuG;cAC7F,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI;IACnD,gHAAgH;cACtG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI;eAC/B,OAAO;SACb,MAAM;gBACC,MAAM;qBACD,OAAO;sBACN,OAAO;yBACJ,MAAM;mBACZ,MAAM;yMAmVtB,CAAA;AAID;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GACjC,eAAe,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtE,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;IACnC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC/B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CACtE;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,wBAAwB,CAAA;IACjC,+EAA+E;IAC/E,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAA;IACnD,iEAAiE;IACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,IAAI,CACN,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAGzC,MAAM,GACN,QAAQ,GACR,OAAO,GACP,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,UAAU,GAIV,SAAS,CACZ,CAAA;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,eAAO,MAAM,kBAAkB;IAlI7B,+EAA+E;aACtE,MAAM;IACf,2EAA2E;mBAC5D,MAAM;IACrB,+DAA+D;eACpD,MAAM;IACjB,oEAAoE;YAC5D,gBAAgB,EAAE;IAC1B;;;;OAIG;aACM,gBAAgB;IACzB,2EAA2E;aAClE,wBAAwB;IACjC,+EAA+E;mBAChE,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,IAAI;IACnD,iEAAiE;cACvD,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI;eACvC,OAAO;SACb,MAAM;gBACC,MAAM;qBACD,OAAO;sBACN,OAAO;yBACJ,MAAM;mBACZ,MAAM;yMAkdrB,CAAA"}