@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,183 @@
|
|
|
1
|
+
import { useFrontmatter } from '@rspress/core/runtime'
|
|
2
|
+
import { match } from 'massaman/match'
|
|
3
|
+
import type React from 'react'
|
|
4
|
+
|
|
5
|
+
import { SiteFooter } from '../footer/site-footer'
|
|
6
|
+
import { CTA } from './cta'
|
|
7
|
+
import { HomeFeature } from './feature'
|
|
8
|
+
import { Hero } from './hero'
|
|
9
|
+
import type { HeroAction } from './hero'
|
|
10
|
+
import { HeroDemo } from './hero-demo'
|
|
11
|
+
import { PageRail } from './page-rail'
|
|
12
|
+
import { HomeSplit } from './split'
|
|
13
|
+
import { TrustStrip } from './trust-strip'
|
|
14
|
+
import { HomeWorkspaces } from './workspaces'
|
|
15
|
+
|
|
16
|
+
interface HomeLayoutProps {
|
|
17
|
+
readonly beforeHero?: React.ReactNode
|
|
18
|
+
readonly afterHero?: React.ReactNode
|
|
19
|
+
readonly beforeFeatures?: React.ReactNode
|
|
20
|
+
readonly afterFeatures?: React.ReactNode
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface FrontmatterHero {
|
|
24
|
+
readonly name?: string
|
|
25
|
+
readonly text?: string
|
|
26
|
+
readonly tagline?: string
|
|
27
|
+
readonly actions?: readonly HeroAction[]
|
|
28
|
+
readonly eyebrow?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface FrontmatterTrust {
|
|
32
|
+
readonly lead?: string
|
|
33
|
+
readonly names?: readonly string[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface FrontmatterCTA {
|
|
37
|
+
readonly title?: string
|
|
38
|
+
readonly subtitle?: string
|
|
39
|
+
readonly actions?: readonly HeroAction[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Custom HomeLayout for ciderpress.
|
|
44
|
+
*
|
|
45
|
+
* Renders the approved mockup landing surface inside a continuous PageRail:
|
|
46
|
+
* Hero → TrustStrip → Features → Workspaces → CTA → SiteFooter. Sections
|
|
47
|
+
* render only when their data is present in frontmatter, so consumers opt
|
|
48
|
+
* in to each band individually.
|
|
49
|
+
*
|
|
50
|
+
* @param props - Slot props (kept for API compatibility with Rspress's HomeLayout).
|
|
51
|
+
* @returns React element with the home page.
|
|
52
|
+
*/
|
|
53
|
+
export function HomeLayout(props: HomeLayoutProps): React.ReactElement {
|
|
54
|
+
const { frontmatter } = useFrontmatter()
|
|
55
|
+
const fm = frontmatter as Record<string, unknown>
|
|
56
|
+
|
|
57
|
+
const hero = fm.hero as FrontmatterHero | undefined
|
|
58
|
+
const trust = fm.trust as FrontmatterTrust | undefined
|
|
59
|
+
const cta = fm.cta as FrontmatterCTA | undefined
|
|
60
|
+
|
|
61
|
+
const heroSection = match(hero)
|
|
62
|
+
.with(undefined, () => null)
|
|
63
|
+
.otherwise((h) => (
|
|
64
|
+
<Hero
|
|
65
|
+
eyebrow={h.eyebrow}
|
|
66
|
+
title={renderTitle(h.text ?? h.name ?? '')}
|
|
67
|
+
tagline={h.tagline}
|
|
68
|
+
actions={h.actions}
|
|
69
|
+
demo={<HeroDemo />}
|
|
70
|
+
/>
|
|
71
|
+
))
|
|
72
|
+
|
|
73
|
+
const trustSection = match(trust)
|
|
74
|
+
.with(undefined, () => null)
|
|
75
|
+
.otherwise((t) => {
|
|
76
|
+
const names = t.names ?? []
|
|
77
|
+
return match(names.length === 0)
|
|
78
|
+
.with(true, () => null)
|
|
79
|
+
.otherwise(() => <TrustStrip lead={t.lead} names={names} />)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const ctaSection = match(cta)
|
|
83
|
+
.with(undefined, () => null)
|
|
84
|
+
.otherwise((c) =>
|
|
85
|
+
match(c.title === undefined)
|
|
86
|
+
.with(true, () => null)
|
|
87
|
+
.otherwise(() => <CTA title={c.title ?? ''} subtitle={c.subtitle} actions={c.actions} />)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<PageRail>
|
|
92
|
+
{props.beforeHero}
|
|
93
|
+
{heroSection}
|
|
94
|
+
{props.afterHero}
|
|
95
|
+
{trustSection}
|
|
96
|
+
{props.beforeFeatures}
|
|
97
|
+
<HomeFeature />
|
|
98
|
+
{props.afterFeatures}
|
|
99
|
+
<HomeSplit
|
|
100
|
+
eyebrow="Configuration"
|
|
101
|
+
title="One file. Validated. Type-safe."
|
|
102
|
+
body="Define your docs site in ciderpress.config.ts. Zod validates at boot — no surprises in prod."
|
|
103
|
+
bullets={[
|
|
104
|
+
'Type-safe config with full IntelliSense',
|
|
105
|
+
'Hot-reloads on every save',
|
|
106
|
+
'Composable presets for OpenAPI, blog, changelog',
|
|
107
|
+
'First-class i18n out of the box',
|
|
108
|
+
]}
|
|
109
|
+
action={{ theme: 'brand', text: 'Read the docs', link: '/getting-started/quick-start' }}
|
|
110
|
+
visual={<ConfigPreview />}
|
|
111
|
+
/>
|
|
112
|
+
<HomeWorkspaces />
|
|
113
|
+
{ctaSection}
|
|
114
|
+
<SiteFooter />
|
|
115
|
+
</PageRail>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* ConfigPreview — minimal `defineConfig` code preview shown inside the
|
|
121
|
+
* Split section. Imports come exclusively from `ciderpress` so the
|
|
122
|
+
* sample resolves against the published package set.
|
|
123
|
+
*
|
|
124
|
+
* @returns React element.
|
|
125
|
+
*/
|
|
126
|
+
function ConfigPreview(): React.ReactElement {
|
|
127
|
+
return (
|
|
128
|
+
<pre>
|
|
129
|
+
<span className="tok-kw">import</span> {'{ defineConfig }'}{' '}
|
|
130
|
+
<span className="tok-kw">from</span> <span className="tok-str">'ciderpress'</span>
|
|
131
|
+
{'\n\n'}
|
|
132
|
+
<span className="tok-kw">export default</span> <span className="tok-fn">defineConfig</span>
|
|
133
|
+
{'({\n'}
|
|
134
|
+
{' title: '}
|
|
135
|
+
<span className="tok-str">'Acme Docs'</span>
|
|
136
|
+
{',\n'}
|
|
137
|
+
{' sections: [\n'}
|
|
138
|
+
{' { title: '}
|
|
139
|
+
<span className="tok-str">'Guides'</span>
|
|
140
|
+
{', include: '}
|
|
141
|
+
<span className="tok-str">'docs/guides/*.md'</span>
|
|
142
|
+
{' },\n'}
|
|
143
|
+
{' ],\n'}
|
|
144
|
+
{' theme: { name: '}
|
|
145
|
+
<span className="tok-str">'mulled'</span>
|
|
146
|
+
{' },\n'}
|
|
147
|
+
{'})'}
|
|
148
|
+
</pre>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Render a hero title with the trailing segment styled as a gradient.
|
|
154
|
+
*
|
|
155
|
+
* Splits the title on its last word break and wraps the tail in
|
|
156
|
+
* `<span className="cp-hero__grad">`. When the title is a single word
|
|
157
|
+
* (or empty), it renders verbatim.
|
|
158
|
+
*
|
|
159
|
+
* @private
|
|
160
|
+
* @param raw - The raw title string from frontmatter.
|
|
161
|
+
* @returns Title fragment with a gradient tail when applicable.
|
|
162
|
+
*/
|
|
163
|
+
function renderTitle(raw: string): React.ReactNode {
|
|
164
|
+
const trimmed = raw.trim()
|
|
165
|
+
return match(trimmed.length === 0)
|
|
166
|
+
.with(true, () => null)
|
|
167
|
+
.otherwise(() => {
|
|
168
|
+
const words = trimmed.split(/\s+/)
|
|
169
|
+
return match(words.length <= 1)
|
|
170
|
+
.with(true, () => trimmed)
|
|
171
|
+
.otherwise(() => {
|
|
172
|
+
const tailCount = Math.max(1, Math.ceil(words.length / 2))
|
|
173
|
+
const headWords = words.slice(0, words.length - tailCount).join(' ')
|
|
174
|
+
const tailWords = words.slice(words.length - tailCount).join(' ')
|
|
175
|
+
return (
|
|
176
|
+
<>
|
|
177
|
+
{headWords}
|
|
178
|
+
<span className="cp-hero__grad"> {tailWords}</span>
|
|
179
|
+
</>
|
|
180
|
+
)
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.cp-page-rail {
|
|
2
|
+
max-width: var(--cp-landing-max-width);
|
|
3
|
+
margin: 0 var(--cp-frame-gutter);
|
|
4
|
+
background: transparent;
|
|
5
|
+
border-left: 1px solid var(--cp-c-border);
|
|
6
|
+
border-right: 1px solid var(--cp-c-border);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cp-page-rail > * {
|
|
10
|
+
border-bottom: 1px solid var(--cp-c-border);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cp-page-rail > *:last-child {
|
|
14
|
+
border-bottom: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (min-width: 1248px) {
|
|
18
|
+
.cp-page-rail {
|
|
19
|
+
margin: 0 auto;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
|
|
3
|
+
import './page-rail.css'
|
|
4
|
+
|
|
5
|
+
export interface PageRailProps {
|
|
6
|
+
readonly children: React.ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* PageRail — bounded max-width rail with continuous vertical hairlines on
|
|
11
|
+
* each outer edge. Wraps the entire home/landing surface so every section
|
|
12
|
+
* inside reads as a stack of compartments. Mirrors the mockup landing.
|
|
13
|
+
*
|
|
14
|
+
* @param props - Children to render inside the rail.
|
|
15
|
+
* @returns React element.
|
|
16
|
+
*/
|
|
17
|
+
export function PageRail(props: PageRailProps): React.ReactElement {
|
|
18
|
+
return <div className="cp-page-rail">{props.children}</div>
|
|
19
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
.cp-split {
|
|
2
|
+
padding: var(--cp-s-96) var(--cp-s-32);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
@media (max-width: 720px) {
|
|
6
|
+
.cp-split {
|
|
7
|
+
padding: var(--cp-s-64) var(--cp-s-20);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.cp-split__inner {
|
|
12
|
+
display: grid;
|
|
13
|
+
grid-template-columns: 1fr 1fr;
|
|
14
|
+
gap: var(--cp-s-64);
|
|
15
|
+
align-items: center;
|
|
16
|
+
max-width: var(--cp-size-split-max);
|
|
17
|
+
margin: 0 auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@media (max-width: 880px) {
|
|
21
|
+
.cp-split__inner {
|
|
22
|
+
grid-template-columns: 1fr;
|
|
23
|
+
gap: var(--cp-s-32);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.cp-split__copy {
|
|
28
|
+
min-width: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.cp-split__eyebrow {
|
|
32
|
+
font-family: var(--cp-font-family-mono);
|
|
33
|
+
font-size: var(--cp-fs-eyebrow);
|
|
34
|
+
text-transform: uppercase;
|
|
35
|
+
letter-spacing: var(--cp-letter-eyebrow);
|
|
36
|
+
color: var(--cp-c-brand-1);
|
|
37
|
+
margin-bottom: var(--cp-s-12);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.cp-split__title {
|
|
41
|
+
font-size: var(--cp-fs-split-title);
|
|
42
|
+
font-weight: 600;
|
|
43
|
+
letter-spacing: var(--cp-letter-display);
|
|
44
|
+
line-height: var(--cp-lh-display);
|
|
45
|
+
margin: 0 0 var(--cp-s-16);
|
|
46
|
+
color: var(--cp-c-text-1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.cp-split__body {
|
|
50
|
+
font-size: var(--cp-fs-body);
|
|
51
|
+
line-height: var(--cp-lh-relaxed);
|
|
52
|
+
color: var(--cp-c-text-2);
|
|
53
|
+
margin: 0 0 var(--cp-s-24);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.cp-split__bullets {
|
|
57
|
+
list-style: none;
|
|
58
|
+
margin: 0 0 var(--cp-s-24);
|
|
59
|
+
padding: 0;
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
gap: var(--cp-s-12);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.cp-split__bullets li {
|
|
66
|
+
display: flex;
|
|
67
|
+
gap: var(--cp-s-12);
|
|
68
|
+
font-size: var(--cp-fs-bullet);
|
|
69
|
+
color: var(--cp-c-text-1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.cp-split__check {
|
|
73
|
+
width: var(--cp-size-check);
|
|
74
|
+
height: var(--cp-size-check);
|
|
75
|
+
border-radius: 50%;
|
|
76
|
+
background: var(--cp-c-brand-soft);
|
|
77
|
+
color: var(--cp-c-brand-1);
|
|
78
|
+
display: grid;
|
|
79
|
+
place-items: center;
|
|
80
|
+
font-size: var(--cp-fs-check);
|
|
81
|
+
flex-shrink: 0;
|
|
82
|
+
margin-top: var(--cp-s-2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.cp-split__btn {
|
|
86
|
+
display: inline-flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: var(--cp-s-8);
|
|
89
|
+
padding: var(--cp-s-10) var(--cp-s-18);
|
|
90
|
+
font-size: var(--cp-fs-btn);
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
border-radius: var(--cp-radius-pill);
|
|
93
|
+
border: 1px solid var(--cp-c-border);
|
|
94
|
+
background: transparent;
|
|
95
|
+
color: var(--cp-c-text-1);
|
|
96
|
+
cursor: pointer;
|
|
97
|
+
transition: all var(--cp-duration-fast) var(--cp-ease-base);
|
|
98
|
+
text-decoration: none;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.cp-split__btn:hover {
|
|
102
|
+
background: var(--cp-c-bg-soft);
|
|
103
|
+
border-color: var(--cp-c-border);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.cp-split__btn--primary {
|
|
107
|
+
background: var(--cp-c-brand-1);
|
|
108
|
+
color: var(--cp-c-brand-fg);
|
|
109
|
+
border-color: var(--cp-c-brand-1);
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.cp-split__btn--primary:hover {
|
|
114
|
+
background: var(--cp-c-brand-2);
|
|
115
|
+
border-color: var(--cp-c-brand-2);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Code visual styling — works for any pre/code or window child */
|
|
119
|
+
.cp-split__visual {
|
|
120
|
+
border: 1px solid var(--cp-c-border);
|
|
121
|
+
border-radius: var(--cp-radius-lg);
|
|
122
|
+
overflow: hidden;
|
|
123
|
+
background: var(--cp-code-block-bg);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.cp-split__visual pre {
|
|
127
|
+
margin: 0;
|
|
128
|
+
padding: var(--cp-s-18) var(--cp-s-20);
|
|
129
|
+
font-family: var(--cp-font-family-mono);
|
|
130
|
+
font-size: var(--cp-fs-code);
|
|
131
|
+
line-height: var(--cp-lh-code);
|
|
132
|
+
white-space: pre;
|
|
133
|
+
overflow-x: auto;
|
|
134
|
+
color: var(--cp-c-text-1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.cp-split__visual .tok-kw {
|
|
138
|
+
color: var(--cp-c-syntax-kw);
|
|
139
|
+
}
|
|
140
|
+
.cp-split__visual .tok-str {
|
|
141
|
+
color: var(--cp-c-syntax-str);
|
|
142
|
+
}
|
|
143
|
+
.cp-split__visual .tok-fn {
|
|
144
|
+
color: var(--cp-c-syntax-fn);
|
|
145
|
+
}
|
|
146
|
+
.cp-split__visual .tok-cmt {
|
|
147
|
+
color: var(--cp-c-text-3);
|
|
148
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { match } from 'massaman/match'
|
|
2
|
+
import type React from 'react'
|
|
3
|
+
|
|
4
|
+
import { RouteLink } from '../../lib/route-link.tsx'
|
|
5
|
+
import { safeUrl } from '../../lib/safe-url.ts'
|
|
6
|
+
|
|
7
|
+
import './split.css'
|
|
8
|
+
|
|
9
|
+
export interface SplitAction {
|
|
10
|
+
/**
|
|
11
|
+
* Visible label.
|
|
12
|
+
*/
|
|
13
|
+
readonly text: string
|
|
14
|
+
/**
|
|
15
|
+
* Destination URL.
|
|
16
|
+
*/
|
|
17
|
+
readonly link: string
|
|
18
|
+
/**
|
|
19
|
+
* Visual style — `brand` is the filled primary, `alt` is the outline.
|
|
20
|
+
*/
|
|
21
|
+
readonly theme?: 'brand' | 'alt'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SplitProps {
|
|
25
|
+
/**
|
|
26
|
+
* Eyebrow label rendered above the headline.
|
|
27
|
+
*/
|
|
28
|
+
readonly eyebrow?: string
|
|
29
|
+
/**
|
|
30
|
+
* Section headline.
|
|
31
|
+
*/
|
|
32
|
+
readonly title: React.ReactNode
|
|
33
|
+
/**
|
|
34
|
+
* Lead paragraph below the headline.
|
|
35
|
+
*/
|
|
36
|
+
readonly body?: React.ReactNode
|
|
37
|
+
/**
|
|
38
|
+
* Optional checkmark bullets rendered under the body.
|
|
39
|
+
*/
|
|
40
|
+
readonly bullets?: readonly string[]
|
|
41
|
+
/**
|
|
42
|
+
* Optional CTA action.
|
|
43
|
+
*/
|
|
44
|
+
readonly action?: SplitAction
|
|
45
|
+
/**
|
|
46
|
+
* Right-side content — typically a code preview or screenshot.
|
|
47
|
+
*/
|
|
48
|
+
readonly visual: React.ReactNode
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* HomeSplit — two-column "show and tell" section. Copy + checkmarks on the
|
|
53
|
+
* left, code/screenshot on the right. Mirrors the mockup landing.
|
|
54
|
+
*
|
|
55
|
+
* @param props - Split section configuration.
|
|
56
|
+
* @returns React element.
|
|
57
|
+
*/
|
|
58
|
+
export function HomeSplit(props: SplitProps): React.ReactElement {
|
|
59
|
+
const { eyebrow, title, body, bullets, action, visual } = props
|
|
60
|
+
const list = bullets ?? []
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<section className="cp-split">
|
|
64
|
+
<div className="cp-split__inner">
|
|
65
|
+
<div className="cp-split__copy">
|
|
66
|
+
{match(eyebrow)
|
|
67
|
+
.with(undefined, () => null)
|
|
68
|
+
.otherwise((e) => (
|
|
69
|
+
<div className="cp-split__eyebrow">{e}</div>
|
|
70
|
+
))}
|
|
71
|
+
<h2 className="cp-split__title">{title}</h2>
|
|
72
|
+
{match(body)
|
|
73
|
+
.with(undefined, () => null)
|
|
74
|
+
.otherwise((b) => (
|
|
75
|
+
<p className="cp-split__body">{b}</p>
|
|
76
|
+
))}
|
|
77
|
+
{match(list.length === 0)
|
|
78
|
+
.with(true, () => null)
|
|
79
|
+
.otherwise(() => (
|
|
80
|
+
<ul className="cp-split__bullets">
|
|
81
|
+
{list.map((bullet) => (
|
|
82
|
+
<li key={bullet}>
|
|
83
|
+
<span className="cp-split__check">✓</span>
|
|
84
|
+
<span>{bullet}</span>
|
|
85
|
+
</li>
|
|
86
|
+
))}
|
|
87
|
+
</ul>
|
|
88
|
+
))}
|
|
89
|
+
{match(action)
|
|
90
|
+
.with(undefined, () => null)
|
|
91
|
+
.otherwise((a) => {
|
|
92
|
+
const href = safeUrl(a.link)
|
|
93
|
+
if (href === null) {
|
|
94
|
+
return null
|
|
95
|
+
}
|
|
96
|
+
return (
|
|
97
|
+
<RouteLink className={btnClass(a.theme)} href={href}>
|
|
98
|
+
{a.text}
|
|
99
|
+
</RouteLink>
|
|
100
|
+
)
|
|
101
|
+
})}
|
|
102
|
+
</div>
|
|
103
|
+
<div className="cp-split__visual">{visual}</div>
|
|
104
|
+
</div>
|
|
105
|
+
</section>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Build the CSS class for a split action button.
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
* @param theme - Action theme.
|
|
114
|
+
* @returns CSS class name string.
|
|
115
|
+
*/
|
|
116
|
+
function btnClass(theme: 'brand' | 'alt' | undefined): string {
|
|
117
|
+
return match(theme ?? 'brand')
|
|
118
|
+
.with('brand', () => 'cp-split__btn cp-split__btn--primary')
|
|
119
|
+
.otherwise(() => 'cp-split__btn')
|
|
120
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
.cp-trust {
|
|
2
|
+
padding: 32px 0;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.cp-trust__row {
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
gap: 12px;
|
|
10
|
+
flex-wrap: wrap;
|
|
11
|
+
font-family: var(--cp-font-family-mono);
|
|
12
|
+
font-size: 12px;
|
|
13
|
+
color: var(--cp-c-text-3);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.cp-trust__lead {
|
|
17
|
+
margin-right: 4px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.cp-trust__item {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: 12px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.cp-trust__name {
|
|
27
|
+
color: var(--cp-c-text-1);
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.cp-trust__sep {
|
|
32
|
+
color: var(--cp-c-text-3);
|
|
33
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { match } from 'massaman/match'
|
|
2
|
+
import type React from 'react'
|
|
3
|
+
|
|
4
|
+
import './trust-strip.css'
|
|
5
|
+
|
|
6
|
+
export interface TrustStripProps {
|
|
7
|
+
/**
|
|
8
|
+
* Lead text shown before the names. Defaults to "used by".
|
|
9
|
+
*/
|
|
10
|
+
readonly lead?: string
|
|
11
|
+
/**
|
|
12
|
+
* Names to render, separated by mono dots.
|
|
13
|
+
*/
|
|
14
|
+
readonly names: readonly string[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* TrustStrip — a single-row "used by …" band with mono dots between names.
|
|
19
|
+
* Renders only when at least one name is supplied.
|
|
20
|
+
*
|
|
21
|
+
* @param props - Trust strip configuration.
|
|
22
|
+
* @returns React element, or null when no names are provided.
|
|
23
|
+
*/
|
|
24
|
+
export function TrustStrip(props: TrustStripProps): React.ReactElement | null {
|
|
25
|
+
const { lead = 'used by', names } = props
|
|
26
|
+
return match(names.length === 0)
|
|
27
|
+
.with(true, () => null)
|
|
28
|
+
.otherwise(() => (
|
|
29
|
+
<section className="cp-trust">
|
|
30
|
+
<div className="cp-trust__row">
|
|
31
|
+
<span className="cp-trust__lead">{lead}</span>
|
|
32
|
+
{names.map((name, i) => (
|
|
33
|
+
<span key={`${name}:${i}`} className="cp-trust__item">
|
|
34
|
+
<span className="cp-trust__name">{name}</span>
|
|
35
|
+
{match(i < names.length - 1)
|
|
36
|
+
.with(true, () => <span className="cp-trust__sep">·</span>)
|
|
37
|
+
.otherwise(() => null)}
|
|
38
|
+
</span>
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
42
|
+
))
|
|
43
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { HomeGridConfig } from '@ciderpress/config'
|
|
2
|
+
import { match, P } from 'massaman/match'
|
|
3
|
+
import type React from 'react'
|
|
4
|
+
|
|
5
|
+
import { useCiderpress } from '../../hooks/use-ciderpress'
|
|
6
|
+
import type { WorkspaceGroupData } from '../../hooks/use-ciderpress'
|
|
7
|
+
import { WorkspaceCard } from '../workspaces/card'
|
|
8
|
+
import { WorkspaceGrid } from '../workspaces/grid'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Smart orchestrator that reads workspace data from themeConfig
|
|
12
|
+
* and renders workspace groups with the correct card component per type.
|
|
13
|
+
*
|
|
14
|
+
* @returns React element with workspace groups or null
|
|
15
|
+
*/
|
|
16
|
+
export function HomeWorkspaces(): React.ReactElement | null {
|
|
17
|
+
const { workspaces, home } = useCiderpress()
|
|
18
|
+
const gridConfig = home && home.workspaces
|
|
19
|
+
|
|
20
|
+
return match(workspaces)
|
|
21
|
+
.with(
|
|
22
|
+
P.when((w): w is readonly WorkspaceGroupData[] => Array.isArray(w) && w.length > 0),
|
|
23
|
+
(groups) => (
|
|
24
|
+
<div className="cp-workspace-section">
|
|
25
|
+
<hr className="cp-divider" />
|
|
26
|
+
{groups.map((group) => renderGroup(group, gridConfig))}
|
|
27
|
+
</div>
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
.otherwise(() => null)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render a single workspace group with its cards.
|
|
35
|
+
*
|
|
36
|
+
* @private
|
|
37
|
+
* @param group - Workspace group data with heading, description, and cards
|
|
38
|
+
* @param gridConfig - Optional grid layout config for columns and truncation
|
|
39
|
+
* @returns Workspace grid element
|
|
40
|
+
*/
|
|
41
|
+
function renderGroup(
|
|
42
|
+
group: WorkspaceGroupData,
|
|
43
|
+
gridConfig: HomeGridConfig | undefined
|
|
44
|
+
): React.ReactElement {
|
|
45
|
+
const titleLines = gridConfig && gridConfig.truncate && gridConfig.truncate.title
|
|
46
|
+
const descLines = gridConfig && gridConfig.truncate && gridConfig.truncate.description
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<WorkspaceGrid
|
|
50
|
+
key={group.heading}
|
|
51
|
+
heading={group.heading}
|
|
52
|
+
description={group.description}
|
|
53
|
+
columns={gridConfig && gridConfig.columns}
|
|
54
|
+
>
|
|
55
|
+
{group.cards.map((card, i) => (
|
|
56
|
+
<WorkspaceCard
|
|
57
|
+
key={`${card.title}-${i}`}
|
|
58
|
+
title={card.title}
|
|
59
|
+
href={card.href}
|
|
60
|
+
icon={card.icon}
|
|
61
|
+
scope={card.scope}
|
|
62
|
+
description={card.description}
|
|
63
|
+
tags={card.tags}
|
|
64
|
+
badge={card.badge}
|
|
65
|
+
titleLines={titleLines}
|
|
66
|
+
descriptionLines={descLines}
|
|
67
|
+
/>
|
|
68
|
+
))}
|
|
69
|
+
</WorkspaceGrid>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branch tag pill — git branch badge positioned in the nav bar.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
.cp-branch-tag {
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: 5px;
|
|
9
|
+
margin-left: 8px;
|
|
10
|
+
padding: 3px 10px;
|
|
11
|
+
border-radius: 20px;
|
|
12
|
+
background: var(--cp-c-bg-soft);
|
|
13
|
+
border: 1px solid var(--cp-c-divider);
|
|
14
|
+
color: var(--cp-c-text-3);
|
|
15
|
+
font-family: var(--cp-font-family-mono);
|
|
16
|
+
font-size: 11px;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
line-height: 1;
|
|
19
|
+
white-space: nowrap;
|
|
20
|
+
max-width: 180px;
|
|
21
|
+
text-decoration: none !important;
|
|
22
|
+
transition:
|
|
23
|
+
border-color 0.2s,
|
|
24
|
+
color 0.2s;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.cp-branch-tag:hover {
|
|
28
|
+
border-color: var(--cp-c-brand-1);
|
|
29
|
+
color: var(--cp-c-brand-1);
|
|
30
|
+
text-decoration: none !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.cp-branch-tag:focus-visible {
|
|
34
|
+
outline: 2px solid var(--rp-c-brand);
|
|
35
|
+
outline-offset: 2px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.cp-branch-tag svg {
|
|
39
|
+
width: 14px;
|
|
40
|
+
height: 14px;
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.cp-branch-tag__text {
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
text-overflow: ellipsis;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ── Responsive ──────────────────────────────────────────── */
|
|
50
|
+
@media (max-width: 768px) {
|
|
51
|
+
.cp-branch-tag__text {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
}
|