import React, { createContext, useContext } from 'react'; import { Tag as AriaTag, TagGroup as AriaTagGroup, type TagGroupProps as AriaTagGroupProps, type TagProps as AriaTagProps, Button, TagList, type TagListProps, Text, composeRenderProps, } from 'react-aria-components'; import { twMerge } from 'tailwind-merge'; import { tv } from 'tailwind-variants'; import { Description, Label } from '../Field/Field.quanta'; import { focusRing } from '../utils'; import { CloseIcon } from '../icons'; const colors = { gray: 'bg-quanta-silver text-foreground border-gray-200 hover:border-gray-300 ', green: 'bg-green-100 text-green-700 border-green-200 hover:border-green-300 ', yellow: 'bg-yellow-100 text-yellow-700 border-yellow-200 hover:border-yellow-300 ', blue: 'bg-blue-100 text-blue-700 border-blue-200 hover:border-blue-300', }; type Color = keyof typeof colors; const ColorContext = createContext('gray'); const tagStyles = tv({ extend: focusRing, base: ` text-md flex max-w-fit cursor-default items-center gap-1 rounded-sm border px-3 py-0.5 transition `, variants: { color: { gray: '', green: '', yellow: '', blue: '', }, allowsRemoving: { true: 'pr-1', }, isSelected: { true: 'border-transparent', }, isDisabled: { true: 'bg-quanta-pigeon text-gray-300', }, }, compoundVariants: (Object.keys(colors) as Color[]).map((color) => ({ isSelected: false, isDisabled: false, color, class: colors[color], })), }); export interface TagGroupProps extends Omit, Pick, 'items' | 'children' | 'renderEmptyState'> { color?: Color; label?: string; description?: string; errorMessage?: string; } export interface TagProps extends AriaTagProps { color?: Color; } export function TagGroup({ label, description, errorMessage, items, children, renderEmptyState, ...props }: TagGroupProps) { return ( {children} {description && {description}} {errorMessage && ( {errorMessage} )} ); } const removeButtonStyles = tv({ extend: focusRing, base: ` flex cursor-default items-center justify-center rounded-full p-0.5 transition-[background-color] `, }); export function Tag({ children, color, ...props }: TagProps) { const textValue = typeof children === 'string' ? children : undefined; const groupColor = useContext(ColorContext); return ( tagStyles({ ...renderProps, className, color: color || groupColor }), )} > {({ allowsRemoving }) => ( <> {children} {allowsRemoving && ( )} )} ); }