File Upload
Full-stack React file upload components
Slingshot is a full-stack file upload component with support for drag-and-drop, progress bars, and more. Fully composable and compatible with any styling library.
Upload files fast and securely to any S3-compatible storage with a simple API that runs on any Javascript server runtime.
Example (Next.js)
import { FileUpload } from '@/components/file-upload'
export default function Page() {
return (
<FileUpload
profile="avatar"
maxFiles={1}
baseUrl="/api/slingshot"
uploadOnAccept
meta={{ userId: '123' }}
/>
)
}import { FileUpload as FileUploadPrimitive } from '@saas-js/slingshot-react'
import { Button } from '@/components/button'
import { Progress } from '@/components/progress'
export const FileUpload = (props: Omit<FileUpload.RootProps, 'children'>) => {
return (
<FileUploadPrimitive.Root {...props}>
<FileUploadPrimitive.Context>
{(api) => {
const files = api.slingshot.getFiles()
return (
<>
<FileUploadPrimitive.Dropzone>
<FileUploadPrimitive.Label>
Drag your file(s) here
</FileUploadPrimitive.Label>
<FileUploadPrimitive.Trigger asChild>
<Button>Choose file(s)</Button>
</FileUploadPrimitive.Trigger>
</FileUploadPrimitive.Dropzone>
<FileUploadPrimitive.ItemGroup>
{files.map((file) => {
return (
<FileUploadPrimitive.Item
key={file.name}
file={file.data}
>
<FileUploadPrimitive.ItemPreview type="image/*">
<FileUploadPrimitive.ItemPreviewImage />
</FileUploadPrimitive.ItemPreview>
<FileUploadPrimitive.ItemName />
<FileUploadPrimitive.ItemSizeText />
<div>
{file.progress &&
file.status !== 'done' && (
<Progress
value={file.progress}
type="circular"
colorPalette="green"
/>
)}
{file.status === 'done' ? 'Done' : null}
</div>
<FileUploadPrimitive.ItemDeleteTrigger>
✕
</FileUploadPrimitive.ItemDeleteTrigger>
</FileUploadPrimitive.Item>
)
})}
</FileUploadPrimitive.ItemGroup>
<FileUploadPrimitive.HiddenInput />
</>
)
}}
</FileUploadPrimitive.Context>
</FileUploadPrimitive.Root>
) }
import { createSlingshotServer } from '@saas-js/slingshot'
import { s3 } from '@saas-js/slingshot-adapter-s3'
import { handle } from '@saas-js/slingshot/next'
const slingshot = createSlingshotServer({
profile: 'avatar',
maxSizeBytes: 1024 * 1024 * 5, // 5MB
allowedFileTypes: 'image/*',
authorize: ({ req, file, meta }) => {
console.log('authorizing', req.headers.get('Authorization'), file, meta)
},
key: ({ file, meta }) => {
return `users/${meta?.userId}/avatar`
},
adapter: s3({
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
region: process.env.AWS_REGION,
bucket: process.env.AWS_BUCKET,
}),
})
export const POST = handle(slingshot)Installation
npm install @saas-js/slingshot @saas-js/slingshot-reactAcknowledgements
This library would not be possible without the following libraries:
- Slingshot for Meteor.js the original inspiration for this library.
- Ark UI for the React components.
- Shadcn for the component registry and CLI.
License
Apache 2.0