---
name: "control panel"
description: "Creates a control panel that allows runtime modification of values. When Claude needs to expose controls for the user to adjust variables and values."
license: Proprietary
---
# Leva Control Panel Skill
You are a specialized expert in creating interactive control panels using **Leva** - a React GUI library for building powerful, real-time controls for prototyping and debugging.
## Available Tools in This Repo
### Leva
Already installed via `leva@^0.10.1`. Import as:
```tsx
import { useControls, button, folder, buttonGroup, LevaPanel } from 'leva'
```
## Core Concepts
1. **useControls Hook** - Primary hook for creating controls
2. **Automatic Type Detection** - Leva infers control types from initial values
3. **Folders & Organization** - Group related controls for better UX
4. **Real-time Updates** - Controls update React state automatically
5. **Transient Mode** - Performance optimization for smooth interactions
## Control Types Reference
### 1. Number Controls
**Basic number:**
```tsx
const { count } = useControls({
count: 42
})
```
**Number with constraints:**
```tsx
const { value } = useControls({
value: { value: 50, min: 0, max: 100, step: 5 }
})
```
**With suffix/prefix:**
```tsx
const { temperature } = useControls({
temperature: { value: 72, min: 32, max: 100, suffix: '°F' }
})
```
### 2. String/Text Controls
**Basic text:**
```tsx
const { name } = useControls({
name: 'Default Name'
})
```
**Multiline text:**
```tsx
const { description } = useControls({
description: { value: 'Long text...', rows: 3 }
})
```
### 3. Boolean Controls
**Simple checkbox:**
```tsx
const { enabled } = useControls({
enabled: true
})
```
### 4. Color Controls
**Supports hex, rgb, hsl:**
```tsx
const { color } = useControls({
background: '#4c9aff',
textColor: { value: '#ffffff', label: 'Text' },
accent: 'rgb(255, 100, 150)'
})
```
### 5. Select/Dropdown Controls
**Array options:**
```tsx
const { size } = useControls({
size: { value: 'medium', options: ['small', 'medium', 'large'] }
})
```
**Object options (custom labels):**
```tsx
const { theme } = useControls({
theme: {
value: 'dark',
options: {
'Light Mode': 'light',
'Dark Mode': 'dark',
'Auto': 'auto'
}
}
})
```
### 6. Vector Controls
**2D vectors:**
```tsx
const { position } = useControls({
position: { value: { x: 0, y: 0 }, step: 1 }
})
```
**3D vectors:**
```tsx
const { position3D } = useControls({
position3D: { value: { x: 0, y: 0, z: 0 }, step: 1 }
})
```
**With constraints:**
```tsx
const { scale } = useControls({
scale: { value: { x: 1, y: 1 }, min: 0.1, max: 3, step: 0.1 }
})
```
### 7. Interval/Range Controls
**Range slider:**
```tsx
const { range } = useControls({
range: { value: [20, 80], min: 0, max: 100 }
})
```
### 8. Button Controls
**Single button:**
```tsx
const controls = useControls({
'Click Me': button(() => {
console.log('Clicked!')
})
})
```
**Button group:**
```tsx
import { buttonGroup } from 'leva'
const controls = useControls({
'Actions': buttonGroup({
Save: () => handleSave(),
Load: () => handleLoad(),
Delete: () => handleDelete()
})
})
```
### 9. Image/File Controls
```tsx
const { image } = useControls({
image: { image: undefined }
})
```
### 10. Monitor (Read-only Display)
```tsx
const { fps } = useControls({
'Current FPS': { value: currentFps, disabled: true }
})
```
## Organization Patterns
### Grouped Controls
```tsx
const controls = useControls('Settings', {
width: 400,
height: 300,
color: '#ff0000'
})
```
### Nested Folders
```tsx
import { folder } from 'leva'
const controls = useControls('Advanced', {
'Animation': folder({
duration: { value: 1000, min: 100, max: 5000, step: 100 },
easing: { value: 'easeOut', options: ['linear', 'easeIn', 'easeOut'] },
loop: false
}),
'Performance': folder({
fps: { value: 60, min: 24, max: 120 },
quality: { value: 'high', options: ['low', 'medium', 'high'] }
}, { collapsed: true }) // Start collapsed
})
```
## Advanced Features
### 1. Transient Mode (Performance)
Use for smooth real-time updates without re-renders:
```tsx
const { value } = useControls({
value: {
value: 50,
min: 0,
max: 100,
transient: false // Set to true for onChange-only updates
}
})
```
**Note:** In Leva 0.10.1, transient mode is handled automatically - just use regular controls for smooth interactions.
### 2. Multiple Panels
```tsx
import { LevaPanel, useControls } from 'leva'
function Component() {
const panel1 = useControls('Panel 1', { value1: 0 })
const panel2 = useControls('Panel 2', { value2: 100 })
return (
<>
>
)
}
```
### 3. Conditional Controls
```tsx
const { mode, detail } = useControls({
mode: { value: 'simple', options: ['simple', 'advanced'] },
...(mode === 'advanced' && {
detail: { value: 5, min: 1, max: 10 }
})
})
```
### 4. Custom Labels
```tsx
const controls = useControls({
bgColor: { value: '#ffffff', label: 'Background Color' }
})
```
### 5. Control Order
```tsx
const controls = useControls({
name: 'Title',
size: { value: 100, order: 0 }, // Appears first
color: { value: '#fff', order: 1 }, // Appears second
enabled: { value: true, order: 2 } // Appears third
})
```
## Common Use Cases
### 1. Visual Prototype Controls
```tsx
function PrototypeComponent() {
const { width, height, color, opacity, rounded } = useControls('Visual', {
width: { value: 200, min: 100, max: 800, step: 10 },
height: { value: 200, min: 100, max: 800, step: 10 },
color: '#4c9aff',
opacity: { value: 1, min: 0, max: 1, step: 0.01 },
rounded: { value: 8, min: 0, max: 50, step: 1, suffix: 'px' }
})
return (
)
}
```
### 2. Animation Controls
```tsx
import { motion } from 'framer-motion'
function AnimatedComponent() {
const { duration, delay, x, y, scale, rotate } = useControls('Animation', {
duration: { value: 1, min: 0.1, max: 5, step: 0.1, suffix: 's' },
delay: { value: 0, min: 0, max: 2, step: 0.1, suffix: 's' },
x: { value: 0, min: -200, max: 200 },
y: { value: 0, min: -200, max: 200 },
scale: { value: 1, min: 0.1, max: 3, step: 0.1 },
rotate: { value: 0, min: 0, max: 360, suffix: '°' }
})
return (
Animated Element
)
}
```
### 3. Theme/Style Controls
```tsx
function ThemedComponent() {
const { theme, spacing, fontSize, fontWeight } = useControls('Theme', {
theme: {
value: 'light',
options: { Light: 'light', Dark: 'dark', Auto: 'auto' }
},
spacing: { value: 'comfortable', options: ['compact', 'comfortable', 'spacious'] },
fontSize: { value: 16, min: 12, max: 24, step: 1, suffix: 'px' },
fontWeight: {
value: 400,
options: { Light: 300, Regular: 400, Medium: 500, Bold: 700 }
}
})
return Styled Content
}
```
### 4. Data Visualization Controls
```tsx
function ChartComponent() {
const { dataPoints, chartType, showGrid, showLegend, colorScheme } = useControls('Chart', {
dataPoints: { value: 50, min: 10, max: 200, step: 10 },
chartType: { value: 'bar', options: ['line', 'bar', 'area', 'scatter'] },
showGrid: true,
showLegend: true,
colorScheme: {
value: 'default',
options: ['default', 'vibrant', 'pastel', 'monochrome']
}
})
// Render chart with these controls
}
```
### 5. Interactive Actions
```tsx
import { button, buttonGroup } from 'leva'
function InteractiveComponent() {
const [state, setState] = useState('idle')
const controls = useControls('Actions', {
'Quick Actions': buttonGroup({
Reset: () => setState('idle'),
Start: () => setState('running'),
Pause: () => setState('paused'),
Stop: () => setState('stopped')
}),
'Export': button(() => {
// Export logic
console.log('Exporting...')
}),
'Current State': { value: state, disabled: true }
})
return State: {state}
}
```
## Best Practices
1. **Group Related Controls** - Use folders to organize complex UIs
2. **Provide Constraints** - Always set min/max for numeric values when appropriate
3. **Use Descriptive Labels** - Make control purposes clear
4. **Add Units** - Use suffix/prefix for clarity (px, %, °, ms, etc.)
5. **Start Collapsed** - Use `{ collapsed: true }` for secondary options
6. **Monitor Important Values** - Use disabled controls to display computed values
7. **Use Button Groups** - Group related actions together for better UX
8. **Keep It Organized** - Don't create too many controls at the root level
9. **Performance** - For real-time controls, Leva is already optimized
10. **Naming** - Use clear, consistent naming conventions
## Integration with Other Libraries
### With Framer Motion
```tsx
import { motion } from 'framer-motion'
import { useControls } from 'leva'
function AnimatedBox() {
const { x, y, rotate, scale } = useControls({
x: { value: 0, min: -200, max: 200 },
y: { value: 0, min: -200, max: 200 },
rotate: { value: 0, min: 0, max: 360 },
scale: { value: 1, min: 0.5, max: 2, step: 0.1 }
})
return (
Content
)
}
```
### With Three.js/React Three Fiber
```tsx
import { useControls } from 'leva'
function Scene() {
const { intensity, position, color } = useControls('Light', {
intensity: { value: 1, min: 0, max: 5, step: 0.1 },
position: { value: { x: 0, y: 5, z: 0 } },
color: '#ffffff'
})
return (
)
}
```
## Styling & Customization
The Leva panel appears by default in the top-right corner. It supports dark/light themes automatically based on system preferences.
For custom positioning or styling, use CSS:
```css
/* Target the Leva root */
:root {
--leva-colors-accent1: #4c9aff;
--leva-colors-accent2: #5c6bc0;
}
```
## Quick Reference
| Control Type | Input | Output |
|-------------|-------|--------|
| Number | `count: 42` | `{ count: number }` |
| String | `name: 'text'` | `{ name: string }` |
| Boolean | `enabled: true` | `{ enabled: boolean }` |
| Color | `color: '#fff'` | `{ color: string }` |
| Select | `size: { options: [...] }` | `{ size: string }` |
| Vector2D | `pos: { x: 0, y: 0 }` | `{ pos: {x, y} }` |
| Vector3D | `pos: { x, y, z }` | `{ pos: {x, y, z} }` |
| Range | `range: [20, 80]` | `{ range: [number, number] }` |
| Button | `button(() => {})` | `void` |
| Image | `image: { image }` | `{ image: string \| undefined }` |
## Example: Complete Control Panel
```tsx
import { useControls, folder, button, buttonGroup } from 'leva'
import { motion } from 'framer-motion'
function CompleteDemo() {
const {
// Basic
name,
count,
enabled,
// Visual
color,
size,
opacity,
// Position
position,
// Advanced
duration,
easing,
quality
} = useControls({
// Basic group
name: 'Demo',
count: { value: 42, min: 0, max: 100 },
enabled: true,
// Visual group
Visual: folder({
color: '#4c9aff',
size: { value: 'medium', options: ['small', 'medium', 'large'] },
opacity: { value: 1, min: 0, max: 1, step: 0.01 }
}),
// Position
position: { value: { x: 0, y: 0 }, step: 5 },
// Advanced
Advanced: folder({
duration: { value: 1000, min: 100, max: 3000, suffix: 'ms' },
easing: { value: 'easeOut', options: ['linear', 'easeIn', 'easeOut'] },
quality: { value: 'high', options: ['low', 'medium', 'high'] }
}, { collapsed: true }),
// Actions
'Reset': button(() => console.log('Reset!')),
'Actions': buttonGroup({
Save: () => console.log('Save'),
Load: () => console.log('Load')
})
})
return (
{name} - {count}
)
}
```
## When to Use Leva
✅ **Use Leva when:**
- Building interactive prototypes
- Debugging visual components
- Creating design system demos
- Fine-tuning animations
- Building configurators
- Creating interactive documentation
- Developing with React Three Fiber
❌ **Don't use Leva for:**
- Production user-facing forms (use proper form libraries)
- Complex validation requirements
- Multi-step wizards
- Data entry applications
Leva excels at rapid prototyping and real-time parameter tweaking during development!