@brycks/core-front 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) 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.js +26 -26
  4. package/dist/components/feedback/Toast/ToastContext.js +3 -3
  5. package/dist/components/feedback.cjs +1 -1
  6. package/dist/components/feedback.js +21 -21
  7. package/dist/components/form/DropZone/DropZone.cjs.map +1 -1
  8. package/dist/components/form/DropZone/DropZone.js.map +1 -1
  9. package/dist/components/form/FileInput/FileInput.cjs.map +1 -1
  10. package/dist/components/form/FileInput/FileInput.js.map +1 -1
  11. package/dist/components/form/FileUpload/FileUpload.cjs +2 -0
  12. package/dist/components/form/FileUpload/FileUpload.cjs.map +1 -0
  13. package/dist/components/form/FileUpload/FileUpload.js +223 -0
  14. package/dist/components/form/FileUpload/FileUpload.js.map +1 -0
  15. package/dist/components/form/FileUpload/fileUpload.utils.cjs +2 -0
  16. package/dist/components/form/FileUpload/fileUpload.utils.cjs.map +1 -0
  17. package/dist/components/form/FileUpload/fileUpload.utils.js +43 -0
  18. package/dist/components/form/FileUpload/fileUpload.utils.js.map +1 -0
  19. package/dist/components/form/FormGroup/FormGroup.cjs +1 -1
  20. package/dist/components/form/FormGroup/FormGroup.js +1 -1
  21. package/dist/components/form/Slider/Slider.cjs +1 -1
  22. package/dist/components/form/Slider/Slider.js +2 -2
  23. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  24. package/dist/components/form/TagInput/TagInput.js +8 -8
  25. package/dist/components/form.cjs +1 -1
  26. package/dist/components/form.js +51 -45
  27. package/dist/components/form.js.map +1 -1
  28. package/dist/components/layout.cjs +1 -1
  29. package/dist/components/layout.js +30 -30
  30. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +1 -1
  31. package/dist/components/navigation/ContextMenu/ContextMenu.js +5 -5
  32. package/dist/components/navigation/Stepper/Stepper.js +4 -4
  33. package/dist/components/navigation/Tabs/Tabs.js +4 -4
  34. package/dist/components/navigation.cjs +1 -1
  35. package/dist/components/navigation.js +22 -22
  36. package/dist/components/typography/Text/Text.cjs +1 -1
  37. package/dist/components/typography/Text/Text.js +1 -1
  38. package/dist/components/utility.cjs +1 -1
  39. package/dist/components/utility.js +28 -28
  40. package/dist/form.d.ts +117 -0
  41. package/dist/index.cjs +1 -1
  42. package/dist/index.d.ts +87 -0
  43. package/dist/index.js +279 -275
  44. package/dist/index.js.map +1 -1
  45. package/dist/styles.css +1 -1
  46. package/package.json +115 -115
@@ -1,5 +1,5 @@
1
1
  import { jsx as M } from "react/jsx-runtime";
2
- import { forwardRef as j, useState as R, useRef as I, useMemo as N, useEffect as $, useCallback as Y } from "react";
2
+ import { forwardRef as j, useState as R, useRef as I, useMemo as N, useCallback as Y, useEffect as $ } from "react";
3
3
  import { cx as B } from "../../../utils/styles.js";
4
4
  function F({
5
5
  items: a,
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./data/Table/Table.cjs"),t=require("./data/List/List.cjs"),i=require("./data/InfoItem/InfoItem.cjs"),l=require("./data/TreeView/TreeView.cjs"),a=require("./data/VirtualList/VirtualList.cjs"),r=require("./data/PieChart/PieChart.cjs");exports.Table=e.Table;exports.TableBody=e.TableBody;exports.TableCaption=e.TableCaption;exports.TableCell=e.TableCell;exports.TableEmpty=e.TableEmpty;exports.TableFoot=e.TableFoot;exports.TableHead=e.TableHead;exports.TableHeader=e.TableHeader;exports.TableRow=e.TableRow;exports.TableSkeleton=e.TableSkeleton;exports.List=t.List;exports.ListDivider=t.ListDivider;exports.ListHeader=t.ListHeader;exports.ListItem=t.ListItem;exports.InfoItem=i.InfoItem;exports.InfoList=i.InfoList;exports.TreeView=l.TreeView;exports.VariableHeightVirtualList=a.VariableHeightVirtualList;exports.VirtualList=a.VirtualList;exports.PieChart=r.PieChart;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./data/InfoItem/InfoItem.cjs"),t=require("./data/List/List.cjs"),l=require("./data/PieChart/PieChart.cjs"),e=require("./data/Table/Table.cjs"),r=require("./data/TreeView/TreeView.cjs"),a=require("./data/VirtualList/VirtualList.cjs");exports.InfoItem=i.InfoItem;exports.InfoList=i.InfoList;exports.List=t.List;exports.ListDivider=t.ListDivider;exports.ListHeader=t.ListHeader;exports.ListItem=t.ListItem;exports.PieChart=l.PieChart;exports.Table=e.Table;exports.TableBody=e.TableBody;exports.TableCaption=e.TableCaption;exports.TableCell=e.TableCell;exports.TableEmpty=e.TableEmpty;exports.TableFoot=e.TableFoot;exports.TableHead=e.TableHead;exports.TableHeader=e.TableHeader;exports.TableRow=e.TableRow;exports.TableSkeleton=e.TableSkeleton;exports.TreeView=r.TreeView;exports.VariableHeightVirtualList=a.VariableHeightVirtualList;exports.VirtualList=a.VirtualList;
2
2
  //# sourceMappingURL=data.cjs.map
@@ -1,29 +1,29 @@
1
- import { Table as o, TableBody as r, TableCaption as a, TableCell as i, TableEmpty as l, TableFoot as b, TableHead as T, TableHeader as m, TableRow as f, TableSkeleton as p } from "./data/Table/Table.js";
2
- import { List as L, ListDivider as x, ListHeader as d, ListItem as n } from "./data/List/List.js";
3
- import { InfoItem as I, InfoList as V } from "./data/InfoItem/InfoItem.js";
4
- import { TreeView as h } from "./data/TreeView/TreeView.js";
5
- import { VariableHeightVirtualList as w, VirtualList as y } from "./data/VirtualList/VirtualList.js";
6
- import { PieChart as k } from "./data/PieChart/PieChart.js";
1
+ import { InfoItem as o, InfoList as r } from "./data/InfoItem/InfoItem.js";
2
+ import { List as i, ListDivider as l, ListHeader as b, ListItem as T } from "./data/List/List.js";
3
+ import { PieChart as f } from "./data/PieChart/PieChart.js";
4
+ import { Table as s, TableBody as L, TableCaption as x, TableCell as d, TableEmpty as n, TableFoot as H, TableHead as I, TableHeader as V, TableRow as C, TableSkeleton as h } from "./data/Table/Table.js";
5
+ import { TreeView as w } from "./data/TreeView/TreeView.js";
6
+ import { VariableHeightVirtualList as g, VirtualList as k } from "./data/VirtualList/VirtualList.js";
7
7
  export {
8
- I as InfoItem,
9
- V as InfoList,
10
- L as List,
11
- x as ListDivider,
12
- d as ListHeader,
13
- n as ListItem,
14
- k as PieChart,
15
- o as Table,
16
- r as TableBody,
17
- a as TableCaption,
18
- i as TableCell,
19
- l as TableEmpty,
20
- b as TableFoot,
21
- T as TableHead,
22
- m as TableHeader,
23
- f as TableRow,
24
- p as TableSkeleton,
25
- h as TreeView,
26
- w as VariableHeightVirtualList,
27
- y as VirtualList
8
+ o as InfoItem,
9
+ r as InfoList,
10
+ i as List,
11
+ l as ListDivider,
12
+ b as ListHeader,
13
+ T as ListItem,
14
+ f as PieChart,
15
+ s as Table,
16
+ L as TableBody,
17
+ x as TableCaption,
18
+ d as TableCell,
19
+ n as TableEmpty,
20
+ H as TableFoot,
21
+ I as TableHead,
22
+ V as TableHeader,
23
+ C as TableRow,
24
+ h as TableSkeleton,
25
+ w as TreeView,
26
+ g as VariableHeightVirtualList,
27
+ k as VirtualList
28
28
  };
29
29
  //# sourceMappingURL=data.js.map
@@ -1,7 +1,7 @@
1
- import { createContext as o, useContext as e } from "react";
2
- const n = o(null);
1
+ import { useContext as o, createContext as e } from "react";
2
+ const n = e(null);
3
3
  function s() {
4
- const t = e(n);
4
+ const t = o(n);
5
5
  if (!t)
6
6
  throw new Error("useToast must be used within a ToastProvider");
7
7
  return t;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./feedback/Modal/Modal.cjs"),e=require("./feedback/Alert/Alert.cjs"),t=require("./feedback/Banner/Banner.cjs"),s=require("./feedback/ConfirmDialog/ConfirmDialog.cjs"),i=require("./feedback/Tooltip/Tooltip.cjs"),r=require("./feedback/Toast/Toast.cjs"),a=require("./feedback/Toast/ToastContext.cjs"),n=require("./feedback/Drawer/Drawer.cjs"),l=require("./feedback/Popover/Popover.cjs"),u=require("./feedback/Progress/Progress.cjs");exports.Modal=o.Modal;exports.Alert=e.Alert;exports.Banner=t.Banner;exports.ConfirmDialog=s.ConfirmDialog;exports.Tooltip=i.Tooltip;exports.Toast=r.Toast;exports.ToastProvider=r.ToastProvider;exports.useToast=a.useToast;exports.Drawer=n.Drawer;exports.Popover=l.Popover;exports.Progress=u.Progress;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./feedback/Alert/Alert.cjs"),e=require("./feedback/Banner/Banner.cjs"),t=require("./feedback/ConfirmDialog/ConfirmDialog.cjs"),s=require("./feedback/Drawer/Drawer.cjs"),i=require("./feedback/Modal/Modal.cjs"),a=require("./feedback/Popover/Popover.cjs"),n=require("./feedback/Progress/Progress.cjs"),r=require("./feedback/Toast/Toast.cjs"),l=require("./feedback/Tooltip/Tooltip.cjs"),u=require("./feedback/Toast/ToastContext.cjs");exports.Alert=o.Alert;exports.Banner=e.Banner;exports.ConfirmDialog=t.ConfirmDialog;exports.Drawer=s.Drawer;exports.Modal=i.Modal;exports.Popover=a.Popover;exports.Progress=n.Progress;exports.Toast=r.Toast;exports.ToastProvider=r.ToastProvider;exports.Tooltip=l.Tooltip;exports.useToast=u.useToast;
2
2
  //# sourceMappingURL=feedback.cjs.map
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileUpload.cjs","sources":["../../../../src/components/form/FileUpload/FileUpload.tsx"],"sourcesContent":["/**\n * FileUpload Component\n *\n * Themed replacement for the native file input, whose entire box — including\n * the \"no file chosen\" text — reacts to clicks and cannot be styled.\n *\n * Two layouts, one visual language:\n * - `dropzone`: a dashed target that also accepts drag-and-drop.\n * - `compact`: a single row where **only the button** opens the file picker.\n *\n * Selected files are always listed with name, size and a remove button, and\n * files refused by `accept`/`maxSize` produce a visible message instead of\n * disappearing silently.\n *\n * Accessibility: the visible control is a real `<button>`, so focus, Enter and\n * Space come from the platform. The native input is hidden and only proxied.\n *\n * @example\n * ```tsx\n * <FileUpload\n * variant=\"compact\"\n * accept=\".pfx,.p12\"\n * files={pfx ? [pfx] : []}\n * onFilesChange={(files) => setPfx(files[0] ?? null)}\n * />\n * ```\n */\n\nimport {\n forwardRef,\n useCallback,\n useRef,\n useState,\n type ChangeEvent,\n type DragEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { formatBytes, selectFiles, type FileRejection } from './fileUpload.utils'\nimport type { FileUploadLabels, FileUploadProps } from './FileUpload.types'\n\nconst defaultLabels: Required<FileUploadLabels> = {\n trigger: 'Choose file',\n placeholder: 'No file selected',\n prompt: 'Click to browse or drag a file here',\n dropPrompt: 'Drop to upload',\n remove: 'Remove file',\n invalidType: (fileName) => `${fileName}: unsupported file type.`,\n tooLarge: (fileName, maxSizeLabel) => `${fileName}: exceeds ${maxSizeLabel}.`,\n}\n\nfunction UploadIcon() {\n return (\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 15V4m0 0L8 8m4-4l4 4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M4 15v2.5A2.5 2.5 0 006.5 20h11a2.5 2.5 0 002.5-2.5V15\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n )\n}\n\nfunction FileIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n 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\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M9 1.5v4h4\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction RemoveIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const FileUpload = forwardRef<HTMLInputElement, FileUploadProps>(\n function FileUpload(\n {\n files,\n onFilesChange,\n variant = 'dropzone',\n size = 'md',\n accept,\n multiple = false,\n maxFiles,\n maxSize,\n hint,\n error,\n isInvalid = false,\n disabled = false,\n icon,\n onReject,\n labels,\n id,\n className,\n testId,\n },\n ref\n ) {\n const inputRef = useRef<HTMLInputElement>(null)\n const [isDragOver, setIsDragOver] = useState(false)\n const [rejections, setRejections] = useState<FileRejection[]>([])\n\n const text = { ...defaultLabels, ...labels }\n const hasError = isInvalid || Boolean(error) || rejections.length > 0\n\n const handleIncoming = useCallback(\n (incoming: FileList | null) => {\n if (!incoming || incoming.length === 0) return\n\n const { accepted, rejected } = selectFiles(Array.from(incoming), {\n accept,\n maxSize,\n multiple,\n maxFiles,\n current: files,\n })\n\n setRejections(rejected)\n if (rejected.length > 0) onReject?.(rejected)\n if (accepted.length > 0 || rejected.length === 0) onFilesChange(accepted)\n },\n [accept, files, maxFiles, maxSize, multiple, onFilesChange, onReject]\n )\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n handleIncoming(event.target.files)\n // Reset so picking the same file twice still fires a change event.\n event.target.value = ''\n },\n [handleIncoming]\n )\n\n const openPicker = useCallback(() => {\n if (!disabled) inputRef.current?.click()\n }, [disabled])\n\n const handleRemove = useCallback(\n (index: number) => {\n setRejections([])\n onFilesChange(files.filter((_, i) => i !== index))\n },\n [files, onFilesChange]\n )\n\n const handleDragOver = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault()\n if (!disabled) setIsDragOver(true)\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((event: DragEvent<HTMLElement>) => {\n event.preventDefault()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLElement>) => {\n event.preventDefault()\n setIsDragOver(false)\n if (!disabled) handleIncoming(event.dataTransfer.files)\n },\n [disabled, handleIncoming]\n )\n\n const maxSizeLabel = maxSize === undefined ? '' : formatBytes(maxSize)\n const rejectionMessages = rejections.map(({ file, reason }) =>\n reason === 'type'\n ? text.invalidType(file.name)\n : text.tooLarge(file.name, maxSizeLabel)\n )\n\n const fileList =\n files.length > 0 ? (\n <ul className=\"brycks-file-upload__files\">\n {files.map((file, index) => (\n <li key={`${file.name}-${file.size}-${index}`} className=\"brycks-file-upload__file\">\n <span className=\"brycks-file-upload__file-icon\">\n <FileIcon />\n </span>\n <span className=\"brycks-file-upload__file-text\">\n <span className=\"brycks-file-upload__file-name\" title={file.name}>\n {file.name}\n </span>\n <span className=\"brycks-file-upload__file-size\">{formatBytes(file.size)}</span>\n </span>\n <button\n type=\"button\"\n className=\"brycks-file-upload__remove\"\n onClick={() => handleRemove(index)}\n disabled={disabled}\n aria-label={`${text.remove}: ${file.name}`}\n >\n <RemoveIcon />\n </button>\n </li>\n ))}\n </ul>\n ) : null\n\n return (\n <div\n className={cx(\n 'brycks-file-upload',\n `brycks-file-upload--${variant}`,\n `brycks-file-upload--${size}`,\n className\n )}\n >\n {variant === 'dropzone' ? (\n <>\n <button\n type=\"button\"\n className=\"brycks-file-upload__dropzone\"\n onClick={openPicker}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n disabled={disabled}\n aria-disabled={disabled}\n aria-invalid={hasError || undefined}\n data-drag-over={isDragOver}\n data-invalid={hasError}\n >\n <span className=\"brycks-file-upload__icon\">{icon ?? <UploadIcon />}</span>\n <span className=\"brycks-file-upload__prompt\">\n {isDragOver ? text.dropPrompt : text.prompt}\n </span>\n {hint ? <span className=\"brycks-file-upload__hint\">{hint}</span> : null}\n </button>\n {fileList}\n </>\n ) : (\n <>\n <div\n className=\"brycks-file-upload__compact\"\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n <button\n type=\"button\"\n className=\"brycks-file-upload__trigger\"\n onClick={openPicker}\n disabled={disabled}\n aria-invalid={hasError || undefined}\n data-drag-over={isDragOver}\n >\n <UploadIcon />\n {text.trigger}\n </button>\n {fileList ?? (\n <span className=\"brycks-file-upload__placeholder\">{text.placeholder}</span>\n )}\n </div>\n {hint ? <span className=\"brycks-file-upload__hint\">{hint}</span> : null}\n </>\n )}\n\n {rejectionMessages.map((message) => (\n <span key={message} className=\"brycks-file-upload__error\" role=\"alert\">\n {message}\n </span>\n ))}\n {error ? (\n <span className=\"brycks-file-upload__error\" role=\"alert\">\n {error}\n </span>\n ) : null}\n\n <input\n ref={(node) => {\n inputRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n id={id}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n tabIndex={-1}\n data-testid={testId}\n />\n </div>\n )\n }\n)\n\nFileUpload.displayName = 'FileUpload'\n"],"names":["defaultLabels","fileName","maxSizeLabel","UploadIcon","jsxs","jsx","FileIcon","RemoveIcon","FileUpload","forwardRef","files","onFilesChange","variant","size","accept","multiple","maxFiles","maxSize","hint","error","isInvalid","disabled","icon","onReject","labels","id","className","testId","ref","inputRef","useRef","isDragOver","setIsDragOver","useState","rejections","setRejections","text","hasError","handleIncoming","useCallback","incoming","accepted","rejected","selectFiles","handleChange","event","openPicker","handleRemove","index","_","i","handleDragOver","handleDragLeave","handleDrop","formatBytes","rejectionMessages","file","reason","fileList","cx","Fragment","message","node"],"mappings":"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"}