manager.mjs (1857B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 import { addons } from "@storybook/manager-api"; 6 import { 7 GLOBALS_UPDATED, 8 UPDATE_GLOBALS, 9 SET_GLOBALS, 10 } from "@storybook/core-events"; 11 import darkTheme from "./theme-dark.mjs"; 12 import lightTheme from "./theme-light.mjs"; 13 14 // Change favicon 15 const link = document.createElement("link"); 16 link.setAttribute("rel", "shortcut icon"); 17 link.setAttribute("href", "chrome://branding/content/document.ico"); 18 document.head.appendChild(link); 19 20 const mql = window.matchMedia("(prefers-color-scheme: dark)"); 21 const getToolbarTheme = () => { 22 // read ‘theme’ from globals in URL if present (initial load) 23 const g = new URLSearchParams(location.search).get("globals"); 24 return g?.match(/(?:^|,)theme:([^,]+)/)?.[1] ?? null; // 'light' | 'dark' | 'system' | null 25 }; 26 27 let selected = getToolbarTheme() || "system"; 28 const pickTheme = () => { 29 if (selected === "dark") { 30 return darkTheme; 31 } 32 if (selected === "light") { 33 return lightTheme; 34 } 35 return mql.matches ? darkTheme : lightTheme; 36 }; 37 38 const apply = () => addons.setConfig({ theme: pickTheme() }); 39 apply(); 40 41 // update when OS changes (only affects 'system') 42 const onOsChange = () => { 43 if (selected === "system") { 44 apply(); 45 } 46 }; 47 mql.addEventListener?.("change", onOsChange) || mql.addListener?.(onOsChange); 48 49 // update when toolbar changes (cover all events some builds emit) 50 const channel = addons.getChannel(); 51 const onGlobals = ({ globals }) => { 52 if (!globals?.theme) { 53 return; 54 } 55 selected = globals.theme; // 'light' | 'dark' | 'system' 56 apply(); 57 }; 58 channel.on(SET_GLOBALS, onGlobals); 59 channel.on(UPDATE_GLOBALS, onGlobals); 60 channel.on(GLOBALS_UPDATED, onGlobals);