Skip to content

Commit f1cb684

Browse files
committed
chore: dir native support
1 parent 1896e01 commit f1cb684

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

src/AjaxUploader.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@ class AjaxUploader extends Component<UploadProps> {
3030

3131
private _isMounted: boolean;
3232

33+
private isNativeDirectory = (): boolean => {
34+
return this.props.directory === 'native';
35+
};
36+
3337
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
34-
const { accept, directory } = this.props;
38+
const { accept } = this.props;
3539
const { files } = e.target;
3640
const acceptedFiles = [...files].filter(
37-
(file: RcFile) => !directory || attrAccept(file, accept),
41+
(file: RcFile) => this.isNativeDirectory() || attrAccept(file, accept),
3842
);
3943
this.uploadFiles(acceptedFiles);
4044
this.reset();
@@ -78,7 +82,7 @@ class AjaxUploader extends Component<UploadProps> {
7882

7983
if (directory) {
8084
files = await traverseFileTree(Array.prototype.slice.call(items), (_file: RcFile) =>
81-
attrAccept(_file, this.props.accept),
85+
this.isNativeDirectory() ? true : attrAccept(_file, this.props.accept),
8286
);
8387
this.uploadFiles(files);
8488
} else {
@@ -322,7 +326,6 @@ class AjaxUploader extends Component<UploadProps> {
322326
capture,
323327
children,
324328
directory,
325-
folder,
326329
openFileDialogOnClick,
327330
onMouseEnter,
328331
onMouseLeave,
@@ -331,8 +334,9 @@ class AjaxUploader extends Component<UploadProps> {
331334
} = this.props;
332335
const cls = clsx(prefixCls, { [`${prefixCls}-disabled`]: disabled, [className]: className });
333336
// because input don't have directory/webkitdirectory type declaration
334-
const dirProps: any =
335-
directory || folder ? { directory: 'directory', webkitdirectory: 'webkitdirectory' } : {};
337+
const dirProps: any = directory
338+
? { directory: 'directory', webkitdirectory: 'webkitdirectory' }
339+
: {};
336340
const events = disabled
337341
? {}
338342
: {

src/interface.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ export interface UploadProps
1313
component?: React.ComponentType<any> | string;
1414
action?: Action;
1515
method?: UploadRequestMethod;
16-
/** @deprecated Please use `folder` instead */
17-
directory?: boolean;
18-
folder?: boolean;
16+
/**
17+
* Whether to support directory upload.
18+
* By default, files within the directory will be filtered through the accept attribute.
19+
* When set to `native`, it will upload the directory directly following native logic without filtering.
20+
*/
21+
directory?: boolean | 'native';
1922
data?: Record<string, unknown> | ((file: RcFile | string | Blob) => Record<string, unknown>);
2023
headers?: UploadRequestHeader;
2124
accept?: string;

tests/uploader.spec.tsx

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,9 +1039,9 @@ describe('uploader', () => {
10391039
},
10401040
);
10411041

1042-
it('should trigger beforeUpload when uploading non-accepted files in folder mode', () => {
1042+
it('should trigger beforeUpload when uploading non-accepted files in native directory mode', () => {
10431043
const beforeUpload = jest.fn();
1044-
const { container } = render(<Upload accept=".png" folder beforeUpload={beforeUpload} />);
1044+
const { container } = render(<Upload accept=".png" directory="native" beforeUpload={beforeUpload} />);
10451045

10461046
fireEvent.change(container.querySelector('input')!, {
10471047
target: {
@@ -1050,6 +1050,47 @@ describe('uploader', () => {
10501050
});
10511051
expect(beforeUpload).toHaveBeenCalledTimes(2);
10521052
});
1053+
1054+
it('should filter files by accept when directory is true', async () => {
1055+
const onStart = jest.fn();
1056+
const { container } = render(<Upload action="/test" accept=".png" directory={true} onStart={onStart} />);
1057+
1058+
// Wait for component to be ready
1059+
await new Promise(resolve => setTimeout(resolve, 0));
1060+
1061+
fireEvent.change(container.querySelector('input')!, {
1062+
target: {
1063+
files: [new File([''], 'bamboo.png'), new File([''], 'light.jpg')],
1064+
},
1065+
});
1066+
1067+
// Wait for async operations
1068+
await new Promise(resolve => setTimeout(resolve, 0));
1069+
1070+
// Only .png file should be uploaded when directory={true}
1071+
expect(onStart).toHaveBeenCalledTimes(1);
1072+
expect(onStart).toHaveBeenCalledWith(expect.objectContaining({ name: 'bamboo.png' }));
1073+
});
1074+
1075+
it('should not filter files by accept when directory is "native"', async () => {
1076+
const onStart = jest.fn();
1077+
const { container } = render(<Upload action="/test" accept=".png" directory="native" onStart={onStart} />);
1078+
1079+
// Wait for component to be ready
1080+
await new Promise(resolve => setTimeout(resolve, 0));
1081+
1082+
fireEvent.change(container.querySelector('input')!, {
1083+
target: {
1084+
files: [new File([''], 'bamboo.png'), new File([''], 'light.jpg')],
1085+
},
1086+
});
1087+
1088+
// Wait for async operations
1089+
await new Promise(resolve => setTimeout(resolve, 0));
1090+
1091+
// Both files should be uploaded when directory="native"
1092+
expect(onStart).toHaveBeenCalledTimes(2);
1093+
});
10531094
});
10541095

10551096
describe('transform file before request', () => {

0 commit comments

Comments
 (0)