Browse Source

Update multiple file uploads

Implement view for multiple file uploads.
master
TheoryOfNekomata 1 year ago
parent
commit
5c73e15044
3 changed files with 64 additions and 34 deletions
  1. +5
    -0
      categories/blob/react/.eslintrc
  2. +45
    -34
      categories/blob/react/src/components/FileSelectBox/index.tsx
  3. +14
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/blob/index.tsx

+ 5
- 0
categories/blob/react/.eslintrc View File

@@ -1,5 +1,10 @@
{
"root": true,
"rules": {
"quote-props": "off",
"react/jsx-props-no-spreading": "off",
"import/no-extraneous-dependencies": "off"
},
"extends": [
"lxsmnsyc/typescript/react"
],


+ 45
- 34
categories/blob/react/src/components/FileSelectBox/index.tsx View File

@@ -227,7 +227,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
};

const handleReselectMouseDown: React.MouseEventHandler<
HTMLLabelElement
HTMLButtonElement
> = React.useCallback(() => {
setAboutToSelect(true);
setTimeout(() => {
@@ -236,6 +236,13 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
});
}, [defaultRef]);

const handleReselectMouseUp: React.MouseEventHandler<
HTMLButtonElement
> = React.useCallback(() => {
const fileInput = defaultRef.current as FileSelectBoxDerivedElement;
fileInput.showPicker();
}, [defaultRef]);

const handleDeleteMouseDown: React.MouseEventHandler<
HTMLButtonElement
> = React.useCallback(() => {
@@ -256,7 +263,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
return () => {
window.removeEventListener('mouseup', handleLabelMouseUp, { capture: true });
};
}, []);
}, [defaultRef, aboutToSelect]);

return (
<div
@@ -266,7 +273,6 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
block && 'flex w-full',
!block && 'inline-flex w-64 min-h-16 justify-center items-center',
className,
clientSide && 'resize-y',
)}
onDragEnter={clientSide ? cancelEvent : undefined}
onDragOver={clientSide ? cancelEvent : undefined}
@@ -280,18 +286,37 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
...(style ?? {}),
}}
>
{clientSide && (
{label && (
<label
data-testid="label"
id={labelId}
htmlFor={id}
className={clsx(
'absolute z-[1] w-full top-0.5 left-0 pointer-events-none select-none pl-1 text-xxs font-bold peer-disabled:opacity-50 group-focus-within:text-secondary text-primary leading-none bg-negative',
{
'sr-only': hiddenLabel,
},
)}
>
<div className="w-full whitespace-nowrap h-[1.1em] overflow-hidden text-ellipsis">
{label}
</div>
</label>
)}
{clientSide && (
<button
type="button"
disabled={disabled}
className={clsx(
'flex items-center justify-center absolute top-0 left-0 w-full h-full cursor-pointer',
'flex items-center justify-center absolute top-0 left-0 w-full h-full cursor-pointer select-none',
(fileList?.length ?? 0) > 0 && 'opacity-0',
)}
data-testid="clickArea"
htmlFor={id}
onMouseDown={handleReselectMouseDown}
onMouseUp={handleReselectMouseUp}
>
{placeholder}
</label>
</button>
)}
<input
{...etcProps}
@@ -316,22 +341,6 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
height: clientSide ? undefined : 256,
}}
/>
{label && (
<div
data-testid="label"
id={labelId}
className={clsx(
'absolute z-[1] w-full top-0.5 left-0 pointer-events-none pl-1 text-xxs font-bold peer-disabled:opacity-50 group-focus-within:text-secondary text-primary leading-none bg-negative',
{
'sr-only': hiddenLabel,
},
)}
>
<div className="w-full whitespace-nowrap h-[1.1em] overflow-hidden text-ellipsis">
{label}
</div>
</div>
)}
{filesCount < 1
&& clientSide
&& hint
@@ -355,13 +364,13 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
>
{multiple
&& (
<div className="w-full h-full overflow-auto -mx-4 px-4">
<div className="w-full grid gap-4 grid-cols-3">
{Array.from(fileList ?? []).map((file, i) => (
<div className="w-full h-full overflow-auto">
<div className="w-full grid gap-2 grid-cols-3">
{Array.from(fileList ?? []).map((file) => (
<div
key={`${file.name}:${i}`}
key={file.name}
data-testid="selectedFileItem"
className="w-full aspect-square rounded overflow-hidden relative before:absolute before:content-[''] before:bg-current before:top-0 before:left-0 before:w-full before:h-full before:opacity-10"
className="w-full p-2 aspect-square rounded overflow-hidden relative before:absolute before:content-[''] before:bg-current before:top-0 before:left-0 before:w-full before:h-full before:opacity-10"
>
<FilePreviewComponent
file={file}
@@ -375,9 +384,9 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
</div>
)}
{!multiple
&& Array.from(fileList ?? []).map((file, i) => (
&& Array.from(fileList ?? []).map((file) => (
<div
key={`${file.name}:${i}`}
key={file.name}
className="w-full h-full"
>
<div
@@ -400,10 +409,12 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
</div>
<div className="absolute bottom-0 left-0 w-full text-center h-12 box-border flex">
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<label
<button
type="button"
data-testid="reselect"
htmlFor={id}
disabled={disabled}
onMouseDown={handleReselectMouseDown}
onMouseUp={handleReselectMouseUp}
className={clsx(
'flex w-full h-full bg-negative text-primary cursor-pointer items-center justify-center leading-none gap-4 select-none',
{
@@ -417,7 +428,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
>
Reselect
</span>
</label>
</button>
</div>
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<button
@@ -471,7 +482,7 @@ FileSelectBox.defaultProps = {

FileSelectBoxDefaultPreviewComponent.defaultProps = {
file: undefined,
mini: false,
mini: false as const,
disabled: FileSelectBox.defaultProps.disabled,
enhanced: FileSelectBox.defaultProps.enhanced,
};

+ 14
- 0
showcases/web-kitchensink-reactnext/src/pages/categories/blob/index.tsx View File

@@ -30,6 +30,20 @@ const BlobPage: NextPage = () => {
onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.files)}}
/>
</Subsection>
<Subsection title="Multiple">
<TesseractBlob.FileSelectBox
label="File"
name="file"
border
enhanced
placeholder="Select a file"
multiple
style={{
height: 256,
}}
onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.files)}}
/>
</Subsection>
</Section>
</DefaultLayout>
)


Loading…
Cancel
Save