@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
|
+
* Custom Sidebar component with multi-scope support.
|
|
3
|
+
*
|
|
4
|
+
* Rspress's `_meta.json` auto-discovery generates a single unified sidebar
|
|
5
|
+
* keyed by `"/"`. This component filters the unified sidebar at runtime to
|
|
6
|
+
* isolate standalone sections (e.g. Packages, Contributing) into their own
|
|
7
|
+
* scope while merging the remaining sections into a shared scope.
|
|
8
|
+
*
|
|
9
|
+
* HMR works because `_meta.json` changes trigger Rspress's auto-discovery
|
|
10
|
+
* re-run via `addDependency()` — the sidebar data updates reactively.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { SidebarData } from '@rspress/core'
|
|
14
|
+
import { useActiveMatcher, useLocation, useSidebar } from '@rspress/core/runtime'
|
|
15
|
+
import { SidebarList } from '@rspress/core/theme-original'
|
|
16
|
+
import type React from 'react'
|
|
17
|
+
import { useLayoutEffect, useMemo, useState } from 'react'
|
|
18
|
+
|
|
19
|
+
import { useCiderpress } from '../../hooks/use-ciderpress'
|
|
20
|
+
import { resolveScopedSidebar } from './sidebar-filter'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Union element of `SidebarData` — sidebar items may be groups, leaf items,
|
|
24
|
+
* dividers, or section headers.
|
|
25
|
+
*
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
type SidebarDataItem = SidebarData[number]
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Scoped Sidebar that supports standalone section isolation.
|
|
32
|
+
*
|
|
33
|
+
* When the current path matches a standalone scope (e.g. `/packages`),
|
|
34
|
+
* only that section's sidebar items are shown. For all other paths,
|
|
35
|
+
* standalone sections are hidden and the remaining sections form a
|
|
36
|
+
* unified sidebar.
|
|
37
|
+
*
|
|
38
|
+
* @returns React element rendering the filtered sidebar
|
|
39
|
+
*/
|
|
40
|
+
export function Sidebar(): React.ReactElement {
|
|
41
|
+
const rawSidebarData = useSidebar()
|
|
42
|
+
const activeMatcher = useActiveMatcher()
|
|
43
|
+
const { pathname: rawPathname } = useLocation()
|
|
44
|
+
const { standaloneScopePaths } = useCiderpress()
|
|
45
|
+
|
|
46
|
+
const pathname = decodeURIComponent(rawPathname)
|
|
47
|
+
const scopes = standaloneScopePaths ?? []
|
|
48
|
+
|
|
49
|
+
const filteredData = useMemo(
|
|
50
|
+
() => resolveScopedSidebar(rawSidebarData, pathname, scopes),
|
|
51
|
+
[rawSidebarData, pathname, scopes]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const [sidebarData, setSidebarData] = useState<SidebarData>(() =>
|
|
55
|
+
initializeCollapsed(structuredClone(filteredData), activeMatcher)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
useLayoutEffect(() => {
|
|
59
|
+
setSidebarData(initializeCollapsed(filteredData, activeMatcher))
|
|
60
|
+
}, [activeMatcher, filteredData])
|
|
61
|
+
|
|
62
|
+
return <SidebarList sidebarData={sidebarData} setSidebarData={setSidebarData} />
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Walk the sidebar tree and uncollapse groups that contain the active path.
|
|
67
|
+
*
|
|
68
|
+
* Mirrors Rspress's `createInitialSidebar` logic: groups whose descendants
|
|
69
|
+
* match the active route get `collapsed = false` so the active page is
|
|
70
|
+
* visible on initial render.
|
|
71
|
+
*
|
|
72
|
+
* @private
|
|
73
|
+
* @param items - Sidebar items (will be mutated for collapsed state)
|
|
74
|
+
* @param activeMatcher - Function that checks if a link matches the current route
|
|
75
|
+
* @returns The same items array with collapsed state applied
|
|
76
|
+
*/
|
|
77
|
+
function initializeCollapsed(
|
|
78
|
+
items: SidebarData,
|
|
79
|
+
activeMatcher: (link: string) => boolean
|
|
80
|
+
): SidebarData {
|
|
81
|
+
const cache = new WeakMap<SidebarDataItem, boolean>()
|
|
82
|
+
const flat = items.filter(Boolean).flat()
|
|
83
|
+
flat.reduce<null>((_, item) => {
|
|
84
|
+
expandItem(item, activeMatcher, cache)
|
|
85
|
+
return null
|
|
86
|
+
}, null)
|
|
87
|
+
return flat
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Check whether a sidebar item or any of its descendants match the active route.
|
|
92
|
+
*
|
|
93
|
+
* @private
|
|
94
|
+
* @param item - Sidebar item to check
|
|
95
|
+
* @param activeMatcher - Route matcher function
|
|
96
|
+
* @param cache - Memoization cache for match results
|
|
97
|
+
* @returns True when the item or a descendant matches
|
|
98
|
+
*/
|
|
99
|
+
function isItemActive(
|
|
100
|
+
item: SidebarDataItem,
|
|
101
|
+
activeMatcher: (link: string) => boolean,
|
|
102
|
+
cache: WeakMap<SidebarDataItem, boolean>
|
|
103
|
+
): boolean {
|
|
104
|
+
const cached = cache.get(item)
|
|
105
|
+
if (cached !== undefined) {
|
|
106
|
+
return cached
|
|
107
|
+
}
|
|
108
|
+
if (Object.hasOwn(item, 'link')) {
|
|
109
|
+
const { link } = item as { readonly link?: string }
|
|
110
|
+
if (link && activeMatcher(link)) {
|
|
111
|
+
cache.set(item, true)
|
|
112
|
+
return true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (Object.hasOwn(item, 'items')) {
|
|
116
|
+
const { items } = item as { readonly items: readonly SidebarDataItem[] }
|
|
117
|
+
const childMatch = items.some((child) => isItemActive(child, activeMatcher, cache))
|
|
118
|
+
if (childMatch) {
|
|
119
|
+
cache.set(item, true)
|
|
120
|
+
return true
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
cache.set(item, false)
|
|
124
|
+
return false
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Recursively expand a sidebar item if it contains the active route.
|
|
129
|
+
*
|
|
130
|
+
* @private
|
|
131
|
+
* @param item - Sidebar item to process
|
|
132
|
+
* @param activeMatcher - Route matcher function
|
|
133
|
+
* @param cache - Memoization cache for match results
|
|
134
|
+
*/
|
|
135
|
+
function expandItem(
|
|
136
|
+
item: SidebarDataItem,
|
|
137
|
+
activeMatcher: (link: string) => boolean,
|
|
138
|
+
cache: WeakMap<SidebarDataItem, boolean>
|
|
139
|
+
): void {
|
|
140
|
+
if (Object.hasOwn(item, 'items')) {
|
|
141
|
+
const group = item as { readonly items: readonly SidebarDataItem[]; collapsed?: boolean }
|
|
142
|
+
group.items.reduce<null>((_, child) => {
|
|
143
|
+
expandItem(child, activeMatcher, cache)
|
|
144
|
+
return null
|
|
145
|
+
}, null)
|
|
146
|
+
if (isItemActive(item, activeMatcher, cache)) {
|
|
147
|
+
// oxlint-disable-next-line eslint/no-param-reassign -- intentional mutation matching Rspress's createInitialSidebar
|
|
148
|
+
group.collapsed = false
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
.cp-sidebar-toggle {
|
|
2
|
+
/* Pinned to the far-left of the nav, matching the mockup hamburger
|
|
3
|
+
position. The nav itself is set to position: relative below. */
|
|
4
|
+
position: absolute;
|
|
5
|
+
left: 16px;
|
|
6
|
+
top: 50%;
|
|
7
|
+
transform: translateY(-50%);
|
|
8
|
+
z-index: 5;
|
|
9
|
+
width: 28px;
|
|
10
|
+
height: 28px;
|
|
11
|
+
display: grid;
|
|
12
|
+
place-items: center;
|
|
13
|
+
border: 0;
|
|
14
|
+
background: transparent;
|
|
15
|
+
border-radius: var(--cp-radius-card);
|
|
16
|
+
color: var(--cp-c-text-2);
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
transition: all 0.15s ease;
|
|
19
|
+
padding: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Hide Rspress's mobile hamburger always — our `.cp-sidebar-toggle`
|
|
23
|
+
owns the role of "menu trigger" across all widths. On mobile our
|
|
24
|
+
toggle programmatically forwards the click to Rspress's hamburger
|
|
25
|
+
(its handler is preserved, only the visual is hidden) so the
|
|
26
|
+
slide-over mobile menu still works. */
|
|
27
|
+
html .rp-nav-hamburger {
|
|
28
|
+
display: none !important;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Replace the hamburger icon inside Rspress's mobile sub-bar
|
|
32
|
+
(`.rp-sidebar-menu__left`) with a "panel-left" affordance so it
|
|
33
|
+
doesn't visually echo the navbar's hamburger. The bar itself stays
|
|
34
|
+
visible because it serves a distinct role (show sidebar / outline
|
|
35
|
+
on mobile). */
|
|
36
|
+
html .rp-sidebar-menu__left > svg {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
html .rp-sidebar-menu__left::before {
|
|
40
|
+
content: '';
|
|
41
|
+
display: inline-block;
|
|
42
|
+
width: 14px;
|
|
43
|
+
height: 14px;
|
|
44
|
+
background: currentColor;
|
|
45
|
+
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><line x1='9' y1='3' x2='9' y2='21'/></svg>")
|
|
46
|
+
no-repeat center / contain;
|
|
47
|
+
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><line x1='9' y1='3' x2='9' y2='21'/></svg>")
|
|
48
|
+
no-repeat center / contain;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.cp-sidebar-toggle:hover {
|
|
52
|
+
background: var(--cp-c-bg-soft);
|
|
53
|
+
color: var(--cp-c-text-1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Pin the nav to the top of the viewport AND make it the positioning
|
|
57
|
+
context for the absolutely-positioned toggle. `sticky` covers both:
|
|
58
|
+
it pins on scroll while still acting as the offset parent for
|
|
59
|
+
`position: absolute` children. */
|
|
60
|
+
html .rp-nav,
|
|
61
|
+
html .rspress-nav {
|
|
62
|
+
position: sticky;
|
|
63
|
+
top: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
html .rp-nav__left,
|
|
67
|
+
html .rspress-nav__left {
|
|
68
|
+
padding-left: 36px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* When collapsed, hide the sidebar + placeholder. Scoped to >=1280px
|
|
72
|
+
where the sidebar is a sticky desktop rail; at ≤1279px the sidebar
|
|
73
|
+
is a fixed overlay drawer (rules below), where the same
|
|
74
|
+
`display: none` would also hide the drawer state and
|
|
75
|
+
`<CiderpressDocsBar />`'s "Menu" button would have nothing to open.
|
|
76
|
+
Threshold mirrors the Outline rail's collapse-vs-drawer cutoff so
|
|
77
|
+
sidebar and outline switch modes in lockstep. */
|
|
78
|
+
@media (min-width: 1280px) {
|
|
79
|
+
html[data-cp-sidebar-collapsed='true'] .rp-doc-layout__sidebar,
|
|
80
|
+
html[data-cp-sidebar-collapsed='true'] .rp-doc-layout__sidebar-placeholder {
|
|
81
|
+
display: none !important;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Mirror collapse behaviour for the outline rail. Rspress turns the
|
|
86
|
+
outline into a fixed overlay drawer at ≤1279px (see
|
|
87
|
+
`DocLayout/index.css` `@media (width <= 1279px)`), so the
|
|
88
|
+
collapse-via-display-none only applies above that breakpoint —
|
|
89
|
+
otherwise opening the drawer via `<CiderpressDocsBar />` would
|
|
90
|
+
silently no-op. */
|
|
91
|
+
@media (min-width: 1280px) {
|
|
92
|
+
html[data-cp-outline-collapsed='true'] .rp-doc-layout__outline,
|
|
93
|
+
html[data-cp-outline-collapsed='true'] .rp-doc-layout__outline-placeholder {
|
|
94
|
+
display: none !important;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Rspress's mobile nav-screen renders dividers around sections like
|
|
99
|
+
translations / appearance-toggle / socials. When some of those
|
|
100
|
+
sections are absent or hidden, two dividers end up adjacent — a
|
|
101
|
+
pair of stacked empty hairlines. Collapse consecutive dividers and
|
|
102
|
+
hide a trailing one with no following content. */
|
|
103
|
+
html .rp-nav-screen-divider + .rp-nav-screen-divider,
|
|
104
|
+
html .rp-nav-screen-divider:last-child {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ── Sidebar drawer mode (<=1279px) ─────────────────────────────
|
|
109
|
+
Rspress ships drawer-base rules natively only at <=768px (its
|
|
110
|
+
`DocLayout/index.css` `@media (width <= 768px)` sets `position:
|
|
111
|
+
fixed`, `transform: translate3d(-100%, 0, 0)`, opacity transitions,
|
|
112
|
+
etc). This block extends that drawer behaviour up to 1279px so the
|
|
113
|
+
sidebar flips to mobile in lockstep with the Outline rail (which
|
|
114
|
+
already drawers at <=1279px). Selector chains `html` for higher
|
|
115
|
+
specificity than Rspress's single-class rules.
|
|
116
|
+
|
|
117
|
+
The slide-over overlays the entire viewport (top: 0, full height)
|
|
118
|
+
so the drawer covers the navbar AND announcement bar — without
|
|
119
|
+
this they'd stay tappable above an open drawer. Applies to both
|
|
120
|
+
the doc sidebar and Rspress's nav screen (top-nav slide-over). */
|
|
121
|
+
@media (max-width: 1279px) {
|
|
122
|
+
html .rp-doc-layout__sidebar {
|
|
123
|
+
position: fixed;
|
|
124
|
+
top: 0 !important;
|
|
125
|
+
left: 0;
|
|
126
|
+
bottom: 0;
|
|
127
|
+
width: var(--rp-sidebar-width, 260px);
|
|
128
|
+
/* Override Rspress's base `height + max-height: calc(100vh -
|
|
129
|
+
var(--rp-nav-height))` rule (NOT media-scoped, so it caps us
|
|
130
|
+
even at this breakpoint). Both height and max-height pinned to
|
|
131
|
+
the full dynamic viewport so the drawer covers navbar +
|
|
132
|
+
announcement + docs bar. */
|
|
133
|
+
height: 100dvh !important;
|
|
134
|
+
max-height: 100dvh !important;
|
|
135
|
+
margin-top: 0;
|
|
136
|
+
/* No `padding-bottom` — the sticky `.cp-sidebar-bottom` band pins
|
|
137
|
+
to the bottom of the content box (padding excluded). Any padding
|
|
138
|
+
here would shift the band up by the same amount, leaving the
|
|
139
|
+
promo floating mid-drawer with empty space below it. */
|
|
140
|
+
background: var(--cp-c-bg-elv);
|
|
141
|
+
opacity: 0;
|
|
142
|
+
visibility: hidden;
|
|
143
|
+
transform: translate3d(-100%, 0, 0);
|
|
144
|
+
transition:
|
|
145
|
+
opacity 0.25s,
|
|
146
|
+
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1),
|
|
147
|
+
visibility 0s linear 0.5s;
|
|
148
|
+
z-index: 100 !important;
|
|
149
|
+
overflow: auto scroll;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
html .rp-doc-layout__sidebar--open {
|
|
153
|
+
opacity: 1;
|
|
154
|
+
visibility: visible;
|
|
155
|
+
transform: translate3d(0, 0, 0);
|
|
156
|
+
transition:
|
|
157
|
+
opacity 0.25s,
|
|
158
|
+
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
html .rp-nav-screen {
|
|
162
|
+
top: 0 !important;
|
|
163
|
+
height: 100vh !important;
|
|
164
|
+
height: 100dvh !important;
|
|
165
|
+
z-index: 100 !important;
|
|
166
|
+
background: var(--cp-c-bg-elv);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* When collapsed: cap the doc reading width and center it within the
|
|
171
|
+
available space (rail width minus outline). Prevents the prose from
|
|
172
|
+
stretching edge-to-edge and makes the layout feel intentional. */
|
|
173
|
+
html[data-cp-sidebar-collapsed='true'] .rp-doc-layout__doc {
|
|
174
|
+
max-width: var(--cp-content-collapsed-max, 1000px) !important;
|
|
175
|
+
margin: 0 auto !important;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
html[data-cp-sidebar-collapsed='true'] .rp-doc-layout__doc-container {
|
|
179
|
+
max-width: var(--cp-content-collapsed-max, 1000px);
|
|
180
|
+
margin: 0 auto;
|
|
181
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { match } from 'massaman/match'
|
|
2
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
3
|
+
|
|
4
|
+
import './sidebar-toggle.css'
|
|
5
|
+
|
|
6
|
+
const STORAGE_KEY = 'ciderpress-sidebar-collapsed'
|
|
7
|
+
const HTML_ATTR = 'cpSidebarCollapsed'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* SidebarToggle — small icon button in the topbar to collapse/expand the
|
|
11
|
+
* docs sidebar on desktop. State persists in localStorage and is applied
|
|
12
|
+
* via `html[data-cp-sidebar-collapsed='true']` for CSS targeting.
|
|
13
|
+
*
|
|
14
|
+
* @returns React element.
|
|
15
|
+
*/
|
|
16
|
+
export function SidebarToggle(): React.ReactElement {
|
|
17
|
+
const [collapsed, setCollapsed] = useState(() => readCollapsed())
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
applyState(collapsed)
|
|
21
|
+
}, [collapsed])
|
|
22
|
+
|
|
23
|
+
const handleClick = useCallback(() => {
|
|
24
|
+
// Below the mobile breakpoint, defer to Rspress's slide-over mobile
|
|
25
|
+
// menu (its hamburger handler is preserved — we just hide its visual).
|
|
26
|
+
const isMobile = globalThis.window !== undefined && globalThis.innerWidth < 960
|
|
27
|
+
if (isMobile) {
|
|
28
|
+
const rspressBurger = globalThis.document.querySelector(
|
|
29
|
+
'.rp-nav-hamburger'
|
|
30
|
+
) as HTMLButtonElement | null
|
|
31
|
+
if (rspressBurger !== null) {
|
|
32
|
+
rspressBurger.click()
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
setCollapsed((prev) => {
|
|
37
|
+
const next = !prev
|
|
38
|
+
writeCollapsed(next)
|
|
39
|
+
return next
|
|
40
|
+
})
|
|
41
|
+
}, [])
|
|
42
|
+
|
|
43
|
+
const label = match(collapsed)
|
|
44
|
+
.with(true, () => 'Show sidebar')
|
|
45
|
+
.otherwise(() => 'Hide sidebar')
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<button
|
|
49
|
+
className="cp-sidebar-toggle"
|
|
50
|
+
type="button"
|
|
51
|
+
onClick={handleClick}
|
|
52
|
+
aria-label={label}
|
|
53
|
+
title={label}
|
|
54
|
+
>
|
|
55
|
+
<svg
|
|
56
|
+
width="14"
|
|
57
|
+
height="14"
|
|
58
|
+
viewBox="0 0 24 24"
|
|
59
|
+
fill="none"
|
|
60
|
+
stroke="currentColor"
|
|
61
|
+
strokeWidth="2"
|
|
62
|
+
>
|
|
63
|
+
<line x1="3" y1="6" x2="21" y2="6" />
|
|
64
|
+
<line x1="3" y1="12" x2="21" y2="12" />
|
|
65
|
+
<line x1="3" y1="18" x2="21" y2="18" />
|
|
66
|
+
</svg>
|
|
67
|
+
</button>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Read the persisted collapsed state from localStorage.
|
|
73
|
+
*
|
|
74
|
+
* @private
|
|
75
|
+
* @returns true when the sidebar is collapsed.
|
|
76
|
+
*/
|
|
77
|
+
function readCollapsed(): boolean {
|
|
78
|
+
if (globalThis.window === undefined) {
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return globalThis.localStorage.getItem(STORAGE_KEY) === '1'
|
|
83
|
+
} catch {
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Persist the collapsed state to localStorage.
|
|
90
|
+
*
|
|
91
|
+
* @private
|
|
92
|
+
* @param collapsed - true when the sidebar is collapsed.
|
|
93
|
+
*/
|
|
94
|
+
function writeCollapsed(collapsed: boolean): void {
|
|
95
|
+
if (globalThis.window === undefined) {
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
if (collapsed) {
|
|
100
|
+
globalThis.localStorage.setItem(STORAGE_KEY, '1')
|
|
101
|
+
} else {
|
|
102
|
+
globalThis.localStorage.removeItem(STORAGE_KEY)
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
// ignore — storage may be unavailable
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Apply the collapsed state to the html dataset for CSS targeting.
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
* @param collapsed - true when the sidebar is collapsed.
|
|
114
|
+
*/
|
|
115
|
+
function applyState(collapsed: boolean): void {
|
|
116
|
+
if (globalThis.document === undefined) {
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
const html = globalThis.document.documentElement
|
|
120
|
+
match(collapsed)
|
|
121
|
+
.with(true, () => {
|
|
122
|
+
html.dataset[HTML_ATTR] = 'true'
|
|
123
|
+
})
|
|
124
|
+
.otherwise(() => {
|
|
125
|
+
delete html.dataset[HTML_ATTR]
|
|
126
|
+
})
|
|
127
|
+
}
|