Refactored the `Button` component to accept and spread standard HTML button attributes. This allows developers to add `aria-label`, `aria-expanded`, and other accessibility properties, which were previously ignored. Added unit tests to verify that attributes are correctly passed to the DOM element.
39 lines
908 B
TypeScript
39 lines
908 B
TypeScript
import { type ReactNode, type ButtonHTMLAttributes } from 'react';
|
|
import { motion } from 'motion/react';
|
|
import styles from './Button.module.css';
|
|
|
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
variant?: 'primary' | 'secondary' | 'outline';
|
|
size?: 'sm' | 'md' | 'lg';
|
|
children: ReactNode;
|
|
isLoading?: boolean;
|
|
}
|
|
|
|
export function Button({
|
|
variant = 'primary',
|
|
size = 'md',
|
|
children,
|
|
isLoading,
|
|
className,
|
|
disabled,
|
|
type = 'button',
|
|
...props
|
|
}: ButtonProps) {
|
|
return (
|
|
<motion.button
|
|
type={type}
|
|
className={`${styles.button} ${styles[variant]} ${styles[size]} ${className || ''}`}
|
|
disabled={disabled || isLoading}
|
|
whileHover={{ scale: 1.02 }}
|
|
whileTap={{ scale: 0.98 }}
|
|
{...props}
|
|
>
|
|
{isLoading ? (
|
|
<span className={styles.loader} />
|
|
) : (
|
|
children
|
|
)}
|
|
</motion.button>
|
|
);
|
|
}
|