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>

  );

});