1
1
import React from 'react' ;
2
2
import { Link } from 'react-router-dom' ;
3
- import PropTypes from 'prop-types' ;
3
+
4
4
5
5
/**
6
- * Helper for switching between <button>, <a>, and <Link>
6
+ * Accepts all the props of an HTML <a> or <button> tag.
7
7
*/
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
+ } ;
8
24
25
+ type Ref = HTMLAnchorElement | HTMLButtonElement
26
+
27
+ /**
28
+ * Helper for switching between <button>, <a>, and <Link>
29
+ */
9
30
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 > ) => {
12
36
if ( isDisabled ) {
13
37
e . preventDefault ( ) ;
14
38
e . stopPropagation ( ) ;
@@ -23,7 +47,8 @@ const ButtonOrLink = React.forwardRef(
23
47
if ( href . startsWith ( 'http' ) ) {
24
48
return (
25
49
< 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 > }
27
52
href = { href }
28
53
target = "_blank"
29
54
rel = "noopener noreferrer"
@@ -37,7 +62,7 @@ const ButtonOrLink = React.forwardRef(
37
62
}
38
63
return (
39
64
< Link
40
- ref = { ref }
65
+ ref = { ref as React . Ref < HTMLAnchorElement > }
41
66
to = { href }
42
67
aria-disabled = { isDisabled }
43
68
{ ...props }
@@ -49,7 +74,7 @@ const ButtonOrLink = React.forwardRef(
49
74
}
50
75
return (
51
76
< button
52
- ref = { ref }
77
+ ref = { ref as React . Ref < HTMLButtonElement > }
53
78
aria-disabled = { isDisabled }
54
79
{ ...props }
55
80
onClick = { handleClick }
@@ -60,30 +85,4 @@ const ButtonOrLink = React.forwardRef(
60
85
}
61
86
) ;
62
87
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
-
89
88
export default ButtonOrLink ;
0 commit comments