diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a6e6b51..6864a9b73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Not released +- Design changes in UploadField component [#548](https://github.com/CartoDB/carto-react/pull/548/) - Divider component adapted to the new design system [#546](https://github.com/CartoDB/carto-react/pull/546/) - UploadField component created for the new design system [#545](https://github.com/CartoDB/carto-react/pull/545/) - Select component adapted to the new design system [#544](https://github.com/CartoDB/carto-react/pull/544/) diff --git a/packages/react-ui/src/components/molecules/UploadField.js b/packages/react-ui/src/components/molecules/UploadField.js index 8ac448d6d..eeb3f3cbf 100644 --- a/packages/react-ui/src/components/molecules/UploadField.js +++ b/packages/react-ui/src/components/molecules/UploadField.js @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import { Button, IconButton, InputAdornment, TextField } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; @@ -8,6 +8,7 @@ const useStyles = makeStyles((theme) => ({ uploadField: { '& .MuiInputBase-root': { cursor: 'pointer', + paddingRight: theme.spacing(1), '& input': { cursor: 'pointer' @@ -47,7 +48,7 @@ const useStyles = makeStyles((theme) => ({ } })); -function UploadField(props) { +function UploadField({ buttonText, accept, files, ...props }) { const classes = useStyles(); const uploadInputRef = useRef(null); const textFieldRef = useRef(null); @@ -55,15 +56,17 @@ function UploadField(props) { const [filesText, setFilesText] = useState(''); const [dragOver, setDragOver] = useState(false); + const isSmall = props.size === 'small'; + useEffect(() => { - if (props.files.length === 0) { + if (files.length === 0) { setFilesText(''); - } else if (props.files.length === 1) { - setFilesText(props.files[0].name); + } else if (files.length === 1) { + setFilesText(files[0].name); } else { - setFilesText(`${props.files.length} files selected`); + setFilesText(`${files.length} files selected`); } - }, [props.files]); + }, [files]); const handleBrowse = () => { uploadInputRef.current?.click(); @@ -111,14 +114,26 @@ function UploadField(props) { setFilesText(''); }; - const dragPlaceholderText = dragOver ? props.dragPlaceholder : props.placeholder; + const getPlaceholder = useMemo(() => { + const multipleSuffix = props.multiple ? '(s)' : ''; + const defaultPlaceholder = `Drag and drop your file${multipleSuffix} or click to browse`; + const dragPlaceholder = `Drop your file${multipleSuffix} here...`; + + let placeholderText; + if (dragOver) { + placeholderText = dragPlaceholder; + } else { + placeholderText = props.placeholder || defaultPlaceholder; + } + return placeholderText; + }, [dragOver, props.multiple, props.placeholder]); return ( <> {!filesText ? ( ) : ( @@ -158,7 +173,7 @@ function UploadField(props) { ref={uploadInputRef} style={{ display: 'none' }} type='file' - accept={props.accept} + accept={accept} multiple={props.multiple} onChange={handleFiles} /> @@ -167,25 +182,21 @@ function UploadField(props) { } UploadField.defaultProps = { - placeholder: 'Drag and drop your file or click to browse', - dragPlaceholder: 'Drop your file here...', buttonText: 'Browse', accept: ['application/JSON'], - multiple: false, - error: false, files: [], onChange: (files) => files }; UploadField.propTypes = { placeholder: PropTypes.string, - dragPlaceholder: PropTypes.string, buttonText: PropTypes.string, accept: PropTypes.array, multiple: PropTypes.bool, error: PropTypes.bool, files: PropTypes.array, - onChange: PropTypes.func.isRequired + onChange: PropTypes.func.isRequired, + size: PropTypes.oneOf(['small', 'medium']) }; export default UploadField; diff --git a/packages/react-ui/src/types.d.ts b/packages/react-ui/src/types.d.ts index a3cd55f38..a6c59c80b 100644 --- a/packages/react-ui/src/types.d.ts +++ b/packages/react-ui/src/types.d.ts @@ -225,13 +225,10 @@ export interface SelectFieldProps extends TextFieldProps { size?: 'small' | 'medium'; } +// UploadField export interface UploadFieldProps extends TextFieldProps { - placeholder?: string; - dragPlaceholder?: string; buttonText?: string; accept?: string[]; - multiple?: boolean; - error?: boolean; files?: []; onChange: (file?: File | null) => void; } diff --git a/packages/react-ui/storybook/stories/atoms/Divider.stories.js b/packages/react-ui/storybook/stories/atoms/Divider.stories.js index 9e6fa8c1c..cb8744bf1 100644 --- a/packages/react-ui/storybook/stories/atoms/Divider.stories.js +++ b/packages/react-ui/storybook/stories/atoms/Divider.stories.js @@ -18,7 +18,7 @@ const options = { url: 'https://www.figma.com/file/nmaoLeo69xBJCHm9nc6lEV/CARTO-Components-1.0?node-id=1534%3A28897' }, status: { - type: 'readyToReview' + type: 'validated' } } }; diff --git a/packages/react-ui/storybook/stories/atoms/SelectField.stories.js b/packages/react-ui/storybook/stories/atoms/SelectField.stories.js index 396b90951..850063763 100644 --- a/packages/react-ui/storybook/stories/atoms/SelectField.stories.js +++ b/packages/react-ui/storybook/stories/atoms/SelectField.stories.js @@ -55,7 +55,7 @@ const options = { url: 'https://www.figma.com/file/nmaoLeo69xBJCHm9nc6lEV/CARTO-Components-1.0?node-id=1534%3A29965' }, status: { - type: 'readyToReview' + type: 'validated' } } }; diff --git a/packages/react-ui/storybook/stories/molecules/UploadField.stories.js b/packages/react-ui/storybook/stories/molecules/UploadField.stories.js index 068daf31d..4de33d7f0 100644 --- a/packages/react-ui/storybook/stories/molecules/UploadField.stories.js +++ b/packages/react-ui/storybook/stories/molecules/UploadField.stories.js @@ -48,11 +48,6 @@ const options = { type: 'text' } }, - dragPlaceholder: { - control: { - type: 'text' - } - }, buttonText: { control: { type: 'text' @@ -114,7 +109,7 @@ const Template = ({ ...args }) => { return ; }; -const VariantsTemplate = ({ label, required, placeholder, dragPlaceholder, ...rest }) => { +const VariantsTemplate = ({ label, required, placeholder, ...rest }) => { const classes = useStyles(); const [files, setFiles] = useState([]); const [files2, setFiles2] = useState([]); @@ -138,7 +133,6 @@ const VariantsTemplate = ({ label, required, placeholder, dragPlaceholder, ...re files={files} label={label} placeholder={placeholder} - dragPlaceholder={dragPlaceholder} onChange={handleUploadFieldChange} /> @@ -154,7 +148,6 @@ const VariantsTemplate = ({ label, required, placeholder, dragPlaceholder, ...re files={files2} label={label} placeholder={placeholder} - dragPlaceholder={dragPlaceholder} onChange={handleUploadFieldChange2} /> @@ -443,10 +436,7 @@ const BehaviorTemplate = ({ label, placeholder, defaultValue, helperText, ...res const commonArgs = { label: 'Label text', - placeholder: 'Drag and drop your file or click to browse', - dragPlaceholder: 'Drop your file here...', helperText: 'Upload a CSV or GeoJSON file, or a zip package with your Shapefile', - buttonText: 'Browse', accept: ['application/JSON', 'image/*'] }; const sizeArgs = {