Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(uploader): Upoader 3.0 重构 & 多端适配 #2660

Merged
merged 61 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
543e0d6
fix: save
Alex-huxiyang Oct 23, 2024
b3fcf31
fix: save
Alex-huxiyang Oct 23, 2024
6e1016b
chore: taro save
Alex-huxiyang Oct 23, 2024
6b5d38c
fix: s
Alex-huxiyang Oct 23, 2024
fe74b6f
fix: save
Alex-huxiyang Oct 23, 2024
2334e78
fix: test
Alex-huxiyang Oct 24, 2024
2983242
fix: taro save
Alex-huxiyang Oct 24, 2024
563e918
fix: simple
Alex-huxiyang Oct 24, 2024
4cf5f7a
fix: update
Alex-huxiyang Oct 24, 2024
58bf2f9
feat: doc update
Alex-huxiyang Oct 24, 2024
ec4bc8a
fix: delete useless
Alex-huxiyang Oct 24, 2024
c2cb152
fix: delete useless
Alex-huxiyang Oct 24, 2024
cf1e6e6
fix: test
Alex-huxiyang Oct 24, 2024
7085e76
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 24, 2024
3b5034e
feat: harmony
Alex-huxiyang Oct 25, 2024
797099a
fix: save
Alex-huxiyang Oct 25, 2024
707919f
fix: doc mistakes
Alex-huxiyang Oct 25, 2024
da4221e
fix: doc mistakes
Alex-huxiyang Oct 25, 2024
3cf2df5
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 25, 2024
4346fb6
fix(uploader): resolve conflicts
Alex-huxiyang Oct 28, 2024
9f572df
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 28, 2024
ccc30e7
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 29, 2024
15986bd
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 30, 2024
9d813b1
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 30, 2024
b9588fd
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 31, 2024
5ee6d66
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Oct 31, 2024
22594ba
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 1, 2024
d59de4c
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 4, 2024
d902a65
fix: default key
Alex-huxiyang Nov 4, 2024
22c6899
fix: ts export
Alex-huxiyang Nov 4, 2024
4cf906b
chore: cr fix
Alex-huxiyang Nov 7, 2024
1763890
chore: update
Alex-huxiyang Nov 7, 2024
bde9cbc
chore: cr
Alex-huxiyang Nov 7, 2024
b6dea57
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 9, 2024
beb6a3c
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 10, 2024
d22c927
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 11, 2024
3c7f4b5
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 11, 2024
589ccd5
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 14, 2024
b3267a0
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 14, 2024
5959362
Merge branch 'V3.0' into hxy/uploader/refactor
Alex-huxiyang Nov 18, 2024
18734d6
fix: resolve conflicts
Alex-huxiyang Nov 26, 2024
81918e9
Merge branch 'feat_v3.x' into hxy/uploader/refactor
Alex-huxiyang Dec 2, 2024
30b0144
Merge branch 'feat_v3.x' into hxy/uploader/refactor
Alex-huxiyang Dec 2, 2024
a50fc2e
chore: unify lock file
Alex-huxiyang Dec 4, 2024
6d8ea36
chore: update v2 to v3 md
Alex-huxiyang Dec 4, 2024
786ff04
Merge branch 'feat_v3.x' into hxy/uploader/refactor
xiaoyatong Dec 4, 2024
aafb914
fix: sth about types
Alex-huxiyang Dec 4, 2024
55d5b91
fix: sth about demos
Alex-huxiyang Dec 4, 2024
f7bca72
fix: sth about space
Alex-huxiyang Dec 4, 2024
54a7218
fix: sth about progress and docs
Alex-huxiyang Dec 4, 2024
0ceb697
fix: sth about progress
Alex-huxiyang Dec 4, 2024
e232ce7
fix: sth about v2v3 md
Alex-huxiyang Dec 4, 2024
3caca30
Merge branch 'feat_v3.x' into hxy/uploader/refactor
Alex-huxiyang Dec 9, 2024
aa0ba95
chore: add unit test
Alex-huxiyang Dec 9, 2024
18a7aa1
chore: add unit test
Alex-huxiyang Dec 9, 2024
a2bbbdd
chore: add unit test
Alex-huxiyang Dec 9, 2024
2edf7b5
chore: add unit test
Alex-huxiyang Dec 9, 2024
4376c2e
chore: add unit test
Alex-huxiyang Dec 9, 2024
eb30e61
chore: add unit test
Alex-huxiyang Dec 9, 2024
13c3216
chore: add unit test
Alex-huxiyang Dec 9, 2024
020eb24
Merge branch 'feat_v3.x' into hxy/uploader/refactor
Alex-huxiyang Dec 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions migrate-from-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,23 +525,15 @@ plugins: [

#### Uploader

- `maximize` 重命名为 `maxFileSize`
- `maximum` 重命名为 `maxCount`
- `listType ` 重命名为 `previewType`
- `isDeletable ` 重命名为 `deletable`
- `isPreview` 重命名为 ` preview`
- `defaultImg` 重命名为 ` previewUrl`
- `defaultFileList` 重命名为 ` defaultValue`
- `uploadIconTip` 重命名为 `uploadLabel`,类型变更为 `ReactNode`
- `onBeforeUpload` 重命名为 `beforeUpload`
- `onBeforeXhrUpload` 重命名为 `beforeXhrUpload`
- `onBeforeDelete` 重命名为 `beforeDelete`
- `onRemove` 重命名为 `onDelete`
- 增加 `fit`,用于图片填充模式
- 增加 `value`,用于受控传值
- 移除 `uploadIconSize`,可通过 icon 属性传入自定义 icon 或借助 CSS Variables 修改 icon 大小
- `uploadIcon` 类型从 `string` 调整为 `ReactNode`
- `onChange` 参数类型从 `{fileList: FileItem[], event: any}` 调整为 `FileItem[]`
- 移除了组件内部关于ajax相关网络逻辑的处理
- 移除了`url`、`headers`、`data`、`xhrState`、`withCredentials`、`timeout` 网络配置相关props
- 移除了`onStart`、`onProgress`、`onFailure`、`beforeXhrUpload` 触发时机函数相关props
Alex-huxiyang marked this conversation as resolved.
Show resolved Hide resolved
- 新增`onOverCount`属性,文件数量超过限制时触发
- 新增`onUploadQueueChange`属性,图片上传队列变化时触发
- 简化`FileItem`类型的使用,除url外其他属性变为可选
- 调整多选状态下`maxCount`属性的默认值为`Number.MAX_VALUE`
- 新增了的 `upload` 方法
- `defaultValue` 和 `value` 的类型从 `FileType` 变更为 `FileItem`

### 操作反馈

Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@
"author": "VickyYe"
},
{
"version": "2.0.0",
"version": "3.0.0",
"name": "Uploader",
"type": "component",
"tarodoc": true,
Expand Down
174 changes: 164 additions & 10 deletions src/packages/uploader/__tests__/uploader.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { render, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'

import { Uploader } from '../uploader'
import { FileItem } from '../file-item'
import { FileItem } from '../types'
import { Preview } from '../preview'
import Button from '@/packages/button'

test('should render base uploader and type', () => {
const { container, getByTestId } = render(
Expand Down Expand Up @@ -73,7 +74,6 @@ test('should render base uploader other props', () => {
<Uploader
deletable
defaultValue={defaultFileList}
headers={{}}
multiple
preview
uploadIcon="dongdong"
Expand Down Expand Up @@ -144,7 +144,7 @@ test('should render base uploader props disabled', () => {
test('before-delete prop return false', () => {
const onDelete = vi.fn()
const App = () => {
const defaultFileList: FileItem[] = [
const fileList: FileItem[] = [
{
name: '文件1.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
Expand All @@ -157,7 +157,7 @@ test('before-delete prop return false', () => {
return (
<Uploader
deletable
defaultValue={defaultFileList}
value={fileList}
onDelete={onDelete}
beforeDelete={() => {
return false
Expand Down Expand Up @@ -199,8 +199,125 @@ test('before-delete prop return true', () => {
expect(onDelete).toBeCalled()
})

test('should render progress', () => {
const App = () => {
const list: FileItem[] = [
{
name: '文件444.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'uploading',
message: '上传中...',
percentage: 30,
},
]
return <Uploader deletable value={list} previewType="list" />
}
const { container } = render(<App />)
const progressElement = container.querySelector('.nut-progress')
expect(progressElement).toBeInTheDocument()
const progressInnerElement = container.querySelector('.nut-progress-inner')
expect(progressInnerElement).toBeInTheDocument()
expect(progressInnerElement).toHaveStyle('width: 30%')
const textElement = container.querySelector('span')
expect(textElement).toHaveTextContent('文件444.png')
})
test('simulates single file upload', () => {
const handleUpload: any = vi.fn()
const { container } = render(
<Uploader upload={(file: File) => handleUpload(file)} />
)
const file = new File(['hello'], 'hello.png', { type: 'image/png' })
const input: any = container.querySelector('input')

fireEvent.change(input, { target: { files: [file] } })

expect(handleUpload).toHaveBeenCalledTimes(1)
expect(handleUpload).toHaveBeenCalledWith(file)
})
test('simulates single file upload fail', async () => {
const handleUpload: any = vi.fn(() =>
Promise.reject(new Error('Upload failed'))
)
const { container } = render(
<Uploader upload={(file: File) => handleUpload(file)} />
)
const file = new File(['hello'], 'hello.png', { type: 'image/png' })
const input: any = container.querySelector('input')

fireEvent.change(input, { target: { files: [file] } })

expect(handleUpload).toHaveBeenCalledTimes(1)
expect(handleUpload).toHaveBeenCalledWith(file)
})
test('simulates multiple file upload', () => {
const handleUpload: any = vi.fn()
const handleOverCount: any = vi.fn()
const { container } = render(
<Uploader
upload={(file: File) => handleUpload(file)}
multiple
maxCount={2}
onOverCount={handleOverCount}
/>
)
const file1 = new File(['file1'], 'file1.txt', { type: 'text/plain' })
const file2 = new File(['file2'], 'file2.txt', { type: 'text/plain' })
const file3 = new File(['file3'], 'file3.txt', { type: 'text/plain' })
const files = [file1, file2, file3]
const input: any = container.querySelector('input')

fireEvent.change(input, { target: { files } })

expect(handleUpload).toHaveBeenCalledTimes(2)
expect(handleOverCount).toHaveBeenCalledTimes(1)
expect(handleOverCount).toHaveBeenCalledWith(3)
})
test('simulates file upload when autoupload is false', () => {
const handleUpload: any = vi.fn()
const handleOverCount: any = vi.fn()
const { container } = render(
<Uploader
upload={(file: File) => handleUpload(file)}
multiple
autoUpload={false}
maxCount={2}
onOverCount={handleOverCount}
/>
)
const file1 = new File(['file1'], 'file1.txt', { type: 'text/plain' })
const file2 = new File(['file2'], 'file2.txt', { type: 'text/plain' })
const file3 = new File(['file3'], 'file3.txt', { type: 'text/plain' })
const files = [file1, file2, file3]
const input: any = container.querySelector('input')
fireEvent.change(input, { target: { files } })
expect(handleUpload).toHaveBeenCalledTimes(0)
})
test('should render button', () => {
const clearUpload = vi.fn()
const submitUpload = vi.fn()
const App = () => {
return (
<>
<Uploader />
<Button type="success" onClick={submitUpload}>
执行上传
</Button>
<Button type="primary" onClick={clearUpload}>
手动清空上传
</Button>
</>
)
}
const { container } = render(<App />)
const buttonElement = container.querySelector('.nut-button')
expect(buttonElement).toBeInTheDocument()
fireEvent.click(container.querySelectorAll('.nut-button-success')[0])
expect(submitUpload).toBeCalled()
fireEvent.click(container.querySelectorAll('.nut-button-primary')[0])
expect(clearUpload).toBeCalled()
})
test('ready file list', () => {
const list = new FileItem()
const list: any = {}
Alex-huxiyang marked this conversation as resolved.
Show resolved Hide resolved
list.name = '文件1.png'
list.url =
'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif'
Expand All @@ -222,7 +339,46 @@ test('ready file list', () => {
const { container, getByText } = render(<App />)
expect(getByText('准备上传')).toHaveTextContent('准备上传')
})

test('type is not image and doesnot set previewurl', () => {
const list: any = {}
list.name = '文件1.png'
list.url =
'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif'
list.status = 'ready'
list.message = '准备上传'
list.type = 'video'
list.uid = '12'
const App = () => {
return <Uploader deletable defaultValue={[list]} />
}
const { container, getByText } = render(<App />)
expect(
container.querySelector('.nut-uploader-preview-img-file')
).toBeInTheDocument()
})
test('type is not image and set previewurl', () => {
const list: any = {}
list.name = '文件1.png'
list.url =
'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif'
list.status = 'ready'
list.message = '准备上传'
list.type = 'video'
list.uid = '12'
const App = () => {
return (
<Uploader
deletable
defaultValue={[list]}
previewUrl="https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif"
/>
)
}
const { container, getByText } = render(<App />)
expect(
container.querySelector('.nut-uploader-preview-img-c')
).toBeInTheDocument()
})
test('preview component', () => {
const delFunc = vi.fn()
const clickFunc = vi.fn()
Expand All @@ -232,6 +388,7 @@ test('preview component', () => {
status: 'success',
message: '上传成功',
uid: '12',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
},
]

Expand All @@ -242,7 +399,6 @@ test('preview component', () => {
deletable
onDeleteItem={delFunc}
handleItemClick={clickFunc}
previewUrl="https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif"
/>
)
fireEvent.click(container.querySelectorAll('.close')[0])
Expand All @@ -260,9 +416,7 @@ test('preview component', () => {
handleItemClick={clickFunc}
/>
)
fireEvent.click(
container1.querySelectorAll('.nut-uploader-preview-img-file-name')[0]
)
fireEvent.click(container1.querySelectorAll('.nut-uploader-preview-img-c')[0])
expect(clickFunc).toBeCalled()

const { container: container2 } = render(
Expand Down
Loading
Loading