// js/docs/DocsSidebar.jsx // IA mirrors scripts/render-docs-config.json — keep both in sync. // Top groups (Getting started, Concepts) start expanded. // Reference / Architecture / Vision / Community & RFCs start collapsed // but auto-expand if the active page lives inside. const Chev = () => ( ); // IA: at most 3 entries per section. Sub-pages are kept on disk + indexed // for search; just removed from sidebar nav. Re-surface by adding back here. // // Hidden-but-on-disk: // Getting started — /docs/install/, /docs/get-started/query-features/ // Concepts — /docs/concepts/get-and-mget/, /docs/concepts/windows/, // /docs/concepts/freshness/, /docs/concepts/embed-mode/, // /docs/concepts/global-aggregation/ // Vision — /docs/vision/open-source/, /docs/vision/benchmarks/ // Reference — /docs/operators/cost-class/ + 7 operator family pages, // /docs/pipeline-dsl/* (3), /docs/sdk-api/{typescript,go,shared}/, // /docs/wire-spec/, /docs/schema-evolution/, /docs/error-codes/ // Architecture — entire section (6 pages) // Community — /docs/community/dev-calls/, // /docs/community/rfcs/rfc-00{1..7}-* const SECTIONS = [ { title: 'Getting started', open: true, items: [ { label: 'Introduction', href: '/docs/' }, { label: 'Quickstart', href: '/docs/get-started/quickstart/' }, { label: 'Build a pipeline', href: '/docs/get-started/define-a-pipeline/' }, ]}, { title: 'Vision', open: true, items: [ { label: 'Why beava', href: '/docs/vision/why-beava/' }, { label: 'Non-goals and tradeoffs', href: '/docs/vision/non-goals/' }, ]}, { title: 'Concepts', open: true, items: [ { label: 'Events', href: '/docs/concepts/streams/' }, { label: 'Tables', href: '/docs/concepts/tables/' }, { label: 'Push and fetch features', href: '/docs/get-started/push-events/' }, ]}, { title: 'Reference', open: false, items: [ { label: 'Operator catalog', href: '/docs/operators/' }, { label: 'Python SDK', href: '/docs/sdk-api/python/' }, { label: 'HTTP API', href: '/docs/http-api/' }, ]}, { title: 'Community', open: false, items: [ { label: 'About RFCs', href: '/docs/community/rfcs/' }, { label: 'Contributing', href: '/docs/community/contributing/' }, { label: 'Discussions', href: 'https://github.com/beava-dev/beava/discussions', external: true }, ]}, ]; const DocsSidebar = ({ active = '' }) => { // Initial open state: per-section default; auto-expand a section if the // active page label matches one of its items. const initialOpen = {}; SECTIONS.forEach(sec => { const containsActive = active && sec.items.some(it => it.label === active); initialOpen[sec.title] = containsActive || sec.open === true; }); const [open, setOpen] = React.useState(initialOpen); const [drawerOpen, setDrawerOpen] = React.useState(false); const toggle = (title) => setOpen(prev => ({ ...prev, [title]: !prev[title] })); React.useEffect(() => { const onResize = () => { if (window.innerWidth >= 1000) setDrawerOpen(false); }; window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, []); React.useEffect(() => { if (drawerOpen) { const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { document.body.style.overflow = prev; }; } }, [drawerOpen]); const sidebarBody = ( <> {SECTIONS.map(sec => { const isOpen = open[sec.title]; const isEmpty = sec.items.length === 0; return (