Add this component

npx zentauri-ui add time-travel-inspector

Accessibility notes

Keyboard accessible by default with semantic markup, visible focus treatment, and tokenized states. Add descriptive labels for icon-only or decorative usage.

Dependency notes

Check Installation for shared peers. This component keeps styling in Tailwind classes and the --zui-* token contract.

Data display

Time Travel Inspector

Move through application snapshots and see exactly what changed. A synchronized scrubber, state viewer, and custom renderer keep each historical moment in context.

Time travel inspector

6 events · 4 of 6

SAVE20 applied

+8.2s · checkpoint

+0.0s+16.0s

State at +8.2s

{
  "quantity": 2,
  "subtotal": 160,
  "discount": 32,
  "shipping": 0,
  "total": 128,
  "status": "Discount applied"
}

Visual preview

Fieldwork / StoreDiscount applied

Everyday carry tote

Sand / Organic canvas

2 × $80.00

Subtotal
$160.00
Discount
−$32.00
Shipping
$0.00
Total
$128.00

3 changes

Quantity changed (+5.1s) → SAVE20 applied (+8.2s)

  • /discount · changed

    Before: 0

    After: 32

  • /total · changed

    Before: 160

    After: 128

  • /status · changed

    Before: "In your cart"

    After: "Discount applied"

Time Travel Inspector playground

Follow the cart total from $0 to $136. Scrub to SAVE20, compare it with any event, bookmark the moment, or open its historical checkout.

Replay a checkout session


Time travel inspector

6 events · 4 of 6

SAVE20 applied

+8.2s · checkpoint

+0.0s+16.0s

State at +8.2s

{
  "quantity": 2,
  "subtotal": 160,
  "discount": 32,
  "shipping": 0,
  "total": 128,
  "status": "Discount applied"
}

Visual preview

Fieldwork / StoreDiscount applied

Everyday carry tote

Sand / Organic canvas

2 × $80.00

Subtotal
$160.00
Discount
−$32.00
Shipping
$0.00
Total
$128.00

3 changes

Quantity changed (+5.1s) → SAVE20 applied (+8.2s)

  • /discount · changed

    Before: 0

    After: 32

  • /total · changed

    Before: 160

    After: 128

  • /status · changed

    Before: "In your cart"

    After: "Discount applied"

All appearances

Incremental history

Supply checkpoints and deltas directly


Time travel inspector

3 events · 3 of 3

Discount

2000 ms · delta

0 ms2000 ms

State at 2000 ms

{
  "cart": {
    "total": 64
  }
}

Visual preview

Provide renderPreview to display your application at this moment.

1 change

Added (1000 ms) → Discount (2000 ms)

  • /cart/total · changed

    Before: 80

    After: 64

History and rendering contract

Pass immutable snapshots in nondecreasing timestamp order with unique, nonempty IDs. The first event must be a checkpoint. Timestamps are milliseconds, including zero; formatTimestamp controls their display. Events at the same timestamp keep their supplied order.

createTimeTravelHistory(captures, checkpointInterval) stores a full checkpoint every 20 events by default and key-level deltas in between. It copies input states. For long sessions, record checkpoints and deltas directly and release the original full captures. Seeking replays only from the nearest checkpoint; nearby event buttons are limited to seven.

In Server Components or server code, import the pure helpers from @zentauri-ui/zentauri-components/ui/time-travel-inspector/history to compact or resolve history before passing snapshots to the client inspector. The UI entry also re-exports these helpers for client use. Replace snapshots and patches immutably when updating history.

State must be finite JSON data: objects, arrays, strings, numbers, booleans, and null. Dates, undefined, class instances, and cyclic objects are unsupported. Changes use object-key path arrays; arrays are replaced atomically. A set with an empty path replaces the root. Remove requires a nonempty path to an object key, and nested patch parents must already exist. Diff results are discriminated by type: added includes after, removed includes before, and changed includes both.

The state viewer, diff, and renderPreview receive the same moment. A null comparisonId follows the previous event; an explicit ID pins any baseline. selectedId, comparisonId, and bookmarks support controlled values with change callbacks. Unknown selection IDs fall back to the latest event; unknown comparison IDs fall back to the previous event. Bookmarks for absent events are hidden.

Use renderPreview for an application-specific historical view and onOpenState to open it elsewhere. Treat renderer and callback data as immutable. The component does not restore live application state or capture sessions automatically. The scrubber supports native arrow, Home, and End keys; navigation, comparison, and bookmarks also use native keyboard controls.

Time Travel Inspector API

Generated from the package prop types and variant definitions.

TimeTravelInspector

TimeTravelInspectorProps

Variants

PropTypeDefault
appearance
amberbluecontrastcyandefaultemeraldglassgradient-bluelimeorangepinkpurple+4
default
size
lgmdsm
md

State

PropTypeDefault
onOpenStateOptional action for opening the selected historical state.((context: TimeTravelRenderContext) => void) | undefinednone

Behavior

PropTypeDefault
bookmarksControlled bookmark IDs. IDs absent from history are ignored.readonly string[] | undefinednone
comparisonIdComparison baseline. Null automatically compares with the preceding event.string | null | undefinednone
defaultBookmarksreadonly string[] | undefinednone
defaultComparisonIdstring | null | undefinednone
defaultSelectedIdInitially selected event; defaults to the latest.string | undefinednone
emptyStateReactNodenone
formatTimestamp((timestamp: number) => string) | undefinednone
onBookmarksChange((ids: string[]) => void) | undefinednone
onComparisonIdChange((id: string | null) => void) | undefinednone
onSelectedIdChange((id: string) => void) | undefinednone
renderPreviewRender a historical application view. Treat state and context as immutable.((context: TimeTravelRenderContext) => ReactNode) | undefinednone
selectedIdControlled selected event. Missing IDs fall back to the latest event.string | undefinednone
snapshots*Immutable history beginning with a checkpoint. Use createTimeTravelHistory to compact captures.readonly TimeTravelSnapshot[]none
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

Installation and theme overrides

pnpm dlx @zentauri-ui/zentauri-components add time-travel-inspector

Import from @zentauri-ui/zentauri-components/ui/time-travel-inspector. This static entry does not require Framer Motion. With the package install, include the package in your Tailwind v4 scan scope:

@source "../node_modules/@zentauri-ui/zentauri-components";

Adjust the source path for your stylesheet location. Scope paired light/dark variables to a wrapper, such as --zui-time-travel-inspector-selected-bg and --zui-time-travel-inspector-selected-bg-dark.

Explore all Time Travel Inspector CSS variables
CSS variable overrides

Time Travel Inspector CSS variables

Override inspector surfaces, selections, focus rings, and diff colors with paired light and dark variables.

80 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-time-travel-inspector-bg: #ffffff;
  --zui-time-travel-inspector-fg: #0f172a;
  --zui-time-travel-inspector-border: #e2e8f0;
  --zui-time-travel-inspector-blue-bg: #eff6ff;
  --zui-time-travel-inspector-blue-border: #bfdbfe;
  --zui-time-travel-inspector-cyan-bg: #ecfeff;
  --zui-time-travel-inspector-cyan-border: #a5f3fc;
  --zui-time-travel-inspector-teal-bg: #f0fdfa;
  --zui-time-travel-inspector-teal-border: #99f6e4;
  --zui-time-travel-inspector-emerald-bg: #ecfdf5;
  --zui-time-travel-inspector-emerald-border: #a7f3d0;
  --zui-time-travel-inspector-lime-bg: #f7fee7;
  --zui-time-travel-inspector-lime-border: #d9f99d;
  --zui-time-travel-inspector-violet-bg: #f5f3ff;
  --zui-time-travel-inspector-violet-border: #ddd6fe;
  --zui-time-travel-inspector-purple-bg: #faf5ff;
  --zui-time-travel-inspector-purple-border: #e9d5ff;
  --zui-time-travel-inspector-pink-bg: #fdf2f8;
  --zui-time-travel-inspector-pink-border: #fbcfe8;
  --zui-time-travel-inspector-rose-bg: #fff1f2;
  --zui-time-travel-inspector-rose-border: #fecdd3;
  --zui-time-travel-inspector-orange-bg: #fff7ed;
  --zui-time-travel-inspector-orange-border: #fed7aa;
  --zui-time-travel-inspector-amber-bg: #fffbeb;
  --zui-time-travel-inspector-amber-border: #fde68a;
  --zui-time-travel-inspector-contrast-bg: #ffffff;
  --zui-time-travel-inspector-gradient-from: #eff6ff;
  --zui-time-travel-inspector-gradient-to: #f5f3ff;
  --zui-time-travel-inspector-glass-bg: #ffffffcc;
  --zui-time-travel-inspector-glass-border: #ffffff66;
  --zui-time-travel-inspector-muted-fg: #475569;
  --zui-time-travel-inspector-control-bg: #ffffff;
  --zui-time-travel-inspector-focus-ring: #2563eb;
  --zui-time-travel-inspector-selected-bg: #dbeafe;
  --zui-time-travel-inspector-selected-fg: #1e40af;
  --zui-time-travel-inspector-accent: #2563eb;
  --zui-time-travel-inspector-panel-bg: #f8fafc;
  --zui-time-travel-inspector-before-fg: #b91c1c;
  --zui-time-travel-inspector-after-fg: #047857;
  --zui-time-travel-inspector-subtle-bg: #f8fafc;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-time-travel-inspector-bg-dark: #0f172a;
  --zui-time-travel-inspector-fg-dark: #f8fafc;
  /* ...same variables with -dark at the end */
}

Overview

TimeTravelInspector combines a keyboard-accessible timeline, bookmarks, timestamp comparison, state differences, and an optional custom preview.

Common use cases

  • Replay a checkout session to inspect when a cart total changed.
  • Compare editor or workflow state before and after an action.
  • Bookmark important events during a debugging session.

FAQ

How are snapshots stored?

Use createTimeTravelHistory to compact JSON captures into periodic checkpoints and incremental key changes, or supply checkpoints and deltas directly. Each seek starts at the nearest checkpoint.

Can I render my own historical UI?

Yes. renderPreview receives the selected state, event, comparison state, and changes. onOpenState lets your application open a historical view.

Does this record my application automatically?

No. Your application owns capture, persistence, and restoration. The inspector displays the immutable history you supply.