Spaces:
Runtime error
Runtime error
File size: 2,502 Bytes
db5855f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
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>
);
});
|