import * as React from 'react'; import { useKnobTheme } from '../core/theme'; export interface PushButtonProps { /** Controlled pressed state. Pair with `onChange`. */ pressed?: boolean; defaultPressed?: boolean; onChange?: (pressed: boolean) => void; /** 'toggle' latches; 'momentary' is only on while held. Default: 'toggle'. */ mode?: 'toggle' | 'momentary'; /** LED / active color. */ color?: string; /** Show the LED strip. Default: true. */ led?: boolean; /** Button height in px. Default: 36. */ size?: number; /** Explicit width; defaults to content. */ width?: number; disabled?: boolean; /** Render a hidden form input carrying "on"/"off". */ name?: string; /** Caption, e.g. "MUTE". */ children?: React.ReactNode; className?: string; style?: React.CSSProperties; 'aria-label'?: string; } /** Studio panel button with an LED strip — mute/solo/bypass in matching style. */ export const PushButton = React.forwardRef( function PushButton( { pressed, defaultPressed = false, onChange, mode = 'toggle', color, led = true, size = 36, width, disabled = false, name, children, className, style, ...aria }, ref, ) { const theme = useKnobTheme(); const accent = color ?? theme.accent ?? '#4cc2ff'; const isControlled = pressed !== undefined; const [internal, setInternal] = React.useState(defaultPressed); const [focusVisible, setFocusVisible] = React.useState(false); const on = isControlled ? (pressed as boolean) : internal; const set = (next: boolean) => { if (next === on) return; if (!isControlled) setInternal(next); onChange?.(next); }; const momentaryProps = mode === 'momentary' ? { onPointerDown: (e: React.PointerEvent) => { e.currentTarget.setPointerCapture(e.pointerId); set(true); }, onPointerUp: () => set(false), onPointerCancel: () => set(false), onKeyDown: (e: React.KeyboardEvent) => { if ((e.key === ' ' || e.key === 'Enter') && !e.repeat) set(true); }, onKeyUp: (e: React.KeyboardEvent) => { if (e.key === ' ' || e.key === 'Enter') set(false); }, } : { onClick: () => set(!on) }; return ( ); }, );