Untitled

mail@pastecode.io avatar
unknown
plain_text
5 months ago
3.8 kB
1
Indexable
import React from "react";
import styles from "./button.module.scss";


type ButtonVariants = "standard" | "outline" | "icon-outline" | "icon-filled";
type ButtonColorSchema = "primary" | "secondary";
type ButtonSize = "sm" | "md" | "lg";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>{
    children: React.ReactNode;
    variant: ButtonVariants,
    colorSchema?: ButtonColorSchema,
    size?: ButtonSize,
}


type ButtonStates = "IDLE" | "PRESSING" | "PRESSED"  | "RELEASED";
type MouseStates = "IDLE" | "PRESSING" | "RELEASED";
type TransitionStates = "IDLE" | "FORWARD" | "FORWARD_END" | "BACKWARD";

type MouseButtonStates = {
    button: ButtonStates;
    mouse: MouseStates;
    transition: TransitionStates
};
export default function Button({children, variant="standard", colorSchema="primary", size="md"}:ButtonProps): React.ReactElement{
    const buttonRef: React.MutableRefObject<HTMLButtonElement | null> = React.useRef<HTMLButtonElement | null>(null);
    const states:React.MutableRefObject<MouseButtonStates> = React.useRef<MouseButtonStates>(
        {
            button: "IDLE",
            mouse: "IDLE",
            transition: "IDLE"
        }
    );
    const onMouseDown = (): void =>{
        if(states.current.button !== "IDLE"){
            states.current.button = "PRESSING";
            states.current.mouse = "PRESSING";
        }
        else{
            states.current.button = "PRESSING";
            states.current.mouse = "PRESSING";
            states.current.transition = "FORWARD"
            buttonRef.current!.classList.add(styles.press);
        }
        console.debug("onMouseDown", states.current);
    };
    const onMouseUp = (): void =>{

        states.current.mouse = "RELEASED";

        if(states.current.transition === "FORWARD_END"){
            states.current.transition = "BACKWARD";
            buttonRef.current!.classList.remove(styles.press);
        }
        console.debug("onMouseUp", states.current);

    };

    const onTransitionEnd = (event: React.TransitionEvent<HTMLButtonElement>): void =>{
        if (event.propertyName === "scale"){
            if(buttonRef.current!.classList.contains(styles.press)){
                states.current.transition = "FORWARD_END";

                if(states.current.mouse !== "PRESSING"){
                    states.current.transition = "BACKWARD";
                    buttonRef.current!.classList.remove(styles.press);
                }
            }

            else{
                if(states.current.mouse === "PRESSING"){
                    buttonRef.current!.classList.add(styles.press);
                    states.current.transition = "FORWARD"
                    console.log("ADHSDH")
                }
                else{
                    states.current.transition = "IDLE";
                    states.current.button = "IDLE";
                    states.current.mouse = "IDLE";
                }
                console.debug("onTransitionEnd", states.current);


            }

        }
    };

    const onMouseLeave = ()=>{
        states.current.transition = "IDLE";
        states.current.button = "IDLE";
        states.current.mouse = "IDLE";
        if(buttonRef.current!.classList.contains(styles.press)){
            buttonRef.current!.classList.remove(styles.press);
        }
    }
    return (
        <button
            ref={buttonRef}
            onMouseDown={onMouseDown}
            onMouseUp={onMouseUp}
            onTransitionEnd={onTransitionEnd}
            onMouseLeave={onMouseLeave}
            className={[styles['button'], styles[variant], styles[colorSchema], styles[size]].join(" ")}
        >
            {children}
        </button>
    )
}
Leave a Comment