Skip to content
Permalink
Browse files

feat: Migrate SafeAnchor to be a ref forwarder

This comes with a minor fix to Button not passing the ref to the
right prop to SafeAnchor.
  • Loading branch information
bpas247 committed Jul 28, 2019
1 parent f16d29b commit fc41617184bf435d74ff276172cd0e2bdc95ad78
Showing with 36 additions and 45 deletions.
  1. +1 −1 src/Button.js
  2. +35 −44 src/SafeAnchor.js
@@ -84,7 +84,7 @@ const Button = React.forwardRef(
<SafeAnchor
{...props}
as={as}
innerRef={ref}
ref={ref}
className={classNames(classes, props.disabled && 'disabled')}
/>
);
@@ -15,9 +15,6 @@ const propTypes = {
* this is sort of silly but needed for Button
*/
as: PropTypes.elementType,

/** @private */
innerRef: PropTypes.any,
};

function isTrivialHref(href) {
@@ -31,47 +28,40 @@ function isTrivialHref(href) {
* button its accessible. It also emulates input `disabled` behavior for
* links, which is usually desirable for Buttons, NavItems, DropdownItems, etc.
*/
class SafeAnchor extends React.Component {
constructor(props, context) {
super(props, context);

this.handleClick = this.handleClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
}

handleClick(event) {
const { disabled, href, onClick } = this.props;

if (disabled || isTrivialHref(href)) {
event.preventDefault();
}

if (disabled) {
event.stopPropagation();
return;
}

if (onClick) {
onClick(event);
}
}

handleKeyDown(event) {
if (event.key === ' ') {
event.preventDefault();
this.handleClick(event);
}
}

render() {
const {
const SafeAnchor = React.forwardRef(
(
{
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
as: Component = 'a',
disabled,
onKeyDown,
innerRef,
...props
} = this.props;
},
ref,
) => {
const handleClick = event => {
const { href, onClick } = props;

if (disabled || isTrivialHref(href)) {
event.preventDefault();
}

if (disabled) {
event.stopPropagation();
return;
}

if (onClick) {
onClick(event);
}
};

const handleKeyDown = event => {
if (event.key === ' ') {
event.preventDefault();
handleClick(event);
}
};

if (isTrivialHref(props.href)) {
props.role = props.role || 'button';
@@ -84,16 +74,17 @@ class SafeAnchor extends React.Component {
props.tabIndex = -1;
props['aria-disabled'] = true;
}
if (innerRef) props.ref = innerRef;

return (
<Component
ref={ref}
{...props}
onClick={this.handleClick}
onKeyDown={createChainedFunction(this.handleKeyDown, onKeyDown)}
onClick={handleClick}
onKeyDown={createChainedFunction(handleKeyDown, onKeyDown)}
/>
);
}
}
},
);

SafeAnchor.propTypes = propTypes;

0 comments on commit fc41617

Please sign in to comment.
You can’t perform that action at this time.