1
1
import React , { FC , ReactNode , ButtonHTMLAttributes , Ref , useRef } from 'react' ;
2
2
import classnames from 'classnames' ;
3
- import { Icon } from './Icon' ;
3
+ import { SvgIcon , IconCategory } from './Icon' ;
4
4
import { Spinner } from './Spinner' ;
5
5
import { useEventCallback , useMergeRefs } from './hooks' ;
6
6
7
7
export type ButtonType =
8
8
| 'neutral'
9
9
| 'brand'
10
+ | 'outline-brand'
10
11
| 'destructive'
12
+ | 'text-destructive'
13
+ | 'success'
11
14
| 'inverse'
12
15
| 'icon'
13
- | 'icon-bare'
14
16
| 'icon-container'
15
17
| 'icon-inverse'
16
18
| 'icon-more'
@@ -31,6 +33,7 @@ export type ButtonIconMoreSize = 'x-small' | 'small' | 'medium' | 'large';
31
33
*/
32
34
export type ButtonIconProps = {
33
35
className ?: string ;
36
+ category ?: IconCategory ;
34
37
icon : string ;
35
38
align ?: ButtonIconAlign ;
36
39
size ?: ButtonIconSize ;
@@ -43,9 +46,9 @@ export type ButtonIconProps = {
43
46
*/
44
47
export const ButtonIcon : FC < ButtonIconProps > = ( {
45
48
icon,
49
+ category = 'utility' ,
46
50
align,
47
51
size,
48
- inverse,
49
52
className,
50
53
style,
51
54
...props
@@ -56,19 +59,22 @@ export const ButtonIcon: FC<ButtonIconProps> = ({
56
59
: null ;
57
60
const sizeClassName =
58
61
size && ICON_SIZES . indexOf ( size ) >= 0 ? `slds-button__icon_${ size } ` : null ;
59
- const inverseClassName = inverse ? 'slds-button__icon_inverse' : null ;
60
62
const iconClassNames = classnames (
61
63
'slds-button__icon' ,
62
64
alignClassName ,
63
65
sizeClassName ,
64
- inverseClassName ,
65
66
className
66
67
) ;
68
+
69
+ if ( icon . indexOf ( ':' ) > 0 ) {
70
+ [ category , icon ] = icon . split ( ':' ) as [ IconCategory , string ] ;
71
+ }
72
+
67
73
return (
68
- < Icon
74
+ < SvgIcon
69
75
className = { iconClassNames }
70
76
icon = { icon }
71
- textColor = { null }
77
+ category = { category }
72
78
pointerEvents = 'none'
73
79
style = { style }
74
80
{ ...props }
@@ -118,6 +124,7 @@ export const Button: FC<ButtonProps> = (props) => {
118
124
buttonRef : buttonRef_ ,
119
125
iconMoreSize : iconMoreSize_ ,
120
126
onClick : onClick_ ,
127
+ tabIndex,
121
128
...rprops
122
129
} = props ;
123
130
@@ -135,19 +142,24 @@ export const Button: FC<ButtonProps> = (props) => {
135
142
onClick_ ?.( e ) ;
136
143
} ) ;
137
144
145
+ const content = children || label ;
146
+ const isIconOnly = type && / ^ i c o n - / . test ( type ) && icon && ! content ;
147
+
138
148
const typeClassName = type ? `slds-button_${ type } ` : null ;
139
149
const btnClassNames = classnames ( className , 'slds-button' , typeClassName , {
140
150
'slds-is-selected' : selected ,
151
+ [ 'slds-button_icon' ] : / ^ i c o n - / . test ( type ?? '' ) ,
141
152
[ `slds-button_icon-${ size ?? '' } ` ] :
142
153
/ ^ ( x - s m a l l | s m a l l ) $ / . test ( size ?? '' ) && / ^ i c o n - / . test ( type ?? '' ) ,
143
154
} ) ;
144
155
145
- const buttonContent = (
146
- // eslint-disable-next-line react/button-has-type
156
+ return (
147
157
< button
148
158
ref = { buttonRef }
149
159
className = { btnClassNames }
150
160
type = { htmlType }
161
+ title = { isIconOnly || alt ? alt : undefined }
162
+ tabIndex = { tabIndex ?? - 1 }
151
163
{ ...rprops }
152
164
onClick = { onClick }
153
165
>
@@ -159,7 +171,7 @@ export const Button: FC<ButtonProps> = (props) => {
159
171
inverse = { inverse }
160
172
/>
161
173
) : undefined }
162
- { children || label }
174
+ { content }
163
175
{ icon && iconAlign === 'right' ? (
164
176
< ButtonIcon
165
177
icon = { icon }
@@ -171,22 +183,10 @@ export const Button: FC<ButtonProps> = (props) => {
171
183
{ iconMore ? (
172
184
< ButtonIcon icon = { iconMore } align = 'right' size = { iconMoreSize } />
173
185
) : undefined }
174
- { alt ? < span className = 'slds-assistive-text' > { alt } </ span > : undefined }
186
+ { isIconOnly || alt ? (
187
+ < span className = 'slds-assistive-text' > { alt ?? icon } </ span >
188
+ ) : undefined }
175
189
{ loading ? < Spinner /> : undefined }
176
190
</ button >
177
191
) ;
178
-
179
- if ( props . tabIndex != null ) {
180
- return (
181
- < span
182
- className = 'react-slds-button-focus-wrapper'
183
- style = { { outline : 0 } }
184
- tabIndex = { - 1 }
185
- >
186
- { buttonContent }
187
- </ span >
188
- ) ;
189
- }
190
-
191
- return buttonContent ;
192
192
} ;
0 commit comments