diff --git a/Source/.storybook/manager.js b/Source/.storybook/manager.js new file mode 100644 index 0000000..5a2ff8a --- /dev/null +++ b/Source/.storybook/manager.js @@ -0,0 +1,30 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { addons } from 'storybook/manager-api'; +import { themes } from 'storybook/theming'; + +const urlParams = new URLSearchParams(window.location.search); +let currentTheme = urlParams.get('docsSiteTheme') ?? 'dark'; + +addons.setConfig({ + theme: currentTheme === 'light' ? themes.light : themes.dark, +}); + +// Relay the current theme to the preview canvas whenever a story renders, +// so the PrimeReact component theme stays in sync with the docs-site preference. +addons.getChannel().on('STORY_RENDERED', () => { + addons.getChannel().emit('STORYBOOK_THEME_CHANGE', { theme: currentTheme }); +}); + +// Receive theme-sync messages from the embedding docs site (StorybookEmbed.astro). +// Reload the manager with the new theme in the URL so addons.setConfig takes effect. +window.addEventListener('message', (event) => { + if (event.data?.type !== 'STORYBOOK_THEME_CHANGE') return; + const newTheme = event.data.theme; + if (currentTheme === newTheme) return; + currentTheme = newTheme; + const url = new URL(window.location.href); + url.searchParams.set('docsSiteTheme', newTheme); + window.location.href = url.toString(); +}); diff --git a/Source/.storybook/preview.js b/Source/.storybook/preview.js index 0541e09..8d43d14 100644 --- a/Source/.storybook/preview.js +++ b/Source/.storybook/preview.js @@ -1,6 +1,7 @@ // Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +import { addons } from 'storybook/preview-api'; import React from 'react'; import 'primeicons/primeicons.css'; import './preview.css'; @@ -46,13 +47,12 @@ const ALL_BODY_CLASSES = Object.values(STYLING_MODES) .map(mode => mode.bodyClass) .filter(Boolean); -// Tracks the theme pushed from the embedding docs site via postMessage. +// Tracks the theme relayed from manager.js via the Storybook channel. // null means "not embedded — use the toolbar selection". let _docsSiteTheme = null; -window.addEventListener('message', (event) => { - if (event.data?.type !== 'STORYBOOK_THEME_CHANGE') return; - _docsSiteTheme = event.data.theme === 'light' ? 'lara-light' : 'lara-dark'; +addons.getChannel().on('STORYBOOK_THEME_CHANGE', ({ theme }) => { + _docsSiteTheme = theme === 'light' ? 'lara-light' : 'lara-dark'; const mode = STYLING_MODES[_docsSiteTheme]; if (mode) { applyThemeLink(mode.themeUrl);