@rgglez/astro-collapsiblecode
v0.1.1
Published
Astro component that highlights a code string with Shiki on the server and shows it in a collapsible panel toggled by your own trigger element.
Maintainers
Readme
astro-collapsiblecode
astro-collapsiblecode highlights a code string with Shiki on the server and shows it in a collapsible panel. The trigger is yours: put a button, a link or any element in the default slot and the component wires it up.
One use case is a blog post (Markdown or MDX) where a live demo is followed by a "View code" toggle showing the source of that demo.
Installation
npm install @rgglez/astro-collapsiblecode shikishiki is a peer dependency, install it in your project.
Usage
import CollapsibleCode from "@rgglez/astro-collapsiblecode";The first element of the slot becomes the trigger:
<CollapsibleCode code={source}>
<button type="button">View code</button>
</CollapsibleCode>Any element works. Links get their default action prevented, and non-interactive
elements get role="button", tabindex="0" and Enter/Space handling:
<CollapsibleCode code={source} lang="python">
<a href="#">Show the source</a>
</CollapsibleCode>If the trigger is not the first element of the slot, mark it explicitly:
<CollapsibleCode code={source}>
<p>Curious? <button type="button" data-code-trigger>View code</button></p>
</CollapsibleCode>Usage in .mdx files
Keeping the code in a separate .ts file lets you run it and list it from the
same string:
import CollapsibleCode from "@rgglez/astro-collapsiblecode";
import { demo } from "@/data/demos";
<CollapsibleCode code={demo}>
<button type="button">View code</button>
</CollapsibleCode>Props
| Prop | Type | Default | Description |
|----------|-------------------------------------|------------------------------------------------|------------------------------------------|
| code | string | — | Code to highlight. Required |
| lang | BundledLanguage | "javascript" | Shiki language id |
| themes | { light: Theme; dark: Theme } | { light: "github-light", dark: "dracula" } | Shiki themes, emitted as CSS variables |
| open | boolean | false | Render the panel already expanded |
| class | string | "" | Extra classes for the wrapper div |
Languages and themes are loaded lazily from the Shiki bundle, on a single highlighter instance shared by every render.
Styling hooks
The component ships almost no CSS (just margins), so it fits any design system.
| Hook | Where | When |
|----------------------------------------|------------------|----------------------------|
| .astro-collapsible-code | wrapper | always |
| [data-expanded] | wrapper | panel open |
| aria-expanded="true" | trigger | panel open |
| [data-code-panel] | panel | always |
For example, to rotate a caret inside the trigger:
[aria-expanded="true"] [data-code-icon] {
transform: rotate(90deg);
}The highlighted <pre> carries the astro-code class as well, so it inherits
the styling Astro applies to its own code blocks.
Notes
- This is an Astro component (
.astro). It cannot be imported into React, Vue, Svelte or other framework components. Use it from.astroor.mdxfiles. - Highlighting uses Shiki's JavaScript regex engine instead of the oniguruma WASM one, so it also works on Cloudflare Workers and other runtimes that disallow WebAssembly compilation.
- Without JavaScript the panel stays collapsed. Pass
openif the code must be visible in that case.
Development
| Target | Description |
|--------|-------------|
| make tags | List git tags sorted by semver (descending) |
| make patch | Bump PATCH version in package.json, commit, tag, and push |
| make publish | Publish current version to npm |
Typical release flow: make patch → make publish.
License
Copyright (C) 2026 Rodolfo González González.
Licensed under the Apache v2.0 license. Read the LICENSE file.
