Skip to content

Commit

Permalink
feat: new FileUpload component (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
Swappea authored Nov 3, 2024
1 parent e57dd03 commit 9abd5d0
Show file tree
Hide file tree
Showing 24 changed files with 1,739 additions and 0 deletions.
114 changes: 114 additions & 0 deletions apps/docs/src/examples/file-upload.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.fileUpload {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
min-height: 300px;
row-gap: 5px;
}

.fileUpload__label {
color: white;
font-size: 14px;
font-weight: 500;
user-select: none;
}

.fileUpload__dropzone {
padding: 20px;
display: flex;
flex-direction: column;
row-gap: 10px;
align-items: center;
justify-content: center;
border: 1px dashed rgb(42, 42, 40);
width: 100%;
min-height: 200px;
color: #ccc;
border-radius: 6px;
}

.fileUpload__trigger {
background-color: hsl(201 96% 32%);
color: white;
padding: 5px 10px;
border-radius: 4px;
}

.fileUpload__itemGroup {
display: flex;
flex-direction: column;
gap: 3px;
width: 100%;
}

.fileUpload__item {
width: 100%;
display: grid;
padding: 16px;
column-gap: 10px;
border-radius: 6px;
grid-template-columns: auto 1fr auto;
grid-template-areas:
"preview name delete"
"preview size delete";
column-gap: 5px;
border: 1px solid rgb(42, 42, 40);
padding: 10px;
}

.fileUpload__itemPreview {
grid-area: preview;
}

.fileUpload__itemPreviewImage {
width: 50px;
object-fit: scale-down;
height: auto;
aspect-ratio: 1;
}

.fileUpload__itemName {
grid-area: name;
font-size: 14px;
color: #fff;
}

.fileUpload__itemSize {
grid-area: size;
font-size: 14px;
color: rgb(181, 179, 173);
}

.fileUpload__itemDeleteTrigger {
grid-area: delete;
cursor: pointer;
background-color: #a23434;
color: white;
padding: 2px 8px;
border-radius: 4px;
height: max-content;
align-self: center;
}

.formContainer {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
row-gap: 5px;
}

.formContainer > .fileUpload__dropzone {
min-height: 200px;
}

.submit-btn {
background-color: hsl(201 96% 32%);
color: white;
padding: 5px 10px;
border-radius: 4px;
align-self: flex-end;
}
131 changes: 131 additions & 0 deletions apps/docs/src/examples/file-upload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { FileUpload } from "@kobalte/core/file-upload";
import { For } from "solid-js";

import style from "./file-upload.module.css";

export function BasicExample() {
return (
<FileUpload
class={style.fileUpload}
multiple
maxFiles={5}
onFileAccept={(data) => console.log("data", data)}
onFileReject={(data) => console.log("data", data)}
onFileChange={(data) => console.log("data", data)}
>
<FileUpload.Label class={style.fileUpload__label}>
File Upload
</FileUpload.Label>
<FileUpload.DropZone class={style.fileUpload__dropzone}>
Drop your files here...
<FileUpload.Trigger class={style.fileUpload__trigger}>
Choose files!
</FileUpload.Trigger>
</FileUpload.DropZone>
<FileUpload.HiddenInput />
<FileUpload.ItemGroup class={style.fileUpload__itemGroup}>
<FileUpload.Context>
{(context) => {
return (
<For each={context.acceptedFiles}>
{(file) => (
<FileUpload.Item file={file} class={style.fileUpload__item}>
<FileUpload.ItemPreview
type="image/*"
class={style.fileUpload__itemPreview}
>
<FileUpload.ItemPreviewImage
class={style.fileUpload__itemPreviewImage}
/>
</FileUpload.ItemPreview>
<FileUpload.ItemName class={style.fileUpload__itemName} />
<FileUpload.ItemSize class={style.fileUpload__itemSize} />
<FileUpload.ItemDeleteTrigger
class={style.fileUpload__itemDeleteTrigger}
>
Delete
</FileUpload.ItemDeleteTrigger>
</FileUpload.Item>
)}
</For>
);
}}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
);
}

export function HTMLFormExample() {
let formRef: HTMLFormElement | undefined;

const onSubmit = (event: SubmitEvent) => {
event.preventDefault();
event.stopPropagation();

const formData = new FormData(formRef);
const uploadedFiles = formData.getAll("uploaded-files");

const fileNames = uploadedFiles
.filter((file): file is File => file instanceof File)
.map((file) => file.name);

alert(JSON.stringify(fileNames, null, 2));
};

return (
<form class={style.formContainer} ref={formRef} onSubmit={onSubmit}>
<FileUpload
class={style.fileUpload}
multiple
maxFiles={5}
onFileAccept={(data) => console.log("data", data)}
onFileReject={(data) => console.log("data", data)}
onFileChange={(data) => console.log("data", data)}
>
<FileUpload.Label class={style.fileUpload__label}>
File Upload
</FileUpload.Label>
<FileUpload.DropZone class={style.fileUpload__dropzone}>
Drop your files here...
<FileUpload.Trigger class={style.fileUpload__trigger}>
Choose files!
</FileUpload.Trigger>
</FileUpload.DropZone>
<FileUpload.HiddenInput name="uploaded-files" />
<FileUpload.ItemGroup class={style.fileUpload__itemGroup}>
<FileUpload.Context>
{(context) => {
return (
<For each={context.acceptedFiles}>
{(file) => (
<FileUpload.Item file={file} class={style.fileUpload__item}>
<FileUpload.ItemPreview
type="image/*"
class={style.fileUpload__itemPreview}
>
<FileUpload.ItemPreviewImage
class={style.fileUpload__itemPreviewImage}
/>
</FileUpload.ItemPreview>
<FileUpload.ItemName class={style.fileUpload__itemName} />
<FileUpload.ItemSize class={style.fileUpload__itemSize} />
<FileUpload.ItemDeleteTrigger
class={style.fileUpload__itemDeleteTrigger}
>
Delete
</FileUpload.ItemDeleteTrigger>
</FileUpload.Item>
)}
</For>
);
}}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
<button type="submit" class={style["submit-btn"]}>
Submit Files
</button>
</form>
);
}
4 changes: 4 additions & 0 deletions apps/docs/src/routes/docs/core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ const CORE_NAV_SECTIONS: NavSection[] = [
title: "Dropdown Menu",
href: "/docs/core/components/dropdown-menu",
},
{
title: "File Upload",
href: "/docs/core/components/file-upload",
},
{
title: "Hover Card",
href: "/docs/core/components/hover-card",
Expand Down
Loading

0 comments on commit 9abd5d0

Please sign in to comment.