helia-ui
@ambiqai/helia-ui is the shared design system behind the HELIA developer
surfaces: the tokens, the Astro parts, the shadcn React components, and the
Starlight theme. It ships as source with no build step, so a consuming site’s
bundler reads the stylesheets and components directly.
This site is one of its consumers. Every page here reaches the package through the export map and the Starlight plugin, never by relative path, so what you read on a page is what an unrelated site gets.
Install
Section titled “Install”npm install @ambiqai/helia-uiBecause the package ships source rather than a bundle, the consuming site supplies the toolchain. These are peer dependencies and the site needs the same majors:
| Peer | Range |
|---|---|
astro | ^7.0.2 |
@astrojs/starlight | ^0.41.5 |
react | ^19 |
react-dom | ^19 |
tailwindcss | ^4.3.3 |
A site wires the package in three places: the Starlight plugin in
astro.config.mjs, its own Tailwind entry, and the React integration if it
uses the React lane.
import { heliaStarlight } from '@ambiqai/helia-ui/starlight';
export default defineConfig({ integrations: [ starlight({ customCss: ['./src/styles/tailwind.css'], plugins: [heliaStarlight({ footer: { links, tagline } })], }), react(), ], vite: { plugins: [tailwindcss()] },});@import '@ambiqai/helia-ui/starlight-tailwind.css';
@source '../content/**/*.{md,mdx}';@source '../components/**/*.{astro,tsx}';@source '../../node_modules/@ambiqai/helia-ui/astro/**/*.astro';The export map
Section titled “The export map”| Export | What it is |
|---|---|
./tokens.css | Primitives for both themes, and the mapping onto Starlight’s --sl-* variables |
./semantic.css | Spacing, radius, type, weight, leading, ink, surfaces, tones |
./recipes.css | helia-surface, chip, eyebrow, button, card, badge, media, and the focus and hover recipes |
./starlight.css | Unlayered chrome overrides: sidebar, header, search, table of contents, steps, skinned built-ins |
./tailwind.css | Layer order and the @theme mapping, with no Starlight dependency |
./starlight-tailwind.css | ./tailwind.css with @astrojs/starlight-tailwind in front; what a Starlight site imports |
./shadcn.css | The shadcn variable bridge, imported by ./tailwind.css |
./astro/* | The Astro parts, one file per part |
./react/* | The generated shadcn components, one file per component |
./starlight | The heliaStarlight() plugin |
./starlight/* | The shell components the plugin installs |
The four stylesheets the plugin injects are unlayered on purpose. Unlayered rules beat every cascade layer, so the token sheets stay the source of truth no matter what the Starlight Tailwind compat package wires up below them. See the Starlight plugin for the injection order.
Three lanes
Section titled “Three lanes”The package offers three ways to put something on a page, and the choice is not a matter of taste.
Astro parts (./astro/*) are the default. Surface, the card family, Badge,
Chip, Button, Media, the carousel: static presentation with zero JavaScript, no
React at build time, inline in MDX. Reach for these first.
React components (./react/*) are the generated shadcn layer, for behavior
a browser cannot do alone: focus trapping, roving focus, filtered lists,
popovers that flip, sorting and paging, charts. Do not re-base an Astro part on
shadcn to get a class name.
Stylesheets (./tokens.css and the rest) carry the vocabulary both lanes
compile against, plus the Tailwind @theme mapping so utilities and parts use
one spacing and color scale. @theme inline keeps a generated utility
referencing the token directly rather than a value snapshotted at :root,
which is what lets utilities follow the theme toggle.
Templates
Section titled “Templates”Two starters ship in the repository rather than in the published tarball, so a new surface begins wired up rather than assembled by hand.
Docs sites (templates/product-docs) is
a Starlight site with the plugin, the Tailwind entry and KaTeX already in place.
Web apps (templates/web-app) is a Vite,
React and TypeScript application for live hardware and streaming data: a worker
that produces samples, a ring buffer that publishes one frame at a time, a
Recharts trace, and the Source interface a device driver implements. Docs and
marketing pages ship no JavaScript; an app’s bar is responsiveness under
streaming instead.
The component contract
Section titled “The component contract”Every part in ./astro/* holds to four rules. They are what makes the package
publishable rather than one site’s own components.
- Composition over configuration. More than about six props means a
composition wearing a primitive’s name. Regions are children or named slots,
never a
title/description/actionprop bundle. - Data enters through props and children only. No part imports data, and no part knows what a product, a demo, or a status is.
- Actions are handed in as children. A card never decides where it links.
- No domain vocabularies. Status names, brand marks, and product accents
are the consumer’s. The package exposes
Badge toneand--accent, and the consumer decides what “Released” looks like.
Where a part takes a spacing prop it names a step ('4', 'none') rather than
a length, so the value resolves through the same scale as every utility.
The island rule
Section titled “The island rule”React context does not cross Astro’s MDX component boundary. Astro gives each
component in an .mdx file its own React root and passes children through as
serialized HTML, so a compound component assembled in a page throws at build
with `TabsTrigger` must be used within `Tabs`. That covers Tabs, Dialog,
Sheet, Select, Combobox, Accordion, Command, Popover, DropdownMenu, and most of
the library.