video-flow-b/components/ui/glass-icon-button.tsx
2025-06-30 12:48:25 +08:00

73 lines
2.0 KiB
TypeScript

'use client';
import React, { forwardRef } from 'react';
import { motion } from 'framer-motion';
import { LucideIcon } from 'lucide-react';
import { cn } from '@/public/lib/utils';
// Define props without the ref
interface GlassIconButtonProps {
icon: LucideIcon;
tooltip?: string;
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
className?: string;
[key: string]: any; // To allow spreading other props
}
const variantStyles = {
primary: 'bg-blue-500/10 hover:bg-blue-500/20 border-blue-500/20',
secondary: 'bg-white/10 hover:bg-white/20 border-white/20',
danger: 'bg-red-500/10 hover:bg-red-500/20 border-red-500/20',
};
const sizeStyles = {
sm: 'p-2',
md: 'p-3',
lg: 'p-4',
};
const iconSizes = {
sm: 'w-4 h-4',
md: 'w-5 h-5',
lg: 'w-6 h-6',
};
// Create a motion button with forwardRef
const MotionButton = motion.button;
export const GlassIconButton = forwardRef<HTMLButtonElement, GlassIconButtonProps>(
({ icon: Icon, tooltip, variant = 'secondary', size = 'md', className, ...props }, ref) => {
return (
<MotionButton
ref={ref}
className={cn(
'relative rounded-full backdrop-blur-md transition-colors shadow-lg border',
variantStyles[variant],
sizeStyles[size],
className
)}
whileHover={{
scale: 1.05,
rotateX: 10,
translateZ: 10
}}
whileTap={{ scale: 0.95 }}
style={{
transformStyle: 'preserve-3d',
perspective: '1000px'
}}
{...props}
>
<Icon className={cn('text-white', iconSizes[size])} />
{tooltip && (
<div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 text-xs
bg-black/80 text-white rounded-md opacity-0 group-hover:opacity-100 transition-opacity
pointer-events-none whitespace-nowrap">
{tooltip}
</div>
)}
</MotionButton>
);
}
);