Claude-skill-registry control panel
Creates a control panel that allows runtime modification of values. When Claude needs to expose controls for the user to adjust variables and values.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/control-panel" ~/.claude/skills/majiayu000-claude-skill-registry-control-panel && rm -rf "$T"
skills/data/control-panel/SKILL.mdLeva 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:
import { useControls, button, folder, buttonGroup, LevaPanel } from 'leva'
Core Concepts
- useControls Hook - Primary hook for creating controls
- Automatic Type Detection - Leva infers control types from initial values
- Folders & Organization - Group related controls for better UX
- Real-time Updates - Controls update React state automatically
- Transient Mode - Performance optimization for smooth interactions
Control Types Reference
1. Number Controls
Basic number:
const { count } = useControls({ count: 42 })
Number with constraints:
const { value } = useControls({ value: { value: 50, min: 0, max: 100, step: 5 } })
With suffix/prefix:
const { temperature } = useControls({ temperature: { value: 72, min: 32, max: 100, suffix: '°F' } })
2. String/Text Controls
Basic text:
const { name } = useControls({ name: 'Default Name' })
Multiline text:
const { description } = useControls({ description: { value: 'Long text...', rows: 3 } })
3. Boolean Controls
Simple checkbox:
const { enabled } = useControls({ enabled: true })
4. Color Controls
Supports hex, rgb, hsl:
const { color } = useControls({ background: '#4c9aff', textColor: { value: '#ffffff', label: 'Text' }, accent: 'rgb(255, 100, 150)' })
5. Select/Dropdown Controls
Array options:
const { size } = useControls({ size: { value: 'medium', options: ['small', 'medium', 'large'] } })
Object options (custom labels):
const { theme } = useControls({ theme: { value: 'dark', options: { 'Light Mode': 'light', 'Dark Mode': 'dark', 'Auto': 'auto' } } })
6. Vector Controls
2D vectors:
const { position } = useControls({ position: { value: { x: 0, y: 0 }, step: 1 } })
3D vectors:
const { position3D } = useControls({ position3D: { value: { x: 0, y: 0, z: 0 }, step: 1 } })
With constraints:
const { scale } = useControls({ scale: { value: { x: 1, y: 1 }, min: 0.1, max: 3, step: 0.1 } })
7. Interval/Range Controls
Range slider:
const { range } = useControls({ range: { value: [20, 80], min: 0, max: 100 } })
8. Button Controls
Single button:
const controls = useControls({ 'Click Me': button(() => { console.log('Clicked!') }) })
Button group:
import { buttonGroup } from 'leva' const controls = useControls({ 'Actions': buttonGroup({ Save: () => handleSave(), Load: () => handleLoad(), Delete: () => handleDelete() }) })
9. Image/File Controls
const { image } = useControls({ image: { image: undefined } })
10. Monitor (Read-only Display)
const { fps } = useControls({ 'Current FPS': { value: currentFps, disabled: true } })
Organization Patterns
Grouped Controls
const controls = useControls('Settings', { width: 400, height: 300, color: '#ff0000' })
Nested Folders
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:
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
import { LevaPanel, useControls } from 'leva' function Component() { const panel1 = useControls('Panel 1', { value1: 0 }) const panel2 = useControls('Panel 2', { value2: 100 }) return ( <> <LevaPanel store={panel1} /> <LevaPanel store={panel2} /> </> ) }
3. Conditional Controls
const { mode, detail } = useControls({ mode: { value: 'simple', options: ['simple', 'advanced'] }, ...(mode === 'advanced' && { detail: { value: 5, min: 1, max: 10 } }) })
4. Custom Labels
const controls = useControls({ bgColor: { value: '#ffffff', label: 'Background Color' } })
5. Control Order
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
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 ( <div style={{ width, height, backgroundColor: color, opacity, borderRadius: rounded }} /> ) }
2. Animation Controls
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 ( <motion.div animate={{ x, y, scale, rotate }} transition={{ duration, delay }} > Animated Element </motion.div> ) }
3. Theme/Style Controls
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 <div style={{ fontSize, fontWeight }}>Styled Content</div> }
4. Data Visualization Controls
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
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 <div>State: {state}</div> }
Best Practices
- Group Related Controls - Use folders to organize complex UIs
- Provide Constraints - Always set min/max for numeric values when appropriate
- Use Descriptive Labels - Make control purposes clear
- Add Units - Use suffix/prefix for clarity (px, %, °, ms, etc.)
- Start Collapsed - Use
for secondary options{ collapsed: true } - Monitor Important Values - Use disabled controls to display computed values
- Use Button Groups - Group related actions together for better UX
- Keep It Organized - Don't create too many controls at the root level
- Performance - For real-time controls, Leva is already optimized
- Naming - Use clear, consistent naming conventions
Integration with Other Libraries
With Framer Motion
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 ( <motion.div animate={{ x, y, rotate, scale }}> Content </motion.div> ) }
With Three.js/React Three Fiber
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 ( <pointLight intensity={intensity} position={[position.x, position.y, position.z]} color={color} /> ) }
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:
/* Target the Leva root */ :root { --leva-colors-accent1: #4c9aff; --leva-colors-accent2: #5c6bc0; }
Quick Reference
| Control Type | Input | Output |
|---|---|---|
| Number | | |
| String | | |
| Boolean | | |
| Color | | |
| Select | | |
| Vector2D | | |
| Vector3D | | |
| Range | | |
| Button | | |
| Image | | |
Example: Complete Control Panel
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 ( <motion.div style={{ backgroundColor: color, opacity, width: size === 'small' ? 100 : size === 'medium' ? 200 : 300 }} animate={{ x: position.x, y: position.y }} transition={{ duration: duration / 1000 }} > {name} - {count} </motion.div> ) }
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!