@react-magma/dropzone 13.0.0 → 13.0.1-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -141,7 +141,6 @@ const formatError = (
141
141
  const messageSuffix = Array.isArray(accept)
142
142
  ? `one of ${accept.join(', ')}`
143
143
  : accept;
144
-
145
144
  switch (error.code) {
146
145
  case 'file-too-large':
147
146
  return {
@@ -168,178 +167,177 @@ const formatError = (
168
167
  }
169
168
  };
170
169
 
171
- export const Preview = forwardRef<
172
- HTMLDivElement,
173
- Omit<PreviewProps, 'children'>
174
- >((props, ref) => {
175
- const {
176
- accept,
177
- file,
178
- isInverse: isInverseProp,
179
- maxSize,
180
- minSize,
181
- onDeleteFile,
182
- onRemoveFile,
183
- testId,
184
- thumbnails,
185
- ...rest
186
- } = props;
170
+ export const Preview = forwardRef<HTMLDivElement, PreviewProps>(
171
+ // eslint-disable-next-line complexity
172
+ (props, ref) => {
173
+ const {
174
+ accept,
175
+ file,
176
+ isInverse: isInverseProp,
177
+ maxSize,
178
+ minSize,
179
+ onDeleteFile,
180
+ onRemoveFile,
181
+ testId,
182
+ thumbnails,
183
+ ...rest
184
+ } = props;
187
185
 
188
- const theme: ThemeInterface = useContext(ThemeContext);
189
- const i18n: I18nInterface = React.useContext(I18nContext);
190
- const isInverse = useIsInverse(isInverseProp);
191
- const [actions, setActions] = useState(<CloseIcon />);
186
+ const theme: ThemeInterface = useContext(ThemeContext);
187
+ const i18n: I18nInterface = React.useContext(I18nContext);
188
+ const isInverse = useIsInverse(isInverseProp);
189
+ const [actions, setActions] = useState(<CloseIcon />);
192
190
 
193
- const handleRemoveFile = () => {
194
- onRemoveFile && typeof onRemoveFile === 'function' && onRemoveFile(file);
195
- };
191
+ const handleRemoveFile = () => {
192
+ onRemoveFile && typeof onRemoveFile === 'function' && onRemoveFile(file);
193
+ };
196
194
 
197
- const handleDeleteFile = () => {
198
- onDeleteFile && typeof onDeleteFile === 'function' && onDeleteFile(file);
199
- };
195
+ const handleDeleteFile = () => {
196
+ onDeleteFile && typeof onDeleteFile === 'function' && onDeleteFile(file);
197
+ };
200
198
 
201
- const FinishedActions = ({ status = 'ready' }: { status?: string }) => {
202
- const [done, setDone] = useState<boolean>(false);
199
+ const FinishedActions = ({ status = 'ready' }: { status?: string }) => {
200
+ const [done, setDone] = useState<boolean>(false);
203
201
 
204
- useEffect(() => {
205
- let mounted = true;
202
+ useEffect(() => {
203
+ let mounted = true;
204
+ setTimeout(() => {
205
+ if (mounted) {
206
+ setDone(true);
207
+ }
208
+ }, 1000);
209
+ return () => {
210
+ mounted = false;
211
+ };
212
+ }, [status]);
206
213
 
207
- setTimeout(() => {
208
- if (mounted) {
209
- setDone(true);
210
- }
211
- }, 1000);
214
+ if (status === 'error' || status === 'ready') {
215
+ return (
216
+ <StatusIcons>
217
+ <IconButton
218
+ onClick={handleRemoveFile}
219
+ variant={ButtonVariant.link}
220
+ color={ButtonColor.secondary}
221
+ aria-label={i18n.dropzone.removeFile}
222
+ icon={<CloseIcon />}
223
+ />
224
+ </StatusIcons>
225
+ );
226
+ }
212
227
 
213
- return () => {
214
- mounted = false;
215
- };
216
- }, [status]);
228
+ if (status === 'pending') {
229
+ return (
230
+ <StatusIcons>
231
+ <Spinner
232
+ color={isInverse ? theme.colors.neutral100 : theme.colors.primary}
233
+ />
234
+ </StatusIcons>
235
+ );
236
+ }
217
237
 
218
- if (status === 'error' || status === 'ready') {
219
238
  return (
220
239
  <StatusIcons>
221
- <IconButton
222
- onClick={handleRemoveFile}
223
- variant={ButtonVariant.link}
224
- color={ButtonColor.secondary}
225
- aria-label={i18n.dropzone.removeFile}
226
- icon={<CloseIcon />}
227
- />
240
+ <Transition isOpen={!done} unmountOnExit fade>
241
+ <CheckCircleIcon
242
+ color={isInverse ? theme.colors.success200 : theme.colors.success}
243
+ style={{ marginTop: '4px' }}
244
+ />
245
+ </Transition>
246
+ <Transition isOpen={done} unmountOnExit fade>
247
+ <IconButton
248
+ onClick={handleDeleteFile}
249
+ variant={ButtonVariant.link}
250
+ color={ButtonColor.secondary}
251
+ aria-label={i18n.dropzone.deleteFile}
252
+ icon={<DeleteIcon />}
253
+ />
254
+ </Transition>
228
255
  </StatusIcons>
229
256
  );
230
- }
257
+ };
231
258
 
232
- if (status === 'pending') {
233
- return (
234
- <StatusIcons>
235
- <Spinner
236
- color={isInverse ? theme.colors.neutral100 : theme.colors.primary}
237
- />
238
- </StatusIcons>
239
- );
240
- }
259
+ useEffect(() => {
260
+ setActions(<FinishedActions status={file?.processor?.status} />);
261
+ }, [file?.processor?.status]);
241
262
 
242
263
  return (
243
- <StatusIcons>
244
- <Transition isOpen={!done} unmountOnExit fade>
245
- <CheckCircleIcon
246
- color={isInverse ? theme.colors.success200 : theme.colors.success}
247
- style={{ marginTop: '4px' }}
248
- />
249
- </Transition>
250
- <Transition isOpen={done} unmountOnExit fade>
251
- <IconButton
252
- onClick={handleDeleteFile}
253
- variant={ButtonVariant.link}
254
- color={ButtonColor.secondary}
255
- aria-label={i18n.dropzone.deleteFile}
256
- icon={<DeleteIcon />}
257
- />
258
- </Transition>
259
- </StatusIcons>
260
- );
261
- };
262
-
263
- useEffect(() => {
264
- setActions(<FinishedActions status={file?.processor?.status} />);
265
- }, [file?.processor?.status]);
266
-
267
- return (
268
- <InverseContext.Provider value={{ isInverse }}>
269
- <StyledCard
270
- isInverse={isInverse}
271
- theme={theme}
272
- file={file}
273
- data-testid={props.testId}
274
- ref={ref}
275
- role={file.errors ? 'alert' : ''}
276
- >
277
- <StyledFlex
264
+ <InverseContext.Provider value={{ isInverse }}>
265
+ <StyledCard
266
+ isInverse={isInverse}
278
267
  theme={theme}
279
- behavior={FlexBehavior.container}
280
- alignItems={FlexAlignItems.center}
281
- {...rest}
268
+ file={file}
269
+ data-testid={props.testId}
270
+ ref={ref}
271
+ role={file.errors ? 'alert' : ''}
282
272
  >
283
- <Flex
284
- behavior={FlexBehavior.item}
273
+ <StyledFlex
274
+ theme={theme}
275
+ behavior={FlexBehavior.container}
285
276
  alignItems={FlexAlignItems.center}
286
- style={IconStyles}
277
+ {...rest}
287
278
  >
288
- {file.errors ? (
289
- <ErrorIcon
290
- color={isInverse ? theme.colors.danger300 : theme.colors.danger}
291
- size={24}
292
- />
293
- ) : file.preview &&
294
- thumbnails &&
295
- file.type &&
296
- file.type.startsWith('image') ? (
297
- <Thumb role="img" file={file} />
298
- ) : (
299
- <FileIcon isInverse={isInverse} file={file} />
300
- )}
301
- </Flex>
302
- <FileName xs behavior={FlexBehavior.item} theme={theme}>
303
- {file.name}
304
- </FileName>
305
- {file.processor && file.processor.status === 'pending' && (
306
279
  <Flex
307
- role="progressbar"
308
- style={{ marginLeft: 'auto' }}
309
280
  behavior={FlexBehavior.item}
281
+ alignItems={FlexAlignItems.center}
282
+ style={IconStyles}
310
283
  >
311
- {file.processor.percent}
284
+ {file.errors ? (
285
+ <ErrorIcon
286
+ color={
287
+ isInverse ? theme.colors.danger300 : theme.colors.danger
288
+ }
289
+ size={24}
290
+ />
291
+ ) : file.preview &&
292
+ thumbnails &&
293
+ file.type &&
294
+ file.type.startsWith('image') ? (
295
+ <Thumb role="img" file={file} />
296
+ ) : (
297
+ <FileIcon isInverse={isInverse} file={file} />
298
+ )}
312
299
  </Flex>
300
+ <FileName xs behavior={FlexBehavior.item} theme={theme}>
301
+ {file.name}
302
+ </FileName>
303
+ {file.processor && file.processor.status === 'pending' && (
304
+ <Flex
305
+ role="progressbar"
306
+ style={{ marginLeft: 'auto' }}
307
+ behavior={FlexBehavior.item}
308
+ >
309
+ {file.processor.percent}
310
+ </Flex>
311
+ )}
312
+ <Flex behavior={FlexBehavior.item}>{actions}</Flex>
313
+ </StyledFlex>
314
+ {file.errors && (
315
+ <Errors theme={theme}>
316
+ {file.errors.slice(0, 1).map(({ code, ...rest }) => {
317
+ const { header = '', message } = formatError(
318
+ { code, ...rest, ...i18n.dropzone.errors[code] },
319
+ { accept, minSize, maxSize },
320
+ i18n.dropzone.bytes
321
+ );
322
+ return (
323
+ <React.Fragment key={code}>
324
+ <ErrorHeader
325
+ style={{
326
+ color: isInverse
327
+ ? theme.colors.danger200
328
+ : theme.colors.danger,
329
+ }}
330
+ >
331
+ {header}
332
+ </ErrorHeader>
333
+ <ErrorMessage>{message}</ErrorMessage>
334
+ </React.Fragment>
335
+ );
336
+ })}
337
+ </Errors>
313
338
  )}
314
- <Flex behavior={FlexBehavior.item}>{actions}</Flex>
315
- </StyledFlex>
316
- {file.errors && (
317
- <Errors theme={theme}>
318
- {file.errors.slice(0, 1).map(({ code, ...rest }) => {
319
- const { header = '', message } = formatError(
320
- { code, ...rest, ...i18n.dropzone.errors[code] },
321
- { accept, minSize, maxSize },
322
- i18n.dropzone.bytes
323
- );
324
-
325
- return (
326
- <React.Fragment key={code}>
327
- <ErrorHeader
328
- style={{
329
- color: isInverse
330
- ? theme.colors.danger200
331
- : theme.colors.danger,
332
- }}
333
- >
334
- {header}
335
- </ErrorHeader>
336
- <ErrorMessage>{message}</ErrorMessage>
337
- </React.Fragment>
338
- );
339
- })}
340
- </Errors>
341
- )}
342
- </StyledCard>
343
- </InverseContext.Provider>
344
- );
345
- });
339
+ </StyledCard>
340
+ </InverseContext.Provider>
341
+ );
342
+ }
343
+ );
@@ -8,7 +8,6 @@ export const formatFileSize = (
8
8
  const k = 1024;
9
9
  const sizes = [bytesLabel, 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
10
10
  const i = Math.floor(Math.log(bytes) / Math.log(k));
11
-
12
11
  return (
13
12
  parseFloat((bytes / Math.pow(k, i)).toFixed(decimalPoint)) + ' ' + sizes[i]
14
13
  );
@@ -1 +0,0 @@
1
- {"version":3,"file":"fileuploader.modern.mjs","sources":["../src/components/dropzone/FileIcon.tsx","../src/components/dropzone/utils.ts","../src/components/dropzone/Preview.tsx","../src/components/dropzone/Dropzone.tsx"],"sourcesContent":["import React from 'react';\n\nimport { magma } from 'react-magma-dom';\nimport {\n InsertDriveFileIcon,\n ImageIcon,\n AudiotrackIcon,\n VideocamIcon,\n FileExcelIcon,\n FilePdfIcon,\n FilePowerpointIcon,\n FileWordIcon,\n FileZipIcon,\n IconProps,\n} from 'react-magma-icons';\n\nimport { FilePreview } from './FilePreview';\n\nexport interface FileIconProps extends IconProps {\n file: FilePreview;\n isInverse?: boolean;\n}\n\nconst icons = {\n default: {\n Icon: InsertDriveFileIcon,\n style: {\n color: magma.colors.neutral500,\n },\n },\n word: {\n Icon: FileWordIcon,\n style: {\n color: magma.colors.info500,\n },\n },\n excel: {\n Icon: FileExcelIcon,\n style: {\n color: magma.colors.success500,\n },\n },\n powerpoint: {\n Icon: FilePowerpointIcon,\n style: {\n color: magma.colors.warning500,\n },\n },\n pdf: {\n Icon: FilePdfIcon,\n style: {\n color: magma.colors.danger500,\n },\n },\n image: {\n Icon: ImageIcon,\n style: {\n color: magma.colors.neutral500,\n },\n },\n video: {\n Icon: VideocamIcon,\n style: {\n color: magma.colors.neutral500,\n },\n },\n audio: {\n Icon: AudiotrackIcon,\n style: {\n color: magma.colors.neutral500,\n },\n },\n archive: {\n Icon: FileZipIcon,\n style: {\n color: magma.colors.neutral500,\n },\n },\n};\n\nconst iconMapping: {\n [key: string]: { Icon: any; style: React.CSSProperties };\n} = {\n default: icons.default,\n xlsx: icons.excel,\n xlsm: icons.excel,\n xlsb: icons.excel,\n xltx: icons.excel,\n xls: icons.excel,\n xlt: icons.excel,\n doc: icons.word,\n docx: icons.word,\n docm: icons.word,\n dotx: icons.word,\n dotm: icons.word,\n docb: icons.word,\n pptx: icons.powerpoint,\n pptm: icons.powerpoint,\n ppt: icons.powerpoint,\n pdf: icons.pdf,\n png: icons.image,\n svg: icons.image,\n image: icons.image,\n audio: icons.audio,\n video: icons.video,\n zip: icons.archive,\n};\n\nexport const FileIcon = ({ file, isInverse }: FileIconProps) => {\n const { path = '', type = '' } = file;\n const category = type.split('/')[0];\n const extension = path.split('.').pop() || 'default';\n const { Icon, style } =\n iconMapping[extension] || iconMapping[category] || iconMapping.default;\n\n return <Icon size={magma.iconSizes.medium} style={isInverse ? {} : style} />;\n};\n","export const formatFileSize = (\n bytes: number | undefined,\n decimalPoint = 2,\n bytesLabel = 'Bytes'\n) => {\n if (bytes === undefined) return;\n if (bytes == 0) return `0 ${bytesLabel}`;\n const k = 1024;\n const sizes = [bytesLabel, 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return (\n parseFloat((bytes / Math.pow(k, i)).toFixed(decimalPoint)) + ' ' + sizes[i]\n );\n};\n","import React, { forwardRef, useContext, useEffect, useState } from 'react';\n\nimport {\n ButtonColor,\n ButtonVariant,\n Card,\n Flex,\n FlexAlignItems,\n FlexBehavior,\n FlexProps,\n I18nContext,\n I18nInterface,\n IconButton,\n InverseContext,\n ThemeContext,\n ThemeInterface,\n Transition,\n Spinner,\n useIsInverse,\n styled,\n} from 'react-magma-dom';\nimport {\n CheckCircleIcon,\n CloseIcon,\n DeleteIcon,\n ErrorIcon,\n} from 'react-magma-icons';\n\nimport { FileIcon } from './FileIcon';\nimport { FilePreview } from './FilePreview';\nimport { formatFileSize } from './utils';\n\nexport interface PreviewProps extends Omit<FlexProps, 'behavior'> {\n accept?: string | string[];\n file: FilePreview;\n isInverse?: boolean;\n maxSize?: number;\n minSize?: number;\n onDeleteFile?: (file: FilePreview) => void;\n onRemoveFile?: (file: FilePreview) => void;\n /**\n * @internal\n */\n testId?: string;\n thumbnails: boolean;\n}\n\nconst Thumb = styled.div<{ file: FilePreview }>`\n background-image: ${({ file }) =>\n `url('${'preview' in file && file.preview}')`};\n background-repeat: no-repeat;\n background-size: cover;\n display: inline-block;\n vertical-align: middle;\n height: 40px;\n width: 40px;\n`;\n\nconst StatusIcons = styled.div`\n display: grid;\n grid-template-areas: 'inner-div';\n height: auto;\n place-items: center;\n width: 46px;\n & > div {\n display: inline-block;\n right: 0;\n grid-area: inner-div;\n }\n`;\n\nconst IconStyles = {\n marginRight: '12px',\n display: 'flex',\n};\n\nconst Errors = styled.div`\n border-top: 1px solid ${({ theme }) => theme.colors.neutral300};\n padding: 16px;\n font-size: ${({ theme }) => theme.typeScale.size02.fontSize};\n line-height: ${({ theme }) => theme.typeScale.size02.lineHeight};\n`;\n\nconst StyledFlex = styled(Flex)`\n height: 56px;\n padding: 0 8px 0 16px;\n font-size: ${({ theme }) => theme.typeScale.size02.fontSize};\n line-height: ${({ theme }) => theme.typeScale.size02.lineHeight};\n`;\n\nconst FileName = styled(Flex)`\n overflow: hidden;\n white-space: nowrap;\n align-items: center;\n text-overflow: ellipsis;\n display: block;\n margin-right: 24px;\n font-size: ${({ theme }) => theme.typeScale.size02.fontSize};\n line-height: ${({ theme }) => theme.typeScale.size02.lineHeight};\n`;\n\nconst StyledCard = styled(Card)<{ file: FilePreview; isInverse: boolean }>`\n background-color: none;\n border-color: ${({ file, theme, isInverse }) =>\n file.errors\n ? isInverse\n ? theme.colors.danger300\n : theme.colors.danger\n : theme.colors.neutral300};\n border-width: 1px;\n margin: 10px 0;\n`;\n\nconst ErrorHeader = styled.span`\n display: block;\n\n > div {\n display: flex;\n align-self: center;\n margin-right: 12px;\n }\n`;\n\nconst ErrorMessage = styled.span`\n display: block;\n`;\n\nconst formatError = (\n error: { header?: string; message: string; code: string },\n constraints: {\n maxSize?: number;\n minSize?: number;\n accept?: string | string[];\n },\n byteLabel: string\n) => {\n const accept =\n Array.isArray(constraints.accept) && constraints.accept.length === 1\n ? constraints.accept[0]\n : constraints.accept;\n const messageSuffix = Array.isArray(accept)\n ? `one of ${accept.join(', ')}`\n : accept;\n\n switch (error.code) {\n case 'file-too-large':\n return {\n ...error,\n message: `${error.message} ${formatFileSize(\n constraints.maxSize,\n 2,\n byteLabel\n )}.`,\n };\n case 'file-too-small':\n return {\n ...error,\n message: `${error.message} ${formatFileSize(\n constraints.minSize,\n 2,\n byteLabel\n )}.`,\n };\n case 'file-invalid-type':\n return { ...error, message: `${error.message}: ${messageSuffix}` };\n default:\n return error;\n }\n};\n\nexport const Preview = forwardRef<\n HTMLDivElement,\n Omit<PreviewProps, 'children'>\n>((props, ref) => {\n const {\n accept,\n file,\n isInverse: isInverseProp,\n maxSize,\n minSize,\n onDeleteFile,\n onRemoveFile,\n testId,\n thumbnails,\n ...rest\n } = props;\n\n const theme: ThemeInterface = useContext(ThemeContext);\n const i18n: I18nInterface = React.useContext(I18nContext);\n const isInverse = useIsInverse(isInverseProp);\n const [actions, setActions] = useState(<CloseIcon />);\n\n const handleRemoveFile = () => {\n onRemoveFile && typeof onRemoveFile === 'function' && onRemoveFile(file);\n };\n\n const handleDeleteFile = () => {\n onDeleteFile && typeof onDeleteFile === 'function' && onDeleteFile(file);\n };\n\n const FinishedActions = ({ status = 'ready' }: { status?: string }) => {\n const [done, setDone] = useState<boolean>(false);\n\n useEffect(() => {\n let mounted = true;\n\n setTimeout(() => {\n if (mounted) {\n setDone(true);\n }\n }, 1000);\n\n return () => {\n mounted = false;\n };\n }, [status]);\n\n if (status === 'error' || status === 'ready') {\n return (\n <StatusIcons>\n <IconButton\n onClick={handleRemoveFile}\n variant={ButtonVariant.link}\n color={ButtonColor.secondary}\n aria-label={i18n.dropzone.removeFile}\n icon={<CloseIcon />}\n />\n </StatusIcons>\n );\n }\n\n if (status === 'pending') {\n return (\n <StatusIcons>\n <Spinner\n color={isInverse ? theme.colors.neutral100 : theme.colors.primary}\n />\n </StatusIcons>\n );\n }\n\n return (\n <StatusIcons>\n <Transition isOpen={!done} unmountOnExit fade>\n <CheckCircleIcon\n color={isInverse ? theme.colors.success200 : theme.colors.success}\n style={{ marginTop: '4px' }}\n />\n </Transition>\n <Transition isOpen={done} unmountOnExit fade>\n <IconButton\n onClick={handleDeleteFile}\n variant={ButtonVariant.link}\n color={ButtonColor.secondary}\n aria-label={i18n.dropzone.deleteFile}\n icon={<DeleteIcon />}\n />\n </Transition>\n </StatusIcons>\n );\n };\n\n useEffect(() => {\n setActions(<FinishedActions status={file?.processor?.status} />);\n }, [file?.processor?.status]);\n\n return (\n <InverseContext.Provider value={{ isInverse }}>\n <StyledCard\n isInverse={isInverse}\n theme={theme}\n file={file}\n data-testid={props.testId}\n ref={ref}\n role={file.errors ? 'alert' : ''}\n >\n <StyledFlex\n theme={theme}\n behavior={FlexBehavior.container}\n alignItems={FlexAlignItems.center}\n {...rest}\n >\n <Flex\n behavior={FlexBehavior.item}\n alignItems={FlexAlignItems.center}\n style={IconStyles}\n >\n {file.errors ? (\n <ErrorIcon\n color={isInverse ? theme.colors.danger300 : theme.colors.danger}\n size={24}\n />\n ) : file.preview &&\n thumbnails &&\n file.type &&\n file.type.startsWith('image') ? (\n <Thumb role=\"img\" file={file} />\n ) : (\n <FileIcon isInverse={isInverse} file={file} />\n )}\n </Flex>\n <FileName xs behavior={FlexBehavior.item} theme={theme}>\n {file.name}\n </FileName>\n {file.processor && file.processor.status === 'pending' && (\n <Flex\n role=\"progressbar\"\n style={{ marginLeft: 'auto' }}\n behavior={FlexBehavior.item}\n >\n {file.processor.percent}\n </Flex>\n )}\n <Flex behavior={FlexBehavior.item}>{actions}</Flex>\n </StyledFlex>\n {file.errors && (\n <Errors theme={theme}>\n {file.errors.slice(0, 1).map(({ code, ...rest }) => {\n const { header = '', message } = formatError(\n { code, ...rest, ...i18n.dropzone.errors[code] },\n { accept, minSize, maxSize },\n i18n.dropzone.bytes\n );\n\n return (\n <React.Fragment key={code}>\n <ErrorHeader\n style={{\n color: isInverse\n ? theme.colors.danger200\n : theme.colors.danger,\n }}\n >\n {header}\n </ErrorHeader>\n <ErrorMessage>{message}</ErrorMessage>\n </React.Fragment>\n );\n })}\n </Errors>\n )}\n </StyledCard>\n </InverseContext.Provider>\n );\n});\n","/* eslint-disable no-empty-pattern */\n/**\n * HELPFUL NOTE!\n * SINCE THIS PACKAGE USES `FILE` WE MUST USE `Object.assign` IN LIEU OF SPREADING\n * `{...file}` WILL NOT COPY ALL OF THE FILE PROPERTIES\n */\n\nimport React, { useImperativeHandle } from 'react';\n\nimport { transparentize } from 'polished';\nimport {\n useDropzone,\n DropzoneOptions,\n DropzoneRootProps,\n FileRejection,\n} from 'react-dropzone';\nimport {\n Button,\n ButtonColor,\n ButtonVariant,\n Flex,\n FlexBehavior,\n FlexProps,\n FormFieldContainer,\n FormFieldContainerBaseProps,\n I18nContext,\n I18nInterface,\n InverseContext,\n ThemeContext,\n ThemeInterface,\n useGenerateId,\n useIsInverse,\n styled,\n} from 'react-magma-dom';\nimport { CloudUploadIcon } from 'react-magma-icons';\n\nimport { FilePreview, FileError } from './FilePreview';\nimport { Preview } from './Preview';\n\nexport interface OnSendFileProps {\n file: FilePreview;\n onError?: ({}: { errors: FileError[]; file: FilePreview }) => void;\n onFinish?: ({}: { file: FilePreview }) => void;\n onProgress?: ({}: { percent: number; file: FilePreview }) => void;\n}\n\ntype DragState =\n | 'error'\n | 'dragAccept'\n | 'dragReject'\n | 'dragActive'\n | 'default';\n\n// NOTE: These props are manually copied to dropzone.mdx\nexport interface DropzoneProps\n extends Omit<FormFieldContainerBaseProps, 'fieldId' | 'errorMessage'> {\n /**\n * Set accepted file types. See https://github.com/okonet/attr-accept for more information. Keep in mind that mime type determination is not reliable across platforms. CSV files, for example, are reported as text/plain under macOS but as application/vnd.ms-excel under Windows. In some cases there might not be a mime type set at all. See: https://github.com/react-dropzone/react-dropzone/issues/276\n */\n accept?: string | string[];\n /**\n * Enable/Disable the input\n */\n disabled?: boolean;\n /**\n * Additional props to pass to the dropzone, see https://react-dropzone.js.org/#src\n */\n dropzoneOptions?: Partial<Omit<DropzoneOptions, 'onDrop'>>;\n /**\n * Content of the helper message.\n */\n helperMessage?: string;\n /**\n * @internal\n */\n id?: string;\n /**\n * Maximum accepted number of files The default value is 0 which means there is no limitation to how many files are accepted.\n * @default 0\n */\n maxFiles?: number;\n /**\n * Minimum accepted number of files.\n */\n minFiles?: number;\n /**\n * Maximum file size (in bytes)\n * @default Infinity\n */\n maxSize?: number;\n /**\n * Minimum file size (in bytes)\n * @default 0\n */\n minSize?: number;\n /**\n * Allow drag 'n' drop (or selection from the file dialog) of multiple files.\n * @default true\n */\n multiple?: boolean;\n /**\n * If true, disables drag 'n' drop\n * @default false\n */\n noDrag?: boolean;\n /**\n * Callback for when a file is deleted\n */\n onDeleteFile?: (file: FilePreview) => void;\n /**\n * Callback for when a file is deleted\n */\n onRemoveFile?: (file: FilePreview) => void;\n /**\n * Callback for when a file is added to the preview list via dropping or selecting. Will be ran on new files when `sendFiles` is true.\n */\n onSendFile?: (props: OnSendFileProps) => void;\n /**\n * Run `onSendFile` on any new files. Delay processing by setting to `false` until processing is desired.\n * @default false\n */\n sendFiles?: boolean;\n /**\n * @internal\n */\n testId?: string;\n /**\n * Show thumbnails for images in lieu of the file icon.\n * @default true\n */\n thumbnails?: boolean;\n}\n\nconst Container = styled(Flex)<\n DropzoneRootProps &\n FlexProps & {\n dragState?: DragState;\n noDrag?: boolean;\n isInverse?: boolean;\n }\n>`\n flex-direction: column;\n align-items: ${({ noDrag }) => (noDrag ? 'left' : 'center')};\n justify-content: ${({ noDrag }) => (noDrag ? 'left' : 'center')};\n text-align: ${({ noDrag }) => (noDrag ? 'left' : 'center')};\n padding: ${({ noDrag }) => (noDrag ? '0px' : '24px')};\n border-radius: ${({ noDrag }) => (noDrag ? '0px' : '4px')};\n border: ${({ dragState = 'default', noDrag, theme, isInverse }) =>\n noDrag\n ? `0px`\n : dragState === 'dragReject' || dragState === 'error'\n ? isInverse\n ? `1px dashed ${theme.colors.danger300}`\n : `1px dashed ${theme.colors.danger}`\n : dragState === 'dragActive'\n ? `1px dashed ${theme.colors.primary}`\n : dragState === 'dragAccept'\n ? `1px dashed ${theme.colors.success}`\n : `1px dashed ${theme.colors.neutral400}`};\n\n border-style: ${({ dragState = 'default' }) =>\n dragState === 'error' ? 'solid' : 'dashed'};\n background-color: ${({ theme, noDrag, isInverse }) =>\n noDrag\n ? 'transparent'\n : isInverse\n ? transparentize(0.75, theme.colors.neutral900)\n : theme.colors.neutral200};\n outline: none;\n transition: ${({ noDrag }) => `border ${noDrag ? 0 : '.24s'} ease-in-out`};\n`;\n\nconst HelperMessage = styled.span<{ isInverse?: boolean }>`\n color: ${({ theme, isInverse }) =>\n isInverse ? theme.colors.neutral100 : theme.colors.neutral700};\n display: block;\n font-size: 14px;\n margin: -8px 0 16px 0;\n`;\n\nconst Wrapper = styled.div<{ isInverse?: boolean }>`\n color: ${({ theme, isInverse }) =>\n isInverse ? theme.colors.neutral100 : theme.colors.neutral700};\n margin: 0 0 24px 0;\n font-size: ${({ theme }) => theme.typeScale.size02.fontSize};\n line-height: ${({ theme }) => theme.typeScale.size02.lineHeight};\n font-weight: 500;\n padding: ${({ theme }) => theme.spaceScale.spacing01};\n`;\n\nexport const Dropzone = React.forwardRef<HTMLInputElement, DropzoneProps>(\n (props, ref) => {\n const {\n accept,\n containerStyle,\n disabled,\n\n dropzoneOptions = {\n multiple: true,\n },\n helperMessage,\n id: defaultId,\n inputSize,\n isInverse: isInverseProp,\n isLabelVisuallyHidden,\n labelStyle,\n labelText,\n maxFiles,\n minFiles,\n maxSize,\n minSize,\n multiple = true,\n noDrag = false,\n onSendFile,\n onDeleteFile,\n onRemoveFile,\n sendFiles = false,\n testId,\n thumbnails = true,\n ...rest\n } = props;\n\n const [files, setFiles] = React.useState<FilePreview[]>([]);\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null);\n\n const isInverse = useIsInverse(isInverseProp);\n const theme: ThemeInterface = React.useContext(ThemeContext);\n const i18n: I18nInterface = React.useContext(I18nContext);\n const id = useGenerateId(defaultId);\n\n const onDrop = React.useCallback(\n (acceptedFiles: FilePreview[], rejectedFiles: FileRejection[]) => {\n setFiles((files: FilePreview[]) => [\n ...files,\n ...acceptedFiles.map((file: FilePreview) =>\n Object.assign(file, {\n preview: URL.createObjectURL(file),\n })\n ),\n ...rejectedFiles.map(\n ({ file, errors }: { file: FilePreview; errors: FileError[] }) =>\n Object.assign(file, {\n errors,\n })\n ),\n ]);\n },\n []\n );\n\n const {\n getInputProps,\n getRootProps,\n isDragAccept,\n isDragActive,\n isDragReject,\n open,\n inputRef,\n } = useDropzone({\n noClick: true,\n disabled,\n multiple,\n maxSize,\n minSize,\n accept,\n onDrop,\n noDrag,\n ...dropzoneOptions,\n });\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => inputRef.current\n );\n\n const inputProps = getInputProps({ id });\n\n const dragState: DragState = errorMessage\n ? 'error'\n : isDragAccept\n ? 'dragAccept'\n : isDragReject\n ? 'dragReject'\n : isDragActive\n ? 'dragActive'\n : 'default';\n\n const handleRemoveFile = (removedFile: FilePreview) => {\n setFiles(files => files.filter(file => file !== removedFile));\n onRemoveFile &&\n typeof onRemoveFile === 'function' &&\n onRemoveFile(removedFile);\n };\n\n const handleDeleteFile = (removedFile: FilePreview) => {\n setFiles(files => files.filter(file => file !== removedFile));\n onDeleteFile &&\n typeof onDeleteFile === 'function' &&\n onDeleteFile(removedFile);\n };\n\n const setProgress = (props: { percent: number; file: FilePreview }) => {\n setFiles(files =>\n files.map(file =>\n file === props.file\n ? Object.assign(file, {\n processor: {\n ...file.processor,\n percent: `${props.percent}%`,\n status: 'pending',\n },\n })\n : file\n )\n );\n };\n\n const setFinished = (props: { file: FilePreview }) => {\n setFiles(files =>\n files.map(file =>\n file === props.file\n ? Object.assign(file, {\n processor: {\n ...file.processor,\n percent: '',\n status: 'finished',\n },\n })\n : file\n )\n );\n };\n\n const setError = (props: { errors: FileError[]; file: FilePreview }) => {\n setFiles(files =>\n files.map(file =>\n file === props.file\n ? Object.assign(file, {\n errors: props.errors,\n processor: { ...file.processor, status: 'error' },\n })\n : file\n )\n );\n };\n\n const formatError = (\n code: string | null,\n constraints: { maxFiles?: number; minFiles?: number }\n ) => {\n if (code === null) return null;\n const error = i18n.dropzone.errors[code];\n\n switch (code) {\n case 'too-many-files':\n return `${error.message} ${constraints.maxFiles} ${i18n.dropzone.files}.`;\n case 'too-few-files':\n return `${error.message} ${constraints.minFiles} ${i18n.dropzone.files}.`;\n default:\n return error.message;\n }\n };\n\n React.useEffect(\n () => () => {\n files.forEach(\n file => file.preview && URL.revokeObjectURL(file.preview)\n );\n },\n [files]\n );\n\n React.useEffect(() => {\n const minFileError = minFiles && files.length < minFiles;\n const maxFileError = maxFiles && files.length > maxFiles;\n\n setErrorMessage(\n formatError(\n maxFileError\n ? 'too-many-files'\n : minFileError\n ? 'too-few-files'\n : null,\n { minFiles, maxFiles }\n )\n );\n\n if (sendFiles && files.length > 0 && !maxFileError && !minFileError) {\n setFiles((files: FilePreview[]) => {\n return files.map((file: FilePreview) => {\n !file.errors &&\n !file.processor &&\n onSendFile &&\n onSendFile({\n file,\n onError: setError,\n onFinish: setFinished,\n onProgress: setProgress,\n });\n\n return file;\n });\n });\n }\n }, [sendFiles, files.length, onSendFile]);\n\n return (\n <InverseContext.Provider value={{ isInverse }}>\n <FormFieldContainer\n actionable={false}\n containerStyle={containerStyle}\n errorMessage={errorMessage}\n fieldId={id}\n inputSize={inputSize}\n isInverse={isInverse}\n isLabelVisuallyHidden={isLabelVisuallyHidden}\n labelStyle={labelStyle}\n labelText={labelText}\n messageStyle={{ minHeight: 0 }}\n data-testid={testId}\n >\n <HelperMessage theme={theme} isInverse={isInverse}>\n {helperMessage}\n </HelperMessage>\n <Container\n behavior={FlexBehavior.container}\n dragState={dragState}\n isInverse={isInverse}\n noDrag={noDrag}\n theme={theme}\n {...getRootProps()}\n {...rest}\n testId={testId}\n tabIndex={-1}\n >\n <input\n ref={inputRef}\n type={inputProps.type}\n accept={inputProps.accept}\n autoComplete={inputProps.autoComplete}\n id={inputProps.id}\n multiple={inputProps.multiple}\n onChange={inputProps.onChange}\n onClick={inputProps.onClick}\n style={inputProps.style}\n tabIndex={inputProps.tabIndex}\n data-testid=\"file-input\"\n />\n {noDrag ? (\n <Flex xs behavior={FlexBehavior.item}>\n <Button\n color={ButtonColor.primary}\n disabled={disabled}\n isInverse={isInverse}\n onClick={open}\n style={{ margin: 0 }}\n >\n {i18n.dropzone.browseFiles}\n </Button>\n </Flex>\n ) : (\n <Flex behavior={FlexBehavior.item}>\n <CloudUploadIcon\n aria-hidden=\"true\"\n color={\n isInverse\n ? theme.colors.neutral100\n : theme.colors.neutral500\n }\n size={48}\n />\n <Wrapper isInverse={isInverse} theme={theme}>\n {i18n.dropzone.dragMessage}\n </Wrapper>\n <Button\n color={ButtonColor.primary}\n disabled={disabled}\n isInverse={isInverse}\n onClick={open}\n style={{ margin: 0 }}\n variant={ButtonVariant.solid}\n >\n {i18n.dropzone.browseFiles}\n </Button>\n </Flex>\n )}\n </Container>\n </FormFieldContainer>\n {files.map((file: FilePreview) => (\n <Preview\n accept={accept}\n file={file}\n isInverse={isInverse}\n key={file.name}\n maxSize={maxSize}\n minSize={minSize}\n onDeleteFile={handleDeleteFile}\n onRemoveFile={handleRemoveFile}\n thumbnails={thumbnails}\n />\n ))}\n </InverseContext.Provider>\n );\n }\n);\n"],"names":["icons","default","Icon","InsertDriveFileIcon","style","color","magma","colors","neutral500","word","FileWordIcon","info500","excel","FileExcelIcon","success500","powerpoint","FilePowerpointIcon","warning500","pdf","FilePdfIcon","danger500","image","ImageIcon","video","VideocamIcon","audio","AudiotrackIcon","archive","FileZipIcon","iconMapping","xlsx","xlsm","xlsb","xltx","xls","xlt","doc","docx","docm","dotx","dotm","docb","pptx","pptm","ppt","png","svg","zip","FileIcon","file","isInverse","path","type","category","split","extension","pop","_jsx","size","iconSizes","medium","formatFileSize","bytes","decimalPoint","bytesLabel","undefined","sizes","i","Math","floor","log","parseFloat","pow","toFixed","_excluded","_excluded2","_t","_t2","_t3","_t4","_t5","_t6","_t7","_t8","_","t","Thumb","styled","div","preview","StatusIcons","IconStyles","marginRight","display","Errors","theme","neutral300","typeScale","size02","fontSize","lineHeight","StyledFlex","Flex","FileName","StyledCard","Card","errors","danger300","danger","ErrorHeader","span","ErrorMessage","Preview","forwardRef","props","ref","_file$processor2","accept","isInverseProp","maxSize","minSize","onDeleteFile","onRemoveFile","thumbnails","rest","_objectWithoutPropertiesLoose","useContext","ThemeContext","i18n","React","I18nContext","useIsInverse","actions","setActions","useState","CloseIcon","handleRemoveFile","handleDeleteFile","FinishedActions","status","done","setDone","useEffect","mounted","setTimeout","children","IconButton","onClick","variant","ButtonVariant","link","ButtonColor","secondary","dropzone","removeFile","icon","Spinner","neutral100","primary","_jsxs","Transition","isOpen","unmountOnExit","fade","CheckCircleIcon","success200","success","marginTop","deleteFile","DeleteIcon","_file$processor","processor","InverseContext","Provider","value","testId","role","_extends","behavior","FlexBehavior","container","alignItems","FlexAlignItems","center","item","ErrorIcon","startsWith","xs","name","marginLeft","percent","slice","map","_ref","code","header","message","formatError","error","constraints","byteLabel","Array","isArray","length","messageSuffix","join","Fragment","danger200","Container","noDrag","dragState","neutral400","transparentize","neutral900","neutral200","HelperMessage","neutral700","Wrapper","spaceScale","spacing01","Dropzone","containerStyle","disabled","dropzoneOptions","multiple","helperMessage","id","defaultId","inputSize","isLabelVisuallyHidden","labelStyle","labelText","maxFiles","minFiles","onSendFile","sendFiles","files","setFiles","errorMessage","setErrorMessage","useGenerateId","onDrop","useCallback","acceptedFiles","rejectedFiles","Object","assign","URL","createObjectURL","getInputProps","getRootProps","isDragAccept","isDragActive","isDragReject","open","inputRef","useDropzone","noClick","useImperativeHandle","current","inputProps","removedFile","filter","setProgress","setFinished","setError","forEach","revokeObjectURL","minFileError","maxFileError","onError","onFinish","onProgress","FormFieldContainer","actionable","fieldId","messageStyle","minHeight","tabIndex","autoComplete","onChange","Button","margin","browseFiles","CloudUploadIcon","dragMessage","solid"],"mappings":"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"}