chore: upload dropzone style changes (#7932)
This commit is contained in:
@@ -133,19 +133,31 @@ export const DefaultListView: React.FC = () => {
|
||||
{Header || (
|
||||
<ListHeader heading={getTranslation(labels?.plural, i18n)}>
|
||||
{hasCreatePermission && (
|
||||
<Button
|
||||
Link={!isBulkUploadEnabled ? Link : undefined}
|
||||
aria-label={i18n.t('general:createNewLabel', {
|
||||
label: getTranslation(labels?.singular, i18n),
|
||||
})}
|
||||
buttonStyle="pill"
|
||||
el={!isBulkUploadEnabled ? 'link' : 'button'}
|
||||
onClick={isBulkUploadEnabled ? openBulkUpload : undefined}
|
||||
size="small"
|
||||
to={!isBulkUploadEnabled ? newDocumentURL : undefined}
|
||||
>
|
||||
{i18n.t('general:createNew')}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
Link={Link}
|
||||
aria-label={i18n.t('general:createNewLabel', {
|
||||
label: getTranslation(labels?.singular, i18n),
|
||||
})}
|
||||
buttonStyle="pill"
|
||||
el={'link'}
|
||||
size="small"
|
||||
to={newDocumentURL}
|
||||
>
|
||||
{i18n.t('general:createNew')}
|
||||
</Button>
|
||||
|
||||
{isBulkUploadEnabled && (
|
||||
<Button
|
||||
aria-label={t('upload:bulkUpload')}
|
||||
buttonStyle="pill"
|
||||
onClick={openBulkUpload}
|
||||
size="small"
|
||||
>
|
||||
{t('upload:bulkUpload')}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{!smallBreak && (
|
||||
<ListSelection label={getTranslation(collectionConfig.labels.plural, i18n)} />
|
||||
|
||||
@@ -40,6 +40,7 @@ export function AddFilesView({ onCancel, onDrop }: Props) {
|
||||
aria-hidden="true"
|
||||
className={`${baseClass}__hidden-input`}
|
||||
hidden
|
||||
multiple
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
onDrop(e.target.files)
|
||||
@@ -53,7 +54,6 @@ export function AddFilesView({ onCancel, onDrop }: Props) {
|
||||
{t('general:or')} {t('upload:dragAndDrop')}
|
||||
</p>
|
||||
</Dropzone>
|
||||
{/* <Dropzone multipleFiles onChange={onDrop} /> */}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: calc(var(--base) * .9) calc(var(--base) / 2);
|
||||
padding: calc(var(--base) * .9) var(--base);
|
||||
background: transparent;
|
||||
border: 1px dotted var(--theme-elevation-400);
|
||||
border-radius: var(--style-radius-s);
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
.file {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
margin: base(-0.25) 0;
|
||||
|
||||
&__thumbnail {
|
||||
display: inline-block;
|
||||
max-width: base(3);
|
||||
height: base(3);
|
||||
max-width: calc(var(--base) * 2);
|
||||
height: calc(var(--base) * 2);
|
||||
border-radius: var(--style-radius-s);
|
||||
}
|
||||
|
||||
&__filename {
|
||||
align-self: center;
|
||||
[dir='ltr'] & {
|
||||
margin-left: base(1);
|
||||
margin-left: var(--base);
|
||||
}
|
||||
[dir='rtl'] & {
|
||||
margin-right: base(1);
|
||||
margin-right: var(--base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: var(--style-radius-s) 0 0 var(--style-radius-s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +86,30 @@
|
||||
|
||||
.dropzone {
|
||||
background-color: transparent;
|
||||
padding-block: calc(var(--base) * 2.25);
|
||||
}
|
||||
|
||||
&__dropzoneContent {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__dropzoneButtons {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
gap: calc(var(--base) * .5);
|
||||
}
|
||||
|
||||
&__orText {
|
||||
color: var(--theme-elevation-500);
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
&__dragAndDropText {
|
||||
margin: 0;
|
||||
text-transform: lowercase;
|
||||
align-self: center;
|
||||
color: var(--theme-elevation-500);
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
@@ -123,4 +143,10 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include small-break {
|
||||
&__dropzoneContent {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,43 +235,46 @@ export const Upload: React.FC<UploadProps> = (props) => {
|
||||
<div className={`${baseClass}__upload`}>
|
||||
{!value && !showUrlInput && (
|
||||
<Dropzone onChange={handleFileSelection}>
|
||||
<div className={`${baseClass}__dropzoneButtons`}>
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
icon="plus"
|
||||
iconPosition="left"
|
||||
onClick={() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.click()
|
||||
}
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
{t('upload:selectFile')}
|
||||
</Button>
|
||||
<input
|
||||
aria-hidden="true"
|
||||
className={`${baseClass}__hidden-input`}
|
||||
hidden
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
handleFileSelection(e.target.files)
|
||||
}
|
||||
}}
|
||||
ref={inputRef}
|
||||
type="file"
|
||||
/>
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
icon="link"
|
||||
iconPosition="left"
|
||||
onClick={() => {
|
||||
setShowUrlInput(true)
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
{t('upload:pasteURL')}
|
||||
</Button>
|
||||
<div className={`${baseClass}__dropzoneContent`}>
|
||||
<div className={`${baseClass}__dropzoneButtons`}>
|
||||
<Button
|
||||
buttonStyle="pill"
|
||||
onClick={() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.click()
|
||||
}
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
{t('upload:selectFile')}
|
||||
</Button>
|
||||
<input
|
||||
aria-hidden="true"
|
||||
className={`${baseClass}__hidden-input`}
|
||||
hidden
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
handleFileSelection(e.target.files)
|
||||
}
|
||||
}}
|
||||
ref={inputRef}
|
||||
type="file"
|
||||
/>
|
||||
<span className={`${baseClass}__orText`}>{t('general:or')}</span>
|
||||
<Button
|
||||
buttonStyle="pill"
|
||||
onClick={() => {
|
||||
setShowUrlInput(true)
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
{t('upload:pasteURL')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<p className={`${baseClass}__dragAndDropText`}>
|
||||
{t('general:or')} {t('upload:dragAndDrop')}
|
||||
</p>
|
||||
</div>
|
||||
</Dropzone>
|
||||
)}
|
||||
|
||||
@@ -25,9 +25,11 @@ import type { ListDrawerProps } from '../../elements/ListDrawer/types.js'
|
||||
|
||||
import { useBulkUpload } from '../../elements/BulkUpload/index.js'
|
||||
import { Button } from '../../elements/Button/index.js'
|
||||
import { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js'
|
||||
import { Dropzone } from '../../elements/Dropzone/index.js'
|
||||
import { useListDrawer } from '../../elements/ListDrawer/index.js'
|
||||
import { ShimmerEffect } from '../../elements/ShimmerEffect/index.js'
|
||||
import { PlusIcon } from '../../icons/Plus/index.js'
|
||||
import { useAuth } from '../../providers/Auth/index.js'
|
||||
import { useLocale } from '../../providers/Locale/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -143,8 +145,14 @@ export function UploadInput(props: UploadInputProps) {
|
||||
collectionSlugs: typeof relationTo === 'string' ? [relationTo] : relationTo,
|
||||
filterOptions,
|
||||
})
|
||||
const [
|
||||
CreateDocDrawer,
|
||||
_,
|
||||
{ closeDrawer: closeCreateDocDrawer, openDrawer: openCreateDocDrawer },
|
||||
] = useDocumentDrawer({
|
||||
collectionSlug: activeRelationTo,
|
||||
})
|
||||
|
||||
const inputRef = React.useRef<HTMLInputElement>(null)
|
||||
const loadedValueDocsRef = React.useRef<boolean>(false)
|
||||
|
||||
const canCreate = useMemo(() => {
|
||||
@@ -242,7 +250,7 @@ export function UploadInput(props: UploadInputProps) {
|
||||
[value, onChange, activeRelationTo, hasMany],
|
||||
)
|
||||
|
||||
const onFileSelection = React.useCallback(
|
||||
const onLocalFileSelection = React.useCallback(
|
||||
(fileList?: FileList) => {
|
||||
let fileListToUse = fileList
|
||||
if (!hasMany && fileList && fileList.length > 1) {
|
||||
@@ -295,6 +303,24 @@ export function UploadInput(props: UploadInputProps) {
|
||||
[activeRelationTo, closeListDrawer, onChange, populateDocs, value],
|
||||
)
|
||||
|
||||
const onDocCreate = React.useCallback(
|
||||
(data) => {
|
||||
if (data.doc) {
|
||||
setPopulatedDocs((currentDocs) => [
|
||||
...(currentDocs || []),
|
||||
{
|
||||
relationTo: activeRelationTo,
|
||||
value: data.doc,
|
||||
},
|
||||
])
|
||||
|
||||
onChange(data.doc.id)
|
||||
}
|
||||
closeCreateDocDrawer()
|
||||
},
|
||||
[closeCreateDocDrawer, activeRelationTo, onChange],
|
||||
)
|
||||
|
||||
const onListSelect = React.useCallback<NonNullable<ListDrawerProps['onSelect']>>(
|
||||
async ({ collectionSlug, docID }) => {
|
||||
const loadedDocs = await populateDocs([docID], collectionSlug)
|
||||
@@ -445,20 +471,18 @@ export function UploadInput(props: UploadInputProps) {
|
||||
) : null}
|
||||
|
||||
{showDropzone ? (
|
||||
<Dropzone multipleFiles={hasMany} onChange={onFileSelection}>
|
||||
<Dropzone multipleFiles={hasMany} onChange={onLocalFileSelection}>
|
||||
<div className={`${baseClass}__dropzoneContent`}>
|
||||
<div className={`${baseClass}__dropzoneContent__buttons`}>
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
buttonStyle="pill"
|
||||
disabled={readOnly || !canCreate}
|
||||
icon="plus"
|
||||
iconPosition="left"
|
||||
onClick={() => {
|
||||
if (!readOnly) {
|
||||
if (hasMany) {
|
||||
onFileSelection()
|
||||
} else if (inputRef.current) {
|
||||
inputRef.current.click()
|
||||
onLocalFileSelection()
|
||||
} else {
|
||||
openCreateDocDrawer()
|
||||
}
|
||||
}
|
||||
}}
|
||||
@@ -466,25 +490,14 @@ export function UploadInput(props: UploadInputProps) {
|
||||
>
|
||||
{t('general:createNew')}
|
||||
</Button>
|
||||
<input
|
||||
aria-hidden="true"
|
||||
className={`${baseClass}__hidden-input`}
|
||||
disabled={readOnly}
|
||||
hidden
|
||||
multiple={hasMany}
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
onFileSelection(e.target.files)
|
||||
}
|
||||
}}
|
||||
ref={inputRef}
|
||||
type="file"
|
||||
/>
|
||||
<span className={`${baseClass}__dropzoneContent__orText`}>{t('general:or')}</span>
|
||||
<ListDrawerToggler className={`${baseClass}__toggler`} disabled={readOnly}>
|
||||
<Button buttonStyle="icon-label" el="span" icon="plus" iconPosition="left">
|
||||
<Button buttonStyle="pill" el="span" size="small">
|
||||
{t('fields:chooseFromExisting')}
|
||||
</Button>
|
||||
</ListDrawerToggler>
|
||||
|
||||
<CreateDocDrawer onSave={onDocCreate} />
|
||||
<ListDrawer
|
||||
enableRowSelections={hasMany}
|
||||
onBulkSelect={onListBulkSelect}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
@import '../../scss/styles.scss';
|
||||
|
||||
.upload {
|
||||
.dropzone {
|
||||
padding-right: var(--base);
|
||||
}
|
||||
|
||||
&__dropzoneAndUpload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -19,7 +15,7 @@
|
||||
|
||||
&__dropzoneContent__buttons {
|
||||
display: flex;
|
||||
gap: var(--base);
|
||||
gap: calc(var(--base) / 2);
|
||||
position: relative;
|
||||
left: -2px;
|
||||
|
||||
@@ -31,11 +27,17 @@
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
|
||||
&__dropzoneContent__orText {
|
||||
color: var(--theme-elevation-500);
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
&__dragAndDropText {
|
||||
margin: 0;
|
||||
text-transform: lowercase;
|
||||
align-self: center;
|
||||
color: var(--theme-elevation-500);
|
||||
}
|
||||
|
||||
&__loadingRows {
|
||||
|
||||
Reference in New Issue
Block a user