Files
DABEEO-DETECTION-APPLICATION/web-app/app/shared/components/button/Button.tsx

148 lines
5.6 KiB
TypeScript

import type { ButtonProps as AriaButtonProps } from 'react-aria-components';
import { Button as AriaButton, composeRenderProps } from 'react-aria-components';
import { tv } from 'tailwind-variants';
import { LoadingSpinnerIcon } from '../icons/LoadingSpinner';
export interface ButtonProps extends AriaButtonProps {
color?: 'primary' | 'light' | 'green' | 'lightGreen' | 'black' | 'gray' | 'orange' | 'navy' | 'lightNavy';
size?: 'small' | 'medium' | 'large';
stopPropagation?: boolean;
}
const button = tv({
base: 'relative inline-flex items-center justify-center gap-2 border cursor-pointer box-border data-focus-visible:ring-2 ring-offset-2',
variants: {
size: {
small: 'h-6 px-3 text-xs font-medium',
medium: 'h-9 px-3 text-xs font-medium',
large: 'min-w-30 h-13 px-5 text-sm font-semibold',
},
color: {
primary: 'text-white bg-primary border-primary disabled:bg-dabeeo-gray-be disabled:border-dabeeo-gray-be ring-primary',
light:
'text-primary border-primary bg-primary-tertiary02 disabled:text-dabeeo-gray-99 disabled:bg-dabeeo-gray-eb disabled:border-dabeeo-gray-be ring-primary',
green:
'text-white bg-dabeeo-green-main border-dabeeo-green-main disabled:bg-dabeeo-gray-be disabled:border-dabeeo-gray-be ring-dabeeo-green-main',
lightGreen:
'text-dabeeo-green-main border-dabeeo-green-main bg-dabeeo-green-tertiary02 disabled:text-dabeeo-gray-99 disabled:bg-dabeeo-gray-eb disabled:border-dabeeo-gray-be ring-dabeeo-green-main',
black:
'text-white bg-dabeeo-black-34 border-dabeeo-black-34 disabled:bg-dabeeo-gray-be disabled:border-dabeeo-gray-be ring-dabeeo-black-34',
gray: 'text-dabeeo-black-34 bg-dabeeo-gray-eb border-dabeeo-black-34 disabled:text-dabeeo-gray-99 disabled:bg-dabeeo-gray-eb disabled:border-dabeeo-gray-be ring-dabeeo-black-34',
orange:
'text-dabeeo-orange-main bg-dabeeo-orange-tertiary01 border-dabeeo-orange-main disabled:text-dabeeo-gray-99 disabled:bg-dabeeo-gray-eb disabled:border-dabeeo-gray-be ring-dabeeo-orange-main',
navy: 'text-white bg-dabeeo-navy-main border-dabeeo-navy-main disabled:bg-dabeeo-gray-be disabled:border-dabeeo-gray-be ring-dabeeo-navy-main',
lightNavy:
'text-dabeeo-navy-main border-dabeeo-navy-main bg-dabeeo-navy-tertiary02 disabled:text-dabeeo-gray-99 disabled:bg-dabeeo-gray-eb disabled:border-dabeeo-gray-be ring-dabeeo-navy-main',
},
isDisabled: {
true: 'cursor-not-allowed',
},
isPending: {
true: 'text-transparent cursor-progress',
},
},
compoundVariants: [
{
color: 'primary',
isDisabled: false,
isPending: false,
className:
'hover:border-primary-tertiary hover:bg-primary-tertiary active:bg-primary-secondary active:border-primary-secondary',
},
{
color: 'light',
isDisabled: false,
isPending: false,
className:
'hover:bg-primary-tertiary01 active:text-primary-secondary active:bg-primary-tertiary01 active:border-primary-secondary',
},
{
color: 'green',
isDisabled: false,
isPending: false,
className:
'hover:bg-dabeeo-green-tertiary hover:border-dabeeo-green-tertiary active:bg-dabeeo-green-secondary active:border-dabeeo-green-secondary',
},
{
color: 'lightGreen',
isDisabled: false,
isPending: false,
className:
'hover:bg-dabeeo-green-tertiary01 active:text-dabeeo-green-secondary active:bg-dabeeo-green-tertiary01 active:border-dabeeo-green-secondary',
},
{
color: 'black',
isDisabled: false,
isPending: false,
className: 'hover:bg-dabeeo-black-47 hover:border-dabeeo-black-47 active:bg-dabeeo-black-22 active:border-dabeeo-black-22',
},
{
color: 'gray',
isDisabled: false,
isPending: false,
className:
'hover:bg-dabeeo-gray-da hover:border-dabeeo-black-47 active:text-dabeeo-black-22 active:bg-dabeeo-gray-da active:border-dabeeo-black-22',
},
{
color: 'orange',
isDisabled: false,
isPending: false,
className:
'hover:bg-dabeeo-orange-tertiary02 active:text-dabeeo-orange-secondary active:bg-dabeeo-orange-tertiary02 active:border-dabeeo-orange-secondary',
},
{
color: 'navy',
isDisabled: false,
isPending: false,
className:
'hover:border-dabeeo-navy-tertiary hover:bg-dabeeo-navy-tertiary active:bg-dabeeo-navy-secondary active:border-dabeeo-navy-secondary',
},
{
color: 'lightNavy',
isDisabled: false,
isPending: false,
className:
'hover:bg-dabeeo-navy-tertiary01 active:text-dabeeo-navy-secondary active:bg-dabeeo-navy-tertiary01 active:border-dabeeo-navy-secondary',
},
],
});
export const Button = (props: ButtonProps) => {
const {
className,
onClick,
color = 'primary',
size = 'medium',
children,
stopPropagation = false,
...restProps
} = props;
return (
<AriaButton
className={composeRenderProps(className, (className, renderProps) => {
return button({ ...renderProps, color, size, className });
})}
onClick={(e) => {
if (stopPropagation) {
e.stopPropagation();
}
onClick?.(e);
}}
{...restProps}
>
{composeRenderProps(children, (children, { isPending }) => (
<>
{children}
{isPending && (
<span aria-hidden className="flex absolute inset-0 justify-center items-center">
<LoadingSpinnerIcon className="w-4 h-4 text-white animate-spin" />
</span>
)}
</>
))}
</AriaButton>
);
};