PURPOSE

Renders editable input controls for a VFX component’s preview uniform values inside the weapon workbench. Reads a uniform schema and a current value map, lets the user edit scalar and vector uniforms, and reports each edit back to the parent via onChange.

OWNS

  • The local helper vecSize(type) mapping uniform type strings (vec2, vec3, vec4) to their component counts.
  • The setScalar(name, n) and setVec(name, idx, n) closures that build the next value map and call onChange.
  • The JSX layout for the “PREVIEW INPUTS” panel: section header, per-uniform rows for scalars (float, int) and grids of inputs for vectors.
  • Inline styling for the panel, header, labels, and <input> elements.
  • data-testid attributes on every <input>: preview-input-<name> for scalars, preview-input-<name>-<i> for vector components.

READS FROM

  • UniformDecl type from @engine/vfx-workbench/component-schema.
  • Props:
    • schema: UniformDecl[] — list of uniform declarations to render.
    • value: Record<string, unknown> — current preview values, keyed by uniform name.
    • onChange: (next: Record<string, unknown>) => void — callback invoked with a new value map on every edit.
  • For each uniform: u.name, u.type, and u.default (used as the fallback for scalar inputs when no current value is present).

PUSHES TO

  • onChange — invoked with a shallow-cloned value map that replaces a single uniform’s entry. Vector edits replace the entire array for that uniform.

DOES NOT

  • Does not store any state internally; the component is fully controlled by value and onChange.
  • Does not validate input ranges, clamp values, or guard against NaN from parseFloat.
  • Does not render anything for uniform types other than float, int, vec2, vec3, vec4 (returns null for unknown types).
  • Does not read or write the workbench store, IndexedDB, or any global state.
  • Does not own component selection, shader compilation, or preview rendering.
  • Does not memoize callbacks or rows.

Signals

  • Scalar <input type="number"> onChange setScalar(name, parseFloat(value)) parent onChange.
  • Vector <input type="number"> onChange setVec(name, idx, parseFloat(value)) parent onChange.
  • Scalar step is 1 for int uniforms and 0.01 for float; vector step is 0.1.

Entry points

  • Named export PreviewSampleInputsEditor({ schema, value, onChange }) — consumed by the weapon workbench preview surface that owns the selected component’s uniform schema and live preview value map.

Pattern notes

  • Controlled component: the editor never mutates value; it always emits a new object via onChange.
  • Vector defaults: when value[name] is absent for a vector uniform, the editor seeds a zero-filled array of vecSize(u.type) for display, and on first edit setVec falls back to new Array(4).fill(0) before slicing — vector writes always emit at least four entries regardless of declared size.
  • Scalar defaults: missing entries fall back to u.default, then 0.
  • Uniform key is u.name; nothing in this component handles duplicate names.
  • Rendering returns null for any uniform whose type is not float, int, or a recognised vec*, silently skipping unsupported types.
  • Styling is hard-coded inline (dark palette, monospace inputs, Cal Sans header) and is not themable from props.