import { cva, VariantProps } from 'class-variance-authority'; import * as React from 'react'; import { cn, ComponentAnatomy, defineStyleAnatomy } from '../core/styling'; /* ------------------------------------------------------------------------------------------------- * Anatomy * -----------------------------------------------------------------------------------------------*/ export const ButtonAnatomy = defineStyleAnatomy({ root: cva( [ 'UI-Button_root', 'shadow-sm whitespace-nowrap font-semibold rounded-[--radius]', 'inline-flex items-center text-white transition ease-in text-center text-base justify-center', 'focus-visible:outline-none focus-visible:ring-2 ring-offset-1 ring-offset-[--background] focus-visible:ring-[--ring]', 'disabled:opacity-50 disabled:pointer-events-none', ], { variants: { intent: { primary: 'bg-brand-500 hover:bg-brand-600 active:bg-brand-700 border border-transparent', 'primary-outline': 'text-[--brand] border border-[--brand] bg-transparent hover:bg-brand-500 active:bg-brand-600 active:border-transparent hover:text-white dark:hover:border-brand-500 dark:active:bg-brand-600 dark:hover:text-white dark:active:border-transparent dark:active:text-white', 'primary-subtle': 'shadow-none text-[--brand] border bg-brand-50 border-transparent hover:bg-brand-100 active:bg-brand-200 dark:bg-opacity-10 dark:hover:bg-opacity-20', 'primary-link': 'shadow-none text-[--brand] border border-transparent bg-transparent hover:underline active:text-brand-700 dark:active:text-brand-300', 'primary-basic': 'shadow-none text-[--brand] border border-transparent bg-transparent hover:bg-brand-100 active:bg-brand-200 dark:hover:bg-opacity-10 dark:active:text-brand-300', warning: 'bg-orange-500 hover:bg-orange-600 active:bg-orange-700 border border-transparent', 'warning-outline': 'text-[--orange] border border-[--orange] bg-transparent hover:bg-orange-500 active:bg-orange-600 active:border-transparent hover:text-white dark:hover:border-orange-500 dark:active:bg-orange-600 dark:hover:text-white dark:active:border-transparent dark:active:text-white', 'warning-subtle': 'shadow-none text-[--orange] border bg-orange-50 border-transparent hover:bg-orange-100 active:bg-orange-200 dark:bg-opacity-10 dark:hover:bg-opacity-20', 'warning-link': 'shadow-none text-[--orange] border border-transparent bg-transparent hover:underline active:text-orange-700 dark:active:text-orange-300', 'warning-basic': 'shadow-none text-[--orange] border border-transparent bg-transparent hover:bg-orange-100 active:bg-orange-200 dark:hover:bg-opacity-10 dark:active:text-orange-300', success: 'bg-green-500 hover:bg-green-600 active:bg-green-700 border border-transparent', 'success-outline': 'text-[--green] border border-[--green] bg-transparent hover:bg-green-500 active:bg-green-600 active:border-transparent hover:text-white dark:hover:border-green-500 dark:active:bg-green-600 dark:hover:text-white dark:active:border-transparent dark:active:text-white', 'success-subtle': 'shadow-none text-[--green] border bg-green-50 border-transparent hover:bg-green-100 active:bg-green-200 dark:bg-opacity-10 dark:hover:bg-opacity-20', 'success-link': 'shadow-none text-[--green] border border-transparent bg-transparent hover:underline active:text-green-700 dark:active:text-green-300', 'success-basic': 'shadow-none text-[--green] border border-transparent bg-transparent hover:bg-green-100 active:bg-green-200 dark:hover:bg-opacity-10 dark:active:text-green-300', alert: 'bg-red-500 hover:bg-red-600 active:bg-red-700 border border-transparent', 'alert-outline': 'text-[--red] border border-[--red] bg-transparent hover:bg-red-500 active:bg-red-600 active:border-transparent hover:text-white dark:hover:border-red-500 dark:active:bg-red-600 dark:hover:text-white dark:active:border-transparent dark:active:text-white', 'alert-subtle': 'shadow-none text-[--red] border bg-red-50 border-transparent hover:bg-red-100 active:bg-red-200 dark:bg-opacity-10 dark:hover:bg-opacity-20', 'alert-link': 'shadow-none text-[--red] border border-transparent bg-transparent hover:underline active:text-red-700 dark:active:text-red-300', 'alert-basic': 'shadow-none text-[--red] border border-transparent bg-transparent hover:bg-red-100 active:bg-red-200 dark:hover:bg-opacity-10 dark:active:text-red-300', gray: 'bg-gray-500 hover:bg-gray-600 active:bg-gray-700 border border-transparent', 'gray-outline': 'text-gray-600 border bg-transparent hover:bg-gray-100 active:border-transparent active:bg-gray-200 dark:text-gray-300 dark: dark:hover:bg-gray-800 dark:hover:bg-opacity-50 dark:active:bg-gray-700 dark:active:border-transparent dark:hover:text-gray-100', 'gray-subtle': 'shadow-none text-[--gray] border bg-gray-100 border-transparent hover:bg-gray-200 active:bg-gray-300 dark:text-gray-300 dark:bg-opacity-10 dark:hover:bg-opacity-20', 'gray-link': 'shadow-none text-[--gray] border border-transparent bg-transparent hover:underline active:text-gray-700 dark:text-gray-300 dark:active:text-gray-200', 'gray-basic': 'shadow-none text-[--gray] border border-transparent bg-transparent hover:bg-gray-100 active:bg-gray-200 dark:active:bg-opacity-20 dark:text-gray-200 dark:hover:bg-opacity-10 dark:active:text-gray-200', white: 'text-[#000] bg-white hover:bg-gray-200 active:bg-gray-300 border border-transparent', 'white-outline': 'text-white border border-gray-200 bg-transparent hover:bg-white hover:text-black active:bg-gray-100 active:text-[#000]', 'white-subtle': 'shadow-none text-white bg-white bg-opacity-15 hover:bg-opacity-20 border border-transparent active:bg-opacity-25', 'white-link': 'shadow-none text-white border border-transparent bg-transparent hover:underline active:text-gray-200', 'white-basic': 'shadow-none text-white border border-transparent bg-transparent hover:bg-white hover:bg-opacity-15 active:bg-opacity-20 active:text-white-300', }, rounded: { true: 'rounded-full', false: null, }, contentWidth: { true: 'w-fit', false: null, }, size: { xs: 'text-sm h-6 px-2', sm: 'text-sm h-8 px-3', md: 'text-sm h-10 px-4', lg: 'h-12 px-6 text-lg', xl: 'text-2xl h-14 px-8', }, }, defaultVariants: { intent: 'primary', size: 'md', }, } ), icon: cva(['UI-Button__icon', 'inline-flex self-center flex-shrink-0']), }); /* ------------------------------------------------------------------------------------------------- * Button * -----------------------------------------------------------------------------------------------*/ export type ButtonProps = React.ComponentPropsWithoutRef<'button'> & VariantProps & ComponentAnatomy & { loading?: boolean; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; iconSpacing?: React.CSSProperties['marginInline']; hideTextOnSmallScreen?: boolean; hideTextOnLargeScreen?: boolean; }; export const Button = React.forwardRef( (props, ref) => { const { children, size, className, rounded = false, contentWidth = false, intent, leftIcon, rightIcon, iconSpacing = '0.5rem', loading, iconClass, disabled, hideTextOnSmallScreen, hideTextOnLargeScreen, ...rest } = props; return ( ); } ); Button.displayName = 'Button';