@ciderpress/ui 1.0.0-rc.1
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/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/0~142.js +2 -0
- package/dist/0~164.js +2 -0
- package/dist/0~2.js +2 -0
- package/dist/0~225.js +2 -0
- package/dist/0~288.js +2 -0
- package/dist/0~299.js +2 -0
- package/dist/0~3.js +2 -0
- package/dist/0~301.js +2 -0
- package/dist/0~311.js +2 -0
- package/dist/0~326.js +2 -0
- package/dist/0~40.js +2 -0
- package/dist/0~43.js +2 -0
- package/dist/0~433.js +2 -0
- package/dist/0~453.js +2 -0
- package/dist/0~457.js +2 -0
- package/dist/0~497.js +2 -0
- package/dist/0~511.js +2 -0
- package/dist/0~603.js +2 -0
- package/dist/0~616.js +2 -0
- package/dist/0~659.js +2 -0
- package/dist/0~670.js +2 -0
- package/dist/0~687.js +2 -0
- package/dist/0~706.js +2 -0
- package/dist/0~729.js +2 -0
- package/dist/0~768.js +2 -0
- package/dist/0~819.js +2 -0
- package/dist/0~830.js +2 -0
- package/dist/0~854.js +2 -0
- package/dist/0~863.js +2 -0
- package/dist/0~879.js +2 -0
- package/dist/0~96.js +2 -0
- package/dist/0~97.js +2 -0
- package/dist/components/FileTree/FileTree.css +90 -0
- package/dist/components/FileTree/FileTree.d.ts +7 -0
- package/dist/components/FileTree/FileTree.js +531 -0
- package/dist/components/FileTree/FileTreeItem.d.ts +8 -0
- package/dist/components/FileTree/RemoteSvgIcon.d.ts +11 -0
- package/dist/components/FileTree/index.d.ts +4 -0
- package/dist/components/folder-icons.d.ts +32 -0
- package/dist/components/languages.d.ts +7 -0
- package/dist/components/tree-parser/tree-parser.d.ts +12 -0
- package/dist/components/tree-parser/types.d.ts +11 -0
- package/dist/head/css/loader-apple.css +1 -0
- package/dist/head/css/loader-backdrop.css +1 -0
- package/dist/head/css/loader-dots.css +1 -0
- package/dist/head/css/themes/amber.css +1 -0
- package/dist/head/css/themes/arcade.css +1 -0
- package/dist/head/css/themes/grannysmith.css +1 -0
- package/dist/head/css/themes/honeycrisp.css +1 -0
- package/dist/head/css/themes/midnight.css +1 -0
- package/dist/head/css/themes/mulled.css +1 -0
- package/dist/head/js/loader-dots.js +1 -0
- package/dist/head/js/vscode-nav.js +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.mjs +40 -0
- package/dist/node.d.ts +81 -0
- package/dist/node.mjs +17762 -0
- package/dist/plugins/mermaid/MermaidRenderer.tsx +480 -0
- package/dist/plugins/mermaid/mermaid.css +199 -0
- package/dist/theme/components/announcement/announcement-bar.css +103 -0
- package/dist/theme/components/announcement/announcement-bar.tsx +173 -0
- package/dist/theme/components/ask-ai/ask-ai-button.css +52 -0
- package/dist/theme/components/ask-ai/ask-ai-button.tsx +56 -0
- package/dist/theme/components/content-footer/content-footer-portal.tsx +70 -0
- package/dist/theme/components/content-footer/feedback.css +47 -0
- package/dist/theme/components/content-footer/feedback.tsx +96 -0
- package/dist/theme/components/content-footer/meta-actions.css +25 -0
- package/dist/theme/components/content-footer/meta-actions.tsx +57 -0
- package/dist/theme/components/content-footer/page-pager.css +61 -0
- package/dist/theme/components/content-footer/page-pager.tsx +110 -0
- package/dist/theme/components/edit-source-button.tsx +97 -0
- package/dist/theme/components/footer/site-footer.css +179 -0
- package/dist/theme/components/footer/site-footer.tsx +115 -0
- package/dist/theme/components/home/cta.css +67 -0
- package/dist/theme/components/home/cta.tsx +77 -0
- package/dist/theme/components/home/feature-card.css +52 -0
- package/dist/theme/components/home/feature-card.tsx +131 -0
- package/dist/theme/components/home/feature.tsx +79 -0
- package/dist/theme/components/home/hero-demo.css +66 -0
- package/dist/theme/components/home/hero-demo.tsx +46 -0
- package/dist/theme/components/home/hero.css +96 -0
- package/dist/theme/components/home/hero.tsx +111 -0
- package/dist/theme/components/home/layout.tsx +183 -0
- package/dist/theme/components/home/page-rail.css +21 -0
- package/dist/theme/components/home/page-rail.tsx +19 -0
- package/dist/theme/components/home/split.css +148 -0
- package/dist/theme/components/home/split.tsx +120 -0
- package/dist/theme/components/home/trust-strip.css +33 -0
- package/dist/theme/components/home/trust-strip.tsx +43 -0
- package/dist/theme/components/home/workspaces.tsx +71 -0
- package/dist/theme/components/nav/branch-tag.css +54 -0
- package/dist/theme/components/nav/branch-tag.tsx +101 -0
- package/dist/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
- package/dist/theme/components/nav/ciderpress-docs-bar.css +505 -0
- package/dist/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
- package/dist/theme/components/nav/ciderpress-header.css +172 -0
- package/dist/theme/components/nav/ciderpress-header.tsx +113 -0
- package/dist/theme/components/nav/ciderpress-layout-context.tsx +49 -0
- package/dist/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
- package/dist/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
- package/dist/theme/components/nav/ciderpress-nav-menu.css +130 -0
- package/dist/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
- package/dist/theme/components/nav/ciderpress-nav-search.css +73 -0
- package/dist/theme/components/nav/ciderpress-nav-search.tsx +55 -0
- package/dist/theme/components/nav/ciderpress-nav-social-links.css +35 -0
- package/dist/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
- package/dist/theme/components/nav/floating-branch-indicator.css +106 -0
- package/dist/theme/components/nav/floating-branch-indicator.tsx +109 -0
- package/dist/theme/components/nav/layout.tsx +268 -0
- package/dist/theme/components/nav/mobile-nav-cta.tsx +79 -0
- package/dist/theme/components/nav/nav-divider.css +15 -0
- package/dist/theme/components/nav/nav-divider.tsx +19 -0
- package/dist/theme/components/nav/nav-logo.css +42 -0
- package/dist/theme/components/nav/nav-logo.tsx +262 -0
- package/dist/theme/components/nav/theme-switcher.css +92 -0
- package/dist/theme/components/nav/theme-switcher.tsx +298 -0
- package/dist/theme/components/nav/topbar-cta.css +45 -0
- package/dist/theme/components/nav/topbar-cta.tsx +39 -0
- package/dist/theme/components/nav/variant-toggle.css +70 -0
- package/dist/theme/components/nav/variant-toggle.tsx +83 -0
- package/dist/theme/components/nav/version-chip.css +31 -0
- package/dist/theme/components/nav/version-chip.tsx +45 -0
- package/dist/theme/components/nav/vscode-tag.css +32 -0
- package/dist/theme/components/nav/vscode-tag.tsx +20 -0
- package/dist/theme/components/openapi/code-sample.tsx +341 -0
- package/dist/theme/components/openapi/copy-markdown-button.tsx +41 -0
- package/dist/theme/components/openapi/icons.tsx +45 -0
- package/dist/theme/components/openapi/index.ts +6 -0
- package/dist/theme/components/openapi/method-badge.tsx +24 -0
- package/dist/theme/components/openapi/openapi.css +665 -0
- package/dist/theme/components/openapi/operation.tsx +200 -0
- package/dist/theme/components/openapi/overview.tsx +207 -0
- package/dist/theme/components/openapi/parameters-table.tsx +149 -0
- package/dist/theme/components/openapi/request-body.tsx +90 -0
- package/dist/theme/components/openapi/response-list.tsx +112 -0
- package/dist/theme/components/openapi/schema-viewer.tsx +277 -0
- package/dist/theme/components/openapi/security-badges.tsx +63 -0
- package/dist/theme/components/openapi/spec-utils.ts +122 -0
- package/dist/theme/components/shared/accordion.css +118 -0
- package/dist/theme/components/shared/accordion.stories.tsx +96 -0
- package/dist/theme/components/shared/accordion.tsx +191 -0
- package/dist/theme/components/shared/brand-logo.stories.tsx +49 -0
- package/dist/theme/components/shared/brand-mark.stories.tsx +53 -0
- package/dist/theme/components/shared/browser-window.css +1 -0
- package/dist/theme/components/shared/browser-window.stories.tsx +100 -0
- package/dist/theme/components/shared/browser-window.tsx +2 -0
- package/dist/theme/components/shared/card.stories.tsx +50 -0
- package/dist/theme/components/shared/card.tsx +35 -0
- package/dist/theme/components/shared/ciderpress-logo.tsx +93 -0
- package/dist/theme/components/shared/ciderpress-mark.tsx +77 -0
- package/dist/theme/components/shared/color.css +56 -0
- package/dist/theme/components/shared/color.stories.tsx +47 -0
- package/dist/theme/components/shared/color.tsx +69 -0
- package/dist/theme/components/shared/columns.css +37 -0
- package/dist/theme/components/shared/columns.stories.tsx +91 -0
- package/dist/theme/components/shared/columns.tsx +50 -0
- package/dist/theme/components/shared/desktop-window.css +339 -0
- package/dist/theme/components/shared/desktop-window.tsx +535 -0
- package/dist/theme/components/shared/field.css +158 -0
- package/dist/theme/components/shared/field.stories.tsx +100 -0
- package/dist/theme/components/shared/field.tsx +186 -0
- package/dist/theme/components/shared/frame.css +39 -0
- package/dist/theme/components/shared/frame.stories.tsx +49 -0
- package/dist/theme/components/shared/frame.tsx +76 -0
- package/dist/theme/components/shared/icon.stories.tsx +90 -0
- package/dist/theme/components/shared/icon.tsx +41 -0
- package/dist/theme/components/shared/prompt.css +178 -0
- package/dist/theme/components/shared/prompt.stories.tsx +57 -0
- package/dist/theme/components/shared/prompt.tsx +369 -0
- package/dist/theme/components/shared/resolve-card-icon.ts +28 -0
- package/dist/theme/components/shared/section-card.stories.tsx +51 -0
- package/dist/theme/components/shared/section-card.tsx +44 -0
- package/dist/theme/components/shared/section-grid.stories.tsx +46 -0
- package/dist/theme/components/shared/section-grid.tsx +15 -0
- package/dist/theme/components/shared/status-badge.css +37 -0
- package/dist/theme/components/shared/status-badge.stories.tsx +61 -0
- package/dist/theme/components/shared/status-badge.tsx +74 -0
- package/dist/theme/components/shared/steps.css +88 -0
- package/dist/theme/components/shared/steps.stories.tsx +68 -0
- package/dist/theme/components/shared/steps.tsx +100 -0
- package/dist/theme/components/shared/tech-icon-table.stories.tsx +29 -0
- package/dist/theme/components/shared/tech-icon-table.tsx +71 -0
- package/dist/theme/components/shared/tech-tag.stories.tsx +40 -0
- package/dist/theme/components/shared/tech-tag.tsx +31 -0
- package/dist/theme/components/shared/theme-color-palette.css +80 -0
- package/dist/theme/components/shared/theme-color-palette.stories.tsx +52 -0
- package/dist/theme/components/shared/theme-color-palette.tsx +275 -0
- package/dist/theme/components/shared/tooltip.css +69 -0
- package/dist/theme/components/shared/tooltip.stories.tsx +72 -0
- package/dist/theme/components/shared/tooltip.tsx +77 -0
- package/dist/theme/components/sidebar/framework-picker.css +77 -0
- package/dist/theme/components/sidebar/framework-picker.tsx +78 -0
- package/dist/theme/components/sidebar/sidebar-filter.test.ts +140 -0
- package/dist/theme/components/sidebar/sidebar-filter.ts +79 -0
- package/dist/theme/components/sidebar/sidebar-links.css +102 -0
- package/dist/theme/components/sidebar/sidebar-links.tsx +122 -0
- package/dist/theme/components/sidebar/sidebar-promo.css +42 -0
- package/dist/theme/components/sidebar/sidebar-promo.tsx +52 -0
- package/dist/theme/components/sidebar/sidebar-scope.tsx +151 -0
- package/dist/theme/components/sidebar/sidebar-toggle.css +181 -0
- package/dist/theme/components/sidebar/sidebar-toggle.tsx +127 -0
- package/dist/theme/components/theme-provider.tsx +637 -0
- package/dist/theme/components/workspaces/card.css +151 -0
- package/dist/theme/components/workspaces/card.tsx +166 -0
- package/dist/theme/components/workspaces/grid.tsx +62 -0
- package/dist/theme/css.d.ts +1 -0
- package/dist/theme/env.d.ts +12 -0
- package/dist/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/dist/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/dist/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/dist/theme/hooks/use-ciderpress.ts +61 -0
- package/dist/theme/hooks/use-nav-items.ts +76 -0
- package/dist/theme/icons/index.ts +2 -0
- package/dist/theme/icons/tech-map.ts +228 -0
- package/dist/theme/index.tsx +180 -0
- package/dist/theme/lib/read-social-links.ts +27 -0
- package/dist/theme/lib/route-link.tsx +126 -0
- package/dist/theme/lib/safe-url.test.ts +0 -0
- package/dist/theme/lib/safe-url.ts +68 -0
- package/dist/theme/lib/theme-favicon.ts +125 -0
- package/dist/theme/lib/user-config-stub.ts +12 -0
- package/dist/theme/styles/layers.css +32 -0
- package/dist/theme/styles/overrides/badge.css +26 -0
- package/dist/theme/styles/overrides/content-footer.css +80 -0
- package/dist/theme/styles/overrides/details.css +61 -0
- package/dist/theme/styles/overrides/fonts.css +32 -0
- package/dist/theme/styles/overrides/home-card.css +133 -0
- package/dist/theme/styles/overrides/home.css +243 -0
- package/dist/theme/styles/overrides/rail.css +337 -0
- package/dist/theme/styles/overrides/rspress.css +62 -0
- package/dist/theme/styles/overrides/scrollbar.css +25 -0
- package/dist/theme/styles/overrides/section-card.css +114 -0
- package/dist/theme/styles/overrides/sidebar.css +144 -0
- package/dist/theme/styles/overrides/tokens.css +288 -0
- package/dist/theme/styles/overrides/vscode.css +88 -0
- package/dist/theme/styles/themes/amber.css +545 -0
- package/dist/theme/styles/themes/arcade-fx.css +366 -0
- package/dist/theme/styles/themes/arcade.css +273 -0
- package/dist/theme/styles/themes/grannysmith.css +545 -0
- package/dist/theme/styles/themes/honeycrisp.css +545 -0
- package/dist/theme/styles/themes/midnight.css +273 -0
- package/dist/theme/styles/themes/mulled.css +817 -0
- package/package.json +103 -0
- package/src/theme/components/announcement/announcement-bar.css +103 -0
- package/src/theme/components/announcement/announcement-bar.tsx +173 -0
- package/src/theme/components/ask-ai/ask-ai-button.css +52 -0
- package/src/theme/components/ask-ai/ask-ai-button.tsx +56 -0
- package/src/theme/components/content-footer/content-footer-portal.tsx +70 -0
- package/src/theme/components/content-footer/feedback.css +47 -0
- package/src/theme/components/content-footer/feedback.tsx +96 -0
- package/src/theme/components/content-footer/meta-actions.css +25 -0
- package/src/theme/components/content-footer/meta-actions.tsx +57 -0
- package/src/theme/components/content-footer/page-pager.css +61 -0
- package/src/theme/components/content-footer/page-pager.tsx +110 -0
- package/src/theme/components/edit-source-button.tsx +97 -0
- package/src/theme/components/footer/site-footer.css +179 -0
- package/src/theme/components/footer/site-footer.tsx +115 -0
- package/src/theme/components/home/cta.css +67 -0
- package/src/theme/components/home/cta.tsx +77 -0
- package/src/theme/components/home/feature-card.css +52 -0
- package/src/theme/components/home/feature-card.tsx +131 -0
- package/src/theme/components/home/feature.tsx +79 -0
- package/src/theme/components/home/hero-demo.css +66 -0
- package/src/theme/components/home/hero-demo.tsx +46 -0
- package/src/theme/components/home/hero.css +96 -0
- package/src/theme/components/home/hero.tsx +111 -0
- package/src/theme/components/home/layout.tsx +183 -0
- package/src/theme/components/home/page-rail.css +21 -0
- package/src/theme/components/home/page-rail.tsx +19 -0
- package/src/theme/components/home/split.css +148 -0
- package/src/theme/components/home/split.tsx +120 -0
- package/src/theme/components/home/trust-strip.css +33 -0
- package/src/theme/components/home/trust-strip.tsx +43 -0
- package/src/theme/components/home/workspaces.tsx +71 -0
- package/src/theme/components/nav/branch-tag.css +54 -0
- package/src/theme/components/nav/branch-tag.tsx +101 -0
- package/src/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
- package/src/theme/components/nav/ciderpress-docs-bar.css +505 -0
- package/src/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
- package/src/theme/components/nav/ciderpress-header.css +172 -0
- package/src/theme/components/nav/ciderpress-header.tsx +113 -0
- package/src/theme/components/nav/ciderpress-layout-context.tsx +49 -0
- package/src/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
- package/src/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
- package/src/theme/components/nav/ciderpress-nav-menu.css +130 -0
- package/src/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
- package/src/theme/components/nav/ciderpress-nav-search.css +73 -0
- package/src/theme/components/nav/ciderpress-nav-search.tsx +55 -0
- package/src/theme/components/nav/ciderpress-nav-social-links.css +35 -0
- package/src/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
- package/src/theme/components/nav/floating-branch-indicator.css +106 -0
- package/src/theme/components/nav/floating-branch-indicator.tsx +109 -0
- package/src/theme/components/nav/layout.tsx +268 -0
- package/src/theme/components/nav/mobile-nav-cta.tsx +79 -0
- package/src/theme/components/nav/nav-divider.css +15 -0
- package/src/theme/components/nav/nav-divider.tsx +19 -0
- package/src/theme/components/nav/nav-logo.css +42 -0
- package/src/theme/components/nav/nav-logo.tsx +262 -0
- package/src/theme/components/nav/theme-switcher.css +92 -0
- package/src/theme/components/nav/theme-switcher.tsx +298 -0
- package/src/theme/components/nav/topbar-cta.css +45 -0
- package/src/theme/components/nav/topbar-cta.tsx +39 -0
- package/src/theme/components/nav/variant-toggle.css +70 -0
- package/src/theme/components/nav/variant-toggle.tsx +83 -0
- package/src/theme/components/nav/version-chip.css +31 -0
- package/src/theme/components/nav/version-chip.tsx +45 -0
- package/src/theme/components/nav/vscode-tag.css +32 -0
- package/src/theme/components/nav/vscode-tag.tsx +20 -0
- package/src/theme/components/openapi/code-sample.tsx +341 -0
- package/src/theme/components/openapi/copy-markdown-button.tsx +41 -0
- package/src/theme/components/openapi/icons.tsx +45 -0
- package/src/theme/components/openapi/index.ts +6 -0
- package/src/theme/components/openapi/method-badge.tsx +24 -0
- package/src/theme/components/openapi/openapi.css +665 -0
- package/src/theme/components/openapi/operation.tsx +200 -0
- package/src/theme/components/openapi/overview.tsx +207 -0
- package/src/theme/components/openapi/parameters-table.tsx +149 -0
- package/src/theme/components/openapi/request-body.tsx +90 -0
- package/src/theme/components/openapi/response-list.tsx +112 -0
- package/src/theme/components/openapi/schema-viewer.tsx +277 -0
- package/src/theme/components/openapi/security-badges.tsx +63 -0
- package/src/theme/components/openapi/spec-utils.ts +122 -0
- package/src/theme/components/shared/accordion.css +118 -0
- package/src/theme/components/shared/accordion.stories.tsx +96 -0
- package/src/theme/components/shared/accordion.tsx +191 -0
- package/src/theme/components/shared/brand-logo.stories.tsx +49 -0
- package/src/theme/components/shared/brand-mark.stories.tsx +53 -0
- package/src/theme/components/shared/browser-window.css +1 -0
- package/src/theme/components/shared/browser-window.stories.tsx +100 -0
- package/src/theme/components/shared/browser-window.tsx +2 -0
- package/src/theme/components/shared/card.stories.tsx +50 -0
- package/src/theme/components/shared/card.tsx +35 -0
- package/src/theme/components/shared/ciderpress-logo.tsx +93 -0
- package/src/theme/components/shared/ciderpress-mark.tsx +77 -0
- package/src/theme/components/shared/color.css +56 -0
- package/src/theme/components/shared/color.stories.tsx +47 -0
- package/src/theme/components/shared/color.tsx +69 -0
- package/src/theme/components/shared/columns.css +37 -0
- package/src/theme/components/shared/columns.stories.tsx +91 -0
- package/src/theme/components/shared/columns.tsx +50 -0
- package/src/theme/components/shared/desktop-window.css +339 -0
- package/src/theme/components/shared/desktop-window.tsx +535 -0
- package/src/theme/components/shared/field.css +158 -0
- package/src/theme/components/shared/field.stories.tsx +100 -0
- package/src/theme/components/shared/field.tsx +186 -0
- package/src/theme/components/shared/frame.css +39 -0
- package/src/theme/components/shared/frame.stories.tsx +49 -0
- package/src/theme/components/shared/frame.tsx +76 -0
- package/src/theme/components/shared/icon.stories.tsx +90 -0
- package/src/theme/components/shared/icon.tsx +41 -0
- package/src/theme/components/shared/prompt.css +178 -0
- package/src/theme/components/shared/prompt.stories.tsx +57 -0
- package/src/theme/components/shared/prompt.tsx +369 -0
- package/src/theme/components/shared/resolve-card-icon.ts +28 -0
- package/src/theme/components/shared/section-card.stories.tsx +51 -0
- package/src/theme/components/shared/section-card.tsx +44 -0
- package/src/theme/components/shared/section-grid.stories.tsx +46 -0
- package/src/theme/components/shared/section-grid.tsx +15 -0
- package/src/theme/components/shared/status-badge.css +37 -0
- package/src/theme/components/shared/status-badge.stories.tsx +61 -0
- package/src/theme/components/shared/status-badge.tsx +74 -0
- package/src/theme/components/shared/steps.css +88 -0
- package/src/theme/components/shared/steps.stories.tsx +68 -0
- package/src/theme/components/shared/steps.tsx +100 -0
- package/src/theme/components/shared/tech-icon-table.stories.tsx +29 -0
- package/src/theme/components/shared/tech-icon-table.tsx +71 -0
- package/src/theme/components/shared/tech-tag.stories.tsx +40 -0
- package/src/theme/components/shared/tech-tag.tsx +31 -0
- package/src/theme/components/shared/theme-color-palette.css +80 -0
- package/src/theme/components/shared/theme-color-palette.stories.tsx +52 -0
- package/src/theme/components/shared/theme-color-palette.tsx +275 -0
- package/src/theme/components/shared/tooltip.css +69 -0
- package/src/theme/components/shared/tooltip.stories.tsx +72 -0
- package/src/theme/components/shared/tooltip.tsx +77 -0
- package/src/theme/components/sidebar/framework-picker.css +77 -0
- package/src/theme/components/sidebar/framework-picker.tsx +78 -0
- package/src/theme/components/sidebar/sidebar-filter.test.ts +140 -0
- package/src/theme/components/sidebar/sidebar-filter.ts +79 -0
- package/src/theme/components/sidebar/sidebar-links.css +102 -0
- package/src/theme/components/sidebar/sidebar-links.tsx +122 -0
- package/src/theme/components/sidebar/sidebar-promo.css +42 -0
- package/src/theme/components/sidebar/sidebar-promo.tsx +52 -0
- package/src/theme/components/sidebar/sidebar-scope.tsx +151 -0
- package/src/theme/components/sidebar/sidebar-toggle.css +181 -0
- package/src/theme/components/sidebar/sidebar-toggle.tsx +127 -0
- package/src/theme/components/theme-provider.tsx +637 -0
- package/src/theme/components/workspaces/card.css +151 -0
- package/src/theme/components/workspaces/card.tsx +166 -0
- package/src/theme/components/workspaces/grid.tsx +62 -0
- package/src/theme/css.d.ts +1 -0
- package/src/theme/env.d.ts +12 -0
- package/src/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/src/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/src/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/src/theme/hooks/use-ciderpress.ts +61 -0
- package/src/theme/hooks/use-nav-items.ts +76 -0
- package/src/theme/icons/index.ts +2 -0
- package/src/theme/icons/tech-map.ts +228 -0
- package/src/theme/index.tsx +180 -0
- package/src/theme/lib/read-social-links.ts +27 -0
- package/src/theme/lib/route-link.tsx +126 -0
- package/src/theme/lib/safe-url.test.ts +0 -0
- package/src/theme/lib/safe-url.ts +68 -0
- package/src/theme/lib/theme-favicon.ts +125 -0
- package/src/theme/lib/user-config-stub.ts +12 -0
- package/src/theme/styles/layers.css +32 -0
- package/src/theme/styles/overrides/badge.css +26 -0
- package/src/theme/styles/overrides/content-footer.css +80 -0
- package/src/theme/styles/overrides/details.css +61 -0
- package/src/theme/styles/overrides/fonts.css +32 -0
- package/src/theme/styles/overrides/home-card.css +133 -0
- package/src/theme/styles/overrides/home.css +243 -0
- package/src/theme/styles/overrides/rail.css +337 -0
- package/src/theme/styles/overrides/rspress.css +62 -0
- package/src/theme/styles/overrides/scrollbar.css +25 -0
- package/src/theme/styles/overrides/section-card.css +114 -0
- package/src/theme/styles/overrides/sidebar.css +144 -0
- package/src/theme/styles/overrides/tokens.css +288 -0
- package/src/theme/styles/overrides/vscode.css +88 -0
- package/src/theme/styles/themes/amber.css +545 -0
- package/src/theme/styles/themes/arcade-fx.css +366 -0
- package/src/theme/styles/themes/arcade.css +273 -0
- package/src/theme/styles/themes/grannysmith.css +545 -0
- package/src/theme/styles/themes/honeycrisp.css +545 -0
- package/src/theme/styles/themes/midnight.css +273 -0
- package/src/theme/styles/themes/mulled.css +817 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace grid, card layout, deploy badge, and tech tags.
|
|
3
|
+
* Base card styles (container, hover, icons) from home-card.css.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Workspace section ───────────────────────────────────── */
|
|
7
|
+
.cp-workspace-section {
|
|
8
|
+
max-width: 1152px;
|
|
9
|
+
margin: 0 auto;
|
|
10
|
+
padding-bottom: 64px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cp-workspace-section h2 {
|
|
14
|
+
font-size: 18px;
|
|
15
|
+
font-weight: 600;
|
|
16
|
+
letter-spacing: 0.02em;
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
margin-bottom: 4px;
|
|
19
|
+
color: var(--cp-c-text-2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.cp-workspace-section__desc {
|
|
23
|
+
margin: 0 0 16px;
|
|
24
|
+
font-size: 14px;
|
|
25
|
+
color: var(--cp-c-text-3);
|
|
26
|
+
line-height: 1.5;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.cp-workspace-grid {
|
|
30
|
+
display: grid;
|
|
31
|
+
grid-template-columns: repeat(var(--cp-workspace-cols, 2), 1fr);
|
|
32
|
+
gap: 12px;
|
|
33
|
+
margin-bottom: 40px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* ── Workspace card layout ───────────────────────────────── */
|
|
37
|
+
.cp-workspace-card {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.cp-workspace-card__header {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
margin-bottom: 10px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.cp-workspace-card__identity {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: 10px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.cp-workspace-card__title {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
line-height: 1.2;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.cp-workspace-card__scope {
|
|
62
|
+
font-family: var(--cp-font-family-mono);
|
|
63
|
+
font-size: 11px;
|
|
64
|
+
color: var(--cp-c-text-3);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.cp-workspace-card__name {
|
|
68
|
+
font-family: var(--cp-font-family-mono);
|
|
69
|
+
font-size: 15px;
|
|
70
|
+
font-weight: 700;
|
|
71
|
+
color: var(--cp-c-text-1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.cp-workspace-card__desc {
|
|
75
|
+
font-size: 13px;
|
|
76
|
+
color: var(--cp-c-text-2);
|
|
77
|
+
line-height: 1.5;
|
|
78
|
+
flex: 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ── Truncation ─────────────────────────────────────────── */
|
|
82
|
+
.cp-workspace-card__name.cp-clamp,
|
|
83
|
+
.cp-workspace-card__desc.cp-clamp {
|
|
84
|
+
display: -webkit-box;
|
|
85
|
+
-webkit-box-orient: vertical;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
text-overflow: ellipsis;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* ── Deploy badge ────────────────────────────────────────── */
|
|
91
|
+
.cp-workspace-card__badge {
|
|
92
|
+
display: flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
padding: 4px 6px;
|
|
96
|
+
border-radius: 6px;
|
|
97
|
+
background: var(--cp-c-bg);
|
|
98
|
+
border: 1px solid var(--cp-c-divider);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.cp-workspace-card__badge-logo {
|
|
102
|
+
height: 16px;
|
|
103
|
+
width: auto;
|
|
104
|
+
opacity: 0.75;
|
|
105
|
+
transition: opacity 0.2s;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.cp-card:hover .cp-workspace-card__badge-logo {
|
|
109
|
+
opacity: 1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* ── Tech tags ───────────────────────────────────────────── */
|
|
113
|
+
.cp-workspace-card__tags {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-wrap: wrap;
|
|
116
|
+
gap: 6px;
|
|
117
|
+
margin-top: 10px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.cp-tag {
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
gap: 4px;
|
|
124
|
+
font-family: var(--cp-font-family-mono);
|
|
125
|
+
font-size: 11px;
|
|
126
|
+
padding: 2px 8px;
|
|
127
|
+
border-radius: var(--rp-radius-small);
|
|
128
|
+
background: var(--cp-c-bg);
|
|
129
|
+
color: var(--cp-c-text-3);
|
|
130
|
+
border: 1px solid var(--cp-c-divider);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.cp-tag svg {
|
|
134
|
+
width: 14px;
|
|
135
|
+
height: 14px;
|
|
136
|
+
flex-shrink: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* ── Responsive ──────────────────────────────────────────── */
|
|
140
|
+
@media (max-width: 1184px) {
|
|
141
|
+
.cp-workspace-section {
|
|
142
|
+
padding-left: 16px;
|
|
143
|
+
padding-right: 16px;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@media (max-width: 768px) {
|
|
148
|
+
.cp-workspace-grid {
|
|
149
|
+
grid-template-columns: 1fr;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { match, P } from 'massaman/match'
|
|
2
|
+
import type React from 'react'
|
|
3
|
+
|
|
4
|
+
import { Card } from '../shared/card'
|
|
5
|
+
import { Icon } from '../shared/icon'
|
|
6
|
+
import { resolveCardIcon } from '../shared/resolve-card-icon'
|
|
7
|
+
import { TechTag } from '../shared/tech-tag'
|
|
8
|
+
|
|
9
|
+
export interface WorkspaceCardProps {
|
|
10
|
+
/**
|
|
11
|
+
* Display name for the card header.
|
|
12
|
+
*/
|
|
13
|
+
readonly title: string
|
|
14
|
+
/**
|
|
15
|
+
* Link target (e.g. "/apps/api").
|
|
16
|
+
*/
|
|
17
|
+
readonly href: string
|
|
18
|
+
/**
|
|
19
|
+
* Icon config — Iconify identifier string or `{ id, color }` object.
|
|
20
|
+
*/
|
|
21
|
+
readonly icon?: string | { readonly id: string; readonly color: string }
|
|
22
|
+
/**
|
|
23
|
+
* Scope prefix shown above the name (e.g. "apps/").
|
|
24
|
+
*/
|
|
25
|
+
readonly scope?: string
|
|
26
|
+
/**
|
|
27
|
+
* Short description rendered below the header.
|
|
28
|
+
*/
|
|
29
|
+
readonly description?: string
|
|
30
|
+
/**
|
|
31
|
+
* Technology tag names resolved via the tech map.
|
|
32
|
+
*/
|
|
33
|
+
readonly tags?: readonly string[]
|
|
34
|
+
/**
|
|
35
|
+
* Deploy badge image for the card header.
|
|
36
|
+
*/
|
|
37
|
+
readonly badge?: { readonly src: string; readonly alt: string }
|
|
38
|
+
/**
|
|
39
|
+
* Max lines for the title before ellipsis truncation.
|
|
40
|
+
*/
|
|
41
|
+
readonly titleLines?: number
|
|
42
|
+
/**
|
|
43
|
+
* Max lines for the description before ellipsis truncation.
|
|
44
|
+
*/
|
|
45
|
+
readonly descriptionLines?: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Workspace card — renders a clickable link card with icon, name,
|
|
50
|
+
* description, tech tags, and optional deploy badge.
|
|
51
|
+
*
|
|
52
|
+
* @param props - Props with title, href, and optional icon, scope, description, tags, badge, titleLines, descriptionLines
|
|
53
|
+
* @returns React element with a workspace link card
|
|
54
|
+
*/
|
|
55
|
+
export function WorkspaceCard({
|
|
56
|
+
title,
|
|
57
|
+
href,
|
|
58
|
+
icon,
|
|
59
|
+
scope,
|
|
60
|
+
description,
|
|
61
|
+
tags,
|
|
62
|
+
badge,
|
|
63
|
+
titleLines,
|
|
64
|
+
descriptionLines,
|
|
65
|
+
}: WorkspaceCardProps): React.ReactElement {
|
|
66
|
+
const name = title.toLowerCase()
|
|
67
|
+
const resolved = resolveCardIcon(icon)
|
|
68
|
+
|
|
69
|
+
const iconEl = match(resolved)
|
|
70
|
+
.with(P.nonNullable, (r) => <Icon icon={r.id} />)
|
|
71
|
+
.otherwise(() => null)
|
|
72
|
+
|
|
73
|
+
const iconColor = match(resolved)
|
|
74
|
+
.with(P.nonNullable, (r) => r.color)
|
|
75
|
+
.otherwise(() => 'purple')
|
|
76
|
+
|
|
77
|
+
const scopeEl = match(scope)
|
|
78
|
+
.with(
|
|
79
|
+
P.when((s): s is string => s !== undefined && s.length > 0),
|
|
80
|
+
(s) => <span className="cp-workspace-card__scope">{s}</span>
|
|
81
|
+
)
|
|
82
|
+
.otherwise(() => null)
|
|
83
|
+
|
|
84
|
+
const badgeEl = match(badge)
|
|
85
|
+
.with(P.nonNullable, (b) => (
|
|
86
|
+
<span className="cp-workspace-card__badge" title={`Deployed on ${b.alt}`}>
|
|
87
|
+
<img src={b.src} alt={b.alt} className="cp-workspace-card__badge-logo" />
|
|
88
|
+
</span>
|
|
89
|
+
))
|
|
90
|
+
.otherwise(() => null)
|
|
91
|
+
|
|
92
|
+
const descEl = match(description)
|
|
93
|
+
.with(P.nonNullable, (d) => (
|
|
94
|
+
<span
|
|
95
|
+
className={clampClass('cp-workspace-card__desc', descriptionLines)}
|
|
96
|
+
style={clampStyle(descriptionLines)}
|
|
97
|
+
>
|
|
98
|
+
{d}
|
|
99
|
+
</span>
|
|
100
|
+
))
|
|
101
|
+
.otherwise(() => null)
|
|
102
|
+
|
|
103
|
+
const tagsEl = match(tags)
|
|
104
|
+
.with(
|
|
105
|
+
P.when((t): t is readonly string[] => t !== undefined && t.length > 0),
|
|
106
|
+
(t) => (
|
|
107
|
+
<div className="cp-workspace-card__tags">
|
|
108
|
+
{t.map((tag) => (
|
|
109
|
+
<TechTag key={tag} name={tag} />
|
|
110
|
+
))}
|
|
111
|
+
</div>
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
.otherwise(() => null)
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<Card href={href} className="cp-workspace-card">
|
|
118
|
+
<div className="cp-workspace-card__header">
|
|
119
|
+
<div className="cp-workspace-card__identity">
|
|
120
|
+
<span className={`cp-card__icon cp-card__icon--${iconColor}`}>{iconEl}</span>
|
|
121
|
+
<div className="cp-workspace-card__title">
|
|
122
|
+
{scopeEl}
|
|
123
|
+
<span
|
|
124
|
+
className={clampClass('cp-workspace-card__name', titleLines)}
|
|
125
|
+
style={clampStyle(titleLines)}
|
|
126
|
+
>
|
|
127
|
+
{name}
|
|
128
|
+
</span>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
{badgeEl}
|
|
132
|
+
</div>
|
|
133
|
+
{descEl}
|
|
134
|
+
{tagsEl}
|
|
135
|
+
</Card>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Build a className string with optional `cp-clamp` suffix.
|
|
141
|
+
*
|
|
142
|
+
* @private
|
|
143
|
+
* @param base - Base CSS class name
|
|
144
|
+
* @param lines - Optional line clamp value
|
|
145
|
+
* @returns Class string with or without cp-clamp
|
|
146
|
+
*/
|
|
147
|
+
function clampClass(base: string, lines: number | undefined): string {
|
|
148
|
+
if (lines) {
|
|
149
|
+
return `${base} cp-clamp`
|
|
150
|
+
}
|
|
151
|
+
return base
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Build an inline style object for line clamping.
|
|
156
|
+
*
|
|
157
|
+
* @private
|
|
158
|
+
* @param lines - Optional line clamp value
|
|
159
|
+
* @returns Style object with WebkitLineClamp or undefined
|
|
160
|
+
*/
|
|
161
|
+
function clampStyle(lines: number | undefined): React.CSSProperties | undefined {
|
|
162
|
+
if (lines) {
|
|
163
|
+
return { WebkitLineClamp: lines }
|
|
164
|
+
}
|
|
165
|
+
return undefined
|
|
166
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
|
|
3
|
+
import './card.css'
|
|
4
|
+
|
|
5
|
+
export interface WorkspaceGridProps {
|
|
6
|
+
/**
|
|
7
|
+
* Section heading (e.g. "Apps", "Packages").
|
|
8
|
+
*/
|
|
9
|
+
readonly heading: string
|
|
10
|
+
/**
|
|
11
|
+
* Brief description rendered below the heading.
|
|
12
|
+
*/
|
|
13
|
+
readonly description: string
|
|
14
|
+
/**
|
|
15
|
+
* Number of grid columns.
|
|
16
|
+
*/
|
|
17
|
+
readonly columns?: number
|
|
18
|
+
/**
|
|
19
|
+
* WorkspaceCard elements.
|
|
20
|
+
*/
|
|
21
|
+
readonly children: React.ReactNode
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Grid container for workspace cards — renders a heading, description,
|
|
26
|
+
* and a CSS grid wrapping its children.
|
|
27
|
+
*
|
|
28
|
+
* @param props - Props with heading, description, columns, and children workspace cards
|
|
29
|
+
* @returns React element with heading, description, and grid layout
|
|
30
|
+
*/
|
|
31
|
+
export function WorkspaceGrid({
|
|
32
|
+
heading,
|
|
33
|
+
description,
|
|
34
|
+
columns,
|
|
35
|
+
children,
|
|
36
|
+
}: WorkspaceGridProps): React.ReactElement {
|
|
37
|
+
const style = columnsStyle(columns)
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
<h2>{heading}</h2>
|
|
42
|
+
<p className="cp-workspace-section__desc">{description}</p>
|
|
43
|
+
<div className="cp-workspace-grid" style={style}>
|
|
44
|
+
{children}
|
|
45
|
+
</div>
|
|
46
|
+
</>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build an inline style object for the workspace grid column count.
|
|
52
|
+
*
|
|
53
|
+
* @private
|
|
54
|
+
* @param columns - Optional column count
|
|
55
|
+
* @returns Style object with CSS variable or undefined
|
|
56
|
+
*/
|
|
57
|
+
function columnsStyle(columns: number | undefined): React.CSSProperties | undefined {
|
|
58
|
+
if (columns !== undefined) {
|
|
59
|
+
return { '--cp-workspace-cols': String(columns) } as React.CSSProperties
|
|
60
|
+
}
|
|
61
|
+
return undefined
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css' {}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface ImportMetaEnv {
|
|
2
|
+
/**
|
|
3
|
+
* Set to `true` by Rspress during the SSG-MD rendering pass
|
|
4
|
+
* (the build step that generates per-page `.md` files and `llms.txt`).
|
|
5
|
+
* Always `false` during normal browser and HTML SSR rendering.
|
|
6
|
+
*/
|
|
7
|
+
readonly SSG_MD: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ImportMeta {
|
|
11
|
+
readonly env: ImportMetaEnv
|
|
12
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { FooterConfig, HomeConfig, SiteConfig } from '@ciderpress/config'
|
|
2
|
+
import { useSite } from '@rspress/core/runtime'
|
|
3
|
+
|
|
4
|
+
export interface CiderpressSidebarItem {
|
|
5
|
+
readonly text?: string
|
|
6
|
+
readonly link?: string
|
|
7
|
+
readonly icon?: string
|
|
8
|
+
readonly items?: readonly CiderpressSidebarItem[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CiderpressSidebarLink {
|
|
12
|
+
readonly text: string
|
|
13
|
+
readonly link: string
|
|
14
|
+
readonly icon?: string | { readonly id: string; readonly color: string }
|
|
15
|
+
readonly style?: 'brand' | 'alt' | 'ghost'
|
|
16
|
+
readonly shape?: 'square' | 'rounded' | 'circle'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface WorkspaceCardData {
|
|
20
|
+
readonly title: string
|
|
21
|
+
readonly href: string
|
|
22
|
+
readonly icon: string | { readonly id: string; readonly color: string } | undefined
|
|
23
|
+
readonly scope: string | undefined
|
|
24
|
+
readonly description: string | undefined
|
|
25
|
+
readonly tags: readonly string[]
|
|
26
|
+
readonly badge: { readonly src: string; readonly alt: string } | undefined
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface WorkspaceGroupData {
|
|
30
|
+
readonly type: 'apps' | 'packages' | 'workspaces'
|
|
31
|
+
readonly heading: string
|
|
32
|
+
readonly description: string
|
|
33
|
+
readonly cards: readonly WorkspaceCardData[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface CiderpressThemeConfig {
|
|
37
|
+
readonly sidebar: Record<string, readonly CiderpressSidebarItem[]>
|
|
38
|
+
readonly sidebarAbove: readonly CiderpressSidebarLink[] | undefined
|
|
39
|
+
readonly sidebarBelow: readonly CiderpressSidebarLink[] | undefined
|
|
40
|
+
readonly workspaces: readonly WorkspaceGroupData[] | undefined
|
|
41
|
+
readonly standaloneScopePaths: readonly string[] | undefined
|
|
42
|
+
readonly home: HomeConfig | undefined
|
|
43
|
+
readonly ciderpressFooter: FooterConfig | undefined
|
|
44
|
+
readonly site: SiteConfig | undefined
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Typed wrapper around Rspress `useSite()` that exposes
|
|
49
|
+
* ciderpress-specific themeConfig fields.
|
|
50
|
+
*
|
|
51
|
+
* The double cast is necessary because Rspress types `themeConfig` as
|
|
52
|
+
* `NormalizedThemeConfig`, but ciderpress injects custom fields (sidebar,
|
|
53
|
+
* workspaces) via spread at build time. No Zod schema exists for runtime
|
|
54
|
+
* validation yet.
|
|
55
|
+
*
|
|
56
|
+
* @returns ciderpress theme config with sidebar and workspace data.
|
|
57
|
+
*/
|
|
58
|
+
export function useCiderpress(): CiderpressThemeConfig {
|
|
59
|
+
const { site } = useSite()
|
|
60
|
+
return site.themeConfig as unknown as CiderpressThemeConfig
|
|
61
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { CiderpressNavMenuItem } from '../components/nav/ciderpress-nav-menu'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook that yields the primary nav items.
|
|
7
|
+
*
|
|
8
|
+
* Rspress's `site` object doesn't surface its top-level `nav` field on
|
|
9
|
+
* the public typings reachable from a custom layout. We fall back to
|
|
10
|
+
* scraping the items off Rspress's auto-rendered `.rp-nav-menu` (which
|
|
11
|
+
* is mounted but visually hidden by `<CiderpressHeader />`). A
|
|
12
|
+
* `MutationObserver` retries if the items haven't been written into
|
|
13
|
+
* the DOM by first paint.
|
|
14
|
+
*
|
|
15
|
+
* @returns Live array of `{ text, link }` items; empty until Rspress mounts
|
|
16
|
+
*/
|
|
17
|
+
export function useNavItems(): readonly CiderpressNavMenuItem[] {
|
|
18
|
+
const [items, setItems] = useState<readonly CiderpressNavMenuItem[]>([])
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const initial = scrapeNavItems()
|
|
22
|
+
if (initial.length > 0) {
|
|
23
|
+
setItems(initial)
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const observer = new MutationObserver(() => {
|
|
28
|
+
const next = scrapeNavItems()
|
|
29
|
+
if (next.length > 0) {
|
|
30
|
+
setItems(next)
|
|
31
|
+
observer.disconnect()
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
observer.observe(document.body, { childList: true, subtree: true })
|
|
35
|
+
return () => {
|
|
36
|
+
observer.disconnect()
|
|
37
|
+
}
|
|
38
|
+
}, [])
|
|
39
|
+
|
|
40
|
+
return items
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Read every anchor under Rspress's hidden `.rp-nav-menu` and project
|
|
45
|
+
* it into a `{ text, link }` item. Anchors with empty text or `href`
|
|
46
|
+
* are dropped so we never surface a placeholder entry.
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
* @returns Nav items currently in the DOM (empty array when not mounted).
|
|
50
|
+
*/
|
|
51
|
+
function scrapeNavItems(): readonly CiderpressNavMenuItem[] {
|
|
52
|
+
const anchors = document.querySelectorAll<HTMLAnchorElement>('.rp-nav-menu .rp-nav-menu__item a')
|
|
53
|
+
return [...anchors]
|
|
54
|
+
.map((anchor) => ({
|
|
55
|
+
text: readAnchorText(anchor),
|
|
56
|
+
link: anchor.getAttribute('href') ?? '',
|
|
57
|
+
}))
|
|
58
|
+
.filter((item) => item.text !== '' && item.link !== '')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Pull the trimmed text content from an anchor. Returns an empty
|
|
63
|
+
* string when `textContent` is missing — callers treat empty as "skip
|
|
64
|
+
* this anchor".
|
|
65
|
+
*
|
|
66
|
+
* @private
|
|
67
|
+
* @param anchor - Anchor element to read.
|
|
68
|
+
* @returns Trimmed inner text, or empty string when absent.
|
|
69
|
+
*/
|
|
70
|
+
function readAnchorText(anchor: HTMLAnchorElement): string {
|
|
71
|
+
const text = anchor.textContent
|
|
72
|
+
if (text === null) {
|
|
73
|
+
return ''
|
|
74
|
+
}
|
|
75
|
+
return text.trim()
|
|
76
|
+
}
|