@react-magma/dropzone 16.0.0-next.1 → 16.0.0-v6-next.1

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.
@@ -1,4 +1,4 @@
1
- export * from './FileIcon';
2
- export * from './FilePreview';
3
- export * from './Dropzone';
4
- export * from './FilePreview';
1
+ export * from './FileIcon';
2
+ export * from './FilePreview';
3
+ export * from './Dropzone';
4
+ export * from './FilePreview';
@@ -1 +1 @@
1
- export declare const formatFileSize: (bytes: number | undefined, decimalPoint?: number, bytesLabel?: string) => string;
1
+ export declare const formatFileSize: (bytes: number | undefined, decimalPoint?: number, bytesLabel?: string) => string | undefined;
@@ -1 +1 @@
1
- export * from './components/dropzone';
1
+ export * from './components/dropzone';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-magma/dropzone",
3
- "version": "16.0.0-next.1",
3
+ "version": "16.0.0-v6-next.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,31 +20,28 @@
20
20
  "build": "microbundle build --jsx jsx --jsxImportSource react --globals react/jsx-runtime=jsx",
21
21
  "build-watch": "microbundle watch --jsx jsx --jsxImportSource react --globals react/jsx-runtime=jsx",
22
22
  "lint": "eslint ./src",
23
- "lint:fix": "eslint ./src --fix",
24
- "lint:check": "eslint ./src --max-warnings=0",
25
23
  "test": "jest",
26
- "test-watch": "jest --watch",
27
- "compiler-checks": "tsc --noEmit --project ./tsconfig.json"
24
+ "test-watch": "jest --watch"
28
25
  },
29
26
  "dependencies": {
30
- "polished": "3.7.2",
27
+ "polished": "^3.7.2",
31
28
  "react-dropzone": "11.3.2"
32
29
  },
33
30
  "devDependencies": {
34
- "@emotion/react": "11.14.0",
35
- "@emotion/styled": "11.14.0",
36
- "react": "18.3.1",
37
- "react-dom": "18.3.1",
38
- "react-magma-dom": "^7.0.0-next.1",
39
- "react-magma-icons": "^3.2.5"
31
+ "@emotion/react": "^11.13.0",
32
+ "@emotion/styled": "^11.13.0",
33
+ "react": "^17.0.2",
34
+ "react-dom": "^17.0.2",
35
+ "react-magma-dom": "^6.1.0-v6-next.2",
36
+ "react-magma-icons": "^3.3.0"
40
37
  },
41
38
  "peerDependencies": {
42
- "@emotion/react": "11.14.0",
43
- "@emotion/styled": "11.14.0",
44
- "react": "18.3.1",
45
- "react-dom": "18.3.1",
46
- "react-magma-dom": "^7.0.0-next.1",
47
- "react-magma-icons": "^3.2.5"
39
+ "@emotion/react": "^11.13.0",
40
+ "@emotion/styled": "^11.13.0",
41
+ "react": "^17.0.2",
42
+ "react-dom": "^17.0.2",
43
+ "react-magma-dom": "^6.1.0-v6-next.2",
44
+ "react-magma-icons": "^3.3.0"
48
45
  },
49
46
  "engines": {
50
47
  "node": ">=22.14.0",
@@ -138,7 +138,6 @@ export const Image = {
138
138
  const onSendFile = (props: OnSendFileProps) => {
139
139
  const { file, onFinish } = props;
140
140
  const reader = new FileReader();
141
-
142
141
  reader.onload = function (evt) {
143
142
  setFile(
144
143
  (evt &&
@@ -184,7 +183,6 @@ export const Text = {
184
183
  const onSendFile = (props: OnSendFileProps) => {
185
184
  const { file, onFinish } = props;
186
185
  const reader = new FileReader();
187
-
188
186
  reader.onload = function (evt) {
189
187
  setFile(
190
188
  (evt &&
@@ -231,7 +229,6 @@ export const Csv = {
231
229
  const onSendFile = (props: OnSendFileProps) => {
232
230
  const { file, onFinish } = props;
233
231
  const reader = new FileReader();
234
-
235
232
  reader.onload = function (evt) {
236
233
  const [columns, rows] =
237
234
  (evt &&
@@ -239,7 +236,6 @@ export const Csv = {
239
236
  evt.target.result &&
240
237
  csvJSON(evt.target.result.toString())) ||
241
238
  [];
242
-
243
239
  setColumns(columns);
244
240
  setFile(rows);
245
241
  onFinish && onFinish({ file });
@@ -11,11 +11,11 @@ import userEvent from '@testing-library/user-event';
11
11
  import { transparentize } from 'polished';
12
12
  import { I18nContext, defaultI18n, magma } from 'react-magma-dom';
13
13
 
14
+ import { FileIcon } from './FileIcon';
15
+ import { Preview } from './Preview';
14
16
  import { axe } from '../../../axe-helper.js';
15
17
 
16
18
  import { Dropzone } from '.';
17
- import { FileIcon } from './FileIcon';
18
- import { Preview } from './Preview';
19
19
 
20
20
  describe('File Uploader', () => {
21
21
  let files;
@@ -764,7 +764,7 @@ describe('File Uploader', () => {
764
764
  });
765
765
 
766
766
  // TODO: Fix test (Delete file doesn't exist in the document (Remove file exists))
767
- xit('changes to delete file on finish', async () => {
767
+ it.skip('changes to delete file on finish', async () => {
768
768
  const onSendFile = ({ file, onFinish }) => {
769
769
  onFinish({ file });
770
770
  };
@@ -788,7 +788,7 @@ describe('File Uploader', () => {
788
788
  });
789
789
 
790
790
  // TODO: Fix test (Delete file doesn't exist in the document (Remove file exists))
791
- xit('deletes the file when the Delete File icon is clicked', async () => {
791
+ it.skip('deletes the file when the Delete File icon is clicked', async () => {
792
792
  const onSendFile = ({ file, onFinish }) => {
793
793
  onFinish({ file });
794
794
  };
@@ -822,7 +822,7 @@ describe('File Uploader', () => {
822
822
  });
823
823
 
824
824
  // TODO: Fix test (Delete file doesn't exist in the document (Remove file exists))
825
- xit('calls onDeleteFile when the Delete File icon is clicked', async () => {
825
+ it.skip('calls onDeleteFile when the Delete File icon is clicked', async () => {
826
826
  const onDeleteFileSpy = jest.fn();
827
827
  const onSendFile = ({ file, onFinish }) => {
828
828
  onFinish({ file });
@@ -134,6 +134,54 @@ export interface DropzoneProps
134
134
  thumbnails?: boolean;
135
135
  }
136
136
 
137
+ const getErrorBorderColor = (
138
+ dragState: DragState,
139
+ theme: ThemeInterface,
140
+ isInverse?: boolean
141
+ ) => {
142
+ if (!isInverse) {
143
+ return theme.colors.danger;
144
+ }
145
+
146
+ return dragState === DragState.error
147
+ ? theme.colors.red500
148
+ : theme.colors.red400;
149
+ };
150
+
151
+ const getContainerBorder = ({
152
+ dragState = DragState.default,
153
+ noDrag,
154
+ theme,
155
+ isInverse,
156
+ }: {
157
+ dragState?: DragState;
158
+ noDrag?: boolean;
159
+ theme: ThemeInterface;
160
+ isInverse?: boolean;
161
+ }) => {
162
+ if (noDrag) {
163
+ return '0px';
164
+ }
165
+
166
+ if (dragState === DragState.dragReject || dragState === DragState.error) {
167
+ const width = dragState === DragState.error ? '1px' : '2px';
168
+
169
+ return `${width} dashed ${getErrorBorderColor(dragState, theme, isInverse)}`;
170
+ }
171
+
172
+ if (dragState === DragState.dragActive) {
173
+ return `2px dashed ${theme.colors.blue500}`;
174
+ }
175
+
176
+ if (dragState === DragState.dragAccept) {
177
+ return `2px dashed ${theme.colors.green500}`;
178
+ }
179
+
180
+ return `2px dashed ${
181
+ isInverse ? theme.colors.neutral800 : theme.colors.neutral300
182
+ }`;
183
+ };
184
+
137
185
  const Container = styled(Flex)<
138
186
  DropzoneRootProps &
139
187
  FlexProps & {
@@ -149,26 +197,7 @@ const Container = styled(Flex)<
149
197
  padding: ${({ noDrag }) => (noDrag ? '0px' : '24px')};
150
198
  border-radius: ${({ noDrag, theme }) =>
151
199
  noDrag ? theme.borderRadiusNone : theme.borderRadiusSmall};
152
- border: ${({ dragState = DragState.default, noDrag, theme, isInverse }) =>
153
- noDrag
154
- ? `0px`
155
- : dragState === DragState.dragReject || dragState === DragState.error
156
- ? isInverse
157
- ? `${dragState === DragState.error ? '1px' : '2px'} dashed ${
158
- dragState === DragState.error
159
- ? theme.colors.red500
160
- : theme.colors.red400
161
- }`
162
- : `${dragState === DragState.error ? '1px' : '2px'} dashed ${
163
- theme.colors.danger
164
- }`
165
- : dragState === DragState.dragActive
166
- ? `2px dashed ${theme.colors.blue500}`
167
- : dragState === DragState.dragAccept
168
- ? `2px dashed ${theme.colors.green500}`
169
- : `2px dashed ${
170
- isInverse ? theme.colors.neutral800 : theme.colors.neutral300
171
- }`};
200
+ border: ${getContainerBorder};
172
201
 
173
202
  border-style: ${({ dragState = DragState.default }) =>
174
203
  dragState === DragState.error ? 'solid' : 'dashed'};
@@ -213,7 +242,7 @@ export const Dropzone = React.forwardRef<HTMLInputElement, DropzoneProps>(
213
242
  accept,
214
243
  containerStyle,
215
244
  disabled,
216
-
245
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
217
246
  dropzoneOptions = {
218
247
  multiple: true,
219
248
  },
@@ -71,6 +71,38 @@ const StatusIcons = styled.div`
71
71
  }
72
72
  `;
73
73
 
74
+ const PreviewIcon = ({
75
+ file,
76
+ isInverse,
77
+ theme,
78
+ thumbnails,
79
+ }: {
80
+ file: FilePreview;
81
+ isInverse: boolean;
82
+ theme: ThemeInterface;
83
+ thumbnails: boolean;
84
+ }) => {
85
+ if (file.errors) {
86
+ return (
87
+ <ErrorIcon
88
+ color={isInverse ? theme.colors.red500 : theme.colors.danger}
89
+ size={24}
90
+ />
91
+ );
92
+ }
93
+
94
+ if (
95
+ file.preview &&
96
+ thumbnails &&
97
+ file.type &&
98
+ file.type.startsWith('image')
99
+ ) {
100
+ return <Thumb role="img" file={file} />;
101
+ }
102
+
103
+ return <FileIcon isInverse={isInverse} file={file} />;
104
+ };
105
+
74
106
  const IconStyles = {
75
107
  marginRight: '12px',
76
108
  display: 'flex',
@@ -245,7 +277,9 @@ export const Preview = forwardRef<
245
277
  return (
246
278
  <StatusIcons>
247
279
  <Spinner
248
- color={isInverse ? theme.colors.brand.skyBlue : theme.colors.primary}
280
+ color={
281
+ isInverse ? theme.colors.brand.skyBlue : theme.colors.primary
282
+ }
249
283
  />
250
284
  </StatusIcons>
251
285
  );
@@ -299,19 +333,12 @@ export const Preview = forwardRef<
299
333
  alignItems={FlexAlignItems.center}
300
334
  style={IconStyles}
301
335
  >
302
- {file.errors ? (
303
- <ErrorIcon
304
- color={isInverse ? theme.colors.red500 : theme.colors.danger}
305
- size={24}
306
- />
307
- ) : file.preview &&
308
- thumbnails &&
309
- file.type &&
310
- file.type.startsWith('image') ? (
311
- <Thumb role="img" file={file} />
312
- ) : (
313
- <FileIcon isInverse={isInverse} file={file} />
314
- )}
336
+ <PreviewIcon
337
+ file={file}
338
+ isInverse={isInverse}
339
+ theme={theme}
340
+ thumbnails={thumbnails}
341
+ />
315
342
  </Flex>
316
343
  <FileName xs behavior={FlexBehavior.item} theme={theme}>
317
344
  {file.name}
@@ -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.neutral700,\n },\n inverseStyle: {\n color: magma.colors.neutral300,\n },\n },\n word: {\n Icon: FileWordIcon,\n style: {\n color: magma.colors.blue500,\n },\n inverseStyle: {\n color: magma.colors.blue500,\n },\n },\n excel: {\n Icon: FileExcelIcon,\n style: {\n color: magma.colors.green500,\n },\n inverseStyle: {\n color: magma.colors.green500,\n },\n },\n powerpoint: {\n Icon: FilePowerpointIcon,\n style: {\n color: magma.colors.tangerine600,\n },\n inverseStyle: {\n color: magma.colors.tangerine500,\n },\n },\n pdf: {\n Icon: FilePdfIcon,\n style: {\n color: magma.colors.red600,\n },\n inverseStyle: {\n color: magma.colors.red500,\n },\n },\n image: {\n Icon: ImageIcon,\n style: {\n color: magma.colors.neutral700,\n },\n inverseStyle: {\n color: magma.colors.neutral300,\n },\n },\n video: {\n Icon: VideocamIcon,\n style: {\n color: magma.colors.neutral700,\n },\n inverseStyle: {\n color: magma.colors.neutral300,\n },\n },\n audio: {\n Icon: AudiotrackIcon,\n style: {\n color: magma.colors.neutral700,\n },\n inverseStyle: {\n color: magma.colors.neutral300,\n },\n },\n archive: {\n Icon: FileZipIcon,\n style: {\n color: magma.colors.neutral700,\n },\n inverseStyle: {\n color: magma.colors.neutral300,\n },\n },\n};\n\nconst iconMapping: {\n [key: string]: {\n Icon: any;\n style: React.CSSProperties;\n inverseStyle: React.CSSProperties;\n };\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, inverseStyle } =\n iconMapping[extension] || iconMapping[category] || iconMapping.default;\n\n return (\n <Icon\n size={magma.iconSizes.medium}\n style={isInverse ? inverseStyle : style}\n />\n );\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 CardBorderRadius,\n CardCornerTreatment,\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<{ isInverse: boolean }>`\n border-top: 1px solid\n ${({ theme, isInverse }) =>\n isInverse ? theme.colors.neutral500 : 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.red500\n : theme.colors.danger\n : isInverse\n ? theme.colors.neutral800\n : theme.colors.neutral200};\n border-width: 1px;\n color: ${({ file, theme, isInverse }) =>\n isInverse\n ? theme.colors.neutral0\n : file.errors\n ? theme.colors.neutral700\n : theme.colors.brand.navy};\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.subtle}\n aria-label={`${i18n.dropzone.removeFile} ${file.name}`}\n icon={<CloseIcon />}\n />\n </StatusIcons>\n );\n }\n\n if (status === 'pending') {\n return (\n <StatusIcons>\n <Spinner\n color={isInverse ? theme.colors.brand.skyBlue : 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.green500 : 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.subtle}\n aria-label={`${i18n.dropzone.deleteFile} ${file.name}`}\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 borderRadius={CardBorderRadius.small}\n cornerTreatment={CardCornerTreatment.all}\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.red500 : 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} isInverse={isInverse}>\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.red500\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 Announce,\n VisuallyHidden,\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\nenum DragState {\n error = 'error',\n dragAccept = 'dragAccept',\n dragReject = 'dragReject',\n dragActive = 'dragActive',\n default = 'default',\n}\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, theme }) =>\n noDrag ? theme.borderRadiusNone : theme.borderRadiusSmall};\n border: ${({ dragState = DragState.default, noDrag, theme, isInverse }) =>\n noDrag\n ? `0px`\n : dragState === DragState.dragReject || dragState === DragState.error\n ? isInverse\n ? `${dragState === DragState.error ? '1px' : '2px'} dashed ${\n dragState === DragState.error\n ? theme.colors.red500\n : theme.colors.red400\n }`\n : `${dragState === DragState.error ? '1px' : '2px'} dashed ${\n theme.colors.danger\n }`\n : dragState === DragState.dragActive\n ? `2px dashed ${theme.colors.blue500}`\n : dragState === DragState.dragAccept\n ? `2px dashed ${theme.colors.green500}`\n : `2px dashed ${\n isInverse ? theme.colors.neutral800 : theme.colors.neutral300\n }`};\n\n border-style: ${({ dragState = DragState.default }) =>\n dragState === DragState.error ? 'solid' : 'dashed'};\n background-color: ${({ theme, noDrag, isInverse }) =>\n noDrag\n ? 'transparent'\n : isInverse\n ? transparentize(0.6, theme.colors.neutral1200)\n : theme.colors.neutral100};\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.neutral500 : 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.neutral0 : theme.colors.brand.navy};\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\nconst PreviewList = styled.ul`\n list-style: none;\n padding: 0;\n`;\n\nconst PreviewItem = styled.li``;\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 const [announcement, setAnnouncement] = React.useState<string>('');\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 const helperMessageId = useGenerateId(`${id}-helper`);\n\n const browseFileButtonRef = React.useRef<HTMLButtonElement>(null);\n\n const onDrop = React.useCallback(\n (acceptedFiles: FilePreview[], rejectedFiles: FileRejection[]) => {\n const newFiles = [\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 setFiles((prevFiles: FilePreview[]) => [...prevFiles, ...newFiles]);\n\n if (acceptedFiles.length > 0) {\n const fileNames = acceptedFiles.map(file => file.name).join(', ');\n const message =\n acceptedFiles.length === 1\n ? i18n.dropzone.fileAdded.replace(/\\{fileName\\}/g, fileNames)\n : i18n.dropzone.filesAdded\n .replace(/\\{count\\}/g, acceptedFiles.length.toString())\n .replace(/\\{fileNames\\}/g, fileNames);\n\n setAnnouncement(message);\n }\n\n browseFileButtonRef.current && browseFileButtonRef.current.focus();\n },\n [i18n]\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 let dragState = DragState.default;\n\n if (errorMessage) {\n dragState = DragState.error;\n } else if (isDragAccept) {\n dragState = DragState.dragAccept;\n } else if (isDragReject) {\n dragState = DragState.dragReject;\n } else if (isDragActive) {\n dragState = DragState.dragActive;\n }\n\n const handleRemoveFile = (removedFile: FilePreview) => {\n setFiles(prevFiles => prevFiles.filter(file => file !== removedFile));\n\n if (onRemoveFile && typeof onRemoveFile === 'function') {\n onRemoveFile(removedFile);\n }\n\n const message = i18n.dropzone.fileRemoved.replace(\n /\\{fileName\\}/g,\n removedFile.name\n );\n\n setAnnouncement(message);\n\n browseFileButtonRef.current && browseFileButtonRef.current.focus();\n };\n\n const handleDeleteFile = (removedFile: FilePreview) => {\n setFiles(prevFiles => prevFiles.filter(file => file !== removedFile));\n\n if (onDeleteFile && typeof onDeleteFile === 'function') {\n onDeleteFile(removedFile);\n }\n\n const message = i18n.dropzone.fileDeleted.replace(\n /\\{fileName\\}/g,\n removedFile.name\n );\n\n setAnnouncement(message);\n\n browseFileButtonRef.current && browseFileButtonRef.current.focus();\n };\n\n const setProgress = (progressProps: {\n percent: number;\n file: FilePreview;\n }) => {\n setFiles(prevFiles =>\n prevFiles.map(file =>\n file === progressProps.file\n ? Object.assign(file, {\n processor: {\n ...file.processor,\n percent: `${progressProps.percent}%`,\n status: 'pending',\n },\n })\n : file\n )\n );\n\n // Announce progress every 25% to avoid too many announcements\n if (progressProps.percent > 0 && progressProps.percent % 25 === 0) {\n const message = i18n.dropzone.fileUploading\n .replace(/\\{fileName\\}/g, progressProps.file.name)\n .replace(/\\{percent\\}/g, progressProps.percent.toString());\n\n setAnnouncement(message);\n }\n };\n\n const setFinished = (finishedProps: { file: FilePreview }) => {\n setFiles(prevFiles =>\n prevFiles.map(file =>\n file === finishedProps.file\n ? Object.assign(file, {\n processor: {\n ...file.processor,\n percent: '',\n status: 'finished',\n },\n })\n : file\n )\n );\n\n // Announce successful upload\n const message = i18n.dropzone.fileUploaded.replace(\n /\\{fileName\\}/g,\n finishedProps.file.name\n );\n\n setAnnouncement(message);\n };\n\n const setError = (errorProps: {\n errors: FileError[];\n file: FilePreview;\n }) => {\n setFiles(prevFiles =>\n prevFiles.map(file =>\n file === errorProps.file\n ? Object.assign(file, {\n errors: errorProps.errors,\n processor: { ...file.processor, status: 'error' },\n })\n : file\n )\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 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 const minFileError = minFiles && files.length < minFiles;\n const maxFileError = maxFiles && files.length > maxFiles;\n\n let errorCode: string | null = null;\n\n if (maxFileError) {\n errorCode = 'too-many-files';\n } else if (minFileError) {\n errorCode = 'too-few-files';\n }\n\n setErrorMessage(formatError(errorCode, { minFiles, maxFiles }));\n\n if (sendFiles && files.length > 0 && !maxFileError && !minFileError) {\n setFiles((prevFiles: FilePreview[]) => {\n return prevFiles.map((file: FilePreview) => {\n if (!file.errors && !file.processor && onSendFile) {\n onSendFile({\n file,\n onError: setError,\n onFinish: setFinished,\n onProgress: setProgress,\n });\n }\n\n return file;\n });\n });\n }\n }, [\n sendFiles,\n files.length,\n onSendFile,\n maxFiles,\n minFiles,\n i18n.dropzone.errors,\n i18n.dropzone.files,\n ]);\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={{\n color: isInverse ? theme.colors.neutral0 : theme.colors.brand.navy,\n ...labelStyle,\n }}\n labelText={labelText}\n messageStyle={{ minHeight: 0 }}\n data-testid={testId}\n >\n <HelperMessage\n id={helperMessageId}\n theme={theme}\n isInverse={isInverse}\n >\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 ref={browseFileButtonRef}\n aria-describedby={helperMessage ? helperMessageId : undefined}\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 ? theme.colors.neutral0 : theme.colors.neutral700\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 ref={browseFileButtonRef}\n aria-describedby={helperMessage ? helperMessageId : undefined}\n >\n {i18n.dropzone.browseFiles}\n </Button>\n </Flex>\n )}\n </Container>\n </FormFieldContainer>\n <PreviewList>\n {files.map((file: FilePreview) => (\n <PreviewItem key={file.name}>\n <Preview\n accept={accept}\n file={file}\n isInverse={isInverse}\n maxSize={maxSize}\n minSize={minSize}\n onDeleteFile={handleDeleteFile}\n onRemoveFile={handleRemoveFile}\n thumbnails={thumbnails}\n />\n </PreviewItem>\n ))}\n </PreviewList>\n\n <VisuallyHidden>\n <Announce>{announcement}</Announce>\n </VisuallyHidden>\n </InverseContext.Provider>\n );\n }\n);\n"],"names":["icons","default","Icon","InsertDriveFileIcon","style","color","magma","colors","neutral700","inverseStyle","neutral300","word","FileWordIcon","blue500","excel","FileExcelIcon","green500","powerpoint","FilePowerpointIcon","tangerine600","tangerine500","pdf","FilePdfIcon","red600","red500","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","neutral500","typeScale","size02","fontSize","lineHeight","StyledFlex","Flex","FileName","StyledCard","Card","errors","danger","neutral800","neutral200","neutral0","brand","navy","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","subtle","dropzone","removeFile","name","icon","Spinner","skyBlue","primary","_jsxs","Transition","isOpen","unmountOnExit","fade","CheckCircleIcon","success","marginTop","deleteFile","DeleteIcon","_file$processor","processor","InverseContext","Provider","value","borderRadius","CardBorderRadius","small","cornerTreatment","CardCornerTreatment","all","testId","role","_extends","behavior","FlexBehavior","container","alignItems","FlexAlignItems","center","item","ErrorIcon","startsWith","xs","marginLeft","percent","slice","map","_ref","code","header","message","formatError","error","constraints","byteLabel","Array","isArray","length","messageSuffix","join","Fragment","DragState","Container","noDrag","borderRadiusNone","borderRadiusSmall","dragState","dragReject","red400","dragActive","dragAccept","transparentize","neutral1200","neutral100","HelperMessage","Wrapper","spaceScale","spacing01","PreviewList","ul","PreviewItem","li","Dropzone","containerStyle","disabled","dropzoneOptions","multiple","helperMessage","id","defaultId","inputSize","isLabelVisuallyHidden","labelStyle","labelText","maxFiles","minFiles","onSendFile","sendFiles","files","setFiles","errorMessage","setErrorMessage","announcement","setAnnouncement","useGenerateId","helperMessageId","browseFileButtonRef","useRef","onDrop","useCallback","acceptedFiles","rejectedFiles","newFiles","Object","assign","URL","createObjectURL","prevFiles","fileNames","fileAdded","replace","filesAdded","toString","current","focus","getInputProps","getRootProps","isDragAccept","isDragActive","isDragReject","open","inputRef","useDropzone","noClick","useImperativeHandle","inputProps","removedFile","filter","fileRemoved","fileDeleted","setProgress","progressProps","fileUploading","setFinished","finishedProps","fileUploaded","setError","errorProps","forEach","revokeObjectURL","minFileError","maxFileError","errorCode","onError","onFinish","onProgress","FormFieldContainer","actionable","fieldId","messageStyle","minHeight","tabIndex","autoComplete","onChange","Button","margin","browseFiles","CloudUploadIcon","dragMessage","solid","VisuallyHidden","Announce"],"mappings":"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"}