'use client'; import * as React from 'react'; import { ToggleGroup as ToggleGroupPrimitive } from '@base-ui-components/react/toggle-group'; import { Toggle as TogglePrimitive } from '@base-ui-components/react/toggle'; import { type HTMLMotionProps, type Transition, motion, AnimatePresence, } from 'motion/react'; import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@workspace/ui/lib/utils'; const toggleVariants = cva( "cursor-pointer inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:text-muted-foreground text-accent-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[pressed]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none focus:outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap", { variants: { type: { single: '', multiple: 'data-[pressed]:bg-accent', }, variant: { default: 'bg-transparent', outline: 'border border-input bg-transparent shadow-xs', }, size: { default: 'h-9 px-2 min-w-9', sm: 'h-8 px-1.5 min-w-8', lg: 'h-10 px-2.5 min-w-10', }, }, defaultVariants: { variant: 'default', size: 'default', }, }, ); type ToggleGroupContextProps = VariantProps & { type?: 'single' | 'multiple'; transition?: Transition; activeClassName?: string; globalId: string; }; const ToggleGroupContext = React.createContext< ToggleGroupContextProps | undefined >(undefined); const useToggleGroup = (): ToggleGroupContextProps => { const context = React.useContext(ToggleGroupContext); if (!context) { throw new Error('useToggleGroup must be used within a ToggleGroup'); } return context; }; type ToggleGroupProps = React.ComponentProps & Omit, 'type'> & { transition?: Transition; activeClassName?: string; }; function ToggleGroup({ className, variant, size, children, transition = { type: 'spring', bounce: 0, stiffness: 200, damping: 25 }, activeClassName, ...props }: ToggleGroupProps) { const globalId = React.useId(); return ( {children} ); } type ToggleGroupItemProps = Omit< React.ComponentProps, 'render' > & Omit, 'type'> & { children?: React.ReactNode; buttonProps?: HTMLMotionProps<'button'>; spanProps?: React.ComponentProps<'span'>; }; function ToggleGroupItem({ ref, className, children, variant, size, buttonProps, spanProps, ...props }: ToggleGroupItemProps) { const { activeClassName, transition, type, variant: contextVariant, size: contextSize, globalId, } = useToggleGroup(); const itemRef = React.useRef(null); React.useImperativeHandle(ref, () => itemRef.current as HTMLButtonElement); const [isActive, setIsActive] = React.useState(false); React.useEffect(() => { const node = itemRef.current; if (!node) return; const observer = new MutationObserver(() => { setIsActive(node.getAttribute('data-pressed') === ''); }); observer.observe(node, { attributes: true, attributeFilter: ['data-pressed'], }); setIsActive(node.getAttribute('data-pressed') === ''); return () => observer.disconnect(); }, [setIsActive]); return ( {children} {isActive && type === 'single' && ( )} } /> ); } export { ToggleGroup, ToggleGroupItem, type ToggleGroupProps, type ToggleGroupItemProps, };