diff --git a/docs/components/upload.md b/docs/components/upload.md index 9bef5ad..e724f3f 100644 --- a/docs/components/upload.md +++ b/docs/components/upload.md @@ -12,11 +12,17 @@ } `" /> +## 键盘操作 + +触发区关联原生文件输入,支持通过 `Tab` 聚焦,并使用浏览器默认的文件选择快捷键打开文件选择器。 + ## API -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| accept | 接受的文件类型 | `string` | - | -| multiple | 是否多选 | `boolean` | `false` | -| fileList | 文件列表 | `UploadFileItem[]` | - | -| onChange | 文件变化回调 | `(files) => void` | - | +| 属性 | 说明 | 类型 | 默认值 | +| ----------- | -------------- | ------------------ | ------------------------------ | +| accept | 接受的文件类型 | `string` | - | +| multiple | 是否多选 | `boolean` | `false` | +| disabled | 禁用上传 | `boolean` | `false` | +| fileList | 文件列表 | `UploadFileItem[]` | - | +| triggerText | 触发区内容 | `ReactNode` | `Click or drag file to upload` | +| onChange | 文件变化回调 | `(files) => void` | - | diff --git a/packages/ui/src/components/form/controls/Upload/Upload.test.tsx b/packages/ui/src/components/form/controls/Upload/Upload.test.tsx new file mode 100644 index 0000000..086d400 --- /dev/null +++ b/packages/ui/src/components/form/controls/Upload/Upload.test.tsx @@ -0,0 +1,65 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import { describe, expect, it, vi } from 'vitest' + +import { Upload } from './Upload' + +describe('Upload', () => { + it('exposes a focusable file input through the visible trigger text', async () => { + const user = userEvent.setup() + + render() + + const input = screen.getByLabelText('Select files') + expect(input).toHaveAttribute('type', 'file') + + await user.tab() + expect(input).toHaveFocus() + }) + + it('calls onChange with selected file metadata', async () => { + const user = userEvent.setup() + const onChange = vi.fn() + const file = new File(['hello'], 'report.txt', { + lastModified: 123, + type: 'text/plain', + }) + + render() + + await user.upload(screen.getByLabelText('Upload report'), file) + + expect(onChange).toHaveBeenCalledWith([ + { + uid: 'report.txt-123', + name: 'report.txt', + size: 5, + }, + ]) + }) + + it('passes accept, multiple, and disabled attributes to the input', () => { + render() + + const input = screen.getByLabelText('Upload images') + + expect(input).toHaveAttribute('accept', 'image/png') + expect(input).toHaveAttribute('multiple') + expect(input).toBeDisabled() + }) + + it('renders the controlled file list with list semantics', () => { + render( + , + ) + + expect(screen.getByRole('list', { name: 'Uploaded files' })).toBeInTheDocument() + expect(screen.getByText('first.pdf')).toBeInTheDocument() + expect(screen.getByText('second.pdf')).toBeInTheDocument() + }) +}) diff --git a/packages/ui/src/components/form/controls/Upload/Upload.tsx b/packages/ui/src/components/form/controls/Upload/Upload.tsx index a19de2e..f2decb1 100644 --- a/packages/ui/src/components/form/controls/Upload/Upload.tsx +++ b/packages/ui/src/components/form/controls/Upload/Upload.tsx @@ -40,19 +40,28 @@ export const Upload = forwardRef(function Upload( return (
-