├── .changeset ├── README.md └── config.json ├── .github ├── dependabot.yml └── workflows │ └── release.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── docs ├── README.md ├── astro.config.mjs ├── package.json ├── public │ └── favicon.svg ├── src │ ├── assets │ │ └── houston.webp │ ├── components │ │ ├── Changelog.astro │ │ └── ListOfUtilities.astro │ ├── content │ │ ├── config.ts │ │ └── docs │ │ │ ├── _quick-start.mdx │ │ │ ├── demos │ │ │ ├── 1.md │ │ │ ├── 2.md │ │ │ ├── 3.md │ │ │ └── 4.md │ │ │ ├── docs │ │ │ ├── changelog.mdx │ │ │ ├── configuration.mdx │ │ │ ├── index.mdx │ │ │ ├── recommended.mdx │ │ │ └── utilities.mdx │ │ │ ├── index.mdx │ │ │ └── utilities │ │ │ ├── multi-sidebar.mdx │ │ │ └── nav-links.mdx │ └── env.d.ts └── tsconfig.json ├── package.json ├── packages └── starlight-utils │ ├── CHANGELOG.md │ ├── README.md │ ├── components │ ├── Dropdown.astro │ ├── HorizontalList.astro │ ├── NavLinks.astro │ ├── Sidebar.astro │ ├── SidebarWrapper.astro │ ├── SiteTitle.astro │ └── index.ts │ ├── config.ts │ ├── index.ts │ ├── integration.ts │ ├── middleware.ts │ ├── package.json │ ├── tsconfig.json │ └── virtual.d.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { "repo": "lorenzolewis/starlight-utils" } 6 | ], 7 | "commit": false, 8 | "fixed": [], 9 | "linked": [], 10 | "access": "public", 11 | "baseBranch": "main", 12 | "updateInternalDependencies": "patch", 13 | "ignore": ["docs"] 14 | } 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | if: ${{ github.repository_owner == 'lorenzolewis' }} 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout Repo 17 | uses: actions/checkout@v4 18 | 19 | - name: Install pnpm 20 | uses: pnpm/action-setup@v3 21 | 22 | - name: Install Node.js 23 | uses: actions/setup-node@v3 24 | with: 25 | cache: pnpm 26 | node-version: 18 27 | 28 | - name: Install dependencies 29 | run: pnpm install 30 | 31 | - name: Create Release Pull Request 32 | uses: changesets/action@v1 33 | with: 34 | version: pnpm run version 35 | publish: pnpm changeset publish 36 | commit: "[ci] release" 37 | title: "[ci] release" 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.enableFiletypes": ["mdx"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Lorenzo Lewis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ./packages/starlight-utils/README.md -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Starlight Starter Kit: Basics 2 | 3 | [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) 4 | 5 | ``` 6 | npm create astro@latest -- --template starlight 7 | ``` 8 | 9 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) 10 | [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) 11 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs) 12 | 13 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 14 | 15 | ## 🚀 Project Structure 16 | 17 | Inside of your Astro + Starlight project, you'll see the following folders and files: 18 | 19 | ``` 20 | . 21 | ├── public/ 22 | ├── src/ 23 | │ ├── assets/ 24 | │ ├── content/ 25 | │ │ ├── docs/ 26 | │ │ └── config.ts 27 | │ └── env.d.ts 28 | ├── astro.config.mjs 29 | ├── package.json 30 | └── tsconfig.json 31 | ``` 32 | 33 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. 34 | 35 | Images can be added to `src/assets/` and embedded in Markdown with a relative link. 36 | 37 | Static assets, like favicons, can be placed in the `public/` directory. 38 | 39 | ## 🧞 Commands 40 | 41 | All commands are run from the root of the project, from a terminal: 42 | 43 | | Command | Action | 44 | | :------------------------ | :----------------------------------------------- | 45 | | `npm install` | Installs dependencies | 46 | | `npm run dev` | Starts local dev server at `localhost:4321` | 47 | | `npm run build` | Build your production site to `./dist/` | 48 | | `npm run preview` | Preview your build locally, before deploying | 49 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 50 | | `npm run astro -- --help` | Get help using the Astro CLI | 51 | 52 | ## 👀 Want to learn more? 53 | 54 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). 55 | -------------------------------------------------------------------------------- /docs/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "astro/config"; 2 | import starlight from "@astrojs/starlight"; 3 | import starlightLinksValidatorPlugin from "starlight-links-validator"; 4 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 5 | 6 | // https://astro.build/config 7 | export default defineConfig({ 8 | site: "https://starlight-utils.pages.dev", 9 | integrations: [ 10 | starlight({ 11 | title: "🧰 Starlight Utils", 12 | credits: true, 13 | social: { 14 | github: "https://github.com/lorenzolewis/starlight-utils", 15 | }, 16 | editLink: { 17 | baseUrl: 18 | "https://github.com/lorenzolewis/starlight-utils/edit/main/docs/", 19 | }, 20 | sidebar: [ 21 | { 22 | label: "Main", 23 | items: [ 24 | { label: "Docs", autogenerate: { directory: "/docs" } }, 25 | { 26 | label: "Utilities", 27 | autogenerate: { directory: "/utilities" }, 28 | }, 29 | ], 30 | }, 31 | { 32 | label: "Demos", 33 | badge: "New", 34 | autogenerate: { directory: "/demos" }, 35 | }, 36 | { 37 | label: "leading", 38 | items: [ 39 | { label: "Docs", link: "/docs" }, 40 | { label: "Demos", link: "/demos/1" }, 41 | ], 42 | }, 43 | ], 44 | components: {}, 45 | plugins: [ 46 | starlightLinksValidatorPlugin(), 47 | starlightUtils({ 48 | multiSidebar: true, 49 | navLinks: { 50 | leading: { useSidebarLabelled: "leading" }, 51 | }, 52 | }), 53 | ], 54 | }), 55 | ], 56 | }); 57 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "private": true, 4 | "type": "module", 5 | "version": "0.0.1", 6 | "scripts": { 7 | "dev": "astro dev", 8 | "start": "astro dev", 9 | "build": "astro check && astro build", 10 | "preview": "astro preview", 11 | "astro": "astro" 12 | }, 13 | "dependencies": { 14 | "@astrojs/check": "^0.9.3", 15 | "@astrojs/starlight": "^0.32.5", 16 | "@lorenzo_lewis/starlight-utils": "workspace:*", 17 | "astro": "^5.6.1", 18 | "sharp": "^0.33.5", 19 | "starlight-links-validator": "^0.15.0", 20 | "starlight-package-managers": "^0.10.0", 21 | "typescript": "^5.8.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/src/assets/houston.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorenzolewis/starlight-utils/6ec8fa66ee0dd4186a02678a5443e8ff1f59ab91/docs/src/assets/houston.webp -------------------------------------------------------------------------------- /docs/src/components/Changelog.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { compiledContent } from "../../../packages/starlight-utils/CHANGELOG.md"; 3 | 4 | const content = (await compiledContent()).replace(/(.*?<\/h1>)/, ""); 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/src/components/ListOfUtilities.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { LinkCard, CardGrid } from "@astrojs/starlight/components"; 3 | import { getCollection } from "astro:content"; 4 | 5 | interface Props { 6 | withConfiguration?: boolean; 7 | } 8 | 9 | const { withConfiguration = false } = Astro.props; 10 | 11 | const utilities = await getCollection("docs", ({ slug }) => { 12 | return slug.startsWith("utilities"); 13 | }); 14 | --- 15 | 16 | 17 | { 18 | utilities.map((util) => ( 19 | 28 | )) 29 | } 30 | 31 | -------------------------------------------------------------------------------- /docs/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from "astro:content"; 2 | import { docsSchema } from "@astrojs/starlight/schema"; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | }; 7 | -------------------------------------------------------------------------------- /docs/src/content/docs/_quick-start.mdx: -------------------------------------------------------------------------------- 1 | import { Steps } from "@astrojs/starlight/components"; 2 | import { PackageManagers } from "starlight-package-managers"; 3 | 4 | 5 | 6 | 1. Setup a Starlight Site: https://starlight.astro.build/getting-started/ 7 | 8 | 2. Install the `starlight-utils` plugin: 9 | 10 | 11 | 12 | 3. Update the `integrations.starlight.plugins` object in `astro.config.mjs` to include the `starlight-utils` plugin: 13 | 14 | ```ts ins={4, 10} 15 | // astro.config.mjs 16 | import { defineConfig } from "astro/config"; 17 | import starlight from "@astrojs/starlight"; 18 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 19 | 20 | // https://astro.build/config 21 | export default defineConfig({ 22 | integrations: [ 23 | starlight({ 24 | plugins: [starlightUtils()], 25 | }), 26 | ], 27 | }); 28 | ``` 29 | 30 | 4. Go to the [Configuration Guide](/docs/configuration) to learn how to set up the different utilities ✨ 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/src/content/docs/demos/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Waltz 3 | --- 4 | 5 | :::tip 6 | 7 | Notice the toggle in the sidebar. It works in mobile as well! 8 | 9 | ::: 10 | 11 | Waltz, bad nymph, for quick jigs vex. 12 | -------------------------------------------------------------------------------- /docs/src/content/docs/demos/2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Quick Zephyrs 3 | --- 4 | 5 | Quick zephyrs blow, vexing daft Jim. 6 | -------------------------------------------------------------------------------- /docs/src/content/docs/demos/3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sphinx 3 | --- 4 | 5 | Sphinx of black quartz, judge my vow. 6 | -------------------------------------------------------------------------------- /docs/src/content/docs/demos/4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The quick brown fox 3 | --- 4 | 5 | The quick brown fox jumps over the lazy dog. 6 | -------------------------------------------------------------------------------- /docs/src/content/docs/docs/changelog.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Changelog 3 | sidebar: 4 | order: 5 5 | --- 6 | 7 | import Changelog from "../../../components/Changelog.astro"; 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/src/content/docs/docs/configuration.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Configuration 3 | sidebar: 4 | order: 2 5 | --- 6 | 7 | Each utility has it's own configuration so that they can be used independently of one another. 8 | 9 | Read the respective page of each utility for the configuration of that utility. 10 | 11 | import List from "@components/ListOfUtilities.astro"; 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/src/content/docs/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | sidebar: 4 | order: 1 5 | --- 6 | 7 | ## Setup Instructions 8 | 9 | import Setup from "../_quick-start.mdx"; 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/src/content/docs/docs/recommended.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Recommended Resources 3 | sidebar: 4 | order: 4 5 | --- 6 | 7 | import { LinkCard, CardGrid } from "@astrojs/starlight/components"; 8 | 9 | ## Plugins 10 | 11 | These are plugins not included in this utility but are fantastic to add to your Starlight site. 12 | 13 | 14 | 19 | 24 | 25 | 26 | --- 27 | 28 | 33 | -------------------------------------------------------------------------------- /docs/src/content/docs/docs/utilities.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: List of Utilities 3 | sidebar: 4 | order: 3 5 | --- 6 | 7 | import { LinkCard, CardGrid } from "@astrojs/starlight/components"; 8 | import List from "@components/ListOfUtilities.astro"; 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/src/content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 🧰 Starlight Utils 3 | description: Utilities to use with your 🌟 Starlight site 4 | tableOfContents: false 5 | hero: 6 | tagline: Utilities to use with your 🌟 Starlight site 7 | image: 8 | file: ../../assets/houston.webp 9 | actions: 10 | - text: Get Started 11 | link: /docs 12 | icon: right-arrow 13 | variant: primary 14 | --- 15 | 16 | import QuickStart from "./_quick-start.mdx"; 17 | 18 | ## Quick Start 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/src/content/docs/utilities/multi-sidebar.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Multi-Sidebar 3 | description: Enable multiple sidebars with your Starlight site. 4 | sidebar: 5 | badge: 6 | text: New 7 | variant: tip 8 | --- 9 | 10 | :::tip 11 | 12 | You can see the `horizontalList` sidebar style in action in this site's sidebar. 13 | 14 | ::: 15 | 16 | There are cases where having multiple sidebars for a Starlight site can be useful. [Starlight does not currently support this natively](https://github.com/withastro/starlight/discussions/959), but this utility gives a minimal implementation of this. 17 | 18 | :::note[Migration] 19 | 20 | Multi-sidebar was originally launched in the (now deprecated) `@lorenzo_lewis/starlight-multi-sidebar` package. 21 | 22 | If migrating from that package read the [Migration Steps](#migration) below. 23 | 24 | ::: 25 | 26 | ## Configuration 27 | 28 | Multi-sidebar can be enabled by adding the `multiSidebar` object to the Starlight Utils configuration. 29 | 30 | To define the sidebars, specify a label and contents for each sidebar. Here is a simplified example of the config used for this site: 31 | 32 | ```ts {12-14,17-27} 33 | // astro.config.mjs 34 | import { defineConfig } from "astro/config"; 35 | import starlight from "@astrojs/starlight"; 36 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 37 | 38 | // https://astro.build/config 39 | export default defineConfig({ 40 | integrations: [ 41 | starlight({ 42 | plugins: [ 43 | starlightUtils({ 44 | multiSidebar: { 45 | switcherStyle: "horizontalList", 46 | }, 47 | }), 48 | ], 49 | sidebar: [ 50 | { 51 | label: "Main", 52 | autogenerate: { directory: "/docs" }, 53 | }, 54 | { 55 | label: "Demos", 56 | autogenerate: { directory: "/demos" }, 57 | badge: "New", 58 | }, 59 | ], 60 | }), 61 | ], 62 | }); 63 | ``` 64 | 65 | ### `multiSidebar` 66 | 67 | **Type:** `boolean | { switcherStyle: "dropdown" | "horizontalList" | "hidden" } | undefined` 68 | 69 | - If `true`, the sidebar will be rendered with the `horizontalList` switcher style. 70 | - If no `multiSidebar` key is set, or if the value is `false` or `undefined`, then the default Starlight sidebar will be used. 71 | - Otherwise, the value specified in `switcherStyle` will be used. 72 | - The `hidden` style hides the sidebar switcher. This is useful if you are using [Nav Links](/utilities/nav-links/) and don't need a sidebar switcher. 73 | 74 | ## Migration 75 | 76 | `@lorenzo_lewis/starlight-multi-sidebar` has been deprecated in favor of this package. 77 | 78 | Here are the steps for migrating from `@lorenzo_lewis/starlight-multi-sidebar`: 79 | 80 | import { Steps } from "@astrojs/starlight/components"; 81 | import { PackageManagers } from "starlight-package-managers"; 82 | 83 | 84 | 85 | 1. Switch to `@lorenzo_lewis/starlight-utils` by running this command to remove the deprecated package: 86 | 87 | 91 | 92 | Then this command to add the new package: 93 | 94 | 95 | 96 | 2. Update the integration in `astro.config.mts`: 97 | 98 | ```ts ins={4, 12} del={5, 13} 99 | // astro.config.mjs 100 | import { defineConfig } from "astro/config"; 101 | import starlight from "@astrojs/starlight"; 102 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 103 | import starlightMultiSidebar from "@lorenzo_lewis/starlight-multi-sidebar"; 104 | 105 | // https://astro.build/config 106 | export default defineConfig({ 107 | integrations: [ 108 | starlight({ 109 | plugins: [ 110 | starlightUtils({ multiSidebar: true }), 111 | starlightMultiSidebar(), 112 | ], 113 | }), 114 | ], 115 | }); 116 | ``` 117 | 118 | Any configuration options used before are also compatible and can be passed to the `multiSidebar` object. 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/src/content/docs/utilities/nav-links.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Nav Links 3 | description: Add additional links to the Starlight navigation. 4 | sidebar: 5 | badge: 6 | text: New 7 | variant: tip 8 | --- 9 | 10 | :::tip 11 | 12 | You can see this in action next to the site title above. 13 | 14 | ::: 15 | 16 | Sometimes you may want to add more links to your Starlight docs outside of the sidebar navigation. [Starlight does not currently support](https://github.com/withastro/starlight/discussions/963) this out of the box. 17 | 18 | With this utility you can add a list of links to the Astro config and they will be rendered in the navigation bar in both desktop and mobile. 19 | 20 | ## Setup 21 | 22 | import { Steps } from "@astrojs/starlight/components"; 23 | 24 | 25 | 26 | 1. Add a new sidebar entry to the Starlight plugin in `astro.config.mjs` with any `label` that will be used in a later step. 27 | 28 | ```ts add={10-12} 29 | // astro.config.mjs 30 | import { defineConfig } from "astro/config"; 31 | import starlight from "@astrojs/starlight"; 32 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 33 | 34 | // https://astro.build/config 35 | export default defineConfig({ 36 | integrations: [ 37 | starlight({ 38 | sidebar: [{ 39 | label: "leadingNavLinks", 40 | }], 41 | }), 42 | ], 43 | }); 44 | ``` 45 | 46 | 2. Add a list of links to the `items` object in the newly added sidebar entry using the Starlight [Links](https://starlight.astro.build/guides/sidebar/#links) syntax. 47 | 48 | Currently [Group](https://starlight.astro.build/guides/sidebar/#groups) and [Autogenerated groups](https://starlight.astro.build/guides/sidebar/#autogenerated-groups) are not supported. 49 | 50 | ```ts add={12-15} 51 | // astro.config.mjs 52 | import { defineConfig } from "astro/config"; 53 | import starlight from "@astrojs/starlight"; 54 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 55 | 56 | // https://astro.build/config 57 | export default defineConfig({ 58 | integrations: [ 59 | starlight({ 60 | sidebar: [{ 61 | label: "leadingNavLinks", 62 | items: [ 63 | { label: "Docs", link: "/docs" }, 64 | { label: "References", link: "/references" } 65 | ] 66 | }], 67 | }), 68 | ], 69 | }); 70 | ``` 71 | 72 | 3. Add the `navLinks.leading.useSidebarLabelled` entry to the Starlight Utils plugin. Use the label created above for `useSidebarLabelled`. 73 | 74 | Be sure that you've added `import starlightUtils from "@lorenzo_lewis/starlight-utils"` to the top of the file. 75 | 76 | ```ts {3} add={19-21} 77 | // astro.config.mjs 78 | import { defineConfig } from "astro/config"; 79 | import starlight from "@astrojs/starlight"; 80 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 81 | 82 | // https://astro.build/config 83 | export default defineConfig({ 84 | integrations: [ 85 | starlight({ 86 | sidebar: [{ 87 | label: "leadingNavLinks", 88 | items: [ 89 | { label: "Docs", link: "/docs" }, 90 | { label: "References", link: "/references" } 91 | ] 92 | }], 93 | plugins: [ 94 | starlightUtils({ 95 | navLinks: { 96 | leading: { useSidebarLabelled: "leadingNavLinks" } 97 | } 98 | }) 99 | ] 100 | }), 101 | ], 102 | }); 103 | ``` 104 | 105 | 4. That's it! ✨ 106 | 107 | 108 | 109 | :::tip 110 | 111 | The sidebar used for creating nav links will automatically be removed for generating normal sidebars. 112 | 113 | ::: 114 | 115 | ## Configuration 116 | 117 | The sidebar can be enabled by adding the `navLinks` object to the Starlight Utils configuration. 118 | 119 | ```ts {12-14} 120 | // astro.config.mjs 121 | import { defineConfig } from "astro/config"; 122 | import starlight from "@astrojs/starlight"; 123 | import starlightUtils from "@lorenzo_lewis/starlight-utils"; 124 | 125 | // https://astro.build/config 126 | export default defineConfig({ 127 | integrations: [ 128 | starlight({ 129 | plugins: [ 130 | starlightUtils({ 131 | navLinks: { 132 | leading: { useSidebarLabelled: "leadingNavLinks" }, 133 | }, 134 | }), 135 | ], 136 | }), 137 | ], 138 | }); 139 | ``` 140 | 141 | ### `navLinks` 142 | 143 | **Type:** `{ leading: NavConfig } | undefined` 144 | 145 | **Default:** `undefined` 146 | 147 | Enables the navigation links for the respective position. 148 | 149 | ### `NavConfig` 150 | 151 | **Type:** `{ useSidebarLabelled: string }` 152 | 153 | - `useSidebarLabelled`: The name of the sidebar defined in the Starlight config that should be used for generating the respective nav links. 154 | -------------------------------------------------------------------------------- /docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@components/*": ["src/components/*"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starlight-utils-monorepo", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "license": "MIT", 6 | "private": true, 7 | "scripts": { 8 | "doc": "pnpm --filter docs", 9 | "version": "pnpm changeset version && pnpm i --no-frozen-lockfile" 10 | }, 11 | "dependencies": { 12 | "@changesets/changelog-github": "^0.5.1", 13 | "@changesets/cli": "^2.28.1", 14 | "astro": "^5.6.1", 15 | "prettier": "^3.5.3", 16 | "prettier-plugin-astro": "^0.14.1", 17 | "typescript": "^5.8.2" 18 | }, 19 | "packageManager": "pnpm@9.1.1" 20 | } 21 | -------------------------------------------------------------------------------- /packages/starlight-utils/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @lorenzo_lewis/starlight-utils 2 | 3 | ## 0.3.2 4 | 5 | ### Patch Changes 6 | 7 | - [#177](https://github.com/lorenzolewis/starlight-utils/pull/177) [`19e07ee`](https://github.com/lorenzolewis/starlight-utils/commit/19e07ee4c1ca7725cae289844b3925f85f27d6de) Thanks [@lorenzolewis](https://github.com/lorenzolewis)! - Fix issue where sidebar was being overridden when not needed, causing issues with other Starlight plugins. 8 | 9 | - [#179](https://github.com/lorenzolewis/starlight-utils/pull/179) [`aa33352`](https://github.com/lorenzolewis/starlight-utils/commit/aa33352478cdd955da5d9324c75ec902d37260dd) Thanks [@lorenzolewis](https://github.com/lorenzolewis)! - Improve compatibility with `starlight-auto-sidebar`. 10 | 11 | ## 0.3.1 12 | 13 | ### Patch Changes 14 | 15 | - [#170](https://github.com/lorenzolewis/starlight-utils/pull/170) [`5a0f41c`](https://github.com/lorenzolewis/starlight-utils/commit/5a0f41c8819cc490002cae72db76157623ee1331) Thanks [@lorenzolewis](https://github.com/lorenzolewis)! - Add support for Starlight 0.32 16 | 17 | ## 0.3.0 18 | 19 | ### Minor Changes 20 | 21 | - [#156](https://github.com/lorenzolewis/starlight-utils/pull/156) [`ce97990`](https://github.com/lorenzolewis/starlight-utils/commit/ce9799099ce0e7536033fde9d5d446b2ec87ad10) Thanks [@ringods](https://github.com/ringods)! - Update to support Astro 5 22 | 23 | ## 0.2.0 24 | 25 | ### Minor Changes 26 | 27 | - [#105](https://github.com/lorenzolewis/starlight-utils/pull/105) [`15ec13f`](https://github.com/lorenzolewis/starlight-utils/commit/15ec13f497f9653bc6ec30b2b5af1649712406e2) Thanks [@huijing](https://github.com/huijing)! - Support translated strings introduced in the Starlight 0.28 localization API 28 | 29 | ## 0.1.2 30 | 31 | ### Patch Changes 32 | 33 | - [#48](https://github.com/lorenzolewis/starlight-utils/pull/48) [`668d9db`](https://github.com/lorenzolewis/starlight-utils/commit/668d9db5fec01c13d8f9c7f4f1ca7dd4ffdf85ac) Thanks [@andrii-bodnar](https://github.com/andrii-bodnar)! - Add `hidden` style for `switcherStyle`. This can be useful when combined with navigation links. 34 | 35 | ## 0.1.1 36 | 37 | ### Patch Changes 38 | 39 | - [#21](https://github.com/lorenzolewis/starlight-utils/pull/21) [`2dcee08`](https://github.com/lorenzolewis/starlight-utils/commit/2dcee083e56d4dcc9a27e77895085a7b081e21f1) Thanks [@lorenzolewis](https://github.com/lorenzolewis)! - Enable badge's for horizontal list style of multi-sidebar. 40 | 41 | ## 0.1.0 42 | 43 | ### Minor Changes 44 | 45 | - [#3](https://github.com/lorenzolewis/starlight-utils/pull/3) [`2ccae4d`](https://github.com/lorenzolewis/starlight-utils/commit/2ccae4da48e1933548879d9e41f2f9a1efd8e9fa) Thanks [@lorenzolewis](https://github.com/lorenzolewis)! - Add Nav Links utility 46 | 47 | More information can be found at https://starlight-utils.pages.dev/utilities/nav-links/. 48 | 49 | ## 0.0.1 50 | 51 | ### Patch Changes 52 | 53 | - Add [multi-sidebar](https://starlight-utils.pages.dev/utilities/multi-sidebar/). 54 | 55 | This was migrated from `@lorenzo_lewis/starlight-multi-sidebar`. Migration documentation can be found at https://starlight-utils.pages.dev/utilities/multi-sidebar/#migration 56 | -------------------------------------------------------------------------------- /packages/starlight-utils/README.md: -------------------------------------------------------------------------------- 1 | # 🧰 Starlight Utils 2 | 3 | Utilities to use with your 🌟 [Starlight](https://starlight.astro.build) site. 4 | 5 | Visit the documentation for instructions on how to use: https://starlight-utils.pages.dev 6 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/Dropdown.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // Component adapted from https://github.com/withastro/starlight/blob/1576e32925276cf35f8f77641d406328eec73fb6/packages/starlight/components/LanguageSelect.astro 3 | 4 | import { Icon } from "@astrojs/starlight/components"; 5 | import SidebarWrapper from "./SidebarWrapper.astro"; 6 | import { AstroError } from "astro/errors"; 7 | 8 | if (!Astro.locals.starlightUtils.multiSidebar) { 9 | throw new AstroError( 10 | "An error occurred with starlight-utils. Please [file an issue on GitHub](https://github.com/lorenzolewis/starlight-utils/issues)." 11 | ); 12 | } 13 | --- 14 | 15 | 16 | 47 | { 48 | Astro.locals.starlightUtils.multiSidebar.map( 49 | ({ isCurrentSidebar, label, sidebar }) => ( 50 | 56 | ) 57 | ) 58 | } 59 | 60 | 61 | 93 | 138 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/HorizontalList.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // Component adapted from https://github.com/withastro/starlight/blob/1576e32925276cf35f8f77641d406328eec73fb6/packages/starlight/user-components/Tabs.astro 3 | 4 | import { Badge } from "@astrojs/starlight/components"; 5 | import { AstroError } from "astro/errors"; 6 | import SidebarWrapper from "./SidebarWrapper.astro"; 7 | 8 | let count = 0; 9 | 10 | if (!Astro.locals.starlightUtils.multiSidebar) { 11 | throw new AstroError( 12 | "An error occurred with starlight-utils. Please [file an issue on GitHub](https://github.com/lorenzolewis/starlight-utils/issues)." 13 | ); 14 | } 15 | 16 | const sidebars = Astro.locals.starlightUtils.multiSidebar.map((sidebar) => { 17 | const id = count++; 18 | return { 19 | panelId: "sidebar-panel-" + id, 20 | tabId: "sidebar-tab-" + id, 21 | ...sidebar, 22 | }; 23 | }); 24 | --- 25 | 26 | 27 |
28 | 61 |
62 | { 63 | sidebars.map(({ isCurrentSidebar, tabId, panelId, sidebar }) => ( 64 | 73 | )) 74 | } 75 |
76 | 117 | 118 | 195 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/NavLinks.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // Styles adapted from https://github.com/withastro/starlight/blob/main/packages/starlight/components/SidebarSublist.astro 3 | // and https://www.figma.com/design/GrDkcguAR7tSWPFuLVDixq/Theme---Starlight-Docs?node-id=454-34753&t=fgVYGvAg6ftBSpJY-0 4 | --- 5 | 6 | { 7 | Astro.locals.starlightUtils.navLinks && ( 8 | 21 | ) 22 | } 23 | 24 | 53 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/Sidebar.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import config from "virtual:starlight-utils/config"; 3 | import Dropdown from "./Dropdown.astro"; 4 | import HorizontalList from "./HorizontalList.astro"; 5 | import SidebarWrapper from "./SidebarWrapper.astro"; 6 | import { AstroError } from "astro/errors"; 7 | import Default from "@astrojs/starlight/components/Sidebar.astro"; 8 | 9 | interface Props { 10 | renderDefault?: boolean; 11 | } 12 | 13 | // Styles and CSS logic derived from https://daisyui.com/components/collapse/ 14 | 15 | // This Sidebar override uses the top-level items from the Starlight sidebar config to create sidebars. 16 | 17 | if (!Astro.locals.starlightUtils.multiSidebar) { 18 | throw new AstroError( 19 | "An error occurred with starlight-utils. Please [file an issue on GitHub](https://github.com/lorenzolewis/starlight-utils/issues)." 20 | ); 21 | } 22 | --- 23 | 24 | { 25 | Astro.props.renderDefault ? ( 26 | 27 | ) : config?.multiSidebar ? ( 28 | <> 29 | {config.multiSidebar.switcherStyle === "dropdown" && } 30 | {config.multiSidebar.switcherStyle === "horizontalList" && ( 31 | 32 | )} 33 | {config.multiSidebar.switcherStyle === "hidden" && 34 | Astro.locals.starlightUtils.multiSidebar.map( 35 | ({ isCurrentSidebar, label, sidebar }) => ( 36 | 42 | ) 43 | )} 44 | 45 | ) : ( 46 | 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/SidebarWrapper.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // This component is used for a manual work-around for re-defining StarlightRouteData. 3 | // This is required because middleware is only updated once per page render. 4 | // Since the original sidebar uses middleware this makes it where the local is overridden manually. 5 | import { type StarlightRouteData } from "@astrojs/starlight/route-data"; 6 | import Default from "@astrojs/starlight/components/Sidebar.astro"; 7 | 8 | interface Props { 9 | sidebar?: StarlightRouteData["sidebar"]; 10 | } 11 | 12 | if (Astro.props.sidebar) { 13 | Astro.locals.starlightRoute.sidebar = Astro.props.sidebar; 14 | } 15 | --- 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/SiteTitle.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Default from "@astrojs/starlight/components/SiteTitle.astro"; 3 | import NavLinks from "./NavLinks.astro"; 4 | 5 | import type { Props } from "@astrojs/starlight/props"; 6 | --- 7 | 8 |
9 | 10 | 11 |
12 | 13 | 20 | -------------------------------------------------------------------------------- /packages/starlight-utils/components/index.ts: -------------------------------------------------------------------------------- 1 | import Sidebar from "./Sidebar.astro"; 2 | 3 | export { Sidebar }; 4 | -------------------------------------------------------------------------------- /packages/starlight-utils/config.ts: -------------------------------------------------------------------------------- 1 | import { AstroError } from "astro/errors"; 2 | import { z } from "astro/zod"; 3 | 4 | const multiSidebarConfig = z 5 | .union([ 6 | z.object({ 7 | switcherStyle: z.union([ 8 | z.enum(["dropdown", "horizontalList", "hidden"]).default("horizontalList"), 9 | z.boolean(), 10 | ]), 11 | }), 12 | z.boolean().transform((value) => { 13 | if (value) { 14 | return { switcherStyle: "horizontalList" as const }; 15 | } else { 16 | return undefined; 17 | } 18 | }), 19 | ]) 20 | .optional(); 21 | 22 | const navLinksConfig = z 23 | .object({ 24 | leading: z.object({ useSidebarLabelled: z.string() }).optional(), 25 | }) 26 | .optional(); 27 | 28 | export const configSchema = z 29 | .object({ 30 | multiSidebar: multiSidebarConfig, 31 | navLinks: navLinksConfig, 32 | }) 33 | .optional(); 34 | 35 | export type StarlightUtilsConfig = z.infer; 36 | 37 | export function validateConfig(userConfig: unknown): StarlightUtilsConfig { 38 | const config = configSchema.safeParse(userConfig); 39 | 40 | if (!config.success) { 41 | const errors = config.error.flatten(); 42 | throw new AstroError( 43 | `Invalid starlight-utils configuration: 44 | 45 | ${errors.formErrors 46 | .map((formError) => ` - ${formError}`) 47 | .join("\n")} 48 | ${Object.entries(errors.fieldErrors) 49 | .map( 50 | ([fieldName, fieldErrors]) => 51 | `- ${fieldName}: ${JSON.stringify(fieldErrors)}` 52 | ) 53 | .join("\n")} 54 | ` 55 | ); 56 | } 57 | 58 | return config.data; 59 | } 60 | -------------------------------------------------------------------------------- /packages/starlight-utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { StarlightPlugin } from "@astrojs/starlight/types"; 2 | import { validateConfig, type StarlightUtilsConfig } from "./config"; 3 | import integration from "./integration"; 4 | 5 | function plugin(userConfig?: StarlightUtilsConfig): StarlightPlugin { 6 | const utilsConfig = validateConfig(userConfig); 7 | return { 8 | name: "starlight-utils", 9 | hooks: { 10 | setup({ 11 | addIntegration, 12 | config, 13 | updateConfig, 14 | addRouteMiddleware, 15 | logger, 16 | }) { 17 | addIntegration(integration(utilsConfig)); 18 | const componentOverrides: typeof config.components = {}; 19 | if (utilsConfig?.multiSidebar) { 20 | const indexStarlightAutoSidebar = config.plugins?.findIndex( 21 | ({ name }) => name === "starlight-auto-sidebar" 22 | ); 23 | const indexStarlightUtils = config.plugins?.findIndex( 24 | ({ name }) => name === "starlight-utils" 25 | ); 26 | if ( 27 | indexStarlightAutoSidebar && 28 | indexStarlightUtils && 29 | // Plugin exists 30 | indexStarlightAutoSidebar !== -1 && 31 | // Plugin is placed after starlight utils 32 | indexStarlightAutoSidebar! > indexStarlightUtils 33 | ) { 34 | logger.warn( 35 | "Move `starlight-auto-sidebar` before `starlight-utils` in the Starlight `plugins` object of the Astro config if you wish to use the plugins together." 36 | ); 37 | } 38 | componentOverrides.Sidebar = 39 | "@lorenzo_lewis/starlight-utils/components/Sidebar.astro"; 40 | } 41 | if (utilsConfig?.navLinks?.leading) { 42 | componentOverrides.SiteTitle = 43 | "@lorenzo_lewis/starlight-utils/components/SiteTitle.astro"; 44 | } 45 | updateConfig({ 46 | components: { 47 | ...componentOverrides, 48 | ...config.components, 49 | }, 50 | }); 51 | addRouteMiddleware({ 52 | entrypoint: "@lorenzo_lewis/starlight-utils/middleware", 53 | order: "post", 54 | }); 55 | }, 56 | }, 57 | }; 58 | } 59 | 60 | export default plugin; 61 | -------------------------------------------------------------------------------- /packages/starlight-utils/integration.ts: -------------------------------------------------------------------------------- 1 | import { defineIntegration, addVirtualImports } from "astro-integration-kit"; 2 | import { configSchema } from "./config"; 3 | 4 | export default defineIntegration({ 5 | name: "starlight-utils-integration", 6 | optionsSchema: configSchema, 7 | setup({ name, options }) { 8 | return { 9 | hooks: { 10 | "astro:config:setup": (params) => { 11 | addVirtualImports(params, { 12 | name, 13 | imports: { 14 | "virtual:starlight-utils/config": `export default ${JSON.stringify( 15 | options 16 | )}`, 17 | }, 18 | }); 19 | }, 20 | }, 21 | }; 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /packages/starlight-utils/middleware.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineRouteMiddleware, 3 | type StarlightRouteData, 4 | } from "@astrojs/starlight/route-data"; 5 | import { AstroError } from "astro/errors"; 6 | import config from "virtual:starlight-utils/config"; 7 | 8 | export const onRequest = defineRouteMiddleware((context) => { 9 | // Initialize object 10 | context.locals.starlightUtils = {}; 11 | 12 | // Logic for navLinks 13 | if (config?.navLinks?.leading) { 14 | const sidebarLabel = config?.navLinks?.leading?.useSidebarLabelled; 15 | 16 | if (!sidebarLabel) { 17 | throw new AstroError( 18 | `No sidebar label was specified for the ${JSON.stringify(config?.navLinks?.leading)} entry in the Astro config.` 19 | ); 20 | } 21 | 22 | const starlightRouteSidebar = context.locals.starlightRoute.sidebar; 23 | const navLinks: typeof starlightRouteSidebar = []; 24 | const filteredSidebar: typeof starlightRouteSidebar = []; 25 | 26 | starlightRouteSidebar.forEach((entry) => { 27 | const condition = 28 | entry.label === config?.navLinks?.leading?.useSidebarLabelled; 29 | condition ? navLinks.push(entry) : filteredSidebar.push(entry); 30 | }); 31 | 32 | if (navLinks.length != 1 || !navLinks[0]) { 33 | throw new AstroError( 34 | `Could not find the sidebar labelled \`${sidebarLabel}\` that was referenced in the Starlight Utils config.` 35 | ); 36 | } 37 | 38 | if (navLinks[0].type !== "group") { 39 | throw new AstroError( 40 | `\`${navLinks[0].label}\` cannot be used with multi-sidebar. 41 | 42 | The sidebar entry specified in the Astro config must be either a group or autogenerated. 43 | 44 | See https://starlight.astro.build/guides/sidebar/#groups and https://starlight.astro.build/guides/sidebar/#autogenerated-groups for more details.` 45 | ); 46 | } 47 | 48 | if (navLinks[0].entries.some((entry) => entry.type !== "link")) { 49 | throw new AstroError( 50 | `Only links can be specified for nav links. No groups or autogenerated types are allowed.` 51 | ); 52 | } 53 | 54 | // Set navLinks value 55 | context.locals.starlightUtils.navLinks = [...navLinks[0].entries]; 56 | // Set the filtered sidebar 57 | context.locals.starlightRoute.sidebar = filteredSidebar; 58 | } 59 | 60 | // Logic for multi-sidebar 61 | if (config?.multiSidebar) { 62 | // All entries must be group types 63 | const data = context.locals.starlightRoute.sidebar.map((entry) => { 64 | if (entry.type != "group") { 65 | throw new AstroError( 66 | `\`${entry.label}\` cannot be used with multi-sidebar. 67 | 68 | Each top-level \`sidebar\` item in the Starlight config must be either a group or autogenerated. 69 | 70 | See https://starlight.astro.build/guides/sidebar/#groups and https://starlight.astro.build/guides/sidebar/#autogenerated-groups for more details.` 71 | ); 72 | } 73 | 74 | // Recursively check if a group of sidebar entries contains the current page 75 | const findIfIsCurrent = ( 76 | entry: StarlightRouteData["sidebar"][number] 77 | ): boolean => { 78 | if (entry.type === "link") { 79 | return entry.isCurrent; 80 | } 81 | return entry.entries.some((item) => findIfIsCurrent(item)); 82 | }; 83 | 84 | const isCurrentSidebar = findIfIsCurrent(entry); 85 | 86 | return { 87 | isCurrentSidebar, 88 | sidebar: [...entry.entries], 89 | label: entry, 90 | }; 91 | }); 92 | // If the current page being built isn't contained in a sidebar, then render the first sidebar 93 | if (data[0] && !data.some(({ isCurrentSidebar }) => isCurrentSidebar)) { 94 | data[0].isCurrentSidebar = true; 95 | } 96 | context.locals.starlightUtils.multiSidebar = data; 97 | } 98 | }); 99 | -------------------------------------------------------------------------------- /packages/starlight-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lorenzo_lewis/starlight-utils", 3 | "author": "Lorenzo Lewis", 4 | "version": "0.3.2", 5 | "license": "MIT", 6 | "description": "Utilities to use with your 🌟 Starlight site.", 7 | "type": "module", 8 | "exports": { 9 | ".": "./index.ts", 10 | "./components": "./components/index.ts", 11 | "./middleware": "./middleware.ts", 12 | "./components/SiteTitle.astro": "./components/SiteTitle.astro", 13 | "./components/Sidebar.astro": "./components/Sidebar.astro" 14 | }, 15 | "scripts": {}, 16 | "devDependencies": { 17 | "@astrojs/starlight": "^0.32.5", 18 | "astro": "^5.6.1" 19 | }, 20 | "peerDependencies": { 21 | "@astrojs/starlight": ">=0.32.0", 22 | "astro": ">=5" 23 | }, 24 | "dependencies": { 25 | "astro-integration-kit": "^0.18.0" 26 | }, 27 | "keywords": [ 28 | "starlight", 29 | "plugin", 30 | "utils", 31 | "astro", 32 | "astro-component", 33 | "withastro" 34 | ], 35 | "homepage": "https://starlight-utils.pages.dev", 36 | "repository": { 37 | "type": "git", 38 | "url": "https://github.com/lorenzolewis/starlight-utils.git", 39 | "directory": "packages/starlight-utils" 40 | }, 41 | "bugs": "https://github.com/lorenzolewis/starlight-utils/issues" 42 | } 43 | -------------------------------------------------------------------------------- /packages/starlight-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/starlight-utils/virtual.d.ts: -------------------------------------------------------------------------------- 1 | declare module "virtual:starlight-utils/config" { 2 | const Config: import("./config").StarlightUtilsConfig; 3 | export default Config; 4 | } 5 | 6 | declare namespace App { 7 | type StarlightLocals = import("@astrojs/starlight").StarlightLocals; 8 | // Define the `locals.t` object in the context of a plugin. 9 | interface Locals extends StarlightLocals { 10 | starlightUtils: { 11 | navLinks?: Array; 12 | multiSidebar?: Array<{ 13 | isCurrentSidebar: boolean; 14 | sidebar: Array; 15 | label: StarlightLocals["sidebar"][number]; 16 | }>; 17 | // Array; 18 | }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "docs" 3 | - "packages/**/*" 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "allowUnreachableCode": false, 6 | "allowUnusedLabels": false, 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "incremental": true, 10 | "jsx": "react-jsx", 11 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 12 | "module": "ESNext", 13 | "moduleResolution": "bundler", 14 | "noFallthroughCasesInSwitch": true, 15 | "noImplicitOverride": true, 16 | "noImplicitReturns": true, 17 | "noPropertyAccessFromIndexSignature": true, 18 | "noUncheckedIndexedAccess": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "resolveJsonModule": true, 22 | "skipLibCheck": true, 23 | "strict": true, 24 | "target": "ESNext", 25 | "useDefineForClassFields": true, 26 | "verbatimModuleSyntax": true 27 | } 28 | } 29 | --------------------------------------------------------------------------------