EN
guide

Using components

How the pre-installed atoms work — props and variants, the cn class helper, compound families, and reusing them in another project.

Last updated

Both templates ship the full set of base components pre-installed in src/components/ui/ — copied from the astro-ignite registry, owned by your repo. There’s no install step and no runtime dependency; you import them like any local file and edit them freely.

---
import Button from '@/components/ui/button.astro';
---

<Button variant="outline" size="sm" href="/contact">Get in touch</Button>

Browse every atom rendered live, with props and source, under Components.

Props & variants

Atoms are typed Astro components. They follow a consistent shape:

  • Variant + size props where it makes sense. Button takes variant (default · secondary · outline · ghost · destructive · link) and size (sm · md · lg · icon).
  • Polymorphic as-by-href. Pass href and the component renders an <a>; omit it and you get a <button>. The correct native attributes are typed for each case.
  • A class passthrough. Anything you pass is merged onto the base classes (see cn below), so you can extend without forking.
  • ...rest spread. Remaining attributes (type, aria-*, data-*, …) land on the underlying element.

The cn helper

Every atom merges classes with cn from src/lib/cn.ts. It flattens strings, arrays, and conditional objects into one class string:

example.astro
import { cn } from '@/lib/cn';

cn('px-3', 'py-2', isActive && 'bg-surface-2', { 'opacity-50': disabled });
// → "px-3 py-2 bg-surface-2"  (falsy values dropped)

Compound families

Five families ship as multiple parts — one file per part — so you compose the structure yourself. Import the parts you need:

card-example.astro
---
import Card from '@/components/ui/card/card.astro';
import CardHeader from '@/components/ui/card/card-header.astro';
import CardTitle from '@/components/ui/card/card-title.astro';
import CardDescription from '@/components/ui/card/card-description.astro';
import CardContent from '@/components/ui/card/card-content.astro';
---

<Card>
<CardHeader>
  <CardTitle>Plan</CardTitle>
  <CardDescription>Everything you need to launch.</CardDescription>
</CardHeader>
<CardContent>…</CardContent>
</Card>

The families and their parts:

FamilyParts
cardcard, card-header, card-title, card-description, card-content, card-footer
tabstabs, tabs-list, tabs-trigger, tabs-content
accordionaccordion, accordion-item
dialogdialog, dialog-title, dialog-description
dropdown-menudropdown-menu, dropdown-menu-item

Interactive ones use native primitives — <dialog> for dialog, the popover API for dropdown-menu, <details name> for accordion, and the <ai-tabs> custom element for tabs. No React, no Radix, no framework runtime.

Toasts

Toasts are imperative. Render <Toaster /> once (the layouts already do), then fire one from anywhere with the helper:

example.ts
import { toast } from '@/lib/toast';

toast('Saved', { description: 'Your changes are live.' });

It dispatches a window event the <Toaster /> listens for.

Reusing a component elsewhere

These atoms aren’t published as an importable library — you own the copies in your project. To use one in a different project, copy the file (and its cn dependency) from the registry source at packages/registry/base/. Compound families bring their whole folder.