refactor: button to allow html attributes & refactor class names (#956)

This commit is contained in:
Aman Harwara
2022-03-28 17:41:54 +05:30
committed by GitHub
parent 3ca7102fd0
commit aba1e35a1d
31 changed files with 117 additions and 90 deletions

View File

@@ -1,60 +1,79 @@
import { JSXInternal } from 'preact/src/jsx';
import TargetedEvent = JSXInternal.TargetedEvent;
import TargetedMouseEvent = JSXInternal.TargetedMouseEvent;
import { ComponentChildren, FunctionComponent, Ref } from 'preact';
import { forwardRef } from 'preact/compat';
const baseClass = `rounded px-4 py-1.75 font-bold text-sm fit-content`;
type ButtonType = 'normal' | 'primary' | 'danger';
type ButtonVariant = 'normal' | 'primary';
const buttonClasses: { [type in ButtonType]: string } = {
normal: `${baseClass} bg-default color-text border-solid border-main border-1 focus:bg-contrast hover:bg-contrast`,
primary: `${baseClass} no-border bg-info color-info-contrast hover:brightness-130 focus:brightness-130`,
danger: `${baseClass} bg-default color-danger border-solid border-main border-1 focus:bg-contrast hover:bg-contrast`,
const getClassName = (
variant: ButtonVariant,
danger: boolean,
disabled: boolean
) => {
const borders =
variant === 'normal' ? 'border-solid border-main border-1' : 'no-border';
const cursor = disabled ? 'cursor-not-allowed' : 'cursor-pointer';
let colors =
variant === 'normal'
? 'bg-default color-text'
: 'bg-info color-info-contrast';
let focusHoverStates =
variant === 'normal'
? 'focus:bg-contrast hover:bg-contrast'
: 'hover:brightness-130 focus:brightness-130';
if (danger) {
colors =
variant === 'normal'
? 'bg-default color-danger'
: 'bg-danger color-info-contrast';
}
if (disabled) {
colors =
variant === 'normal'
? 'bg-default color-grey-2'
: 'bg-grey-2 color-info-contrast';
focusHoverStates =
variant === 'normal'
? 'focus:bg-default hover:bg-default'
: 'focus:brightness-default hover:brightness-default';
}
return `${baseClass} ${colors} ${borders} ${focusHoverStates} ${cursor}`;
};
type ButtonProps = {
type ButtonProps = JSXInternal.HTMLAttributes<HTMLButtonElement> & {
children?: ComponentChildren;
className?: string;
type: ButtonType;
variant?: ButtonVariant;
dangerStyle?: boolean;
label?: string;
onClick: (
event:
| TargetedEvent<HTMLFormElement>
| TargetedMouseEvent<HTMLButtonElement>
) => void;
onBlur?: (event: FocusEvent) => void;
disabled?: boolean;
};
export const Button: FunctionComponent<ButtonProps> = forwardRef(
(
{
type,
variant = 'normal',
label,
className = '',
onBlur,
onClick,
dangerStyle: danger = false,
disabled = false,
children,
...props
}: ButtonProps,
ref: Ref<HTMLButtonElement>
) => {
const buttonClass = buttonClasses[type];
const cursorClass = disabled ? 'cursor-default' : 'cursor-pointer';
return (
<button
className={`${buttonClass} ${cursorClass} ${className}`}
onBlur={onBlur}
onClick={(e) => {
onClick(e);
e.preventDefault();
}}
type="button"
className={`${getClassName(variant, danger, disabled)} ${className}`}
disabled={disabled}
ref={ref}
{...props}
>
{label ?? children}
</button>