@brycks/core-front 0.11.0 → 0.12.1

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 (61) hide show
  1. package/dist/components/data/VirtualList/VirtualList.js +1 -1
  2. package/dist/components/data.cjs +1 -1
  3. package/dist/components/data.d.ts +387 -2
  4. package/dist/components/data.js +26 -26
  5. package/dist/components/feedback/Toast/ToastContext.js +3 -3
  6. package/dist/components/feedback.cjs +1 -1
  7. package/dist/components/feedback.d.ts +317 -2
  8. package/dist/components/feedback.js +21 -21
  9. package/dist/components/form/DropZone/DropZone.cjs.map +1 -1
  10. package/dist/components/form/DropZone/DropZone.js.map +1 -1
  11. package/dist/components/form/FileInput/FileInput.cjs.map +1 -1
  12. package/dist/components/form/FileInput/FileInput.js.map +1 -1
  13. package/dist/components/form/FileUpload/FileUpload.cjs +2 -0
  14. package/dist/components/form/FileUpload/FileUpload.cjs.map +1 -0
  15. package/dist/components/form/FileUpload/FileUpload.js +223 -0
  16. package/dist/components/form/FileUpload/FileUpload.js.map +1 -0
  17. package/dist/components/form/FileUpload/fileUpload.utils.cjs +2 -0
  18. package/dist/components/form/FileUpload/fileUpload.utils.cjs.map +1 -0
  19. package/dist/components/form/FileUpload/fileUpload.utils.js +43 -0
  20. package/dist/components/form/FileUpload/fileUpload.utils.js.map +1 -0
  21. package/dist/components/form/FormGroup/FormGroup.cjs +1 -1
  22. package/dist/components/form/FormGroup/FormGroup.js +1 -1
  23. package/dist/components/form/Slider/Slider.cjs +1 -1
  24. package/dist/components/form/Slider/Slider.js +2 -2
  25. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  26. package/dist/components/form/TagInput/TagInput.js +8 -8
  27. package/dist/components/form.cjs +1 -1
  28. package/dist/components/form.d.ts +889 -2
  29. package/dist/components/form.js +51 -45
  30. package/dist/components/form.js.map +1 -1
  31. package/dist/components/layout.cjs +1 -1
  32. package/dist/components/layout.d.ts +587 -2
  33. package/dist/components/layout.js +30 -30
  34. package/dist/components/media/Video/Video.cjs +1 -1
  35. package/dist/components/media/Video/Video.cjs.map +1 -1
  36. package/dist/components/media/Video/Video.js +54 -54
  37. package/dist/components/media/Video/Video.js.map +1 -1
  38. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +1 -1
  39. package/dist/components/navigation/ContextMenu/ContextMenu.js +5 -5
  40. package/dist/components/navigation/Stepper/Stepper.js +4 -4
  41. package/dist/components/navigation/Tabs/Tabs.js +4 -4
  42. package/dist/components/navigation.cjs +1 -1
  43. package/dist/components/navigation.d.ts +436 -2
  44. package/dist/components/navigation.js +22 -22
  45. package/dist/components/typography/Text/Text.cjs +1 -1
  46. package/dist/components/typography/Text/Text.js +1 -1
  47. package/dist/components/utility.cjs +1 -1
  48. package/dist/components/utility.d.ts +278 -2
  49. package/dist/components/utility.js +28 -28
  50. package/dist/index.cjs +1 -1
  51. package/dist/index.d.ts +87 -0
  52. package/dist/index.js +279 -275
  53. package/dist/index.js.map +1 -1
  54. package/dist/styles.css +1 -1
  55. package/package.json +116 -115
  56. package/dist/data.d.ts +0 -387
  57. package/dist/feedback.d.ts +0 -317
  58. package/dist/form.d.ts +0 -772
  59. package/dist/layout.d.ts +0 -587
  60. package/dist/navigation.d.ts +0 -436
  61. package/dist/utility.d.ts +0 -278
@@ -1,2 +1,317 @@
1
- export * from './feedback/index'
2
- export {}
1
+ import { default as default_2 } from 'react';
2
+ import { ForwardRefExoticComponent } from 'react';
3
+ import { HTMLAttributes } from 'react';
4
+ import { JSX } from 'react/jsx-runtime';
5
+ import { ReactElement } from 'react';
6
+ import { ReactNode } from 'react';
7
+ import { RefAttributes } from 'react';
8
+
9
+ export declare const Alert: default_2.ForwardRefExoticComponent<AlertProps & default_2.RefAttributes<HTMLDivElement>>;
10
+
11
+ export declare type AlertIntent = 'info' | 'success' | 'warning' | 'error';
12
+
13
+ export declare interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
14
+ /** Visual intent/status */
15
+ intent?: AlertIntent;
16
+ /** Visual variant */
17
+ variant?: AlertVariant;
18
+ /** Alert title */
19
+ title?: ReactNode;
20
+ /** Custom icon */
21
+ icon?: ReactNode;
22
+ /** Whether to show default icon */
23
+ showIcon?: boolean;
24
+ /** Action element (button, link) */
25
+ action?: ReactNode;
26
+ /** Whether alert can be dismissed */
27
+ isDismissible?: boolean;
28
+ /** Callback when dismissed */
29
+ onDismiss?: () => void;
30
+ /** Accessible label of the dismiss button */
31
+ dismissLabel?: string;
32
+ /** Custom class name */
33
+ className?: string;
34
+ /** Test ID */
35
+ testId?: string;
36
+ /** Alert content */
37
+ children?: ReactNode;
38
+ }
39
+
40
+ export declare type AlertVariant = 'subtle' | 'solid' | 'outline';
41
+
42
+ export declare const Banner: default_2.ForwardRefExoticComponent<BannerProps & default_2.RefAttributes<HTMLDivElement>>;
43
+
44
+ export declare type BannerIntent = 'info' | 'success' | 'warning' | 'error' | 'neutral';
45
+
46
+ export declare interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
47
+ /** Visual intent/status */
48
+ intent?: BannerIntent;
49
+ /** Banner title (stronger weight, sits above the description) */
50
+ title?: ReactNode;
51
+ /** Custom icon (overrides the default per-intent icon) */
52
+ icon?: ReactNode;
53
+ /** Whether to show the leading icon */
54
+ showIcon?: boolean;
55
+ /** Action element (button, link) shown on the trailing edge */
56
+ action?: ReactNode;
57
+ /** Whether the banner can be dismissed */
58
+ isDismissible?: boolean;
59
+ /** Callback when dismissed */
60
+ onDismiss?: () => void;
61
+ /** Accessible label of the dismiss button */
62
+ dismissLabel?: string;
63
+ /**
64
+ * ARIA live-region role. Defaults to `alert` for warning/error and
65
+ * `status` for info/success/neutral. Override when the default is wrong.
66
+ */
67
+ role?: 'alert' | 'status';
68
+ /** Custom class name */
69
+ className?: string;
70
+ /** Test ID */
71
+ testId?: string;
72
+ /** Banner content (description) */
73
+ children?: ReactNode;
74
+ }
75
+
76
+ export declare const ConfirmDialog: ForwardRefExoticComponent<ConfirmDialogProps & RefAttributes<HTMLDivElement>>;
77
+
78
+ export declare interface ConfirmDialogProps {
79
+ /** Whether the dialog is open */
80
+ isOpen: boolean;
81
+ /** Callback when the dialog should close (cancel / overlay / escape) */
82
+ onClose: () => void;
83
+ /** Callback when the user confirms */
84
+ onConfirm: () => void;
85
+ /** Dialog title */
86
+ title: ReactNode;
87
+ /** Body message (use `children` for richer content) */
88
+ message?: ReactNode;
89
+ /** Label of the confirm button */
90
+ confirmLabel?: string;
91
+ /** Label of the cancel button */
92
+ cancelLabel?: string;
93
+ /** Accessible label of the modal close button */
94
+ closeLabel?: string;
95
+ /** Visual variant — `danger` for destructive actions */
96
+ variant?: ConfirmDialogVariant;
97
+ /** Whether the confirm action is in progress (disables cancel, spins confirm) */
98
+ isLoading?: boolean;
99
+ /** Test ID */
100
+ testId?: string;
101
+ /** Richer body content (rendered below `message`) */
102
+ children?: ReactNode;
103
+ }
104
+
105
+ export declare type ConfirmDialogVariant = 'default' | 'danger';
106
+
107
+ export declare const Drawer: ForwardRefExoticComponent<DrawerProps & RefAttributes<HTMLDivElement>>;
108
+
109
+ export declare type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';
110
+
111
+ export declare interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
112
+ /** Whether the drawer is open */
113
+ isOpen: boolean;
114
+ /** Callback when drawer should close */
115
+ onClose: () => void;
116
+ /** Drawer placement */
117
+ placement?: DrawerPlacement;
118
+ /** Drawer size */
119
+ size?: DrawerSize;
120
+ /** Drawer title */
121
+ title?: ReactNode;
122
+ /** Whether to close on overlay click */
123
+ closeOnOverlayClick?: boolean;
124
+ /** Whether to close on escape key */
125
+ closeOnEscape?: boolean;
126
+ /** Whether to show close button */
127
+ showCloseButton?: boolean;
128
+ /** Accessible label of the close button */
129
+ closeLabel?: string;
130
+ /** Whether to show overlay */
131
+ showOverlay?: boolean;
132
+ /** Custom class name */
133
+ className?: string;
134
+ /** Test ID */
135
+ testId?: string;
136
+ }
137
+
138
+ export declare type DrawerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
139
+
140
+ export declare const Modal: ForwardRefExoticComponent<ModalProps & RefAttributes<HTMLDivElement>>;
141
+
142
+ export declare interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
143
+ /** Whether the modal is open */
144
+ isOpen: boolean;
145
+ /** Callback when modal should close */
146
+ onClose: () => void;
147
+ /** Modal size */
148
+ size?: ModalSize;
149
+ /** Modal title */
150
+ title?: ReactNode;
151
+ /** Modal description */
152
+ description?: ReactNode;
153
+ /** Whether to close on overlay click */
154
+ closeOnOverlayClick?: boolean;
155
+ /** Whether to close on escape key */
156
+ closeOnEscape?: boolean;
157
+ /** Whether to show close button */
158
+ showCloseButton?: boolean;
159
+ /** Accessible label of the close button */
160
+ closeLabel?: string;
161
+ /** Footer content (e.g. action buttons), pinned below the scrollable body */
162
+ footer?: ReactNode;
163
+ /** Custom class name */
164
+ className?: string;
165
+ /** Test ID */
166
+ testId?: string;
167
+ /** Modal content */
168
+ children?: ReactNode;
169
+ }
170
+
171
+ export declare type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
172
+
173
+ export declare const Popover: default_2.ForwardRefExoticComponent<PopoverProps & default_2.RefAttributes<HTMLDivElement>>;
174
+
175
+ export declare type PopoverPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
176
+
177
+ export declare interface PopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
178
+ /** Popover content */
179
+ content: ReactNode;
180
+ /** Trigger element */
181
+ children: ReactElement;
182
+ /** Placement relative to trigger */
183
+ placement?: PopoverPlacement;
184
+ /** How to trigger the popover */
185
+ trigger?: PopoverTrigger;
186
+ /** Whether the popover is open (controlled) */
187
+ isOpen?: boolean;
188
+ /** Default open state (uncontrolled) */
189
+ defaultOpen?: boolean;
190
+ /** Callback when open state changes */
191
+ onOpenChange?: (isOpen: boolean) => void;
192
+ /** Offset from trigger in pixels */
193
+ offset?: number;
194
+ /** Delay before showing (hover trigger) */
195
+ openDelay?: number;
196
+ /** Delay before hiding (hover trigger) */
197
+ closeDelay?: number;
198
+ /** Whether to close on outside click */
199
+ closeOnOutsideClick?: boolean;
200
+ /** Custom class name for content */
201
+ className?: string;
202
+ /** Test ID */
203
+ testId?: string;
204
+ }
205
+
206
+ export declare type PopoverTrigger = 'click' | 'hover';
207
+
208
+ export declare const Progress: ForwardRefExoticComponent<ProgressProps & RefAttributes<HTMLDivElement>>;
209
+
210
+ export declare type ProgressIntent = 'primary' | 'success' | 'warning' | 'error';
211
+
212
+ export declare interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
213
+ /** Current value (0-100) */
214
+ value?: number;
215
+ /** Maximum value */
216
+ max?: number;
217
+ /** Progress size */
218
+ size?: ProgressSize;
219
+ /** Progress variant */
220
+ variant?: ProgressVariant;
221
+ /** Progress intent/color */
222
+ intent?: ProgressIntent;
223
+ /** Whether to show the value label */
224
+ showValue?: boolean;
225
+ /** Whether the progress is indeterminate */
226
+ indeterminate?: boolean;
227
+ /** Format value for display */
228
+ formatValue?: (value: number, max: number) => string;
229
+ /** Label text */
230
+ label?: string;
231
+ /** Custom class name */
232
+ className?: string;
233
+ /** Test ID */
234
+ testId?: string;
235
+ }
236
+
237
+ export declare type ProgressSize = 'xs' | 'sm' | 'md' | 'lg';
238
+
239
+ export declare type ProgressVariant = 'linear' | 'circular';
240
+
241
+ export declare const Toast: ForwardRefExoticComponent<ToastProps & RefAttributes<HTMLDivElement>>;
242
+
243
+ export declare interface ToastContextValue {
244
+ toasts: ToastItem[];
245
+ addToast: (props: Omit<ToastProps, 'isOpen' | 'onClose'>) => string;
246
+ removeToast: (id: string) => void;
247
+ removeAll: () => void;
248
+ }
249
+
250
+ export declare type ToastIntent = 'info' | 'success' | 'warning' | 'error';
251
+
252
+ export declare interface ToastItem {
253
+ id: string;
254
+ props: Omit<ToastProps, 'isOpen' | 'onClose'>;
255
+ }
256
+
257
+ export declare type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
258
+
259
+ export declare interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
260
+ /** Toast intent/type */
261
+ intent?: ToastIntent;
262
+ /** Toast title */
263
+ title?: ReactNode;
264
+ /** Toast description */
265
+ description?: ReactNode;
266
+ /** Whether the toast is visible */
267
+ isOpen?: boolean;
268
+ /** Duration in ms before auto-dismiss (0 = no auto-dismiss) */
269
+ duration?: number;
270
+ /** Callback when toast should close */
271
+ onClose?: () => void;
272
+ /** Whether to show close button */
273
+ showCloseButton?: boolean;
274
+ /** Accessible label of the close button */
275
+ closeLabel?: string;
276
+ /** Action button */
277
+ action?: ReactNode;
278
+ /** Custom icon */
279
+ icon?: ReactNode;
280
+ /** Custom class name */
281
+ className?: string;
282
+ /** Test ID */
283
+ testId?: string;
284
+ }
285
+
286
+ export declare function ToastProvider({ children, position, maxToasts, }: ToastProviderProps): JSX.Element;
287
+
288
+ export declare interface ToastProviderProps {
289
+ children: ReactNode;
290
+ position?: ToastPosition;
291
+ maxToasts?: number;
292
+ }
293
+
294
+ export declare const Tooltip: ForwardRefExoticComponent<TooltipProps & RefAttributes<HTMLDivElement>>;
295
+
296
+ export declare type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
297
+
298
+ export declare interface TooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
299
+ /** Tooltip content */
300
+ content: ReactNode;
301
+ /** Placement relative to trigger */
302
+ placement?: TooltipPlacement;
303
+ /** Delay before showing (ms) */
304
+ delay?: number;
305
+ /** Whether tooltip is disabled */
306
+ isDisabled?: boolean;
307
+ /** Custom class name */
308
+ className?: string;
309
+ /** Test ID */
310
+ testId?: string;
311
+ /** Trigger element */
312
+ children: ReactNode;
313
+ }
314
+
315
+ export declare function useToast(): ToastContextValue;
316
+
317
+ export { }
@@ -1,24 +1,24 @@
1
- import { Modal as e } from "./feedback/Modal/Modal.js";
2
- import { Alert as p } from "./feedback/Alert/Alert.js";
3
- import { Banner as m } from "./feedback/Banner/Banner.js";
4
- import { ConfirmDialog as a } from "./feedback/ConfirmDialog/ConfirmDialog.js";
5
- import { Tooltip as i } from "./feedback/Tooltip/Tooltip.js";
6
- import { Toast as T, ToastProvider as n } from "./feedback/Toast/Toast.js";
7
- import { useToast as d } from "./feedback/Toast/ToastContext.js";
8
- import { Drawer as v } from "./feedback/Drawer/Drawer.js";
9
- import { Popover as u } from "./feedback/Popover/Popover.js";
10
- import { Progress as A } from "./feedback/Progress/Progress.js";
1
+ import { Alert as e } from "./feedback/Alert/Alert.js";
2
+ import { Banner as p } from "./feedback/Banner/Banner.js";
3
+ import { ConfirmDialog as m } from "./feedback/ConfirmDialog/ConfirmDialog.js";
4
+ import { Drawer as a } from "./feedback/Drawer/Drawer.js";
5
+ import { Modal as i } from "./feedback/Modal/Modal.js";
6
+ import { Popover as T } from "./feedback/Popover/Popover.js";
7
+ import { Progress as P } from "./feedback/Progress/Progress.js";
8
+ import { Toast as g, ToastProvider as v } from "./feedback/Toast/Toast.js";
9
+ import { Tooltip as u } from "./feedback/Tooltip/Tooltip.js";
10
+ import { useToast as A } from "./feedback/Toast/ToastContext.js";
11
11
  export {
12
- p as Alert,
13
- m as Banner,
14
- a as ConfirmDialog,
15
- v as Drawer,
16
- e as Modal,
17
- u as Popover,
18
- A as Progress,
19
- T as Toast,
20
- n as ToastProvider,
21
- i as Tooltip,
22
- d as useToast
12
+ e as Alert,
13
+ p as Banner,
14
+ m as ConfirmDialog,
15
+ a as Drawer,
16
+ i as Modal,
17
+ T as Popover,
18
+ P as Progress,
19
+ g as Toast,
20
+ v as ToastProvider,
21
+ u as Tooltip,
22
+ A as useToast
23
23
  };
24
24
  //# sourceMappingURL=feedback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DropZone.cjs","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DropZone.cjs","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n *\n * @deprecated Use {@link FileUpload} with `variant=\"dropzone\"` instead, which\n * also lists the selected files and reports rejected ones. Kept only for API\n * stability.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DropZone.js","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DropZone.js","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n *\n * @deprecated Use {@link FileUpload} with `variant=\"dropzone\"` instead, which\n * also lists the selected files and reports rejected ones. Kept only for API\n * stability.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileInput.cjs","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
1
+ {"version":3,"file":"FileInput.cjs","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n *\n * @deprecated Use {@link FileUpload} instead. `FileInput` never shows what was\n * selected, drops files above `maxSize` without telling the user, hardcodes\n * English copy and ignores `variant=\"default\"`. Kept only for API stability.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileInput.js","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
1
+ {"version":3,"file":"FileInput.js","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n *\n * @deprecated Use {@link FileUpload} instead. `FileInput` never shows what was\n * selected, drops files above `maxSize` without telling the user, hardcodes\n * English copy and ignores `variant=\"default\"`. Kept only for API stability.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("react"),E=require("../../../utils/styles.cjs"),v=require("./fileUpload.utils.cjs"),H={trigger:"Choose file",placeholder:"No file selected",prompt:"Click to browse or drag a file here",dropPrompt:"Drop to upload",remove:"Remove file",invalidType:c=>`${c}: unsupported file type.`,tooLarge:(c,l)=>`${c}: exceeds ${l}.`};function B(){return e.jsxs("svg",{width:"22",height:"22",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:[e.jsx("path",{d:"M12 15V4m0 0L8 8m4-4l4 4",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M4 15v2.5A2.5 2.5 0 006.5 20h11a2.5 2.5 0 002.5-2.5V15",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})]})}function G(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e.jsx("path",{d:"M9 1.5H4.5A1.5 1.5 0 003 3v10A1.5 1.5 0 004.5 14.5h7A1.5 1.5 0 0013 13V5.5L9 1.5z",stroke:"currentColor",strokeWidth:"1.3",strokeLinejoin:"round"}),e.jsx("path",{d:"M9 1.5v4h4",stroke:"currentColor",strokeWidth:"1.3",strokeLinejoin:"round"})]})}function J(){return e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:e.jsx("path",{d:"M4 4l6 6M10 4l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const I=a.forwardRef(function({files:l,onFilesChange:i,variant:_="dropzone",size:O="md",accept:f,multiple:k=!1,maxFiles:g,maxSize:d,hint:u,error:m,isInvalid:U=!1,disabled:s=!1,icon:z,onReject:b,labels:A,id:W,className:q,testId:F},p){const N=a.useRef(null),[j,x]=a.useState(!1),[C,L]=a.useState([]),t={...H,...A},y=U||!!m||C.length>0,h=a.useCallback(r=>{if(!r||r.length===0)return;const{accepted:o,rejected:n}=v.selectFiles(Array.from(r),{accept:f,maxSize:d,multiple:k,maxFiles:g,current:l});L(n),n.length>0&&b?.(n),(o.length>0||n.length===0)&&i(o)},[f,l,g,d,k,i,b]),P=a.useCallback(r=>{h(r.target.files),r.target.value=""},[h]),D=a.useCallback(()=>{s||N.current?.click()},[s]),T=a.useCallback(r=>{L([]),i(l.filter((o,n)=>n!==r))},[l,i]),$=a.useCallback(r=>{r.preventDefault(),s||x(!0)},[s]),w=a.useCallback(r=>{r.preventDefault(),x(!1)},[]),M=a.useCallback(r=>{r.preventDefault(),x(!1),s||h(r.dataTransfer.files)},[s,h]),V=d===void 0?"":v.formatBytes(d),S=C.map(({file:r,reason:o})=>o==="type"?t.invalidType(r.name):t.tooLarge(r.name,V)),R=l.length>0?e.jsx("ul",{className:"brycks-file-upload__files",children:l.map((r,o)=>e.jsxs("li",{className:"brycks-file-upload__file",children:[e.jsx("span",{className:"brycks-file-upload__file-icon",children:e.jsx(G,{})}),e.jsxs("span",{className:"brycks-file-upload__file-text",children:[e.jsx("span",{className:"brycks-file-upload__file-name",title:r.name,children:r.name}),e.jsx("span",{className:"brycks-file-upload__file-size",children:v.formatBytes(r.size)})]}),e.jsx("button",{type:"button",className:"brycks-file-upload__remove",onClick:()=>T(o),disabled:s,"aria-label":`${t.remove}: ${r.name}`,children:e.jsx(J,{})})]},`${r.name}-${r.size}-${o}`))}):null;return e.jsxs("div",{className:E.cx("brycks-file-upload",`brycks-file-upload--${_}`,`brycks-file-upload--${O}`,q),children:[_==="dropzone"?e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",className:"brycks-file-upload__dropzone",onClick:D,onDragOver:$,onDragLeave:w,onDrop:M,disabled:s,"aria-disabled":s,"aria-invalid":y||void 0,"data-drag-over":j,"data-invalid":y,children:[e.jsx("span",{className:"brycks-file-upload__icon",children:z??e.jsx(B,{})}),e.jsx("span",{className:"brycks-file-upload__prompt",children:j?t.dropPrompt:t.prompt}),u?e.jsx("span",{className:"brycks-file-upload__hint",children:u}):null]}),R]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"brycks-file-upload__compact",onDragOver:$,onDragLeave:w,onDrop:M,children:[e.jsxs("button",{type:"button",className:"brycks-file-upload__trigger",onClick:D,disabled:s,"aria-invalid":y||void 0,"data-drag-over":j,children:[e.jsx(B,{}),t.trigger]}),R??e.jsx("span",{className:"brycks-file-upload__placeholder",children:t.placeholder})]}),u?e.jsx("span",{className:"brycks-file-upload__hint",children:u}):null]}),S.map(r=>e.jsx("span",{className:"brycks-file-upload__error",role:"alert",children:r},r)),m?e.jsx("span",{className:"brycks-file-upload__error",role:"alert",children:m}):null,e.jsx("input",{ref:r=>{N.current=r,typeof p=="function"?p(r):p&&(p.current=r)},id:W,type:"file",accept:f,multiple:k,disabled:s,onChange:P,style:{display:"none"},tabIndex:-1,"data-testid":F})]})});I.displayName="FileUpload";exports.FileUpload=I;
2
+ //# sourceMappingURL=FileUpload.cjs.map