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.

$ Installieren

git clone https://github.com/majiayu000/claude-skill-registry /tmp/claude-skill-registry && cp -r /tmp/claude-skill-registry/skills/development/control-panel ~/.claude/skills/claude-skill-registry

// tip: Run this command in your terminal to install the skill


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:

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:

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

  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

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 TypeInputOutput
Numbercount: 42{ count: number }
Stringname: 'text'{ name: string }
Booleanenabled: true{ enabled: boolean }
Colorcolor: '#fff'{ color: string }
Selectsize: { options: [...] }{ size: string }
Vector2Dpos: { x: 0, y: 0 }{ pos: {x, y} }
Vector3Dpos: { x, y, z }{ pos: {x, y, z} }
Rangerange: [20, 80]{ range: [number, number] }
Buttonbutton(() => {})void
Imageimage: { image }{ image: string | undefined }

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!