No results

For AI agents and crawlers: a structured index of this site is available at https://danny.is/llms.txt.

UI Components

Site styleguide

The components on this page are the reusable building blocks I use outside of my content files.

CommandPalette

The global command palette — a native modal <dialog> built on the WAI-ARIA combobox pattern. It offers baked-in commands and navigation, plus live full-text search across the site (Pagefind). It's dropped into every layout (a separate concern from the header nav), so it's already on this page: press ⌘K / Ctrl K, or use the button below. It takes no props — the commands and navigation are defined in the component itself.

The dialog exposes a stable id of command-palette, so any element can open it with zero JavaScript via the Invoker Commands API:

<button type="button" command="show-modal" commandfor="command-palette">
Search…
</button>

Pill

Small label badges for tags, categories, status indicators and the like. By default a Pill is a subtle outline but you can pass a color and it fills, deriving a readable text colour from the background with color-mix().

PropTypeDefaultDescription
textstringrequiredThe label text.
colorstringFill colour. When set, the pill switches from outline to filled.
textColorstringOverride the auto-derived text colour.
iconstringAn astro-icon name (e.g. heroicons:check-circle-20-solid) shown before the text.
titlestringNative hover tooltip; also sets cursor: help.

Default

<Pill text="Default" />
Default

Custom colour

<Pill text="Coral" color="var(--color-coral)" />
<Pill text="Blue" color="var(--color-blue)" />
<Pill text="Green" color="var(--color-green)" />
<Pill text="Purple" color="var(--color-purple)" />
<Pill text="Orange" color="var(--color-orange)" />
<Pill text="Custom Text" color="var(--color-charcoal)" textColor="var(--color-coral)" />

CoralBlueGreenPurpleOrangeCustom Text

Icon & tooltip

Pass an icon (any astro-icon name) for a leading glyph, and a title for a native hover tooltip (the cursor becomes help). Both drive the status pills on/making.

<Pill text="Finished" icon="heroicons:check-circle-20-solid" title="Done, but not necessarily kept up to date." />
<Pill text="In active development" color="var(--color-blue)" icon="heroicons:code-bracket-20-solid" title="I'm working on this right now." />

FinishedIn active development

Spinner

An animated loading indicator drawn in the accent colour. The size prop accepts any CSS length.

PropTypeDefaultDescription
sizestring'5rem'Width and height as a CSS length.
<Spinner size="1.5rem" />
<Spinner size="2.5rem" />
<Spinner size="4rem" />

ThemeToggle

A three-option segmented control (light / auto / dark) with a sliding thumb. CSS handles all the visuals via :has(); the script only tracks state and talks to the global theme API. An optional class prop is forwarded to the wrapper.

<ThemeToggle />

MarkdownContentActions

The copy / view / share links shown below content for grabbing the page as markdown. The share link only appears on devices that support the Web Share API.

PropTypeDefaultDescription
markdownUrlstringrequiredURL of the .md source to copy and link to.
disableSharebooleanfalseHide the share link entirely, even where the Web Share API exists.
<MarkdownContentActions markdownUrl="/example.md" />
copy / view as markdown

FormattedDate

Renders a Date as a machine-readable <time> element with a human-friendly label (e.g. Jun 12, 2025). Used for publication dates across the site.

PropTypeDefaultDescription
dateDaterequiredThe date to render.
itempropstringOptional microdata itemprop attribute.
<FormattedDate date={new Date('2025-06-12')} />
Back to top