import * as React from 'react';
import type { Meta, StoryObj } from '@storybook/react-vite';
import { FileIcon, ImageIcon } from 'lucide-react';
import { Upload } from './upload';
import { Progress } from '../progress/progress';
const meta = {
title: 'Components/Upload',
component: Upload,
parameters: {
layout: 'centered',
docs: {
description: {
component:
'File picker with drag and drop. A hidden but focusable file input wrapped in a label, so the control is reachable by keyboard and announced as the file input it is. The visible surface is entirely yours. Point it at an endpoint with `action`, or take over the request with `customRequest` for signed URLs.',
},
},
},
tags: ['autodocs'],
decorators: [(Story) =>
],
} satisfies Meta;
export default meta;
type Story = StoryObj;
/** No `action` here, so nothing is sent — `beforeUpload` cancels the request. */
export const Default: Story = {
args: { beforeUpload: () => false },
};
export const ImagesOnly: Story = {
render: () => (
false}>
Drop images here
PNG, JPG or WebP · up to 5 MB
),
};
export const Disabled: Story = {
args: { disabled: true, beforeUpload: () => false },
};
/**
* A realistic flow: `beforeUpload` records the file and returns `false` so the
* story stays offline, then a fake progress ticker stands in for the request.
*/
export const WithFileList: Story = {
render: function WithFileListStory() {
const [files, setFiles] = React.useState<{ name: string; percent: number }[]>([]);
React.useEffect(() => {
if (!files.some((f) => f.percent < 100)) return;
const id = setInterval(() => {
setFiles((current) =>
current.map((f) => (f.percent >= 100 ? f : { ...f, percent: f.percent + 20 }))
);
}, 400);
return () => clearInterval(id);
}, [files]);
return (
{
setFiles((current) => [...current, { name: file.name, percent: 0 }]);
return false;
}}
/>
{files.length > 0 && (
)}
);
},
};