@am92/react-design-system 2.9.12 → 2.10.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.
- package/dist/Components/DsBottomSheet/DsBottomSheet.Component.js +6 -6
- package/dist/Components/DsDialog/DsDialog.Component.js +4 -4
- package/dist/Components/DsFileUploader/DsFileUploader.Component.d.ts +2 -3
- package/dist/Components/DsFileUploader/DsFileUploader.Component.js +109 -158
- package/dist/Components/DsFileUploader/DsFileUploader.Overrides.d.ts +5 -1
- package/dist/Components/DsFileUploader/DsFileUploader.Overrides.js +6 -1
- package/dist/Components/DsFileUploader/DsFileUploader.Types.d.ts +306 -13
- package/dist/Components/DsFileUploader/DsFileUploader.Types.js +46 -4
- package/dist/Components/DsFileUploader/DsFileUploaderPreview/DsFileUploaderImagePreview.Component.d.ts +11 -0
- package/dist/Components/DsFileUploader/DsFileUploaderPreview/DsFileUploaderImagePreview.Component.js +68 -0
- package/dist/Components/DsFileUploader/DsFileUploaderPreview/DsFileUploaderPreview.Component.d.ts +14 -0
- package/dist/Components/DsFileUploader/DsFileUploaderPreview/DsFileUploaderPreview.Component.js +28 -0
- package/dist/Components/DsFileUploader/FileUploaderFiles.d.ts +3 -0
- package/dist/Components/DsFileUploader/FileUploaderFiles.js +48 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderActionButton.Component.d.ts +10 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderActionButton.Component.js +18 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderDropZone.d.ts +10 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderDropZone.js +130 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderSelectedFilesSegment.d.ts +10 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderSelectedFilesSegment.js +21 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderUploadedFilesSegment.d.ts +10 -0
- package/dist/Components/DsFileUploader/Slots/DsFileUploaderUploadedFilesSegment.js +21 -0
- package/dist/Components/DsFileUploader/converter.d.ts +2 -0
- package/dist/Components/DsFileUploader/converter.js +25 -0
- package/dist/Components/DsFileUploader/helpers.d.ts +9 -0
- package/dist/Components/DsFileUploader/helpers.js +88 -0
- package/dist/Components/DsFileUploader/validator.d.ts +2 -0
- package/dist/Components/DsFileUploader/validator.js +37 -0
- package/dist/Theme/componentOverrides.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DsBox } from '../../DsBox';
|
|
3
|
+
import { DsButton } from '../../DsButton';
|
|
4
|
+
import { DsInput } from '../../DsInput';
|
|
5
|
+
import { DsRemixIcon } from '../../DsRemixIcon';
|
|
6
|
+
import { DsStack } from '../../DsStack';
|
|
7
|
+
import { DsTypography } from '../../DsTypography';
|
|
8
|
+
import { DsFileUploaderDropzoneDefaultProps } from '../DsFileUploader.Types';
|
|
9
|
+
/**
|
|
10
|
+
* DsFileUploaderDropZone
|
|
11
|
+
*
|
|
12
|
+
* This component renders a drop zone area where users can drag & drop files
|
|
13
|
+
* or click to upload using a hidden input field. It supports two layout variants:
|
|
14
|
+
* - 'DEFAULT': Large button with drag and drop space area
|
|
15
|
+
* - 'COMPRESSED': Smaller area and button size to save space
|
|
16
|
+
*/
|
|
17
|
+
export const DsFileUploaderDropZone = (inProps) => {
|
|
18
|
+
const props = {
|
|
19
|
+
...DsFileUploaderDropzoneDefaultProps,
|
|
20
|
+
...inProps
|
|
21
|
+
};
|
|
22
|
+
const { variant, IconProps, title, description, InputProps, disabled, ...restDsStackProps } = props;
|
|
23
|
+
const isCompressed = variant === 'COMPRESSED';
|
|
24
|
+
const renderDescription = () => {
|
|
25
|
+
if (!description)
|
|
26
|
+
return null;
|
|
27
|
+
const isArray = Array.isArray(description);
|
|
28
|
+
const isString = typeof description === 'string';
|
|
29
|
+
const shouldRenderCompressedArray = isArray && isCompressed;
|
|
30
|
+
const shouldRenderString = isString;
|
|
31
|
+
if (!shouldRenderCompressedArray && !shouldRenderString)
|
|
32
|
+
return null;
|
|
33
|
+
const color = `var(--ds-colour-${isCompressed ? 'typoPrimary' : 'typoTertiary'})`;
|
|
34
|
+
const containerProps = {
|
|
35
|
+
direction: isCompressed ? 'row' : undefined,
|
|
36
|
+
justifyContent: isCompressed
|
|
37
|
+
? isArray && description.length > 1
|
|
38
|
+
? 'space-between'
|
|
39
|
+
: 'center'
|
|
40
|
+
: 'center',
|
|
41
|
+
alignItems: isCompressed ? 'center' : undefined,
|
|
42
|
+
textAlign: isCompressed ? 'center' : undefined,
|
|
43
|
+
pb: isCompressed ? undefined : 'var(--ds-spacing-bitterCold)',
|
|
44
|
+
sx: isCompressed
|
|
45
|
+
? {
|
|
46
|
+
py: 'var(--ds-spacing-quickFreeze)',
|
|
47
|
+
px: 'var(--ds-spacing-glacial)',
|
|
48
|
+
backgroundColor: 'var(--ds-colour-surfaceSecondary)',
|
|
49
|
+
borderRadius: 'var(--ds-radius-quickFreeze)'
|
|
50
|
+
}
|
|
51
|
+
: undefined
|
|
52
|
+
};
|
|
53
|
+
const renderTypographies = () => {
|
|
54
|
+
const descList = isString ? [description] : description;
|
|
55
|
+
return descList.map((desc, index) => (_jsx(DsTypography, { variant: 'bodyRegularSmall', align: 'center', color: color, children: desc }, index)));
|
|
56
|
+
};
|
|
57
|
+
return (_jsx(DsStack, { ...containerProps, children: renderTypographies() }, 'dropzone-description'));
|
|
58
|
+
};
|
|
59
|
+
return [
|
|
60
|
+
_jsxs(DsBox, { sx: {
|
|
61
|
+
width: '100%',
|
|
62
|
+
position: 'relative',
|
|
63
|
+
borderRadius: 'var(--ds-radius-glacial)',
|
|
64
|
+
borderWidth: '1px',
|
|
65
|
+
borderStyle: 'dashed',
|
|
66
|
+
borderColor: 'var(--ds-colour-strokeDefault)',
|
|
67
|
+
backgroundColor: disabled
|
|
68
|
+
? 'var(--ds-colour-stateDisabledSurface)'
|
|
69
|
+
: 'var(--ds-colour-surfacePrimary)',
|
|
70
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
71
|
+
'&:hover': {
|
|
72
|
+
borderColor: disabled
|
|
73
|
+
? 'var(--ds-colour-strokeDefault)'
|
|
74
|
+
: 'var(--ds-colour-strokeSecondarySelected)',
|
|
75
|
+
'.dropzone-content-wrapper': {
|
|
76
|
+
backgroundColor: disabled
|
|
77
|
+
? 'var(--ds-colour-stateDisabledSurface)'
|
|
78
|
+
: isCompressed
|
|
79
|
+
? 'var(--ds-colour-surfaceSecondary)'
|
|
80
|
+
: 'var(--ds-colour-stateSelectedSecondaryHover)'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, children: [_jsxs(DsStack, { className: 'dropzone-content-wrapper', flexDirection: isCompressed ? 'row' : 'column', gap: 'var(--ds-spacing-quickFreeze)', justifyContent: 'center', alignItems: 'center', ...restDsStackProps, sx: {
|
|
84
|
+
borderRadius: isCompressed
|
|
85
|
+
? 'var(--ds-radius-quickFreeze)'
|
|
86
|
+
: 'var(--ds-radius-glacial)',
|
|
87
|
+
m: isCompressed
|
|
88
|
+
? 'var(--ds-spacing-frostbite)'
|
|
89
|
+
: 'var(--ds-spacing-zero)',
|
|
90
|
+
px: isCompressed
|
|
91
|
+
? 'var(--ds-spacing-glacial)'
|
|
92
|
+
: 'var(--ds-spacing-bitterCold)',
|
|
93
|
+
pt: isCompressed
|
|
94
|
+
? 'var(--ds-spacing-zero)'
|
|
95
|
+
: 'var(--ds-spacing-bitterCold)',
|
|
96
|
+
backgroundColor: disabled
|
|
97
|
+
? 'var(--ds-colour-stateDisabledSurface)'
|
|
98
|
+
: isCompressed
|
|
99
|
+
? 'var(--ds-colour-surfaceSecondary)'
|
|
100
|
+
: 'var(--ds-colour-surfacePrimary)',
|
|
101
|
+
'&:hover': {
|
|
102
|
+
backgroundColor: isCompressed
|
|
103
|
+
? 'var(--ds-colour-surfaceSecondary)'
|
|
104
|
+
: 'var(--ds-colour-stateSelectedSecondaryHover)'
|
|
105
|
+
},
|
|
106
|
+
...restDsStackProps?.sx
|
|
107
|
+
}, children: [_jsx(DsRemixIcon, { className: isCompressed ? 'ri-upload-line' : 'ri-upload-cloud-2-line', fontSize: isCompressed ? 'frostbite' : 'mild', color: disabled ? 'disabled' : 'secondary', ...IconProps }), _jsx(DsButton, { disabled: disabled, variant: 'text', color: 'secondary', children: title }), !isCompressed && renderDescription()] }), _jsx(DsInput, { type: 'file', slot: 'input', disabled: disabled, sx: {
|
|
108
|
+
position: 'absolute',
|
|
109
|
+
top: 0,
|
|
110
|
+
left: 0,
|
|
111
|
+
height: '100%',
|
|
112
|
+
width: '100%',
|
|
113
|
+
opacity: 0,
|
|
114
|
+
margin: 'var(--ds-spacing-zero) !important'
|
|
115
|
+
}, onChange: InputProps?.onChange, onDrop: InputProps?.onDrop, onDragOver: InputProps?.onDragOver, disableUnderline: true, inputProps: {
|
|
116
|
+
title,
|
|
117
|
+
value: '',
|
|
118
|
+
...InputProps,
|
|
119
|
+
accept: InputProps?.accept,
|
|
120
|
+
multiple: InputProps?.multiple,
|
|
121
|
+
style: {
|
|
122
|
+
height: '100%',
|
|
123
|
+
width: '100%',
|
|
124
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
125
|
+
...InputProps?.style
|
|
126
|
+
}
|
|
127
|
+
} })] }, 'dropzone-box'),
|
|
128
|
+
isCompressed && renderDescription()
|
|
129
|
+
];
|
|
130
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TDsFileUploaderSlotProps } from '../DsFileUploader.Types';
|
|
2
|
+
/**
|
|
3
|
+
* DsFileUploaderSelectedFilesSegment
|
|
4
|
+
*
|
|
5
|
+
* This component is a wrapper to render a labeled section
|
|
6
|
+
* for displaying selected files in a scrollable container.
|
|
7
|
+
*
|
|
8
|
+
* It supports slot-level customization via props and merges them with default values.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DsFileUploaderSelectedFilesSegment: (inProps: TDsFileUploaderSlotProps["SelectedItemSegment"]) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DsStack } from '../../DsStack';
|
|
3
|
+
import { DsTypography } from '../../DsTypography';
|
|
4
|
+
import { DsFileUploaderDefaultProps } from '../DsFileUploader.Types';
|
|
5
|
+
import { cloneElement, isValidElement } from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* DsFileUploaderSelectedFilesSegment
|
|
8
|
+
*
|
|
9
|
+
* This component is a wrapper to render a labeled section
|
|
10
|
+
* for displaying selected files in a scrollable container.
|
|
11
|
+
*
|
|
12
|
+
* It supports slot-level customization via props and merges them with default values.
|
|
13
|
+
*/
|
|
14
|
+
export const DsFileUploaderSelectedFilesSegment = (inProps) => {
|
|
15
|
+
const props = {
|
|
16
|
+
...DsFileUploaderDefaultProps.slotProps?.SelectedItemSegment,
|
|
17
|
+
...inProps
|
|
18
|
+
};
|
|
19
|
+
const { label, children } = props;
|
|
20
|
+
return (_jsxs(DsStack, { spacing: 'var(--ds-spacing-frostbite)', children: [_jsx(DsTypography, { py: 'var(--ds-spacing-glacial)', variant: 'subheadingSemiboldDefault', color: 'var(--ds-colour-typoSecondary)', children: label }), _jsx(DsStack, { spacing: 'var(--ds-spacing-frostbite)', sx: { maxHeight: '440px', overflowY: 'auto' }, children: isValidElement(children) && cloneElement(children, { ...props }) })] }));
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TDsFileUploaderSlotProps } from '../DsFileUploader.Types';
|
|
2
|
+
/**
|
|
3
|
+
* DsFileUploaderSelectedFilesSegment
|
|
4
|
+
*
|
|
5
|
+
* This component is a wrapper to render a labeled section
|
|
6
|
+
* for displaying uploaded files in a scrollable container.
|
|
7
|
+
*
|
|
8
|
+
* It supports slot-level customization via props and merges them with default values.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DsFileUploaderUploadedFilesSegment: (inProps: TDsFileUploaderSlotProps["UploadedItemSegment"]) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DsStack } from '../../DsStack';
|
|
3
|
+
import { DsTypography } from '../../DsTypography';
|
|
4
|
+
import { DsFileUploaderDefaultProps } from '../DsFileUploader.Types';
|
|
5
|
+
import { cloneElement, isValidElement } from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* DsFileUploaderSelectedFilesSegment
|
|
8
|
+
*
|
|
9
|
+
* This component is a wrapper to render a labeled section
|
|
10
|
+
* for displaying uploaded files in a scrollable container.
|
|
11
|
+
*
|
|
12
|
+
* It supports slot-level customization via props and merges them with default values.
|
|
13
|
+
*/
|
|
14
|
+
export const DsFileUploaderUploadedFilesSegment = (inProps) => {
|
|
15
|
+
const props = {
|
|
16
|
+
...DsFileUploaderDefaultProps.slotProps?.UploadedItemSegment,
|
|
17
|
+
...inProps
|
|
18
|
+
};
|
|
19
|
+
const { label, children } = props;
|
|
20
|
+
return (_jsxs(DsStack, { spacing: 'var(--ds-spacing-frostbite)', children: [_jsx(DsTypography, { py: 'var(--ds-spacing-glacial)', variant: 'subheadingSemiboldDefault', color: 'var(--ds-colour-typoSecondary)', children: label }), _jsx(DsStack, { spacing: 'var(--ds-spacing-frostbite)', sx: { maxHeight: '440px', overflowY: 'auto' }, children: isValidElement(children) && cloneElement(children, { ...props }) })] }));
|
|
21
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const fileToFileUploader = async (file, contentType) => {
|
|
2
|
+
const { name, type, size } = file;
|
|
3
|
+
let content = file;
|
|
4
|
+
if (contentType === 'BASE64') {
|
|
5
|
+
content = await fileToBase64(file);
|
|
6
|
+
if (typeof content === 'string' && content.startsWith('data:')) {
|
|
7
|
+
content = content.substring(content.indexOf(',') + 1);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const fileUploader = {
|
|
11
|
+
name,
|
|
12
|
+
type,
|
|
13
|
+
size,
|
|
14
|
+
content
|
|
15
|
+
};
|
|
16
|
+
return fileUploader;
|
|
17
|
+
};
|
|
18
|
+
const fileToBase64 = (file) => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const reader = new FileReader();
|
|
21
|
+
reader.readAsDataURL(file);
|
|
22
|
+
reader.onload = () => resolve(reader.result);
|
|
23
|
+
reader.onerror = error => reject(error);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IDsFileUploaderProps, TContentType, TErrorValue, TFile, TMultiple, TFileValue } from './DsFileUploader.Types';
|
|
2
|
+
export declare const mergeProps: <T extends Record<string, any>>(inProps: Partial<T>, defaultProps: T) => T;
|
|
3
|
+
export declare const getFileTypeIcon: <ContentType extends TContentType>(file: TFile<ContentType>) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare const humanizeFileSize: (bytes: number, decimals?: number) => string;
|
|
5
|
+
export declare const getDefaultValue: <Multiple extends TMultiple, ContentType extends TContentType>(props: IDsFileUploaderProps<Multiple, ContentType>) => TFileValue<Multiple, ContentType> | null;
|
|
6
|
+
export declare const getValidProcessedFile: <Multiple extends TMultiple, ContentType extends TContentType>(filesToProcess: FileList, files: TFileValue<Multiple, ContentType> | null, accept: string, minSize?: number, maxSize?: number, contentType?: TContentType) => Promise<{
|
|
7
|
+
valid: TFileValue<Multiple, ContentType>;
|
|
8
|
+
invalid: TErrorValue<Multiple, ContentType>;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DsFileUploaderImagePreview } from './DsFileUploaderPreview/DsFileUploaderImagePreview.Component';
|
|
3
|
+
import { getFileValidator } from './validator';
|
|
4
|
+
import { fileToFileUploader } from './converter';
|
|
5
|
+
import { DsRemixIcon } from '../DsRemixIcon';
|
|
6
|
+
export const mergeProps = (inProps, defaultProps) => {
|
|
7
|
+
return {
|
|
8
|
+
...defaultProps,
|
|
9
|
+
...inProps,
|
|
10
|
+
slots: {
|
|
11
|
+
...defaultProps.slots,
|
|
12
|
+
...inProps.slots
|
|
13
|
+
},
|
|
14
|
+
slotProps: {
|
|
15
|
+
...defaultProps.slotProps,
|
|
16
|
+
...inProps.slotProps,
|
|
17
|
+
SelectedItemSegment: {
|
|
18
|
+
...defaultProps.slotProps?.SelectedItemSegment,
|
|
19
|
+
...inProps.slotProps?.SelectedItemSegment
|
|
20
|
+
},
|
|
21
|
+
UploadedItemSegment: {
|
|
22
|
+
...defaultProps.slotProps?.UploadedItemSegment,
|
|
23
|
+
...inProps.slotProps?.UploadedItemSegment
|
|
24
|
+
},
|
|
25
|
+
DropZone: {
|
|
26
|
+
...defaultProps?.slotProps?.DropZone,
|
|
27
|
+
...inProps.slotProps?.DropZone
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export const getFileTypeIcon = (file) => {
|
|
33
|
+
const { type: mimeType } = file;
|
|
34
|
+
const IMAGE_REGEX = new RegExp('^image/.*');
|
|
35
|
+
const VIDEO_REGEX = new RegExp('^video/.*');
|
|
36
|
+
if (IMAGE_REGEX.test(mimeType)) {
|
|
37
|
+
return _jsx(DsFileUploaderImagePreview, { file: file });
|
|
38
|
+
}
|
|
39
|
+
else if (VIDEO_REGEX.test(mimeType)) {
|
|
40
|
+
return _jsx(DsRemixIcon, { className: "ri-video-line" });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return _jsx(DsRemixIcon, { className: "ri-file-list-2-line" });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export const humanizeFileSize = (bytes, decimals = 2) => {
|
|
47
|
+
if (!+bytes)
|
|
48
|
+
return '0 Bytes';
|
|
49
|
+
const k = 1024;
|
|
50
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
51
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
52
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
53
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
54
|
+
};
|
|
55
|
+
export const getDefaultValue = (props) => {
|
|
56
|
+
const { value, multiple } = props;
|
|
57
|
+
if (value) {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
if (multiple) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
};
|
|
65
|
+
export const getValidProcessedFile = async (filesToProcess, files, accept, minSize, maxSize, contentType) => {
|
|
66
|
+
const validator = getFileValidator(accept, minSize, maxSize);
|
|
67
|
+
const isMultiple = Array.isArray(files);
|
|
68
|
+
const validFiles = isMultiple ? [...files] : [];
|
|
69
|
+
const invalidFiles = [];
|
|
70
|
+
const fileList = [...filesToProcess];
|
|
71
|
+
for (const file of fileList) {
|
|
72
|
+
const fileUploader = await fileToFileUploader(file, contentType || 'FILE');
|
|
73
|
+
const errorCode = validator(file);
|
|
74
|
+
if (!errorCode) {
|
|
75
|
+
validFiles.unshift(fileUploader);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const temp = {
|
|
79
|
+
file: fileUploader,
|
|
80
|
+
errorCode
|
|
81
|
+
};
|
|
82
|
+
invalidFiles.push(temp);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const valid = isMultiple ? validFiles : validFiles[0];
|
|
86
|
+
const invalid = (isMultiple ? invalidFiles : invalidFiles[0]);
|
|
87
|
+
return { valid, invalid };
|
|
88
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ERROR_CODES } from './DsFileUploader.Types';
|
|
2
|
+
export const getFileValidator = (accept, minSize = 0, maxSize = Infinity) => {
|
|
3
|
+
const validateFileType = getFileTypeValidator(accept);
|
|
4
|
+
return (file) => {
|
|
5
|
+
const { size, type } = file;
|
|
6
|
+
if (!validateMinSize(size, minSize)) {
|
|
7
|
+
return ERROR_CODES.FILE_SIZE_BELOW_MIN;
|
|
8
|
+
}
|
|
9
|
+
if (!validateMaxSize(size, maxSize)) {
|
|
10
|
+
return ERROR_CODES.MAX_FILE_SIZE_EXCEEDED;
|
|
11
|
+
}
|
|
12
|
+
if (!validateFileType(type)) {
|
|
13
|
+
return ERROR_CODES.INVALID_FILE_TYPE;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const validateMinSize = (size, minSize = 0) => {
|
|
18
|
+
return size >= minSize;
|
|
19
|
+
};
|
|
20
|
+
const validateMaxSize = (size, maxSize = Infinity) => {
|
|
21
|
+
return size <= maxSize;
|
|
22
|
+
};
|
|
23
|
+
const getFileTypeValidator = (accept) => {
|
|
24
|
+
// Escape dots and replace wildcards with .* for regex
|
|
25
|
+
const typesPattern = accept
|
|
26
|
+
.split(',')
|
|
27
|
+
.map(type => type.trim())
|
|
28
|
+
.map(type => type.replace(/\./g, '\\.').replace(/\*/g, '.*'))
|
|
29
|
+
.join('|');
|
|
30
|
+
// Create a regex with start and end anchors
|
|
31
|
+
const typesRegex = new RegExp(`^(${typesPattern})$`);
|
|
32
|
+
// Validator function
|
|
33
|
+
const validateFileType = (mimeType) => {
|
|
34
|
+
return typesRegex.test(mimeType);
|
|
35
|
+
};
|
|
36
|
+
return validateFileType;
|
|
37
|
+
};
|
|
@@ -1030,6 +1030,9 @@ declare const componentOverrides: {
|
|
|
1030
1030
|
};
|
|
1031
1031
|
};
|
|
1032
1032
|
};
|
|
1033
|
+
DsFileUploader: {
|
|
1034
|
+
defaultProps: import("../Components").IDsFileUploaderProps<import("../Components").TMultiple, "FILE">;
|
|
1035
|
+
};
|
|
1033
1036
|
MuiFab: {
|
|
1034
1037
|
defaultProps: import("../Components").DsFabProps;
|
|
1035
1038
|
styleOverrides: {
|