Signal-valued inputs
Pibbl-provided components accept signals wherever reactive replacement is meaningful: drawing and layout geometry, style fields, text, animation inputs, and applicable official render-layer, Three.js, particles, physics, and visualization inputs. Plain values take the same direct path as before.
SignalValue
Section titled “SignalValue”SignalValue<T> is T | Signal<T>. A receiving component resolves the input
and therefore owns its dependency:
import { Rectangle, Text, resolveSignalValue, useSignal, type SignalValue,} from "@pibbl/core";
const left = useSignal(10);const color = useSignal("red");const label = useSignal("Current");
<Rectangle style={{ left, fill: color, width: 50, height: 50 }} />;<Text>{label}</Text>;Passing left.get() remains valid. That explicit read intentionally makes the
enclosing component the consumer and passes a plain number downstream.
Declared, shallow resolution
Section titled “Declared, shallow resolution”Resolution follows each component’s published input schema. Pibbl can resolve a
whole-object signal such as style={styleSignal} or individual declared fields
such as style={{ left: xSignal }}. Text and structural child grammars resolve
signals encountered while walking their own declared arrays and finite
iterables.
Pibbl never recursively searches arbitrary application data. A signal inside a dataset row, event payload, callback closure, custom metadata object, or nested descriptor is ordinary application data unless that exact descriptor schema explicitly opts into a shallow signal-valued field. A signal returned by another signal is not unwrapped again.
Event handlers and callbacks are selected as values and are not invoked by
input resolution. APIs that intentionally require the signal object itself use
an exact prop such as valueSignal: WritableSignal<T> rather than
SignalValue<WritableSignal<T>>.
Custom receivers
Section titled “Custom receivers”Use resolveSignalValue at the declared
boundary of an ordinary custom component:
interface Point { readonly x: number; readonly y: number;}
interface SeriesProps { data: SignalValue<readonly Point[]>;}
function drawSeries(data: readonly Point[]) { return <Text>{data.length}</Text>;}
function Series(props: SeriesProps) { const data = resolveSignalValue(props.data); return drawSeries(data);}The helper resolves exactly one plain-or-signal value. It performs no wrapper allocation and no deep inspection. Call it while the receiving component is evaluating so Pibbl attributes the dependency to that component.
Layout and pure measurement preserve the same ownership rule. Mounted layout
prepasses transfer declared reads to the eventual receiving child; standalone
measureElement() reads untracked and creates no persistent consumer.
API details from source
Section titled “API details from source”
A literal value or a signal supplying that value to a receiver-owned input.
type SignalValue<T> = T | Signal<T>Related API: SignalValue, Signal.
See also
Section titled “See also”View source — packages/core/src/lib/signals/types.ts:55
Implementation guidance for agents
Section titled “Implementation guidance for agents”Read the Authoring, signals, and lifecycle companion for ownership, adaptation, failure modes, and verification. Agent start provides the version-selection workflow.
Complete minimal examples
Section titled “Complete minimal examples”- Read and update signals: Use writable, readonly, and computed values with synchronous batching. Plain source
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 380919b. ALPHA — NOT FOR PRODUCTION USE.