@ciderpress/ui 1.0.0-rc.1 → 1.0.0-rc.10

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 (106) 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 +335 -51
  5. package/dist/plugins/mermaid/MermaidRenderer.tsx +49 -6
  6. package/dist/theme/components/footer/site-footer.tsx +68 -9
  7. package/dist/theme/components/home/feature-card.tsx +5 -8
  8. package/dist/theme/components/home/feature.tsx +31 -11
  9. package/dist/theme/components/home/hero-demo-custom.tsx +116 -0
  10. package/dist/theme/components/home/hero-demo.css +27 -0
  11. package/dist/theme/components/home/layout.tsx +149 -26
  12. package/dist/theme/components/home/split-visual-custom.tsx +26 -0
  13. package/dist/theme/components/home/workspaces.tsx +39 -3
  14. package/dist/theme/components/nav/branch-tag.tsx +7 -7
  15. package/dist/theme/components/nav/ciderpress-docs-bar.css +13 -1
  16. package/dist/theme/components/nav/ciderpress-docs-bar.tsx +33 -2
  17. package/dist/theme/components/nav/ciderpress-header.css +2 -1
  18. package/dist/theme/components/nav/ciderpress-header.tsx +26 -3
  19. package/dist/theme/components/nav/ciderpress-nav-hamburger.css +50 -0
  20. package/dist/theme/components/nav/ciderpress-nav-hamburger.tsx +95 -9
  21. package/dist/theme/components/nav/ciderpress-nav-menu.css +88 -0
  22. package/dist/theme/components/nav/ciderpress-nav-menu.tsx +397 -38
  23. package/dist/theme/components/nav/ciderpress-nav-social-links.tsx +27 -22
  24. package/dist/theme/components/nav/floating-branch-indicator.tsx +7 -7
  25. package/dist/theme/components/nav/header-icon.css +24 -0
  26. package/dist/theme/components/nav/header-icon.tsx +119 -0
  27. package/dist/theme/components/nav/header-logo.css +16 -0
  28. package/dist/theme/components/nav/header-logo.tsx +200 -0
  29. package/dist/theme/components/nav/layout.tsx +117 -16
  30. package/dist/theme/components/nav/nav-logo.tsx +16 -19
  31. package/dist/theme/components/openapi/index.ts +0 -2
  32. package/dist/theme/components/openapi/openapi.css +0 -14
  33. package/dist/theme/components/shared/card-icon.tsx +37 -0
  34. package/dist/theme/components/shared/ciderpress-logo.tsx +5 -1
  35. package/dist/theme/components/shared/icon.tsx +120 -35
  36. package/dist/theme/components/shared/resolve-card-icon.ts +53 -12
  37. package/dist/theme/components/shared/section-card.tsx +37 -6
  38. package/dist/theme/components/sidebar/sidebar-badge.css +50 -0
  39. package/dist/theme/components/sidebar/sidebar-badge.tsx +153 -0
  40. package/dist/theme/components/sidebar/sidebar-links.tsx +6 -2
  41. package/dist/theme/components/sidebar/sidebar-scope.tsx +24 -1
  42. package/dist/theme/components/theme-provider.tsx +27 -11
  43. package/dist/theme/components/workspaces/card.tsx +7 -9
  44. package/dist/theme/hooks/use-ciderpress.ts +65 -5
  45. package/dist/theme/hooks/use-nav-items.ts +82 -11
  46. package/dist/theme/index.tsx +5 -3
  47. package/dist/theme/lib/read-social-links.ts +4 -3
  48. package/dist/theme/lib/theme-favicon.ts +1 -1
  49. package/dist/theme/lib/with-mount-base.ts +31 -0
  50. package/dist/theme/styles/overrides/footnotes.css +54 -0
  51. package/dist/theme/styles/overrides/lists.css +83 -0
  52. package/dist/theme/styles/overrides/rail.css +27 -10
  53. package/dist/theme/styles/overrides/section-card.css +9 -0
  54. package/dist/theme/styles/overrides/sidebar.css +22 -0
  55. package/package.json +18 -16
  56. package/src/theme/components/footer/site-footer.tsx +68 -9
  57. package/src/theme/components/home/feature-card.tsx +5 -8
  58. package/src/theme/components/home/feature.tsx +31 -11
  59. package/src/theme/components/home/hero-demo-custom.tsx +116 -0
  60. package/src/theme/components/home/hero-demo.css +27 -0
  61. package/src/theme/components/home/layout.tsx +149 -26
  62. package/src/theme/components/home/split-visual-custom.tsx +26 -0
  63. package/src/theme/components/home/workspaces.tsx +39 -3
  64. package/src/theme/components/nav/branch-tag.tsx +7 -7
  65. package/src/theme/components/nav/ciderpress-docs-bar.css +13 -1
  66. package/src/theme/components/nav/ciderpress-docs-bar.tsx +33 -2
  67. package/src/theme/components/nav/ciderpress-header.css +2 -1
  68. package/src/theme/components/nav/ciderpress-header.tsx +26 -3
  69. package/src/theme/components/nav/ciderpress-nav-hamburger.css +50 -0
  70. package/src/theme/components/nav/ciderpress-nav-hamburger.tsx +95 -9
  71. package/src/theme/components/nav/ciderpress-nav-menu.css +88 -0
  72. package/src/theme/components/nav/ciderpress-nav-menu.tsx +397 -38
  73. package/src/theme/components/nav/ciderpress-nav-social-links.tsx +27 -22
  74. package/src/theme/components/nav/floating-branch-indicator.tsx +7 -7
  75. package/src/theme/components/nav/header-icon.css +24 -0
  76. package/src/theme/components/nav/header-icon.tsx +119 -0
  77. package/src/theme/components/nav/header-logo.css +16 -0
  78. package/src/theme/components/nav/header-logo.tsx +200 -0
  79. package/src/theme/components/nav/layout.tsx +117 -16
  80. package/src/theme/components/nav/nav-logo.tsx +16 -19
  81. package/src/theme/components/openapi/index.ts +0 -2
  82. package/src/theme/components/openapi/openapi.css +0 -14
  83. package/src/theme/components/shared/card-icon.tsx +37 -0
  84. package/src/theme/components/shared/ciderpress-logo.tsx +5 -1
  85. package/src/theme/components/shared/icon.tsx +120 -35
  86. package/src/theme/components/shared/resolve-card-icon.ts +53 -12
  87. package/src/theme/components/shared/section-card.tsx +37 -6
  88. package/src/theme/components/sidebar/sidebar-badge.css +50 -0
  89. package/src/theme/components/sidebar/sidebar-badge.tsx +153 -0
  90. package/src/theme/components/sidebar/sidebar-links.tsx +6 -2
  91. package/src/theme/components/sidebar/sidebar-scope.tsx +24 -1
  92. package/src/theme/components/theme-provider.tsx +27 -11
  93. package/src/theme/components/workspaces/card.tsx +7 -9
  94. package/src/theme/hooks/use-ciderpress.ts +65 -5
  95. package/src/theme/hooks/use-nav-items.ts +82 -11
  96. package/src/theme/index.tsx +5 -3
  97. package/src/theme/lib/read-social-links.ts +4 -3
  98. package/src/theme/lib/theme-favicon.ts +1 -1
  99. package/src/theme/lib/with-mount-base.ts +31 -0
  100. package/src/theme/styles/overrides/footnotes.css +54 -0
  101. package/src/theme/styles/overrides/lists.css +83 -0
  102. package/src/theme/styles/overrides/rail.css +27 -10
  103. package/src/theme/styles/overrides/section-card.css +9 -0
  104. package/src/theme/styles/overrides/sidebar.css +22 -0
  105. package/dist/theme/components/openapi/copy-markdown-button.tsx +0 -41
  106. package/src/theme/components/openapi/copy-markdown-button.tsx +0 -41
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');
@@ -17395,7 +17469,22 @@ function createRspressConfig(options) {
17395
17469
  name: 'scopes.json',
17396
17470
  fallback: []
17397
17471
  });
17472
+ const pageBadges = loadGenerated({
17473
+ contentDir: paths.contentDir,
17474
+ name: 'badges.json',
17475
+ fallback: {}
17476
+ });
17398
17477
  const gitBranch = detectGitBranch();
17478
+ const brand = config.brand;
17479
+ const home = config.home;
17480
+ const editLink = config.editLink;
17481
+ const reportLink = config.reportLink;
17482
+ const topbar = config.topbar;
17483
+ const sidebar = config.sidebar;
17484
+ const footer = config.footer;
17485
+ const favicon = brand && brand.favicon;
17486
+ const loaderRaw = brand && brand.loader;
17487
+ const logoRaw = brand && brand.logo;
17399
17488
  const themeName = resolveThemeName(config, options.themeOverride);
17400
17489
  const userThemes = resolveUserThemes(config);
17401
17490
  const variant = resolveActiveVariant({
@@ -17408,35 +17497,59 @@ function createRspressConfig(options) {
17408
17497
  const themeColors = resolveThemeColors(config);
17409
17498
  const themeDarkColors = resolveThemeDarkColors(config);
17410
17499
  const userThemesCss = userThemes.map(themeToCss).join('');
17411
- const loaderStyle = config.loader ?? 'apple';
17500
+ const loaderStyle = resolveLoaderStyle(loaderRaw);
17412
17501
  const themeCss = getThemeCss(themeName, loaderStyle) + userThemesCss;
17413
17502
  const themeRegistry = [
17414
17503
  ...BUILT_IN_THEME_REGISTRY,
17415
17504
  ...userThemes.map(buildRegistryEntry)
17416
17505
  ];
17417
17506
  const isVscode = true === vscode;
17507
+ const loaderMaxMs = resolveLoaderMaxMs(loaderRaw);
17418
17508
  const headScriptBody = buildHeadScriptBody({
17419
17509
  variant,
17420
17510
  themeName,
17421
17511
  vscode: isVscode,
17422
- registry: themeRegistry
17512
+ registry: themeRegistry,
17513
+ loaderMaxMs,
17514
+ useDotsLoader: 'classic' === loaderStyle,
17515
+ loaderEnabled: false !== loaderStyle
17423
17516
  });
17424
17517
  const selfRequire = createRequire(import.meta.url);
17425
17518
  const reactAlias = node_path.dirname(selfRequire.resolve('react/package.json'));
17426
17519
  const reactDomAlias = node_path.dirname(selfRequire.resolve('react-dom/package.json'));
17427
17520
  const userConfigAlias = resolveUserConfigAlias(paths.repoRoot);
17428
- const resolvedLogo = resolveLogo(config.logo);
17521
+ const envBase = process.env.CIDERPRESS_BASE;
17522
+ const resolvedBase = match_match([
17523
+ envBase,
17524
+ config.base
17525
+ ]).with([
17526
+ P.string.minLength(1),
17527
+ P._
17528
+ ], ([b])=>b).with([
17529
+ P._,
17530
+ P.string.minLength(1)
17531
+ ], ([, b])=>b).otherwise(()=>'/');
17532
+ const siteBlock = buildSiteBlock({
17533
+ config,
17534
+ editLink,
17535
+ reportLink,
17536
+ feedback: config.feedback,
17537
+ topbar,
17538
+ sidebar,
17539
+ footer
17540
+ });
17429
17541
  return {
17430
17542
  root: paths.contentDir,
17431
17543
  outDir: paths.distDir,
17544
+ base: resolvedBase,
17432
17545
  route: {
17433
17546
  cleanUrls: true
17434
17547
  },
17435
17548
  llms: true,
17436
17549
  title: config.title ?? 'ciderpress',
17437
17550
  description: config.description ?? 'Documentation',
17438
- icon: config.icon ?? '/icon.svg',
17439
- logo: resolvedLogo,
17551
+ icon: resolveFaviconPath(favicon),
17552
+ logo: match_match(logoRaw).with(P.string, (l)=>l).otherwise(()=>''),
17440
17553
  logoText: '',
17441
17554
  themeDir: node_path.resolve(import.meta.dirname, 'theme'),
17442
17555
  plugins: [
@@ -17451,7 +17564,12 @@ function createRspressConfig(options) {
17451
17564
  markdown: {
17452
17565
  remarkPlugins: [
17453
17566
  remarkMathToDiv
17454
- ]
17567
+ ],
17568
+ link: {
17569
+ checkDeadLinks: {
17570
+ excludes: (url)=>url.startsWith('/examples/')
17571
+ }
17572
+ }
17455
17573
  },
17456
17574
  builderConfig: {
17457
17575
  ...(()=>{
@@ -17462,6 +17580,7 @@ function createRspressConfig(options) {
17462
17580
  })(),
17463
17581
  html: {
17464
17582
  tags: [
17583
+ ...resolveFaviconLinkTags(favicon),
17465
17584
  {
17466
17585
  tag: 'style',
17467
17586
  children: themeCss,
@@ -17498,7 +17617,15 @@ function createRspressConfig(options) {
17498
17617
  __CIDERPRESS_THEME_DARK_COLORS__: JSON.stringify(JSON.stringify(themeDarkColors)),
17499
17618
  __CIDERPRESS_THEME_SWITCHER__: JSON.stringify(themeSwitcher),
17500
17619
  __CIDERPRESS_THEME_REGISTRY__: JSON.stringify(JSON.stringify(themeRegistry)),
17501
- __CIDERPRESS_VSCODE__: JSON.stringify(isVscode)
17620
+ __CIDERPRESS_VSCODE__: JSON.stringify(isVscode),
17621
+ __CIDERPRESS_HAS_USER_FAVICON__: JSON.stringify(void 0 !== favicon),
17622
+ __CIDERPRESS_LOADER_MIN_MS__: JSON.stringify(resolveLoaderMinMs(loaderRaw)),
17623
+ __CIDERPRESS_LOADER_MAX_MS__: JSON.stringify(resolveLoaderMaxMs(loaderRaw)),
17624
+ __CIDERPRESS_HAS_VARIANT_TOGGLE__: JSON.stringify(resolveHasVariantToggle({
17625
+ themeName,
17626
+ themeSwitcher,
17627
+ registry: themeRegistry
17628
+ }))
17502
17629
  }
17503
17630
  },
17504
17631
  output: {
@@ -17515,29 +17642,26 @@ function createRspressConfig(options) {
17515
17642
  },
17516
17643
  ...{
17517
17644
  workspaces,
17518
- standaloneScopePaths
17645
+ standaloneScopePaths,
17646
+ pageBadges
17519
17647
  },
17520
17648
  ...{
17521
- socialLinks: config.socialLinks,
17649
+ socialLinks: serializeSocials(config.socials),
17522
17650
  sidebarAbove: resolveSidebarLinks({
17523
17651
  config,
17524
- position: 'above'
17652
+ position: 'top'
17525
17653
  }),
17526
17654
  sidebarBelow: resolveSidebarLinks({
17527
17655
  config,
17528
- position: 'below'
17656
+ position: 'bottom'
17529
17657
  }),
17530
- home: resolveHomeConfig(config),
17531
- ciderpressFooter: config.footer,
17532
- site: config.site
17658
+ home: resolveHomeConfig(home),
17659
+ ciderpressFooter: footer,
17660
+ site: siteBlock
17533
17661
  }
17534
17662
  }
17535
17663
  };
17536
17664
  }
17537
- function resolveLogo(logo) {
17538
- if ('string' == typeof logo) return logo;
17539
- if (null == logo) return '/logo.svg';
17540
- }
17541
17665
  function loadGenerated(params) {
17542
17666
  const p = node_path.resolve(params.contentDir, '.generated', params.name);
17543
17667
  if (!existsSync(p)) {
@@ -17565,17 +17689,35 @@ function resolveThemeName(config, override) {
17565
17689
  const registeredNames = collectRegisteredThemeNames(config);
17566
17690
  const requested = resolveThemeAlias(resolveRequestedThemeName(config, override));
17567
17691
  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`);
17692
+ 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
17693
  return DEFAULT_THEME_NAME;
17570
17694
  }
17571
17695
  function resolveRequestedThemeName(config, override) {
17572
17696
  if (override) return override;
17573
- if (config.theme && config.theme.name) return config.theme.name;
17697
+ const fromThemes = resolveDefaultEntryName(config.theme && config.theme.themes);
17698
+ if (void 0 !== fromThemes) return fromThemes;
17574
17699
  return DEFAULT_THEME_NAME;
17575
17700
  }
17701
+ function resolveDefaultEntryName(themes) {
17702
+ if (void 0 === themes || 0 === themes.length) return;
17703
+ const marked = themes.find(isDefaultMarked);
17704
+ if (void 0 !== marked) return readThemeEntryName(marked);
17705
+ return readThemeEntryName(themes[0]);
17706
+ }
17707
+ function isDefaultMarked(entry) {
17708
+ if ('string' == typeof entry) return false;
17709
+ const obj = entry;
17710
+ return true === obj.default;
17711
+ }
17712
+ function readThemeEntryName(entry) {
17713
+ if ('string' == typeof entry) return entry;
17714
+ const obj = entry;
17715
+ if ('string' == typeof obj.name) return obj.name;
17716
+ return '';
17717
+ }
17576
17718
  function collectRegisteredThemeNames(config) {
17577
17719
  const builtIn = Object.keys(BUILT_IN_THEMES);
17578
- const user = (config.themes ?? []).map((t)=>t.name);
17720
+ const user = resolveUserThemeInputs(config).map((t)=>t.name);
17579
17721
  return new Set([
17580
17722
  ...builtIn,
17581
17723
  ...user
@@ -17584,8 +17726,8 @@ function collectRegisteredThemeNames(config) {
17584
17726
  function resolveActiveVariant(params) {
17585
17727
  const supported = resolveSupportedVariants(params.themeName, params.userThemes);
17586
17728
  const themeBlock = params.config.theme;
17587
- const fromConfig = match_match(themeBlock).with(void 0, ()=>{}).otherwise((block)=>block.variant);
17588
- const requested = params.override ?? fromConfig;
17729
+ const fromConfig = match_match(themeBlock).with(void 0, ()=>void 0).otherwise((block)=>block.defaultVariant);
17730
+ const requested = match_match(params.override).with(P.nonNullable, (o)=>o).otherwise(()=>normaliseConfigVariant(fromConfig));
17589
17731
  if (void 0 !== requested && supported.includes(requested)) return requested;
17590
17732
  if (void 0 !== requested) process.stderr.write(`[ciderpress] Theme '${params.themeName}' does not declare variant '${requested}'. Falling back to its default variant.\n`);
17591
17733
  if (isBuiltInTheme(params.themeName)) return resolveDefaultVariant(params.themeName);
@@ -17593,6 +17735,9 @@ function resolveActiveVariant(params) {
17593
17735
  if (userTheme) return userTheme.defaultVariant;
17594
17736
  return 'dark';
17595
17737
  }
17738
+ function normaliseConfigVariant(raw) {
17739
+ if ('light' === raw || 'dark' === raw) return raw;
17740
+ }
17596
17741
  function resolveSupportedVariants(themeName, userThemes) {
17597
17742
  if (isBuiltInTheme(themeName)) return resolveThemeVariants(themeName);
17598
17743
  const userTheme = userThemes.find((t)=>t.name === themeName);
@@ -17602,37 +17747,131 @@ function resolveSupportedVariants(themeName, userThemes) {
17602
17747
  ];
17603
17748
  }
17604
17749
  function resolveThemeSwitcher(config) {
17605
- if (config.theme && config.theme.switcher) return config.theme.switcher;
17750
+ const themeBlock = config.theme;
17751
+ if (void 0 === themeBlock) return false;
17752
+ if (void 0 !== themeBlock.themeSwitcher) return themeBlock.themeSwitcher;
17753
+ const themes = themeBlock.themes;
17754
+ if (void 0 !== themes && themes.length > 1) return true;
17606
17755
  return false;
17607
17756
  }
17608
17757
  function resolveThemeColors(config) {
17609
- if (config.theme && config.theme.colors) return config.theme.colors;
17758
+ if (config.theme && config.theme.overrides) return config.theme.overrides;
17610
17759
  return {};
17611
17760
  }
17612
- function resolveThemeDarkColors(config) {
17613
- if (config.theme && config.theme.darkColors) return config.theme.darkColors;
17761
+ function resolveThemeDarkColors(_config) {
17614
17762
  return {};
17615
17763
  }
17764
+ function resolveUserThemeInputs(config) {
17765
+ const themes = config.theme && config.theme.themes;
17766
+ if (!themes) return [];
17767
+ return themes.flatMap((entry)=>{
17768
+ if ('string' == typeof entry) return [];
17769
+ const obj = entry;
17770
+ if (!('variants' in obj)) return [];
17771
+ const { default: _default, ...rest } = obj;
17772
+ return [
17773
+ rest
17774
+ ];
17775
+ });
17776
+ }
17616
17777
  function resolveUserThemes(config) {
17617
- if (!config.themes) return [];
17618
- return config.themes.map(defineTheme);
17778
+ return resolveUserThemeInputs(config).map(defineTheme);
17619
17779
  }
17620
17780
  function resolveSidebarLinks(params) {
17621
- const items = params.config.sidebar && params.config.sidebar[params.position];
17622
- if (items) return items;
17623
- return [];
17781
+ const sidebar = params.config.sidebar;
17782
+ if (void 0 === sidebar) return [];
17783
+ const items = sidebar[params.position];
17784
+ if (!items) return [];
17785
+ return items.map((item)=>({
17786
+ text: item.text,
17787
+ link: item.href,
17788
+ icon: serializeIcon(resolveOptionalIcon(item.icon)),
17789
+ style: mapButtonVariantToStyle(item.variant),
17790
+ shape: item.shape
17791
+ }));
17624
17792
  }
17625
- function resolveHomeConfig(config) {
17626
- if (config.home) return {
17627
- features: config.home.features,
17628
- workspaces: {
17629
- columns: 2,
17630
- ...config.home.workspaces
17631
- }
17793
+ function mapButtonVariantToStyle(variant) {
17794
+ return match_match(variant).with(void 0, ()=>void 0).with('primary', ()=>'brand').with('secondary', ()=>'alt').with('ghost', ()=>'ghost').exhaustive();
17795
+ }
17796
+ function serializeSocials(socials) {
17797
+ if (void 0 === socials) return [];
17798
+ return socials.map((entry)=>({
17799
+ icon: entry.icon,
17800
+ url: entry.url,
17801
+ label: entry.label
17802
+ }));
17803
+ }
17804
+ function buildSiteBlock(params) {
17805
+ const editBlock = match_match(params.editLink).with(void 0, ()=>void 0).with(false, ()=>void 0).otherwise((e)=>{
17806
+ if (void 0 === e.repo) return;
17807
+ return {
17808
+ repo: e.repo,
17809
+ branch: e.branch,
17810
+ directory: e.directory,
17811
+ label: e.label
17812
+ };
17813
+ });
17814
+ const reportBlock = match_match(params.reportLink).with(void 0, ()=>void 0).with(false, ()=>void 0).otherwise((r)=>{
17815
+ if (void 0 === r.repo) return;
17816
+ return {
17817
+ repo: r.repo,
17818
+ branch: r.branch,
17819
+ directory: r.directory,
17820
+ label: r.label
17821
+ };
17822
+ });
17823
+ const topbar = params.topbar;
17824
+ const topbarCta = match_match(topbar).with(void 0, ()=>void 0).otherwise((t)=>{
17825
+ const cta = t.cta;
17826
+ if (void 0 === cta) return;
17827
+ return {
17828
+ text: cta.text,
17829
+ href: cta.href
17830
+ };
17831
+ });
17832
+ const announcement = match_match(topbar).with(void 0, ()=>void 0).otherwise((t)=>t.announcement);
17833
+ const sidebar = params.sidebar;
17834
+ const sidebarPromo = match_match(sidebar).with(void 0, ()=>void 0).otherwise((s)=>s.promo);
17835
+ const footer = params.footer;
17836
+ const footerBlock = match_match(footer).with(void 0, ()=>void 0).otherwise((f)=>({
17837
+ columns: f.columns,
17838
+ tagline: f.tagline,
17839
+ brandMark: f.brandMark
17840
+ }));
17841
+ const feedbackBlock = match_match(params.feedback).with(true, ()=>({
17842
+ enabled: true,
17843
+ question: void 0
17844
+ })).with(P.union(false, void 0), ()=>({
17845
+ enabled: false,
17846
+ question: void 0
17847
+ })).otherwise((f)=>({
17848
+ enabled: true,
17849
+ question: f.question
17850
+ }));
17851
+ return {
17852
+ version: params.config.version,
17853
+ edit: editBlock,
17854
+ report: reportBlock,
17855
+ topbarCta,
17856
+ sidebarPromo,
17857
+ announcement,
17858
+ footer: footerBlock,
17859
+ feedback: feedbackBlock
17860
+ };
17861
+ }
17862
+ function resolveHomeConfig(home) {
17863
+ const fallbackShowcase = {
17864
+ columns: 2
17865
+ };
17866
+ if (void 0 === home) return {
17867
+ hero: {},
17868
+ showcase: fallbackShowcase
17632
17869
  };
17633
17870
  return {
17634
- workspaces: {
17635
- columns: 2
17871
+ ...home,
17872
+ showcase: {
17873
+ columns: 2,
17874
+ ...home.showcase
17636
17875
  }
17637
17876
  };
17638
17877
  }
@@ -17684,12 +17923,57 @@ function buildHeadScriptBody(options) {
17684
17923
  ].join(';');
17685
17924
  return '';
17686
17925
  })();
17926
+ 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(()=>'');
17927
+ const loaderJs = match_match(options.useDotsLoader).with(true, ()=>LOADER_DOTS_JS).otherwise(()=>'');
17687
17928
  return [
17688
17929
  resolveJs,
17689
17930
  vscodeJs,
17690
- LOADER_DOTS_JS
17931
+ loaderJs,
17932
+ fallbackJs
17691
17933
  ].filter(Boolean).join(';');
17692
17934
  }
17935
+ function resolveLoaderStyle(loader) {
17936
+ if (void 0 === loader) return 'apple';
17937
+ return loader;
17938
+ }
17939
+ function resolveLoaderMinMs(loader) {
17940
+ if (isLoaderConfig(loader) && 'number' == typeof loader.minDisplayMs) return loader.minDisplayMs;
17941
+ return DEFAULT_LOADER_MIN_MS;
17942
+ }
17943
+ function resolveLoaderMaxMs(loader) {
17944
+ if (isLoaderConfig(loader) && 'number' == typeof loader.maxDisplayMs) return loader.maxDisplayMs;
17945
+ return DEFAULT_LOADER_MAX_MS;
17946
+ }
17947
+ function isLoaderConfig(loader) {
17948
+ return 'object' == typeof loader && null !== loader;
17949
+ }
17950
+ function resolveFaviconPath(favicon) {
17951
+ if (void 0 === favicon) return '/icon.svg';
17952
+ if ('string' == typeof favicon) return favicon;
17953
+ return favicon.src;
17954
+ }
17955
+ function resolveFaviconLinkTags(favicon) {
17956
+ if (void 0 === favicon || 'string' == typeof favicon) return [];
17957
+ if (void 0 === favicon.type) return [];
17958
+ return [
17959
+ {
17960
+ tag: 'link',
17961
+ attrs: {
17962
+ rel: 'icon',
17963
+ href: favicon.src,
17964
+ type: favicon.type
17965
+ },
17966
+ head: true,
17967
+ append: false
17968
+ }
17969
+ ];
17970
+ }
17971
+ function resolveHasVariantToggle(params) {
17972
+ if (params.themeSwitcher) return true;
17973
+ const entry = params.registry.find((e)=>e.name === params.themeName);
17974
+ if (void 0 === entry) return false;
17975
+ return entry.variants.length > 1;
17976
+ }
17693
17977
  function buildRegistryEntry(theme) {
17694
17978
  const defaultTokens = theme.variants[theme.defaultVariant];
17695
17979
  const swatch = match_match(defaultTokens).with(void 0, ()=>'').otherwise((tokens)=>tokens.colors.brand.primary);
@@ -17738,7 +18022,7 @@ const CIDERPRESS_ART = Object.freeze([
17738
18022
  ]);
17739
18023
  function CiderpressLogo(props) {
17740
18024
  const title = props.title ?? 'ciderpress';
17741
- return /*#__PURE__*/ React.createElement("svg", {
18025
+ return /*#__PURE__*/ react.createElement("svg", {
17742
18026
  xmlns: "http://www.w3.org/2000/svg",
17743
18027
  viewBox: LOGO_VIEWBOX,
17744
18028
  className: props.className,
@@ -17748,11 +18032,11 @@ function CiderpressLogo(props) {
17748
18032
  color: `var(--rp-c-brand, ${LOGO_FALLBACK_COLOR})`
17749
18033
  },
17750
18034
  role: "img"
17751
- }, /*#__PURE__*/ React.createElement("title", null, title), /*#__PURE__*/ React.createElement("g", {
18035
+ }, /*#__PURE__*/ react.createElement("title", null, title), /*#__PURE__*/ react.createElement("g", {
17752
18036
  transform: `translate(${X_OFFSET}, ${Y_OFFSET})`,
17753
18037
  fontFamily: FONT_STACK,
17754
18038
  fill: "currentColor"
17755
- }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ React.createElement("text", {
18039
+ }, CIDERPRESS_ART.map((line, i)=>/*#__PURE__*/ react.createElement("text", {
17756
18040
  key: line,
17757
18041
  fontSize: FONT_SIZE,
17758
18042
  y: i * LINE_HEIGHT,