{"version":3,"sources":["../../src/components/FileInput.tsx","../../src/components/FileInputButton.tsx","../../src/components/icons/Upload.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useCallback, useState, type DragEvent, type ReactNode } from 'react';\nimport Typography from '@mui/material/Typography';\nimport { styled, useThemeProps } from '@mui/material/styles';\n\nimport varnishTokens from '@allenai/varnish-theme/mui';\n\nimport { FileInputButton } from './FileInputButton';\n\ninterface FileInputProps {\n    onSelect?: (files: FileList | null) => void;\n    acceptedFileTypes?: string[];\n    allowsMultiple?: boolean;\n    icon?: ReactNode;\n    defaultText?: string | ReactNode;\n    variant?: 'contained' | 'outlined';\n    size?: 'small' | 'medium' | 'large' | 'full';\n    errorMessage?: string;\n    className?: string;\n    disabled?: boolean;\n    children?: ReactNode;\n}\n\ninterface FileInputOwnerState {\n    variant: 'contained' | 'outlined';\n    size: 'small' | 'medium' | 'large' | 'full';\n    isDragOver: boolean;\n    hasError: boolean;\n}\n\nconst sizeStyles = {\n    small: { padding: varnishTokens.spacing[2].value },\n    medium: { padding: varnishTokens.spacing[3].value },\n    large: { padding: varnishTokens.spacing[5].value },\n    full: { padding: varnishTokens.spacing[3].value, width: '100%' },\n} as const;\n\nconst FileInputRoot = styled('div', {\n    name: 'MuiFileInput',\n    slot: 'root',\n})<{ ownerState: FileInputOwnerState }>(({ theme, ownerState }) => ({\n    display: 'flex',\n    flexDirection: 'column',\n    alignItems: 'center',\n    justifyContent: 'center',\n    gap: theme.spacing(1),\n    borderRadius: theme.shape.borderRadius,\n    transition: 'border-color 0.2s, background-color 0.2s',\n    ...sizeStyles[ownerState.size],\n\n    ...(ownerState.variant === 'contained' && {\n        backgroundColor: theme.palette.form.input.fill,\n        border: `2px solid ${theme.palette.form.input.stroke}`,\n    }),\n\n    ...(ownerState.variant === 'outlined' && {\n        backgroundColor: 'transparent',\n        border: `2px dashed ${theme.palette.form.input.stroke}`,\n    }),\n\n    ...(ownerState.isDragOver && {\n        borderColor: theme.palette.primary.main,\n        backgroundColor:\n            ownerState.variant === 'contained'\n                ? theme.palette.action.hover\n                : theme.palette.primary.main + '0A',\n    }),\n\n    ...(ownerState.hasError && {\n        borderColor: theme.palette.error.main,\n    }),\n}));\n\nfunction filterFiles(files: FileList, acceptedFileTypes?: string[]): FileList {\n    if (!acceptedFileTypes || acceptedFileTypes.length === 0) {\n        return files;\n    }\n    const dt = new DataTransfer();\n    for (let i = 0; i < files.length; i++) {\n        const file = files[i];\n        if (acceptedFileTypes.includes(file.type)) {\n            dt.items.add(file);\n        }\n    }\n    return dt.files;\n}\n\nconst FileInput = forwardRef<HTMLDivElement, FileInputProps>(function FileInput(inProps, ref) {\n    const props = useThemeProps({ props: inProps, name: 'MuiFileInput' });\n    const {\n        onSelect,\n        acceptedFileTypes,\n        allowsMultiple = false,\n        icon,\n        defaultText = 'Drag & Drop or browse',\n        variant = 'outlined',\n        size = 'medium',\n        errorMessage,\n        className,\n        disabled,\n        children,\n    } = props;\n\n    const [isDragOver, setIsDragOver] = useState(false);\n    const [fileNames, setFileNames] = useState('');\n\n    const ownerState: FileInputOwnerState = {\n        variant,\n        size,\n        isDragOver,\n        hasError: !!errorMessage,\n    };\n\n    const handleFiles = useCallback(\n        (raw: FileList) => {\n            let filtered = filterFiles(raw, acceptedFileTypes);\n\n            if (!allowsMultiple && filtered.length > 1) {\n                const dt = new DataTransfer();\n                dt.items.add(filtered[0]);\n                filtered = dt.files;\n            }\n\n            const names: string[] = [];\n            for (let i = 0; i < filtered.length; i++) {\n                names.push(filtered[i].name);\n            }\n            setFileNames(names.join(', '));\n            onSelect?.(filtered);\n        },\n        [acceptedFileTypes, allowsMultiple, onSelect]\n    );\n\n    const handleDragOver = useCallback(\n        (e: DragEvent<HTMLDivElement>) => {\n            e.preventDefault();\n            if (!disabled) {\n                setIsDragOver(true);\n            }\n        },\n        [disabled]\n    );\n\n    const handleDragLeave = useCallback(() => {\n        setIsDragOver(false);\n    }, []);\n\n    const handleDrop = useCallback(\n        (e: DragEvent<HTMLDivElement>) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            if (disabled) {\n                return;\n            }\n            if (e.dataTransfer.files.length > 0) {\n                handleFiles(e.dataTransfer.files);\n            }\n        },\n        [disabled, handleFiles]\n    );\n\n    return (\n        <FileInputRoot\n            ref={ref}\n            ownerState={ownerState}\n            className={className}\n            onDragOver={handleDragOver}\n            onDragLeave={handleDragLeave}\n            onDrop={handleDrop}>\n            {children || (\n                <>\n                    <FileInputButton\n                        variant={variant === 'outlined' ? 'outlined' : 'contained'}\n                        size={size === 'full' ? 'medium' : size}\n                        onSelect={(files) => {\n                            if (files) {\n                                handleFiles(files);\n                            }\n                        }}\n                        acceptedFileTypes={acceptedFileTypes}\n                        allowsMultiple={allowsMultiple}\n                        icon={icon}\n                        buttonText={fileNames || defaultText}\n                        disabled={disabled}\n                    />\n                    {fileNames ? (\n                        <Typography variant=\"body2\" color=\"text.secondary\">\n                            {fileNames}\n                        </Typography>\n                    ) : null}\n                </>\n            )}\n            {errorMessage ? (\n                <Typography variant=\"body2\" color=\"error\">\n                    {errorMessage}\n                </Typography>\n            ) : null}\n        </FileInputRoot>\n    );\n});\n\nexport { FileInput };\nexport type { FileInputProps };\n","'use client';\n\nimport { forwardRef, useCallback, useRef, type ChangeEvent, type ReactNode } from 'react';\nimport Button from '@mui/material/Button';\nimport { styled, useThemeProps } from '@mui/material/styles';\n\nimport { Upload } from './icons';\n\ninterface FileInputButtonProps {\n    onSelect?: (files: FileList | null) => void;\n    acceptedFileTypes?: string[];\n    allowsMultiple?: boolean;\n    icon?: ReactNode | false;\n    buttonText?: string | ReactNode;\n    variant?: 'contained' | 'outlined';\n    size?: 'small' | 'medium' | 'large';\n    className?: string;\n    disabled?: boolean;\n}\n\nconst FileInputButtonRoot = styled('span', {\n    name: 'MuiFileInputButton',\n    slot: 'root',\n})({\n    display: 'inline-flex',\n});\n\nconst FileInputButtonHiddenInput = styled('input', {\n    name: 'MuiFileInputButton',\n    slot: 'hiddenInput',\n})({\n    display: 'none',\n});\n\nconst FileInputButton = forwardRef<HTMLSpanElement, FileInputButtonProps>(\n    function FileInputButton(inProps, ref) {\n        const props = useThemeProps({ props: inProps, name: 'MuiFileInputButton' });\n        const {\n            onSelect,\n            acceptedFileTypes,\n            allowsMultiple = false,\n            icon,\n            buttonText = 'Browse files',\n            variant = 'contained',\n            size = 'medium',\n            className,\n            disabled,\n        } = props;\n\n        const inputRef = useRef<HTMLInputElement>(null);\n\n        const handleClick = useCallback(() => {\n            inputRef.current?.click();\n        }, []);\n\n        const handleChange = useCallback(\n            (e: ChangeEvent<HTMLInputElement>) => {\n                onSelect?.(e.target.files);\n                // Reset so the same file can be selected again\n                if (inputRef.current) {\n                    inputRef.current.value = '';\n                }\n            },\n            [onSelect]\n        );\n\n        const accept = acceptedFileTypes?.join(',');\n\n        return (\n            <FileInputButtonRoot ref={ref} className={className}>\n                <FileInputButtonHiddenInput\n                    ref={inputRef}\n                    type=\"file\"\n                    accept={accept}\n                    multiple={allowsMultiple}\n                    onChange={handleChange}\n                />\n                <Button\n                    variant={variant}\n                    size={size}\n                    disabled={disabled}\n                    onClick={handleClick}\n                    startIcon={icon !== false ? (icon ?? <Upload />) : undefined}>\n                    {buttonText}\n                </Button>\n            </FileInputButtonRoot>\n        );\n    }\n);\n\nexport { FileInputButton };\nexport type { FileInputButtonProps };\n","import { createSvgIcon } from '@mui/material/utils';\n\nconst Upload = createSvgIcon(\n    <svg viewBox=\"0 -960 960 960\">\n        <path d=\"M440-320v-326L336-542l-56-58 200-200 200 200-56 58-104-104v326h-80ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z\" />\n    </svg>,\n    'Upload'\n);\n\nexport { Upload };\n"],"mappings":"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","names":["import_react","import_styles","import_jsx_runtime","FileInputButton","Button","import_jsx_runtime","varnishTokens","FileInput","Typography"]}