Skip to content

Commit

Permalink
fix: Pass through data and aria attributes (#238)
Browse files Browse the repository at this point in the history
* 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 <cameron.hessler@buildertrend.com>
  • Loading branch information
C-Hess and BTCameronHessler committed Apr 10, 2020
1 parent f5e06f9 commit cfd7ac5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/AjaxUploader.jsx
Expand Up @@ -6,6 +6,18 @@ import getUid from './uid';
import attrAccept from './attr-accept';
import traverseFileTree from './traverseFileTree';

const dataOrAriaAttributeProps = (props) => {
return Object.keys(props).reduce(
(acc, key) => {
if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role') {
acc[key] = props[key];
}
return acc;
},
{},
);
};

class AjaxUploader extends Component {
state = { uid: getUid() }

Expand Down Expand Up @@ -199,6 +211,7 @@ class AjaxUploader extends Component {
const {
component: Tag, prefixCls, className, disabled, id,
style, multiple, accept, children, directory, openFileDialogOnClick,
...otherProps,
} = this.props;
const cls = classNames({
[prefixCls]: true,
Expand All @@ -220,6 +233,7 @@ class AjaxUploader extends Component {
style={style}
>
<input
{...dataOrAriaAttributeProps(otherProps)}
id={id}
type="file"
ref={this.saveFileInput}
Expand Down
59 changes: 59 additions & 0 deletions tests/uploader.spec.js
Expand Up @@ -5,6 +5,7 @@ import Uploader from '../index';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
import { format } from 'util';
const { Simulate } = TestUtils;
import sinon from 'sinon';

Expand Down Expand Up @@ -47,15 +48,24 @@ const makeDataTransferItem = item => {
describe('uploader', () => {
let requests;
let xhr;
let errorMock;

beforeEach(() => {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = req => requests.push(req);

const originalConsoleError = global.console.error;
errorMock = jest.spyOn(global.console, 'error');
errorMock.mockImplementation((message, ...otherParams) => {
originalConsoleError(message, ...otherParams);
throw new Error(format(message, ...otherParams));
});
});

afterEach(() => {
xhr.restore();
errorMock.mockRestore();
});

describe('ajax uploader', () => {
Expand Down Expand Up @@ -116,6 +126,55 @@ describe('uploader', () => {
});
});

it('should pass through data attributes', done => {
ReactDOM.render(
(
<Uploader
data-testid="data-testid"
data-my-custom-attr="custom data attribute"
/>
),
node,
function init() {
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
.getAttribute('data-testid'))
.to.be('data-testid');
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
.getAttribute('data-my-custom-attr'))
.to.be('custom data attribute');
done();
}
);
});

it('should pass through aria attributes', done => {
ReactDOM.render(<Uploader aria-label="Upload a file"/>, node, function init() {
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
.getAttribute('aria-label'))
.to.be('Upload a file');
done();
});
});

it('should pass through role attributes', done => {
ReactDOM.render(<Uploader role="button"/>, node, function init() {
expect(TestUtils.findRenderedDOMComponentWithTag(this, 'input')
.getAttribute('role'))
.to.be('button');
done();
});
});

it('should not pass through unknown props', done => {
ReactDOM.render(<Uploader customProp="This shouldn't be rendered to DOM"/>,
node,
() => {
// Fails when React reports unrecognized prop is added to DOM in console.error
done();
}
);
});

it('create works', () => {
expect(TestUtils.scryRenderedDOMComponentsWithTag(uploader, 'span').length).to.be(1);
});
Expand Down

0 comments on commit cfd7ac5

Please sign in to comment.