@ciderpress/ui 1.0.0-rc.3 → 1.0.0-rc.5

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.
Files changed (67) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.mjs +4 -3
  3. package/dist/node.d.ts +1 -1
  4. package/dist/node.mjs +316 -50
  5. package/dist/theme/components/footer/site-footer.tsx +68 -9
  6. package/dist/theme/components/home/feature-card.tsx +5 -8
  7. package/dist/theme/components/home/feature.tsx +31 -11
  8. package/dist/theme/components/home/hero-demo-custom.tsx +116 -0
  9. package/dist/theme/components/home/hero-demo.css +27 -0
  10. package/dist/theme/components/home/layout.tsx +149 -26
  11. package/dist/theme/components/home/split-visual-custom.tsx +26 -0
  12. package/dist/theme/components/home/workspaces.tsx +39 -3
  13. package/dist/theme/components/nav/branch-tag.tsx +7 -7
  14. package/dist/theme/components/nav/ciderpress-header.css +2 -1
  15. package/dist/theme/components/nav/ciderpress-header.tsx +26 -3
  16. package/dist/theme/components/nav/ciderpress-nav-social-links.tsx +9 -7
  17. package/dist/theme/components/nav/floating-branch-indicator.tsx +7 -7
  18. package/dist/theme/components/nav/header-icon.css +24 -0
  19. package/dist/theme/components/nav/header-icon.tsx +119 -0
  20. package/dist/theme/components/nav/header-logo.css +16 -0
  21. package/dist/theme/components/nav/header-logo.tsx +200 -0
  22. package/dist/theme/components/nav/layout.tsx +45 -7
  23. package/dist/theme/components/nav/nav-logo.tsx +5 -1
  24. package/dist/theme/components/shared/card-icon.tsx +37 -0
  25. package/dist/theme/components/shared/ciderpress-logo.tsx +5 -1
  26. package/dist/theme/components/shared/icon.tsx +119 -35
  27. package/dist/theme/components/shared/resolve-card-icon.ts +53 -12
  28. package/dist/theme/components/shared/section-card.tsx +9 -6
  29. package/dist/theme/components/sidebar/sidebar-links.tsx +6 -2
  30. package/dist/theme/components/theme-provider.tsx +27 -11
  31. package/dist/theme/components/workspaces/card.tsx +7 -9
  32. package/dist/theme/hooks/use-ciderpress.ts +60 -5
  33. package/dist/theme/lib/read-social-links.ts +4 -3
  34. package/dist/theme/lib/theme-favicon.ts +1 -1
  35. package/dist/theme/lib/with-mount-base.ts +31 -0
  36. package/package.json +13 -13
  37. package/src/theme/components/footer/site-footer.tsx +68 -9
  38. package/src/theme/components/home/feature-card.tsx +5 -8
  39. package/src/theme/components/home/feature.tsx +31 -11
  40. package/src/theme/components/home/hero-demo-custom.tsx +116 -0
  41. package/src/theme/components/home/hero-demo.css +27 -0
  42. package/src/theme/components/home/layout.tsx +149 -26
  43. package/src/theme/components/home/split-visual-custom.tsx +26 -0
  44. package/src/theme/components/home/workspaces.tsx +39 -3
  45. package/src/theme/components/nav/branch-tag.tsx +7 -7
  46. package/src/theme/components/nav/ciderpress-header.css +2 -1
  47. package/src/theme/components/nav/ciderpress-header.tsx +26 -3
  48. package/src/theme/components/nav/ciderpress-nav-social-links.tsx +9 -7
  49. package/src/theme/components/nav/floating-branch-indicator.tsx +7 -7
  50. package/src/theme/components/nav/header-icon.css +24 -0
  51. package/src/theme/components/nav/header-icon.tsx +119 -0
  52. package/src/theme/components/nav/header-logo.css +16 -0
  53. package/src/theme/components/nav/header-logo.tsx +200 -0
  54. package/src/theme/components/nav/layout.tsx +45 -7
  55. package/src/theme/components/nav/nav-logo.tsx +5 -1
  56. package/src/theme/components/shared/card-icon.tsx +37 -0
  57. package/src/theme/components/shared/ciderpress-logo.tsx +5 -1
  58. package/src/theme/components/shared/icon.tsx +119 -35
  59. package/src/theme/components/shared/resolve-card-icon.ts +53 -12
  60. package/src/theme/components/shared/section-card.tsx +9 -6
  61. package/src/theme/components/sidebar/sidebar-links.tsx +6 -2
  62. package/src/theme/components/theme-provider.tsx +27 -11
  63. package/src/theme/components/workspaces/card.tsx +7 -9
  64. package/src/theme/hooks/use-ciderpress.ts +60 -5
  65. package/src/theme/lib/read-social-links.ts +4 -3
  66. package/src/theme/lib/theme-favicon.ts +1 -1
  67. package/src/theme/lib/with-mount-base.ts +31 -0
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { default as React_2 } from 'react';
1
+ import { default as React_2 } from 'react';
2
2
 
3
3
  /**
4
4
  * Inline `<svg>` ciderpress wordmark logo that auto-themes to the active theme.
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BRAND_COLORS, DEFAULT_THEME_NAME } from "@ciderpress/theme";
2
+ import react from "react";
2
3
  const FONT_STACK = "'SF Mono', 'Fira Code', 'JetBrains Mono', Consolas, monospace";
3
4
  const LOGO_VIEWBOX = '-1 -1 588 101';
4
5
  const LOGO_FALLBACK_COLOR = BRAND_COLORS[DEFAULT_THEME_NAME].primary;
@@ -16,7 +17,7 @@ const CIDERPRESS_ART = Object.freeze([
16
17
  ]);
17
18
  function CiderpressLogo(props) {
18
19
  const title = props.title ?? 'ciderpress';
19
- return /*#__PURE__*/ React.createElement("svg", {
20
+ return /*#__PURE__*/ react.createElement("svg", {
20
21
  xmlns: "http://www.w3.org/2000/svg",
21
22
  viewBox: LOGO_VIEWBOX,
22
23
  className: props.className,
@@ -26,11 +27,11 @@ function CiderpressLogo(props) {
26
27
  color: `var(--rp-c-brand, ${LOGO_FALLBACK_COLOR})`
27
28
  },
28
29
  role: "img"
29
- }, /*#__PURE__*/ React.createElement("title", null, title), /*#__PURE__*/ React.createElement("g", {
30
+ }, /*#__PURE__*/ react.createElement("title", null, title), /*#__PURE__*/ react.createElement("g", {
30
31
  transform: `translate(${X_OFFSET}, ${Y_OFFSET})`,
31
32
  fontFamily: FONT_STACK,
32
33
  fill: "currentColor"
33
- }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ React.createElement("text", {
34
+ }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ react.createElement("text", {
34
35
  key: line,
35
36
  fontSize: FONT_SIZE,
36
37
  y: i * LINE_HEIGHT,
package/dist/node.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { CiderpressConfig } from '@ciderpress/config';
2
2
  import type { Paths } from '@ciderpress/config';
3
- import type { default as React_2 } from 'react';
3
+ import { default as React_2 } from 'react';
4
4
  import type { RspressPlugin } from '@rspress/core';
5
5
  import type { ThemeName } from '@ciderpress/config';
6
6
  import type { ThemeVariant } from '@ciderpress/theme';
package/dist/node.mjs CHANGED
@@ -4,13 +4,15 @@ import { existsSync, readFileSync } from "node:fs";
4
4
  import { createRequire } from "node:module";
5
5
  import node_path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
+ import { resolveOptionalIcon, serializeIcon } from "@ciderpress/config";
7
8
  import { BRAND_COLORS, BUILT_IN_THEMES, DEFAULT_THEME_NAME, defineTheme, isBuiltInTheme, resolveDefaultVariant, resolveThemeAlias, resolveThemeVariants, themeToCss } from "@ciderpress/theme";
8
- import { match as match_match } from "massaman/match";
9
+ import { P, match as match_match } from "massaman/match";
9
10
  import { visit as external_unist_util_visit_visit } from "unist-util-visit";
10
11
  import path_0 from "path";
11
12
  import { Project, SyntaxKind as external_ts_morph_SyntaxKind } from "ts-morph";
12
13
  import node_process from "node:process";
13
14
  import katex from "katex";
15
+ import react from "react";
14
16
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
15
17
  import { dirname as __rspack_dirname } from "node:path";
16
18
  import { createRequire as __rspack_createRequire } from "node:module";
@@ -8763,7 +8765,7 @@ const svgCaseSensitiveTagNames = [
8763
8765
  'textPath'
8764
8766
  ];
8765
8767
  const lib_h = createH(property_information_html, 'div');
8766
- const s = createH(property_information_svg, 'g', svgCaseSensitiveTagNames);
8768
+ const lib_s = createH(property_information_svg, 'g', svgCaseSensitiveTagNames);
8767
8769
  function lib_location(file) {
8768
8770
  const value = String(file);
8769
8771
  const indices = [];
@@ -8915,7 +8917,7 @@ function lib_element(state, node) {
8915
8917
  const name = (attribute.prefix ? attribute.prefix + ':' : '') + attribute.name;
8916
8918
  if (!own.call(proto, name)) properties[name] = attribute.value;
8917
8919
  }
8918
- const x = 'svg' === state.schema.space ? s : lib_h;
8920
+ const x = 'svg' === state.schema.space ? lib_s : lib_h;
8919
8921
  const result = x(node.tagName, properties, hast_util_from_parse5_lib_all(state, node.childNodes));
8920
8922
  patch(state, node, result);
8921
8923
  if ('template' === result.tagName) {
@@ -17285,8 +17287,14 @@ const APPLE_LOADER_CSS = readCss('css/loader-apple.css');
17285
17287
  const DOTS_LOADER_CSS = readCss('css/loader-dots.css');
17286
17288
  const DEFAULT_LOADER_STYLE = 'apple';
17287
17289
  function resolveLoaderCss(loader) {
17290
+ if (false === loader) return '';
17288
17291
  if ('classic' === loader) return BACKDROP_CSS + DOTS_LOADER_CSS;
17289
- return BACKDROP_CSS + APPLE_LOADER_CSS;
17292
+ if ('apple' === loader) return BACKDROP_CSS + APPLE_LOADER_CSS;
17293
+ if (isStaticLoader(loader)) return BACKDROP_CSS + buildCustomLoaderCss(loader);
17294
+ return BACKDROP_CSS;
17295
+ }
17296
+ function isStaticLoader(loader) {
17297
+ return 'content' in loader && 'string' == typeof loader.content;
17290
17298
  }
17291
17299
  function getThemeCss(themeName, loader = DEFAULT_LOADER_STYLE) {
17292
17300
  const loaderCss = resolveLoaderCss(loader);
@@ -17296,14 +17304,78 @@ function getThemeCss(themeName, loader = DEFAULT_LOADER_STYLE) {
17296
17304
  if (themeColors) return themeColors + loaderCss;
17297
17305
  return loaderCss;
17298
17306
  }
17307
+ function buildCustomLoaderCss(config) {
17308
+ const glyph = resolveGlyphUrl(config.content);
17309
+ const label = config.label ?? 'loading';
17310
+ const hasLabel = label.length > 0;
17311
+ const labelRule = match_match(hasLabel).with(true, ()=>buildLabelCss(label)).otherwise(()=>'');
17312
+ const marginLeft = match_match(hasLabel).with(true, ()=>'-110px').otherwise(()=>'-32px');
17313
+ return `
17314
+ html::before {
17315
+ content: '';
17316
+ position: fixed;
17317
+ top: 50%;
17318
+ left: 50%;
17319
+ width: 64px;
17320
+ height: 64px;
17321
+ margin-left: ${marginLeft};
17322
+ margin-top: -32px;
17323
+ background-image: ${glyph};
17324
+ background-repeat: no-repeat;
17325
+ background-position: center center;
17326
+ background-size: contain;
17327
+ image-rendering: pixelated;
17328
+ z-index: 9999;
17329
+ pointer-events: none;
17330
+ opacity: 1;
17331
+ transition: opacity 0.2s ease;
17332
+ }
17333
+ ${labelRule}
17334
+ html.cp-loader-fade::before,
17335
+ html.cp-loader-fade::after {
17336
+ opacity: 0;
17337
+ }
17338
+ html[data-cp-ready]::before,
17339
+ html[data-cp-ready]::after {
17340
+ display: none;
17341
+ }
17342
+ `;
17343
+ }
17344
+ function resolveGlyphUrl(content) {
17345
+ if (content.includes('<svg')) return `url("data:image/svg+xml;utf8,${encodeURIComponent(content)}")`;
17346
+ const safe = content.replaceAll('\\', String.raw`\\`).replaceAll('"', String.raw`\"`).replaceAll('<', String.raw`\3c `).replaceAll('\n', String.raw`\A `).replaceAll('\r', String.raw`\D `).replaceAll('\f', String.raw`\C `);
17347
+ return `url("${safe}")`;
17348
+ }
17349
+ function buildLabelCss(label) {
17350
+ const escaped = label.replaceAll('\\', String.raw`\\`).replaceAll("'", String.raw`\'`).replaceAll('<', String.raw`\3c `).replaceAll('\n', String.raw`\A `).replaceAll('\r', String.raw`\D `).replaceAll('\f', String.raw`\C `);
17351
+ return `html::after {
17352
+ content: '${escaped}';
17353
+ position: fixed;
17354
+ top: 50%;
17355
+ left: 50%;
17356
+ width: 160px;
17357
+ margin-left: -40px;
17358
+ margin-top: -14px;
17359
+ text-align: left;
17360
+ color: var(--cp-c-text-2, #888);
17361
+ font-family: 'Geist Pixel Square', ui-sans-serif, system-ui, sans-serif;
17362
+ font-size: 28px;
17363
+ font-weight: 400;
17364
+ line-height: 1;
17365
+ letter-spacing: 0.04em;
17366
+ z-index: 9999;
17367
+ pointer-events: none;
17368
+ opacity: 1;
17369
+ transition: opacity 0.2s ease;
17370
+ }`;
17371
+ }
17299
17372
  function ciderpressPlugin() {
17300
17373
  const componentsDir = node_path.resolve(import.meta.dirname, 'theme', 'components');
17301
17374
  return {
17302
17375
  name: 'ciderpress',
17303
17376
  globalUIComponents: [
17304
17377
  node_path.resolve(componentsDir, 'theme-provider.tsx'),
17305
- node_path.resolve(componentsDir, 'edit-source-button.tsx'),
17306
- node_path.resolve(componentsDir, 'nav', 'nav-logo.tsx')
17378
+ node_path.resolve(componentsDir, 'edit-source-button.tsx')
17307
17379
  ]
17308
17380
  };
17309
17381
  }
@@ -17379,6 +17451,8 @@ function mermaidPlugin(options = {}) {
17379
17451
  builderConfig: remarkMermaid.builderConfig
17380
17452
  };
17381
17453
  }
17454
+ const DEFAULT_LOADER_MIN_MS = 150;
17455
+ const DEFAULT_LOADER_MAX_MS = 5000;
17382
17456
  const VSCODE_SET_JS = "document.documentElement.dataset.ciderpressEnv='vscode'";
17383
17457
  const VSCODE_NAV_JS = readJs('js/vscode-nav.js');
17384
17458
  const LOADER_DOTS_JS = readJs('js/loader-dots.js');
@@ -17396,6 +17470,16 @@ function createRspressConfig(options) {
17396
17470
  fallback: []
17397
17471
  });
17398
17472
  const gitBranch = detectGitBranch();
17473
+ const brand = config.brand;
17474
+ const home = config.home;
17475
+ const editLink = config.editLink;
17476
+ const reportLink = config.reportLink;
17477
+ const topbar = config.topbar;
17478
+ const sidebar = config.sidebar;
17479
+ const footer = config.footer;
17480
+ const favicon = brand && brand.favicon;
17481
+ const loaderRaw = brand && brand.loader;
17482
+ const logoRaw = brand && brand.logo;
17399
17483
  const themeName = resolveThemeName(config, options.themeOverride);
17400
17484
  const userThemes = resolveUserThemes(config);
17401
17485
  const variant = resolveActiveVariant({
@@ -17408,35 +17492,58 @@ function createRspressConfig(options) {
17408
17492
  const themeColors = resolveThemeColors(config);
17409
17493
  const themeDarkColors = resolveThemeDarkColors(config);
17410
17494
  const userThemesCss = userThemes.map(themeToCss).join('');
17411
- const loaderStyle = config.loader ?? 'apple';
17495
+ const loaderStyle = resolveLoaderStyle(loaderRaw);
17412
17496
  const themeCss = getThemeCss(themeName, loaderStyle) + userThemesCss;
17413
17497
  const themeRegistry = [
17414
17498
  ...BUILT_IN_THEME_REGISTRY,
17415
17499
  ...userThemes.map(buildRegistryEntry)
17416
17500
  ];
17417
17501
  const isVscode = true === vscode;
17502
+ const loaderMaxMs = resolveLoaderMaxMs(loaderRaw);
17418
17503
  const headScriptBody = buildHeadScriptBody({
17419
17504
  variant,
17420
17505
  themeName,
17421
17506
  vscode: isVscode,
17422
- registry: themeRegistry
17507
+ registry: themeRegistry,
17508
+ loaderMaxMs,
17509
+ useDotsLoader: 'classic' === loaderStyle,
17510
+ loaderEnabled: false !== loaderStyle
17423
17511
  });
17424
17512
  const selfRequire = createRequire(import.meta.url);
17425
17513
  const reactAlias = node_path.dirname(selfRequire.resolve('react/package.json'));
17426
17514
  const reactDomAlias = node_path.dirname(selfRequire.resolve('react-dom/package.json'));
17427
17515
  const userConfigAlias = resolveUserConfigAlias(paths.repoRoot);
17428
- const resolvedLogo = resolveLogo(config.logo);
17516
+ const envBase = process.env.CIDERPRESS_BASE;
17517
+ const resolvedBase = match_match([
17518
+ envBase,
17519
+ config.base
17520
+ ]).with([
17521
+ P.string.minLength(1),
17522
+ P._
17523
+ ], ([b])=>b).with([
17524
+ P._,
17525
+ P.string.minLength(1)
17526
+ ], ([, b])=>b).otherwise(()=>'/');
17527
+ const siteBlock = buildSiteBlock({
17528
+ config,
17529
+ editLink,
17530
+ reportLink,
17531
+ topbar,
17532
+ sidebar,
17533
+ footer
17534
+ });
17429
17535
  return {
17430
17536
  root: paths.contentDir,
17431
17537
  outDir: paths.distDir,
17538
+ base: resolvedBase,
17432
17539
  route: {
17433
17540
  cleanUrls: true
17434
17541
  },
17435
17542
  llms: true,
17436
17543
  title: config.title ?? 'ciderpress',
17437
17544
  description: config.description ?? 'Documentation',
17438
- icon: config.favicon ?? '/icon.svg',
17439
- logo: resolvedLogo,
17545
+ icon: resolveFaviconPath(favicon),
17546
+ logo: match_match(logoRaw).with(P.string, (l)=>l).otherwise(()=>''),
17440
17547
  logoText: '',
17441
17548
  themeDir: node_path.resolve(import.meta.dirname, 'theme'),
17442
17549
  plugins: [
@@ -17451,7 +17558,12 @@ function createRspressConfig(options) {
17451
17558
  markdown: {
17452
17559
  remarkPlugins: [
17453
17560
  remarkMathToDiv
17454
- ]
17561
+ ],
17562
+ link: {
17563
+ checkDeadLinks: {
17564
+ excludes: (url)=>url.startsWith('/examples/')
17565
+ }
17566
+ }
17455
17567
  },
17456
17568
  builderConfig: {
17457
17569
  ...(()=>{
@@ -17462,6 +17574,7 @@ function createRspressConfig(options) {
17462
17574
  })(),
17463
17575
  html: {
17464
17576
  tags: [
17577
+ ...resolveFaviconLinkTags(favicon),
17465
17578
  {
17466
17579
  tag: 'style',
17467
17580
  children: themeCss,
@@ -17498,7 +17611,15 @@ function createRspressConfig(options) {
17498
17611
  __CIDERPRESS_THEME_DARK_COLORS__: JSON.stringify(JSON.stringify(themeDarkColors)),
17499
17612
  __CIDERPRESS_THEME_SWITCHER__: JSON.stringify(themeSwitcher),
17500
17613
  __CIDERPRESS_THEME_REGISTRY__: JSON.stringify(JSON.stringify(themeRegistry)),
17501
- __CIDERPRESS_VSCODE__: JSON.stringify(isVscode)
17614
+ __CIDERPRESS_VSCODE__: JSON.stringify(isVscode),
17615
+ __CIDERPRESS_HAS_USER_FAVICON__: JSON.stringify(void 0 !== favicon),
17616
+ __CIDERPRESS_LOADER_MIN_MS__: JSON.stringify(resolveLoaderMinMs(loaderRaw)),
17617
+ __CIDERPRESS_LOADER_MAX_MS__: JSON.stringify(resolveLoaderMaxMs(loaderRaw)),
17618
+ __CIDERPRESS_HAS_VARIANT_TOGGLE__: JSON.stringify(resolveHasVariantToggle({
17619
+ themeName,
17620
+ themeSwitcher,
17621
+ registry: themeRegistry
17622
+ }))
17502
17623
  }
17503
17624
  },
17504
17625
  output: {
@@ -17518,26 +17639,22 @@ function createRspressConfig(options) {
17518
17639
  standaloneScopePaths
17519
17640
  },
17520
17641
  ...{
17521
- socialLinks: config.socialLinks,
17642
+ socialLinks: serializeSocials(config.socials),
17522
17643
  sidebarAbove: resolveSidebarLinks({
17523
17644
  config,
17524
- position: 'above'
17645
+ position: 'top'
17525
17646
  }),
17526
17647
  sidebarBelow: resolveSidebarLinks({
17527
17648
  config,
17528
- position: 'below'
17649
+ position: 'bottom'
17529
17650
  }),
17530
- home: resolveHomeConfig(config),
17531
- ciderpressFooter: config.footer,
17532
- site: config.site
17651
+ home: resolveHomeConfig(home),
17652
+ ciderpressFooter: footer,
17653
+ site: siteBlock
17533
17654
  }
17534
17655
  }
17535
17656
  };
17536
17657
  }
17537
- function resolveLogo(logo) {
17538
- if ('string' == typeof logo) return logo;
17539
- if (null == logo) return '/logo.svg';
17540
- }
17541
17658
  function loadGenerated(params) {
17542
17659
  const p = node_path.resolve(params.contentDir, '.generated', params.name);
17543
17660
  if (!existsSync(p)) {
@@ -17565,17 +17682,35 @@ function resolveThemeName(config, override) {
17565
17682
  const registeredNames = collectRegisteredThemeNames(config);
17566
17683
  const requested = resolveThemeAlias(resolveRequestedThemeName(config, override));
17567
17684
  if (registeredNames.has(requested)) return requested;
17568
- process.stderr.write(`[ciderpress] Unknown theme '${requested}' — not a built-in and not declared in config.themes. Falling back to '${DEFAULT_THEME_NAME}'.\n`);
17685
+ process.stderr.write(`[ciderpress] Unknown theme '${requested}' — not a built-in and not declared in theme.themes. Falling back to '${DEFAULT_THEME_NAME}'.\n`);
17569
17686
  return DEFAULT_THEME_NAME;
17570
17687
  }
17571
17688
  function resolveRequestedThemeName(config, override) {
17572
17689
  if (override) return override;
17573
- if (config.theme && config.theme.name) return config.theme.name;
17690
+ const fromThemes = resolveDefaultEntryName(config.theme && config.theme.themes);
17691
+ if (void 0 !== fromThemes) return fromThemes;
17574
17692
  return DEFAULT_THEME_NAME;
17575
17693
  }
17694
+ function resolveDefaultEntryName(themes) {
17695
+ if (void 0 === themes || 0 === themes.length) return;
17696
+ const marked = themes.find(isDefaultMarked);
17697
+ if (void 0 !== marked) return readThemeEntryName(marked);
17698
+ return readThemeEntryName(themes[0]);
17699
+ }
17700
+ function isDefaultMarked(entry) {
17701
+ if ('string' == typeof entry) return false;
17702
+ const obj = entry;
17703
+ return true === obj.default;
17704
+ }
17705
+ function readThemeEntryName(entry) {
17706
+ if ('string' == typeof entry) return entry;
17707
+ const obj = entry;
17708
+ if ('string' == typeof obj.name) return obj.name;
17709
+ return '';
17710
+ }
17576
17711
  function collectRegisteredThemeNames(config) {
17577
17712
  const builtIn = Object.keys(BUILT_IN_THEMES);
17578
- const user = (config.themes ?? []).map((t)=>t.name);
17713
+ const user = resolveUserThemeInputs(config).map((t)=>t.name);
17579
17714
  return new Set([
17580
17715
  ...builtIn,
17581
17716
  ...user
@@ -17584,8 +17719,8 @@ function collectRegisteredThemeNames(config) {
17584
17719
  function resolveActiveVariant(params) {
17585
17720
  const supported = resolveSupportedVariants(params.themeName, params.userThemes);
17586
17721
  const themeBlock = params.config.theme;
17587
- const fromConfig = match_match(themeBlock).with(void 0, ()=>{}).otherwise((block)=>block.variant);
17588
- const requested = params.override ?? fromConfig;
17722
+ const fromConfig = match_match(themeBlock).with(void 0, ()=>void 0).otherwise((block)=>block.defaultVariant);
17723
+ const requested = match_match(params.override).with(P.nonNullable, (o)=>o).otherwise(()=>normaliseConfigVariant(fromConfig));
17589
17724
  if (void 0 !== requested && supported.includes(requested)) return requested;
17590
17725
  if (void 0 !== requested) process.stderr.write(`[ciderpress] Theme '${params.themeName}' does not declare variant '${requested}'. Falling back to its default variant.\n`);
17591
17726
  if (isBuiltInTheme(params.themeName)) return resolveDefaultVariant(params.themeName);
@@ -17593,6 +17728,9 @@ function resolveActiveVariant(params) {
17593
17728
  if (userTheme) return userTheme.defaultVariant;
17594
17729
  return 'dark';
17595
17730
  }
17731
+ function normaliseConfigVariant(raw) {
17732
+ if ('light' === raw || 'dark' === raw) return raw;
17733
+ }
17596
17734
  function resolveSupportedVariants(themeName, userThemes) {
17597
17735
  if (isBuiltInTheme(themeName)) return resolveThemeVariants(themeName);
17598
17736
  const userTheme = userThemes.find((t)=>t.name === themeName);
@@ -17602,37 +17740,120 @@ function resolveSupportedVariants(themeName, userThemes) {
17602
17740
  ];
17603
17741
  }
17604
17742
  function resolveThemeSwitcher(config) {
17605
- if (config.theme && config.theme.switcher) return config.theme.switcher;
17743
+ const themeBlock = config.theme;
17744
+ if (void 0 === themeBlock) return false;
17745
+ if (void 0 !== themeBlock.themeSwitcher) return themeBlock.themeSwitcher;
17746
+ const themes = themeBlock.themes;
17747
+ if (void 0 !== themes && themes.length > 1) return true;
17606
17748
  return false;
17607
17749
  }
17608
17750
  function resolveThemeColors(config) {
17609
- if (config.theme && config.theme.colors) return config.theme.colors;
17751
+ if (config.theme && config.theme.overrides) return config.theme.overrides;
17610
17752
  return {};
17611
17753
  }
17612
- function resolveThemeDarkColors(config) {
17613
- if (config.theme && config.theme.darkColors) return config.theme.darkColors;
17754
+ function resolveThemeDarkColors(_config) {
17614
17755
  return {};
17615
17756
  }
17757
+ function resolveUserThemeInputs(config) {
17758
+ const themes = config.theme && config.theme.themes;
17759
+ if (!themes) return [];
17760
+ return themes.flatMap((entry)=>{
17761
+ if ('string' == typeof entry) return [];
17762
+ const obj = entry;
17763
+ if (!('variants' in obj)) return [];
17764
+ const { default: _default, ...rest } = obj;
17765
+ return [
17766
+ rest
17767
+ ];
17768
+ });
17769
+ }
17616
17770
  function resolveUserThemes(config) {
17617
- if (!config.themes) return [];
17618
- return config.themes.map(defineTheme);
17771
+ return resolveUserThemeInputs(config).map(defineTheme);
17619
17772
  }
17620
17773
  function resolveSidebarLinks(params) {
17621
- const items = params.config.sidebar && params.config.sidebar[params.position];
17622
- if (items) return items;
17623
- return [];
17774
+ const sidebar = params.config.sidebar;
17775
+ if (void 0 === sidebar) return [];
17776
+ const items = sidebar[params.position];
17777
+ if (!items) return [];
17778
+ return items.map((item)=>({
17779
+ text: item.text,
17780
+ link: item.href,
17781
+ icon: serializeIcon(resolveOptionalIcon(item.icon)),
17782
+ style: mapButtonVariantToStyle(item.variant),
17783
+ shape: item.shape
17784
+ }));
17624
17785
  }
17625
- function resolveHomeConfig(config) {
17626
- if (config.home) return {
17627
- features: config.home.features,
17628
- workspaces: {
17629
- columns: 2,
17630
- ...config.home.workspaces
17631
- }
17786
+ function mapButtonVariantToStyle(variant) {
17787
+ return match_match(variant).with(void 0, ()=>void 0).with('primary', ()=>'brand').with('secondary', ()=>'alt').with('ghost', ()=>'ghost').exhaustive();
17788
+ }
17789
+ function serializeSocials(socials) {
17790
+ if (void 0 === socials) return [];
17791
+ return socials.map((entry)=>({
17792
+ icon: entry.icon,
17793
+ url: entry.url,
17794
+ label: entry.label
17795
+ }));
17796
+ }
17797
+ function buildSiteBlock(params) {
17798
+ const editBlock = match_match(params.editLink).with(void 0, ()=>void 0).with(false, ()=>void 0).otherwise((e)=>{
17799
+ if (void 0 === e.repo) return;
17800
+ return {
17801
+ repo: e.repo,
17802
+ branch: e.branch,
17803
+ directory: e.directory,
17804
+ label: e.label
17805
+ };
17806
+ });
17807
+ const reportBlock = match_match(params.reportLink).with(void 0, ()=>void 0).with(false, ()=>void 0).otherwise((r)=>{
17808
+ if (void 0 === r.repo) return;
17809
+ return {
17810
+ repo: r.repo,
17811
+ branch: r.branch,
17812
+ directory: r.directory,
17813
+ label: r.label
17814
+ };
17815
+ });
17816
+ const topbar = params.topbar;
17817
+ const topbarCta = match_match(topbar).with(void 0, ()=>void 0).otherwise((t)=>{
17818
+ const cta = t.cta;
17819
+ if (void 0 === cta) return;
17820
+ return {
17821
+ text: cta.text,
17822
+ href: cta.href
17823
+ };
17824
+ });
17825
+ const announcement = match_match(topbar).with(void 0, ()=>void 0).otherwise((t)=>t.announcement);
17826
+ const sidebar = params.sidebar;
17827
+ const sidebarPromo = match_match(sidebar).with(void 0, ()=>void 0).otherwise((s)=>s.promo);
17828
+ const footer = params.footer;
17829
+ const footerBlock = match_match(footer).with(void 0, ()=>void 0).otherwise((f)=>({
17830
+ columns: f.columns,
17831
+ tagline: f.tagline,
17832
+ brandMark: f.brandMark
17833
+ }));
17834
+ return {
17835
+ version: params.config.version,
17836
+ edit: editBlock,
17837
+ report: reportBlock,
17838
+ topbarCta,
17839
+ sidebarPromo,
17840
+ announcement,
17841
+ footer: footerBlock
17842
+ };
17843
+ }
17844
+ function resolveHomeConfig(home) {
17845
+ const fallbackShowcase = {
17846
+ columns: 2
17847
+ };
17848
+ if (void 0 === home) return {
17849
+ hero: {},
17850
+ showcase: fallbackShowcase
17632
17851
  };
17633
17852
  return {
17634
- workspaces: {
17635
- columns: 2
17853
+ ...home,
17854
+ showcase: {
17855
+ columns: 2,
17856
+ ...home.showcase
17636
17857
  }
17637
17858
  };
17638
17859
  }
@@ -17684,12 +17905,57 @@ function buildHeadScriptBody(options) {
17684
17905
  ].join(';');
17685
17906
  return '';
17686
17907
  })();
17908
+ const fallbackJs = match_match(options.loaderEnabled).with(true, ()=>`setTimeout(function(){var d=document.documentElement;if(d.dataset.cpReady!=='true'){d.classList.add('cp-loader-fade');setTimeout(function(){d.dataset.cpReady='true'},220)}},${options.loaderMaxMs})`).otherwise(()=>'');
17909
+ const loaderJs = match_match(options.useDotsLoader).with(true, ()=>LOADER_DOTS_JS).otherwise(()=>'');
17687
17910
  return [
17688
17911
  resolveJs,
17689
17912
  vscodeJs,
17690
- LOADER_DOTS_JS
17913
+ loaderJs,
17914
+ fallbackJs
17691
17915
  ].filter(Boolean).join(';');
17692
17916
  }
17917
+ function resolveLoaderStyle(loader) {
17918
+ if (void 0 === loader) return 'apple';
17919
+ return loader;
17920
+ }
17921
+ function resolveLoaderMinMs(loader) {
17922
+ if (isLoaderConfig(loader) && 'number' == typeof loader.minDisplayMs) return loader.minDisplayMs;
17923
+ return DEFAULT_LOADER_MIN_MS;
17924
+ }
17925
+ function resolveLoaderMaxMs(loader) {
17926
+ if (isLoaderConfig(loader) && 'number' == typeof loader.maxDisplayMs) return loader.maxDisplayMs;
17927
+ return DEFAULT_LOADER_MAX_MS;
17928
+ }
17929
+ function isLoaderConfig(loader) {
17930
+ return 'object' == typeof loader && null !== loader;
17931
+ }
17932
+ function resolveFaviconPath(favicon) {
17933
+ if (void 0 === favicon) return '/icon.svg';
17934
+ if ('string' == typeof favicon) return favicon;
17935
+ return favicon.src;
17936
+ }
17937
+ function resolveFaviconLinkTags(favicon) {
17938
+ if (void 0 === favicon || 'string' == typeof favicon) return [];
17939
+ if (void 0 === favicon.type) return [];
17940
+ return [
17941
+ {
17942
+ tag: 'link',
17943
+ attrs: {
17944
+ rel: 'icon',
17945
+ href: favicon.src,
17946
+ type: favicon.type
17947
+ },
17948
+ head: true,
17949
+ append: false
17950
+ }
17951
+ ];
17952
+ }
17953
+ function resolveHasVariantToggle(params) {
17954
+ if (params.themeSwitcher) return true;
17955
+ const entry = params.registry.find((e)=>e.name === params.themeName);
17956
+ if (void 0 === entry) return false;
17957
+ return entry.variants.length > 1;
17958
+ }
17693
17959
  function buildRegistryEntry(theme) {
17694
17960
  const defaultTokens = theme.variants[theme.defaultVariant];
17695
17961
  const swatch = match_match(defaultTokens).with(void 0, ()=>'').otherwise((tokens)=>tokens.colors.brand.primary);
@@ -17738,7 +18004,7 @@ const CIDERPRESS_ART = Object.freeze([
17738
18004
  ]);
17739
18005
  function CiderpressLogo(props) {
17740
18006
  const title = props.title ?? 'ciderpress';
17741
- return /*#__PURE__*/ React.createElement("svg", {
18007
+ return /*#__PURE__*/ react.createElement("svg", {
17742
18008
  xmlns: "http://www.w3.org/2000/svg",
17743
18009
  viewBox: LOGO_VIEWBOX,
17744
18010
  className: props.className,
@@ -17748,11 +18014,11 @@ function CiderpressLogo(props) {
17748
18014
  color: `var(--rp-c-brand, ${LOGO_FALLBACK_COLOR})`
17749
18015
  },
17750
18016
  role: "img"
17751
- }, /*#__PURE__*/ React.createElement("title", null, title), /*#__PURE__*/ React.createElement("g", {
18017
+ }, /*#__PURE__*/ react.createElement("title", null, title), /*#__PURE__*/ react.createElement("g", {
17752
18018
  transform: `translate(${X_OFFSET}, ${Y_OFFSET})`,
17753
18019
  fontFamily: FONT_STACK,
17754
18020
  fill: "currentColor"
17755
- }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ React.createElement("text", {
18021
+ }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ react.createElement("text", {
17756
18022
  key: line,
17757
18023
  fontSize: FONT_SIZE,
17758
18024
  y: i * LINE_HEIGHT,