From 512eba474a403df91503e1cf3e8bf3a85335217d Mon Sep 17 00:00:00 2001 From: Mats Bosson Date: Sun, 29 Mar 2026 02:40:38 +0700 Subject: [PATCH] Fix null handling in controllable signal --- packages/core/src/primitives/create-controllable-signal.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/src/primitives/create-controllable-signal.ts b/packages/core/src/primitives/create-controllable-signal.ts index 9a66cd0..71fd9ab 100644 --- a/packages/core/src/primitives/create-controllable-signal.ts +++ b/packages/core/src/primitives/create-controllable-signal.ts @@ -3,7 +3,7 @@ import { type Accessor, createSignal } from "solid-js"; export interface CreateControllableSignalOptions { /** Returns the controlled value, or undefined if uncontrolled. */ value: Accessor; - /** Default value used when uncontrolled. */ + /** Default value used when uncontrolled. Only read once at creation time — not reactive after mount. */ defaultValue: Accessor; /** Called whenever the value changes (both modes). */ onChange?: (value: T) => void; @@ -21,12 +21,14 @@ export function createControllableSignal( const get: Accessor = () => { const controlled = options.value(); - return controlled !== undefined ? controlled : internalValue(); + if (controlled !== undefined) return controlled; + return internalValue(); }; const set = (value: T) => { const isControlled = options.value() !== undefined; if (!isControlled) { + // Use functional form so SolidJS does not interpret T-as-function as an updater. setInternalValue(() => value); } options.onChange?.(value);