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