mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
added dropzones for comments and node editors
This commit is contained in:
parent
fb8ad315c0
commit
f10a1fa2d8
23 changed files with 247 additions and 41 deletions
|
@ -25,6 +25,7 @@
|
|||
"ramda": "^0.26.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dropzone": "^11.4.2",
|
||||
"react-masonry-css": "^1.0.16",
|
||||
"react-popper": "^2.2.3",
|
||||
"react-redux": "^7.2.2",
|
||||
|
@ -69,6 +70,7 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/throttle-debounce": "^2.1.0",
|
||||
"@craco/craco": "5.8.0",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/marked": "^1.2.2",
|
||||
|
|
|
@ -11,7 +11,7 @@ import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
|
|||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { IComment, INode } from '~/redux/types';
|
||||
import { EMPTY_COMMENT } from '~/redux/node/constants';
|
||||
import { CommentFormDropzone } from '~/components/comment/CommentFormDropzone';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
import styles from './styles.module.scss';
|
||||
import { ERROR_LITERAL } from '~/constants/errors';
|
||||
import { useInputPasteUpload } from '~/utils/hooks/useInputPasteUpload';
|
||||
|
@ -50,7 +50,7 @@ const CommentForm: FC<IProps> = ({ comment, nodeId, onCancelEdit }) => {
|
|||
useInputPasteUpload(textarea, uploader.uploadFiles);
|
||||
|
||||
return (
|
||||
<CommentFormDropzone onUpload={uploader.uploadFiles}>
|
||||
<UploadDropzone onUpload={uploader.uploadFiles}>
|
||||
<form onSubmit={formik.handleSubmit} className={styles.wrap}>
|
||||
<FormikProvider value={formik}>
|
||||
<FileUploaderProvider value={uploader}>
|
||||
|
@ -103,7 +103,7 @@ const CommentForm: FC<IProps> = ({ comment, nodeId, onCancelEdit }) => {
|
|||
</FileUploaderProvider>
|
||||
</FormikProvider>
|
||||
</form>
|
||||
</CommentFormDropzone>
|
||||
</UploadDropzone>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { SortableAudioGrid } from '~/components/editors/SortableAudioGrid';
|
|||
import { IFile } from '~/redux/types';
|
||||
import { SortEnd } from 'react-sortable-hoc';
|
||||
import { moveArrItem } from '~/utils/fn';
|
||||
import { useDropZone } from '~/utils/hooks';
|
||||
import { useFileDropZone } from '~/utils/hooks';
|
||||
import { COMMENT_FILE_TYPES, UPLOAD_TYPES } from '~/redux/uploads/constants';
|
||||
import { useFileUploaderContext } from '~/utils/hooks/useFileUploader';
|
||||
|
||||
|
@ -29,7 +29,7 @@ const CommentFormAttaches: FC = () => {
|
|||
pending,
|
||||
]);
|
||||
|
||||
const onDrop = useDropZone(uploadFiles, COMMENT_FILE_TYPES);
|
||||
const onDrop = useFileDropZone(uploadFiles, COMMENT_FILE_TYPES);
|
||||
|
||||
const hasImageAttaches = images.length > 0 || pendingImages.length > 0;
|
||||
const hasAudioAttaches = audios.length > 0 || pendingAudios.length > 0;
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import React, { FC } from 'react';
|
||||
import { COMMENT_FILE_TYPES } from '~/redux/uploads/constants';
|
||||
import { useDropZone } from '~/utils/hooks';
|
||||
|
||||
interface IProps {
|
||||
onUpload: (files: File[]) => void;
|
||||
}
|
||||
|
||||
const CommentFormDropzone: FC<IProps> = ({ children, onUpload }) => {
|
||||
const onDrop = useDropZone(onUpload, COMMENT_FILE_TYPES);
|
||||
return <div onDropCapture={onDrop}>{children}</div>;
|
||||
};
|
||||
|
||||
export { CommentFormDropzone };
|
|
@ -12,12 +12,13 @@ import { useNodeImages } from '~/utils/hooks/node/useNodeImages';
|
|||
import { useNodeAudios } from '~/utils/hooks/node/useNodeAudios';
|
||||
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
|
||||
import { useFileUploaderContext } from '~/utils/hooks/useFileUploader';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
|
||||
type IProps = NodeEditorProps;
|
||||
|
||||
const AudioEditor: FC<IProps> = () => {
|
||||
const { values } = useNodeFormContext();
|
||||
const { pending, setFiles } = useFileUploaderContext()!;
|
||||
const { pending, setFiles, uploadFiles } = useFileUploaderContext()!;
|
||||
|
||||
const images = useNodeImages(values);
|
||||
const audios = useNodeAudios(values);
|
||||
|
@ -35,10 +36,12 @@ const AudioEditor: FC<IProps> = () => {
|
|||
const setAudios = useCallback(values => setFiles([...values, ...images]), [setFiles, images]);
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<ImageGrid files={images} setFiles={setImages} locked={pendingImages} />
|
||||
<AudioGrid files={audios} setFiles={setAudios} locked={pendingAudios} />
|
||||
</div>
|
||||
<UploadDropzone onUpload={uploadFiles} helperClassName={styles.dropzone}>
|
||||
<div className={styles.wrap}>
|
||||
<ImageGrid files={images} setFiles={setImages} locked={pendingImages} />
|
||||
<AudioGrid files={audios} setFiles={setAudios} locked={pendingAudios} />
|
||||
</div>
|
||||
</UploadDropzone>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
pointer-events: none;
|
||||
touch-action: none;
|
||||
|
||||
& > * {
|
||||
margin: 0 $gap / 2;
|
||||
pointer-events: all;
|
||||
touch-action: auto;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = IEditorComponentProps & {};
|
||||
|
||||
const EditorFiller: FC<IProps> = () => <Filler />;
|
||||
const EditorFiller: FC<IProps> = () => <Filler className={styles.filler} />;
|
||||
|
||||
export { EditorFiller };
|
||||
|
|
4
src/components/editors/EditorFiller/styles.module.scss
Normal file
4
src/components/editors/EditorFiller/styles.module.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
.filler {
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
}
|
|
@ -1,22 +1,21 @@
|
|||
import React, { FC, useMemo, useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { INode, IFile } from '~/redux/types';
|
||||
import * as UPLOAD_ACTIONS from '~/redux/uploads/actions';
|
||||
import { selectUploads } from '~/redux/uploads/selectors';
|
||||
import React, { FC } from 'react';
|
||||
import { ImageGrid } from '~/components/editors/ImageGrid';
|
||||
import styles from './styles.module.scss';
|
||||
import { NodeEditorProps } from '~/redux/node/types';
|
||||
import { useFileUploaderContext } from '~/utils/hooks/useFileUploader';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
|
||||
type IProps = NodeEditorProps;
|
||||
|
||||
const ImageEditor: FC<IProps> = () => {
|
||||
const { pending, files, setFiles } = useFileUploaderContext()!;
|
||||
const { pending, files, setFiles, uploadFiles } = useFileUploaderContext()!;
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<ImageGrid files={files} setFiles={setFiles} locked={pending} />
|
||||
</div>
|
||||
<UploadDropzone onUpload={uploadFiles} helperClassName={styles.dropzone}>
|
||||
<div className={styles.wrap}>
|
||||
<ImageGrid files={files} setFiles={setFiles} locked={pending} />
|
||||
</div>
|
||||
</UploadDropzone>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
@import "src/styles/variables";
|
||||
@import 'src/styles/variables';
|
||||
|
||||
.wrap {
|
||||
min-height: 200px;
|
||||
padding-bottom: $upload_button_height + $gap;
|
||||
}
|
||||
|
||||
div.dropzone {
|
||||
}
|
||||
|
|
18
src/components/input/DropHereIcon/index.tsx
Normal file
18
src/components/input/DropHereIcon/index.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { SVGProps } from '~/utils/types';
|
||||
|
||||
interface Props extends SVGProps {}
|
||||
|
||||
const DropHereIcon: FC<Props> = ({ ...rest }) => (
|
||||
<svg viewBox="0 0 24 24" stroke="none" {...rest}>
|
||||
<path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z" />
|
||||
|
||||
<path
|
||||
d="M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"
|
||||
className={styles.arrow}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export { DropHereIcon };
|
8
src/components/input/DropHereIcon/styles.module.scss
Normal file
8
src/components/input/DropHereIcon/styles.module.scss
Normal file
|
@ -0,0 +1,8 @@
|
|||
@keyframes bounce {
|
||||
0% { transform: translate(0, -5%); }
|
||||
100% { transform: translate(0, 5%); }
|
||||
}
|
||||
|
||||
.arrow {
|
||||
animation: bounce alternate infinite 0.25s;
|
||||
}
|
48
src/components/upload/UploadDropzone/index.tsx
Normal file
48
src/components/upload/UploadDropzone/index.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import classnames from 'classnames';
|
||||
import classNames from 'classnames';
|
||||
import styles from './styles.module.scss';
|
||||
import { DivProps } from '~/utils/types';
|
||||
import { DropHereIcon } from '~/components/input/DropHereIcon';
|
||||
import { useDragDetector } from '~/utils/hooks/useDragDetector';
|
||||
|
||||
interface IProps extends DivProps {
|
||||
onUpload: (files: File[]) => void;
|
||||
helperClassName?: string;
|
||||
}
|
||||
|
||||
const UploadDropzone: FC<IProps> = ({ children, onUpload, helperClassName, ...rest }) => {
|
||||
const { isDragging: isDraggingOnBody, onStopDragging } = useDragDetector();
|
||||
const onDrop = useCallback(
|
||||
(files: File[]) => {
|
||||
onStopDragging();
|
||||
onUpload(files);
|
||||
},
|
||||
[onUpload]
|
||||
);
|
||||
|
||||
return (
|
||||
<Dropzone onDrop={onDrop}>
|
||||
{({ getRootProps, isDragActive }) => (
|
||||
<div
|
||||
{...getRootProps({
|
||||
...rest,
|
||||
className: classnames(styles.zone),
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
<div
|
||||
className={classNames(styles.helper, helperClassName, {
|
||||
[styles.active]: isDragActive || isDraggingOnBody,
|
||||
})}
|
||||
>
|
||||
<DropHereIcon className={styles.icon} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Dropzone>
|
||||
);
|
||||
};
|
||||
|
||||
export { UploadDropzone };
|
34
src/components/upload/UploadDropzone/styles.module.scss
Normal file
34
src/components/upload/UploadDropzone/styles.module.scss
Normal file
|
@ -0,0 +1,34 @@
|
|||
@import '~/styles/variables';
|
||||
|
||||
.zone {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.helper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: transparentize($wisegreen, 0.7);
|
||||
border-radius: $radius;
|
||||
z-index: 10;
|
||||
box-shadow: inset $wisegreen 0 0 0 2px;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
touch-action: none;
|
||||
|
||||
&.active, :global(.dragging) & {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
svg.icon {
|
||||
width: auto;
|
||||
height: 72px;
|
||||
fill: $wisegreen;
|
||||
}
|
|
@ -10,6 +10,7 @@ import { BlurWrapper } from '~/components/containers/BlurWrapper';
|
|||
import { PageCover } from '~/components/containers/PageCover';
|
||||
import { BottomContainer } from '~/containers/main/BottomContainer';
|
||||
import { MainRouter } from '~/containers/main/MainRouter';
|
||||
import { DragDetectorProvider } from '~/utils/hooks/useDragDetector';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
modal: selectModal(state),
|
||||
|
@ -21,7 +22,7 @@ type IProps = typeof mapDispatchToProps & ReturnType<typeof mapStateToProps> & {
|
|||
const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
||||
return (
|
||||
<ConnectedRouter history={history}>
|
||||
<div>
|
||||
<DragDetectorProvider>
|
||||
<BlurWrapper is_blurred={is_shown}>
|
||||
<PageCover />
|
||||
|
||||
|
@ -32,9 +33,8 @@ const Component: FC<IProps> = ({ modal: { is_shown } }) => {
|
|||
<MainRouter />
|
||||
</MainLayout>
|
||||
</BlurWrapper>
|
||||
|
||||
<BottomContainer />
|
||||
</div>
|
||||
</DragDetectorProvider>
|
||||
</ConnectedRouter>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ import { ModalWrapper } from '~/components/dialogs/ModalWrapper';
|
|||
import { useTranslatedError } from '~/utils/hooks/useTranslatedError';
|
||||
import { useCloseOnEscape } from '~/utils/hooks';
|
||||
import { EditorConfirmClose } from '~/components/editors/EditorConfirmClose';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
|
||||
interface Props extends IDialogProps {
|
||||
node: INode;
|
||||
|
|
|
@ -74,3 +74,5 @@ export const COMMENT_FILE_TYPES = [
|
|||
...FILE_MIMES[UPLOAD_TYPES.IMAGE],
|
||||
...FILE_MIMES[UPLOAD_TYPES.AUDIO],
|
||||
];
|
||||
|
||||
export const IMAGE_FILE_TYPES = [...FILE_MIMES[UPLOAD_TYPES.IMAGE]];
|
||||
|
|
|
@ -334,6 +334,14 @@ const Sprites: FC = () => (
|
|||
d="M409.132,114.573c-19.608-33.596-46.205-60.194-79.798-79.8C295.736,15.166,259.057,5.365,219.271,5.365 c-39.781,0-76.472,9.804-110.063,29.408c-33.596,19.605-60.192,46.204-79.8,79.8C9.803,148.168,0,184.854,0,224.63 c0,47.78,13.94,90.745,41.827,128.906c27.884,38.164,63.906,64.572,108.063,79.227c5.14,0.954,8.945,0.283,11.419-1.996 c2.475-2.282,3.711-5.14,3.711-8.562c0-0.571-0.049-5.708-0.144-15.417c-0.098-9.709-0.144-18.179-0.144-25.406l-6.567,1.136 c-4.187,0.767-9.469,1.092-15.846,1c-6.374-0.089-12.991-0.757-19.842-1.999c-6.854-1.231-13.229-4.086-19.13-8.559 c-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559 c-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-0.951-2.568-2.098-3.711-3.429c-1.142-1.331-1.997-2.663-2.568-3.997 c-0.572-1.335-0.098-2.43,1.427-3.289c1.525-0.859,4.281-1.276,8.28-1.276l5.708,0.853c3.807,0.763,8.516,3.042,14.133,6.851 c5.614,3.806,10.229,8.754,13.846,14.842c4.38,7.806,9.657,13.754,15.846,17.847c6.184,4.093,12.419,6.136,18.699,6.136 c6.28,0,11.704-0.476,16.274-1.423c4.565-0.952,8.848-2.383,12.847-4.285c1.713-12.758,6.377-22.559,13.988-29.41 c-10.848-1.14-20.601-2.857-29.264-5.14c-8.658-2.286-17.605-5.996-26.835-11.14c-9.235-5.137-16.896-11.516-22.985-19.126 c-6.09-7.614-11.088-17.61-14.987-29.979c-3.901-12.374-5.852-26.648-5.852-42.826c0-23.035,7.52-42.637,22.557-58.817 c-7.044-17.318-6.379-36.732,1.997-58.24c5.52-1.715,13.706-0.428,24.554,3.853c10.85,4.283,18.794,7.952,23.84,10.994 c5.046,3.041,9.089,5.618,12.135,7.708c17.705-4.947,35.976-7.421,54.818-7.421s37.117,2.474,54.823,7.421l10.849-6.849 c7.419-4.57,16.18-8.758,26.262-12.565c10.088-3.805,17.802-4.853,23.134-3.138c8.562,21.509,9.325,40.922,2.279,58.24 c15.036,16.18,22.559,35.787,22.559,58.817c0,16.178-1.958,30.497-5.853,42.966c-3.9,12.471-8.941,22.457-15.125,29.979 c-6.191,7.521-13.901,13.85-23.131,18.986c-9.232,5.14-18.182,8.85-26.84,11.136c-8.662,2.286-18.415,4.004-29.263,5.146 c9.894,8.562,14.842,22.077,14.842,40.539v60.237c0,3.422,1.19,6.279,3.572,8.562c2.379,2.279,6.136,2.95,11.276,1.995 c44.163-14.653,80.185-41.062,108.068-79.226c27.88-38.161,41.825-81.126,41.825-128.906 C438.536,184.851,428.728,148.168,409.132,114.573z"
|
||||
/>
|
||||
</g>
|
||||
|
||||
<g id="upload">
|
||||
<path fill="none" d="M0 0h24v24H0V0z" stroke="none" />
|
||||
<path
|
||||
stroke="none"
|
||||
d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview590"
|
||||
pagecolor="#332b39"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
|
@ -30,7 +30,7 @@
|
|||
borderlayer="true"
|
||||
inkscape:zoom="0.35723204"
|
||||
inkscape:cx="-284.12905"
|
||||
inkscape:cy="565.45879"
|
||||
inkscape:cy="565.4588"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
|
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
@ -39,10 +39,12 @@ export const useDelayedReady = (setReady: (val: boolean) => void, delay: number
|
|||
* @param onUpload -- upload callback
|
||||
* @param allowedTypes -- list of allowed types
|
||||
*/
|
||||
export const useDropZone = (onUpload: (file: File[]) => void, allowedTypes?: string[]) => {
|
||||
export const useFileDropZone = (onUpload: (file: File[]) => void, allowedTypes?: string[]) => {
|
||||
return useCallback(
|
||||
event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const files: File[] = Array.from((event.dataTransfer?.files as File[]) || []).filter(
|
||||
(file: File) => file?.type && (!allowedTypes || allowedTypes.includes(file.type))
|
||||
);
|
||||
|
|
50
src/utils/hooks/useDragDetector.tsx
Normal file
50
src/utils/hooks/useDragDetector.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import React, { FC, useContext } from 'react';
|
||||
import { createContext, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
const DragContext = createContext({
|
||||
isDragging: false,
|
||||
setIsDragging: (val: boolean) => {},
|
||||
});
|
||||
|
||||
export const DragDetectorProvider: FC = ({ children }) => {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
||||
return (
|
||||
<DragContext.Provider value={{ isDragging, setIsDragging }}>{children}</DragContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useDragDetector = () => {
|
||||
const { isDragging, setIsDragging } = useContext(DragContext);
|
||||
|
||||
const onStopDragging = useCallback(() => setIsDragging(false), [setIsDragging]);
|
||||
|
||||
useEffect(() => {
|
||||
const addClass = () => setIsDragging(true);
|
||||
|
||||
const removeClass = event => {
|
||||
// Small hack to ignore intersection with child elements
|
||||
if (event.pageX !== 0 && event.pageY !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDragging(false);
|
||||
};
|
||||
|
||||
document.addEventListener('dragenter', addClass);
|
||||
document.addEventListener('dragover', addClass);
|
||||
document.addEventListener('dragleave', removeClass);
|
||||
document.addEventListener('blur', removeClass);
|
||||
document.addEventListener('drop', onStopDragging);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('dragenter', addClass);
|
||||
document.removeEventListener('dragover', addClass);
|
||||
document.removeEventListener('dragleave', removeClass);
|
||||
document.removeEventListener('blur', removeClass);
|
||||
document.removeEventListener('drop', onStopDragging);
|
||||
};
|
||||
}, [setIsDragging]);
|
||||
|
||||
return { isDragging, onStopDragging };
|
||||
};
|
|
@ -4,3 +4,5 @@ export type DivProps = React.DetailedHTMLProps<
|
|||
React.HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
>;
|
||||
|
||||
export type SVGProps = React.SVGProps<SVGSVGElement>;
|
||||
|
|
31
yarn.lock
31
yarn.lock
|
@ -1805,6 +1805,11 @@
|
|||
dependencies:
|
||||
"@types/jest" "*"
|
||||
|
||||
"@types/throttle-debounce@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776"
|
||||
integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "15.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
|
||||
|
@ -2410,6 +2415,11 @@ atob@^2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
attr-accept@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
|
||||
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
|
||||
|
||||
autoprefixer@^9.6.1:
|
||||
version "9.8.6"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
|
||||
|
@ -4885,6 +4895,13 @@ file-loader@4.3.0:
|
|||
loader-utils "^1.2.3"
|
||||
schema-utils "^2.5.0"
|
||||
|
||||
file-selector@^0.2.2:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.2.4.tgz#7b98286f9dbb9925f420130ea5ed0a69238d4d80"
|
||||
integrity sha512-ZDsQNbrv6qRi1YTDOEWzf5J2KjZ9KMI1Q2SGeTkCJmNNW25Jg4TW4UMcmoqcg4WrAyKRcpBXdbWRxkfrOzVRbA==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
|
@ -9361,6 +9378,15 @@ react-dom@^17.0.1:
|
|||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.1"
|
||||
|
||||
react-dropzone@^11.4.2:
|
||||
version "11.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-11.4.2.tgz#1eb99e9def4cc7520f4f58e85c853ce52c483d56"
|
||||
integrity sha512-ocYzYn7Qgp0tFc1gQtUTOaHHSzVTwhWHxxY+r7cj2jJTPfMTZB5GWSJHdIVoxsl+EQENpjJ/6Zvcw0BqKZQ+Eg==
|
||||
dependencies:
|
||||
attr-accept "^2.2.1"
|
||||
file-selector "^0.2.2"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-error-overlay@^6.0.7:
|
||||
version "6.0.8"
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de"
|
||||
|
@ -11137,6 +11163,11 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.3:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue