Tier 1: origin anchor, detents, theming, type-in editing, ImageKnob

- origin: bipolar anchor value — Arc from=center, Fader fill and
  LEDFader segments draw from origin instead of min/mid-travel
- detents + detentSize: magnetic snap while dragging (normalized
  space, wheel/keyboard unaffected); applyDetents exported
- DreamknobProvider + KnobTheme: accent/track/face/text/label/ticks/
  focusRing/fonts tokens with dark and light bases; every skin
  resolves defaults from the theme, instance props win
- editable + parseValue: double-click knobs (or click fader readouts)
  to type exact values; Enter/blur commits, Esc cancels, 1.2k parses;
  ValueInput + defaultParseValue exported; setValue added to context
- ImageKnob: film-strip sprite knob (KnobMan-style strips), vertical
  or horizontal, with focus ring, editing, value/label
- Docs: LED gallery cards for film-strip/bipolar/editing/theming,
  playground editable toggle, theming API section, README updates
This commit is contained in:
Dreamodus 2026-07-12 15:05:46 -07:00
parent d8992408fa
commit 804a85cca6
25 changed files with 999 additions and 162 deletions

View file

@ -1,6 +1,8 @@
import type * as React from 'react';
import type { KnobCoreProps } from '../core/types';
export { MONO_FONT, UI_FONT } from '../core/theme';
/** Props common to every prebuilt knob skin. */
export interface SkinProps extends KnobCoreProps {
/** Square canvas size in px. */
@ -13,11 +15,15 @@ export interface SkinProps extends KnobCoreProps {
unit?: string;
/** Custom readout formatter (takes precedence over unit/decimals). */
format?: (value: number) => string;
/** Keyboard focus ring color, or false to disable. Defaults to the theme's. */
focusRing?: string | false;
/**
* Type-in editing: double-click (knobs) or click the readout (faders) to
* enter an exact value. Enter/blur commits, Escape cancels, "1.2k" works.
*/
editable?: boolean;
/** Custom parser for typed input when `editable` is set. */
parseValue?: (text: string) => number | null;
className?: string;
style?: React.CSSProperties;
}
export const MONO_FONT =
"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
export const UI_FONT =
"'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif";