Skip to content

Commit cfd7ac5

Browse files
fix: Pass through data and aria attributes (#238)
* Add spread operator to pass through props * Use dataOrAttributeProps function instead of omit Credit to DylanVann for dataOrAriaAttributeProps function from https://github.com/react-component/notification/pull/54/files * Add tests for "role" attribute passthrough Co-authored-by: Cameron Hessler <[email protected]>
1 parent f5e06f9 commit cfd7ac5

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/AjaxUploader.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ import getUid from './uid';
66
import attrAccept from './attr-accept';
77
import traverseFileTree from './traverseFileTree';
88

9+
const dataOrAriaAttributeProps = (props) => {
10+
return Object.keys(props).reduce(
11+
(acc, key) => {
12+
if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role') {
13+
acc[key] = props[key];
14+
}
15+
return acc;
16+
},
17+
{},
18+
);
19+
};
20+
921
class AjaxUploader extends Component {
1022
state = { uid: getUid() }
1123

@@ -199,6 +211,7 @@ class AjaxUploader extends Component {
199211
const {
200212
component: Tag, prefixCls, className, disabled, id,
201213
style, multiple, accept, children, directory, openFileDialogOnClick,
214+
...otherProps,
202215
} = this.props;
203216
const cls = classNames({
204217
[prefixCls]: true,
@@ -220,6 +233,7 @@ class AjaxUploader extends Component {
220233
style={style}
221234
>
222235
<input
236+
{...dataOrAriaAttributeProps(otherProps)}
223237
id={id}
224238
type="file"
225239
ref={this.saveFileInput}

tests/uploader.spec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Uploader from '../index';
55
import React from 'react';
66
import ReactDOM from 'react-dom';
77
import TestUtils from 'react-dom/test-utils';
8+
import { format } from 'util';
89
const { Simulate } = TestUtils;
910
import sinon from 'sinon';
1011

@@ -47,15 +48,24 @@ const makeDataTransferItem = item => {
4748
describe('uploader', () => {
4849
let requests;
4950
let xhr;
51+
let errorMock;
5052

5153
beforeEach(() => {
5254
xhr = sinon.useFakeXMLHttpRequest();
5355
requests = [];
5456
xhr.onCreate = req => requests.push(req);
57+
58+
const originalConsoleError = global.console.error;
59+
errorMock = jest.spyOn(global.console, 'error');
60+
errorMock.mockImplementation((message, ...otherParams) => {
61+
originalConsoleError(message, ...otherParams);
62+
throw new Error(format(message, ...otherParams));
63+
});
5564
});
5665

5766
afterEach(() => {
5867
xhr.restore();
68+
errorMock.mockRestore();
5969
});
6070

6171
describe('ajax uploader', () => {
@@ -116,6 +126,55 @@ describe('uploader', () => {
116126
});
117127
});
118128

129+
it('should pass through data attributes', done => {
130+
ReactDOM.render(
131+
(
132+
<Uploader
133+
data-testid="data-testid"
134+
data-my-custom-attr="custom data attribute"
135+
/>
136+
),
137+
node,
138+
function init() {
139+
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
140+
.getAttribute('data-testid'))
141+
.to.be('data-testid');
142+
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
143+
.getAttribute('data-my-custom-attr'))
144+
.to.be('custom data attribute');
145+
done();
146+
}
147+
);
148+
});
149+
150+
it('should pass through aria attributes', done => {
151+
ReactDOM.render(<Uploader aria-label="Upload a file"/>, node, function init() {
152+
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
153+
.getAttribute('aria-label'))
154+
.to.be('Upload a file');
155+
done();
156+
});
157+
});
158+
159+
it('should pass through role attributes', done => {
160+
ReactDOM.render(<Uploader role="button"/>, node, function init() {
161+
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
162+
.getAttribute('role'))
163+
.to.be('button');
164+
done();
165+
});
166+
});
167+
168+
it('should not pass through unknown props', done => {
169+
ReactDOM.render(<Uploader customProp="This shouldn't be rendered to DOM"/>,
170+
node,
171+
() => {
172+
// Fails when React reports unrecognized prop is added to DOM in console.error
173+
done();
174+
}
175+
);
176+
});
177+
119178
it('create works', () => {
120179
expect(TestUtils.scryRenderedDOMComponentsWithTag(uploader, 'span').length).to.be(1);
121180
});

0 commit comments

Comments
 (0)