@trailvine/core
The framework-agnostic engine. Zero runtime dependencies, pure functions only —
no DOM, no styling, no I/O. Both @trailvine/react and @trailvine/vanilla
are built entirely on top of this package.
Field-level details for layout, path, and wrap live on the
options reference page — this page covers only the functions themselves.
buildTimelinePath
The primary, documented entry point. Dispatches to the right curve builder based on path.curveType.
function buildTimelinePath(
points: Point[],
options: PathOptions
): string | string[]; // string[] only when options.asSegments is true Throws if fewer than 2 points are given, or if any option is invalid (negative radius, etc.) — see validation behavior.
Individual curve builders
Lower-level "escape hatch" functions — useful if you already know exactly which curve you want and would
rather skip the dispatcher. Each has a matching *Segments variant returning string[]
(one path per segment) instead of one combined string.
function buildElbowPath(points: Point[], radius?: number): string;
function buildElbowPathSegments(points: Point[], radius?: number): string[];
function buildStraightPath(points: Point[]): string;
function buildStraightPathSegments(points: Point[]): string[];
function buildSmoothPath(points: Point[]): string;
function buildSmoothPathSegments(points: Point[]): string[];
function buildArcPath(points: Point[], radius?: number): string;
function buildArcPathSegments(points: Point[], radius?: number): string[]; buildElbowPath—radius: 0(or omitted) gives a sharp corner; any positive value rounds it, clamped so it never exceeds half the shorter adjacent segment.buildSmoothPath— a hand-written Catmull-Rom-to-bezier conversion. No dependency on d3-shape or similar.buildArcPath— semicircular arcs, sweep alternating per segment. With noradiusgiven, defaults to half the chord distance (a true semicircle).
getMaxPointsForCurve
Returns the recommended point-count ceiling for a curve type — 12 for 'smooth' and 'arc' (past which the curve tends to look visually mediocre), Infinity for everything else.
function getMaxPointsForCurve(curveType: CurveType): number; This is advisory, not enforced — exceeding it logs a console warning but still renders.
layoutTimelinePoints
Spaces count points evenly along the primary axis, cycling through bands for the secondary axis.
function layoutTimelinePoints(count: number, options: LayoutOptions): Point[]; Throws if count < 2, if bands is empty, or if width/marginX is negative.
generateBands
Convenience helper — generates bandCount evenly spaced values between min and max, for anyone who doesn't want to hand-pick each value.
function generateBands(bandCount: number, min: number, max: number): number[];
generateBands(3, 20, 80); // -> [20, 50, 80]
generateBands(1, 20, 80); // -> [20] wrapText
Greedy word-wrap for SVG <text>, since browsers don't wrap SVG text automatically.
function wrapText(text: string, options: WrapOptions): WrapResult;
interface WrapResult {
lines: string[];
truncated: boolean; // true if maxLines cut the text short
}
Measures by character count by default (zero-dependency, SSR-safe) — pass measureFn to substitute
real DOM measurement client-side. Cannot break in the middle of a single word longer than maxChars;
that word is placed on its own line rather than split.
validateTimelineInput
Validates a full TrailvineOptions object up front — what both bindings call internally before doing any work, so a bad config fails fast with one clear error rather than partway through rendering.
function validateTimelineInput(options: TrailvineOptions): void;
Structurally invalid input throws (empty bands, negative radius, fewer than 2 points).
Merely unusual input — like marginX leaving no usable space — warns instead of throwing.
Next steps
- Options reference — every field on
layout,path, andwrap. - React API / Vanilla API — the bindings built on top of this package.