Skip to content

Commit fc41617

Browse files
committed
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.
1 parent f16d29b commit fc41617

File tree

2 files changed

+36
-45
lines changed

2 files changed

+36
-45
lines changed

src/Button.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const Button = React.forwardRef(
8484
<SafeAnchor
8585
{...props}
8686
as={as}
87-
innerRef={ref}
87+
ref={ref}
8888
className={classNames(classes, props.disabled && 'disabled')}
8989
/>
9090
);

src/SafeAnchor.js

+35-44
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ const propTypes = {
1515
* this is sort of silly but needed for Button
1616
*/
1717
as: PropTypes.elementType,
18-
19-
/** @private */
20-
innerRef: PropTypes.any,
2118
};
2219

2320
function isTrivialHref(href) {
@@ -31,47 +28,40 @@ function isTrivialHref(href) {
3128
* button its accessible. It also emulates input `disabled` behavior for
3229
* links, which is usually desirable for Buttons, NavItems, DropdownItems, etc.
3330
*/
34-
class SafeAnchor extends React.Component {
35-
constructor(props, context) {
36-
super(props, context);
37-
38-
this.handleClick = this.handleClick.bind(this);
39-
this.handleKeyDown = this.handleKeyDown.bind(this);
40-
}
41-
42-
handleClick(event) {
43-
const { disabled, href, onClick } = this.props;
44-
45-
if (disabled || isTrivialHref(href)) {
46-
event.preventDefault();
47-
}
48-
49-
if (disabled) {
50-
event.stopPropagation();
51-
return;
52-
}
53-
54-
if (onClick) {
55-
onClick(event);
56-
}
57-
}
58-
59-
handleKeyDown(event) {
60-
if (event.key === ' ') {
61-
event.preventDefault();
62-
this.handleClick(event);
63-
}
64-
}
65-
66-
render() {
67-
const {
31+
const SafeAnchor = React.forwardRef(
32+
(
33+
{
6834
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
6935
as: Component = 'a',
7036
disabled,
7137
onKeyDown,
72-
innerRef,
7338
...props
74-
} = this.props;
39+
},
40+
ref,
41+
) => {
42+
const handleClick = event => {
43+
const { href, onClick } = props;
44+
45+
if (disabled || isTrivialHref(href)) {
46+
event.preventDefault();
47+
}
48+
49+
if (disabled) {
50+
event.stopPropagation();
51+
return;
52+
}
53+
54+
if (onClick) {
55+
onClick(event);
56+
}
57+
};
58+
59+
const handleKeyDown = event => {
60+
if (event.key === ' ') {
61+
event.preventDefault();
62+
handleClick(event);
63+
}
64+
};
7565

7666
if (isTrivialHref(props.href)) {
7767
props.role = props.role || 'button';
@@ -84,16 +74,17 @@ class SafeAnchor extends React.Component {
8474
props.tabIndex = -1;
8575
props['aria-disabled'] = true;
8676
}
87-
if (innerRef) props.ref = innerRef;
77+
8878
return (
8979
<Component
80+
ref={ref}
9081
{...props}
91-
onClick={this.handleClick}
92-
onKeyDown={createChainedFunction(this.handleKeyDown, onKeyDown)}
82+
onClick={handleClick}
83+
onKeyDown={createChainedFunction(handleKeyDown, onKeyDown)}
9384
/>
9485
);
95-
}
96-
}
86+
},
87+
);
9788

9889
SafeAnchor.propTypes = propTypes;
9990

0 commit comments

Comments
 (0)