From 2f4a06dd4046d6b3fd2a1e9a0b616ba53eb5fb14 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 12 Apr 2026 07:39:39 +0000 Subject: [PATCH] fix(theme): remove stale React Compiler memo wrappers from theme hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebase on current main (includes #589 reconciler fix). The React Compiler memo caches (_c) in useTheme() and usePreviewTheme() use referential equality checks on destructured context values. These caches can return stale references when the ThemeProvider's useMemo recreates the context value object but the individual property references (setThemeSetting, setPreviewTheme, etc.) compare equal — the memo short-circuits and returns a cached tuple/object that still holds the old closure captures. This is a distinct bug from #589 (which fixed the ink reconciler's commitUpdate path for host prop updates). #589 ensures that when React _does_ re-render a component with new props, those props actually reach the DOM node. But the memo wrappers here prevent React from _even seeing_ the new context value in the first place — the hook returns the stale cached result. Removing the memo wrappers ensures useTheme() and usePreviewTheme() always read the current context value, eliminating the stale-reference path entirely. --- .../design-system/ThemeProvider.tsx | 41 +++---------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/src/components/design-system/ThemeProvider.tsx b/src/components/design-system/ThemeProvider.tsx index 67724b0d..910e08af 100644 --- a/src/components/design-system/ThemeProvider.tsx +++ b/src/components/design-system/ThemeProvider.tsx @@ -1,4 +1,3 @@ -import { c as _c } from "react-compiler-runtime"; import { feature } from 'bun:bundle'; import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; import useStdin from '../../ink/hooks/use-stdin.js'; @@ -120,21 +119,8 @@ export function ThemeProvider({ * accepts any ThemeSetting (including 'auto'). */ export function useTheme() { - const $ = _c(3); - const { - currentTheme, - setThemeSetting - } = useContext(ThemeContext); - let t0; - if ($[0] !== currentTheme || $[1] !== setThemeSetting) { - t0 = [currentTheme, setThemeSetting]; - $[0] = currentTheme; - $[1] = setThemeSetting; - $[2] = t0; - } else { - t0 = $[2]; - } - return t0; + const { currentTheme, setThemeSetting } = useContext(ThemeContext); + return [currentTheme, setThemeSetting] as const; } /** @@ -145,25 +131,10 @@ export function useThemeSetting() { return useContext(ThemeContext).themeSetting; } export function usePreviewTheme() { - const $ = _c(4); - const { + const { setPreviewTheme, savePreview, cancelPreview } = useContext(ThemeContext); + return { setPreviewTheme, savePreview, - cancelPreview - } = useContext(ThemeContext); - let t0; - if ($[0] !== cancelPreview || $[1] !== savePreview || $[2] !== setPreviewTheme) { - t0 = { - setPreviewTheme, - savePreview, - cancelPreview - }; - $[0] = cancelPreview; - $[1] = savePreview; - $[2] = setPreviewTheme; - $[3] = t0; - } else { - t0 = $[3]; - } - return t0; + cancelPreview, + }; }