Skip to main content
astrocraft-ui/ components · 101

Timeline

Free · MIT

Headless, accessible, and styled entirely through the attribute surface below — bring your own CSS system, or start from the reference theme.

Install

Without a flag you get no styling at all — plain HTML carrying the attribute surface below. --theme copies the same theme in two dialects;--bridge lumos re-points either one onto Lumos for Astro's tokens (it needs a theme to re-point, and Lumos itself, already in your project).

Unstyled — behavior only, you write the CSS

Install command
npx astrocraft-ui add display/timeline

Plain-CSS theme — no build step

Install command
npx astrocraft-ui add display/timeline --theme css

Tailwind theme — needs Tailwind v4

Install command
npx astrocraft-ui add display/timeline --theme tailwind

Plain-CSS theme, re-pointed onto Lumos tokens

Install command
npx astrocraft-ui add display/timeline --theme css --bridge lumos

Tailwind theme, re-pointed onto Lumos tokens

Install command
npx astrocraft-ui add display/timeline --theme tailwind --bridge lumos

Live demo

Timeline

A real <ol>, because the order is the meaning. The dot and the connector exist only so a theme has something to draw the rail on — delete every rule and you still have a numbered list of events.

  1. 0.1.0 — the port261 class strings became attributes.
  2. 0.2.0 — form wiringFormField and the grouping set.
  3. 0.3.0 — overlaysPopover, menus, Toast, Tour.
  4. 0.4.0 — navigationSidebar, Tree, Stepper, and this.

Attribute surface

With no class-merging machinery, these attributes are the whole extension point. State is a data-attribute or a native attribute; visibility is the hiddenattribute. Generated from source by pnpm slots.

ComponentSlotsVariantsRuntime stateNative state
`Timeline.astro``timeline``data-orientation`: `vertical` · `horizontal`——
`TimelineConnector.astro``timeline-connector`———
`TimelineDot.astro``timeline-dot`———
`TimelineItem.astro``timeline-item`———

Source

What the command copies — 5 files, alias-free so the copy lands standing alone. This is the whole component, shown without its comments; the files you install keep them, with the reasoning behind every rule.

src/components/ui/display/timeline/Timeline.astro
---
import type { HTMLAttributes } from "astro/types";

type Props = HTMLAttributes<"ol"> & { orientation?: "vertical" | "horizontal" };

const { orientation = "vertical", class: className, ...rest } = Astro.props;
---

<ol class={className} data-slot="timeline" data-orientation={orientation} {...rest}>
  <slot />
</ol>
src/components/ui/display/timeline/TimelineConnector.astro
---
import type { HTMLAttributes } from "astro/types";

type Props = HTMLAttributes<"span">;

const { class: className, ...rest } = Astro.props;
---

<span aria-hidden="true" class={className} data-slot="timeline-connector" {...rest}></span>
src/components/ui/display/timeline/TimelineDot.astro
---
import type { HTMLAttributes } from "astro/types";

type Props = HTMLAttributes<"span">;

const { class: className, ...rest } = Astro.props;
---

<span aria-hidden="true" class={className} data-slot="timeline-dot" {...rest}><slot /></span>
src/components/ui/display/timeline/TimelineItem.astro
---
import type { HTMLAttributes } from "astro/types";

type Props = HTMLAttributes<"li">;

const { class: className, ...rest } = Astro.props;
---

<li class={className} data-slot="timeline-item" {...rest}>
  <slot />
</li>
src/components/ui/display/timeline/index.ts
import Timeline from "./Timeline.astro";
import TimelineConnector from "./TimelineConnector.astro";
import TimelineDot from "./TimelineDot.astro";
import TimelineItem from "./TimelineItem.astro";

export { Timeline, TimelineConnector, TimelineDot, TimelineItem };
export default Timeline;

What you get

The component source, copied into your project by npx astrocraft-ui add display/timeline — no package dependency, no CSS to fight. Whatever the paid blocks compose, this is it.