2
2
3
3
import React from 'react' ;
4
4
5
- import type { DOMProps , QAProps } from '../types' ;
5
+ import { useLinkProps } from '../lab/router/router' ;
6
+ import type { DOMProps , Href , QAProps , RouterOptions } from '../types' ;
6
7
import { block } from '../utils/cn' ;
7
8
import { isIcon , isSvg } from '../utils/common' ;
8
9
import { eventBroker } from '../utils/event-broker' ;
@@ -49,7 +50,7 @@ export interface ButtonProps extends DOMProps, QAProps {
49
50
id ?: string ;
50
51
type ?: 'button' | 'submit' | 'reset' ;
51
52
component ?: React . ElementType ;
52
- href ?: string ;
53
+ href ?: Href ;
53
54
target ?: string ;
54
55
rel ?: string ;
55
56
extraProps ?:
@@ -62,6 +63,7 @@ export interface ButtonProps extends DOMProps, QAProps {
62
63
onBlur ?: React . FocusEventHandler < HTMLButtonElement | HTMLAnchorElement > ;
63
64
/** Button content. You can mix button text with `<Icon/>` component */
64
65
children ?: React . ReactNode ;
66
+ routerOptions ?: RouterOptions ;
65
67
}
66
68
67
69
const b = block ( 'button' ) ;
@@ -79,9 +81,6 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
79
81
tabIndex,
80
82
type = 'button' ,
81
83
component,
82
- href,
83
- target,
84
- rel,
85
84
extraProps,
86
85
onClick,
87
86
onMouseEnter,
@@ -93,6 +92,7 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
93
92
style,
94
93
className,
95
94
qa,
95
+ ...props
96
96
} ,
97
97
ref ,
98
98
) {
@@ -137,37 +137,60 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
137
137
'data-qa' : qa ,
138
138
} ;
139
139
140
- if ( typeof href === 'string' || component ) {
141
- const linkProps = {
142
- href,
143
- target,
144
- rel : target === '_blank' && ! rel ? 'noopener noreferrer' : rel ,
145
- } ;
140
+ const linkProps = useLinkProps ( {
141
+ ...extraProps ,
142
+ ...props ,
143
+ onClick : ( e ) => {
144
+ if ( disabled ) {
145
+ e . preventDefault ( ) ;
146
+ return ;
147
+ }
148
+
149
+ if ( typeof onClick === 'function' ) {
150
+ onClick ( e ) ;
151
+ }
152
+ } ,
153
+ } ) ;
154
+
155
+ if ( component ) {
146
156
return React . createElement (
147
- component || 'a' ,
157
+ component ,
148
158
{
149
159
...extraProps ,
150
160
...commonProps ,
151
- ...( component ? { } : linkProps ) ,
152
- ref : ref as React . Ref < HTMLAnchorElement > ,
161
+ ref,
153
162
'aria-disabled' : disabled || loading ,
154
163
} ,
155
164
prepareChildren ( children ) ,
156
165
) ;
157
- } else {
166
+ }
167
+
168
+ if ( props . href ) {
158
169
return (
159
- < button
160
- { ...( extraProps as React . ButtonHTMLAttributes < HTMLButtonElement > ) }
170
+ < a
171
+ { ...( extraProps as React . ButtonHTMLAttributes < HTMLAnchorElement > ) }
161
172
{ ...commonProps }
162
- ref = { ref as React . Ref < HTMLButtonElement > }
163
- type = { type }
164
- disabled = { disabled || loading }
165
- aria-pressed = { selected }
173
+ { ...linkProps }
174
+ ref = { ref as React . Ref < HTMLAnchorElement > }
175
+ aria-disabled = { disabled || loading }
166
176
>
167
177
{ prepareChildren ( children ) }
168
- </ button >
178
+ </ a >
169
179
) ;
170
180
}
181
+
182
+ return (
183
+ < button
184
+ { ...( extraProps as React . ButtonHTMLAttributes < HTMLButtonElement > ) }
185
+ { ...commonProps }
186
+ ref = { ref as React . Ref < HTMLButtonElement > }
187
+ type = { type }
188
+ disabled = { disabled || loading }
189
+ aria-pressed = { selected }
190
+ >
191
+ { prepareChildren ( children ) }
192
+ </ button >
193
+ ) ;
171
194
} ) ;
172
195
173
196
ButtonWithHandlers . displayName = 'Button' ;
0 commit comments