Options Reference
These types are defined once in @trailvine/core and used identically by both
@trailvine/react's <Timeline /> and @trailvine/vanilla's
renderTimelineSVG/mountTimeline. This page is the single source of truth for
what each field does — the React and Vanilla
pages mostly just link back here.
TrailvineOptions
The top-level shape both bindings accept.
interface TrailvineOptions<T = {}> {
points: ExtendedTimelinePoint<T>[];
layout: LayoutOptions;
path: PathOptions;
wrap?: WrapOptions;
mobileBehavior?: MobileBehavior;
} Points
interface TimelinePoint<T = {}> {
date: string;
title: string;
subtitle?: string;
current?: boolean;
ariaLabel?: string;
} | Field | Type | Notes |
|---|---|---|
date | string | Just a label — never parsed as an actual date. Duplicate values across points are fine. |
title | string | Wrapped per wrap options if provided; otherwise rendered as-is. |
subtitle | string? | Optional second line — e.g. "Infosys" / "Product Engineer, 5 years". |
current | boolean? | Marks a point for visual emphasis (a larger dot by default). |
ariaLabel | string? | Overrides the auto-generated "{date}: {title}" accessibility label. |
The generic T lets you attach arbitrary extra fields (a link, an id, an
icon) that pass through untouched — the default (no T supplied) stays strictly limited to the
fields above.
layout — LayoutOptions
interface LayoutOptions {
width: number;
marginX: number;
bands: number[];
orientation?: 'horizontal' | 'vertical'; // default: 'horizontal'
} | Field | Notes |
|---|---|
width | Total length along the primary (spread) axis. |
marginX | Margin at each end of that axis before the first/last point. |
bands |
Y-values (or X-values in 'vertical' mode) cycled through via index % bands.length.
Length 2 gives the classic alternating high/low rhythm; length N gives fully
non-uniform heights — same mechanism either way, no separate "mode" flag. Use generateBands()
if you want evenly-spaced values without hand-picking each one.
|
orientation | Same underlying math, rotated axes. 'vertical' is also what mobileBehavior: 'vertical' switches into automatically on narrow viewports. |
path — PathOptions
A discriminated union on curveType — fields like radius only type-check for the curve types where they're actually meaningful.
type PathOptions =
| { curveType: 'elbow'; radius?: number; maxPoints?: number; asSegments?: boolean }
| { curveType: 'straight'; maxPoints?: number; asSegments?: boolean }
| { curveType: 'smooth'; maxPoints?: number; asSegments?: boolean }
| { curveType: 'arc'; radius?: number; maxPoints?: number; asSegments?: boolean }; | curveType | radius | Notes |
|---|---|---|
elbow | ✓ | 0 (or omitted) = sharp corner. Any positive value rounds it, clamped to half the shorter adjacent segment. |
straight | — | Direct line between points, no rounding possible. |
smooth | — | Catmull-Rom-derived bezier. Soft ceiling of 12 points (see getMaxPointsForCurve). |
arc | ✓ | Omitted defaults to half the chord distance (a full semicircle). Larger values flatten the bulge. Soft ceiling of 12 points. |
asSegments: true returns string[] (one path per point-to-point segment) instead of one combined string — useful for per-segment styling like dashed-vs-solid, or highlighting up to a hovered point.
wrap — WrapOptions
interface WrapOptions {
maxChars: number;
maxLines?: number;
ellipsis?: boolean; // default: true when maxLines is set
measureFn?: (text: string) => number;
} | Field | Notes |
|---|---|
maxChars | Greedy word-wrap width. Must be greater than 0. |
maxLines | Caps the line count; extra content is cut and the last line gets an ellipsis (unless disabled). Omit for unlimited wrapping. |
ellipsis | Set false to cut the last line cleanly without adding …. |
measureFn | Substitutes real DOM text measurement (e.g. getComputedTextLength) for the default character-count heuristic. Only useful client-side — the default is SSR-safe with no DOM at all. |
Omitting wrap entirely means titles are never wrapped or truncated — every word always renders somewhere, just potentially on one long line.
mobileBehavior
| Value | Behavior |
|---|---|
'list' (default) | Swaps to a plain vertical list below a breakpoint — pure CSS, no JS required, works during SSR. |
'vertical' | Switches orientation to 'vertical' below the breakpoint. Needs real viewport access, so only <Timeline /> and mountTimeline support it — renderTimelineSVG alone can't react to resizing. |
'none' | No responsive behavior at all. |
Next steps
- Core API — the functions that actually consume these options.
- React API / Vanilla API — binding-specific props on top of this shared shape.
- Playground — see these options change the output live.