Skip to content

Commit 916819d

Browse files
committed
ButtonOrLink: add types
1 parent b60cfdf commit 916819d

File tree

1 file changed

+32
-33
lines changed

1 file changed

+32
-33
lines changed

client/common/ButtonOrLink.tsx

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
import React from 'react';
22
import { Link } from 'react-router-dom';
3-
import PropTypes from 'prop-types';
3+
44

55
/**
6-
* Helper for switching between <button>, <a>, and <Link>
6+
* Accepts all the props of an HTML <a> or <button> tag.
77
*/
8+
type ButtonOrLinkProps = {
9+
/**
10+
* If providing an href, will render as a link instead of a button.
11+
* Can be internal or external.
12+
* Internal links will use react-router.
13+
* External links should start with 'http' or 'https' and will open in a new window.
14+
*/
15+
href?: string,
16+
isDisabled?: boolean,
17+
/**
18+
* Content of the button/link.
19+
* Can be either a string or a complex element.
20+
*/
21+
children: React.ReactNode,
22+
onClick?: (e: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;
23+
};
824

25+
type Ref = HTMLAnchorElement | HTMLButtonElement
26+
27+
/**
28+
* Helper for switching between <button>, <a>, and <Link>
29+
*/
930
const ButtonOrLink = React.forwardRef(
10-
({ href, children, isDisabled, onClick, ...props }, ref) => {
11-
const handleClick = (e) => {
31+
(
32+
{ href, children, isDisabled = false, onClick, ...props }: ButtonOrLinkProps,
33+
ref: React.Ref<Ref>
34+
) => {
35+
const handleClick = (e: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => {
1236
if (isDisabled) {
1337
e.preventDefault();
1438
e.stopPropagation();
@@ -23,7 +47,8 @@ const ButtonOrLink = React.forwardRef(
2347
if (href.startsWith('http')) {
2448
return (
2549
<a
26-
ref={ref}
50+
// eslint-disable-next-line prettier/prettier -- not able to parse 'as' for some reason
51+
ref={ref as React.Ref<HTMLAnchorElement>}
2752
href={href}
2853
target="_blank"
2954
rel="noopener noreferrer"
@@ -37,7 +62,7 @@ const ButtonOrLink = React.forwardRef(
3762
}
3863
return (
3964
<Link
40-
ref={ref}
65+
ref={ref as React.Ref<HTMLAnchorElement>}
4166
to={href}
4267
aria-disabled={isDisabled}
4368
{...props}
@@ -49,7 +74,7 @@ const ButtonOrLink = React.forwardRef(
4974
}
5075
return (
5176
<button
52-
ref={ref}
77+
ref={ref as React.Ref<HTMLButtonElement>}
5378
aria-disabled={isDisabled}
5479
{...props}
5580
onClick={handleClick}
@@ -60,30 +85,4 @@ const ButtonOrLink = React.forwardRef(
6085
}
6186
);
6287

63-
/**
64-
* Accepts all the props of an HTML <a> or <button> tag.
65-
*/
66-
ButtonOrLink.propTypes = {
67-
/**
68-
* If providing an href, will render as a link instead of a button.
69-
* Can be internal or external.
70-
* Internal links will use react-router.
71-
* External links should start with 'http' or 'https' and will open in a new window.
72-
*/
73-
href: PropTypes.string,
74-
isDisabled: PropTypes.bool,
75-
/**
76-
* Content of the button/link.
77-
* Can be either a string or a complex element.
78-
*/
79-
children: PropTypes.node.isRequired,
80-
onClick: PropTypes.func
81-
};
82-
83-
ButtonOrLink.defaultProps = {
84-
href: null,
85-
isDisabled: false,
86-
onClick: null
87-
};
88-
8988
export default ButtonOrLink;

0 commit comments

Comments
 (0)