kss-modern 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@ A modern, KSS-compatible styleguide generator. Parses KSS comment blocks from CS
6
6
 
7
7
  - KSS-compatible comment parsing from CSS/SCSS files
8
8
  - Live component previews with modifier variants
9
- - Theme dropdowns — a global one in the header (`themes` option) and per-section ones (`Themes:`) — switch previews between the default and themed views
9
+ - Theme dropdowns — a global one in the header (`previewThemes` option) and per-section ones (`Themes:`) — switch previews between the default and themed views, optionally loading a stylesheet per theme
10
10
  - Pug template support via worker thread pool
11
11
  - Color palette and icon gallery documentation
12
12
  - Figma embed integration with light/dark theme sync
@@ -99,29 +99,60 @@ declare function createLogger(tag?: string): Logger;
99
99
  /** Shared styleguide logger instance. */
100
100
  declare const logger: Logger;
101
101
 
102
- interface StyleguideConfiguration {
102
+ /** The styleguide's accent colour: one value, or one per color scheme. */
103
+ type StyleguideBrandColor = string | {
104
+ light: string;
105
+ dark: string;
106
+ };
107
+ /**
108
+ * One entry of the header's **Theme** dropdown — an alternative theme context the previews can be
109
+ * shown in, not a color scheme (that is the separate System/Light/Dark toggle).
110
+ */
111
+ interface PreviewTheme {
112
+ /**
113
+ * The theme's class or class list — `'theme-midnight'`, `'.theme-midnight.compact'` — added to
114
+ * the `<html>` of every preview iframe while the theme is selected.
115
+ */
116
+ value: string;
117
+ /** The label shown in the dropdown. */
118
+ label: string;
119
+ /**
120
+ * Stylesheets loaded into a preview while this theme is selected, layered on top of
121
+ * `html.assets.css` (they are never replaced). Every preview document carries a `<link>` for
122
+ * each of these from the start — inert until the theme is selected — so switching costs no
123
+ * request and shows no flash.
124
+ *
125
+ * The CSS is keyed on the theme's class list, so a section's `Themes:` entry gets the same
126
+ * stylesheets as soon as it resolves to the same classes (`.theme-midnight` here and in the
127
+ * KSS comment); a section theme that matches no configured entry simply loads no extra CSS.
128
+ */
129
+ css?: string[];
130
+ }
131
+ /** Every styleguide option except the accent colour, which carries the deprecated `theme` alias. */
132
+ interface StyleguideOptions {
103
133
  mode: 'development' | 'production';
104
134
  outDir: string;
105
135
  contentDir: `${string}/`;
106
136
  projectTitle: string;
107
137
  deactivateDarkMode?: boolean;
108
- /**
109
- * Themes offered by the header's global **Theme** dropdown. Each entry is a theme class (or class
110
- * list — `'theme-midnight'`, `'.theme-midnight.compact'`) that is added to the `<html>` of every
111
- * preview iframe while selected, plus the label shown in the dropdown. A section's own `Themes:`
112
- * dropdown overrides the global theme for that section.
113
- */
114
- themes?: {
115
- value: string;
116
- label: string;
117
- }[];
118
138
  launchInEditor?: boolean | {
119
139
  rootDir: string;
120
140
  };
121
- theme: string | {
122
- light: string;
123
- dark: string;
124
- };
141
+ /** The themes offered by the header's **Theme** dropdown. */
142
+ previewThemes?: PreviewTheme[];
143
+ /** @deprecated Renamed to `previewThemes`, to tell it apart from `brandColor`. */
144
+ themes?: PreviewTheme[];
145
+ /**
146
+ * Reload a preview iframe when its theme changes, instead of swapping the theme's classes and
147
+ * stylesheets into the loaded document.
148
+ *
149
+ * Off by default: the in-place swap is instant and keeps the preview's state. Turn it on when a
150
+ * preview's own JavaScript reads styling at startup — components that measure, canvas/chart
151
+ * rendering, web components that snapshot tokens on connect — and so needs to run again against
152
+ * the new theme. A preview is reloaded only when the visitor actually changes a theme, never on
153
+ * the initial page load.
154
+ */
155
+ reloadPreviewsOnThemeChange?: boolean;
125
156
  logoSignet?: {
126
157
  href: string;
127
158
  } | {
@@ -145,6 +176,35 @@ interface StyleguideConfiguration {
145
176
  ogImage?: (section: in2Section) => string;
146
177
  };
147
178
  }
179
+ /**
180
+ * The styleguide configuration. The accent colour is required under one of its two names:
181
+ * `brandColor`, or the deprecated `theme`.
182
+ *
183
+ * `theme` never had anything to do with the preview themes; it is the colour behind
184
+ * `<meta name="theme-color">`, the generated favicons and the styleguide UI's highlight — hence
185
+ * the rename, which also ends its collision with `themes` / `previewThemes`.
186
+ */
187
+ type StyleguideConfiguration = (StyleguideOptions & {
188
+ brandColor: StyleguideBrandColor;
189
+ theme?: never;
190
+ }) | (StyleguideOptions & {
191
+ /** @deprecated Renamed to `brandColor` — this is the accent colour, not a preview theme. */
192
+ theme: StyleguideBrandColor;
193
+ brandColor?: never;
194
+ });
195
+ /**
196
+ * A configuration with the deprecated aliases resolved away. Everything past
197
+ * {@link resolveConfiguration} works with this, so no internal code has to know about the old names.
198
+ */
199
+ interface ResolvedStyleguideConfiguration extends StyleguideOptions {
200
+ brandColor: StyleguideBrandColor;
201
+ previewThemes: PreviewTheme[];
202
+ }
203
+ /**
204
+ * Resolve the deprecated `theme` / `themes` aliases into `brandColor` / `previewThemes`, warning
205
+ * once per option. Idempotent, so the public entry points can each call it without re-warning.
206
+ */
207
+ declare function resolveConfiguration(config: StyleguideConfiguration | ResolvedStyleguideConfiguration): ResolvedStyleguideConfiguration;
148
208
  interface StyleguideBuildOutput {
149
209
  errors?: {
150
210
  overwrittenSectionsIds?: string[];
@@ -198,7 +258,7 @@ declare function parseStyleguide(contentDir: StyleguideConfiguration['contentDir
198
258
  * Full build: parse, compile every section, and write all fullpage + preview files. Returns the
199
259
  * reusable context so the watcher can perform targeted incremental rebuilds afterwards.
200
260
  */
201
- declare function buildAll(config: StyleguideConfiguration): Promise<{
261
+ declare function buildAll(input: StyleguideConfiguration | ResolvedStyleguideConfiguration): Promise<{
202
262
  errors: StyleguideBuildOutput['errors'];
203
263
  context: StyleguideContext;
204
264
  }>;
@@ -212,7 +272,7 @@ declare function buildStyleguide(config: StyleguideConfiguration): Promise<Style
212
272
  * (cache-aware), re-resolve <insert-markup>, and rewrite just their fullpage + owning preview files.
213
273
  * `changedSectionIds` are the sections whose pug (or a dependency) changed.
214
274
  */
215
- declare function rebuildSections(config: StyleguideConfiguration, context: StyleguideContext, changedSectionIds: Iterable<string>): Promise<void>;
275
+ declare function rebuildSections(config: ResolvedStyleguideConfiguration, context: StyleguideContext, changedSectionIds: Iterable<string>): Promise<void>;
216
276
  /**
217
277
  * What triggered a {@link watchStyleguide} rebuild:
218
278
  * - `structural` — a CSS/SCSS/Markdown edit that can change section structure; the whole styleguide is rebuilt.
@@ -227,11 +287,11 @@ type StyleguideChange = {
227
287
  };
228
288
  /**
229
289
  * Builds the styleguide and watches for changes
230
- * @param config - The configuration for the styleguide
290
+ * @param input - The configuration for the styleguide
231
291
  * @param onChange - Optional callback invoked after each rebuild, with the change that triggered it
232
292
  * @param onError - Optional callback function to call when an error occurs while building the styleguide
233
293
  */
234
- declare function watchStyleguide(config: StyleguideConfiguration, onChange?: (change: StyleguideChange) => void, onError?: (errorData: StyleguideBuildOutput['errors']) => void): Promise<void>;
294
+ declare function watchStyleguide(input: StyleguideConfiguration | ResolvedStyleguideConfiguration, onChange?: (change: StyleguideChange) => void, onError?: (errorData: StyleguideBuildOutput['errors']) => void): Promise<void>;
235
295
 
236
- export { buildAll, buildStyleguide, createLogger, logger, parseStyleguide, rebuildSections, watchStyleguide };
237
- export type { LogBox, Logger, StyleguideChange, StyleguideConfiguration, StyleguideContext };
296
+ export { buildAll, buildStyleguide, createLogger, logger, parseStyleguide, rebuildSections, resolveConfiguration, watchStyleguide };
297
+ export type { LogBox, Logger, PreviewTheme, ResolvedStyleguideConfiguration, StyleguideBrandColor, StyleguideChange, StyleguideConfiguration, StyleguideContext };
@@ -99,29 +99,60 @@ declare function createLogger(tag?: string): Logger;
99
99
  /** Shared styleguide logger instance. */
100
100
  declare const logger: Logger;
101
101
 
102
- interface StyleguideConfiguration {
102
+ /** The styleguide's accent colour: one value, or one per color scheme. */
103
+ type StyleguideBrandColor = string | {
104
+ light: string;
105
+ dark: string;
106
+ };
107
+ /**
108
+ * One entry of the header's **Theme** dropdown — an alternative theme context the previews can be
109
+ * shown in, not a color scheme (that is the separate System/Light/Dark toggle).
110
+ */
111
+ interface PreviewTheme {
112
+ /**
113
+ * The theme's class or class list — `'theme-midnight'`, `'.theme-midnight.compact'` — added to
114
+ * the `<html>` of every preview iframe while the theme is selected.
115
+ */
116
+ value: string;
117
+ /** The label shown in the dropdown. */
118
+ label: string;
119
+ /**
120
+ * Stylesheets loaded into a preview while this theme is selected, layered on top of
121
+ * `html.assets.css` (they are never replaced). Every preview document carries a `<link>` for
122
+ * each of these from the start — inert until the theme is selected — so switching costs no
123
+ * request and shows no flash.
124
+ *
125
+ * The CSS is keyed on the theme's class list, so a section's `Themes:` entry gets the same
126
+ * stylesheets as soon as it resolves to the same classes (`.theme-midnight` here and in the
127
+ * KSS comment); a section theme that matches no configured entry simply loads no extra CSS.
128
+ */
129
+ css?: string[];
130
+ }
131
+ /** Every styleguide option except the accent colour, which carries the deprecated `theme` alias. */
132
+ interface StyleguideOptions {
103
133
  mode: 'development' | 'production';
104
134
  outDir: string;
105
135
  contentDir: `${string}/`;
106
136
  projectTitle: string;
107
137
  deactivateDarkMode?: boolean;
108
- /**
109
- * Themes offered by the header's global **Theme** dropdown. Each entry is a theme class (or class
110
- * list — `'theme-midnight'`, `'.theme-midnight.compact'`) that is added to the `<html>` of every
111
- * preview iframe while selected, plus the label shown in the dropdown. A section's own `Themes:`
112
- * dropdown overrides the global theme for that section.
113
- */
114
- themes?: {
115
- value: string;
116
- label: string;
117
- }[];
118
138
  launchInEditor?: boolean | {
119
139
  rootDir: string;
120
140
  };
121
- theme: string | {
122
- light: string;
123
- dark: string;
124
- };
141
+ /** The themes offered by the header's **Theme** dropdown. */
142
+ previewThemes?: PreviewTheme[];
143
+ /** @deprecated Renamed to `previewThemes`, to tell it apart from `brandColor`. */
144
+ themes?: PreviewTheme[];
145
+ /**
146
+ * Reload a preview iframe when its theme changes, instead of swapping the theme's classes and
147
+ * stylesheets into the loaded document.
148
+ *
149
+ * Off by default: the in-place swap is instant and keeps the preview's state. Turn it on when a
150
+ * preview's own JavaScript reads styling at startup — components that measure, canvas/chart
151
+ * rendering, web components that snapshot tokens on connect — and so needs to run again against
152
+ * the new theme. A preview is reloaded only when the visitor actually changes a theme, never on
153
+ * the initial page load.
154
+ */
155
+ reloadPreviewsOnThemeChange?: boolean;
125
156
  logoSignet?: {
126
157
  href: string;
127
158
  } | {
@@ -145,6 +176,35 @@ interface StyleguideConfiguration {
145
176
  ogImage?: (section: in2Section) => string;
146
177
  };
147
178
  }
179
+ /**
180
+ * The styleguide configuration. The accent colour is required under one of its two names:
181
+ * `brandColor`, or the deprecated `theme`.
182
+ *
183
+ * `theme` never had anything to do with the preview themes; it is the colour behind
184
+ * `<meta name="theme-color">`, the generated favicons and the styleguide UI's highlight — hence
185
+ * the rename, which also ends its collision with `themes` / `previewThemes`.
186
+ */
187
+ type StyleguideConfiguration = (StyleguideOptions & {
188
+ brandColor: StyleguideBrandColor;
189
+ theme?: never;
190
+ }) | (StyleguideOptions & {
191
+ /** @deprecated Renamed to `brandColor` — this is the accent colour, not a preview theme. */
192
+ theme: StyleguideBrandColor;
193
+ brandColor?: never;
194
+ });
195
+ /**
196
+ * A configuration with the deprecated aliases resolved away. Everything past
197
+ * {@link resolveConfiguration} works with this, so no internal code has to know about the old names.
198
+ */
199
+ interface ResolvedStyleguideConfiguration extends StyleguideOptions {
200
+ brandColor: StyleguideBrandColor;
201
+ previewThemes: PreviewTheme[];
202
+ }
203
+ /**
204
+ * Resolve the deprecated `theme` / `themes` aliases into `brandColor` / `previewThemes`, warning
205
+ * once per option. Idempotent, so the public entry points can each call it without re-warning.
206
+ */
207
+ declare function resolveConfiguration(config: StyleguideConfiguration | ResolvedStyleguideConfiguration): ResolvedStyleguideConfiguration;
148
208
  interface StyleguideBuildOutput {
149
209
  errors?: {
150
210
  overwrittenSectionsIds?: string[];
@@ -198,7 +258,7 @@ declare function parseStyleguide(contentDir: StyleguideConfiguration['contentDir
198
258
  * Full build: parse, compile every section, and write all fullpage + preview files. Returns the
199
259
  * reusable context so the watcher can perform targeted incremental rebuilds afterwards.
200
260
  */
201
- declare function buildAll(config: StyleguideConfiguration): Promise<{
261
+ declare function buildAll(input: StyleguideConfiguration | ResolvedStyleguideConfiguration): Promise<{
202
262
  errors: StyleguideBuildOutput['errors'];
203
263
  context: StyleguideContext;
204
264
  }>;
@@ -212,7 +272,7 @@ declare function buildStyleguide(config: StyleguideConfiguration): Promise<Style
212
272
  * (cache-aware), re-resolve <insert-markup>, and rewrite just their fullpage + owning preview files.
213
273
  * `changedSectionIds` are the sections whose pug (or a dependency) changed.
214
274
  */
215
- declare function rebuildSections(config: StyleguideConfiguration, context: StyleguideContext, changedSectionIds: Iterable<string>): Promise<void>;
275
+ declare function rebuildSections(config: ResolvedStyleguideConfiguration, context: StyleguideContext, changedSectionIds: Iterable<string>): Promise<void>;
216
276
  /**
217
277
  * What triggered a {@link watchStyleguide} rebuild:
218
278
  * - `structural` — a CSS/SCSS/Markdown edit that can change section structure; the whole styleguide is rebuilt.
@@ -227,11 +287,11 @@ type StyleguideChange = {
227
287
  };
228
288
  /**
229
289
  * Builds the styleguide and watches for changes
230
- * @param config - The configuration for the styleguide
290
+ * @param input - The configuration for the styleguide
231
291
  * @param onChange - Optional callback invoked after each rebuild, with the change that triggered it
232
292
  * @param onError - Optional callback function to call when an error occurs while building the styleguide
233
293
  */
234
- declare function watchStyleguide(config: StyleguideConfiguration, onChange?: (change: StyleguideChange) => void, onError?: (errorData: StyleguideBuildOutput['errors']) => void): Promise<void>;
294
+ declare function watchStyleguide(input: StyleguideConfiguration | ResolvedStyleguideConfiguration, onChange?: (change: StyleguideChange) => void, onError?: (errorData: StyleguideBuildOutput['errors']) => void): Promise<void>;
235
295
 
236
- export { buildAll, buildStyleguide, createLogger, logger, parseStyleguide, rebuildSections, watchStyleguide };
237
- export type { LogBox, Logger, StyleguideChange, StyleguideConfiguration, StyleguideContext };
296
+ export { buildAll, buildStyleguide, createLogger, logger, parseStyleguide, rebuildSections, resolveConfiguration, watchStyleguide };
297
+ export type { LogBox, Logger, PreviewTheme, ResolvedStyleguideConfiguration, StyleguideBrandColor, StyleguideChange, StyleguideConfiguration, StyleguideContext };
@@ -1353,6 +1353,7 @@ async function generateFullPageFile(data) {
1353
1353
  const computedStyleTags = data.css.filter((entry) => entry.type !== "overwriteStyleguide").map((css) => {
1354
1354
  return `<link rel="stylesheet" type="text/css" href="${css.src}">`;
1355
1355
  }).join("\n");
1356
+ const computedThemeStyleTags = (data.previewThemes ?? []).flatMap((theme) => (theme.css ?? []).map((src) => ({ src, classList: themeClassList(theme.value) }))).filter((entry) => entry.classList).map((entry) => `<link rel="stylesheet" type="text/css" href="${entry.src}" media="not all" data-theme-css="${sanitizeSpecialCharacters(entry.classList)}">`).join("\n");
1356
1357
  const content = `
1357
1358
  <!DOCTYPE html>
1358
1359
  <html lang="${data.page.lang}"${data.page.htmlclass ? ` class="scroll-smooth ${data.page.htmlclass}"` : ""} data-styleguide-dark-mode="${supportsDarkMode}">
@@ -1364,12 +1365,13 @@ async function generateFullPageFile(data) {
1364
1365
  <meta name="generator" content="styleguide">
1365
1366
  <link rel="icon" type="image/svg+xml" href="/styleguide-assets/favicon/fullpage.svg">
1366
1367
  ${data.ogImageUrl ? `<meta property="og:image" content="${data.ogImageUrl}">` : ""}
1367
- ${typeof data.theme === "object" && "dark" in data.theme && "light" in data.theme ? `
1368
- <meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
1369
- <meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
1370
- ` : `<meta name="theme-color" content="${data.theme}">`}
1371
- <script type="module" src="/styleguide-assets/fullpage-B7IV3eSt.js"><\/script>
1368
+ ${typeof data.brandColor === "object" && "dark" in data.brandColor && "light" in data.brandColor ? `
1369
+ <meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.brandColor.light}">
1370
+ <meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.brandColor.dark}">
1371
+ ` : `<meta name="theme-color" content="${data.brandColor}">`}
1372
+ <script type="module" src="/styleguide-assets/fullpage-DSD6-0qF.js"><\/script>
1372
1373
  ${computedStyleTags}
1374
+ ${computedThemeStyleTags}
1373
1375
  </head>
1374
1376
  <body${data.page.bodyclass ? ` class="${data.page.bodyclass}"` : ""}>
1375
1377
  ${data.html}
@@ -1435,7 +1437,7 @@ function getHeaderHtml(config) {
1435
1437
  </button>
1436
1438
 
1437
1439
  <div class="flex gap-4">
1438
- ${config.themes?.length ? renderGlobalThemeSelect(config.themes) : ""}
1440
+ ${config.previewThemes.length > 0 ? renderGlobalThemeSelect(config.previewThemes) : ""}
1439
1441
  ${config.mode === "development" && config.launchInEditor ? `
1440
1442
  <form class="hidden editor-select md:block">
1441
1443
  <fieldset class="flex items-center rounded-3xl border border-styleguide-border">
@@ -2219,7 +2221,7 @@ async function generatePreviewFile(data) {
2219
2221
  const shouldRenderMetaDescription = data.page.description && data.page.description.length > 0 && !(data.page.description.includes("<") && data.page.description.includes(">"));
2220
2222
  const content = `
2221
2223
  <!DOCTYPE html>
2222
- <html lang="${data.page.lang}" class="scroll-smooth">
2224
+ <html lang="${data.page.lang}" class="scroll-smooth"${data.reloadPreviewsOnThemeChange ? " data-reload-previews-on-theme-change" : ""}>
2223
2225
  <head>
2224
2226
  <title>${sanitizeSpecialCharacters(data.page.title)}</title>
2225
2227
  ${data.page.description && shouldRenderMetaDescription ? `<meta name="description" content="${data.page.description.replaceAll(`'`, "").replaceAll(`"`, "")}">` : ""}
@@ -2228,10 +2230,10 @@ async function generatePreviewFile(data) {
2228
2230
  <meta name="generator" content="styleguide">
2229
2231
  <link rel="icon" type="image/svg+xml" href="/styleguide-assets/favicon/preview.svg">
2230
2232
  ${data.ogImageUrl ? `<meta property="og:image" content="${data.ogImageUrl}">` : ""}
2231
- ${typeof data.theme === "object" && "dark" in data.theme && "light" in data.theme ? `
2232
- <meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
2233
- <meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
2234
- ` : `<meta name="theme-color" content="${data.theme}">`}
2233
+ ${typeof data.brandColor === "object" && "dark" in data.brandColor && "light" in data.brandColor ? `
2234
+ <meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.brandColor.light}">
2235
+ <meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.brandColor.dark}">
2236
+ ` : `<meta name="theme-color" content="${data.brandColor}">`}
2235
2237
  <link rel="stylesheet" type="text/css" href="/styleguide-assets/kss-modern-Cg1aeKi1.css">
2236
2238
  <script>
2237
2239
  //#region client/lib/iframe-resize.ts
@@ -2395,7 +2397,7 @@ document.addEventListener("DOMContentLoaded", () => {
2395
2397
  //#endregion
2396
2398
  ;
2397
2399
  <\/script>
2398
- <script type="module" src="/styleguide-assets/preview-tkLDBWOv.js"><\/script>
2400
+ <script type="module" src="/styleguide-assets/preview-CCjPdowU.js"><\/script>
2399
2401
  <link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
2400
2402
  <link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
2401
2403
  <link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-300-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
@@ -2405,7 +2407,7 @@ document.addEventListener("DOMContentLoaded", () => {
2405
2407
  ${computedStyleTags}
2406
2408
  <style>
2407
2409
  :root {
2408
- --styleguide-color-theme-highlight: ${typeof data.theme === "string" ? data.theme : `light-dark(${data.theme.light}, ${data.theme.dark})`};
2410
+ --styleguide-color-theme-highlight: ${typeof data.brandColor === "string" ? data.brandColor : `light-dark(${data.brandColor.light}, ${data.brandColor.dark})`};
2409
2411
  }
2410
2412
  </style>
2411
2413
  </head>
@@ -2595,6 +2597,28 @@ function watchStyleguideForChanges(watchPath, handlers) {
2595
2597
  });
2596
2598
  }
2597
2599
 
2600
+ const warnedDeprecations = /* @__PURE__ */ new Set();
2601
+ function warnDeprecatedOption(deprecated, replacement) {
2602
+ if (warnedDeprecations.has(deprecated))
2603
+ return;
2604
+ warnedDeprecations.add(deprecated);
2605
+ logger.warn(`\`${deprecated}\` is deprecated and will be removed in the next major \u2014 rename it to \`${replacement}\`.`);
2606
+ }
2607
+ function resolveConfiguration(config) {
2608
+ const { theme, themes, ...options } = config;
2609
+ if (theme !== void 0)
2610
+ warnDeprecatedOption("theme", "brandColor");
2611
+ if (themes !== void 0)
2612
+ warnDeprecatedOption("themes", "previewThemes");
2613
+ const brandColor = options.brandColor ?? theme;
2614
+ if (brandColor === void 0)
2615
+ throw new Error("Styleguide configuration is missing `brandColor` (the styleguide accent colour).");
2616
+ return {
2617
+ ...options,
2618
+ brandColor,
2619
+ previewThemes: options.previewThemes ?? themes ?? []
2620
+ };
2621
+ }
2598
2622
  async function parseStyleguide(contentDir) {
2599
2623
  const styleguideContentPaths = await glob(`${contentDir}/**/*.{css,scss}`);
2600
2624
  const styleguideContent = await Promise.all(
@@ -2665,8 +2689,9 @@ async function writeFullPageFile(config, baseDirectory, section) {
2665
2689
  },
2666
2690
  css: config.html.assets.css,
2667
2691
  js: config.html.assets.js,
2692
+ previewThemes: config.previewThemes,
2668
2693
  html: htmlMarkup,
2669
- theme: config.theme,
2694
+ brandColor: config.brandColor,
2670
2695
  deactivateDarkMode: config.deactivateDarkMode,
2671
2696
  ogImageUrl: config.plugins?.ogImage ? config.plugins.ogImage(section) : void 0
2672
2697
  });
@@ -2723,8 +2748,9 @@ function writePreviewFile(config, context, firstLevelIndex, secondLevelIndex) {
2723
2748
  alerts: getAlerts(),
2724
2749
  preloadIframes
2725
2750
  },
2726
- theme: config.theme,
2751
+ brandColor: config.brandColor,
2727
2752
  deactivateDarkMode: config.deactivateDarkMode,
2753
+ reloadPreviewsOnThemeChange: config.reloadPreviewsOnThemeChange,
2728
2754
  ogImageUrl: config.plugins?.ogImage ? config.plugins.ogImage(secondLevelSection) : void 0
2729
2755
  });
2730
2756
  }
@@ -2805,9 +2831,9 @@ async function buildContext(config) {
2805
2831
  };
2806
2832
  }
2807
2833
  const ASSETS_MARKER_FILE = ".kss-modern-assets";
2808
- function getAssetsBuildId(theme) {
2834
+ function getAssetsBuildId(brandColor) {
2809
2835
  return `kss-modern-Cg1aeKi1.css
2810
- ${JSON.stringify(theme)}
2836
+ ${JSON.stringify(brandColor)}
2811
2837
  `;
2812
2838
  }
2813
2839
  async function readAssetsBuildId(markerPath) {
@@ -2829,17 +2855,18 @@ async function copyStyleguideAssets(config) {
2829
2855
  const assetsDirectoryPath = findAssetsDirectoryPath();
2830
2856
  const assetsDirectoryOutputPath = path.join(config.outDir, "styleguide-assets");
2831
2857
  const markerPath = path.join(assetsDirectoryOutputPath, ASSETS_MARKER_FILE);
2832
- const expectedBuildId = getAssetsBuildId(config.theme);
2858
+ const expectedBuildId = getAssetsBuildId(config.brandColor);
2833
2859
  const currentBuildId = await readAssetsBuildId(markerPath);
2834
2860
  if (currentBuildId === expectedBuildId) {
2835
2861
  return;
2836
2862
  }
2837
2863
  await fs.remove(assetsDirectoryOutputPath);
2838
2864
  await fs.copy(assetsDirectoryPath, assetsDirectoryOutputPath);
2839
- await generateFaviconFiles(assetsDirectoryOutputPath, config.theme);
2865
+ await generateFaviconFiles(assetsDirectoryOutputPath, config.brandColor);
2840
2866
  await fs.writeFile(markerPath, expectedBuildId);
2841
2867
  }
2842
- async function buildAll(config) {
2868
+ async function buildAll(input) {
2869
+ const config = resolveConfiguration(input);
2843
2870
  if (config.mode === "production" && await fs.exists(config.outDir)) {
2844
2871
  const files = await glob(`${config.outDir}/**/*.html`);
2845
2872
  await Promise.all(files.map((file) => fs.remove(file)));
@@ -2926,7 +2953,8 @@ async function rebuildSections(config, context, changedSectionIds) {
2926
2953
  }
2927
2954
  await Promise.all(writeTasks);
2928
2955
  }
2929
- async function watchStyleguide(config, onChange, onError) {
2956
+ async function watchStyleguide(input, onChange, onError) {
2957
+ const config = resolveConfiguration(input);
2930
2958
  const initialBuild = await buildAll(config);
2931
2959
  if (onError && initialBuild.errors) {
2932
2960
  onError(initialBuild.errors);
@@ -2966,4 +2994,4 @@ async function watchStyleguide(config, onChange, onError) {
2966
2994
  });
2967
2995
  }
2968
2996
 
2969
- export { buildAll, buildStyleguide, logger, parseStyleguide, rebuildSections, watchStyleguide };
2997
+ export { buildAll, buildStyleguide, logger, parseStyleguide, rebuildSections, resolveConfiguration, watchStyleguide };
@@ -11,10 +11,11 @@
11
11
  "file": "code-highlight-Fm7cxf-E.js",
12
12
  "name": "code-highlight"
13
13
  },
14
- "_preview-theme-DS4xqXIm.js": {
15
- "file": "preview-theme-DS4xqXIm.js",
14
+ "_preview-theme-DIgnwL5g.js": {
15
+ "file": "preview-theme-DIgnwL5g.js",
16
16
  "name": "preview-theme",
17
17
  "imports": [
18
+ "_theme-document-CtY2qFyJ.js",
18
19
  "_section-previews-CnlrC8Gz.js"
19
20
  ]
20
21
  },
@@ -34,18 +35,23 @@
34
35
  "file": "signal-ZVBNTRLw.js",
35
36
  "name": "signal"
36
37
  },
38
+ "_theme-document-CtY2qFyJ.js": {
39
+ "file": "theme-document-CtY2qFyJ.js",
40
+ "name": "theme-document"
41
+ },
37
42
  "_utils-DtB-AzJa.js": {
38
43
  "file": "utils-DtB-AzJa.js",
39
44
  "name": "utils"
40
45
  },
41
46
  "client/fullpage.ts": {
42
- "file": "fullpage-B7IV3eSt.js",
47
+ "file": "fullpage-DSD6-0qF.js",
43
48
  "name": "fullpage",
44
49
  "src": "client/fullpage.ts",
45
50
  "isEntry": true,
46
51
  "imports": [
47
52
  "_rolldown-runtime-B1bRi_D7.js",
48
- "_shared-hGcWlnRM.js"
53
+ "_shared-hGcWlnRM.js",
54
+ "_theme-document-CtY2qFyJ.js"
49
55
  ],
50
56
  "dynamicImports": [
51
57
  "node_modules/axe-core/axe.js",
@@ -81,12 +87,12 @@
81
87
  "isDynamicEntry": true
82
88
  },
83
89
  "client/lib/global-theme-select.ts": {
84
- "file": "global-theme-select-DM7GN8Dn.js",
90
+ "file": "global-theme-select-DCnqGEUr.js",
85
91
  "name": "global-theme-select",
86
92
  "src": "client/lib/global-theme-select.ts",
87
93
  "isDynamicEntry": true,
88
94
  "imports": [
89
- "_preview-theme-DS4xqXIm.js"
95
+ "_preview-theme-DIgnwL5g.js"
90
96
  ]
91
97
  },
92
98
  "client/lib/html-validator.ts": {
@@ -113,13 +119,13 @@
113
119
  ]
114
120
  },
115
121
  "client/lib/section-theme-select.ts": {
116
- "file": "section-theme-select-BHhiP4pl.js",
122
+ "file": "section-theme-select-CVOwp7VZ.js",
117
123
  "name": "section-theme-select",
118
124
  "src": "client/lib/section-theme-select.ts",
119
125
  "isDynamicEntry": true,
120
126
  "imports": [
121
127
  "_section-previews-CnlrC8Gz.js",
122
- "_preview-theme-DS4xqXIm.js"
128
+ "_preview-theme-DIgnwL5g.js"
123
129
  ]
124
130
  },
125
131
  "client/preview-inline.ts": {
@@ -129,7 +135,7 @@
129
135
  "isEntry": true
130
136
  },
131
137
  "client/preview.ts": {
132
- "file": "preview-tkLDBWOv.js",
138
+ "file": "preview-CCjPdowU.js",
133
139
  "name": "preview",
134
140
  "src": "client/preview.ts",
135
141
  "isEntry": true,