Skip to content

Commit eb69138

Browse files
committed
ButtonOrLink: update to typescript
1 parent c1883c5 commit eb69138

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

client/common/ButtonOrLink.tsx

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

54
/**
6-
* Helper for switching between <button>, <a>, and <Link>
5+
* Accepts all the props of an HTML <a> or <button> tag.
76
*/
7+
export type ButtonOrLinkProps = {
8+
/**
9+
* Can be internal or external ('http'- or 'https'-).
10+
*/
11+
href?: string;
12+
isDisabled?: boolean;
13+
/**
14+
* Content of the button/link.
15+
* Can be either a string or a complex element.
16+
*/
17+
children: React.ReactNode;
18+
onClick?: (
19+
e: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>
20+
) => void;
21+
};
22+
23+
export type Ref = HTMLAnchorElement | HTMLButtonElement;
824

25+
/**
26+
* Helper for switching between `<button>`, `<a>`, and `<Link>`
27+
* If providing an `href`, will render as a link instead of a button.
28+
* - Internal links will use react-router.
29+
* - External links should start with 'http' or 'https' and will open in a new window.
30+
*/
931
const ButtonOrLink = React.forwardRef(
10-
({ href, children, isDisabled, onClick, ...props }, ref) => {
11-
const handleClick = (e) => {
32+
(
33+
{
34+
href,
35+
children,
36+
isDisabled = false,
37+
onClick,
38+
...props
39+
}: ButtonOrLinkProps,
40+
ref: React.Ref<Ref>
41+
) => {
42+
const handleClick = (
43+
e: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>
44+
) => {
1245
if (isDisabled) {
1346
e.preventDefault();
1447
e.stopPropagation();
@@ -23,7 +56,7 @@ const ButtonOrLink = React.forwardRef(
2356
if (href.startsWith('http')) {
2457
return (
2558
<a
26-
ref={ref}
59+
ref={ref as React.Ref<HTMLAnchorElement>}
2760
href={href}
2861
target="_blank"
2962
rel="noopener noreferrer"
@@ -37,7 +70,7 @@ const ButtonOrLink = React.forwardRef(
3770
}
3871
return (
3972
<Link
40-
ref={ref}
73+
ref={ref as React.Ref<HTMLAnchorElement>}
4174
to={href}
4275
aria-disabled={isDisabled}
4376
{...props}
@@ -49,7 +82,7 @@ const ButtonOrLink = React.forwardRef(
4982
}
5083
return (
5184
<button
52-
ref={ref}
85+
ref={ref as React.Ref<HTMLButtonElement>}
5386
aria-disabled={isDisabled}
5487
{...props}
5588
onClick={handleClick}
@@ -60,30 +93,4 @@ const ButtonOrLink = React.forwardRef(
6093
}
6194
);
6295

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-
8996
export default ButtonOrLink;

0 commit comments

Comments
 (0)