@spark-ui/components 11.4.0 → 11.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/docgen.json CHANGED
@@ -30628,6 +30628,44 @@
30628
30628
  "name": "number"
30629
30629
  }
30630
30630
  },
30631
+ "deleteButtonAriaLabel": {
30632
+ "defaultValue": null,
30633
+ "description": "Accessible label for the delete button",
30634
+ "name": "deleteButtonAriaLabel",
30635
+ "parent": {
30636
+ "fileName": "src/file-upload/FileUploadAcceptedFile.tsx",
30637
+ "name": "FileUploadAcceptedFileProps"
30638
+ },
30639
+ "declarations": [
30640
+ {
30641
+ "fileName": "src/file-upload/FileUploadAcceptedFile.tsx",
30642
+ "name": "FileUploadAcceptedFileProps"
30643
+ }
30644
+ ],
30645
+ "required": true,
30646
+ "type": {
30647
+ "name": "string"
30648
+ }
30649
+ },
30650
+ "progressAriaLabel": {
30651
+ "defaultValue": null,
30652
+ "description": "Accessible label for the progress bar. Required when uploadProgress is provided.",
30653
+ "name": "progressAriaLabel",
30654
+ "parent": {
30655
+ "fileName": "src/file-upload/FileUploadAcceptedFile.tsx",
30656
+ "name": "FileUploadAcceptedFileProps"
30657
+ },
30658
+ "declarations": [
30659
+ {
30660
+ "fileName": "src/file-upload/FileUploadAcceptedFile.tsx",
30661
+ "name": "FileUploadAcceptedFileProps"
30662
+ }
30663
+ ],
30664
+ "required": false,
30665
+ "type": {
30666
+ "name": "string"
30667
+ }
30668
+ },
30631
30669
  "className": {
30632
30670
  "defaultValue": null,
30633
30671
  "description": "",
@@ -31402,6 +31440,25 @@
31402
31440
  "name": "(error: FileUploadFileError) => string"
31403
31441
  }
31404
31442
  },
31443
+ "deleteButtonAriaLabel": {
31444
+ "defaultValue": null,
31445
+ "description": "Accessible label for the delete button",
31446
+ "name": "deleteButtonAriaLabel",
31447
+ "parent": {
31448
+ "fileName": "src/file-upload/FileUploadRejectedFile.tsx",
31449
+ "name": "FileUploadRejectedFileProps"
31450
+ },
31451
+ "declarations": [
31452
+ {
31453
+ "fileName": "src/file-upload/FileUploadRejectedFile.tsx",
31454
+ "name": "FileUploadRejectedFileProps"
31455
+ }
31456
+ ],
31457
+ "required": true,
31458
+ "type": {
31459
+ "name": "string"
31460
+ }
31461
+ },
31405
31462
  "className": {
31406
31463
  "defaultValue": null,
31407
31464
  "description": "",
@@ -110,10 +110,18 @@ interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {
110
110
  * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.
111
111
  */
112
112
  uploadProgress?: number;
113
+ /**
114
+ * Accessible label for the delete button
115
+ */
116
+ deleteButtonAriaLabel: string;
117
+ /**
118
+ * Accessible label for the progress bar. Required when uploadProgress is provided.
119
+ */
120
+ progressAriaLabel?: string;
113
121
  className?: string;
114
122
  }
115
123
  declare const AcceptedFile: {
116
- ({ asChild: _asChild, className, file, fileIndex, uploadProgress, ...props }: FileUploadAcceptedFileProps): react_jsx_runtime.JSX.Element;
124
+ ({ asChild: _asChild, className, file, fileIndex, uploadProgress, deleteButtonAriaLabel, progressAriaLabel, ...props }: FileUploadAcceptedFileProps): react_jsx_runtime.JSX.Element;
117
125
  displayName: string;
118
126
  };
119
127
 
@@ -237,10 +245,14 @@ interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {
237
245
  * @returns The error message to display
238
246
  */
239
247
  renderError: (error: FileUploadFileError) => string;
248
+ /**
249
+ * Accessible label for the delete button
250
+ */
251
+ deleteButtonAriaLabel: string;
240
252
  className?: string;
241
253
  }
242
254
  declare const RejectedFile: {
243
- ({ asChild: _asChild, className, rejectedFile, rejectedFileIndex, renderError, ...props }: FileUploadRejectedFileProps): react_jsx_runtime.JSX.Element;
255
+ ({ asChild: _asChild, className, rejectedFile, rejectedFileIndex, renderError, deleteButtonAriaLabel, ...props }: FileUploadRejectedFileProps): react_jsx_runtime.JSX.Element;
244
256
  displayName: string;
245
257
  };
246
258
 
@@ -110,10 +110,18 @@ interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {
110
110
  * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.
111
111
  */
112
112
  uploadProgress?: number;
113
+ /**
114
+ * Accessible label for the delete button
115
+ */
116
+ deleteButtonAriaLabel: string;
117
+ /**
118
+ * Accessible label for the progress bar. Required when uploadProgress is provided.
119
+ */
120
+ progressAriaLabel?: string;
113
121
  className?: string;
114
122
  }
115
123
  declare const AcceptedFile: {
116
- ({ asChild: _asChild, className, file, fileIndex, uploadProgress, ...props }: FileUploadAcceptedFileProps): react_jsx_runtime.JSX.Element;
124
+ ({ asChild: _asChild, className, file, fileIndex, uploadProgress, deleteButtonAriaLabel, progressAriaLabel, ...props }: FileUploadAcceptedFileProps): react_jsx_runtime.JSX.Element;
117
125
  displayName: string;
118
126
  };
119
127
 
@@ -237,10 +245,14 @@ interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {
237
245
  * @returns The error message to display
238
246
  */
239
247
  renderError: (error: FileUploadFileError) => string;
248
+ /**
249
+ * Accessible label for the delete button
250
+ */
251
+ deleteButtonAriaLabel: string;
240
252
  className?: string;
241
253
  }
242
254
  declare const RejectedFile: {
243
- ({ asChild: _asChild, className, rejectedFile, rejectedFileIndex, renderError, ...props }: FileUploadRejectedFileProps): react_jsx_runtime.JSX.Element;
255
+ ({ asChild: _asChild, className, rejectedFile, rejectedFileIndex, renderError, deleteButtonAriaLabel, ...props }: FileUploadRejectedFileProps): react_jsx_runtime.JSX.Element;
244
256
  displayName: string;
245
257
  };
246
258
 
@@ -1708,6 +1708,8 @@ var AcceptedFile = ({
1708
1708
  file,
1709
1709
  fileIndex,
1710
1710
  uploadProgress,
1711
+ deleteButtonAriaLabel,
1712
+ progressAriaLabel,
1711
1713
  ...props
1712
1714
  }) => {
1713
1715
  const { locale } = useFileUploadContext();
@@ -1718,16 +1720,9 @@ var AcceptedFile = ({
1718
1720
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ItemFileName, { children: file.name }),
1719
1721
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ItemSizeText, { className: "opacity-dim-1", children: formatFileSize(file.size, locale) })
1720
1722
  ] }),
1721
- uploadProgress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "mt-md", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1722
- Progress2,
1723
- {
1724
- value: uploadProgress,
1725
- max: 100,
1726
- "aria-label": `Upload progress: ${uploadProgress}%`
1727
- }
1728
- ) })
1723
+ uploadProgress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "mt-md", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Progress2, { value: uploadProgress, max: 100, "aria-label": progressAriaLabel }) })
1729
1724
  ] }),
1730
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ItemDeleteTrigger, { "aria-label": "Delete file", fileIndex })
1725
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ItemDeleteTrigger, { "aria-label": deleteButtonAriaLabel, fileIndex })
1731
1726
  ] });
1732
1727
  };
1733
1728
  AcceptedFile.displayName = "FileUpload.AcceptedFile";
@@ -1950,6 +1945,7 @@ var RejectedFile = ({
1950
1945
  rejectedFile,
1951
1946
  rejectedFileIndex,
1952
1947
  renderError,
1948
+ deleteButtonAriaLabel,
1953
1949
  ...props
1954
1950
  }) => {
1955
1951
  const { locale } = useFileUploadContext();
@@ -1965,7 +1961,7 @@ var RejectedFile = ({
1965
1961
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1966
1962
  RejectedFileDeleteTrigger,
1967
1963
  {
1968
- "aria-label": `Remove ${rejectedFile.file.name} error`,
1964
+ "aria-label": deleteButtonAriaLabel,
1969
1965
  rejectedFileIndex
1970
1966
  }
1971
1967
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/file-upload/index.ts","../../src/file-upload/FileUpload.tsx","../../src/file-upload/utils.ts","../../src/icon/Icon.tsx","../../src/slot/Slot.tsx","../../src/visually-hidden/VisuallyHidden.tsx","../../src/icon/Icon.styles.tsx","../../src/progress/Progress.tsx","../../src/progress/ProgressBar.styles.ts","../../src/progress/ProgressContext.tsx","../../src/progress/ProgressIndicator.tsx","../../src/progress/ProgressIndicator.styles.ts","../../src/progress/ProgressBar.tsx","../../src/progress/ProgressLabel.tsx","../../src/progress/index.ts","../../src/file-upload/FileUploadItem.tsx","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/button/Button.tsx","../../src/spinner/Spinner.styles.tsx","../../src/spinner/Spinner.tsx","../../src/button/Button.styles.tsx","../../src/button/variants/filled.ts","../../src/button/variants/ghost.ts","../../src/button/variants/outlined.ts","../../src/button/variants/tinted.ts","../../src/button/variants/contrast.ts","../../src/icon-button/IconButton.styles.tsx","../../src/icon-button/IconButton.tsx","../../src/file-upload/FileUploadItemFileName.tsx","../../src/file-upload/FileUploadItemSizeText.tsx","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx"],"sourcesContent":["import { FileUpload as Root, type FileUploadFileError, type RejectedFile } from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { Dropzone } from './FileUploadDropzone'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type { RejectedFile, FileUploadFileError }\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n Item: typeof Item\n ItemFileName: typeof ItemFileName\n ItemSizeText: typeof ItemSizeText\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n Trigger,\n Dropzone,\n Context,\n Item,\n ItemFileName,\n ItemSizeText,\n ItemDeleteTrigger,\n PreviewImage,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItem.displayName = 'FileUpload.Item'\nItemFileName.displayName = 'FileUpload.ItemFileName'\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { createContext, ReactNode, Ref, useContext, useRef, useState } from 'react'\n\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are selected\n */\n onFilesChange?: (files: File[]) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Callback when the maximum number of files is reached\n * @param maxFiles - The maximum number of files allowed\n * @param rejectedCount - The number of files that were rejected\n */\n onMaxFilesReached?: (maxFiles: number, rejectedCount: number) => void\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * Callback when a file size validation error occurs\n * @param file - The file that failed validation\n * @param error - The error message\n */\n onFileSizeError?: (file: File, error: string) => void\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport type FileUploadFileError =\n | 'TOO_MANY_FILES'\n | 'FILE_INVALID_TYPE'\n | 'FILE_TOO_LARGE'\n | 'FILE_TOO_SMALL'\n | 'FILE_INVALID'\n | 'FILE_EXISTS'\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n} | null>(null)\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFilesChange,\n multiple = true,\n accept,\n maxFiles,\n onMaxFilesReached,\n maxFileSize,\n minFileSize,\n onFileSizeError,\n disabled = false,\n readOnly = false,\n locale,\n}: FileUploadProps) => {\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n const [filesState, setFilesState, ,] = useCombinedState(\n controlledValue,\n defaultValue,\n onFilesChange\n )\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n\n // Call onFileSizeError callback if provided\n if (onFileSizeError) {\n onFileSizeError(file, error)\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n // Check maxFiles limit FIRST for all files (even if they will be rejected by other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, mark all new files with TOO_MANY_FILES error\n newFiles.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n }\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, 'FILE_INVALID_TYPE')\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, 'FILE_TOO_LARGE')\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, 'FILE_TOO_SMALL')\n } else {\n addRejectedFile(file, 'FILE_INVALID')\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n // This must be done AFTER size validation but BEFORE maxFiles check\n const seenFiles = new Map<string, File>()\n const duplicateFiles: File[] = []\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Track files rejected by maxFiles limit (only for files that passed other validations)\n // Note: We already checked maxFiles at the beginning for ALL files to allow multiple error codes\n // This second check is to prevent adding files when we're at the limit\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, reject all new files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n if (maxFiles !== undefined && updated.length < maxFiles) {\n setRejectedFiles(prevRejected =>\n prevRejected.filter(rejected => !rejected.errors.includes('TOO_MANY_FILES'))\n )\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n deleteButtonRefs.current = []\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale: defaultLocale,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id=\"image_uploads\"\n multiple={multiple}\n name=\"image_uploads\"\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n","import { Children, cloneElement, ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { iconStyles, IconVariantsProps } from './Icon.styles'\n\nexport interface IconProps extends IconVariantsProps, ComponentPropsWithoutRef<'svg'> {\n /**\n * The svg icon that will be wrapped\n */\n children: ReactNode\n /**\n * The accessible label for the icon. This label will be visually hidden but announced to screen\n * reader users, similar to `alt` text for `img` tags.\n */\n label?: string\n}\n\nexport const Icon = ({\n label,\n className,\n size = 'current',\n intent = 'current',\n children,\n ...others\n}: IconProps) => {\n const child = Children.only(children)\n\n return (\n <>\n {cloneElement(child as ReactElement<Record<string, any>>, {\n className: iconStyles({ className, size, intent }),\n 'data-spark-component': 'icon',\n 'aria-hidden': 'true',\n focusable: 'false',\n ...others,\n })}\n\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </>\n )\n}\n\nIcon.displayName = 'Icon'\n","import { Slot as RadixSlot } from 'radix-ui'\nimport {\n cloneElement,\n HTMLAttributes,\n isValidElement,\n PropsWithChildren,\n ReactNode,\n Ref,\n} from 'react'\n\nexport const Slottable: typeof RadixSlot.Slottable = RadixSlot.Slottable\n\nexport type SlotProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n ref?: Ref<HTMLElement>\n}\n\nexport const Slot = ({ ref, ...props }: SlotProps) => {\n return <RadixSlot.Root ref={ref} {...props} />\n}\n\n/**\n * When using Radix `Slot` component, it will consider its first child to merge its props with.\n * In some cases, you might need to wrap the top child with additional markup without breaking this behaviour.\n */\nexport const wrapPolymorphicSlot = (\n asChild: boolean | undefined,\n children: ReactNode,\n callback: (children: ReactNode) => ReactNode\n) => {\n if (!asChild) return callback(children) // If polymorphic behaviour is not used, we keep the original children\n\n return isValidElement(children)\n ? cloneElement(\n children,\n undefined,\n callback((children.props as { children: ReactNode }).children)\n )\n : null\n}\n","import { HTMLAttributes, PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\n\nexport type VisuallyHiddenProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const VisuallyHidden = ({ asChild = false, ref, ...props }: VisuallyHiddenProps) => {\n const Component = asChild ? Slot : 'span'\n\n return (\n <Component\n {...props}\n ref={ref}\n style={{\n // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss\n position: 'absolute',\n border: 0,\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n wordWrap: 'normal',\n ...props.style,\n }}\n />\n )\n}\n\nVisuallyHidden.displayName = 'VisuallyHidden'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nexport const iconStyles = cva(['fill-current shrink-0'], {\n variants: {\n /**\n * Color scheme of the icon.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['text-current'],\n main: ['text-main'],\n support: ['text-support'],\n accent: ['text-accent'],\n basic: ['text-basic'],\n success: ['text-success'],\n alert: ['text-alert'],\n error: ['text-error'],\n info: ['text-info'],\n neutral: ['text-neutral'],\n }),\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['current', 'sm', 'md', 'lg', 'xl']>({\n current: ['u-current-font-size'],\n sm: ['w-sz-16', 'h-sz-16'],\n md: ['w-sz-24', 'h-sz-24'],\n lg: ['w-sz-32', 'h-sz-32'],\n xl: ['w-sz-40', 'h-sz-40'],\n }),\n },\n})\n\nexport type IconVariantsProps = VariantProps<typeof iconStyles>\n","import { cx } from 'class-variance-authority'\nimport { Progress as RadixProgress } from 'radix-ui'\nimport { PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressContext } from './ProgressContext'\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressProps\n extends RadixProgress.ProgressProps,\n Pick<ProgressIndicatorStylesProps, 'intent'> {\n shape?: 'square' | 'rounded'\n isIndeterminate?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\nexport const Progress = ({\n className,\n value: valueProp,\n max = 100,\n shape = 'square',\n intent = 'basic',\n isIndeterminate = false,\n children = <ProgressBar />,\n ref,\n ...others\n}: PropsWithChildren<ProgressProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const value = useMemo(() => {\n return { value: valueProp ?? 0, max, intent, shape, isIndeterminate, onLabelId: setLabelId }\n }, [max, valueProp, intent, shape, isIndeterminate, setLabelId])\n\n return (\n <ProgressContext.Provider data-spark-component=\"progress\" value={value}>\n <RadixProgress.Progress\n data-spark-component=\"progress\"\n ref={ref}\n className={cx('gap-sm focus-visible:u-outline flex flex-col', className)}\n value={valueProp}\n aria-labelledby={labelId}\n max={max}\n tabIndex={-1}\n {...others}\n >\n {children}\n </RadixProgress.Progress>\n </ProgressContext.Provider>\n )\n}\n\nProgress.displayName = 'Progress'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressBarStyles = cva(\n ['relative', 'h-sz-4 w-full', 'transform-gpu overflow-hidden', 'bg-on-background/dim-4'],\n {\n variants: {\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n },\n }\n)\n\nexport type ProgressBarStylesProps = VariantProps<typeof progressBarStyles>\n","import { createContext, useContext } from 'react'\n\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressContextValue {\n value: number\n max: number\n isIndeterminate: boolean\n shape: 'square' | 'rounded'\n intent: ProgressIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n}\n\nexport const ProgressContext = createContext<ProgressContextValue | null>(null)\n\nexport const ID_PREFIX = ':progress'\n\nexport const useProgress = () => {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error('useProgress must be used within a Progress provider')\n }\n\n return context\n}\n","import { Progress as RadixProgress } from 'radix-ui'\nimport { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { useProgress } from './ProgressContext'\nimport { progressIndicatorStyles } from './ProgressIndicator.styles'\n\nexport type ProgressIndicatorProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressIndicator = ({\n className,\n style,\n ref,\n ...others\n}: PropsWithChildren<ProgressIndicatorProps>) => {\n const { value, max, intent, shape, isIndeterminate } = useProgress()\n const x = ((max - value) / max) * 100\n\n return (\n <RadixProgress.ProgressIndicator\n data-spark-component=\"progress-indicator\"\n className={progressIndicatorStyles({ className, intent, shape, isIndeterminate })}\n style={{ ...style, ...(!isIndeterminate && { transform: `translateX(-${x}%)` }) }}\n ref={ref}\n {...others}\n />\n )\n}\n\nProgressIndicator.displayName = 'Progress.Indicator'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressIndicatorStyles = cva(['h-full w-full', 'transition-transform duration-400'], {\n variants: {\n /**\n * Color scheme of the progress component.\n */\n intent: {\n basic: ['bg-basic'],\n main: ['bg-main'],\n support: ['bg-support'],\n accent: ['bg-accent'],\n success: ['bg-success'],\n alert: ['bg-alert'],\n danger: ['bg-error'],\n info: ['bg-info'],\n neutral: ['bg-neutral'],\n },\n /**\n * Shape of the progress component.\n */\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n /**\n * Sets if the progress value is not determinated.\n */\n isIndeterminate: {\n true: ['absolute', '-translate-x-1/2', 'animate-standalone-indeterminate-bar'],\n false: [],\n },\n },\n})\n\nexport type ProgressIndicatorStylesProps = VariantProps<typeof progressIndicatorStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { progressBarStyles } from './ProgressBar.styles'\nimport { useProgress } from './ProgressContext'\nimport { ProgressIndicator } from './ProgressIndicator'\n\nexport type ProgressBarProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressBar = ({\n className,\n children = <ProgressIndicator />,\n ref,\n ...others\n}: PropsWithChildren<ProgressBarProps>) => {\n const { shape } = useProgress()\n\n return (\n <div\n data-spark-component=\"progress-bar\"\n className={progressBarStyles({ className, shape })}\n ref={ref}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nProgressBar.displayName = 'Progress.Bar'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { ComponentPropsWithRef, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useProgress } from './ProgressContext'\n\nexport type ProgressLabelProps = ComponentPropsWithRef<'span'>\n\nexport const ProgressLabel = ({\n id: idProp,\n children,\n ref: forwardedRef,\n ...others\n}: ProgressLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId } = useProgress()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <span\n data-spark-component=\"progress-label\"\n id={id}\n className=\"text-body-2 text-on-surface\"\n ref={ref}\n {...others}\n >\n {children}\n </span>\n )\n}\n\nProgressLabel.displayName = 'Progress.Label'\n","import { Progress as Root } from './Progress'\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressIndicator } from './ProgressIndicator'\nimport { ProgressLabel } from './ProgressLabel'\n\nexport const Progress: typeof Root & {\n Label: typeof ProgressLabel\n Bar: typeof ProgressBar\n Indicator: typeof ProgressIndicator\n} = Object.assign(Root, {\n Label: ProgressLabel,\n Bar: ProgressBar,\n Indicator: ProgressIndicator,\n})\n\nProgress.displayName = 'Progress'\nProgressBar.displayName = 'Progress.Bar'\nProgressIndicator.displayName = 'Progress.Indicator'\nProgressLabel.displayName = 'Progress.Label'\n\nexport { type ProgressProps } from './Progress'\nexport { type ProgressBarProps } from './ProgressBar'\nexport { type ProgressLabelProps } from './ProgressLabel'\nexport { type ProgressIndicatorProps } from './ProgressIndicator'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n children: ReactNode\n className?: string\n}\n\nexport const Item = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemProps) => {\n return (\n <li\n data-spark-component=\"file-upload-item\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n {children}\n </li>\n )\n}\n\nItem.displayName = 'FileUpload.Item'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the file to delete\n */\n fileIndex: number\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n fileIndex,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, focus on trigger or dropzone\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n }, 0)\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, type DOMAttributes, Ref, useMemo } from 'react'\n\nimport { Slot, wrapPolymorphicSlot } from '../slot'\nimport { Spinner, type SpinnerProps } from '../spinner'\nimport { buttonStyles, type ButtonStylesProps } from './Button.styles'\n\nexport interface ButtonProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'disabled'>,\n ButtonStylesProps {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild?: boolean\n /**\n * Display a spinner to indicate to the user that the button is loading something after they interacted with it.\n */\n isLoading?: boolean\n /**\n * If your loading state should only display a spinner, it's better to specify a label for it (a11y).\n */\n loadingLabel?: string\n /**\n * If your loading state should also display a label, you can use this prop instead of `loadingLabel`.\n * **Please note that using this can result in layout shifting when the Button goes from loading state to normal state.**\n */\n loadingText?: string\n ref?: Ref<HTMLButtonElement>\n}\n\ntype DOMAttributesEventHandler = keyof Omit<\n DOMAttributes<HTMLButtonElement>,\n 'children' | 'dangerouslySetInnerHTML'\n>\n\nconst blockedEventHandlers: DOMAttributesEventHandler[] = [\n 'onClick',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onKeyDown',\n 'onKeyPress',\n 'onKeyUp',\n 'onSubmit',\n]\n\nexport const Button = ({\n children,\n design = 'filled',\n disabled = false,\n intent = 'main',\n isLoading = false,\n loadingLabel,\n loadingText,\n shape = 'rounded',\n size = 'md',\n asChild,\n className,\n underline = false,\n ref,\n ...others\n}: ButtonProps) => {\n const Component = asChild ? Slot : 'button'\n\n const shouldNotInteract = !!disabled || isLoading\n\n const disabledEventHandlers = useMemo(() => {\n const result: Partial<Record<DOMAttributesEventHandler, () => void>> = {}\n\n if (shouldNotInteract) {\n blockedEventHandlers.forEach(eventHandler => (result[eventHandler] = undefined))\n }\n\n return result\n }, [shouldNotInteract])\n\n const spinnerProps = {\n size: 'current' as SpinnerProps['size'],\n className: loadingText ? 'inline-block' : 'absolute',\n ...(loadingLabel && { 'aria-label': loadingLabel }),\n }\n\n return (\n <Component\n data-spark-component=\"button\"\n {...(Component === 'button' && { type: 'button' })}\n ref={ref}\n className={buttonStyles({\n className,\n design,\n disabled: shouldNotInteract,\n intent,\n shape,\n size,\n underline,\n })}\n disabled={!!disabled}\n aria-busy={isLoading}\n aria-live={isLoading ? 'assertive' : 'off'}\n {...others}\n {...disabledEventHandlers}\n >\n {wrapPolymorphicSlot(asChild, children, slotted =>\n isLoading ? (\n <>\n <Spinner {...spinnerProps} />\n {loadingText && loadingText}\n\n <div\n aria-hidden\n className={cx('gap-md', loadingText ? 'hidden' : 'inline-flex opacity-0')}\n >\n {slotted}\n </div>\n </>\n ) : (\n slotted\n )\n )}\n </Component>\n )\n}\n\nButton.displayName = 'Button'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nconst defaultVariants = {\n intent: 'current',\n size: 'current',\n isBackgroundVisible: false,\n} as const\n\nexport const spinnerStyles = cva(\n ['inline-block', 'border-solid', 'rounded-full', 'border-md', 'animate-spin'],\n {\n variants: {\n /**\n * Use `size` prop to set the size of the spinner. If you want to set the full size for the spinner, don't forget to add a wrapping container with its own size.\n */\n size: {\n current: ['u-current-font-size'],\n sm: ['w-sz-20', 'h-sz-20'],\n md: ['w-sz-28', 'h-sz-28'],\n full: ['w-full', 'h-full'],\n },\n /**\n * Color scheme of the spinner.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['border-current'],\n main: ['border-main'],\n support: ['border-support'],\n accent: ['border-accent'],\n basic: ['border-basic'],\n success: ['border-success'],\n alert: ['border-alert'],\n error: ['border-error'],\n info: ['border-info'],\n neutral: ['border-neutral'],\n }),\n /**\n * Size of the button.\n */\n isBackgroundVisible: {\n true: ['border-b-neutral-container', 'border-l-neutral-container'],\n false: ['border-b-transparent', 'border-l-transparent'],\n },\n },\n defaultVariants,\n }\n)\n\nexport type SpinnerStylesProps = VariantProps<typeof spinnerStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { spinnerStyles, SpinnerStylesProps } from './Spinner.styles'\n\nexport interface SpinnerProps extends ComponentPropsWithRef<'div'>, SpinnerStylesProps {\n /**\n * Use `label` prop for accessibility, it is important to add a fallback loading text. This text will be visible to screen readers.\n */\n label?: string\n}\n\nexport const Spinner = ({\n className,\n size = 'current',\n intent = 'current',\n label,\n isBackgroundVisible,\n ref,\n ...others\n}: PropsWithChildren<SpinnerProps>) => {\n return (\n <span\n role=\"status\"\n data-spark-component=\"spinner\"\n ref={ref}\n className={spinnerStyles({ className, size, intent, isBackgroundVisible })}\n {...others}\n >\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </span>\n )\n}\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nimport {\n contrastVariants,\n filledVariants,\n ghostVariants,\n outlinedVariants,\n tintedVariants,\n} from './variants'\n\nexport const buttonStyles = cva(\n [\n 'u-shadow-border-transition',\n 'box-border inline-flex items-center justify-center gap-md whitespace-nowrap',\n 'default:px-lg',\n 'text-body-1 font-bold',\n 'focus-visible:u-outline',\n ],\n {\n variants: {\n /**\n * Main style of the button.\n *\n * - `filled`: Button will be plain.\n *\n * - `outlined`: Button will be transparent with an outline.\n *\n * - `tinted`: Button will be filled but using a lighter color scheme.\n *\n * - `ghost`: Button will look like a link. No borders, plain text.\n *\n * - `contrast`: Button will be surface filled. No borders, plain text.\n *\n */\n design: makeVariants<'design', ['filled', 'outlined', 'tinted', 'ghost', 'contrast']>({\n filled: [],\n outlined: ['bg-transparent', 'border-sm', 'border-current'],\n tinted: [],\n ghost: ['default:-mx-md px-md hover:bg-main/dim-5'],\n contrast: [],\n }),\n underline: {\n true: ['underline'],\n },\n /**\n * Color scheme of the button.\n */\n intent: makeVariants<\n 'intent',\n [\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'danger',\n 'info',\n 'neutral',\n 'surface',\n 'surfaceInverse',\n ]\n >({\n main: [],\n support: [],\n accent: [],\n basic: [],\n success: [],\n alert: [],\n danger: [],\n info: [],\n neutral: [],\n surface: [],\n surfaceInverse: [],\n }),\n /**\n * Size of the button.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['min-w-sz-32', 'h-sz-32'],\n md: ['min-w-sz-44', 'h-sz-44'],\n lg: ['min-w-sz-56', 'h-sz-56'],\n }),\n /**\n * Shape of the button.\n */\n shape: makeVariants<'shape', ['rounded', 'square', 'pill']>({\n rounded: ['rounded-lg'],\n square: ['rounded-0'],\n pill: ['rounded-full'],\n }),\n /**\n * Disable the button, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['cursor-not-allowed', 'opacity-dim-3'],\n false: ['cursor-pointer'],\n },\n },\n compoundVariants: [\n ...filledVariants,\n ...outlinedVariants,\n ...tintedVariants,\n ...ghostVariants,\n ...contrastVariants,\n ],\n defaultVariants: {\n design: 'filled',\n intent: 'main',\n size: 'md',\n shape: 'rounded',\n },\n }\n)\n\nexport type ButtonStylesProps = VariantProps<typeof buttonStyles>\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const filledVariants = [\n // Main\n {\n intent: 'main',\n design: 'filled',\n class: tw([\n 'bg-main',\n 'text-on-main',\n 'hover:bg-main-hovered',\n 'enabled:active:bg-main-hovered',\n 'focus-visible:bg-main-hovered',\n ]),\n },\n // Support\n {\n intent: 'support',\n design: 'filled',\n class: tw([\n 'bg-support',\n 'text-on-support',\n 'hover:bg-support-hovered',\n 'enabled:active:bg-support-hovered',\n 'focus-visible:bg-support-hovered',\n ]),\n },\n // Accent\n {\n intent: 'accent',\n design: 'filled',\n class: tw([\n 'bg-accent',\n 'text-on-accent',\n 'hover:bg-accent-hovered',\n 'enabled:active:bg-accent-hovered',\n 'focus-visible:bg-accent-hovered',\n ]),\n },\n // Basic\n {\n intent: 'basic',\n design: 'filled',\n class: tw([\n 'bg-basic',\n 'text-on-basic',\n 'hover:bg-basic-hovered',\n 'enabled:active:bg-basic-hovered',\n 'focus-visible:bg-basic-hovered',\n ]),\n },\n // Success\n {\n intent: 'success',\n design: 'filled',\n class: tw([\n 'bg-success',\n 'text-on-success',\n 'hover:bg-success-hovered',\n 'enabled:active:bg-success-hovered',\n 'focus-visible:bg-success-hovered',\n ]),\n },\n // Alert\n {\n intent: 'alert',\n design: 'filled',\n class: tw([\n 'bg-alert',\n 'text-on-alert',\n 'hover:bg-alert-hovered',\n 'enabled:active:bg-alert-hovered',\n 'focus-visible:bg-alert-hovered',\n ]),\n },\n // Danger\n {\n intent: 'danger',\n design: 'filled',\n class: tw([\n 'text-on-error bg-error',\n 'hover:bg-error-hovered enabled:active:bg-error-hovered',\n 'focus-visible:bg-error-hovered',\n ]),\n },\n // Info\n {\n intent: 'info',\n design: 'filled',\n class: tw([\n 'text-on-error bg-info',\n 'hover:bg-info-hovered enabled:active:bg-info-hovered',\n 'focus-visible:bg-info-hovered',\n ]),\n },\n // Neutral\n {\n intent: 'neutral',\n design: 'filled',\n class: tw([\n 'bg-neutral',\n 'text-on-neutral',\n 'hover:bg-neutral-hovered',\n 'enabled:active:bg-neutral-hovered',\n 'focus-visible:bg-neutral-hovered',\n ]),\n },\n // Surface\n {\n intent: 'surface',\n design: 'filled',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'filled',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const ghostVariants = [\n {\n intent: 'main',\n design: 'ghost',\n class: tw([\n 'text-on-main-container',\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n ]),\n },\n {\n intent: 'support',\n design: 'ghost',\n class: tw([\n 'text-on-support-container',\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n ]),\n },\n {\n intent: 'accent',\n design: 'ghost',\n class: tw([\n 'text-on-accent-container',\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n ]),\n },\n {\n intent: 'basic',\n design: 'ghost',\n class: tw([\n 'text-on-basic-container',\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n ]),\n },\n {\n intent: 'success',\n design: 'ghost',\n class: tw([\n 'text-on-success-container',\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n ]),\n },\n {\n intent: 'alert',\n design: 'ghost',\n class: tw([\n 'text-on-alert-container',\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n ]),\n },\n {\n intent: 'danger',\n design: 'ghost',\n class: tw([\n 'text-on-error-container',\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n ]),\n },\n {\n intent: 'info',\n design: 'ghost',\n class: tw([\n 'text-on-info-container',\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n ]),\n },\n {\n intent: 'neutral',\n design: 'ghost',\n class: tw([\n 'text-on-neutral-container',\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n ]),\n },\n {\n intent: 'surface',\n design: 'ghost',\n class: tw([\n 'text-surface',\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'ghost',\n class: tw([\n 'text-surface-inverse',\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const outlinedVariants = [\n {\n intent: 'main',\n design: 'outlined',\n class: tw([\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n 'text-main',\n ]),\n },\n {\n intent: 'support',\n design: 'outlined',\n class: tw([\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n 'text-support',\n ]),\n },\n {\n intent: 'accent',\n design: 'outlined',\n class: tw([\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n 'text-accent',\n ]),\n },\n {\n intent: 'basic',\n design: 'outlined',\n class: tw([\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n 'text-basic',\n ]),\n },\n {\n intent: 'success',\n design: 'outlined',\n class: tw([\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n 'text-success',\n ]),\n },\n {\n intent: 'alert',\n design: 'outlined',\n class: tw([\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n 'text-alert',\n ]),\n },\n {\n intent: 'danger',\n design: 'outlined',\n class: tw([\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n 'text-error',\n ]),\n },\n {\n intent: 'info',\n design: 'outlined',\n class: tw([\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n 'text-info',\n ]),\n },\n {\n intent: 'neutral',\n design: 'outlined',\n class: tw([\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n 'text-neutral',\n ]),\n },\n {\n intent: 'surface',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n 'text-surface',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n 'text-surface-inverse',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const tintedVariants = [\n {\n intent: 'main',\n design: 'tinted',\n class: tw([\n 'bg-main-container',\n 'text-on-main-container',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'tinted',\n class: tw([\n 'bg-support-container',\n 'text-on-support-container',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'tinted',\n class: tw([\n 'bg-accent-container',\n 'text-on-accent-container',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'tinted',\n class: tw([\n 'bg-basic-container',\n 'text-on-basic-container',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'tinted',\n class: tw([\n 'bg-success-container',\n 'text-on-success-container',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'tinted',\n class: tw([\n 'bg-alert-container',\n 'text-on-alert-container',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'tinted',\n class: tw([\n 'bg-error-container',\n 'text-on-error-container',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'tinted',\n class: tw([\n 'bg-info-container',\n 'text-on-info-container',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'tinted',\n class: tw([\n 'bg-neutral-container',\n 'text-on-neutral-container',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'tinted',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'tinted',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const contrastVariants = [\n {\n intent: 'main',\n design: 'contrast',\n class: tw([\n 'text-on-main-contaier bg-surface',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'contrast',\n class: tw([\n 'text-on-support-container bg-surface',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'contrast',\n class: tw([\n 'text-on-accent-container bg-surface',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'contrast',\n class: tw([\n 'text-on-basic-container bg-surface',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'contrast',\n class: tw([\n 'text-on-success-container bg-surface',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'contrast',\n class: tw([\n 'text-on-alert-container bg-surface',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'contrast',\n class: tw([\n 'text-on-error-container bg-surface',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'contrast',\n class: tw([\n 'text-on-info-container bg-surface',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'contrast',\n class: tw([\n 'text-on-neutral-container bg-surface',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'contrast',\n class: tw([\n 'text-on-surface bg-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'contrast',\n class: tw([\n 'text-on-surface-inverse bg-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\n// override the Button component's px-lg padding by using a more specific class selector (pl-0 pr-0)\nexport const iconButtonStyles = cva(['pl-0 pr-0'], {\n variants: {\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['text-body-1'],\n md: ['text-body-1'],\n lg: ['text-display-3'],\n }),\n },\n})\n\nexport type IconButtonStylesProps = VariantProps<typeof iconButtonStyles>\n","import { Ref } from 'react'\n\nimport { Button, ButtonProps } from '../button'\nimport { iconButtonStyles } from './IconButton.styles'\n\nexport interface IconButtonProps extends Omit<ButtonProps, 'loadingText'> {\n 'aria-label': string\n ref?: Ref<HTMLButtonElement>\n}\n\nexport const IconButton = ({\n design = 'filled',\n disabled = false,\n intent = 'main',\n shape = 'rounded',\n size = 'md',\n className,\n ref,\n ...others\n}: IconButtonProps) => {\n return (\n <Button\n data-spark-component=\"icon-button\"\n ref={ref}\n className={iconButtonStyles({ size, className })}\n design={design}\n disabled={disabled}\n intent={intent}\n shape={shape}\n size={size}\n {...others}\n />\n )\n}\n\nIconButton.displayName = 'IconButton'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemFileNameProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemFileName = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemFileNameProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-file-name\"\n className={cx('text-body-2 truncate font-medium', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemFileName.displayName = 'FileUpload.ItemFileName'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemSizeTextProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemSizeText = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemSizeTextProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-size-text\"\n className={cx('text-caption', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\n","import { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * The index of the file in the accepted files array\n */\n fileIndex: number\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n className?: string\n}\n\nexport const AcceptedFile = ({\n asChild: _asChild = false,\n className,\n file,\n fileIndex,\n uploadProgress,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={className} {...props}>\n <div className=\"size-sz-40 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">{formatFileSize(file.size, locale)}</ItemSizeText>\n </div>\n {uploadProgress !== undefined && (\n <div className=\"mt-md\">\n <Progress\n value={uploadProgress}\n max={100}\n aria-label={`Upload progress: ${uploadProgress}%`}\n />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label=\"Delete file\" fileIndex={fileIndex} />\n </Item>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\nexport function Dropzone({\n children,\n onFiles,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n onFiles?: (files: FileList) => void\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n onFiles?.(files)\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n asChild: _asChild = false,\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * The index of the rejected file in the rejectedFiles array\n */\n rejectedFileIndex: number\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n className?: string\n}\n\nexport const RejectedFile = ({\n asChild: _asChild = false,\n className,\n rejectedFile,\n rejectedFileIndex,\n renderError,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={cx('border-error border-md', className)} {...props}>\n <div className=\"size-sz-40 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{rejectedFile.file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </ItemSizeText>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger\n aria-label={`Remove ${rejectedFile.file.name} error`}\n rejectedFileIndex={rejectedFileIndex}\n />\n </Item>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the rejected file to remove\n */\n rejectedFileIndex: number\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFileIndex,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Try to focus on trigger or dropzone if available\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }, 0)\n\n onClick?.(e)\n }\n\n return (\n <IconButton\n ref={buttonRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly } = useFileUploadContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n const buttonComponent = unstyled ? 'button' : Button\n const Comp = asChild ? Slot : buttonComponent\n\n return (\n <Comp\n // htmlFor=\"image_uploads\"\n type=\"button\"\n ref={(node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }}\n design={design}\n intent={intent}\n data-spark-component=\"file-upload-trigger\"\n className={cx(className)}\n disabled={disabled || readOnly}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,oBAAAA;AAAA;AAAA;;;ACCA,gCAAiC;AACjC,IAAAC,gBAA4E;;;ACF5E,uBAA0B;AAC1B,4BAA+B;AAC/B,0BAA6B;AAC7B,yBAA4B;AAC5B,mBAA4C;AAOrC,SAAS,mBAAmB,MAAY,QAAyB;AACtE,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,MAAM,GAAG,EAAE,IAAI,aAAW,QAAQ,KAAK,CAAC;AAEhE,SAAO,SAAS,KAAK,aAAW;AAE9B,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,UAAI,QAAQ,SAAS,IAAI,GAAG;AAE1B,cAAM,WAAW,QAAQ,MAAM,GAAG,EAAE;AAEpC,eAAO,KAAK,KAAK,WAAW,WAAW,GAAG;AAAA,MAC5C;AAGA,aAAO,KAAK,SAAS;AAAA,IACvB;AAGA,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,YAAMC,aAAY,QAAQ,YAAY;AACtC,YAAMC,YAAW,KAAK,KAAK,YAAY;AAEvC,aAAOA,UAAS,SAASD,UAAS;AAAA,IACpC;AAGA,UAAM,YAAY,MAAM,QAAQ,YAAY;AAC5C,UAAM,WAAW,KAAK,KAAK,YAAY;AAEvC,WAAO,SAAS,SAAS,SAAS;AAAA,EACpC,CAAC;AACH;AAUO,SAAS,iBACd,MACA,aACA,aACA,QACoC;AACpC,QAAM,gBAAgB,UAAU,iBAAiB;AACjD,MAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,UAAM,eAAe,SAAS,KAAK,IAAI,mCAAmC,eAAe,aAAa,aAAa,CAAC;AAEpH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,UAAM,eAAe,SAAS,KAAK,IAAI,mCAAmC,eAAe,aAAa,aAAa,CAAC;AAEpH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;AAMA,SAAS,mBAA2B;AAClC,MAAI,OAAO,cAAc,eAAe,UAAU,UAAU;AAC1D,WAAO,UAAU;AAAA,EACnB;AAEA,SAAO;AACT;AAQO,SAAS,eAAe,OAAe,QAAyB;AACrE,QAAM,gBAAgB,UAAU,iBAAiB;AAEjD,MAAI,mBAAmB;AACvB,MAAI,cAAc,WAAW,GAAG;AAC9B,uBAAmB,kBAAkB,OAAO,UAAU;AAAA,EACxD;AAEA,MAAI,UAAU,GAAG;AACf,UAAME,aAAY,IAAI,KAAK,aAAa,kBAAkB;AAAA,MACxD,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC;AAED,WAAOA,WAAU,OAAO,CAAC;AAAA,EAC3B;AAEA,QAAM,IAAI;AACV,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAGlD,QAAM,QAAQ,CAAC,QAAQ,YAAY,YAAY,UAAU;AACzD,QAAM,OAAO,MAAM,CAAC,KAAK;AAEzB,QAAM,OAAO,QAAQ,KAAK,IAAI,GAAG,CAAC;AAIlC,QAAM,cAAc,MAAM,IAAI,SAAS;AAGvC,QAAM,YAAY,IAAI,KAAK,aAAa,kBAAkB;AAAA,IACxD,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC;AAED,SAAO,UAAU,OAAO,IAAI;AAC9B;AAOO,SAAS,YAAY,MAA0B;AACpD,QAAM,WAAW,KAAK,KAAK,YAAY;AACvC,QAAM,WAAW,KAAK,KAAK,YAAY;AAGvC,MAAI,SAAS,WAAW,QAAQ,KAAK,0CAA0C,KAAK,QAAQ,GAAG;AAC7F,eAAO,4BAAc,gCAAY;AAAA,EACnC;AAGA,MAAI,aAAa,qBAAqB,SAAS,SAAS,MAAM,GAAG;AAC/D,eAAO,4BAAc,oCAAc;AAAA,EACrC;AAGA,MAAI,SAAS,WAAW,QAAQ,KAAK,qCAAqC,KAAK,QAAQ,GAAG;AACxF,eAAO,4BAAc,8BAAW;AAAA,EAClC;AAGA,aAAO,4BAAc,0BAAS;AAChC;;;ADmNM;AA/RC,IAAM,wBAAoB,6BAkBvB,IAAI;AAEP,IAAM,aAAa,CAAC;AAAA,EACzB,SAAS,WAAW;AAAA,EACpB;AAAA,EACA,eAAe,CAAC;AAAA,EAChB,OAAO;AAAA,EACP;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AACF,MAAuB;AAErB,QAAM,gBACJ,WAAW,OAAO,cAAc,eAAe,UAAU,WAAW,UAAU,WAAW;AAE3F,QAAM,eAAW,sBAAyB,IAAI;AAC9C,QAAM,iBAAa,sBAAoB,IAAI;AAC3C,QAAM,kBAAc,sBAAoB,IAAI;AAC5C,QAAM,uBAAmB,sBAA4B,CAAC,CAAC;AACvD,QAAM,CAAC,YAAY,eAAe,CAAC,QAAI;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,cAAc,CAAC;AAC7B,QAAM,WAAW;AACjB,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAyB,CAAC,CAAC;AAErE,QAAM,WAAW,CAAC,aAAqB;AAErC,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,qBAAiB,CAAC,CAAC;AAEnB,UAAM,mBAAmC,CAAC;AAI1C,UAAM,aAAa,CAAC,MAAY,kBAAmC;AACjE,aAAO,cAAc;AAAA,QACnB,kBAAgB,aAAa,SAAS,KAAK,QAAQ,aAAa,SAAS,KAAK;AAAA,MAChF;AAAA,IACF;AAGA,UAAM,kBAAkB,CAAC,MAAY,UAA+B;AAClE,YAAM,oBAAoB,iBAAiB;AAAA,QACzC,cAAY,SAAS,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK,SAAS,KAAK;AAAA,MAC9E;AAEA,UAAI,mBAAmB;AAErB,YAAI,CAAC,kBAAkB,OAAO,SAAS,KAAK,GAAG;AAC7C,4BAAkB,OAAO,KAAK,KAAK;AAAA,QACrC;AAAA,MACF,OAAO;AAEL,yBAAiB,KAAK;AAAA,UACpB;AAAA,UACA,QAAQ,CAAC,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAGA,UAAI,iBAAiB;AACnB,wBAAgB,MAAM,KAAK;AAAA,MAC7B;AAAA,IACF;AAEA,aAAS,CAAC,SAAiB;AACzB,YAAM,eAAe,QAAQ,CAAC;AAG9B,UAAI,aAAa,QAAW;AAC1B,cAAM,eAAe,aAAa;AAClC,cAAM,iBAAiB,WAAW;AAElC,YAAI,kBAAkB,GAAG;AAEvB,mBAAS,QAAQ,UAAQ;AACvB,4BAAgB,MAAM,gBAAgB;AAAA,UACxC,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,gBAAgB;AACpB,UAAI,QAAQ;AACV,cAAM,mBAAmB,SAAS,OAAO,UAAQ,CAAC,mBAAmB,MAAM,MAAM,CAAC;AAClF,yBAAiB,QAAQ,UAAQ;AAC/B,0BAAgB,MAAM,mBAAmB;AAAA,QAC3C,CAAC;AACD,wBAAgB,SAAS,OAAO,UAAQ,mBAAmB,MAAM,MAAM,CAAC;AAAA,MAC1E;AAGA,UAAI,iBAAiB;AACrB,UAAI,gBAAgB,UAAa,gBAAgB,QAAW;AAC1D,yBAAiB,cAAc,OAAO,UAAQ;AAC5C,gBAAM,aAAa,iBAAiB,MAAM,aAAa,aAAa,aAAa;AACjF,cAAI,CAAC,WAAW,OAAO;AACrB,gBAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,8BAAgB,MAAM,gBAAgB;AAAA,YACxC,WAAW,gBAAgB,UAAa,KAAK,OAAO,aAAa;AAC/D,8BAAgB,MAAM,gBAAgB;AAAA,YACxC,OAAO;AACL,8BAAgB,MAAM,cAAc;AAAA,YACtC;AAEA,mBAAO;AAAA,UACT;AAEA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAIA,YAAM,YAAY,oBAAI,IAAkB;AACxC,YAAM,iBAAyB,CAAC;AAChC,YAAM,cAAc,eAAe,OAAO,UAAQ;AAGhD,cAAM,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI;AAGzC,cAAM,eAAe,WAAW,MAAM,YAAY;AAClD,YAAI,cAAc;AAChB,yBAAe,KAAK,IAAI;AACxB,0BAAgB,MAAM,aAAa;AAEnC,iBAAO;AAAA,QACT;AAGA,YAAI,UAAU,IAAI,OAAO,GAAG;AAC1B,yBAAe,KAAK,IAAI;AACxB,0BAAgB,MAAM,aAAa;AAEnC,iBAAO;AAAA,QACT;AAGA,kBAAU,IAAI,SAAS,IAAI;AAE3B,eAAO;AAAA,MACT,CAAC;AAGD,UAAI,aAAa,WAAW,cAAc,YAAY,MAAM,GAAG,CAAC;AAKhE,UAAI,aAAa,QAAW;AAC1B,cAAM,eAAe,aAAa;AAClC,cAAM,iBAAiB,WAAW;AAElC,YAAI,kBAAkB,GAAG;AAEvB,qBAAW,QAAQ,UAAQ;AACzB,4BAAgB,MAAM,gBAAgB;AAAA,UACxC,CAAC;AACD,8BAAoB,UAAU,WAAW,MAAM;AAC/C,uBAAa,CAAC;AAAA,QAChB,WAAW,WAAW,SAAS,gBAAgB;AAE7C,qBAAW,QAAQ,UAAQ;AACzB,4BAAgB,MAAM,gBAAgB;AAAA,UACxC,CAAC;AACD,8BAAoB,UAAU,WAAW,MAAM;AAC/C,uBAAa,CAAC;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,UAAU,WAAW,CAAC,GAAG,cAAc,GAAG,UAAU,IAAI;AAK9D,YAAM,qBAAqB,CAAC,GAAG,gBAAgB;AAE/C,uBAAiB,kBAAkB;AAEnC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,CAAC,UAAkB;AAEpC,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,aAAS,CAAC,SAAiB;AACzB,YAAM,eAAe,QAAQ,CAAC;AAC9B,YAAM,UAAU,aAAa,OAAO,CAAC,GAAS,MAAc,MAAM,KAAK;AAGvE,UAAI,aAAa,UAAa,QAAQ,SAAS,UAAU;AACvD;AAAA,UAAiB,kBACf,aAAa,OAAO,cAAY,CAAC,SAAS,OAAO,SAAS,gBAAgB,CAAC;AAAA,QAC7E;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,MAAM;AAEvB,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,aAAS,CAAC,CAAC;AACX,qBAAiB,CAAC,CAAC;AACnB,qBAAiB,UAAU,CAAC;AAAA,EAC9B;AAEA,QAAM,qBAAqB,CAAC,UAAkB;AAE5C,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,qBAAiB,UAAQ,KAAK,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,EAC7D;AAEA,QAAM,qBAAqB,MAAM;AAC/B,qBAAiB,CAAC,CAAC;AAAA,EACrB;AAEA,QAAM,kBAAkB,aAAa,UAAa,MAAM,UAAU;AAElE,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,MAGA,uDAAC,SAAI,WAAU,YACZ;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,MAAK;AAAA,YACL,UAAU;AAAA,YACV,IAAG;AAAA,YACH;AAAA,YACA,MAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA,UAAU,YAAY,CAAC;AAAA,YACvB,WAAU;AAAA,YACV,UAAU,OAAK;AACb,kBAAI,EAAE,OAAO,SAAS,CAAC,YAAY,CAAC,UAAU;AAC5C,yBAAS,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;AAEnC,oBAAI;AACF,oBAAE,OAAO,QAAQ;AAAA,gBACnB,QAAQ;AAAA,gBAER;AAAA,cACF;AAAA,YACF;AAAA;AAAA,QACF;AAAA,SACF;AAAA;AAAA,EAEF;AAEJ;AAEA,WAAW,cAAc;AAElB,IAAM,uBAAuB,MAAM;AACxC,QAAM,cAAU,0BAAW,iBAAiB;AAE5C,MAAI,CAAC,SAAS;AACZ,UAAM,MAAM,gEAAgE;AAAA,EAC9E;AAEA,SAAO;AACT;;;AEzaA,IAAAC,gBAA0F;;;ACA1F,sBAAkC;AAClC,IAAAC,gBAOO;AASE,IAAAC,sBAAA;AAPF,IAAM,YAAwC,gBAAAC,KAAU;AAMxD,IAAM,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,MAAiB;AACpD,SAAO,6CAAC,gBAAAA,KAAU,MAAV,EAAe,KAAW,GAAG,OAAO;AAC9C;AAMO,IAAM,sBAAsB,CACjC,SACA,UACA,aACG;AACH,MAAI,CAAC,QAAS,QAAO,SAAS,QAAQ;AAEtC,aAAO,8BAAe,QAAQ,QAC1B;AAAA,IACE;AAAA,IACA;AAAA,IACA,SAAU,SAAS,MAAkC,QAAQ;AAAA,EAC/D,IACA;AACN;;;ACtBI,IAAAC,sBAAA;AAJG,IAAM,iBAAiB,CAAC,EAAE,UAAU,OAAO,KAAK,GAAG,MAAM,MAA2B;AACzF,QAAM,YAAY,UAAU,OAAO;AAEnC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,OAAO;AAAA;AAAA,QAEL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,GAAG,MAAM;AAAA,MACX;AAAA;AAAA,EACF;AAEJ;AAEA,eAAe,cAAc;;;ACrC7B,4BAA6B;AAC7B,sCAAkC;AAE3B,IAAM,iBAAa,qCAAI,CAAC,uBAAuB,GAAG;AAAA,EACvD,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,YAAQ,oCAcN;AAAA,MACA,SAAS,CAAC,cAAc;AAAA,MACxB,MAAM,CAAC,WAAW;AAAA,MAClB,SAAS,CAAC,cAAc;AAAA,MACxB,QAAQ,CAAC,aAAa;AAAA,MACtB,OAAO,CAAC,YAAY;AAAA,MACpB,SAAS,CAAC,cAAc;AAAA,MACxB,OAAO,CAAC,YAAY;AAAA,MACpB,OAAO,CAAC,YAAY;AAAA,MACpB,MAAM,CAAC,WAAW;AAAA,MAClB,SAAS,CAAC,cAAc;AAAA,IAC1B,CAAC;AAAA;AAAA;AAAA;AAAA,IAID,UAAM,oCAA0D;AAAA,MAC9D,SAAS,CAAC,qBAAqB;AAAA,MAC/B,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,IAC3B,CAAC;AAAA,EACH;AACF,CAAC;;;AHjBG,IAAAC,sBAAA;AAXG,IAAM,OAAO,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA,GAAG;AACL,MAAiB;AACf,QAAM,QAAQ,uBAAS,KAAK,QAAQ;AAEpC,SACE,8EACG;AAAA,oCAAa,OAA4C;AAAA,MACxD,WAAW,WAAW,EAAE,WAAW,MAAM,OAAO,CAAC;AAAA,MACjD,wBAAwB;AAAA,MACxB,eAAe;AAAA,MACf,WAAW;AAAA,MACX,GAAG;AAAA,IACL,CAAC;AAAA,IAEA,SAAS,6CAAC,kBAAgB,iBAAM;AAAA,KACnC;AAEJ;AAEA,KAAK,cAAc;;;AI1CnB,IAAAC,mCAAmB;AACnB,IAAAC,mBAA0C;AAC1C,IAAAC,gBAA0D;;;ACF1D,IAAAC,mCAAkC;AAE3B,IAAM,wBAAoB;AAAA,EAC/B,CAAC,YAAY,iBAAiB,iCAAiC,wBAAwB;AAAA,EACvF;AAAA,IACE,UAAU;AAAA,MACR,OAAO;AAAA,QACL,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC,YAAY;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;ACZA,IAAAC,gBAA0C;AAanC,IAAM,sBAAkB,6BAA2C,IAAI;AAEvE,IAAM,YAAY;AAElB,IAAM,cAAc,MAAM;AAC/B,QAAM,cAAU,0BAAW,eAAe;AAE1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,SAAO;AACT;;;ACzBA,IAAAC,mBAA0C;;;ACA1C,IAAAC,mCAAkC;AAE3B,IAAM,8BAA0B,sCAAI,CAAC,iBAAiB,mCAAmC,GAAG;AAAA,EACjG,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,QAAQ;AAAA,MACN,OAAO,CAAC,UAAU;AAAA,MAClB,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS,CAAC,YAAY;AAAA,MACtB,QAAQ,CAAC,WAAW;AAAA,MACpB,SAAS,CAAC,YAAY;AAAA,MACtB,OAAO,CAAC,UAAU;AAAA,MAClB,QAAQ,CAAC,UAAU;AAAA,MACnB,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS,CAAC,YAAY;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAIA,OAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,SAAS,CAAC,YAAY;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAIA,iBAAiB;AAAA,MACf,MAAM,CAAC,YAAY,oBAAoB,sCAAsC;AAAA,MAC7E,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF,CAAC;;;ADfG,IAAAC,sBAAA;AAVG,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAiD;AAC/C,QAAM,EAAE,OAAO,KAAK,QAAQ,OAAO,gBAAgB,IAAI,YAAY;AACnE,QAAM,KAAM,MAAM,SAAS,MAAO;AAElC,SACE;AAAA,IAAC,iBAAAC,SAAc;AAAA,IAAd;AAAA,MACC,wBAAqB;AAAA,MACrB,WAAW,wBAAwB,EAAE,WAAW,QAAQ,OAAO,gBAAgB,CAAC;AAAA,MAChF,OAAO,EAAE,GAAG,OAAO,GAAI,CAAC,mBAAmB,EAAE,WAAW,eAAe,CAAC,KAAK,EAAG;AAAA,MAChF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,kBAAkB,cAAc;;;AElBnB,IAAAC,sBAAA;AAFN,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA,WAAW,6CAAC,qBAAkB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,MAA2C;AACzC,QAAM,EAAE,MAAM,IAAI,YAAY;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,MACjD;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,YAAY,cAAc;;;ALLb,IAAAC,sBAAA;AAPN,IAAM,WAAW,CAAC;AAAA,EACvB;AAAA,EACA,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,WAAW,6CAAC,eAAY;AAAA,EACxB;AAAA,EACA,GAAG;AACL,MAAwC;AACtC,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAiB;AAE/C,QAAM,YAAQ,uBAAQ,MAAM;AAC1B,WAAO,EAAE,OAAO,aAAa,GAAG,KAAK,QAAQ,OAAO,iBAAiB,WAAW,WAAW;AAAA,EAC7F,GAAG,CAAC,KAAK,WAAW,QAAQ,OAAO,iBAAiB,UAAU,CAAC;AAE/D,SACE,6CAAC,gBAAgB,UAAhB,EAAyB,wBAAqB,YAAW,OACxD;AAAA,IAAC,iBAAAC,SAAc;AAAA,IAAd;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,eAAW,qCAAG,gDAAgD,SAAS;AAAA,MACvE,OAAO;AAAA,MACP,mBAAiB;AAAA,MACjB;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAEA,SAAS,cAAc;;;AMnDvB,4BAA6B;AAC7B,IAAAC,gBAA0D;AAyBtD,IAAAC,sBAAA;AAnBG,IAAM,gBAAgB,CAAC;AAAA,EAC5B,IAAI;AAAA,EACJ;AAAA,EACA,KAAK;AAAA,EACL,GAAG;AACL,MAA0B;AACxB,QAAM,aAAa,GAAG,SAAS,cAAU,qBAAM,CAAC;AAChD,QAAM,KAAK,UAAU;AAErB,QAAM,EAAE,UAAU,IAAI,YAAY;AAClC,QAAM,cAAU;AAAA,IACd,CAAC,OAAwB;AACvB,gBAAU,KAAK,KAAK,MAAS;AAAA,IAC/B;AAAA,IACA,CAAC,IAAI,SAAS;AAAA,EAChB;AACA,QAAM,UAAM,oCAAa,cAAc,OAAO;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,cAAc,cAAc;;;ACjCrB,IAAMC,YAIT,OAAO,OAAO,UAAM;AAAA,EACtB,OAAO;AAAA,EACP,KAAK;AAAA,EACL,WAAW;AACb,CAAC;AAEDA,UAAS,cAAc;AACvB,YAAY,cAAc;AAC1B,kBAAkB,cAAc;AAChC,cAAc,cAAc;;;AClB5B,IAAAC,mCAAmB;AAoBf,IAAAC,sBAAA;AAPG,IAAM,OAAO,CAAC;AAAA,EACnB,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,KAAK,cAAc;;;ACnCnB,mBAAsB;AACtB,IAAAC,oCAAmB;AACnB,IAAAC,gBAAuB;;;ACFvB,IAAAC,mCAAmB;AACnB,IAAAC,gBAA2E;;;ACD3E,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;AAElC,IAAM,kBAAkB;AAAA,EACtB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,qBAAqB;AACvB;AAEO,IAAM,oBAAgB;AAAA,EAC3B,CAAC,gBAAgB,gBAAgB,gBAAgB,aAAa,cAAc;AAAA,EAC5E;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA,MAIR,MAAM;AAAA,QACJ,SAAS,CAAC,qBAAqB;AAAA,QAC/B,IAAI,CAAC,WAAW,SAAS;AAAA,QACzB,IAAI,CAAC,WAAW,SAAS;AAAA,QACzB,MAAM,CAAC,UAAU,QAAQ;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAIA,YAAQ,qCAcN;AAAA,QACA,SAAS,CAAC,gBAAgB;AAAA,QAC1B,MAAM,CAAC,aAAa;AAAA,QACpB,SAAS,CAAC,gBAAgB;AAAA,QAC1B,QAAQ,CAAC,eAAe;AAAA,QACxB,OAAO,CAAC,cAAc;AAAA,QACtB,SAAS,CAAC,gBAAgB;AAAA,QAC1B,OAAO,CAAC,cAAc;AAAA,QACtB,OAAO,CAAC,cAAc;AAAA,QACtB,MAAM,CAAC,aAAa;AAAA,QACpB,SAAS,CAAC,gBAAgB;AAAA,MAC5B,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,qBAAqB;AAAA,QACnB,MAAM,CAAC,8BAA8B,4BAA4B;AAAA,QACjE,OAAO,CAAC,wBAAwB,sBAAsB;AAAA,MACxD;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;;;AChCgB,IAAAC,uBAAA;AAjBT,IAAM,UAAU,CAAC;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAuC;AACrC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAW,cAAc,EAAE,WAAW,MAAM,QAAQ,oBAAoB,CAAC;AAAA,MACxE,GAAG;AAAA,MAEH,mBAAS,8CAAC,kBAAgB,iBAAM;AAAA;AAAA,EACnC;AAEJ;;;AChCA,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;;;ACDlC,IAAAC,yBAAmB;AAEZ,IAAM,iBAAiB;AAAA;AAAA,EAE5B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClIA,IAAAC,yBAAmB;AAEZ,IAAM,gBAAgB;AAAA,EAC3B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjHA,IAAAC,yBAAmB;AAEZ,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjHA,IAAAC,yBAAmB;AAEZ,IAAM,iBAAiB;AAAA,EAC5B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC5HA,IAAAC,yBAAmB;AAEZ,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ALtGO,IAAM,mBAAe;AAAA,EAC1B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAeR,YAAQ,qCAA8E;AAAA,QACpF,QAAQ,CAAC;AAAA,QACT,UAAU,CAAC,kBAAkB,aAAa,gBAAgB;AAAA,QAC1D,QAAQ,CAAC;AAAA,QACT,OAAO,CAAC,0CAA0C;AAAA,QAClD,UAAU,CAAC;AAAA,MACb,CAAC;AAAA,MACD,WAAW;AAAA,QACT,MAAM,CAAC,WAAW;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA,MAIA,YAAQ,qCAeN;AAAA,QACA,MAAM,CAAC;AAAA,QACP,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,OAAO,CAAC;AAAA,QACR,SAAS,CAAC;AAAA,QACV,OAAO,CAAC;AAAA,QACR,QAAQ,CAAC;AAAA,QACT,MAAM,CAAC;AAAA,QACP,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,gBAAgB,CAAC;AAAA,MACnB,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,UAAM,qCAAyC;AAAA,QAC7C,IAAI,CAAC,eAAe,SAAS;AAAA,QAC7B,IAAI,CAAC,eAAe,SAAS;AAAA,QAC7B,IAAI,CAAC,eAAe,SAAS;AAAA,MAC/B,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,WAAO,qCAAqD;AAAA,QAC1D,SAAS,CAAC,YAAY;AAAA,QACtB,QAAQ,CAAC,WAAW;AAAA,QACpB,MAAM,CAAC,cAAc;AAAA,MACvB,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,UAAU;AAAA,QACR,MAAM,CAAC,sBAAsB,eAAe;AAAA,QAC5C,OAAO,CAAC,gBAAgB;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AHPU,IAAAC,uBAAA;AAxEV,IAAM,uBAAoD;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,SAAS,CAAC;AAAA,EACrB;AAAA,EACA,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,MAAmB;AACjB,QAAM,YAAY,UAAU,OAAO;AAEnC,QAAM,oBAAoB,CAAC,CAAC,YAAY;AAExC,QAAM,4BAAwB,uBAAQ,MAAM;AAC1C,UAAM,SAAiE,CAAC;AAExE,QAAI,mBAAmB;AACrB,2BAAqB,QAAQ,kBAAiB,OAAO,YAAY,IAAI,MAAU;AAAA,IACjF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN,WAAW,cAAc,iBAAiB;AAAA,IAC1C,GAAI,gBAAgB,EAAE,cAAc,aAAa;AAAA,EACnD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACpB,GAAI,cAAc,YAAY,EAAE,MAAM,SAAS;AAAA,MAChD;AAAA,MACA,WAAW,aAAa;AAAA,QACtB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,UAAU,CAAC,CAAC;AAAA,MACZ,aAAW;AAAA,MACX,aAAW,YAAY,cAAc;AAAA,MACpC,GAAG;AAAA,MACH,GAAG;AAAA,MAEH;AAAA,QAAoB;AAAA,QAAS;AAAA,QAAU,aACtC,YACE,gFACE;AAAA,wDAAC,WAAS,GAAG,cAAc;AAAA,UAC1B,eAAe;AAAA,UAEhB;AAAA,YAAC;AAAA;AAAA,cACC,eAAW;AAAA,cACX,eAAW,qCAAG,UAAU,cAAc,WAAW,uBAAuB;AAAA,cAEvE;AAAA;AAAA,UACH;AAAA,WACF,IAEA;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;AAEA,OAAO,cAAc;;;AS9HrB,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;AAG3B,IAAM,uBAAmB,sCAAI,CAAC,WAAW,GAAG;AAAA,EACjD,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,UAAM,qCAAyC;AAAA,MAC7C,IAAI,CAAC,aAAa;AAAA,MAClB,IAAI,CAAC,aAAa;AAAA,MAClB,IAAI,CAAC,gBAAgB;AAAA,IACvB,CAAC;AAAA,EACH;AACF,CAAC;;;ACMG,IAAAC,uBAAA;AAXG,IAAM,aAAa,CAAC;AAAA,EACzB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAuB;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAW,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,WAAW,cAAc;;;AXuDjB,IAAAC,uBAAA;AA3ED,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAwC;AACtC,QAAM,EAAE,YAAY,YAAY,aAAa,kBAAkB,UAAU,SAAS,IAChF,qBAAqB;AACvB,QAAM,gBAAY,sBAA0B,IAAI;AAEhD,QAAM,cAAc,CAAC,MAA2C;AAE9D,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,eAAW,SAAS;AAGpB,eAAW,MAAM;AAEf,YAAM,mBAAmB,iBAAiB,QAAQ,OAAO,OAAO;AAEhE,UAAI,iBAAiB,SAAS,GAAG;AAI/B,cAAM,cAAc,KAAK,IAAI,WAAW,iBAAiB,SAAS,CAAC;AACnE,cAAM,aAAa,iBAAiB,WAAW;AAE/C,YAAI,YAAY;AACd,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,OAAO;AAEL,cAAM,cAAc,WAAW,WAAW,YAAY;AACtD,YAAI,aAAa;AACf,sBAAY,MAAM;AAAA,QACpB;AAAA,MACF;AAAA,IACF,GAAG,CAAC;AAEJ,cAAU,CAAC;AAAA,EACb;AAEA,QAAM,SAAS,CAAC,SAAmC;AACjD,cAAU,UAAU;AACpB,QAAI,MAAM;AAER,aAAO,iBAAiB,QAAQ,UAAU,WAAW;AACnD,yBAAiB,QAAQ,KAAK,IAAW;AAAA,MAC3C;AACA,uBAAiB,QAAQ,SAAS,IAAI;AAAA,IACxC,OAAO;AAEL,UAAI,iBAAiB,QAAQ,SAAS,GAAG;AACvC,yBAAiB,QAAQ,SAAS,IAAI;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,eAAW,sCAAG,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,YAAY;AAAA,MACtB,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACN,GAAG;AAAA,MAEJ,wDAAC,QAAK,MAAK,MACT,wDAAC,sBAAM,GACT;AAAA;AAAA,EACF;AAEJ;AAEA,kBAAkB,cAAc;;;AYhGhC,IAAAC,oCAAmB;AAoBf,IAAAC,uBAAA;AAPG,IAAM,eAAe,CAAC;AAAA,EAC3B,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW,sCAAG,oCAAoC,SAAS;AAAA,MAC1D,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,aAAa,cAAc;;;AC9B3B,IAAAC,oCAAmB;AAoBf,IAAAC,uBAAA;AAPG,IAAM,eAAe,CAAC;AAAA,EAC3B,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW,sCAAG,gBAAgB,SAAS;AAAA,MACtC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,aAAa,cAAc;;;ACenB,IAAAC,uBAAA;AAbD,IAAM,eAAe,CAAC;AAAA,EAC3B,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,QAAM,EAAE,OAAO,IAAI,qBAAqB;AAExC,SACE,+CAAC,QAAK,WAAuB,GAAG,OAC9B;AAAA,kDAAC,SAAI,WAAU,+EACb,wDAAC,QAAK,MAAK,MAAM,sBAAY,IAAI,GAAE,GACrC;AAAA,IAEA,+CAAC,SAAI,WAAU,kBACb;AAAA,qDAAC,SAAI,WAAU,qDACb;AAAA,sDAAC,gBAAc,eAAK,MAAK;AAAA,QACzB,8CAAC,gBAAa,WAAU,iBAAiB,yBAAe,KAAK,MAAM,MAAM,GAAE;AAAA,SAC7E;AAAA,MACC,mBAAmB,UAClB,8CAAC,SAAI,WAAU,SACb;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP,KAAK;AAAA,UACL,cAAY,oBAAoB,cAAc;AAAA;AAAA,MAChD,GACF;AAAA,OAEJ;AAAA,IAEA,8CAAC,qBAAkB,cAAW,eAAc,WAAsB;AAAA,KACpE;AAEJ;AAEA,aAAa,cAAc;;;AChDvB,IAAAC,uBAAA;AAJG,IAAM,UAAU,CAAC,EAAE,SAAS,MAA8B;AAC/D,QAAM,EAAE,QAAQ,CAAC,GAAG,gBAAgB,CAAC,GAAG,OAAO,IAAI,qBAAqB;AAExE,SACE,+EACG,mBAAS;AAAA,IACR,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,GACH;AAEJ;AAEA,QAAQ,cAAc;;;AChCtB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAuB;AA+DnB,IAAAC,uBAAA;AA3DG,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAKG;AACD,QAAM,MAAM,qBAAqB;AACjC,QAAM,kBAAc,uBAAuB,IAAI;AAE/C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,qDAAqD;AAE/E,QAAM,aAAa,CAAC,MAAuB;AACzC,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,MAAE,cAAc,aAAa,kBAAkB,OAAO;AAGtD,QAAI,IAAI,YAAY,IAAI,UAAU;AAChC;AAAA,IACF;AAEA,UAAM,QAAQ,EAAE,aAAa;AAC7B,cAAU,KAAK;AAIf,QAAI,aAAqB,CAAC;AAC1B,QAAI,OAAO;AACT,mBAAa,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,MAAM,KAAK,KAAK;AAAA,IACnE;AAEA,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,SAAS,UAAU;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,UAAU;AAClC,UAAI,SAAS,SAAS,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAA2B;AAChD,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,QAAE,eAAe;AACjB,UAAI,CAAC,IAAI,YAAY,CAAC,IAAI,UAAU;AAClC,YAAI,SAAS,SAAS,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,YAAY,IAAI;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,UAAQ;AACX,oBAAY,UAAU;AACtB,YAAI,IAAI,aAAa;AACnB,cAAI,YAAY,UAAU;AAAA,QAC5B;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,UAAU,aAAa,KAAK;AAAA,MAC5B,iBAAe,IAAI,WAAW,OAAO;AAAA,MACrC,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,YAAY,OAAK;AACf,UAAE,eAAe;AAAA,MACnB;AAAA,MACA,WACE,WACI,gBACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,cAAc;AAAA,QACf;AAAA;AAAA,QAEA,IAAI,YAAY;AAAA;AAAA,QAEhB,IAAI,YAAY,CAAC,IAAI,YAAY;AAAA,QACjC;AAAA,MACF;AAAA,MAEN,aAAa,OAAK;AAChB,YAAI,CAAC,YAAY;AACf,YAAE,cAAc,aAAa,kBAAkB,MAAM;AAAA,QACvD;AAAA,MACF;AAAA,MACA,aAAa,OAAK;AAChB,UAAE,cAAc,aAAa,kBAAkB,OAAO;AAAA,MACxD;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,cAAc;;;AC/GvB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAmE;AA2C7D,IAAAC,uBAAA;AAxBC,IAAM,eAAe,CAAC;AAAA,EAC3B,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,GAAG;AACL,MAAmC;AACjC,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,KAAK;AAClD,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAS,KAAK;AAEpD,QAAM,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC7C,QAAM,WAAW,UAAU,IAAI,gBAAgB,IAAI,IAAI;AAGvD,gCAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,UAAU;AACZ,YAAI,gBAAgB,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,MAAI,CAAC,WAAW,YAAY;AAC1B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,wBAAqB;AAAA,QACrB,eAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW,sCAAG,wCAAwC,SAAS;AAAA,MAC9D,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,KAAK;AAAA,YACV,eAAW,sCAAG,0BAA0B,CAAC,eAAe,WAAW;AAAA,YACnE,QAAQ,MAAM,eAAe,IAAI;AAAA,YACjC,SAAS,MAAM,cAAc,IAAI;AAAA;AAAA,QACnC;AAAA,QACC,CAAC,eACA,8CAAC,SAAI,WAAU,qDAAqD,oBAAS;AAAA;AAAA;AAAA,EAEjF;AAEJ;AAEA,aAAa,cAAc;;;AC7E3B,4BAA+B;AAC/B,IAAAC,oCAAmB;;;ACDnB,IAAAC,gBAAsB;AACtB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAuB;AAyDf,IAAAC,uBAAA;AA3CD,IAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgD;AAC9C,QAAM,EAAE,oBAAoB,YAAY,aAAa,UAAU,SAAS,IAAI,qBAAqB;AACjG,QAAM,gBAAY,uBAA0B,IAAI;AAEhD,QAAM,cAAc,CAAC,MAA2C;AAE9D,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,uBAAmB,iBAAiB;AAGpC,eAAW,MAAM;AAEf,YAAM,cAAc,WAAW,WAAW,YAAY;AACtD,UAAI,aAAa;AACf,oBAAY,MAAM;AAAA,MACpB;AAAA,IACF,GAAG,CAAC;AAEJ,cAAU,CAAC;AAAA,EACb;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,eAAW,sCAAG,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,YAAY;AAAA,MACtB,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACN,GAAG;AAAA,MAEJ,wDAAC,QAAK,MAAK,MACT,wDAAC,uBAAM,GACT;AAAA;AAAA,EACF;AAEJ;AAEA,0BAA0B,cAAc;;;ADZ9B,IAAAC,uBAAA;AAdH,IAAM,eAAe,CAAC;AAAA,EAC3B,SAAS,WAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,QAAM,EAAE,OAAO,IAAI,qBAAqB;AAExC,SACE,+CAAC,QAAK,eAAW,sCAAG,0BAA0B,SAAS,GAAI,GAAG,OAC5D;AAAA,kDAAC,SAAI,WAAU,6EACb,wDAAC,QAAK,MAAK,MAAK,WAAU,cACxB,wDAAC,wCAAe,GAClB,GACF;AAAA,IAEA,8CAAC,SAAI,WAAU,kBACb,yDAAC,SAAI,WAAU,wBACb;AAAA,qDAAC,SAAI,WAAU,qDACb;AAAA,sDAAC,gBAAc,uBAAa,KAAK,MAAK;AAAA,QACtC,8CAAC,gBAAa,WAAU,iBACrB,yBAAe,aAAa,KAAK,MAAM,MAAM,GAChD;AAAA,SACF;AAAA,MACA,8CAAC,SAAI,WAAU,wBACZ,uBAAa,OAAO,IAAI,CAAC,OAAO,eAC/B,8CAAC,SAAqB,WAAU,2BAA0B,mBAAiB,OACxE,sBAAY,KAAK,KADV,UAEV,CACD,GACH;AAAA,OACF,GACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,cAAY,UAAU,aAAa,KAAK,IAAI;AAAA,QAC5C;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAEA,aAAa,cAAc;;;AEnF3B,IAAAC,oCAAmB;AAsCf,IAAAC,uBAAA;AAxBG,IAAM,UAAU,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA,GAAG;AACL,MAA8B;AAC5B,QAAM,EAAE,UAAU,YAAY,UAAU,SAAS,IAAI,qBAAqB;AAE1E,QAAM,cAAc,CAAC,MAAwB;AAC3C,MAAE,gBAAgB;AAClB,MAAE,eAAe;AACjB,QAAI,CAAC,YAAY,CAAC,UAAU;AAC1B,eAAS,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,WAAW,WAAW;AAC9C,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,KAAK,CAAC,SAA6B;AAEjC,YAAI,YAAY;AACd,qBAAW,UAAU;AAAA,QACvB;AACA,YAAI,KAAK;AACP,cAAI,OAAO,QAAQ,YAAY;AAC7B,gBAAI,IAAyB;AAAA,UAC/B,OAAO;AACL,gBAAI,UAAU;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA,wBAAqB;AAAA,MACrB,eAAW,sCAAG,SAAS;AAAA,MACvB,UAAU,YAAY;AAAA,MACtB,SAAS;AAAA,MACR,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,QAAQ,cAAc;;;ApCpDf,IAAMC,cAYT,OAAO,OAAO,YAAM;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEDA,YAAW,cAAc;AACzB,QAAQ,cAAc;AACtB,SAAS,cAAc;AACvB,QAAQ,cAAc;AACtB,KAAK,cAAc;AACnB,aAAa,cAAc;AAC3B,aAAa,cAAc;AAC3B,kBAAkB,cAAc;AAChC,aAAa,cAAc;AAC3B,aAAa,cAAc;AAC3B,aAAsB,cAAc;AACpC,0BAA0B,cAAc;","names":["FileUpload","import_react","extension","fileName","formatter","import_react","import_react","import_jsx_runtime","RadixSlot","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_radix_ui","import_react","import_class_variance_authority","import_react","import_radix_ui","import_class_variance_authority","import_jsx_runtime","RadixProgress","import_jsx_runtime","import_jsx_runtime","RadixProgress","import_react","import_jsx_runtime","Progress","import_class_variance_authority","import_jsx_runtime","import_class_variance_authority","import_react","import_class_variance_authority","import_react","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","Progress","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_Close","import_class_variance_authority","import_react","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","FileUpload"]}
1
+ {"version":3,"sources":["../../src/file-upload/index.ts","../../src/file-upload/FileUpload.tsx","../../src/file-upload/utils.ts","../../src/icon/Icon.tsx","../../src/slot/Slot.tsx","../../src/visually-hidden/VisuallyHidden.tsx","../../src/icon/Icon.styles.tsx","../../src/progress/Progress.tsx","../../src/progress/ProgressBar.styles.ts","../../src/progress/ProgressContext.tsx","../../src/progress/ProgressIndicator.tsx","../../src/progress/ProgressIndicator.styles.ts","../../src/progress/ProgressBar.tsx","../../src/progress/ProgressLabel.tsx","../../src/progress/index.ts","../../src/file-upload/FileUploadItem.tsx","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/button/Button.tsx","../../src/spinner/Spinner.styles.tsx","../../src/spinner/Spinner.tsx","../../src/button/Button.styles.tsx","../../src/button/variants/filled.ts","../../src/button/variants/ghost.ts","../../src/button/variants/outlined.ts","../../src/button/variants/tinted.ts","../../src/button/variants/contrast.ts","../../src/icon-button/IconButton.styles.tsx","../../src/icon-button/IconButton.tsx","../../src/file-upload/FileUploadItemFileName.tsx","../../src/file-upload/FileUploadItemSizeText.tsx","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx"],"sourcesContent":["import { FileUpload as Root, type FileUploadFileError, type RejectedFile } from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { Dropzone } from './FileUploadDropzone'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type { RejectedFile, FileUploadFileError }\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n Item: typeof Item\n ItemFileName: typeof ItemFileName\n ItemSizeText: typeof ItemSizeText\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n Trigger,\n Dropzone,\n Context,\n Item,\n ItemFileName,\n ItemSizeText,\n ItemDeleteTrigger,\n PreviewImage,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItem.displayName = 'FileUpload.Item'\nItemFileName.displayName = 'FileUpload.ItemFileName'\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { createContext, ReactNode, Ref, useContext, useRef, useState } from 'react'\n\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are selected\n */\n onFilesChange?: (files: File[]) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Callback when the maximum number of files is reached\n * @param maxFiles - The maximum number of files allowed\n * @param rejectedCount - The number of files that were rejected\n */\n onMaxFilesReached?: (maxFiles: number, rejectedCount: number) => void\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * Callback when a file size validation error occurs\n * @param file - The file that failed validation\n * @param error - The error message\n */\n onFileSizeError?: (file: File, error: string) => void\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport type FileUploadFileError =\n | 'TOO_MANY_FILES'\n | 'FILE_INVALID_TYPE'\n | 'FILE_TOO_LARGE'\n | 'FILE_TOO_SMALL'\n | 'FILE_INVALID'\n | 'FILE_EXISTS'\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n} | null>(null)\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFilesChange,\n multiple = true,\n accept,\n maxFiles,\n onMaxFilesReached,\n maxFileSize,\n minFileSize,\n onFileSizeError,\n disabled = false,\n readOnly = false,\n locale,\n}: FileUploadProps) => {\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n const [filesState, setFilesState, ,] = useCombinedState(\n controlledValue,\n defaultValue,\n onFilesChange\n )\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n\n // Call onFileSizeError callback if provided\n if (onFileSizeError) {\n onFileSizeError(file, error)\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n // Check maxFiles limit FIRST for all files (even if they will be rejected by other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, mark all new files with TOO_MANY_FILES error\n newFiles.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n }\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, 'FILE_INVALID_TYPE')\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, 'FILE_TOO_LARGE')\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, 'FILE_TOO_SMALL')\n } else {\n addRejectedFile(file, 'FILE_INVALID')\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n // This must be done AFTER size validation but BEFORE maxFiles check\n const seenFiles = new Map<string, File>()\n const duplicateFiles: File[] = []\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Track files rejected by maxFiles limit (only for files that passed other validations)\n // Note: We already checked maxFiles at the beginning for ALL files to allow multiple error codes\n // This second check is to prevent adding files when we're at the limit\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, reject all new files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n if (maxFiles !== undefined && updated.length < maxFiles) {\n setRejectedFiles(prevRejected =>\n prevRejected.filter(rejected => !rejected.errors.includes('TOO_MANY_FILES'))\n )\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n deleteButtonRefs.current = []\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale: defaultLocale,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id=\"image_uploads\"\n multiple={multiple}\n name=\"image_uploads\"\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n","import { Children, cloneElement, ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { iconStyles, IconVariantsProps } from './Icon.styles'\n\nexport interface IconProps extends IconVariantsProps, ComponentPropsWithoutRef<'svg'> {\n /**\n * The svg icon that will be wrapped\n */\n children: ReactNode\n /**\n * The accessible label for the icon. This label will be visually hidden but announced to screen\n * reader users, similar to `alt` text for `img` tags.\n */\n label?: string\n}\n\nexport const Icon = ({\n label,\n className,\n size = 'current',\n intent = 'current',\n children,\n ...others\n}: IconProps) => {\n const child = Children.only(children)\n\n return (\n <>\n {cloneElement(child as ReactElement<Record<string, any>>, {\n className: iconStyles({ className, size, intent }),\n 'data-spark-component': 'icon',\n 'aria-hidden': 'true',\n focusable: 'false',\n ...others,\n })}\n\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </>\n )\n}\n\nIcon.displayName = 'Icon'\n","import { Slot as RadixSlot } from 'radix-ui'\nimport {\n cloneElement,\n HTMLAttributes,\n isValidElement,\n PropsWithChildren,\n ReactNode,\n Ref,\n} from 'react'\n\nexport const Slottable: typeof RadixSlot.Slottable = RadixSlot.Slottable\n\nexport type SlotProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n ref?: Ref<HTMLElement>\n}\n\nexport const Slot = ({ ref, ...props }: SlotProps) => {\n return <RadixSlot.Root ref={ref} {...props} />\n}\n\n/**\n * When using Radix `Slot` component, it will consider its first child to merge its props with.\n * In some cases, you might need to wrap the top child with additional markup without breaking this behaviour.\n */\nexport const wrapPolymorphicSlot = (\n asChild: boolean | undefined,\n children: ReactNode,\n callback: (children: ReactNode) => ReactNode\n) => {\n if (!asChild) return callback(children) // If polymorphic behaviour is not used, we keep the original children\n\n return isValidElement(children)\n ? cloneElement(\n children,\n undefined,\n callback((children.props as { children: ReactNode }).children)\n )\n : null\n}\n","import { HTMLAttributes, PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\n\nexport type VisuallyHiddenProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const VisuallyHidden = ({ asChild = false, ref, ...props }: VisuallyHiddenProps) => {\n const Component = asChild ? Slot : 'span'\n\n return (\n <Component\n {...props}\n ref={ref}\n style={{\n // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss\n position: 'absolute',\n border: 0,\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n wordWrap: 'normal',\n ...props.style,\n }}\n />\n )\n}\n\nVisuallyHidden.displayName = 'VisuallyHidden'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nexport const iconStyles = cva(['fill-current shrink-0'], {\n variants: {\n /**\n * Color scheme of the icon.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['text-current'],\n main: ['text-main'],\n support: ['text-support'],\n accent: ['text-accent'],\n basic: ['text-basic'],\n success: ['text-success'],\n alert: ['text-alert'],\n error: ['text-error'],\n info: ['text-info'],\n neutral: ['text-neutral'],\n }),\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['current', 'sm', 'md', 'lg', 'xl']>({\n current: ['u-current-font-size'],\n sm: ['w-sz-16', 'h-sz-16'],\n md: ['w-sz-24', 'h-sz-24'],\n lg: ['w-sz-32', 'h-sz-32'],\n xl: ['w-sz-40', 'h-sz-40'],\n }),\n },\n})\n\nexport type IconVariantsProps = VariantProps<typeof iconStyles>\n","import { cx } from 'class-variance-authority'\nimport { Progress as RadixProgress } from 'radix-ui'\nimport { PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressContext } from './ProgressContext'\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressProps\n extends RadixProgress.ProgressProps,\n Pick<ProgressIndicatorStylesProps, 'intent'> {\n shape?: 'square' | 'rounded'\n isIndeterminate?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\nexport const Progress = ({\n className,\n value: valueProp,\n max = 100,\n shape = 'square',\n intent = 'basic',\n isIndeterminate = false,\n children = <ProgressBar />,\n ref,\n ...others\n}: PropsWithChildren<ProgressProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const value = useMemo(() => {\n return { value: valueProp ?? 0, max, intent, shape, isIndeterminate, onLabelId: setLabelId }\n }, [max, valueProp, intent, shape, isIndeterminate, setLabelId])\n\n return (\n <ProgressContext.Provider data-spark-component=\"progress\" value={value}>\n <RadixProgress.Progress\n data-spark-component=\"progress\"\n ref={ref}\n className={cx('gap-sm focus-visible:u-outline flex flex-col', className)}\n value={valueProp}\n aria-labelledby={labelId}\n max={max}\n tabIndex={-1}\n {...others}\n >\n {children}\n </RadixProgress.Progress>\n </ProgressContext.Provider>\n )\n}\n\nProgress.displayName = 'Progress'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressBarStyles = cva(\n ['relative', 'h-sz-4 w-full', 'transform-gpu overflow-hidden', 'bg-on-background/dim-4'],\n {\n variants: {\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n },\n }\n)\n\nexport type ProgressBarStylesProps = VariantProps<typeof progressBarStyles>\n","import { createContext, useContext } from 'react'\n\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressContextValue {\n value: number\n max: number\n isIndeterminate: boolean\n shape: 'square' | 'rounded'\n intent: ProgressIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n}\n\nexport const ProgressContext = createContext<ProgressContextValue | null>(null)\n\nexport const ID_PREFIX = ':progress'\n\nexport const useProgress = () => {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error('useProgress must be used within a Progress provider')\n }\n\n return context\n}\n","import { Progress as RadixProgress } from 'radix-ui'\nimport { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { useProgress } from './ProgressContext'\nimport { progressIndicatorStyles } from './ProgressIndicator.styles'\n\nexport type ProgressIndicatorProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressIndicator = ({\n className,\n style,\n ref,\n ...others\n}: PropsWithChildren<ProgressIndicatorProps>) => {\n const { value, max, intent, shape, isIndeterminate } = useProgress()\n const x = ((max - value) / max) * 100\n\n return (\n <RadixProgress.ProgressIndicator\n data-spark-component=\"progress-indicator\"\n className={progressIndicatorStyles({ className, intent, shape, isIndeterminate })}\n style={{ ...style, ...(!isIndeterminate && { transform: `translateX(-${x}%)` }) }}\n ref={ref}\n {...others}\n />\n )\n}\n\nProgressIndicator.displayName = 'Progress.Indicator'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressIndicatorStyles = cva(['h-full w-full', 'transition-transform duration-400'], {\n variants: {\n /**\n * Color scheme of the progress component.\n */\n intent: {\n basic: ['bg-basic'],\n main: ['bg-main'],\n support: ['bg-support'],\n accent: ['bg-accent'],\n success: ['bg-success'],\n alert: ['bg-alert'],\n danger: ['bg-error'],\n info: ['bg-info'],\n neutral: ['bg-neutral'],\n },\n /**\n * Shape of the progress component.\n */\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n /**\n * Sets if the progress value is not determinated.\n */\n isIndeterminate: {\n true: ['absolute', '-translate-x-1/2', 'animate-standalone-indeterminate-bar'],\n false: [],\n },\n },\n})\n\nexport type ProgressIndicatorStylesProps = VariantProps<typeof progressIndicatorStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { progressBarStyles } from './ProgressBar.styles'\nimport { useProgress } from './ProgressContext'\nimport { ProgressIndicator } from './ProgressIndicator'\n\nexport type ProgressBarProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressBar = ({\n className,\n children = <ProgressIndicator />,\n ref,\n ...others\n}: PropsWithChildren<ProgressBarProps>) => {\n const { shape } = useProgress()\n\n return (\n <div\n data-spark-component=\"progress-bar\"\n className={progressBarStyles({ className, shape })}\n ref={ref}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nProgressBar.displayName = 'Progress.Bar'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { ComponentPropsWithRef, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useProgress } from './ProgressContext'\n\nexport type ProgressLabelProps = ComponentPropsWithRef<'span'>\n\nexport const ProgressLabel = ({\n id: idProp,\n children,\n ref: forwardedRef,\n ...others\n}: ProgressLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId } = useProgress()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <span\n data-spark-component=\"progress-label\"\n id={id}\n className=\"text-body-2 text-on-surface\"\n ref={ref}\n {...others}\n >\n {children}\n </span>\n )\n}\n\nProgressLabel.displayName = 'Progress.Label'\n","import { Progress as Root } from './Progress'\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressIndicator } from './ProgressIndicator'\nimport { ProgressLabel } from './ProgressLabel'\n\nexport const Progress: typeof Root & {\n Label: typeof ProgressLabel\n Bar: typeof ProgressBar\n Indicator: typeof ProgressIndicator\n} = Object.assign(Root, {\n Label: ProgressLabel,\n Bar: ProgressBar,\n Indicator: ProgressIndicator,\n})\n\nProgress.displayName = 'Progress'\nProgressBar.displayName = 'Progress.Bar'\nProgressIndicator.displayName = 'Progress.Indicator'\nProgressLabel.displayName = 'Progress.Label'\n\nexport { type ProgressProps } from './Progress'\nexport { type ProgressBarProps } from './ProgressBar'\nexport { type ProgressLabelProps } from './ProgressLabel'\nexport { type ProgressIndicatorProps } from './ProgressIndicator'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n children: ReactNode\n className?: string\n}\n\nexport const Item = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemProps) => {\n return (\n <li\n data-spark-component=\"file-upload-item\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n {children}\n </li>\n )\n}\n\nItem.displayName = 'FileUpload.Item'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the file to delete\n */\n fileIndex: number\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n fileIndex,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, focus on trigger or dropzone\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n }, 0)\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, type DOMAttributes, Ref, useMemo } from 'react'\n\nimport { Slot, wrapPolymorphicSlot } from '../slot'\nimport { Spinner, type SpinnerProps } from '../spinner'\nimport { buttonStyles, type ButtonStylesProps } from './Button.styles'\n\nexport interface ButtonProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'disabled'>,\n ButtonStylesProps {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild?: boolean\n /**\n * Display a spinner to indicate to the user that the button is loading something after they interacted with it.\n */\n isLoading?: boolean\n /**\n * If your loading state should only display a spinner, it's better to specify a label for it (a11y).\n */\n loadingLabel?: string\n /**\n * If your loading state should also display a label, you can use this prop instead of `loadingLabel`.\n * **Please note that using this can result in layout shifting when the Button goes from loading state to normal state.**\n */\n loadingText?: string\n ref?: Ref<HTMLButtonElement>\n}\n\ntype DOMAttributesEventHandler = keyof Omit<\n DOMAttributes<HTMLButtonElement>,\n 'children' | 'dangerouslySetInnerHTML'\n>\n\nconst blockedEventHandlers: DOMAttributesEventHandler[] = [\n 'onClick',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onKeyDown',\n 'onKeyPress',\n 'onKeyUp',\n 'onSubmit',\n]\n\nexport const Button = ({\n children,\n design = 'filled',\n disabled = false,\n intent = 'main',\n isLoading = false,\n loadingLabel,\n loadingText,\n shape = 'rounded',\n size = 'md',\n asChild,\n className,\n underline = false,\n ref,\n ...others\n}: ButtonProps) => {\n const Component = asChild ? Slot : 'button'\n\n const shouldNotInteract = !!disabled || isLoading\n\n const disabledEventHandlers = useMemo(() => {\n const result: Partial<Record<DOMAttributesEventHandler, () => void>> = {}\n\n if (shouldNotInteract) {\n blockedEventHandlers.forEach(eventHandler => (result[eventHandler] = undefined))\n }\n\n return result\n }, [shouldNotInteract])\n\n const spinnerProps = {\n size: 'current' as SpinnerProps['size'],\n className: loadingText ? 'inline-block' : 'absolute',\n ...(loadingLabel && { 'aria-label': loadingLabel }),\n }\n\n return (\n <Component\n data-spark-component=\"button\"\n {...(Component === 'button' && { type: 'button' })}\n ref={ref}\n className={buttonStyles({\n className,\n design,\n disabled: shouldNotInteract,\n intent,\n shape,\n size,\n underline,\n })}\n disabled={!!disabled}\n aria-busy={isLoading}\n aria-live={isLoading ? 'assertive' : 'off'}\n {...others}\n {...disabledEventHandlers}\n >\n {wrapPolymorphicSlot(asChild, children, slotted =>\n isLoading ? (\n <>\n <Spinner {...spinnerProps} />\n {loadingText && loadingText}\n\n <div\n aria-hidden\n className={cx('gap-md', loadingText ? 'hidden' : 'inline-flex opacity-0')}\n >\n {slotted}\n </div>\n </>\n ) : (\n slotted\n )\n )}\n </Component>\n )\n}\n\nButton.displayName = 'Button'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nconst defaultVariants = {\n intent: 'current',\n size: 'current',\n isBackgroundVisible: false,\n} as const\n\nexport const spinnerStyles = cva(\n ['inline-block', 'border-solid', 'rounded-full', 'border-md', 'animate-spin'],\n {\n variants: {\n /**\n * Use `size` prop to set the size of the spinner. If you want to set the full size for the spinner, don't forget to add a wrapping container with its own size.\n */\n size: {\n current: ['u-current-font-size'],\n sm: ['w-sz-20', 'h-sz-20'],\n md: ['w-sz-28', 'h-sz-28'],\n full: ['w-full', 'h-full'],\n },\n /**\n * Color scheme of the spinner.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['border-current'],\n main: ['border-main'],\n support: ['border-support'],\n accent: ['border-accent'],\n basic: ['border-basic'],\n success: ['border-success'],\n alert: ['border-alert'],\n error: ['border-error'],\n info: ['border-info'],\n neutral: ['border-neutral'],\n }),\n /**\n * Size of the button.\n */\n isBackgroundVisible: {\n true: ['border-b-neutral-container', 'border-l-neutral-container'],\n false: ['border-b-transparent', 'border-l-transparent'],\n },\n },\n defaultVariants,\n }\n)\n\nexport type SpinnerStylesProps = VariantProps<typeof spinnerStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { spinnerStyles, SpinnerStylesProps } from './Spinner.styles'\n\nexport interface SpinnerProps extends ComponentPropsWithRef<'div'>, SpinnerStylesProps {\n /**\n * Use `label` prop for accessibility, it is important to add a fallback loading text. This text will be visible to screen readers.\n */\n label?: string\n}\n\nexport const Spinner = ({\n className,\n size = 'current',\n intent = 'current',\n label,\n isBackgroundVisible,\n ref,\n ...others\n}: PropsWithChildren<SpinnerProps>) => {\n return (\n <span\n role=\"status\"\n data-spark-component=\"spinner\"\n ref={ref}\n className={spinnerStyles({ className, size, intent, isBackgroundVisible })}\n {...others}\n >\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </span>\n )\n}\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nimport {\n contrastVariants,\n filledVariants,\n ghostVariants,\n outlinedVariants,\n tintedVariants,\n} from './variants'\n\nexport const buttonStyles = cva(\n [\n 'u-shadow-border-transition',\n 'box-border inline-flex items-center justify-center gap-md whitespace-nowrap',\n 'default:px-lg',\n 'text-body-1 font-bold',\n 'focus-visible:u-outline',\n ],\n {\n variants: {\n /**\n * Main style of the button.\n *\n * - `filled`: Button will be plain.\n *\n * - `outlined`: Button will be transparent with an outline.\n *\n * - `tinted`: Button will be filled but using a lighter color scheme.\n *\n * - `ghost`: Button will look like a link. No borders, plain text.\n *\n * - `contrast`: Button will be surface filled. No borders, plain text.\n *\n */\n design: makeVariants<'design', ['filled', 'outlined', 'tinted', 'ghost', 'contrast']>({\n filled: [],\n outlined: ['bg-transparent', 'border-sm', 'border-current'],\n tinted: [],\n ghost: ['default:-mx-md px-md hover:bg-main/dim-5'],\n contrast: [],\n }),\n underline: {\n true: ['underline'],\n },\n /**\n * Color scheme of the button.\n */\n intent: makeVariants<\n 'intent',\n [\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'danger',\n 'info',\n 'neutral',\n 'surface',\n 'surfaceInverse',\n ]\n >({\n main: [],\n support: [],\n accent: [],\n basic: [],\n success: [],\n alert: [],\n danger: [],\n info: [],\n neutral: [],\n surface: [],\n surfaceInverse: [],\n }),\n /**\n * Size of the button.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['min-w-sz-32', 'h-sz-32'],\n md: ['min-w-sz-44', 'h-sz-44'],\n lg: ['min-w-sz-56', 'h-sz-56'],\n }),\n /**\n * Shape of the button.\n */\n shape: makeVariants<'shape', ['rounded', 'square', 'pill']>({\n rounded: ['rounded-lg'],\n square: ['rounded-0'],\n pill: ['rounded-full'],\n }),\n /**\n * Disable the button, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['cursor-not-allowed', 'opacity-dim-3'],\n false: ['cursor-pointer'],\n },\n },\n compoundVariants: [\n ...filledVariants,\n ...outlinedVariants,\n ...tintedVariants,\n ...ghostVariants,\n ...contrastVariants,\n ],\n defaultVariants: {\n design: 'filled',\n intent: 'main',\n size: 'md',\n shape: 'rounded',\n },\n }\n)\n\nexport type ButtonStylesProps = VariantProps<typeof buttonStyles>\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const filledVariants = [\n // Main\n {\n intent: 'main',\n design: 'filled',\n class: tw([\n 'bg-main',\n 'text-on-main',\n 'hover:bg-main-hovered',\n 'enabled:active:bg-main-hovered',\n 'focus-visible:bg-main-hovered',\n ]),\n },\n // Support\n {\n intent: 'support',\n design: 'filled',\n class: tw([\n 'bg-support',\n 'text-on-support',\n 'hover:bg-support-hovered',\n 'enabled:active:bg-support-hovered',\n 'focus-visible:bg-support-hovered',\n ]),\n },\n // Accent\n {\n intent: 'accent',\n design: 'filled',\n class: tw([\n 'bg-accent',\n 'text-on-accent',\n 'hover:bg-accent-hovered',\n 'enabled:active:bg-accent-hovered',\n 'focus-visible:bg-accent-hovered',\n ]),\n },\n // Basic\n {\n intent: 'basic',\n design: 'filled',\n class: tw([\n 'bg-basic',\n 'text-on-basic',\n 'hover:bg-basic-hovered',\n 'enabled:active:bg-basic-hovered',\n 'focus-visible:bg-basic-hovered',\n ]),\n },\n // Success\n {\n intent: 'success',\n design: 'filled',\n class: tw([\n 'bg-success',\n 'text-on-success',\n 'hover:bg-success-hovered',\n 'enabled:active:bg-success-hovered',\n 'focus-visible:bg-success-hovered',\n ]),\n },\n // Alert\n {\n intent: 'alert',\n design: 'filled',\n class: tw([\n 'bg-alert',\n 'text-on-alert',\n 'hover:bg-alert-hovered',\n 'enabled:active:bg-alert-hovered',\n 'focus-visible:bg-alert-hovered',\n ]),\n },\n // Danger\n {\n intent: 'danger',\n design: 'filled',\n class: tw([\n 'text-on-error bg-error',\n 'hover:bg-error-hovered enabled:active:bg-error-hovered',\n 'focus-visible:bg-error-hovered',\n ]),\n },\n // Info\n {\n intent: 'info',\n design: 'filled',\n class: tw([\n 'text-on-error bg-info',\n 'hover:bg-info-hovered enabled:active:bg-info-hovered',\n 'focus-visible:bg-info-hovered',\n ]),\n },\n // Neutral\n {\n intent: 'neutral',\n design: 'filled',\n class: tw([\n 'bg-neutral',\n 'text-on-neutral',\n 'hover:bg-neutral-hovered',\n 'enabled:active:bg-neutral-hovered',\n 'focus-visible:bg-neutral-hovered',\n ]),\n },\n // Surface\n {\n intent: 'surface',\n design: 'filled',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'filled',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const ghostVariants = [\n {\n intent: 'main',\n design: 'ghost',\n class: tw([\n 'text-on-main-container',\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n ]),\n },\n {\n intent: 'support',\n design: 'ghost',\n class: tw([\n 'text-on-support-container',\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n ]),\n },\n {\n intent: 'accent',\n design: 'ghost',\n class: tw([\n 'text-on-accent-container',\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n ]),\n },\n {\n intent: 'basic',\n design: 'ghost',\n class: tw([\n 'text-on-basic-container',\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n ]),\n },\n {\n intent: 'success',\n design: 'ghost',\n class: tw([\n 'text-on-success-container',\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n ]),\n },\n {\n intent: 'alert',\n design: 'ghost',\n class: tw([\n 'text-on-alert-container',\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n ]),\n },\n {\n intent: 'danger',\n design: 'ghost',\n class: tw([\n 'text-on-error-container',\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n ]),\n },\n {\n intent: 'info',\n design: 'ghost',\n class: tw([\n 'text-on-info-container',\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n ]),\n },\n {\n intent: 'neutral',\n design: 'ghost',\n class: tw([\n 'text-on-neutral-container',\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n ]),\n },\n {\n intent: 'surface',\n design: 'ghost',\n class: tw([\n 'text-surface',\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'ghost',\n class: tw([\n 'text-surface-inverse',\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const outlinedVariants = [\n {\n intent: 'main',\n design: 'outlined',\n class: tw([\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n 'text-main',\n ]),\n },\n {\n intent: 'support',\n design: 'outlined',\n class: tw([\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n 'text-support',\n ]),\n },\n {\n intent: 'accent',\n design: 'outlined',\n class: tw([\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n 'text-accent',\n ]),\n },\n {\n intent: 'basic',\n design: 'outlined',\n class: tw([\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n 'text-basic',\n ]),\n },\n {\n intent: 'success',\n design: 'outlined',\n class: tw([\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n 'text-success',\n ]),\n },\n {\n intent: 'alert',\n design: 'outlined',\n class: tw([\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n 'text-alert',\n ]),\n },\n {\n intent: 'danger',\n design: 'outlined',\n class: tw([\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n 'text-error',\n ]),\n },\n {\n intent: 'info',\n design: 'outlined',\n class: tw([\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n 'text-info',\n ]),\n },\n {\n intent: 'neutral',\n design: 'outlined',\n class: tw([\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n 'text-neutral',\n ]),\n },\n {\n intent: 'surface',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n 'text-surface',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n 'text-surface-inverse',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const tintedVariants = [\n {\n intent: 'main',\n design: 'tinted',\n class: tw([\n 'bg-main-container',\n 'text-on-main-container',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'tinted',\n class: tw([\n 'bg-support-container',\n 'text-on-support-container',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'tinted',\n class: tw([\n 'bg-accent-container',\n 'text-on-accent-container',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'tinted',\n class: tw([\n 'bg-basic-container',\n 'text-on-basic-container',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'tinted',\n class: tw([\n 'bg-success-container',\n 'text-on-success-container',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'tinted',\n class: tw([\n 'bg-alert-container',\n 'text-on-alert-container',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'tinted',\n class: tw([\n 'bg-error-container',\n 'text-on-error-container',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'tinted',\n class: tw([\n 'bg-info-container',\n 'text-on-info-container',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'tinted',\n class: tw([\n 'bg-neutral-container',\n 'text-on-neutral-container',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'tinted',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'tinted',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const contrastVariants = [\n {\n intent: 'main',\n design: 'contrast',\n class: tw([\n 'text-on-main-contaier bg-surface',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'contrast',\n class: tw([\n 'text-on-support-container bg-surface',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'contrast',\n class: tw([\n 'text-on-accent-container bg-surface',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'contrast',\n class: tw([\n 'text-on-basic-container bg-surface',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'contrast',\n class: tw([\n 'text-on-success-container bg-surface',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'contrast',\n class: tw([\n 'text-on-alert-container bg-surface',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'contrast',\n class: tw([\n 'text-on-error-container bg-surface',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'contrast',\n class: tw([\n 'text-on-info-container bg-surface',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'contrast',\n class: tw([\n 'text-on-neutral-container bg-surface',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'contrast',\n class: tw([\n 'text-on-surface bg-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'contrast',\n class: tw([\n 'text-on-surface-inverse bg-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\n// override the Button component's px-lg padding by using a more specific class selector (pl-0 pr-0)\nexport const iconButtonStyles = cva(['pl-0 pr-0'], {\n variants: {\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['text-body-1'],\n md: ['text-body-1'],\n lg: ['text-display-3'],\n }),\n },\n})\n\nexport type IconButtonStylesProps = VariantProps<typeof iconButtonStyles>\n","import { Ref } from 'react'\n\nimport { Button, ButtonProps } from '../button'\nimport { iconButtonStyles } from './IconButton.styles'\n\nexport interface IconButtonProps extends Omit<ButtonProps, 'loadingText'> {\n 'aria-label': string\n ref?: Ref<HTMLButtonElement>\n}\n\nexport const IconButton = ({\n design = 'filled',\n disabled = false,\n intent = 'main',\n shape = 'rounded',\n size = 'md',\n className,\n ref,\n ...others\n}: IconButtonProps) => {\n return (\n <Button\n data-spark-component=\"icon-button\"\n ref={ref}\n className={iconButtonStyles({ size, className })}\n design={design}\n disabled={disabled}\n intent={intent}\n shape={shape}\n size={size}\n {...others}\n />\n )\n}\n\nIconButton.displayName = 'IconButton'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemFileNameProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemFileName = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemFileNameProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-file-name\"\n className={cx('text-body-2 truncate font-medium', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemFileName.displayName = 'FileUpload.ItemFileName'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemSizeTextProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemSizeText = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemSizeTextProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-size-text\"\n className={cx('text-caption', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\n","import { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * The index of the file in the accepted files array\n */\n fileIndex: number\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n /**\n * Accessible label for the progress bar. Required when uploadProgress is provided.\n */\n progressAriaLabel?: string\n className?: string\n}\n\nexport const AcceptedFile = ({\n asChild: _asChild = false,\n className,\n file,\n fileIndex,\n uploadProgress,\n deleteButtonAriaLabel,\n progressAriaLabel,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={className} {...props}>\n <div className=\"size-sz-40 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">{formatFileSize(file.size, locale)}</ItemSizeText>\n </div>\n {uploadProgress !== undefined && (\n <div className=\"mt-md\">\n <Progress value={uploadProgress} max={100} aria-label={progressAriaLabel} />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label={deleteButtonAriaLabel} fileIndex={fileIndex} />\n </Item>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\nexport function Dropzone({\n children,\n onFiles,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n onFiles?: (files: FileList) => void\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n onFiles?.(files)\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n asChild: _asChild = false,\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * The index of the rejected file in the rejectedFiles array\n */\n rejectedFileIndex: number\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n className?: string\n}\n\nexport const RejectedFile = ({\n asChild: _asChild = false,\n className,\n rejectedFile,\n rejectedFileIndex,\n renderError,\n deleteButtonAriaLabel,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={cx('border-error border-md', className)} {...props}>\n <div className=\"size-sz-40 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{rejectedFile.file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </ItemSizeText>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger\n aria-label={deleteButtonAriaLabel}\n rejectedFileIndex={rejectedFileIndex}\n />\n </Item>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the rejected file to remove\n */\n rejectedFileIndex: number\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFileIndex,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Try to focus on trigger or dropzone if available\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }, 0)\n\n onClick?.(e)\n }\n\n return (\n <IconButton\n ref={buttonRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly } = useFileUploadContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n const buttonComponent = unstyled ? 'button' : Button\n const Comp = asChild ? Slot : buttonComponent\n\n return (\n <Comp\n // htmlFor=\"image_uploads\"\n type=\"button\"\n ref={(node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }}\n design={design}\n intent={intent}\n data-spark-component=\"file-upload-trigger\"\n className={cx(className)}\n disabled={disabled || readOnly}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n"],"mappings":"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","names":["FileUpload","import_react","extension","fileName","formatter","import_react","import_react","import_jsx_runtime","RadixSlot","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_radix_ui","import_react","import_class_variance_authority","import_react","import_radix_ui","import_class_variance_authority","import_jsx_runtime","RadixProgress","import_jsx_runtime","import_jsx_runtime","RadixProgress","import_react","import_jsx_runtime","Progress","import_class_variance_authority","import_jsx_runtime","import_class_variance_authority","import_react","import_class_variance_authority","import_react","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","Progress","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_Close","import_class_variance_authority","import_react","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","FileUpload"]}
@@ -495,6 +495,8 @@ var AcceptedFile = ({
495
495
  file,
496
496
  fileIndex,
497
497
  uploadProgress,
498
+ deleteButtonAriaLabel,
499
+ progressAriaLabel,
498
500
  ...props
499
501
  }) => {
500
502
  const { locale } = useFileUploadContext();
@@ -505,16 +507,9 @@ var AcceptedFile = ({
505
507
  /* @__PURE__ */ jsx6(ItemFileName, { children: file.name }),
506
508
  /* @__PURE__ */ jsx6(ItemSizeText, { className: "opacity-dim-1", children: formatFileSize(file.size, locale) })
507
509
  ] }),
508
- uploadProgress !== void 0 && /* @__PURE__ */ jsx6("div", { className: "mt-md", children: /* @__PURE__ */ jsx6(
509
- Progress,
510
- {
511
- value: uploadProgress,
512
- max: 100,
513
- "aria-label": `Upload progress: ${uploadProgress}%`
514
- }
515
- ) })
510
+ uploadProgress !== void 0 && /* @__PURE__ */ jsx6("div", { className: "mt-md", children: /* @__PURE__ */ jsx6(Progress, { value: uploadProgress, max: 100, "aria-label": progressAriaLabel }) })
516
511
  ] }),
517
- /* @__PURE__ */ jsx6(ItemDeleteTrigger, { "aria-label": "Delete file", fileIndex })
512
+ /* @__PURE__ */ jsx6(ItemDeleteTrigger, { "aria-label": deleteButtonAriaLabel, fileIndex })
518
513
  ] });
519
514
  };
520
515
  AcceptedFile.displayName = "FileUpload.AcceptedFile";
@@ -737,6 +732,7 @@ var RejectedFile = ({
737
732
  rejectedFile,
738
733
  rejectedFileIndex,
739
734
  renderError,
735
+ deleteButtonAriaLabel,
740
736
  ...props
741
737
  }) => {
742
738
  const { locale } = useFileUploadContext();
@@ -752,7 +748,7 @@ var RejectedFile = ({
752
748
  /* @__PURE__ */ jsx11(
753
749
  RejectedFileDeleteTrigger,
754
750
  {
755
- "aria-label": `Remove ${rejectedFile.file.name} error`,
751
+ "aria-label": deleteButtonAriaLabel,
756
752
  rejectedFileIndex
757
753
  }
758
754
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/file-upload/FileUpload.tsx","../../src/file-upload/utils.ts","../../src/file-upload/FileUploadItem.tsx","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/file-upload/FileUploadItemFileName.tsx","../../src/file-upload/FileUploadItemSizeText.tsx","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx","../../src/file-upload/index.ts"],"sourcesContent":["/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { createContext, ReactNode, Ref, useContext, useRef, useState } from 'react'\n\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are selected\n */\n onFilesChange?: (files: File[]) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Callback when the maximum number of files is reached\n * @param maxFiles - The maximum number of files allowed\n * @param rejectedCount - The number of files that were rejected\n */\n onMaxFilesReached?: (maxFiles: number, rejectedCount: number) => void\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * Callback when a file size validation error occurs\n * @param file - The file that failed validation\n * @param error - The error message\n */\n onFileSizeError?: (file: File, error: string) => void\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport type FileUploadFileError =\n | 'TOO_MANY_FILES'\n | 'FILE_INVALID_TYPE'\n | 'FILE_TOO_LARGE'\n | 'FILE_TOO_SMALL'\n | 'FILE_INVALID'\n | 'FILE_EXISTS'\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n} | null>(null)\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFilesChange,\n multiple = true,\n accept,\n maxFiles,\n onMaxFilesReached,\n maxFileSize,\n minFileSize,\n onFileSizeError,\n disabled = false,\n readOnly = false,\n locale,\n}: FileUploadProps) => {\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n const [filesState, setFilesState, ,] = useCombinedState(\n controlledValue,\n defaultValue,\n onFilesChange\n )\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n\n // Call onFileSizeError callback if provided\n if (onFileSizeError) {\n onFileSizeError(file, error)\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n // Check maxFiles limit FIRST for all files (even if they will be rejected by other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, mark all new files with TOO_MANY_FILES error\n newFiles.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n }\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, 'FILE_INVALID_TYPE')\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, 'FILE_TOO_LARGE')\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, 'FILE_TOO_SMALL')\n } else {\n addRejectedFile(file, 'FILE_INVALID')\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n // This must be done AFTER size validation but BEFORE maxFiles check\n const seenFiles = new Map<string, File>()\n const duplicateFiles: File[] = []\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Track files rejected by maxFiles limit (only for files that passed other validations)\n // Note: We already checked maxFiles at the beginning for ALL files to allow multiple error codes\n // This second check is to prevent adding files when we're at the limit\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, reject all new files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n if (maxFiles !== undefined && updated.length < maxFiles) {\n setRejectedFiles(prevRejected =>\n prevRejected.filter(rejected => !rejected.errors.includes('TOO_MANY_FILES'))\n )\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n deleteButtonRefs.current = []\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale: defaultLocale,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id=\"image_uploads\"\n multiple={multiple}\n name=\"image_uploads\"\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n children: ReactNode\n className?: string\n}\n\nexport const Item = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemProps) => {\n return (\n <li\n data-spark-component=\"file-upload-item\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n {children}\n </li>\n )\n}\n\nItem.displayName = 'FileUpload.Item'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the file to delete\n */\n fileIndex: number\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n fileIndex,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, focus on trigger or dropzone\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n }, 0)\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemFileNameProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemFileName = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemFileNameProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-file-name\"\n className={cx('text-body-2 truncate font-medium', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemFileName.displayName = 'FileUpload.ItemFileName'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemSizeTextProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemSizeText = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemSizeTextProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-size-text\"\n className={cx('text-caption', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\n","import { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * The index of the file in the accepted files array\n */\n fileIndex: number\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n className?: string\n}\n\nexport const AcceptedFile = ({\n asChild: _asChild = false,\n className,\n file,\n fileIndex,\n uploadProgress,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={className} {...props}>\n <div className=\"size-sz-40 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">{formatFileSize(file.size, locale)}</ItemSizeText>\n </div>\n {uploadProgress !== undefined && (\n <div className=\"mt-md\">\n <Progress\n value={uploadProgress}\n max={100}\n aria-label={`Upload progress: ${uploadProgress}%`}\n />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label=\"Delete file\" fileIndex={fileIndex} />\n </Item>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\nexport function Dropzone({\n children,\n onFiles,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n onFiles?: (files: FileList) => void\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n onFiles?.(files)\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n asChild: _asChild = false,\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * The index of the rejected file in the rejectedFiles array\n */\n rejectedFileIndex: number\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n className?: string\n}\n\nexport const RejectedFile = ({\n asChild: _asChild = false,\n className,\n rejectedFile,\n rejectedFileIndex,\n renderError,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={cx('border-error border-md', className)} {...props}>\n <div className=\"size-sz-40 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{rejectedFile.file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </ItemSizeText>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger\n aria-label={`Remove ${rejectedFile.file.name} error`}\n rejectedFileIndex={rejectedFileIndex}\n />\n </Item>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the rejected file to remove\n */\n rejectedFileIndex: number\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFileIndex,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Try to focus on trigger or dropzone if available\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }, 0)\n\n onClick?.(e)\n }\n\n return (\n <IconButton\n ref={buttonRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly } = useFileUploadContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n const buttonComponent = unstyled ? 'button' : Button\n const Comp = asChild ? Slot : buttonComponent\n\n return (\n <Comp\n // htmlFor=\"image_uploads\"\n type=\"button\"\n ref={(node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }}\n design={design}\n intent={intent}\n data-spark-component=\"file-upload-trigger\"\n className={cx(className)}\n disabled={disabled || readOnly}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n","import { FileUpload as Root, type FileUploadFileError, type RejectedFile } from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { Dropzone } from './FileUploadDropzone'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type { RejectedFile, FileUploadFileError }\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n Item: typeof Item\n ItemFileName: typeof ItemFileName\n ItemSizeText: typeof ItemSizeText\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n Trigger,\n Dropzone,\n Context,\n Item,\n ItemFileName,\n ItemSizeText,\n ItemDeleteTrigger,\n PreviewImage,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItem.displayName = 'FileUpload.Item'\nItemFileName.displayName = 'FileUpload.ItemFileName'\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n"],"mappings":"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","names":["extension","fileName","formatter","jsx","cx","useRef","jsx","useRef","cx","cx","jsx","cx","jsx","jsx","jsxs","jsx","cx","useRef","jsx","useRef","cx","cx","useState","jsx","jsxs","cx","Close","cx","useRef","jsx","useRef","cx","Close","jsx","jsxs","cx","cx","jsx","cx","FileUpload"]}
1
+ {"version":3,"sources":["../../src/file-upload/FileUpload.tsx","../../src/file-upload/utils.ts","../../src/file-upload/FileUploadItem.tsx","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/file-upload/FileUploadItemFileName.tsx","../../src/file-upload/FileUploadItemSizeText.tsx","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx","../../src/file-upload/index.ts"],"sourcesContent":["/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { createContext, ReactNode, Ref, useContext, useRef, useState } from 'react'\n\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are selected\n */\n onFilesChange?: (files: File[]) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Callback when the maximum number of files is reached\n * @param maxFiles - The maximum number of files allowed\n * @param rejectedCount - The number of files that were rejected\n */\n onMaxFilesReached?: (maxFiles: number, rejectedCount: number) => void\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * Callback when a file size validation error occurs\n * @param file - The file that failed validation\n * @param error - The error message\n */\n onFileSizeError?: (file: File, error: string) => void\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport type FileUploadFileError =\n | 'TOO_MANY_FILES'\n | 'FILE_INVALID_TYPE'\n | 'FILE_TOO_LARGE'\n | 'FILE_TOO_SMALL'\n | 'FILE_INVALID'\n | 'FILE_EXISTS'\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n} | null>(null)\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFilesChange,\n multiple = true,\n accept,\n maxFiles,\n onMaxFilesReached,\n maxFileSize,\n minFileSize,\n onFileSizeError,\n disabled = false,\n readOnly = false,\n locale,\n}: FileUploadProps) => {\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n const [filesState, setFilesState, ,] = useCombinedState(\n controlledValue,\n defaultValue,\n onFilesChange\n )\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n\n // Call onFileSizeError callback if provided\n if (onFileSizeError) {\n onFileSizeError(file, error)\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n // Check maxFiles limit FIRST for all files (even if they will be rejected by other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, mark all new files with TOO_MANY_FILES error\n newFiles.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n }\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, 'FILE_INVALID_TYPE')\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, 'FILE_TOO_LARGE')\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, 'FILE_TOO_SMALL')\n } else {\n addRejectedFile(file, 'FILE_INVALID')\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n // This must be done AFTER size validation but BEFORE maxFiles check\n const seenFiles = new Map<string, File>()\n const duplicateFiles: File[] = []\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Track files rejected by maxFiles limit (only for files that passed other validations)\n // Note: We already checked maxFiles at the beginning for ALL files to allow multiple error codes\n // This second check is to prevent adding files when we're at the limit\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, reject all new files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n onMaxFilesReached?.(maxFiles, filesToAdd.length)\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n if (maxFiles !== undefined && updated.length < maxFiles) {\n setRejectedFiles(prevRejected =>\n prevRejected.filter(rejected => !rejected.errors.includes('TOO_MANY_FILES'))\n )\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n deleteButtonRefs.current = []\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale: defaultLocale,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id=\"image_uploads\"\n multiple={multiple}\n name=\"image_uploads\"\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n children: ReactNode\n className?: string\n}\n\nexport const Item = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemProps) => {\n return (\n <li\n data-spark-component=\"file-upload-item\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n {children}\n </li>\n )\n}\n\nItem.displayName = 'FileUpload.Item'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the file to delete\n */\n fileIndex: number\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n fileIndex,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, focus on trigger or dropzone\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n }, 0)\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemFileNameProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemFileName = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemFileNameProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-file-name\"\n className={cx('text-body-2 truncate font-medium', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemFileName.displayName = 'FileUpload.ItemFileName'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, ReactNode, Ref } from 'react'\n\nexport interface FileUploadItemSizeTextProps extends ComponentPropsWithoutRef<'p'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLParagraphElement>\n className?: string\n children?: ReactNode\n}\n\nexport const ItemSizeText = ({\n asChild: _asChild = false,\n className,\n children,\n ...props\n}: FileUploadItemSizeTextProps) => {\n return (\n <p\n data-spark-component=\"file-upload-item-size-text\"\n className={cx('text-caption', className)}\n {...props}\n >\n {children}\n </p>\n )\n}\n\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\n","import { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * The index of the file in the accepted files array\n */\n fileIndex: number\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n /**\n * Accessible label for the progress bar. Required when uploadProgress is provided.\n */\n progressAriaLabel?: string\n className?: string\n}\n\nexport const AcceptedFile = ({\n asChild: _asChild = false,\n className,\n file,\n fileIndex,\n uploadProgress,\n deleteButtonAriaLabel,\n progressAriaLabel,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={className} {...props}>\n <div className=\"size-sz-40 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">{formatFileSize(file.size, locale)}</ItemSizeText>\n </div>\n {uploadProgress !== undefined && (\n <div className=\"mt-md\">\n <Progress value={uploadProgress} max={100} aria-label={progressAriaLabel} />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label={deleteButtonAriaLabel} fileIndex={fileIndex} />\n </Item>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\nexport function Dropzone({\n children,\n onFiles,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n onFiles?: (files: FileList) => void\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n onFiles?.(files)\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n asChild: _asChild = false,\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { Item } from './FileUploadItem'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * The index of the rejected file in the rejectedFiles array\n */\n rejectedFileIndex: number\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n className?: string\n}\n\nexport const RejectedFile = ({\n asChild: _asChild = false,\n className,\n rejectedFile,\n rejectedFileIndex,\n renderError,\n deleteButtonAriaLabel,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <Item className={cx('border-error border-md', className)} {...props}>\n <div className=\"size-sz-40 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <ItemFileName>{rejectedFile.file.name}</ItemFileName>\n <ItemSizeText className=\"opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </ItemSizeText>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger\n aria-label={deleteButtonAriaLabel}\n rejectedFileIndex={rejectedFileIndex}\n />\n </Item>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * Index of the rejected file to remove\n */\n rejectedFileIndex: number\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFileIndex,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Try to focus on trigger or dropzone if available\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }, 0)\n\n onClick?.(e)\n }\n\n return (\n <IconButton\n ref={buttonRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly } = useFileUploadContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n const buttonComponent = unstyled ? 'button' : Button\n const Comp = asChild ? Slot : buttonComponent\n\n return (\n <Comp\n // htmlFor=\"image_uploads\"\n type=\"button\"\n ref={(node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }}\n design={design}\n intent={intent}\n data-spark-component=\"file-upload-trigger\"\n className={cx(className)}\n disabled={disabled || readOnly}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n","import { FileUpload as Root, type FileUploadFileError, type RejectedFile } from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { Dropzone } from './FileUploadDropzone'\nimport { Item } from './FileUploadItem'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { ItemFileName } from './FileUploadItemFileName'\nimport { ItemSizeText } from './FileUploadItemSizeText'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type { RejectedFile, FileUploadFileError }\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n Item: typeof Item\n ItemFileName: typeof ItemFileName\n ItemSizeText: typeof ItemSizeText\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n Trigger,\n Dropzone,\n Context,\n Item,\n ItemFileName,\n ItemSizeText,\n ItemDeleteTrigger,\n PreviewImage,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItem.displayName = 'FileUpload.Item'\nItemFileName.displayName = 'FileUpload.ItemFileName'\nItemSizeText.displayName = 'FileUpload.ItemSizeText'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n"],"mappings":"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","names":["extension","fileName","formatter","jsx","cx","useRef","jsx","useRef","cx","cx","jsx","cx","jsx","jsx","jsxs","jsx","cx","useRef","jsx","useRef","cx","cx","useState","jsx","jsxs","cx","Close","cx","useRef","jsx","useRef","cx","Close","jsx","jsxs","cx","cx","jsx","cx","FileUpload"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-ui/components",
3
- "version": "11.4.0",
3
+ "version": "11.4.2",
4
4
  "license": "MIT",
5
5
  "description": "Spark (Leboncoin design system) components.",
6
6
  "exports": {
@@ -53,11 +53,11 @@
53
53
  "@react-aria/toast": "^3.0.0-beta.18",
54
54
  "@react-stately/numberfield": "3.9.11",
55
55
  "@react-stately/toast": "^3.0.0-beta.7",
56
- "@spark-ui/hooks": "^11.4.0",
57
- "@spark-ui/icons": "^11.4.0",
58
- "@spark-ui/internal-utils": "^11.4.0",
59
- "@zag-js/pagination": "1.25.0",
60
- "@zag-js/react": "1.25.0",
56
+ "@spark-ui/hooks": "^11.4.2",
57
+ "@spark-ui/icons": "^11.4.2",
58
+ "@spark-ui/internal-utils": "^11.4.2",
59
+ "@zag-js/pagination": "1.28.0",
60
+ "@zag-js/react": "1.28.0",
61
61
  "class-variance-authority": "0.7.1",
62
62
  "downshift": "9.0.10",
63
63
  "emulate-tab": "^1.2.1",
@@ -82,5 +82,5 @@
82
82
  "url": "https://github.com/leboncoin/spark-web/issues?q=is%3Aopen+label%3A%22Component%3A+button%22"
83
83
  },
84
84
  "homepage": "https://sparkui.vercel.app",
85
- "gitHead": "0e0da6241debedaa1cf73b2fe402e4106d7c0662"
85
+ "gitHead": "645324726513881f9d23c9cf32e989d70e4936c4"
86
86
  }