Skip to content

Commit

Permalink
Merge pull request #39088 from code-dot-org/download-button
Browse files Browse the repository at this point in the history
Add a 'download' property to Button
  • Loading branch information
Hamms committed Feb 18, 2021
2 parents bba0812 + d64ce85 commit d8c25a4
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
11 changes: 11 additions & 0 deletions apps/src/templates/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class Button extends React.Component {
target: PropTypes.string,
style: PropTypes.object,
disabled: PropTypes.bool,
download: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
onClick: PropTypes.func,
id: PropTypes.string,
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
Expand Down Expand Up @@ -226,6 +227,7 @@ class Button extends React.Component {
style,
onClick,
disabled,
download,
id,
tabIndex,
isPending,
Expand All @@ -245,6 +247,14 @@ class Button extends React.Component {
Tag = href ? 'a' : 'div';
}

if (download && Tag !== 'a') {
// <button> and <div> elements do not support the download attribute, so
// don't let this component attempt to do that.
throw new Error(
'Attempted to use the download attribute with a non-anchor tag'
);
}

const sizeStyle = __useDeprecatedTag
? styles.sizes[size]
: {...styles.sizes[size], ...styles.updated};
Expand All @@ -256,6 +266,7 @@ class Button extends React.Component {
href={disabled ? 'javascript:void(0);' : href}
target={target}
disabled={disabled}
download={download}
onClick={disabled ? null : onClick}
onKeyDown={this.onKeyDown}
tabIndex={tabIndex}
Expand Down
27 changes: 27 additions & 0 deletions apps/test/unit/templates/ButtonTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,31 @@ describe('Button', () => {
assert(icon);
assert.equal(icon.props().icon, 'lock');
});

it('supports the download property/attribute', () => {
// The download attribute can be used with or without a value (see
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download),
// so make sure to test both.
const wrapper = shallow(
<Button __useDeprecatedTag download href="/foo/bar" text="Click me" />
);
assert.equal(wrapper.find('a').prop('download'), true);
wrapper.setProps({download: 'baz'});
assert.equal(wrapper.find('a').prop('download'), 'baz');
});

it('does not support the download property/attribute for non-anchor tags', () => {
// <button> and <div> elements do not have a download attribute, so we
// proactively prevent our component from attempting to use the download
// property when the underlying element would be one of them.
assert.throws(() => {
// button case
shallow(<Button download text="Click me" />);
});

assert.throws(() => {
// div case
shallow(<Button __useDeprecatedTag download text="Click me" />);
});
});
});

0 comments on commit d8c25a4

Please sign in to comment.