--- ## JourneyTimeline Retrospective chronicle timeline (focus + context): an ordered record of what happened / where things stand — shipment tracking, audit trails, travel logs, billing runs. Exactly one focusable node is in focus and shows rich detail (`node` snippet); the rest stay quiet, compact context rows. The chronicle axis is first-class: per-node `meta` (time/date/actor) renders on a meta rail, connectors carry meaning (`solid | dashed | dotted`) and `segmentLabel` annotates the stretch between nodes. Rows extend without forking the layout: a `marker` snippet puts glyphs inside the status dots, a `trailing` snippet adds badges/help/actions beside each header (outside the button — safe for interactive elements), and the `attention` status flags optional-but-noteworthy rows. Detail placement is configurable: `detail="inline"` expands in place (vertical default); `detail="panel"` renders a stable readout beside (wide) or docked below (narrow) the rail — horizontal always uses the panel. Use `Stepper` for a prospective wizard/progress indicator and `Tab` for switching between peer views; JourneyTimeline is read-only observation of a sequence, not process control or navigation. **Import:** `import { JourneyTimeline } from '@urbicon-ui/blocks';` ### Examples ```svelte {#snippet node(item)}

Details for {item.title}…

{/snippet}
``` ```svelte track(id)}> {#snippet node(item)} {/snippet} ``` ### Variants - size: lg, md, sm (default: md) - orientation: horizontal, vertical (default: vertical) ### Api | Prop | Type | Required | Default | Description | | --- | --- | :---: | --- | --- | | items | `JourneyNode[]` | yes | | The ordered journey nodes. | | ...HTMLAttributes | `HTMLAttributes` | no | | HTML attributes (excluding: 'children') | | ...JourneyTimelineVariants | `VariantProps` | no | | Styling variants from JourneyTimelineVariants | | class | `string` | no | | Extra classes merged onto the root element. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | defaultFocusId | `string` | no | | Initial focused node id in uncontrolled mode. Ignored once `focusId` is bound. | | detail | `'inline' | 'panel'` | no | 'inline' (vertical) / 'panel' (horizontal) | Where the focused node's detail renders. `inline` expands in place inside the rail; `panel` renders a stable readout — beside the rail on wide viewports, docked to the viewport bottom on narrow ones. Horizontal orientation always uses the panel and ignores `inline` (DEV warning). | | focusId | `string` | no | | The focused node id. Supports `bind:focusId`. When omitted the component is uncontrolled and falls back to `defaultFocusId`, then the first `active` node, then the first focusable node. | | marker | `Snippet<[JourneyNode]>` | no | | Custom content *inside* each status dot — a glyph, count or icon. The dot keeps its status colour, shape and size contract (scale it via `slotClasses.marker`, e.g. `size-5`). Markers stay decorative (`aria-hidden`); the status is still announced through the hidden label. | | meta | `Snippet<[JourneyNode]>` | no | | Rich override for the meta rail — receives each `JourneyNode` and replaces the plain `item.meta` text (e.g. planned + actual time with a Badge). | | node | `Snippet<[JourneyNode]>` | no | | Renders the detail of the focused node. Receives the focused `JourneyNode`. | | onFocusChange | `(id: string) => void` | no | | Fires when the focused node changes (click or keyboard). | | orientation | `'vertical' | 'horizontal'` | no | 'vertical' | Layout direction. | | preset | `string` | no | | Apply a named preset registered via ``. Prefer this over `class` overrides when the requested look falls outside the semantic intent palette — presets keep hover/active/dark-mode logic coherent and make the custom look reusable across the project. | | size | `'sm' | 'md' | 'lg'` | no | 'md' | Marker + label scale. | | slotClasses | `Partial>` | no | | Per-slot class overrides. Slots: base | rail | node | metaColumn | meta | markerColumn | marker | connector | content | card | header | trigger | trailing | labelGroup | title | subtitle | segment | detail | detailInner | detailContent | panel. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | trailing | `Snippet<[JourneyNode]>` | no | | End-of-row content beside each node's header — status badges, a help affordance, quick actions. Renders *outside* the trigger button (a sibling in the header row), so interactive elements are valid HTML and activating them never moves the focused node. Right-aligned in vertical orientation, appended to the label pill in horizontal. | | unstyled | `boolean` | no | | Remove all default tv() classes. | Inherited from: - Pick (pick-pattern) - Omit, 'children'> (omit-pattern) ### Types ```ts type JourneyStatus = 'complete' | 'active' | 'pending' | 'attention' | 'blocked' | 'skipped' ``` - `interface JourneyNode` — 8 members, definition omitted (41 lines; full definition: packages/blocks/src/lib/primitives/JourneyTimeline/index.ts) ```ts type SlotNames = keyof ReturnType & string ``` ```ts type VariantProps = Omit< Exclude[0], undefined>, 'class' > ``` ### Slots (slotClasses keys) `base`, `rail`, `node`, `metaColumn`, `meta`, `markerColumn`, `marker`, `connector`, `content`, `card`, `header`, `trigger`, `trailing`, `labelGroup`, `title`, `subtitle`, `segment`, `detail`, `detailInner`, `detailContent`, `panel`