@mantine/dropzone
Version:
Dropzone component built with Mantine theme and components
1 lines • 12 kB
Source Map (JSON)
{"version":3,"file":"Dropzone.mjs","names":["classes"],"sources":["../src/Dropzone.tsx"],"sourcesContent":["import {\n Accept,\n DropEvent,\n FileError,\n FileRejection,\n FileWithPath,\n useDropzone,\n} from 'react-dropzone';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getRadius,\n LoaderProps,\n LoadingOverlay,\n MantineColor,\n MantineRadius,\n StylesApiProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport { assignRef } from '@mantine/hooks';\nimport { DropzoneProvider } from './Dropzone.context';\nimport type {\n DropzoneFullScreenFactory,\n DropzoneFullScreenProps,\n DropzoneFullScreenStylesNames,\n DropzoneFullScreenType,\n} from './DropzoneFullScreen';\nimport { DropzoneAccept, DropzoneIdle, DropzoneReject } from './DropzoneStatus';\nimport classes from './Dropzone.module.css';\n\nexport type DropzoneStylesNames = 'root' | 'inner';\nexport type DropzoneVariant = 'filled' | 'light';\nexport type DropzoneCssVariables = {\n root:\n | '--dropzone-radius'\n | '--dropzone-accept-color'\n | '--dropzone-accept-bg'\n | '--dropzone-reject-color'\n | '--dropzone-reject-bg';\n};\n\nexport interface DropzoneProps\n extends BoxProps, StylesApiProps<DropzoneFactory>, ElementProps<'div', 'onDrop'> {\n /** Key of `theme.colors` or any valid CSS color to set colors of `Dropzone.Accept` @default theme.primaryColor */\n acceptColor?: MantineColor;\n\n /** Key of `theme.colors` or any valid CSS color to set colors of `Dropzone.Reject` @default 'red' */\n rejectColor?: MantineColor;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Determines whether files capturing should be disabled @default false */\n disabled?: boolean;\n\n /** Called when any files are dropped to the dropzone */\n onDropAny?: (files: FileWithPath[], fileRejections: FileRejection[]) => void;\n\n /** Called when valid files are dropped to the dropzone */\n onDrop: (files: FileWithPath[]) => void;\n\n /** Called when dropped files do not meet file restrictions */\n onReject?: (fileRejections: FileRejection[]) => void;\n\n /** Determines whether a loading overlay should be displayed over the dropzone @default false */\n loading?: boolean;\n\n /** Mime types of the files that dropzone can accepts. By default, dropzone accepts all file types. */\n accept?: Accept | string[];\n\n /** A ref function which when called opens the file system file picker */\n openRef?: React.Ref<() => void | undefined>;\n\n /** Determines whether multiple files can be dropped to the dropzone or selected from file system picker @default true */\n multiple?: boolean;\n\n /** Maximum file size in bytes */\n maxSize?: number;\n\n /** Name of the form control. Submitted with the form as part of a name/value pair. */\n name?: string;\n\n /** Maximum number of files that can be picked at once */\n maxFiles?: number;\n\n /** Set to autofocus the root element */\n autoFocus?: boolean;\n\n /** If `false`, disables click to open the native file selection dialog */\n activateOnClick?: boolean;\n\n /** If `false`, disables drag 'n' drop */\n activateOnDrag?: boolean;\n\n /** If `false`, disables Space/Enter to open the native file selection dialog. Note that it also stops tracking the focus state. */\n activateOnKeyboard?: boolean;\n\n /** If `false`, stops drag event propagation to parents */\n dragEventsBubbling?: boolean;\n\n /** Called when the `dragenter` event occurs */\n onDragEnter?: (event: React.DragEvent<HTMLElement>) => void;\n\n /** Called when the `dragleave` event occurs */\n onDragLeave?: (event: React.DragEvent<HTMLElement>) => void;\n\n /** Called when the `dragover` event occurs */\n onDragOver?: (event: React.DragEvent<HTMLElement>) => void;\n\n /** Called when user closes the file selection dialog with no selection */\n onFileDialogCancel?: () => void;\n\n /** Called when user opens the file selection dialog */\n onFileDialogOpen?: () => void;\n\n /** If `false`, allow dropped items to take over the current browser window */\n preventDropOnDocument?: boolean;\n\n /** Set to true to use the File System Access API to open the file picker instead of using an `input type=\"file\"` click event @default false */\n useFsAccessApi?: boolean;\n\n /** Use this to provide a custom file aggregator */\n getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;\n\n /** Custom validation function. It must return null if there's no errors. */\n validator?: <T extends File>(file: T) => FileError | FileError[] | null;\n\n /** Determines whether pointer events should be enabled on the inner element @default false */\n enablePointerEvents?: boolean;\n\n /** Props passed down to the Loader component */\n loaderProps?: LoaderProps;\n\n /** Props passed down to the internal Input component */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n}\n\nexport type DropzoneFactory = Factory<{\n props: DropzoneProps;\n ref: HTMLDivElement;\n stylesNames: DropzoneStylesNames;\n vars: DropzoneCssVariables;\n staticComponents: {\n Accept: typeof DropzoneAccept;\n Idle: typeof DropzoneIdle;\n Reject: typeof DropzoneReject;\n FullScreen: DropzoneFullScreenType;\n };\n}>;\n\nconst defaultProps = {\n multiple: true,\n maxSize: Infinity,\n activateOnClick: true,\n activateOnDrag: true,\n dragEventsBubbling: true,\n activateOnKeyboard: true,\n useFsAccessApi: false,\n variant: 'light',\n rejectColor: 'red',\n} satisfies Partial<DropzoneProps>;\n\nconst varsResolver = createVarsResolver<DropzoneFactory>(\n (theme, { radius, variant, acceptColor, rejectColor }) => {\n const acceptColors = theme.variantColorResolver({\n color: acceptColor || theme.primaryColor,\n theme,\n variant: variant!,\n });\n\n const rejectColors = theme.variantColorResolver({\n color: rejectColor || 'red',\n theme,\n variant: variant!,\n });\n\n return {\n root: {\n '--dropzone-radius': getRadius(radius),\n '--dropzone-accept-color': acceptColors.color,\n '--dropzone-accept-bg': acceptColors.background,\n '--dropzone-reject-color': rejectColors.color,\n '--dropzone-reject-bg': rejectColors.background,\n },\n };\n }\n);\n\nexport const Dropzone = factory<DropzoneFactory>((_props) => {\n const props = useProps('Dropzone', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n radius,\n disabled,\n loading,\n multiple,\n maxSize,\n accept,\n children,\n onDropAny,\n onDrop,\n onReject,\n openRef,\n name,\n maxFiles,\n autoFocus,\n activateOnClick,\n activateOnDrag,\n dragEventsBubbling,\n activateOnKeyboard,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onFileDialogCancel,\n onFileDialogOpen,\n preventDropOnDocument,\n useFsAccessApi,\n getFilesFromEvent,\n validator,\n rejectColor,\n acceptColor,\n enablePointerEvents,\n loaderProps,\n inputProps,\n mod,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<DropzoneFactory>({\n name: 'Dropzone',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { getRootProps, getInputProps, isDragAccept, isDragReject, isDragActive, open } =\n useDropzone({\n onDrop: onDropAny,\n onDropAccepted: onDrop,\n onDropRejected: onReject,\n disabled: disabled || loading,\n accept: Array.isArray(accept) ? accept.reduce((r, key) => ({ ...r, [key]: [] }), {}) : accept,\n multiple,\n maxSize,\n maxFiles,\n autoFocus,\n noClick: !activateOnClick,\n noDrag: !activateOnDrag,\n noDragEventsBubbling: !dragEventsBubbling,\n noKeyboard: !activateOnKeyboard,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onFileDialogCancel,\n onFileDialogOpen,\n preventDropOnDocument,\n useFsAccessApi,\n validator,\n ...(getFilesFromEvent ? { getFilesFromEvent } : null),\n });\n\n assignRef(openRef, open);\n\n const isAccepted = isDragActive && isDragAccept;\n const isRejected = isDragActive && isDragReject;\n const isIdle = !isAccepted && !isRejected;\n\n return (\n <DropzoneProvider value={{ accept: isAccepted, reject: isRejected, idle: isIdle }}>\n <Box\n {...getRootProps()}\n {...getStyles('root', { focusable: true })}\n {...others}\n mod={[\n {\n accept: isAccepted,\n reject: isRejected,\n idle: isIdle,\n disabled,\n loading,\n 'activate-on-click': activateOnClick,\n },\n mod,\n ]}\n >\n <LoadingOverlay\n visible={loading}\n overlayProps={{ radius }}\n unstyled={unstyled}\n loaderProps={loaderProps}\n />\n <input {...getInputProps(inputProps)} name={name} />\n <div {...getStyles('inner')} data-enable-pointer-events={enablePointerEvents || undefined}>\n {children}\n </div>\n </Box>\n </DropzoneProvider>\n );\n});\n\nDropzone.classes = classes;\nDropzone.varsResolver = varsResolver;\nDropzone.displayName = '@mantine/dropzone/Dropzone';\nDropzone.Accept = DropzoneAccept;\nDropzone.Idle = DropzoneIdle;\nDropzone.Reject = DropzoneReject;\n\nexport namespace Dropzone {\n export type Props = DropzoneProps;\n export type StylesNames = DropzoneStylesNames;\n export type CssVariables = DropzoneCssVariables;\n export type Factory = DropzoneFactory;\n\n export namespace FullScreen {\n export type Props = DropzoneFullScreenProps;\n export type StylesNames = DropzoneFullScreenStylesNames;\n export type Factory = DropzoneFullScreenFactory;\n }\n}\n"],"mappings":";;;;;;;;;AA2JA,MAAM,eAAe;CACnB,UAAU;CACV,SAAS;CACT,iBAAiB;CACjB,gBAAgB;CAChB,oBAAoB;CACpB,oBAAoB;CACpB,gBAAgB;CAChB,SAAS;CACT,aAAa;AACf;AAEA,MAAM,eAAe,oBAClB,OAAO,EAAE,QAAQ,SAAS,aAAa,kBAAkB;CACxD,MAAM,eAAe,MAAM,qBAAqB;EAC9C,OAAO,eAAe,MAAM;EAC5B;EACS;CACX,CAAC;CAED,MAAM,eAAe,MAAM,qBAAqB;EAC9C,OAAO,eAAe;EACtB;EACS;CACX,CAAC;CAED,OAAO,EACL,MAAM;EACJ,qBAAqB,UAAU,MAAM;EACrC,2BAA2B,aAAa;EACxC,wBAAwB,aAAa;EACrC,2BAA2B,aAAa;EACxC,wBAAwB,aAAa;CACvC,EACF;AACF,CACF;AAEA,MAAa,WAAW,SAA0B,WAAW;CAC3D,MAAM,QAAQ,SAAS,YAAY,cAAc,MAAM;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,QACA,UACA,SACA,UACA,SACA,QACA,UACA,WACA,QACA,UACA,SACA,MACA,UACA,WACA,iBACA,gBACA,oBACA,oBACA,aACA,aACA,YACA,oBACA,kBACA,uBACA,gBACA,mBACA,WACA,aACA,aACA,qBACA,aACA,YACA,KACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAA2B;EAC3C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,cAAc,eAAe,cAAc,cAAc,cAAc,SAC7E,YAAY;EACV,QAAQ;EACR,gBAAgB;EAChB,gBAAgB;EAChB,UAAU,YAAY;EACtB,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,QAAQ,GAAG,SAAS;GAAE,GAAG;IAAI,MAAM,CAAC;EAAE,IAAI,CAAC,CAAC,IAAI;EACvF;EACA;EACA;EACA;EACA,SAAS,CAAC;EACV,QAAQ,CAAC;EACT,sBAAsB,CAAC;EACvB,YAAY,CAAC;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAI,oBAAoB,EAAE,kBAAkB,IAAI;CAClD,CAAC;CAEH,UAAU,SAAS,IAAI;CAEvB,MAAM,aAAa,gBAAgB;CACnC,MAAM,aAAa,gBAAgB;CACnC,MAAM,SAAS,CAAC,cAAc,CAAC;CAE/B,OACE,oBAAC,kBAAD;EAAkB,OAAO;GAAE,QAAQ;GAAY,QAAQ;GAAY,MAAM;EAAO;YAC9E,qBAAC,KAAD;GACE,GAAI,aAAa;GACjB,GAAI,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;GACzC,GAAI;GACJ,KAAK,CACH;IACE,QAAQ;IACR,QAAQ;IACR,MAAM;IACN;IACA;IACA,qBAAqB;GACvB,GACA,GACF;aAdF;IAgBE,oBAAC,gBAAD;KACE,SAAS;KACT,cAAc,EAAE,OAAO;KACb;KACG;IACd,CAAA;IACD,oBAAC,SAAD;KAAO,GAAI,cAAc,UAAU;KAAS;IAAO,CAAA;IACnD,oBAAC,OAAD;KAAK,GAAI,UAAU,OAAO;KAAG,8BAA4B,uBAAuB,KAAA;KAC7E;IACE,CAAA;GACF;;CACW,CAAA;AAEtB,CAAC;AAED,SAAS,UAAUA;AACnB,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,SAAS;AAClB,SAAS,OAAO;AAChB,SAAS,SAAS"}