Theme Card (components/Editor/theme-card.tsx)¶
Overview¶
A card component for displaying and managing individual themes, featuring expandable views, editing capabilities, and smooth animations. The component supports theme selection, editing, and deletion with interactive UI elements.
Features¶
- Expandable views
- Theme editing
- Interactive UI
- Smooth animations
- State management
Dependencies¶
import { useState } from 'react'
import { motion } from 'framer-motion'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
Props¶
interface ThemeCardProps {
id: string;
name: string;
description: string;
onUpdate: (id: string, name: string, description: string) => void;
onDelete: (id: string) => void;
onExpand: (id: string) => void;
onCollapse: (id: string) => void;
onSelect: (id: string) => void;
isSelected: boolean;
}
Implementation¶
State Management¶
const [isEditing, setIsEditing] = useState(false);
const [isExpanded, setIsExpanded] = useState(false);
const [themeName, setThemeName] = useState(name);
const [themeDescription, setThemeDescription] = useState(description);
Methods¶
const handleSave = () => {
onUpdate(id, themeName, themeDescription);
setIsEditing(false);
};
const handleExpand = () => {
setIsExpanded(true);
onExpand(id);
};
const handleCollapse = () => {
setIsExpanded(false);
onCollapse(id);
};
Unique Functionality¶
HTML Structure¶
<Card className={`relative transition-all duration-300 ${isExpanded ? 'h-auto' : 'h-24'}`}>
<CardContent className="p-4">
<div className="flex justify-between items-center">
{isEditing ? (
<Input
value={themeName}
onChange={(e) => setThemeName(e.target.value)}
className="w-full"
/>
) : (
<h3 className="text-lg font-semibold">{name}</h3>
)}
<div className="flex space-x-2">
<Button onClick={() => setIsEditing(!isEditing)}>
{isEditing ? 'Cancel' : 'Edit'}
</Button>
{isEditing && (
<Button onClick={handleSave}>Save</Button>
)}
</div>
</div>
{isExpanded && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
>
{isEditing ? (
<Textarea
value={themeDescription}
onChange={(e) => setThemeDescription(e.target.value)}
className="mt-4"
/>
) : (
<p className="mt-4">{description}</p>
)}
</motion.div>
)}
</CardContent>
</Card>
API Integration¶
- Not applicable for this component
Components Used¶
Notes¶
- Features expandable content
- Supports theme editing
- Uses smooth animations
- Maintains state consistency
- Provides user feedback