@peasant-labs/fairtrade 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/base.css +48 -0
- package/dist/lib/components.css +2 -0
- package/dist/lib/fonts.css +28 -0
- package/dist/lib/icons.js +1 -0
- package/dist/lib/tokens.css +184 -0
- package/dist/lib/tokens.json +768 -0
- package/dist/lib/types/Accordion.d.ts +47 -0
- package/dist/lib/types/Avatar.d.ts +94 -0
- package/dist/lib/types/BrandMark.d.ts +25 -0
- package/dist/lib/types/Breadcrumb.d.ts +66 -0
- package/dist/lib/types/Button.d.ts +86 -0
- package/dist/lib/types/Card.d.ts +145 -0
- package/dist/lib/types/ChartBar.d.ts +51 -0
- package/dist/lib/types/ChartLine.d.ts +54 -0
- package/dist/lib/types/Checkbox.d.ts +132 -0
- package/dist/lib/types/Chip.d.ts +85 -0
- package/dist/lib/types/CliOnboard.d.ts +68 -0
- package/dist/lib/types/CommandPalette.d.ts +6 -0
- package/dist/lib/types/CommitGraph.d.ts +71 -0
- package/dist/lib/types/ConnectionState.d.ts +82 -0
- package/dist/lib/types/ConsentDialog.d.ts +97 -0
- package/dist/lib/types/DataTable.d.ts +116 -0
- package/dist/lib/types/DateRange.d.ts +242 -0
- package/dist/lib/types/Dialog.d.ts +9 -0
- package/dist/lib/types/DiffView.d.ts +39 -0
- package/dist/lib/types/EmptyState.d.ts +28 -0
- package/dist/lib/types/EvidenceCaption.d.ts +39 -0
- package/dist/lib/types/Explainer.d.ts +82 -0
- package/dist/lib/types/FacetRail.d.ts +13 -0
- package/dist/lib/types/Feedback.d.ts +222 -0
- package/dist/lib/types/GroupedMultiSelect.d.ts +67 -0
- package/dist/lib/types/Input.d.ts +158 -0
- package/dist/lib/types/Intensity.d.ts +55 -0
- package/dist/lib/types/MapCanvas.d.ts +89 -0
- package/dist/lib/types/Menu.d.ts +62 -0
- package/dist/lib/types/ModerationQueue.d.ts +135 -0
- package/dist/lib/types/Pager.d.ts +47 -0
- package/dist/lib/types/Pagination.d.ts +50 -0
- package/dist/lib/types/PolicySelect.d.ts +80 -0
- package/dist/lib/types/ProviderIcon.d.ts +84 -0
- package/dist/lib/types/RailShell.d.ts +199 -0
- package/dist/lib/types/Redaction.d.ts +53 -0
- package/dist/lib/types/RoleRoster.d.ts +97 -0
- package/dist/lib/types/SignIn.d.ts +78 -0
- package/dist/lib/types/Sparkline.d.ts +19 -0
- package/dist/lib/types/StatTiles.d.ts +118 -0
- package/dist/lib/types/StepWizard.d.ts +92 -0
- package/dist/lib/types/StepsWaterfall.d.ts +67 -0
- package/dist/lib/types/Switch.d.ts +63 -0
- package/dist/lib/types/Tabs.d.ts +48 -0
- package/dist/lib/types/TimeStrip.d.ts +12 -0
- package/dist/lib/types/Timeline.d.ts +192 -0
- package/dist/lib/types/ToastHost.d.ts +70 -0
- package/dist/lib/types/ToolRenderers.d.ts +24 -0
- package/dist/lib/types/Tooltip.d.ts +80 -0
- package/dist/lib/types/Tour.d.ts +37 -0
- package/dist/lib/types/TranscriptMarkers.d.ts +50 -0
- package/dist/lib/types/Treemap.d.ts +77 -0
- package/dist/lib/types/VisibilityControl.d.ts +54 -0
- package/dist/lib/types/chart-shared.d.ts +63 -0
- package/dist/lib/types/icons.d.ts +1 -0
- package/dist/lib/types/index.d.ts +53 -0
- package/dist/lib/ui.js +8736 -0
- package/package.json +6 -5
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatTile — one KPI: a mono eyebrow label, a big tabular display number, an optional sub line.
|
|
3
|
+
*
|
|
4
|
+
* @param {object} props
|
|
5
|
+
* @param {string} props.label - the metric name (lowercase chrome; e.g. "transcripts").
|
|
6
|
+
* @param {React.ReactNode} props.value - the headline figure (USER CONTENT — pre-formatted, e.g. "4.2M").
|
|
7
|
+
* @param {React.ReactNode} [props.sub] - an optional secondary line under the value (e.g. "9,610 turns").
|
|
8
|
+
* @param {React.ComponentType<{className?: string}>} [props.icon] - optional lucide icon for the label row.
|
|
9
|
+
* @param {string} [props.className] - extra classes appended to the root.
|
|
10
|
+
*/
|
|
11
|
+
export function StatTile({ label, value, sub, icon: Icon, className, ...rest }: {
|
|
12
|
+
label: string;
|
|
13
|
+
value: React.ReactNode;
|
|
14
|
+
sub?: React.ReactNode;
|
|
15
|
+
icon?: React.ComponentType<{
|
|
16
|
+
className?: string;
|
|
17
|
+
}>;
|
|
18
|
+
className?: string;
|
|
19
|
+
}): any;
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {object} TileSpec
|
|
22
|
+
* @property {string} key - stable key for the tile.
|
|
23
|
+
* @property {string} label - the metric name.
|
|
24
|
+
* @property {React.ReactNode} value - the headline figure.
|
|
25
|
+
* @property {React.ReactNode} [sub] - optional sub line.
|
|
26
|
+
* @property {React.ComponentType<{className?: string}>} [icon] - optional label icon.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* StatGrid — a responsive grid of StatTiles with a STABLE, capped column count (1→4 across
|
|
30
|
+
* breakpoints) so tiles keep equal widths and their eyebrows wrap consistently. The grid keys
|
|
31
|
+
* off its own width via a thin query-container wrapper (an element cannot query a container it
|
|
32
|
+
* establishes itself), so it stays correct wherever it is dropped — not just at the page width.
|
|
33
|
+
*
|
|
34
|
+
* @param {object} props
|
|
35
|
+
* @param {TileSpec[]} props.tiles - the KPI tiles to render, in order.
|
|
36
|
+
* @param {string} [props.className] - extra classes appended to the grid.
|
|
37
|
+
*/
|
|
38
|
+
export function StatGrid({ tiles, className, ...rest }: {
|
|
39
|
+
tiles: TileSpec[];
|
|
40
|
+
className?: string;
|
|
41
|
+
}): any;
|
|
42
|
+
/**
|
|
43
|
+
* GovTile — a governance fact: a mono eyebrow label, an icon, and a value that may carry one
|
|
44
|
+
* scarce earth-tone accent (e.g. amber for a "members only" / scarce policy). The value is mono,
|
|
45
|
+
* not the big display number — governance reads as a stated setting, not a metric.
|
|
46
|
+
*
|
|
47
|
+
* @param {object} props
|
|
48
|
+
* @param {string} props.label - the governance dimension (e.g. "access", "your role").
|
|
49
|
+
* @param {React.ReactNode} props.value - the setting (USER CONTENT — e.g. "members only", "contributor").
|
|
50
|
+
* @param {React.ComponentType<{className?: string}>} [props.icon] - optional lucide icon for the label row.
|
|
51
|
+
* @param {'amber'|'teal'|'olive'|'clay'|'mauve'} [props.tone] - optional earth-tone accent on the value.
|
|
52
|
+
* @param {string} [props.className] - extra classes appended to the root.
|
|
53
|
+
*/
|
|
54
|
+
export function GovTile({ label, value, icon: Icon, tone, className, ...rest }: {
|
|
55
|
+
label: string;
|
|
56
|
+
value: React.ReactNode;
|
|
57
|
+
icon?: React.ComponentType<{
|
|
58
|
+
className?: string;
|
|
59
|
+
}>;
|
|
60
|
+
tone?: "amber" | "teal" | "olive" | "clay" | "mauve";
|
|
61
|
+
className?: string;
|
|
62
|
+
}): any;
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {object} ProviderDatum
|
|
65
|
+
* @property {string} label - provider name (USER CONTENT — case preserved; e.g. "claude-code").
|
|
66
|
+
* @property {number} value - this provider's count.
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* ProviderBars — a labeled horizontal distribution. Each row is a provider name, a monochrome bar
|
|
70
|
+
* whose width is its share of `total`, and a tabular %. Bars are one ink weight (no per-row hue):
|
|
71
|
+
* the eye reads length + label + the written %, so the distribution survives greyscale and AT.
|
|
72
|
+
*
|
|
73
|
+
* @param {object} props
|
|
74
|
+
* @param {ProviderDatum[]} props.data - the providers, in the order to display (caller pre-sorts).
|
|
75
|
+
* @param {number} [props.total] - the denominator for the shares; defaults to the sum of values.
|
|
76
|
+
* @param {string} [props.label='provider distribution'] - accessible name for the list (lowercase chrome).
|
|
77
|
+
* @param {string} [props.className] - extra classes appended to the root.
|
|
78
|
+
*/
|
|
79
|
+
export function ProviderBars({ data, total, label, className, ...rest }: {
|
|
80
|
+
data: ProviderDatum[];
|
|
81
|
+
total?: number;
|
|
82
|
+
label?: string;
|
|
83
|
+
className?: string;
|
|
84
|
+
}): any;
|
|
85
|
+
export type TileSpec = {
|
|
86
|
+
/**
|
|
87
|
+
* - stable key for the tile.
|
|
88
|
+
*/
|
|
89
|
+
key: string;
|
|
90
|
+
/**
|
|
91
|
+
* - the metric name.
|
|
92
|
+
*/
|
|
93
|
+
label: string;
|
|
94
|
+
/**
|
|
95
|
+
* - the headline figure.
|
|
96
|
+
*/
|
|
97
|
+
value: React.ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* - optional sub line.
|
|
100
|
+
*/
|
|
101
|
+
sub?: React.ReactNode;
|
|
102
|
+
/**
|
|
103
|
+
* - optional label icon.
|
|
104
|
+
*/
|
|
105
|
+
icon?: React.ComponentType<{
|
|
106
|
+
className?: string;
|
|
107
|
+
}>;
|
|
108
|
+
};
|
|
109
|
+
export type ProviderDatum = {
|
|
110
|
+
/**
|
|
111
|
+
* - provider name (USER CONTENT — case preserved; e.g. "claude-code").
|
|
112
|
+
*/
|
|
113
|
+
label: string;
|
|
114
|
+
/**
|
|
115
|
+
* - this provider's count.
|
|
116
|
+
*/
|
|
117
|
+
value: number;
|
|
118
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} WizardStep
|
|
3
|
+
* @property {string} id stable id for the step (aria wiring + completed/reachable sets)
|
|
4
|
+
* @property {React.ReactNode} label the step's lowercase chrome label, shown under its number
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The rail alone: numbered square markers joined by connector lines. Pure/controlled — it owns no
|
|
8
|
+
* state. current = amber fill + bold near-black number + aria-current="step"; completed = olive +
|
|
9
|
+
* check glyph (clickable to jump back); future/unreachable = hairline + --ink-4 + aria-disabled
|
|
10
|
+
* (not clickable). Completed steps are always reachable.
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} props
|
|
13
|
+
* @param {WizardStep[]} props.steps the ordered steps
|
|
14
|
+
* @param {string} props.current id of the active step
|
|
15
|
+
* @param {Set<string>} [props.completed] ids of finished steps (olive + check, jump-back enabled)
|
|
16
|
+
* @param {Set<string>} [props.reachable] ids the user may jump to (the gate). current + completed are implicitly reachable
|
|
17
|
+
* @param {(id: string) => void} [props.onJump] called with a step id when a reachable/complete marker is activated
|
|
18
|
+
* @param {string} [props['aria-label']] accessible name for the rail (default "progress")
|
|
19
|
+
*/
|
|
20
|
+
export function StepIndicator({ steps, current, completed, reachable, onJump, "aria-label": ariaLabel, }: {
|
|
21
|
+
steps: WizardStep[];
|
|
22
|
+
current: string;
|
|
23
|
+
completed?: Set<string>;
|
|
24
|
+
reachable?: Set<string>;
|
|
25
|
+
onJump?: (id: string) => void;
|
|
26
|
+
}): any;
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {Object} WizardBodyArgs
|
|
29
|
+
* @property {WizardStep} step the active step descriptor
|
|
30
|
+
* @property {number} index its zero-based position
|
|
31
|
+
* @property {boolean} isLast whether it's the final step
|
|
32
|
+
* @property {(valid: boolean) => void} setValid report whether the step may advance (gates continue)
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Uncontrolled wizard: the rail + a per-step body slot + a sticky footer action bar.
|
|
36
|
+
* Tracks current / completed / reachable internally. Continue advances, marks the step complete,
|
|
37
|
+
* and unlocks the next step; on the last step its primary action reads "submit" and fires
|
|
38
|
+
* onComplete. Back is enabled on every step except the first.
|
|
39
|
+
*
|
|
40
|
+
* Step bodies come from either `children` (an array, one node per step — index-aligned to `steps`)
|
|
41
|
+
* or a `renderStep` render-prop called with {step, index, isLast, setValid}. A step is advanceable
|
|
42
|
+
* unless its render-prop has reported setValid(false); plain-children bodies are always valid.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} props
|
|
45
|
+
* @param {WizardStep[]} props.steps the ordered steps (>= 1)
|
|
46
|
+
* @param {(args: { completed: Set<string> }) => void} [props.onComplete] fired when the last step's submit is activated
|
|
47
|
+
* @param {(args: WizardBodyArgs) => React.ReactNode} [props.renderStep] render-prop for the active step's body
|
|
48
|
+
* @param {React.ReactNode[]} [props.children] index-aligned step bodies (alternative to renderStep)
|
|
49
|
+
* @param {string} [props.continueLabel='continue'] primary label for non-final steps
|
|
50
|
+
* @param {string} [props.submitLabel='submit'] primary label for the final step
|
|
51
|
+
* @param {string} [props.backLabel='back'] secondary (back) label
|
|
52
|
+
* @param {string} [props['aria-label']] accessible name for the rail
|
|
53
|
+
*/
|
|
54
|
+
export default function StepWizard({ steps, onComplete, renderStep, children, continueLabel, submitLabel, backLabel, "aria-label": ariaLabel, }: {
|
|
55
|
+
steps: WizardStep[];
|
|
56
|
+
onComplete?: (args: {
|
|
57
|
+
completed: Set<string>;
|
|
58
|
+
}) => void;
|
|
59
|
+
renderStep?: (args: WizardBodyArgs) => React.ReactNode;
|
|
60
|
+
children?: React.ReactNode[];
|
|
61
|
+
continueLabel?: string;
|
|
62
|
+
submitLabel?: string;
|
|
63
|
+
backLabel?: string;
|
|
64
|
+
}): any;
|
|
65
|
+
export type WizardStep = {
|
|
66
|
+
/**
|
|
67
|
+
* stable id for the step (aria wiring + completed/reachable sets)
|
|
68
|
+
*/
|
|
69
|
+
id: string;
|
|
70
|
+
/**
|
|
71
|
+
* the step's lowercase chrome label, shown under its number
|
|
72
|
+
*/
|
|
73
|
+
label: React.ReactNode;
|
|
74
|
+
};
|
|
75
|
+
export type WizardBodyArgs = {
|
|
76
|
+
/**
|
|
77
|
+
* the active step descriptor
|
|
78
|
+
*/
|
|
79
|
+
step: WizardStep;
|
|
80
|
+
/**
|
|
81
|
+
* its zero-based position
|
|
82
|
+
*/
|
|
83
|
+
index: number;
|
|
84
|
+
/**
|
|
85
|
+
* whether it's the final step
|
|
86
|
+
*/
|
|
87
|
+
isLast: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* report whether the step may advance (gates continue)
|
|
90
|
+
*/
|
|
91
|
+
setValid: (valid: boolean) => void;
|
|
92
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Human-readable ms duration: "4.2s", "42s", "2m 14s", "1.5h". Tabular-friendly, no leading zeros. */
|
|
2
|
+
export function formatDuration(ms: any): string;
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {object} Task
|
|
5
|
+
* @property {string} id - stable key; passed back to onJump (e.g. the prompt turn id).
|
|
6
|
+
* @property {number} [index] - the displayed task number (#1). Falls back to row order + 1.
|
|
7
|
+
* @property {string} prompt - the user prompt that opened the task (USER CONTENT — case preserved).
|
|
8
|
+
* @property {number} durationMs - how long the task took, in ms (drives the bar + the label).
|
|
9
|
+
* @property {number} [tools] - tool calls in the task (shown as "n tools" when no `turns`).
|
|
10
|
+
* @property {number} [turns] - assistant turns in the task (shown as "n turns").
|
|
11
|
+
* @property {'ok'|'error'} [outcome] - 'error' draws the clay marker + the "error" word/icon.
|
|
12
|
+
* @property {string} [error] - a short error label; shown in place of "error" when present.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* StepsWaterfall — render `tasks` as a duration waterfall: a header (total + count + collapse-all)
|
|
16
|
+
* over a list of selectable rows, each with a monochrome duration bar.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} props
|
|
19
|
+
* @param {Task[]} props.tasks - the tasks, in order; one row each.
|
|
20
|
+
* @param {(id: string) => void} [props.onJump] - called with a task id when its row is chosen.
|
|
21
|
+
* @param {number} [props.totalMs] - total session time; defaults to the sum of task durations.
|
|
22
|
+
* @param {boolean} [props.defaultCollapsed=false] - start with the rows collapsed.
|
|
23
|
+
* @param {string} [props.label='steps by duration'] - accessible name for the list (lowercase chrome).
|
|
24
|
+
* @param {string} [props.className] - extra classes appended to the root.
|
|
25
|
+
*/
|
|
26
|
+
export default function StepsWaterfall({ tasks, onJump, totalMs, defaultCollapsed, label, className, ...rest }: {
|
|
27
|
+
tasks: Task[];
|
|
28
|
+
onJump?: (id: string) => void;
|
|
29
|
+
totalMs?: number;
|
|
30
|
+
defaultCollapsed?: boolean;
|
|
31
|
+
label?: string;
|
|
32
|
+
className?: string;
|
|
33
|
+
}): any;
|
|
34
|
+
export type Task = {
|
|
35
|
+
/**
|
|
36
|
+
* - stable key; passed back to onJump (e.g. the prompt turn id).
|
|
37
|
+
*/
|
|
38
|
+
id: string;
|
|
39
|
+
/**
|
|
40
|
+
* - the displayed task number (#1). Falls back to row order + 1.
|
|
41
|
+
*/
|
|
42
|
+
index?: number;
|
|
43
|
+
/**
|
|
44
|
+
* - the user prompt that opened the task (USER CONTENT — case preserved).
|
|
45
|
+
*/
|
|
46
|
+
prompt: string;
|
|
47
|
+
/**
|
|
48
|
+
* - how long the task took, in ms (drives the bar + the label).
|
|
49
|
+
*/
|
|
50
|
+
durationMs: number;
|
|
51
|
+
/**
|
|
52
|
+
* - tool calls in the task (shown as "n tools" when no `turns`).
|
|
53
|
+
*/
|
|
54
|
+
tools?: number;
|
|
55
|
+
/**
|
|
56
|
+
* - assistant turns in the task (shown as "n turns").
|
|
57
|
+
*/
|
|
58
|
+
turns?: number;
|
|
59
|
+
/**
|
|
60
|
+
* - 'error' draws the clay marker + the "error" word/icon.
|
|
61
|
+
*/
|
|
62
|
+
outcome?: "ok" | "error";
|
|
63
|
+
/**
|
|
64
|
+
* - a short error label; shown in place of "error" when present.
|
|
65
|
+
*/
|
|
66
|
+
error?: string;
|
|
67
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} SwitchProps
|
|
3
|
+
* @property {boolean} [checked] controlled on/off state; pair with onChange.
|
|
4
|
+
* @property {boolean} [defaultChecked=false] initial state when uncontrolled.
|
|
5
|
+
* @property {(next: boolean) => void} [onChange] called with the next state on toggle.
|
|
6
|
+
* @property {boolean} [disabled=false] real `disabled` attribute (dim, not focusable).
|
|
7
|
+
* @property {boolean} [busy=false] sets aria-busy; pairs with an aria-live marker.
|
|
8
|
+
* @property {React.ReactNode} [label] text rendered in the associated .sw-label.
|
|
9
|
+
* @property {string} [onText='on'] state-marker text shown when checked.
|
|
10
|
+
* @property {string} [offText='off'] state-marker text shown when unchecked.
|
|
11
|
+
* @property {React.ComponentType<{size?: number}>} [stateIcon] override icon for the
|
|
12
|
+
* .sw-state marker; defaults to CircleCheck (on) / Circle (off).
|
|
13
|
+
* @property {string} [id] id for the control; links the label's `for`.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @param {SwitchProps} props
|
|
17
|
+
*/
|
|
18
|
+
export default function Switch({ checked, defaultChecked, onChange, disabled, busy, label, onText, offText, stateIcon: StateIcon, id, }: SwitchProps): any;
|
|
19
|
+
export type SwitchProps = {
|
|
20
|
+
/**
|
|
21
|
+
* controlled on/off state; pair with onChange.
|
|
22
|
+
*/
|
|
23
|
+
checked?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* initial state when uncontrolled.
|
|
26
|
+
*/
|
|
27
|
+
defaultChecked?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* called with the next state on toggle.
|
|
30
|
+
*/
|
|
31
|
+
onChange?: (next: boolean) => void;
|
|
32
|
+
/**
|
|
33
|
+
* real `disabled` attribute (dim, not focusable).
|
|
34
|
+
*/
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* sets aria-busy; pairs with an aria-live marker.
|
|
38
|
+
*/
|
|
39
|
+
busy?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* text rendered in the associated .sw-label.
|
|
42
|
+
*/
|
|
43
|
+
label?: React.ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* state-marker text shown when checked.
|
|
46
|
+
*/
|
|
47
|
+
onText?: string;
|
|
48
|
+
/**
|
|
49
|
+
* state-marker text shown when unchecked.
|
|
50
|
+
*/
|
|
51
|
+
offText?: string;
|
|
52
|
+
/**
|
|
53
|
+
* override icon for the
|
|
54
|
+
* .sw-state marker; defaults to CircleCheck (on) / Circle (off).
|
|
55
|
+
*/
|
|
56
|
+
stateIcon?: React.ComponentType<{
|
|
57
|
+
size?: number;
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* id for the control; links the label's `for`.
|
|
61
|
+
*/
|
|
62
|
+
id?: string;
|
|
63
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} TabItem
|
|
3
|
+
* @property {string} id stable id for the tab/panel pair (used for ids + aria wiring)
|
|
4
|
+
* @property {React.ReactNode} label the tab's visible label; force-lowercased as ui chrome, so pass a section name, never user content / proper nouns
|
|
5
|
+
* @property {number} [count] optional count shown in a .cnt badge after the label
|
|
6
|
+
* @property {React.ReactNode} content the panel's content
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Self-contained ARIA tablist matching the trails-section specimen. Renders a
|
|
10
|
+
* `role="tablist".tabs` of `role="tab".tab` buttons (roving tabindex, `.active`
|
|
11
|
+
* on the selected tab, optional `.cnt` count) controlling `role="tabpanel".tabpanel`
|
|
12
|
+
* regions whose `hidden` attribute is toggled. Keyboard: Arrow/Home/End move
|
|
13
|
+
* selection (also focusing the tab), click selects + focuses. Ports the delegated
|
|
14
|
+
* logic from App.jsx's tablist useEffect.
|
|
15
|
+
*
|
|
16
|
+
* Supports controlled (`value` + `onChange`) and uncontrolled (`defaultTab`) use.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} props
|
|
19
|
+
* @param {TabItem[]} props.tabs the tabs to render
|
|
20
|
+
* @param {string} [props.defaultTab] initial selected tab id (uncontrolled; defaults to tabs[0].id)
|
|
21
|
+
* @param {string} [props.value] selected tab id (controlled)
|
|
22
|
+
* @param {(id: string) => void} [props.onChange] called with the newly selected tab id
|
|
23
|
+
* @param {string} [props['aria-label']] accessible name for the tablist (default "tabs")
|
|
24
|
+
*/
|
|
25
|
+
export default function Tabs({ tabs, defaultTab, value, onChange, "aria-label": ariaLabel }: {
|
|
26
|
+
tabs: TabItem[];
|
|
27
|
+
defaultTab?: string;
|
|
28
|
+
value?: string;
|
|
29
|
+
onChange?: (id: string) => void;
|
|
30
|
+
}): any;
|
|
31
|
+
export type TabItem = {
|
|
32
|
+
/**
|
|
33
|
+
* stable id for the tab/panel pair (used for ids + aria wiring)
|
|
34
|
+
*/
|
|
35
|
+
id: string;
|
|
36
|
+
/**
|
|
37
|
+
* the tab's visible label; force-lowercased as ui chrome, so pass a section name, never user content / proper nouns
|
|
38
|
+
*/
|
|
39
|
+
label: React.ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* optional count shown in a .cnt badge after the label
|
|
42
|
+
*/
|
|
43
|
+
count?: number;
|
|
44
|
+
/**
|
|
45
|
+
* the panel's content
|
|
46
|
+
*/
|
|
47
|
+
content: React.ReactNode;
|
|
48
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function TimeStrip({ buckets, value, defaultValue, onScrub, branches, label, maxBranchChips, className, ...rest }: {
|
|
2
|
+
[x: string]: any;
|
|
3
|
+
buckets?: any[];
|
|
4
|
+
value: any;
|
|
5
|
+
defaultValue?: number;
|
|
6
|
+
onScrub: any;
|
|
7
|
+
branches?: any[];
|
|
8
|
+
label?: string;
|
|
9
|
+
maxBranchChips?: number;
|
|
10
|
+
className?: string;
|
|
11
|
+
}): any;
|
|
12
|
+
export default TimeStrip;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkingBlock — a collapsible reasoning panel. Controlled when `open`/`onToggle`
|
|
3
|
+
* are passed, otherwise it self-manages. Header is a real <button aria-expanded>;
|
|
4
|
+
* the body lazy-mounts on open so collapsed reasoning is absent from the a11y tree.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} props
|
|
7
|
+
* @param {Thinking} props.block the reasoning block (words + text)
|
|
8
|
+
* @param {boolean} [props.open] controlled open state
|
|
9
|
+
* @param {() => void} [props.onToggle] controlled toggle handler
|
|
10
|
+
*/
|
|
11
|
+
export function ThinkingBlock({ block, open: openProp, onToggle }: {
|
|
12
|
+
block: Thinking;
|
|
13
|
+
open?: boolean;
|
|
14
|
+
onToggle?: () => void;
|
|
15
|
+
}): any;
|
|
16
|
+
/**
|
|
17
|
+
* ToolCall — one collapsible tool call. Controlled when `open`/`onToggle` are passed
|
|
18
|
+
* (lets a host own expand-all), otherwise self-managed. Header is a real
|
|
19
|
+
* <button aria-expanded>; the body lazy-mounts on open. `renderTool` overrides the
|
|
20
|
+
* built-in body dispatch.
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} props
|
|
23
|
+
* @param {Tool} props.tool
|
|
24
|
+
* @param {number} [props.index] position, passed to renderTool
|
|
25
|
+
* @param {boolean} [props.open] controlled open state
|
|
26
|
+
* @param {() => void} [props.onToggle] controlled toggle handler
|
|
27
|
+
* @param {(tool: Tool, i: number) => React.ReactNode} [props.renderTool] custom body renderer
|
|
28
|
+
*/
|
|
29
|
+
export function ToolCall({ tool, index, open: openProp, onToggle, renderTool }: {
|
|
30
|
+
tool: Tool;
|
|
31
|
+
index?: number;
|
|
32
|
+
open?: boolean;
|
|
33
|
+
onToggle?: () => void;
|
|
34
|
+
renderTool?: (tool: Tool, i: number) => React.ReactNode;
|
|
35
|
+
}): any;
|
|
36
|
+
/**
|
|
37
|
+
* TimelineItem — renders one node on the spine, switching on `kind`. Owns the
|
|
38
|
+
* decorative dot, the role glyph + head meta and the body slot. Exported so a host
|
|
39
|
+
* can map its own array and compose custom containers.
|
|
40
|
+
*
|
|
41
|
+
* @param {Object} props
|
|
42
|
+
* @param {TimelineItem} props.item
|
|
43
|
+
* @param {(tool: Tool, i: number) => React.ReactNode} [props.renderTool]
|
|
44
|
+
* @param {(item: TimelineItem) => React.ReactNode} [props.renderBody]
|
|
45
|
+
*/
|
|
46
|
+
export function TimelineItem({ item, renderTool, renderBody }: {
|
|
47
|
+
item: TimelineItem;
|
|
48
|
+
renderTool?: (tool: Tool, i: number) => React.ReactNode;
|
|
49
|
+
renderBody?: (item: TimelineItem) => React.ReactNode;
|
|
50
|
+
}): any;
|
|
51
|
+
export type TimelineItem = {
|
|
52
|
+
id: string;
|
|
53
|
+
/**
|
|
54
|
+
* node type on the spine
|
|
55
|
+
*/
|
|
56
|
+
kind: "turn" | "phase" | "checkpoint";
|
|
57
|
+
/**
|
|
58
|
+
* (kind: turn)
|
|
59
|
+
*/
|
|
60
|
+
role?: "user" | "assistant" | "subagent" | "tool" | "system";
|
|
61
|
+
/**
|
|
62
|
+
* turn label e.g. '2a' (tabular)
|
|
63
|
+
*/
|
|
64
|
+
label?: string;
|
|
65
|
+
/**
|
|
66
|
+
* 0 = main thread; > 0 = subagent inset
|
|
67
|
+
*/
|
|
68
|
+
depth?: number;
|
|
69
|
+
/**
|
|
70
|
+
* subagent name when depth > 0
|
|
71
|
+
*/
|
|
72
|
+
subagent?: string;
|
|
73
|
+
/**
|
|
74
|
+
* relative, e.g. '8m ago'
|
|
75
|
+
*/
|
|
76
|
+
time?: string;
|
|
77
|
+
/**
|
|
78
|
+
* absolute, used for title=
|
|
79
|
+
*/
|
|
80
|
+
longTime?: string;
|
|
81
|
+
/**
|
|
82
|
+
* the turn text (passed to renderBody)
|
|
83
|
+
*/
|
|
84
|
+
body?: string;
|
|
85
|
+
/**
|
|
86
|
+
* collapsible reasoning block
|
|
87
|
+
*/
|
|
88
|
+
thinking?: Thinking;
|
|
89
|
+
/**
|
|
90
|
+
* collapsible tool calls
|
|
91
|
+
*/
|
|
92
|
+
tools?: Tool[];
|
|
93
|
+
tokens?: {
|
|
94
|
+
in: number;
|
|
95
|
+
out: number;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* turn surfaced a tool error
|
|
99
|
+
*/
|
|
100
|
+
error?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* marks the last assistant turn; caps the spine below it
|
|
103
|
+
*/
|
|
104
|
+
final?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* (kind: phase) e.g. 'debugging'
|
|
107
|
+
*/
|
|
108
|
+
phaseLabel?: string;
|
|
109
|
+
/**
|
|
110
|
+
* lucide phase icon
|
|
111
|
+
*/
|
|
112
|
+
icon?: React.ComponentType<any>;
|
|
113
|
+
/**
|
|
114
|
+
* 'turns 3–4 · 1 error'
|
|
115
|
+
*/
|
|
116
|
+
range?: string;
|
|
117
|
+
/**
|
|
118
|
+
* (kind: checkpoint) commit hash
|
|
119
|
+
*/
|
|
120
|
+
hash?: string;
|
|
121
|
+
/**
|
|
122
|
+
* commit message
|
|
123
|
+
*/
|
|
124
|
+
msg?: string;
|
|
125
|
+
stat?: {
|
|
126
|
+
files: number;
|
|
127
|
+
adds: number;
|
|
128
|
+
dels: number;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Timeline — a vertical spine for a whole session: phase dividers, role-tinted
|
|
133
|
+
* turn nodes, collapsible thinking + tool calls, subagent insets and commit
|
|
134
|
+
* checkpoints, read top to bottom. The vertical sibling of the horizontal Steps
|
|
135
|
+
* wizard; they share no geometry. Role is carried by glyph + label, never tint
|
|
136
|
+
* alone; the spine stays continuous even through subagent insets.
|
|
137
|
+
*
|
|
138
|
+
* Emits `<ol class="tl" aria-label>` — turns are an ordered list so DOM order
|
|
139
|
+
* equals visual order equals conversation order. Renders an EmptyState-style
|
|
140
|
+
* `.empty` block when `items` is empty.
|
|
141
|
+
*
|
|
142
|
+
* @param {Object} props
|
|
143
|
+
* @param {TimelineItem[]} [props.items=[]] ordered top->bottom event stream
|
|
144
|
+
* @param {(tool: Tool, i: number) => React.ReactNode} [props.renderTool] per-tool body override
|
|
145
|
+
* @param {(item: TimelineItem) => React.ReactNode} [props.renderBody] per-role body override
|
|
146
|
+
* @param {boolean} [props.dense=false] compact rhythm for sidebars
|
|
147
|
+
* @param {string} [props.ariaLabel='conversation timeline'] label for the <ol> landmark
|
|
148
|
+
*/
|
|
149
|
+
export default function Timeline({ items, renderTool, renderBody, dense, ariaLabel }: {
|
|
150
|
+
items?: TimelineItem[];
|
|
151
|
+
renderTool?: (tool: Tool, i: number) => React.ReactNode;
|
|
152
|
+
renderBody?: (item: TimelineItem) => React.ReactNode;
|
|
153
|
+
dense?: boolean;
|
|
154
|
+
ariaLabel?: string;
|
|
155
|
+
}): any;
|
|
156
|
+
export type Thinking = {
|
|
157
|
+
/**
|
|
158
|
+
* word count shown next to the toggle (tabular)
|
|
159
|
+
*/
|
|
160
|
+
words: number;
|
|
161
|
+
/**
|
|
162
|
+
* the reasoning text (kept in original case)
|
|
163
|
+
*/
|
|
164
|
+
text: string;
|
|
165
|
+
};
|
|
166
|
+
export type Tool = {
|
|
167
|
+
id: string;
|
|
168
|
+
/**
|
|
169
|
+
* switch for the built-in renderer
|
|
170
|
+
*/
|
|
171
|
+
kind: "read" | "grep" | "edit" | "write" | "bash" | "task" | "webfetch" | string;
|
|
172
|
+
/**
|
|
173
|
+
* content-case label e.g. 'Read' (NEVER lowercased)
|
|
174
|
+
*/
|
|
175
|
+
name: string;
|
|
176
|
+
/**
|
|
177
|
+
* one-line summary shown while collapsed
|
|
178
|
+
*/
|
|
179
|
+
preview: string;
|
|
180
|
+
/**
|
|
181
|
+
* e.g. '4.1s' (tabular)
|
|
182
|
+
*/
|
|
183
|
+
duration?: string;
|
|
184
|
+
/**
|
|
185
|
+
* bash exit code; !== 0 surfaces an error pill + tints the dot
|
|
186
|
+
* kind-specific payload: read{path,lines,excerpt} · grep{pattern,scope,glob,matches,results}
|
|
187
|
+
* · edit{path,adds,dels,hunk[]} · bash{command,description,stdout,exit,duration}
|
|
188
|
+
* · webfetch{url,prompt,result} · task{agent,status,task,owner,promptBody,result}
|
|
189
|
+
* · default{args,result}
|
|
190
|
+
*/
|
|
191
|
+
exit?: number;
|
|
192
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} ToastOpts
|
|
3
|
+
* @property {React.ReactNode} [title] the title line; defaults to the tone label.
|
|
4
|
+
* @property {'ok'|'err'} [variant] tone; defaults per method ('ok' for show()).
|
|
5
|
+
* @property {React.ComponentType} [icon] override the leading lucide glyph.
|
|
6
|
+
* @property {number} [duration] per-toast auto-dismiss ms; 0/Infinity = sticky.
|
|
7
|
+
* @property {string} [closeLabel] aria-label for the dismiss button.
|
|
8
|
+
* @property {string} [id] supply to dedupe / target with update().
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* ToastProvider — wraps a subtree and renders the fixed stacking host. children that
|
|
12
|
+
* call useToast() get a stable imperative api (memoised; identity never changes).
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} props
|
|
15
|
+
* @param {React.ReactNode} props.children the app subtree that may call useToast().
|
|
16
|
+
* @param {'bottom-right'|'bottom-left'|'top-right'|'top-left'|'bottom-center'|'top-center'} [props.placement='bottom-right']
|
|
17
|
+
* which corner the fixed region pins to and the edge new toasts enter from.
|
|
18
|
+
* @param {number} [props.max=4] cap on simultaneously-visible toasts.
|
|
19
|
+
* @param {number} [props.duration=5000] default auto-dismiss ms; 0/Infinity = sticky.
|
|
20
|
+
* @param {boolean} [props.inline=false] pin the host absolutely inside a relative
|
|
21
|
+
* container (for an in-frame doc/story example) instead of fixed to the viewport.
|
|
22
|
+
*/
|
|
23
|
+
export function ToastProvider({ children, placement, max, duration, inline, }: {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
placement?: "bottom-right" | "bottom-left" | "top-right" | "top-left" | "bottom-center" | "top-center";
|
|
26
|
+
max?: number;
|
|
27
|
+
duration?: number;
|
|
28
|
+
inline?: boolean;
|
|
29
|
+
}): any;
|
|
30
|
+
/**
|
|
31
|
+
* useToast — the imperative api object from the nearest ToastProvider. throws a clear
|
|
32
|
+
* lowercase error when called outside a provider so a missing host is caught in dev.
|
|
33
|
+
* @returns {{ ok: Function, err: Function, show: Function, dismiss: Function, dismissAll: Function, update: Function, promise: Function }}
|
|
34
|
+
*/
|
|
35
|
+
export function useToast(): {
|
|
36
|
+
ok: Function;
|
|
37
|
+
err: Function;
|
|
38
|
+
show: Function;
|
|
39
|
+
dismiss: Function;
|
|
40
|
+
dismissAll: Function;
|
|
41
|
+
update: Function;
|
|
42
|
+
promise: Function;
|
|
43
|
+
};
|
|
44
|
+
export default ToastProvider;
|
|
45
|
+
export type ToastOpts = {
|
|
46
|
+
/**
|
|
47
|
+
* the title line; defaults to the tone label.
|
|
48
|
+
*/
|
|
49
|
+
title?: React.ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* tone; defaults per method ('ok' for show()).
|
|
52
|
+
*/
|
|
53
|
+
variant?: "ok" | "err";
|
|
54
|
+
/**
|
|
55
|
+
* override the leading lucide glyph.
|
|
56
|
+
*/
|
|
57
|
+
icon?: React.ComponentType;
|
|
58
|
+
/**
|
|
59
|
+
* per-toast auto-dismiss ms; 0/Infinity = sticky.
|
|
60
|
+
*/
|
|
61
|
+
duration?: number;
|
|
62
|
+
/**
|
|
63
|
+
* aria-label for the dismiss button.
|
|
64
|
+
*/
|
|
65
|
+
closeLabel?: string;
|
|
66
|
+
/**
|
|
67
|
+
* supply to dedupe / target with update().
|
|
68
|
+
*/
|
|
69
|
+
id?: string;
|
|
70
|
+
};
|