'use client'; import { useEffect, useRef } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { PRESETS, PRESET_CATEGORIES } from '@/lib/animate/presets'; import { buildKeyframesOnly } from '@/lib/animate/cssBuilder'; import type { AnimationConfig, AnimationPreset } from '@/types/animate'; interface Props { onSelect: (config: AnimationConfig) => void; } function PresetCard({ preset, onSelect }: { preset: AnimationPreset; onSelect: () => void; }) { const styleRef = useRef(null); const animName = `preview-${preset.id}`; // Inject only the @keyframes block under a unique name — no .animated class rule useEffect(() => { const renamedConfig = { ...preset.config, name: animName }; if (!styleRef.current) { styleRef.current = document.createElement('style'); document.head.appendChild(styleRef.current); } styleRef.current.textContent = buildKeyframesOnly(renamedConfig); return () => { styleRef.current?.remove(); styleRef.current = null; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Cap thumbnail duration so fast presets loop nicely; slow ones cap at 1.2s const thumbDuration = Math.min(preset.config.duration, 1200); return ( ); } export function PresetLibrary({ onSelect }: Props) { return ( Presets {PRESET_CATEGORIES.map((cat) => ( {cat} ))} {PRESET_CATEGORIES.map((cat) => (
{PRESETS.filter((p) => p.category === cat).map((preset) => ( onSelect(preset.config)} /> ))}
))}
); }