@aokiapp/rjsf-mantine-theme
Version:
Mantine theme, fields and widgets for react-jsonschema-form
1 lines • 14.5 kB
Source Map (JSON)
{"version":3,"file":"FileWidget.mjs","sources":["../../src/widgets/FileWidget.tsx"],"sourcesContent":["import { ChangeEvent, createContext, useCallback, useContext, useMemo } from 'react';\nimport { dataURItoBlob, FormContextType, getTemplate, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils';\nimport { Badge, Card, Group, Text, Image, Box, AspectRatio, CloseButton } from '@mantine/core';\nimport {\n IconCode,\n IconFile,\n IconFileDigit,\n IconFileTypeTxt,\n IconFileZip,\n IconPdf,\n IconPhoto,\n} from '@tabler/icons-react';\n\nfunction addNameToDataURL(dataURL: string, name: string) {\n if (dataURL === null) {\n return null;\n }\n return dataURL.replace(';base64', `;name=${encodeURIComponent(name)};base64`);\n}\n\ntype FileInfoType = {\n dataURL?: string | null;\n name: string;\n size: number;\n type: string;\n};\n\nfunction processFile(file: File): Promise<FileInfoType> {\n const { name, size, type } = file;\n return new Promise((resolve, reject) => {\n const reader = new window.FileReader();\n reader.onerror = reject;\n reader.onload = (event) => {\n if (typeof event.target?.result === 'string') {\n resolve({\n dataURL: addNameToDataURL(event.target.result, name),\n name,\n size,\n type,\n });\n } else {\n resolve({\n dataURL: null,\n name,\n size,\n type,\n });\n }\n };\n reader.readAsDataURL(file);\n });\n}\n\nfunction processFiles(files: FileList) {\n return Promise.all(Array.from(files).map(processFile));\n}\n\nconst fileInfoCtx = createContext<{\n filesInfo: FileInfoType[];\n onRemove: (index: number) => void;\n preview: boolean;\n}>(null!);\n\nfunction FileInfoPreview({ fileInfo }: { fileInfo: FileInfoType }) {\n const { preview } = useContext(fileInfoCtx);\n const { dataURL, type, name } = fileInfo;\n if (!dataURL) {\n return null;\n }\n\n if (preview && type.indexOf('image') !== -1) {\n return <Image src={dataURL} alt={name} />;\n }\n let IconComponent;\n\n switch (type) {\n case 'application/pdf':\n case 'application/x-pdf':\n IconComponent = IconPdf;\n break;\n case 'image/svg+xml':\n case 'image/svg':\n IconComponent = IconFile;\n break;\n case 'image/png':\n case 'image/jpeg':\n case 'image/gif':\n case 'image/bmp':\n IconComponent = IconPhoto;\n break;\n case 'application/zip':\n case 'application/x-zip-compressed':\n case 'application/x-gzip':\n case 'application/x-tar':\n case 'application/x-bzip':\n case 'application/x-bzip2':\n case 'application/x-7z-compressed':\n case 'application/x-rar-compressed':\n IconComponent = IconFileZip;\n break;\n case 'text/plain':\n IconComponent = IconFileTypeTxt;\n break;\n case 'text/html':\n case 'application/xhtml+xml':\n case 'application/xml':\n case 'application/json':\n case 'application/javascript':\n IconComponent = IconCode;\n break;\n case 'application/octet-stream':\n IconComponent = IconFileDigit;\n break;\n default:\n IconComponent = IconFile;\n break;\n }\n\n return (\n <Box\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'column',\n }}\n >\n <IconComponent size={30} />\n <Badge variant='outline'>{type}</Badge>\n </Box>\n );\n}\n\nfunction convertUnitPrefix(size: number) {\n const prefixes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const index = Math.floor(Math.log(size) / Math.log(1024));\n return `${(size / Math.pow(1024, index)).toFixed(2)} ${prefixes[index]}`;\n}\nfunction FilesInfo() {\n const { filesInfo, onRemove } = useContext(fileInfoCtx);\n\n if (filesInfo.length === 0) {\n return null;\n }\n return (\n <Group m={'sm'}>\n {filesInfo.map((fileInfo, key) => {\n const { name, size } = fileInfo;\n const rmFile = () => onRemove(key);\n return (\n <Card key={key} shadow='sm' padding='xs' radius='md' w={200} withBorder>\n <Card.Section>\n <AspectRatio ratio={2} maw={240} mx='auto'>\n <FileInfoPreview fileInfo={fileInfo} />\n </AspectRatio>\n </Card.Section>\n <Text fw={600} truncate='end'>\n {name}\n </Text>\n <Group gap='xs' justify='space-between'>\n <Badge color='blue' variant='light'>\n {convertUnitPrefix(size)}\n </Badge>\n <CloseButton onClick={rmFile} />\n </Group>\n </Card>\n );\n })}\n </Group>\n );\n}\n\nfunction extractFileInfo(dataURLs: string[]): FileInfoType[] {\n return dataURLs\n .filter((dataURL) => dataURL)\n .map((dataURL) => {\n const { blob, name } = dataURItoBlob(dataURL);\n return {\n dataURL,\n name: name,\n size: blob.size,\n type: blob.type,\n };\n });\n}\n\n/**\n * The `FileWidget` is a widget for rendering file upload fields.\n * It is typically used with a string property with data-url format.\n */\nfunction FileWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(\n props: WidgetProps<T, S, F>,\n) {\n const { disabled, readonly, required, multiple, onChange, value, options, registry } = props;\n const BaseInputTemplate = getTemplate<'BaseInputTemplate', T, S, F>('BaseInputTemplate', registry, options);\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n if (!event.target.files) {\n return;\n }\n // Due to variances in themes, dealing with multiple files for the array case now happens one file at a time.\n // This is because we don't pass `multiple` into the `BaseInputTemplate` anymore. Instead, we deal with the single\n // file in each event and concatenate them together ourselves\n processFiles(event.target.files).then((filesInfoEvent) => {\n const newValue = filesInfoEvent.map((fileInfo) => fileInfo.dataURL);\n if (multiple) {\n onChange(value.concat(newValue[0]));\n } else {\n onChange(newValue[0]);\n }\n });\n },\n [multiple, value, onChange],\n );\n\n const filesInfo = useMemo(() => extractFileInfo(Array.isArray(value) ? value : [value]), [value]);\n const rmFile = useCallback(\n (index: number) => {\n if (multiple) {\n const newValue = value.filter((_: any, i: number) => i !== index);\n onChange(newValue);\n } else {\n onChange(undefined);\n }\n },\n [multiple, value, onChange],\n );\n return (\n <div className='armt-widget-file'>\n <fileInfoCtx.Provider value={{ filesInfo, onRemove: rmFile, preview: options.filePreview ?? false }}>\n <BaseInputTemplate\n {...props}\n disabled={disabled || readonly}\n type='file'\n required={value ? false : required} // this turns off HTML required validation when a value exists\n onChangeOverride={handleChange}\n value=''\n accept={options.accept ? String(options.accept) : undefined}\n />\n <FilesInfo />\n </fileInfoCtx.Provider>\n </div>\n );\n}\n\nexport default FileWidget;\n"],"names":[],"mappings":"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"}