From 041217ca3367e28ce7bdbfd8e3708a186c6efee8 Mon Sep 17 00:00:00 2001 From: Mats Bosson Date: Sun, 29 Mar 2026 07:23:19 +0700 Subject: [PATCH] Fix Checkbox indeterminate state --- .../core/src/components/checkbox/checkbox.tsx | 23 ++++++++----------- .../primitives/create-controllable-signal.ts | 2 +- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/packages/core/src/components/checkbox/checkbox.tsx b/packages/core/src/components/checkbox/checkbox.tsx index 9e46e39..d698fe8 100644 --- a/packages/core/src/components/checkbox/checkbox.tsx +++ b/packages/core/src/components/checkbox/checkbox.tsx @@ -1,5 +1,5 @@ import type { JSX } from "solid-js"; -import { splitProps } from "solid-js"; +import { createEffect, splitProps } from "solid-js"; import { createControllableSignal } from "../../primitives/create-controllable-signal"; /** Represents all three states a checkbox can be in. */ @@ -37,18 +37,11 @@ export function Checkbox(props: CheckboxProps): JSX.Element { "children", ]); - const [isChecked, setChecked] = createControllableSignal( - local.onCheckedChange - ? { - value: () => local.checked, - defaultValue: () => local.defaultChecked ?? false, - onChange: local.onCheckedChange, - } - : { - value: () => local.checked, - defaultValue: () => local.defaultChecked ?? false, - }, - ); + const [isChecked, setChecked] = createControllableSignal({ + value: () => local.checked, + defaultValue: () => local.defaultChecked ?? false, + onChange: local.onCheckedChange, + }); const ariaChecked = (): boolean | "mixed" => { const c = isChecked(); @@ -87,7 +80,9 @@ export function Checkbox(props: CheckboxProps): JSX.Element { value={local.value ?? "on"} checked={isChecked() === true} ref={(el) => { - if (el) el.indeterminate = isChecked() === "indeterminate"; + createEffect(() => { + el.indeterminate = isChecked() === "indeterminate"; + }); }} style={{ display: "none" }} /> diff --git a/packages/core/src/primitives/create-controllable-signal.ts b/packages/core/src/primitives/create-controllable-signal.ts index 71fd9ab..a36b39f 100644 --- a/packages/core/src/primitives/create-controllable-signal.ts +++ b/packages/core/src/primitives/create-controllable-signal.ts @@ -6,7 +6,7 @@ export interface CreateControllableSignalOptions { /** 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; + onChange?: ((value: T) => void) | undefined; } /**