import * as React from 'react'; import { Knob } from '../components/Knob'; import { Pointer } from '../primitives/Pointer'; import { Ticks } from '../primitives/Ticks'; import { KnobLabel } from '../primitives/Text'; import { useKnobTheme } from '../core/theme'; import type { SkinProps } from './shared'; export interface SteppedKnobProps extends SkinProps { /** Position names, e.g. ['LP','BP','HP']. Sets the number of detents. */ positions?: readonly string[]; /** Number of detents when `positions` is not given. */ steps?: number; color?: string; tickColor?: string; faceColor?: string; textColor?: string; labelColor?: string; } /** Detented selector knob — mode/range switches with hard stops. */ export const SteppedKnob = React.forwardRef(function SteppedKnob({ size = 90, positions, steps, color: colorProp, tickColor, faceColor = '#1c1d22', textColor, labelColor, label, sublabel, labelSize, showValue = true, format, focusRing, className, style, ...core }, ref) { const theme = useKnobTheme(); const color = colorProp ?? theme.accent ?? '#ffd23e'; const detents = positions ? positions.length : steps ?? 5; const min = core.min ?? 0; const max = core.max ?? (positions ? positions.length - 1 : 100); return ( positions[Math.round(((v - min) / (max - min || 1)) * (detents - 1))] ?? String(v) : format ? (v: number) => format(v) : undefined)} > {ctx => { const index = Math.round(ctx.normalized * (detents - 1)); return ( <> (i === index ? { stroke: color } : undefined)} /> {showValue && ( {positions ? positions[index] : format ? format(ctx.value) : ctx.value.toFixed(ctx.decimals)} )} {label && ( {label} )} ); }} ); });