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 } from '@saas-js/slingshot-react'
import { Button } from '@/components/button'
import { Progress } from '@/components/progress'
export const FileUpload = (props: Omit<FileUpload.RootProps, 'children'>) => {
return (
<FileUpload.Root {...props}>
<FileUpload.Context>
{(api) => {
const files = api.slingshot.getFiles()
return (
<>
<FileUpload.Dropzone>
<FileUpload.Label>
Drag your file(s) here
</FileUpload.Label>
<FileUpload.Trigger asChild>
<Button>Choose file(s)</Button>
</FileUpload.Trigger>
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
{files.map((file) => {
return (
<FileUpload.Item
key={file.name}
file={file.data}
>
<FileUpload.ItemPreview type="image/*">
<FileUpload.ItemPreviewImage />
</FileUpload.ItemPreview>
<FileUpload.ItemName />
<FileUpload.ItemSizeText />
<div>
{file.progress &&
file.status !== 'done' && (
<Progress
value={file.progress}
type="circular"
colorPalette="green"
/>
)}
{file.status === 'done' ? 'Done' : null}
</div>
<FileUpload.ItemDeleteTrigger>
✕
</FileUpload.ItemDeleteTrigger>
</FileUpload.Item>
)
})}
</FileUpload.ItemGroup>
<FileUpload.HiddenInput />
</>
)
}}
</FileUpload.Context>
</FileUpload.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-react
Acknowledgements
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