Spaces:
Runtime error
Runtime error
| import './Button.scss'; | |
| import { AnchorHTMLAttributes, ButtonHTMLAttributes, forwardRef, FunctionComponent, SVGProps } from 'react'; | |
| const sparkClassNames = { | |
| button: 'spark-button spark-focus-visible spark-focus-visible-self spark-focus-visible-snap', | |
| buttonSizePrefix: 'spark-button-size-', | |
| buttonVariantPrefix: 'spark-button-', | |
| disabledButton: 'spark-button-disabled', | |
| buttonStartSlot: 'spark-button-start-slot', | |
| buttonContent: 'spark-button-content', | |
| buttonOnly: 'spark-button-icon-only', | |
| }; | |
| type ButtonVariant = 'action' | 'primary' | 'secondary' | 'ghost'; | |
| type ButtonSize = 'l' | 'm' | 's'; | |
| type AsElementProps = | |
| | (ButtonHTMLAttributes<HTMLButtonElement> & { as?: 'button' }) | |
| | (AnchorHTMLAttributes<HTMLAnchorElement> & { as?: 'link' }); | |
| type ButtonProps = { | |
| text?: string; | |
| variant?: ButtonVariant; | |
| size?: ButtonSize; | |
| disabled?: boolean; | |
| value?: string; | |
| onClick?: () => void; | |
| icon?: FunctionComponent<SVGProps<SVGSVGElement>>; | |
| className?: string; | |
| } & AsElementProps; | |
| export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button( | |
| { text, as = 'button', variant = 'primary', size = 'm', disabled = false, onClick, icon, className, ...props }, | |
| ref | |
| ): JSX.Element { | |
| const sizeClassName = `${sparkClassNames.buttonSizePrefix}${size}`; | |
| const variantClassName = `${sparkClassNames.buttonVariantPrefix}${variant}`; | |
| const classNames = [sparkClassNames.button, sizeClassName, variantClassName]; | |
| if (disabled) { | |
| classNames.push(sparkClassNames.disabledButton); | |
| } | |
| if (!text && icon) { | |
| classNames.push(sparkClassNames.buttonOnly); | |
| } | |
| if (className) { | |
| classNames.push(className); | |
| } | |
| const buttonContent = ( | |
| <> | |
| {icon && <span className={sparkClassNames.buttonStartSlot}>{icon({ className: 'button-icon' })}</span>} | |
| <span className={sparkClassNames.buttonContent}>{text}</span> | |
| </> | |
| ); | |
| if (as === 'link') { | |
| return ( | |
| <a | |
| className={classNames.join(' ')} | |
| href={(props as AnchorHTMLAttributes<HTMLAnchorElement>).href} | |
| target="_blank" | |
| rel="noreferrer" | |
| aria-label={text} | |
| > | |
| {buttonContent} | |
| </a> | |
| ); | |
| } | |
| return ( | |
| <button | |
| className={classNames.join(' ')} | |
| type="button" | |
| role="radio" | |
| onClick={(e) => onClick?.(e)} | |
| aria-label={text} | |
| ref={ref} | |
| > | |
| {buttonContent} | |
| </button> | |
| ); | |
| }); | |