Core
Import from astro-pigment/components:
Layout
Main page shell. Renders sticky header with navigation, both sidebar slots, content area, footer, and code copy buttons. Includes ThemeToggle, ThemeScript, CodeBlockWrapper, and Search (when search: true, the default) automatically.
---
import { Layout } from "astro-pigment/components";
---
<Layout
title="Page Title"
navLinks={[
{ href: "", label: "Home" },
{ href: "api", label: "API" },
]}
>
<MyLogo slot="logo" />
<meta slot="head-extra" name="robots" content="noindex" />
<TableOfContents slot="sidebar-right" headings={headings} />
<article class="prose">
<slot />
</article>
<span slot="footer-extra">& Additional Credit</span>
</Layout>
Props: title (required), navLinks? (array of { href, label, attrs? }, where attrs is spread onto the rendered <a>), alternate? (array of { type, title, href } — renders <link rel="alternate"> tags in <head> plus a visually-hidden hint at the top of main content when a text/markdown entry is present).
Slots: default, sidebar, sidebar-right, logo, head-extra, footer-extra. Each sidebar is rendered only when its slot produces content, so a conditionally-passed sidebar ({cond && <Toc slot="sidebar" />}) collapses the column when the condition is false.
Below the laptop breakpoint the rails collapse into popovers. Layout scans the rendered sidebars for those popovers and renders their triggers as one floating ButtonGroup in the bottom-right corner — a hamburger for the menu, a dotted-list icon for the table of contents, or just the one that exists.
TableOfContents
Scroll-spy outline plus its mobile popover, both rendered from a single component. Goes in the sidebar-right slot — the outline owns the right rail, and the left one is reserved for navigation between pages. Layout supplies the popover’s floating trigger. It lists h2 and h3 headings only. A page with none of them keeps the right column empty rather than dropping it, so the content column does not shift between pages that share a menu, and it gets no mobile outline button.
---
import { TableOfContents } from "astro-pigment/components";
const headings = await getHeadings(); // from Astro content render
---
<TableOfContents slot="sidebar-right" headings={headings} />
Default itemsSelector is "#content :is(h2, h3)[id]", targeting the id="content" article injected by the default page. Pass a custom selector if your layout differs:
<TableOfContents
slot="sidebar-right"
headings={headings}
itemsSelector="#my-content :is(h2, h3)[id]"
/>
Button
Styled <button> with an optional square prop for icon-only buttons.
---
import { Button } from "astro-pigment/components";
---
<Button>Click me</Button>
<Button square aria-label="Settings">
<Icon name="hamburger" />
</Button>
ButtonGroup
Joins adjacent Buttons into one segmented control: shared borders collapse and only the outer corners stay rounded. Pass aria-label to name the group.
---
import { Button, ButtonGroup, Icon } from "astro-pigment/components";
---
<ButtonGroup aria-label="Page actions">
<Button square aria-label="Copy page">
<Icon name="copy" />
</Button>
<Button square aria-label="View as markdown">
<Icon name="markdown" />
</Button>
</ButtonGroup>
Icon
Built-in SVG icons: check, chevron-down, chevron-left, close, copy, github, hamburger, markdown, search, toc, x. Use name="custom" with a slot for your own SVG.
---
import { Icon } from "astro-pigment/components";
---
<Icon name="github" />
<Icon name="github" size={32} />
<Icon name="custom" label="Mastodon">
<svg viewBox="0 0 24 24">
<path d="..."></path>
</svg>
</Icon>
Footer
Site footer with license, GitHub, and author links. Read from the virtual config automatically. Renders credits from config as & Name links after the author. Has an extra slot for additional content beyond config-driven credits. Included in Layout by default.
---
import { Footer } from "astro-pigment/components";
---
<Footer />
ThemeToggle
Three-state theme switcher (auto/light/dark) with sun/moon/split icons.
---
import { ThemeToggle } from "astro-pigment/components";
---
<ThemeToggle />
ThemeScript
Inline script that prevents FOUC by setting data-theme before first paint. Included in Layout automatically.
ThemePicker
Floating hue + saturation picker for dialling in theme colors interactively. Layout renders it when the integration’s themePicker: true is set, so you only import it directly in a custom layout. Closing it copies { hue, saturation } to the clipboard — put those in theme config and drop the flag. ThemePickerScript is the inline script applying the picked values before paint; Layout includes it alongside the picker.
---
import { ThemePicker } from "astro-pigment/components";
---
<ThemePicker />
CodeBlockWrapper
Adds copy-to-clipboard buttons to all .prose pre blocks. Included in Layout automatically.
InstallPackage
Tabbed package manager switcher (pnpm/npm/yarn/bun). Selection persists to localStorage.
---
import { InstallPackage } from "astro-pigment/components";
---
<InstallPackage pkg="nanotags nanostores" />
<InstallPackage pkg="typescript" dev />
AgentSkillsInstall / AgentSkillsIndex
AgentSkillsInstall shows the command that installs the project’s Agent Skills, per scope, agent and install method; skill="<name>" narrows it to one skill. AgentSkillsIndex renders an “Available Skills” heading and lists the skills, each with its own install panel. Both need the agentSkills integration option; see Agent skills.
import { AgentSkillsIndex, AgentSkillsInstall } from "astro-pigment/components";
<AgentSkillsInstall />
<AgentSkillsInstall skill="lint" />
<AgentSkillsIndex />
PrevNextNav
Previous/next page navigation links.
---
import { PrevNextNav } from "astro-pigment/components";
---
<PrevNextNav
prev={{ title: "Getting Started", href: "/getting-started" }}
next={{ title: "API Reference", href: "/api" }}
/>
PageHeading
Heading row with an optional “view as markdown” icon link. Omit href to hide the icon on pages without a .md twin.
---
import { PageHeading } from "astro-pigment/components";
import { getMarkdownAlternate } from "astro-pigment/utils/urls";
const alt = getMarkdownAlternate("api"); // { type, title, href: "/api.md" }
---
<PageHeading title="API Reference" href={alt.href} />
Props: title (required), href?, back? ({ href, label }), class?.
Pair with Layout’s alternate prop so the same URL is announced in <head> and (visually-hidden) at the top of main content:
---
import { Layout, PageHeading } from "astro-pigment/components";
import { getMarkdownAlternate } from "astro-pigment/utils/urls";
const alt = getMarkdownAlternate("api");
---
<Layout title="API Reference" alternate={[alt]}>
<PageHeading title="API Reference" href={alt.href} />
<article class="prose">
<slot />
</article>
</Layout>
ThemeImage
A pair of images where only the one matching the current color scheme is shown, e.g. screenshots taken in light and dark mode. Follows the theme toggle, not only the OS preference. Both images go through astro:assets, so they are optimized and keep their width and height.
---
import { ThemeImage } from "astro-pigment/components";
import screenshotLight from "../assets/screenshot-light.png";
import screenshotDark from "../assets/screenshot-dark.png";
---
<ThemeImage light={screenshotLight} dark={screenshotDark} alt="The settings panel" />
Props: light (required), dark (required), alt (required), class?.
Playground
Import from astro-pigment/components/playground:
CodeEditor
CodeMirror 6 editor with Catppuccin themes that sync with dark mode. Supports JavaScript, HTML, CSS, and JSON.
---
import { CodeEditor } from "astro-pigment/components/playground";
---
<CodeEditor lang="javascript" />
LivePreview
Sandboxed iframe execution. Captures console output and posts it back to the parent.
---
import { LivePreview } from "astro-pigment/components/playground";
---
<LivePreview />
CodeExample
Full interactive playground: tabbed editor + live preview + collapsible logs.
---
import { CodeExample } from "astro-pigment/components/playground";
const files = [
{ name: "index.html", type: "html", lang: "html", content: "<h1>Hello</h1>" },
{ name: "app.js", type: "javascript", lang: "javascript", content: "console.log('hi')" },
];
---
<CodeExample files={files} />
CodePanels
Multiple code snippets with Shiki highlighting and tab switching.
---
import { CodePanels } from "astro-pigment/components/playground";
const items = [
{ id: "pnpm", content: "pnpm add my-lib" },
{ id: "npm", content: "npm install my-lib" },
];
---
<CodePanels items={items} defaultValue="pnpm" lang="shellscript" />
ResizablePanes / ResizablePane
Draggable split-pane layout with keyboard support. Supports horizontal and vertical directions.
---
import { ResizablePanes, ResizablePane } from "astro-pigment/components/playground";
---
<ResizablePanes direction="horizontal">
<ResizablePane>Left content</ResizablePane>
<ResizablePane>Right content</ResizablePane>
</ResizablePanes>
CollapsiblePane
Expandable/collapsible section with an optional resize handle.
---
import { CollapsiblePane } from "astro-pigment/components/playground";
---
<CollapsiblePane expanded expandedSize={30}>
<span slot="header">Details</span>
<p>Collapsible content here</p>
</CollapsiblePane>
Tabs / Tab
Accessible tabs with roving focus, scroll arrows for overflow, and keyboard navigation.
---
import { Tabs, Tab } from "astro-pigment/components/playground";
---
<Tabs value="one">
<Tab value="one">First</Tab>
<Tab value="two">Second</Tab>
<Tab value="three">Third</Tab>
</Tabs>