From fbd30bebfbae103e0e0e5a3e58dc3ed3cc63852c Mon Sep 17 00:00:00 2001 From: Jacob Kofoed Date: Thu, 21 May 2026 14:43:08 +0200 Subject: [PATCH 1/2] Update theme signal along with cookie --- packages/core/src/types.ts | 6 ++++++ packages/lib/actions/setTheme/handler.ts | 2 ++ packages/runtime/src/editor-preview.main.ts | 14 +++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 0e5fea056..68fedc410 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -37,6 +37,12 @@ export type ActionHandler = ( ) => void env: ToddleEnv abortSignal: AbortSignal + stores?: { + theme: { + set: (value: string | null) => void + get: () => string | null + } + } }, event?: Nullable, ) => void diff --git a/packages/lib/actions/setTheme/handler.ts b/packages/lib/actions/setTheme/handler.ts index b72e18652..44c575dbc 100644 --- a/packages/lib/actions/setTheme/handler.ts +++ b/packages/lib/actions/setTheme/handler.ts @@ -23,6 +23,8 @@ const handler: ActionHandler = async function ([name], ctx) { expires: shouldDelete ? 0 : Date.now() + ONE_YEAR, sameSite: 'none', }) + // Also update the theme store directly for cases where cookies are not supported or delayed. + ctx.stores?.theme.set(name) ctx.triggerActionEvent('Success', undefined) } catch (error) { ctx.triggerActionEvent('Error', error as Error) diff --git a/packages/runtime/src/editor-preview.main.ts b/packages/runtime/src/editor-preview.main.ts index dce392af7..4bef8a0d9 100644 --- a/packages/runtime/src/editor-preview.main.ts +++ b/packages/runtime/src/editor-preview.main.ts @@ -35,7 +35,10 @@ import { getThemeEntries, renderThemeValues, } from '@nordcraft/core/dist/styling/theme' -import { THEME_DATA_ATTRIBUTE } from '@nordcraft/core/dist/styling/theme.const' +import { + THEME_COOKIE_NAME, + THEME_DATA_ATTRIBUTE, +} from '@nordcraft/core/dist/styling/theme.const' import type { StyleVariant } from '@nordcraft/core/dist/styling/variantSelector' import type { ActionHandler, @@ -1166,6 +1169,15 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d } case 'preview_theme': { const { theme } = message.data + themeSignal.set(theme) + const shouldDelete = theme === null || theme === '' + await cookieStore.set({ + name: THEME_COOKIE_NAME, + value: theme ?? '', + path: '/', + expires: shouldDelete ? 0 : Date.now() + 1000 * 60 * 60 * 24, // 1 day + sameSite: 'none', + }) if (theme) { document.body.setAttribute(THEME_DATA_ATTRIBUTE, theme) } else { From 37090521bde28e50eff62b16359e2910fdafa919 Mon Sep 17 00:00:00 2001 From: Jacob Kofoed Date: Fri, 22 May 2026 10:07:26 +0200 Subject: [PATCH 2/2] Simplified editor signal setup --- packages/runtime/src/editor-preview.main.ts | 32 +++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/runtime/src/editor-preview.main.ts b/packages/runtime/src/editor-preview.main.ts index 4bef8a0d9..c440d268c 100644 --- a/packages/runtime/src/editor-preview.main.ts +++ b/packages/runtime/src/editor-preview.main.ts @@ -247,6 +247,20 @@ export const createRoot = ( testMode: false, }) const themeSignal = signal(null) + themeSignal.subscribe((theme) => { + if (isDefined(theme)) { + document.documentElement.setAttribute(THEME_DATA_ATTRIBUTE, theme) + } else { + document.documentElement.removeAttribute(THEME_DATA_ATTRIBUTE) + } + dataSignal.update((data) => ({ + ...data, + Page: { + ...(data.Page ?? {}), + Theme: theme ?? null, + }, + })) + }) const resizeCanvasOptions: { viewport?: { height: number | null } enabled?: boolean @@ -1178,11 +1192,6 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d expires: shouldDelete ? 0 : Date.now() + 1000 * 60 * 60 * 24, // 1 day sameSite: 'none', }) - if (theme) { - document.body.setAttribute(THEME_DATA_ATTRIBUTE, theme) - } else { - document.body.removeAttribute(THEME_DATA_ATTRIBUTE) - } requestResizeCanvas(resizeCanvasOptions) break } @@ -2116,19 +2125,6 @@ function setupThemeSubscription( ) { _themeRootSignal?.destroy() _themeRootSignal = getThemeSignal(component, dataSignal, env) - _themeRootSignal.subscribe((theme) => { - if (isDefined(theme)) { - document.documentElement.setAttribute(THEME_DATA_ATTRIBUTE, theme) - } else { - document.documentElement.removeAttribute(THEME_DATA_ATTRIBUTE) - } - dataSignal.update((data) => ({ - ...data, - Page: { - Theme: theme ?? null, - }, - })) - }) return _themeRootSignal }