Interactive states for UI elements - hover, active, focus, disabled, loading. Use when implementing button states, form field states, or interactive feedback.
View on GitHubFebruary 2, 2026
Select agents to install to:
npx add-skill https://github.com/fusengine/agents/blob/main/plugins/design-expert/skills/interactive-states/SKILL.md -a claude-code --skill interactive-statesInstallation paths:
.claude/skills/interactive-states/# Interactive States
Complete state system for interactive elements.
## Agent Workflow (MANDATORY)
Before implementation:
1. **fuse-ai-pilot:explore-codebase** - Check existing state patterns
2. **fuse-ai-pilot:research-expert** - Framer Motion state animations
After: Run **fuse-ai-pilot:sniper** for validation.
## State Flow
```
Default → Hover → Pressed/Active → Focus → Disabled → Loading
```
## Button States
```tsx
import { motion } from "framer-motion";
export function Button({ children, disabled, isLoading }) {
return (
<motion.button
// Hover state (50-100ms)
whileHover={{ scale: 1.02 }}
// Pressed state (100-150ms)
whileTap={{ scale: 0.98 }}
transition={{ duration: 0.1 }}
disabled={disabled || isLoading}
className={cn(
// Default
"px-4 py-2 rounded-lg bg-primary text-primary-foreground",
"font-medium transition-colors",
// Focus visible
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
// Disabled
"disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none",
)}
>
{isLoading ? <Spinner className="h-4 w-4 animate-spin" /> : children}
</motion.button>
);
}
```
## State Timing Guide
| State | Duration | Easing |
|-------|----------|--------|
| Hover in | 50-100ms | ease-out |
| Hover out | 150ms | ease-in |
| Press | 100-150ms | ease-out |
| Focus | instant | - |
| Loading | - | linear (spin) |
## Card Hover States
```tsx
<motion.div
className="bg-surface rounded-2xl p-6 shadow-md transition-shadow"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
whileHover={{
y: -4,
boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.15)",
}}
transition={{ duration: 0.2 }}
>
{children}
</motion.div>
```
## Input Field States
```tsx
const inputStates = {
default: "border-border bg-surface",
focus: "border-primary ring-2 ring-primary/20",
valid: "border-success bg-suc