import { ReactNode, createContext, useContext } from 'react'; import clsx from 'clsx'; import { cva, type VariantProps } from 'class-variance-authority'; import { StatusDot, type StatusDotColor } from '@@/primitives/StatusDot'; const containerVariants = cva( 'flex min-w-[6rem] flex-col gap-1 rounded-md border border-solid px-3 py-2', { variants: { status: { success: 'border-green-4 bg-green-2 th-dark:border-green-8 th-dark:bg-green-10 th-highcontrast:border-white th-highcontrast:bg-green-10', danger: 'border-error-4 bg-error-2 th-dark:border-error-8 th-dark:bg-error-10 th-highcontrast:border-white th-highcontrast:bg-error-10', warning: 'border-warning-4 bg-warning-2 th-dark:border-warning-8 th-dark:bg-warning-10 th-highcontrast:border-white th-highcontrast:bg-warning-10', pending: 'border-blue-4 bg-blue-2 th-dark:border-blue-8 th-dark:bg-blue-10 th-highcontrast:border-white th-highcontrast:bg-blue-10', muted: 'border-gray-4 bg-gray-2 th-dark:border-gray-8 th-dark:bg-gray-iron-10 th-highcontrast:border-gray-11 th-highcontrast:bg-transparent', }, }, defaultVariants: { status: 'muted' }, } ); const valueVariants = cva('font-semibold leading-tight', { variants: { status: { success: 'text-green-8 th-dark:text-white th-highcontrast:text-white', danger: 'text-error-8 th-dark:text-white th-highcontrast:text-white', warning: 'text-warning-8 th-dark:text-white th-highcontrast:text-white', pending: 'text-blue-8 th-dark:text-white th-highcontrast:text-white', muted: 'text-graphite-700 th-dark:text-white th-highcontrast:text-white', }, size: { xs: 'text-xs', sm: 'text-sm', base: 'text-base', lg: 'text-lg', }, }, defaultVariants: { status: 'muted', size: 'xs' }, }); const statusToColor: Record = { success: 'success', danger: 'danger', warning: 'warn', pending: 'info', muted: 'muted', }; export type ResourceStatBlockStatus = NonNullable< VariantProps['status'] >; const StatusContext = createContext('muted'); interface RootProps { status?: ResourceStatBlockStatus; children: ReactNode; 'data-cy'?: string; } export function ResourceStatBlock({ status = 'muted', children, 'data-cy': dataCy, }: RootProps) { return (
{children}
); } interface LabelProps { icon?: ReactNode; children: ReactNode; } function StatBlockLabel({ icon, children }: LabelProps) { return (
{icon && } {children}
); } const valueAlignClasses = { start: 'justify-start', center: 'justify-center', end: 'justify-end', } as const; interface ValueProps { dot?: boolean; suffix?: ReactNode; size?: NonNullable['size']>; align?: keyof typeof valueAlignClasses; children: ReactNode; } function StatBlockValue({ dot, suffix, size = 'xs', align = 'start', children, }: ValueProps) { const status = useContext(StatusContext); return (
{dot && ( )} {children} {suffix && ( {suffix} )}
); } interface MetaProps { children: ReactNode; } function StatBlockMeta({ children }: MetaProps) { return ( {children} ); } ResourceStatBlock.Label = StatBlockLabel; ResourceStatBlock.Value = StatBlockValue; ResourceStatBlock.Meta = StatBlockMeta;