11import React , { FC , ReactNode , ButtonHTMLAttributes , Ref , useRef } from 'react' ;
22import classnames from 'classnames' ;
3- import { Icon } from './Icon' ;
3+ import { SvgButtonIcon , IconCategory } from './Icon' ;
44import { Spinner } from './Spinner' ;
55import { useEventCallback , useMergeRefs } from './hooks' ;
66
@@ -31,6 +31,7 @@ export type ButtonIconMoreSize = 'x-small' | 'small' | 'medium' | 'large';
3131 */
3232export type ButtonIconProps = {
3333 className ?: string ;
34+ category ?: IconCategory ;
3435 icon : string ;
3536 align ?: ButtonIconAlign ;
3637 size ?: ButtonIconSize ;
@@ -42,33 +43,32 @@ export type ButtonIconProps = {
4243 *
4344 */
4445export const ButtonIcon : FC < ButtonIconProps > = ( {
45- icon,
4646 align,
47- size,
48- inverse,
4947 className,
5048 style,
49+ icon,
50+ category = 'utility' ,
5151 ...props
5252} ) => {
5353 const alignClassName =
5454 align && ICON_ALIGNS . indexOf ( align ) >= 0
5555 ? `slds-button__icon_${ align } `
5656 : null ;
57- const sizeClassName =
58- size && ICON_SIZES . indexOf ( size ) >= 0 ? `slds-button__icon_${ size } ` : null ;
59- const inverseClassName = inverse ? 'slds-button__icon_inverse' : null ;
6057 const iconClassNames = classnames (
6158 'slds-button__icon' ,
6259 alignClassName ,
63- sizeClassName ,
64- inverseClassName ,
6560 className
6661 ) ;
62+
63+ if ( icon . indexOf ( ':' ) > 0 ) {
64+ [ category , icon ] = icon . split ( ':' ) as [ IconCategory , string ] ;
65+ }
66+
6767 return (
68- < Icon
68+ < SvgButtonIcon
6969 className = { iconClassNames }
7070 icon = { icon }
71- textColor = { null }
71+ category = { category }
7272 pointerEvents = 'none'
7373 style = { style }
7474 { ...props }
@@ -118,6 +118,7 @@ export const Button: FC<ButtonProps> = (props) => {
118118 buttonRef : buttonRef_ ,
119119 iconMoreSize : iconMoreSize_ ,
120120 onClick : onClick_ ,
121+ tabIndex,
121122 ...rprops
122123 } = props ;
123124
@@ -135,19 +136,33 @@ export const Button: FC<ButtonProps> = (props) => {
135136 onClick_ ?.( e ) ;
136137 } ) ;
137138
138- const typeClassName = type ? `slds-button_${ type } ` : null ;
139+ const content = children || label ;
140+ const isIconOnly = type && / ^ i c o n - / . test ( type ) && icon && ! content ;
141+
142+ const typeClassName = classnames (
143+ {
144+ 'slds-button_icon' : isIconOnly ,
145+ } ,
146+ type ? `slds-button_${ type } ` : null ,
147+ isIconOnly && iconSize && ICON_SIZES . indexOf ( iconSize ) >= 0
148+ ? `slds-button_icon-${ iconSize } `
149+ : null
150+ ) ;
139151 const btnClassNames = classnames ( className , 'slds-button' , typeClassName , {
140152 'slds-is-selected' : selected ,
153+ [ 'slds-button_icon' ] : / ^ i c o n - / . test ( type ?? '' ) ,
141154 [ `slds-button_icon-${ size ?? '' } ` ] :
142155 / ^ ( x - s m a l l | s m a l l ) $ / . test ( size ?? '' ) && / ^ i c o n - / . test ( type ?? '' ) ,
143156 } ) ;
144157
145- const buttonContent = (
158+ return (
146159 // eslint-disable-next-line react/button-has-type
147160 < button
148161 ref = { buttonRef }
149162 className = { btnClassNames }
150163 type = { htmlType }
164+ title = { isIconOnly || alt ? alt ?? icon : undefined }
165+ tabIndex = { tabIndex ?? - 1 }
151166 { ...rprops }
152167 onClick = { onClick }
153168 >
@@ -159,7 +174,7 @@ export const Button: FC<ButtonProps> = (props) => {
159174 inverse = { inverse }
160175 />
161176 ) : undefined }
162- { children || label }
177+ { content }
163178 { icon && iconAlign === 'right' ? (
164179 < ButtonIcon
165180 icon = { icon }
@@ -171,22 +186,10 @@ export const Button: FC<ButtonProps> = (props) => {
171186 { iconMore ? (
172187 < ButtonIcon icon = { iconMore } align = 'right' size = { iconMoreSize } />
173188 ) : undefined }
174- { alt ? < span className = 'slds-assistive-text' > { alt } </ span > : undefined }
189+ { isIconOnly || alt ? (
190+ < span className = 'slds-assistive-text' > { alt ?? icon } </ span >
191+ ) : undefined }
175192 { loading ? < Spinner /> : undefined }
176193 </ button >
177194 ) ;
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 ;
192195} ;
0 commit comments