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:
parent
d8992408fa
commit
804a85cca6
25 changed files with 999 additions and 162 deletions
|
|
@ -3,7 +3,8 @@ import { Knob } from '../components/Knob';
|
|||
import { Pointer } from '../primitives/Pointer';
|
||||
import { Ticks } from '../primitives/Ticks';
|
||||
import { KnobLabel } from '../primitives/Text';
|
||||
import { MONO_FONT, UI_FONT, type SkinProps } from './shared';
|
||||
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. */
|
||||
|
|
@ -22,23 +23,35 @@ export const SteppedKnob: React.FC<SteppedKnobProps> = ({
|
|||
size = 90,
|
||||
positions,
|
||||
steps,
|
||||
color = '#ffd23e',
|
||||
tickColor = 'rgba(255,255,255,0.18)',
|
||||
color: colorProp,
|
||||
tickColor,
|
||||
faceColor = '#1c1d22',
|
||||
textColor = 'rgba(255,255,255,0.92)',
|
||||
labelColor = 'rgba(255,255,255,0.45)',
|
||||
textColor,
|
||||
labelColor,
|
||||
label,
|
||||
showValue = true,
|
||||
focusRing,
|
||||
className,
|
||||
style,
|
||||
...core
|
||||
}) => {
|
||||
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 (
|
||||
<Knob size={size} className={className} style={style} {...core} min={min} max={max} steps={detents}>
|
||||
<Knob
|
||||
size={size}
|
||||
className={className}
|
||||
style={style}
|
||||
focusRing={focusRing}
|
||||
{...core}
|
||||
min={min}
|
||||
max={max}
|
||||
steps={detents}
|
||||
>
|
||||
{ctx => {
|
||||
const index = Math.round(ctx.normalized * (detents - 1));
|
||||
return (
|
||||
|
|
@ -48,7 +61,7 @@ export const SteppedKnob: React.FC<SteppedKnobProps> = ({
|
|||
radius={size / 2 - 1}
|
||||
length={size * 0.07}
|
||||
width={Math.max(1.5, size * 0.022)}
|
||||
color={tickColor}
|
||||
color={tickColor ?? theme.ticks}
|
||||
getTickProps={i => (i === index ? { stroke: color } : undefined)}
|
||||
/>
|
||||
<circle
|
||||
|
|
@ -73,8 +86,8 @@ export const SteppedKnob: React.FC<SteppedKnobProps> = ({
|
|||
textAnchor="middle"
|
||||
dominantBaseline="central"
|
||||
fontSize={size * (positions ? 0.15 : 0.17)}
|
||||
fill={textColor}
|
||||
fontFamily={MONO_FONT}
|
||||
fill={textColor ?? theme.text}
|
||||
fontFamily={theme.fontMono}
|
||||
fontWeight={600}
|
||||
style={{ pointerEvents: 'none' }}
|
||||
>
|
||||
|
|
@ -82,7 +95,12 @@ export const SteppedKnob: React.FC<SteppedKnobProps> = ({
|
|||
</text>
|
||||
)}
|
||||
{label && (
|
||||
<KnobLabel color={labelColor} fontFamily={UI_FONT} dy={size * 0.45} fontSize={size * 0.095}>
|
||||
<KnobLabel
|
||||
color={labelColor ?? theme.label}
|
||||
fontFamily={theme.fontUI}
|
||||
dy={size * 0.45}
|
||||
fontSize={size * 0.095}
|
||||
>
|
||||
{label}
|
||||
</KnobLabel>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue