Skip to content

Commit 90ffba0

Browse files
TannerSkodiakhq[bot]tay1orjones
authored
feat(fileuploaderdropcontainer): added pattern for accepted file ext (#9929)
* feat(fileuploaderdropcontainer): added pattern for accepted file ext * chore: update snaps Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Taylor Jones <taylor.jones826@gmail.com> Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>
1 parent f6352a1 commit 90ffba0

4 files changed

Lines changed: 104 additions & 1 deletion

File tree

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2946,6 +2946,7 @@ Map {
29462946
"labelText": "Add file",
29472947
"multiple": false,
29482948
"onAddFiles": [Function],
2949+
"pattern": ".[0-9a-z]+$",
29492950
"tabIndex": 0,
29502951
},
29512952
"propTypes": Object {
@@ -2979,6 +2980,9 @@ Map {
29792980
"onAddFiles": Object {
29802981
"type": "func",
29812982
},
2983+
"pattern": Object {
2984+
"type": "string",
2985+
},
29822986
"role": Object {
29832987
"type": "string",
29842988
},

packages/react/src/components/FileUploader/FileUploader-story.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ const props = {
140140
disabled: boolean('Disabled (disabled)', false),
141141
role: text('ARIA role of the button (role)', ''),
142142
tabIndex: number('Tab index (tabIndex)', 0),
143+
pattern: text(
144+
'Accepted MIME types or file extensions regex pattern (pattern)',
145+
undefined
146+
),
143147
onAddFiles: action('onAddFiles'),
144148
}),
145149
};

packages/react/src/components/FileUploader/FileUploaderDropContainer.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function FileUploaderDropContainer({
2121
multiple,
2222
name,
2323
onAddFiles,
24+
pattern,
2425
role,
2526
tabIndex,
2627
...rest
@@ -52,7 +53,7 @@ function FileUploaderDropContainer({
5253
const acceptedTypes = new Set(accept);
5354
return transferredFiles.reduce((acc, curr) => {
5455
const { name, type: mimeType = '' } = curr;
55-
const fileExtensionRegExp = new RegExp(/\.[0-9a-z]+$/, 'i');
56+
const fileExtensionRegExp = new RegExp(pattern, 'i');
5657
const hasFileExtension = fileExtensionRegExp.test(name);
5758
if (!hasFileExtension) {
5859
return acc;
@@ -178,6 +179,11 @@ FileUploaderDropContainer.propTypes = {
178179
*/
179180
onAddFiles: PropTypes.func,
180181

182+
/**
183+
* Provide a custom regex pattern for the acceptedTypes
184+
*/
185+
pattern: PropTypes.string,
186+
181187
/**
182188
* Provide an accessibility role for the <FileUploaderButton>
183189
*/
@@ -202,6 +208,7 @@ FileUploaderDropContainer.defaultProps = {
202208
multiple: false,
203209
onAddFiles: () => {},
204210
accept: [],
211+
pattern: '.[0-9a-z]+$',
205212
};
206213

207214
export default FileUploaderDropContainer;

packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,92 @@ describe('FileUploaderDropContainer', () => {
8787
{ addedFiles: files }
8888
);
8989
});
90+
91+
it('should mark invalid files using default pattern', () => {
92+
const onAddFiles = jest.fn();
93+
const { container } = render(
94+
<FileUploaderDropContainer onAddFiles={onAddFiles} accept={['.txt']} />
95+
);
96+
const input = container.querySelector('input');
97+
98+
const files = [
99+
new File(['foo'], 'foo.txt', { type: 'text/plain' }),
100+
new File(['bar'], 'bar.a_a', { type: 'text/plain' }),
101+
new File(['bar_foo'], 'bar_foo.b-b', { type: 'text/plain' }),
102+
new File(['bar-foo'], 'bar-foo.a-b_c', { type: 'text/plain' }),
103+
];
104+
105+
uploadFiles(input, files);
106+
107+
expect(onAddFiles).toHaveBeenCalledWith(
108+
expect.objectContaining({
109+
target: {
110+
files,
111+
},
112+
}),
113+
{ addedFiles: files }
114+
);
115+
116+
expect(onAddFiles).toHaveBeenCalledWith(
117+
expect.objectContaining({
118+
target: {
119+
files,
120+
},
121+
}),
122+
{
123+
addedFiles: expect.arrayContaining([
124+
expect.not.objectContaining({ invalidFileType: true }),
125+
expect.objectContaining({ invalidFileType: true }),
126+
expect.objectContaining({ invalidFileType: true }),
127+
expect.objectContaining({ invalidFileType: true }),
128+
]),
129+
}
130+
);
131+
});
132+
133+
it('should not mark any invalid files using custom pattern', () => {
134+
const onAddFiles = jest.fn();
135+
const { container } = render(
136+
<FileUploaderDropContainer
137+
onAddFiles={onAddFiles}
138+
accept={['.txt', '.a_a', '.b-b', '.a-b_c']}
139+
pattern=".[0-9a-z-_]+$"
140+
/>
141+
);
142+
const input = container.querySelector('input');
143+
144+
const files = [
145+
new File(['foo'], 'foo.txt', { type: 'text/plain' }),
146+
new File(['bar'], 'bar.a_a', { type: 'text/plain' }),
147+
new File(['bar_foo'], 'bar_foo.b-b', { type: 'text/plain' }),
148+
new File(['bar-foo'], 'bar-foo.a-b_c', { type: 'text/plain' }),
149+
];
150+
151+
uploadFiles(input, files);
152+
153+
expect(onAddFiles).toHaveBeenCalledWith(
154+
expect.objectContaining({
155+
target: {
156+
files,
157+
},
158+
}),
159+
{ addedFiles: files }
160+
);
161+
162+
expect(onAddFiles).toHaveBeenCalledWith(
163+
expect.objectContaining({
164+
target: {
165+
files,
166+
},
167+
}),
168+
{
169+
addedFiles: expect.arrayContaining([
170+
expect.not.objectContaining({ invalidFileType: true }),
171+
expect.not.objectContaining({ invalidFileType: true }),
172+
expect.not.objectContaining({ invalidFileType: true }),
173+
expect.not.objectContaining({ invalidFileType: true }),
174+
]),
175+
}
176+
);
177+
});
90178
});

0 commit comments

Comments
 (0)