Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ jobs:
FOSSILIZE_PLATFORMS: linux-x64,linux-arm64,win-x64,darwin-x64,darwin-arm64
FOSSILIZE_SIGN: ${{ github.event_name == 'push' && (github.ref_name == 'main' || startsWith(github.ref_name, 'release/')) && 'y' || 'n' }}
run: pnpm build

- name: Build component registry
working-directory: packages/spotlight
run: pnpm registry:build

- name: Checking npx
run: npx ./packages/spotlight --help
Expand Down
28 changes: 28 additions & 0 deletions packages/docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# deps
/node_modules

# generated content
.contentlayer
.content-collections
.source

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts
22 changes: 22 additions & 0 deletions packages/docs/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/global.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
146 changes: 146 additions & 0 deletions packages/docs/content/docs/components/span-tree.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
title: SpanTree
description: Hierarchical waterfall visualization for distributed trace spans
---

# SpanTree

A hierarchical waterfall visualization component for distributed trace spans. Displays timing information and parent-child relationships between spans.

<SpanTreeDemo />

## Installation

<InstallationTabs component="span-tree" />

## Usage

```tsx
import { SpanTree } from "@/components/ui/span-tree";
```

```tsx
<SpanTree
spans={spans}
traceStartTimestamp={startTime}
traceDuration={duration}
selectedSpanId={selectedId}
onSpanSelect={(spanId) => setSelectedId(spanId)}
/>
```

## Examples

### Basic Usage

```tsx
import { SpanTree } from "@/components/ui/span-tree";
import type { SpanData } from "@/components/ui/span-tree/types";

const spans: SpanData[] = [
{
span_id: "span-001",
op: "http.server",
description: "GET /api/users",
start_timestamp: 1700000000000,
timestamp: 1700000000450,
status: "ok",
children: [],
},
];

export function BasicExample() {
return (
<SpanTree
spans={spans}
traceStartTimestamp={1700000000000}
traceDuration={450}
/>
);
}
```

### With Selection

```tsx
import { SpanTree } from "@/components/ui/span-tree";
import { useState } from "react";

export function SelectionExample() {
const [selectedSpanId, setSelectedSpanId] = useState<string>();

return (
<SpanTree
spans={spans}
traceStartTimestamp={startTime}
traceDuration={duration}
selectedSpanId={selectedSpanId}
onSpanSelect={(spanId, span) => {
setSelectedSpanId(spanId);
console.log("Selected span:", span);
}}
/>
);
}
```

### With Highlighting

```tsx
import { SpanTree } from "@/components/ui/span-tree";

const highlightedIds = new Set(["span-002", "span-003"]);

export function HighlightExample() {
return (
<SpanTree
spans={spans}
traceStartTimestamp={startTime}
traceDuration={duration}
highlightedSpanIds={highlightedIds}
/>
);
}
```

## API Reference

### SpanTree

The main component for rendering a span tree visualization.

<APITable props={[
{ name: "spans", type: "SpanData[]", description: "Array of root spans with children populated", required: true },
{ name: "traceStartTimestamp", type: "number", description: "Start timestamp of the entire trace (Unix ms)", required: true },
{ name: "traceDuration", type: "number", description: "Total duration of the trace in milliseconds", required: true },
{ name: "selectedSpanId", type: "string", description: "Currently selected span ID" },
{ name: "onSpanSelect", type: "(spanId: string, span: SpanData) => void", description: "Callback when a span is clicked" },
{ name: "highlightedSpanIds", type: "Set<string>", description: "Set of span IDs to highlight" },
{ name: "initialNodeWidth", type: "number", default: "50", description: "Initial width percentage of span name column" },
{ name: "className", type: "string", description: "Custom class name for the root element" }
]} />

### SpanData Type

```tsx
interface SpanData {
span_id: string;
trace_id?: string;
parent_span_id?: string | null;
op?: string | null;
description?: string | null;
start_timestamp: number;
timestamp: number;
status?: "ok" | "error" | string;
children?: SpanData[];
data?: Record<string, unknown>;
tags?: Record<string, string>;
}
```

## Notes

- The component uses a resizable column layout - drag the divider between the span name and waterfall columns
- Spans with many children (more than 10) or deep nesting (depth 10 or more) are auto-collapsed for performance
- Duration colors indicate performance: green (under 100ms), yellow (100-500ms), orange (500ms-1s), red (over 1s)
- The component is fully keyboard accessible - use Tab to navigate and Enter/Space to select
178 changes: 178 additions & 0 deletions packages/docs/content/docs/components/trace-item.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
title: TraceItem
description: Summary row component for displaying distributed trace information
---

# TraceItem

A summary row component for displaying distributed trace information. Perfect for trace lists and overviews.

<TraceItemDemo />

## Installation

<InstallationTabs component="trace-item" />

## Usage

```tsx
import { TraceItem } from "@/components/ui/trace-item";
```

```tsx
<TraceItem
trace={trace}
isSelected={selectedId === trace.trace_id}
onSelect={(traceId) => setSelectedId(traceId)}
/>
```

## Examples

### Basic Usage

```tsx
import { TraceItem } from "@/components/ui/trace-item";
import type { TraceData } from "@/components/ui/trace-item/types";

const trace: TraceData = {
trace_id: "abc123def456",
start_timestamp: Date.now() - 120000,
timestamp: Date.now() - 119550,
status: "ok",
spans: new Map(),
spanTree: [],
rootTransactionName: "/api/users",
rootTransactionMethod: "GET",
environment: "production",
};

export function BasicExample() {
return <TraceItem trace={trace} />;
}
```

### With Selection

```tsx
import { TraceItem } from "@/components/ui/trace-item";
import { useState } from "react";

export function SelectionExample() {
const [selectedId, setSelectedId] = useState<string>();

return (
<TraceItem
trace={trace}
isSelected={selectedId === trace.trace_id}
onSelect={(traceId, trace) => {
setSelectedId(traceId);
console.log("Selected trace:", trace);
}}
/>
);
}
```

### Trace List

```tsx
import { TraceItem } from "@/components/ui/trace-item";
import { useState } from "react";

export function TraceList({ traces }) {
const [selectedId, setSelectedId] = useState<string>();

return (
<div className="border rounded-lg overflow-hidden">
{traces.map((trace) => (
<TraceItem
key={trace.trace_id}
trace={trace}
isSelected={selectedId === trace.trace_id}
onSelect={(traceId) => setSelectedId(traceId)}
/>
))}
</div>
);
}
```

## API Reference

### TraceItem

The main component for rendering a trace summary row.

<APITable props={[
{ name: "trace", type: "TraceData", description: "The trace data to render", required: true },
{ name: "isSelected", type: "boolean", default: "false", description: "Whether this trace is currently selected" },
{ name: "onSelect", type: "(traceId: string, trace: TraceData) => void", description: "Callback when trace is clicked" },
{ name: "className", type: "string", description: "Custom class name" }
]} />

### TraceData Type

```tsx
interface TraceData {
trace_id: string;
start_timestamp: number;
timestamp: number;
status?: "ok" | "error" | string;
spans: Map<string, SpanData>;
spanTree: SpanData[];
rootTransactionName: string;
rootTransactionMethod?: string;
transactionCount?: number;
spanCount?: number;
platform?: string;
environment?: string;
}
```

### Additional Components

The trace-item package also includes helper components:

#### StatusBadge

```tsx
import { StatusBadge } from "@/components/ui/trace-item";

<StatusBadge status="ok" />
<StatusBadge status="error" />
```

#### MethodBadge

```tsx
import { MethodBadge } from "@/components/ui/trace-item";

<MethodBadge method="GET" />
<MethodBadge method="POST" />
```

#### EnvironmentBadge

```tsx
import { EnvironmentBadge } from "@/components/ui/trace-item";

<EnvironmentBadge environment="production" />
<EnvironmentBadge environment="staging" />
```

#### TimeSince

```tsx
import { TimeSince } from "@/components/ui/trace-item";

<TimeSince date={timestamp} refreshInterval={5000} />
```

## Notes

- The component displays a truncated trace ID (first 8 characters)
- Relative time ("2 minutes ago") updates automatically every 5 seconds by default
- Error traces are highlighted with a red icon and status badge
- The component is fully keyboard accessible - use Tab to navigate and Enter/Space to select
- Duration is calculated from `timestamp - start_timestamp`
Loading
Loading