From c272995f62083dcc420a5589c424c22b25eb5698 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 12 Aug 2026 16:12:01 +0200 Subject: [PATCH 1/6] Add community page and redesign the navigation to support the addition of more context --- .claude/launch.json | 14 +++ astro.config.mjs | 41 +++++-- src/components/Header.astro | 166 ++++++++++++++++++++++++++ src/components/Sidebar.astro | 35 ++++++ src/components/SiteTitle.astro | 5 +- src/content/docs/CommunityMeeting.mdx | 53 ++++++++ src/content/docs/support.md | 1 + src/data/nav.ts | 34 ++++++ src/pages/[distro].astro | 1 + src/pages/index.astro | 4 +- src/styles/custom.css | 33 +++++ 11 files changed, 372 insertions(+), 15 deletions(-) create mode 100644 .claude/launch.json create mode 100644 src/components/Header.astro create mode 100644 src/components/Sidebar.astro create mode 100644 src/content/docs/CommunityMeeting.mdx create mode 100644 src/data/nav.ts diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 00000000..c3703481 --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,14 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "dev", + "runtimeExecutable": "pnpm", + "runtimeArgs": [ + "run", + "dev" + ], + "port": 4321 + } + ] +} diff --git a/astro.config.mjs b/astro.config.mjs index c5b956ee..b4018733 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,7 +2,6 @@ import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; import svelte from "@astrojs/svelte"; -import { newestRelease } from "./src/data/distros.ts"; export default defineConfig({ site: "https://robostack.github.io", @@ -33,25 +32,43 @@ export default defineConfig({ customCss: ["./src/styles/custom.css"], routeMiddleware: "./src/routeData.ts", components: { + Header: "./src/components/Header.astro", + Sidebar: "./src/components/Sidebar.astro", SiteTitle: "./src/components/SiteTitle.astro", PageTitle: "./src/components/PageTitle.astro", }, sidebar: [ - // Slugs are set explicitly in each page's frontmatter to keep the - // published mixed-case URLs (`GettingStarted.html`, `FAQ.html`, ...). - { label: "Getting Started", slug: "GettingStarted" }, + // One top-level group per header tab (src/components/Header.astro); + // the Sidebar override shows only the current page's group, so these + // group labels never render. Slugs are set explicitly in each page's + // frontmatter to keep the published mixed-case URLs + // (`GettingStarted.html`, `FAQ.html`, ...). { - label: "Alternative to Pixi", + label: "Docs", items: [ - { label: "Micromamba", slug: "micromamba" }, - { label: "Conda", slug: "conda" }, + { label: "Getting Started", slug: "GettingStarted" }, + { + label: "Alternative to Pixi", + items: [ + { label: "Micromamba", slug: "micromamba" }, + { label: "Conda", slug: "conda" }, + ], + }, + { label: "JupyterRos", slug: "JupyterRos" }, + { label: "FAQ", slug: "FAQ" }, + // Cross-listed; its primary section is Community (the last + // group containing a page wins in the Sidebar override). + { label: "Contributing", slug: "Contributing" }, + ], + }, + { + label: "Community", + items: [ + { label: "Community Meeting", slug: "CommunityMeeting" }, + { label: "Support", slug: "support" }, + { label: "Contributing", slug: "Contributing" }, ], }, - { label: "Packages", link: `/${newestRelease().name}.html` }, - { label: "JupyterRos", slug: "JupyterRos" }, - { label: "Support", slug: "support" }, - { label: "Contributing", slug: "Contributing" }, - { label: "FAQ", slug: "FAQ" }, ], }), svelte(), diff --git a/src/components/Header.astro b/src/components/Header.astro new file mode 100644 index 00000000..4855ed70 --- /dev/null +++ b/src/components/Header.astro @@ -0,0 +1,166 @@ +--- +import config from "virtual:starlight/user-config"; + +import LanguageSelect from "virtual:starlight/components/LanguageSelect"; +import Search from "virtual:starlight/components/Search"; +import SiteTitle from "virtual:starlight/components/SiteTitle"; +import SocialIcons from "virtual:starlight/components/SocialIcons"; +import ThemeSelect from "virtual:starlight/components/ThemeSelect"; + +import { NAV_TABS as tabs } from "../data/nav"; + +/** + * Override of Starlight's Header: the original row plus a tab row underneath + * (the zensical.org pattern), so the main sections stay reachable from every + * page - the splash homepage has no sidebar. The row's extra height comes + * from `--sl-nav-height`, raised in custom.css; the first row keeps the + * original height via `--rs-nav-row`. The tabs live in src/data/nav.ts, + * shared with the Sidebar override. + */ + +const shouldRenderSearch = + config.pagefind || + config.components.Search !== "@astrojs/starlight/components/Search.astro"; + +const pathname = Astro.url.pathname; +--- + +
+
+
+ +
+
+ {shouldRenderSearch && } +
+
+ + + +
+
+ +
+ + + +{ + /* The first-row styles are copied from Starlight's Header.astro so the + original layout survives the override; only `.stacked` and `.top-nav` + are new. */ +} + diff --git a/src/components/Sidebar.astro b/src/components/Sidebar.astro new file mode 100644 index 00000000..cceaeb0f --- /dev/null +++ b/src/components/Sidebar.astro @@ -0,0 +1,35 @@ +--- +import MobileMenuFooter from "virtual:starlight/components/MobileMenuFooter"; +import SidebarPersister from "@astrojs/starlight/components/SidebarPersister.astro"; +import SidebarSublist from "@astrojs/starlight/components/SidebarSublist.astro"; + +import { NAV_TABS } from "../data/nav"; + +/** + * Override of Starlight's Sidebar: the header tabs are the top level of the + * navigation, so the sidebar only shows the pages of the current section. + * The section comes from the shared nav.ts patterns - the same ones that + * pick the active header tab - and names the matching top-level group in + * `astro.config.mjs`. Pages outside any section fall back to the full + * sidebar. The distro table pages opt out of the sidebar entirely; their + * in-page distro tabs are the sub-navigation. + */ + +const { sidebar } = Astro.locals.starlightRoute; +const pathname = Astro.url.pathname; + +const tab = NAV_TABS.find((t) => t.match.test(pathname)); +const section = sidebar.find( + (entry) => entry.type === "group" && entry.label === tab?.label, +); + +const entries = section && section.type === "group" ? section.entries : sidebar; +--- + + + + + +
+ +
diff --git a/src/components/SiteTitle.astro b/src/components/SiteTitle.astro index ec716170..64e3a811 100644 --- a/src/components/SiteTitle.astro +++ b/src/components/SiteTitle.astro @@ -24,7 +24,10 @@ const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute; min-width: 0; } .site-title :global(svg) { - height: calc(var(--sl-nav-height) - 2.4 * var(--sl-nav-pad-y)); + /* Sized against the header's first row, not the full two-row header. */ + height: calc( + var(--rs-nav-row, var(--sl-nav-height)) - 2.4 * var(--sl-nav-pad-y) + ); width: auto; } diff --git a/src/content/docs/CommunityMeeting.mdx b/src/content/docs/CommunityMeeting.mdx new file mode 100644 index 00000000..8931e166 --- /dev/null +++ b/src/content/docs/CommunityMeeting.mdx @@ -0,0 +1,53 @@ +--- +title: Community Meeting +slug: CommunityMeeting +--- + +import { LinkButton } from "@astrojs/starlight/components"; + +RoboStack is a multi-owner project, so once a month we host an online meeting to discuss changes and potential user questions. +Join in to understand or influence the project. + +:::note[Everyone is welcome] +You don't have to be a maintainer or contributor. +Using RoboStack, or just curious about it, is reason enough to join. +No sign-up needed. +::: + +## When + +- **Every third Thursday of the month, 16:00 Amsterdam time (CET/CEST)** +- That is 14:00 UTC, 10:00 in New York and 7:00 in San Francisco during summer time. + +## How to join + +Add the recurring event to your calendar, the Google Meet link is attached to it: + + + Add the meeting to your calendar + + +## Agenda and notes + +The agenda and notes live in [one shared document](https://docs.google.com/document/d/11zfgoNtyu1I55EHNk42vEWgFMPT_QGaI5XehcdU_ttc/edit), one running doc with the newest meeting on top. + +Want something discussed? +Add a comment to the doc with your topic, or bring it up at the start of the call. +Notes from past meetings stay in the same doc, so that is also the place to catch up on what you missed. + +## What we talk about + +- The state of the distros we package and the potential coming packages. +- New features in [Pixi](https://pixi.sh) and [Vinca](https://github.com/RoboStack/vinca) that make using RoboStack easier or more feature-full. +- Ongoing work, like migrations, CI and new platforms. +- Your questions, issues and use cases. +- Anything you bring to the agenda. + +## Between meetings + +For quicker async feedback or support, contact the team in the [robotics channel on the prefix.dev Discord](https://discord.gg/kKV8ZxyzY4). + +See you there! diff --git a/src/content/docs/support.md b/src/content/docs/support.md index ccf0dc76..a8e56bc8 100644 --- a/src/content/docs/support.md +++ b/src/content/docs/support.md @@ -9,6 +9,7 @@ How to help improve our documentation: - For typos, grammar, or other errors, we'd appreciate your support! Simply [fork](https://github.com/RoboStack/robostack.github.io/fork) our repo, make the necessary changes, and submit a pull request. - If you have questions or need help, feel free to create an [issue](https://github.com/RoboStack/robostack.github.io/issues) or join the community in the [robotics channel on the prefix.dev Discord](https://discord.gg/kKV8ZxyzY4). +- Prefer talking to us live? Join the monthly [community meeting](/CommunityMeeting.html). We're always eager to improve, and your input is valuable to us. Thank you for being part of the RoboStack community! diff --git a/src/data/nav.ts b/src/data/nav.ts new file mode 100644 index 00000000..ca38d256 --- /dev/null +++ b/src/data/nav.ts @@ -0,0 +1,34 @@ +import { DISTROS, newestRelease } from "./distros"; + +/** + * The site's top-level sections: one header tab each (Header.astro), and - + * for tabs whose label matches a top-level sidebar group in astro.config.mjs + * - the sidebar shows that group's pages (Sidebar.astro). `match` decides + * both the active tab and which section a page belongs to, so cross-listed + * pages (Contributing sits in Docs and Community) resolve consistently. + */ +export interface NavTab { + label: string; + href: string; + match: RegExp; +} + +export const NAV_TABS: NavTab[] = [ + { label: "Home", href: "/index.html", match: /^\/(index(\.html)?)?$/ }, + { + label: "Docs", + href: "/GettingStarted.html", + match: /^\/(GettingStarted|micromamba|conda|JupyterRos|FAQ)/, + }, + { + label: "Packages", + href: `/${newestRelease().name}.html`, + // Active on every distro table page (/noetic.html, /lyrical.html, ...). + match: new RegExp(`^/(${DISTROS.map((d) => d.name).join("|")})(\\.html)?$`), + }, + { + label: "Community", + href: "/CommunityMeeting.html", + match: /^\/(CommunityMeeting|support|Contributing)/, + }, +]; diff --git a/src/pages/[distro].astro b/src/pages/[distro].astro index 1267e9bb..af8e7e53 100644 --- a/src/pages/[distro].astro +++ b/src/pages/[distro].astro @@ -29,6 +29,7 @@ const install = [ title: `ROS ${distro.ros} ${title(distro)}`, tableOfContents: false, }} + hasSidebar={false} > { /* Phrased about upstream, not about our rebuilds. Noetic is end of life diff --git a/src/pages/index.astro b/src/pages/index.astro index bdd7380e..cc46fd31 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -149,10 +149,10 @@ const packagesHref = `/${newestRelease().name}.html`; {/* Page backdrop and measure: the cream paper tone, wider than the docs. */} diff --git a/src/styles/custom.css b/src/styles/custom.css index 2f0f9693..397daece 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -53,16 +53,6 @@ samp { font-family: var(--font-display); } -/* Starlight hides the header's social links and theme switcher below 50rem - and offers them in the sidebar drawer instead. Pages without a sidebar - (the splash landing page) have no drawer, so keep the controls in the - header there; they fit because those pages have no menu button either. */ -@media (max-width: 49.999rem) { - :root:not([data-has-sidebar]) .header .right-group { - display: flex; - } -} - :root { --sl-color-accent-low: #dee5ff; --sl-color-accent: #2e46d8; From 3e59fd4f2dd5520126f1c2fba8723f809ae83fed Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 12 Aug 2026 16:45:09 +0200 Subject: [PATCH 3/6] improve spacing on navigation in topbar --- src/components/Header.astro | 4 ++++ src/styles/custom.css | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Header.astro b/src/components/Header.astro index 7632c013..98b15a15 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -109,6 +109,10 @@ const pathname = Astro.url.pathname; overflow-x: auto; scrollbar-width: none; font-size: var(--sl-text-sm); + /* Sit on the header's bottom border, zensical-style: the active tab's + underline touches the border, and the space freed up moves between + the logo row and the tabs. */ + margin-block-end: calc(-1 * var(--sl-nav-pad-y)); } .top-nav a { color: var(--sl-color-gray-2); diff --git a/src/styles/custom.css b/src/styles/custom.css index 397daece..70f66a8f 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -31,7 +31,7 @@ because Starlight positions it all with --sl-nav-height. */ :root { --rs-nav-row: 3.5rem; - --sl-nav-height: calc(var(--rs-nav-row) + 2.25rem); + --sl-nav-height: calc(var(--rs-nav-row) + 2.75rem); } @media (min-width: 50em) { :root { From d16685a74f71f5491c19dd09c82ecd33d4424159 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 12 Aug 2026 16:47:26 +0200 Subject: [PATCH 4/6] fix claude launch json to help with testing --- .claude/launch.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.claude/launch.json b/.claude/launch.json index c3703481..069b1adf 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -2,12 +2,9 @@ "version": "0.0.1", "configurations": [ { - "name": "dev", - "runtimeExecutable": "pnpm", - "runtimeArgs": [ - "run", - "dev" - ], + "name": "robostack-site", + "runtimeExecutable": "env", + "runtimeArgs": ["ASTRO_DEV_BACKGROUND=1", "pixi", "run", "serve"], "port": 4321 } ] From ad32095e6730385e39eafb849c24198c80b71923 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 12 Aug 2026 16:51:29 +0200 Subject: [PATCH 5/6] Apply suggestion from @ruben-arts --- src/content/docs/CommunityMeeting.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/CommunityMeeting.mdx b/src/content/docs/CommunityMeeting.mdx index 8931e166..f8417aaf 100644 --- a/src/content/docs/CommunityMeeting.mdx +++ b/src/content/docs/CommunityMeeting.mdx @@ -5,7 +5,7 @@ slug: CommunityMeeting import { LinkButton } from "@astrojs/starlight/components"; -RoboStack is a multi-owner project, so once a month we host an online meeting to discuss changes and potential user questions. +RoboStack has multiple stakeholders, so once a month we host an online meeting to discuss changes and potential user questions. Join in to understand or influence the project. :::note[Everyone is welcome] From 54f2fdff302ef335df4fa98a1a2064992ef166ce Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 12 Aug 2026 16:51:51 +0200 Subject: [PATCH 6/6] Apply suggestion from @ruben-arts --- src/content/docs/CommunityMeeting.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/content/docs/CommunityMeeting.mdx b/src/content/docs/CommunityMeeting.mdx index f8417aaf..14b09b70 100644 --- a/src/content/docs/CommunityMeeting.mdx +++ b/src/content/docs/CommunityMeeting.mdx @@ -11,7 +11,6 @@ Join in to understand or influence the project. :::note[Everyone is welcome] You don't have to be a maintainer or contributor. Using RoboStack, or just curious about it, is reason enough to join. -No sign-up needed. ::: ## When