Contact Us

UI Components

DOC-00015 reference implementor, developer

The UI components layer provides navigation aids, empty-state feedback, and content-relationship widgets that sit between primitives and full section compositions. This page documents the five UI components introduced in work package C6. All components are CORE-OWNED, consume semantic tokens (--st-*), and render no markup when their content conditions are not met.

Who this is for

  • Implementors placing breadcrumbs, pagination, or related-content blocks in page templates
  • Developers extending or overriding UI component behavior

File: src/core/components/ui/Breadcrumbs.astro

Explicit per-route breadcrumb navigation with CSS-only separators and aria-current="page" on the last item.

Props

PropTypeRequiredDefaultNotes
itemsArray<{ label: string; href?: string }>yesOrdered segments. Last item has no href (current page).
classstringnoAdditional CSS classes

Usage

---
import Breadcrumbs from "@core/components/ui/Breadcrumbs.astro";

const breadcrumbItems = [
  { label: "Home", href: "/" },
  { label: "Articles", href: "/articles/" },
  { label: "My Article Title" },
];
---

<Breadcrumbs items={breadcrumbItems} />

Behavior

  • Renders <nav aria-label="Breadcrumb"> wrapping an <ol>.
  • Items with href render as <a>. The last item renders as <span aria-current="page">.
  • Visual separators (/) via CSS ::before pseudo-elements — not in the DOM.
  • Renders nothing when items is empty.

Accessibility

  • aria-label="Breadcrumb" on the <nav> element.
  • aria-current="page" on the last item.
  • Focus ring on all links via --st-color-focus-ring.

EmptyState

File: src/core/components/ui/EmptyState.astro

Standardized empty-state pattern with optional icon and “Go Back” CTA.

Props

PropTypeRequiredDefaultNotes
messagestringyesEmpty-state text
iconstringnoIcon name resolved by the Icon primitive
ctaLabelstringno"Go Back"CTA button text
ctaHrefstringno"/"Fallback URL when JS is unavailable
showCtabooleannotrueSuppress CTA when false
classstringnoAdditional CSS classes

Usage

---
import EmptyState from "@core/components/ui/EmptyState.astro";
---

<EmptyState message="No articles found." icon="messages-question" />

<!-- Without CTA -->
<EmptyState message="Nothing here yet." showCta={false} />

Behavior

  • Centered layout with optional icon (rendered via the Icon primitive), message, and CTA.
  • CTA renders as a Button (secondary, sm) with data-back attribute.
  • An inline <script> attaches a click listener that calls history.back(). Without JS, the button navigates to ctaHref.
  • Renders nothing when message is falsy.

Accessibility

  • Icon container has no semantic role (decorative).
  • CTA is a visible, focusable button with clear label text.

Pagination

File: src/core/components/ui/Pagination.astro

Generalized page-based pagination with clean page-1 URLs.

Props

PropTypeRequiredDefaultNotes
baseHrefstringyesBase path for page URLs (e.g., "/articles")
currentPagenumberyesActive page number
totalPagesnumberyesTotal page count
labelstringno"Pagination"aria-label for the nav element
classstringnoAdditional CSS classes

Usage

---
import Pagination from "@core/components/ui/Pagination.astro";
---

<Pagination
  baseHref="/articles"
  currentPage={1}
  totalPages={5}
  label="Article pages"
/>

Behavior

  • Renders <nav aria-label={label}> with Previous/Next links and numbered page links.
  • aria-current="page" on the active page number.
  • URL construction: page 1 → ${baseHref}/, pages 2+ → ${baseHref}/page/${n}/. Trailing slashes on baseHref are normalized.
  • Previous link hidden on page 1; Next link hidden on last page.
  • Renders nothing when totalPages <= 1.
  • Page links are centered via justify-content: center.

Accessibility

  • aria-current="page" on the active page link.
  • Focus ring on all links via --st-color-focus-ring.

PrevNextNav

File: src/core/components/ui/PrevNextNav.astro

Previous/next navigation for ordered collection entries.

Props

PropTypeRequiredDefaultNotes
prev{ label: string; href: string }noPrevious item
next{ label: string; href: string }noNext item
classstringnoAdditional CSS classes

Usage

---
import PrevNextNav from "@core/components/ui/PrevNextNav.astro";
---

<PrevNextNav
  prev={{ label: "Getting Started", href: "/theme-docs/getting-started/" }}
  next={{ label: "Advanced Usage", href: "/theme-docs/advanced-usage/" }}
/>

Behavior

  • Renders <nav aria-label="Adjacent pages"> with a two-column grid layout.
  • Previous link aligned left with indicator; next link aligned right with indicator.
  • Directional indicators are aria-hidden="true".
  • Renders nothing when both prev and next are undefined.

Accessibility

  • aria-label="Adjacent pages" on the <nav> element.
  • Focus ring on all links via --st-color-focus-ring.

RelatedContent

File: src/core/components/ui/RelatedContent.astro

Related content section with heading and link list.

Props

PropTypeRequiredDefaultNotes
itemsArray<{ label: string; href: string }>noResolved related items
headingstringno"Related Content"Section heading text
classstringnoAdditional CSS classes

Usage

---
import RelatedContent from "@core/components/ui/RelatedContent.astro";
---

<RelatedContent
  items={[
    { label: "Design Tokens", href: "/theme-docs/design-tokens/" },
    { label: "Layouts", href: "/theme-docs/layouts/" },
  ]}
  heading="Related Docs"
/>

Behavior

  • Renders <section aria-labelledby="related-content-heading"> with a Heading (level={2}) and a <ul> list.
  • Renders no markup at all when items is empty or undefined — no section, no heading, nothing in the DOM.

Accessibility

  • aria-labelledby connects the section to its heading.
  • Focus ring on all links via --st-color-focus-ring.

Token Usage

All five components consume semantic tokens (--st-*) for colors, borders, and spacing. No raw color values are used. Key token families:

  • Links: --st-color-link, --st-color-link-hover
  • Text: --st-color-text-default, --st-color-text-muted
  • Surfaces: --st-color-surface-soft, --st-color-surface-strong
  • Borders: --st-color-border-default
  • Focus: --st-color-focus-ring with --pt-focus-ring-width and --pt-focus-ring-offset
  • Spacing: --pt-space-* primitives

Modal and overlay components (dialogs, drawers, lightboxes, popovers) are not yet implemented as standalone components but the following behavioral requirements apply to all future implementations and any custom overlays built with this theme.

Focus Management

  • Focus trapping (REQ-00050): When a modal opens, keyboard focus must be constrained within it. Tab and Shift+Tab must not reach elements behind the overlay. Use native <dialog> with showModal() which provides this natively, or vanilla JS focus trapping.
  • Focus restoration (REQ-00053): When a modal or transient overlay closes, focus must return to the element that triggered it. Store a reference to the trigger element before opening and call .focus() on dismissal.

Scroll Locking

  • Scroll lock (REQ-00054): While a modal is active, background page scroll must be suppressed. Apply overflow: hidden to <body> (or the scroll container) on open and restore it on close. Account for scrollbar width to prevent layout shift.

Implementation Pattern

---
// Example: minimal accessible modal pattern using native <dialog>
---

<!-- Trigger -->
<button id="open-modal" data-action="open-modal">Open</button>

<!-- Modal -->
<dialog id="my-modal" aria-labelledby="modal-title">
  <h2 id="modal-title">Modal Title</h2>
  <button data-action="close-modal">Close</button>
</dialog>

Native <dialog> with showModal() provides focus trapping and scroll lock automatically. For non-dialog overlays, vanilla JS focus trapping handles keyboard containment.

REQ-00048 implemented A Breadcrumbs component shall be provided.
REQ-00050 normative Modal/lightbox components shall implement focus trapping and restoration.
REQ-00053 normative Transient interactive UI shall restore focus upon dismissal.
REQ-00054 normative Modal and overlay components shall define scroll locking behavior while active.
REQ-00055 implemented A Back to Top control shall be provided.
REQ-00073 implemented Standardized empty-state UI patterns shall be defined.
REQ-00181 implemented The system shall provide Similar/Related Items content blocks for content pages.
REQ-00230 implemented Client-side filtering and pagination on listing pages shall synchronize state with URL query parameters, enabling shareable and bookmarkable filtered views with browser back/forward navigation support.
REQ-00254 implemented Article detail pages shall provide previous/next navigation links to adjacent articles in the collection, ordered by publication date.
REQ-00255 implemented Content detail pages shall support a RelatedContent section displaying links to related pages or articles, driven by frontmatter configuration (relatedDocs field).

Search

Search across pages and articles. Use arrow keys to navigate results.

Search across pages and articles.

Loading search...

Search is unavailable. Please try again later.

    No results for ""

    Try different keywords or fewer words.