'use client'; import * as React from 'react'; import { type HTMLMotionProps, type Transition, type Variant, motion, } from 'motion/react'; import { cn } from '@workspace/ui/lib/utils'; type FlipDirection = 'top' | 'bottom' | 'left' | 'right'; type FlipButtonProps = HTMLMotionProps<'button'> & { frontText: string; backText: string; transition?: Transition; frontClassName?: string; backClassName?: string; from?: FlipDirection; }; const DEFAULT_SPAN_CLASS_NAME = 'absolute inset-0 flex items-center justify-center rounded-lg'; function FlipButton({ frontText, backText, transition = { type: 'spring', stiffness: 280, damping: 20 }, className, frontClassName, backClassName, from = 'top', ...props }: FlipButtonProps) { const isVertical = from === 'top' || from === 'bottom'; const rotateAxis = isVertical ? 'rotateX' : 'rotateY'; const frontOffset = from === 'top' || from === 'left' ? '50%' : '-50%'; const backOffset = from === 'top' || from === 'left' ? '-50%' : '50%'; const buildVariant = ( opacity: number, rotation: number, offset: string | null = null, ): Variant => ({ opacity, [rotateAxis]: rotation, ...(isVertical && offset !== null ? { y: offset } : {}), ...(!isVertical && offset !== null ? { x: offset } : {}), }); const frontVariants = { initial: buildVariant(1, 0, '0%'), hover: buildVariant(0, 90, frontOffset), }; const backVariants = { initial: buildVariant(0, 90, backOffset), hover: buildVariant(1, 0, '0%'), }; return ( {frontText} {backText} {frontText} ); } export { FlipButton, type FlipButtonProps, type FlipDirection };