v1.1.4: light-theme support (LED wells, panel buttons, readouts)

The controls whose chrome was hardcoded dark now adapt to a light base —
previously they rendered as dark chips/holes on light themes. (Flat knobs and
faders already adapted: their face is the `face` token.)

- `ledWell` theme token — the recessed screen behind LED segments (LEDKnob,
  LEDFader, Meter) and the default well of SegmentDisplay / AlphaDisplay now
  comes from the theme. Dark base keeps #0b0d0e; light base is `transparent`,
  so LED controls and readouts render as clean flat rings / bars / digits on
  the light panel. faceColor / background props still override.
- `scheme` theme token ('dark' | 'light', set by base) + a shared
  panelButtonChrome() helper drive the raised gradient/border/shadow of
  PushButton (and Button), TransportButton and SegmentSwitch — light raised
  buttons on light themes instead of dark chips; unlit LED pips flip to a
  faint dark so they still read.
- Docs: a "Light theme" gallery card showing the panel family under
  base="light"; ledWell/scheme documented; install URLs bumped to v1.1.4.

Library + docs typecheck and build; 46 tests pass.
This commit is contained in:
Dreamodus 2026-07-14 13:06:16 -07:00
parent d183d7d16b
commit 8b462dfb83
17 changed files with 180 additions and 44 deletions

View file

@ -1,5 +1,5 @@
import * as React from 'react';
import { useKnobTheme } from '../core/theme';
import { panelButtonChrome, useKnobTheme } from '../core/theme';
export type TransportKind =
| 'play'
@ -90,6 +90,7 @@ export const TransportButton = React.forwardRef<HTMLButtonElement, TransportButt
const theme = useKnobTheme();
const [focusVisible, setFocusVisible] = React.useState(false);
const glyphRef = React.useRef<SVGSVGElement>(null);
const chrome = panelButtonChrome(theme.scheme, active);
const accent =
color ??
@ -145,17 +146,11 @@ export const TransportButton = React.forwardRef<HTMLButtonElement, TransportButt
height: size,
padding: 0,
borderRadius: 8,
border: '1px solid rgba(0,0,0,0.6)',
background: active
? 'linear-gradient(180deg, #17181d, #232429)'
: 'linear-gradient(180deg, #35363d, #1d1e24)',
boxShadow: `${
active
? 'inset 0 2px 5px rgba(0,0,0,0.6)'
: 'inset 0 1px 0 rgba(255,255,255,0.09), 0 2px 4px rgba(0,0,0,0.45)'
}${active ? `, 0 0 ${size * 0.28}px ${accent}55` : ''}${
focusVisible ? `, 0 0 0 2px ${theme.focusRing}` : ''
}`,
border: chrome.border,
background: chrome.background,
boxShadow: `${chrome.boxShadow}${
active ? `, 0 0 ${size * 0.28}px ${accent}55` : ''
}${focusVisible ? `, 0 0 0 2px ${theme.focusRing}` : ''}`,
outline: 'none',
cursor: disabled ? 'not-allowed' : 'pointer',
opacity: disabled ? 0.45 : 1,