Skip to content

Commit 88da0db

Browse files
committed
Polish trace UI: Inter font everywhere, resizable detail panel, neutral step cards
Every Monaco editor and font-mono usage now goes through Inter instead of a mix of Monaco's default and JetBrains Mono, centralized in monacoTheme.ts and index.css's --font-mono so there's one place to change it. Add a font picker for the Call Stack cards (defaults to Inter, JetBrains Mono/Fira Code/etc. still selectable). Make the Dependencies/Dependents/Lint panel vertically resizable instead of letting it grow unbounded. Drop the per-schema health percentage badges from the directory tree (noise, not decision-relevant there). Neutralize trace step cards in the Result panel so only the PASS/FAIL/PUSH pill is colored instead of the whole card glowing green/red, and make that pill bigger and bolder. Show the Custom Debugger's Annotations panel even before a trace has run, matching the Call Stack panel's existing empty state. Signed-off-by: itvi-1234 <rjsumit71@gmail.com>
1 parent 1c0ee39 commit 88da0db

11 files changed

Lines changed: 117 additions & 55 deletions

File tree

‎src/components/AnnotationsPanel.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ const AnnotationsPanel = ({
2121
}) => (
2222
<div className="w-72 shrink-0 flex flex-col rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] overflow-hidden">
2323
<div className="px-3 py-1.5 border-b border-[var(--border)]">
24-
<div className="text-xs text-[var(--text-secondary)]">Annotations</div>
25-
<div className="text-[10px] text-[var(--text-secondary)] opacity-70 mt-0.5">
24+
<div className="text-sm text-[var(--text-secondary)]">Annotations</div>
25+
<div className="text-xs text-[var(--text-secondary)] opacity-70 mt-0.5">
2626
Collected so far, in emission order
2727
</div>
2828
</div>
2929
<div className="flex-1 min-h-0 overflow-y-auto p-2 flex flex-col gap-1.5">
3030
{annotations.length === 0 && (
31-
<span className="text-xs text-[var(--text-secondary)] p-1">
31+
<span className="text-sm text-[var(--text-secondary)] p-1">
3232
No annotations emitted yet
3333
</span>
3434
)}
@@ -37,7 +37,7 @@ const AnnotationsPanel = ({
3737
return (
3838
<div
3939
key={entry.stepIndex}
40-
className={`rounded-[var(--radius-sm)] border px-2 py-1.5 text-xs font-mono transition-opacity ${
40+
className={`rounded-[var(--radius-sm)] border px-2 py-1.5 text-sm transition-opacity ${
4141
isCurrentScope
4242
? "border-[var(--info)]/50 bg-[var(--info-soft)]"
4343
: "border-[var(--border)] bg-[var(--bg-inset)] opacity-60"
@@ -46,7 +46,7 @@ const AnnotationsPanel = ({
4646
<div className="truncate text-[var(--info)]">
4747
{formatAnnotationList(entry.values)}
4848
</div>
49-
<div className="text-[10px] text-[var(--text-secondary)] truncate">
49+
<div className="text-xs text-[var(--text-secondary)] truncate">
5050
at {entry.keywordLocation || "/"} · instance {entry.instanceLocation || "/"}
5151
</div>
5252
</div>

‎src/components/CustomDebugger/CustomDebugger.tsx‎

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { useMemo, useRef, useState, useEffect } from "react";
22
import Editor, { type Monaco } from "@monaco-editor/react";
33
import type { editor as MonacoEditor } from "monaco-editor";
44
import { traceCustomSchema } from "../../api/one";
5-
import { defineMonacoTheme, ONE_UI_MONACO_THEME } from "../../utils/monacoTheme";
5+
import { defineMonacoTheme, ONE_UI_EDITOR_FONT_OPTIONS, ONE_UI_MONACO_THEME } from "../../utils/monacoTheme";
66
import { getCollectedAnnotations, getDynamicScope, getOpenFrames } from "../../utils/traceStack";
77
import { computeJsonPositions } from "../../utils/jsonPointerPositions";
88
import type { TraceResult } from "../../types/one";
99
import StackVisualizer from "../TraceDebugger/StackVisualizer";
1010
import AnnotationsPanel from "../AnnotationsPanel";
11+
import { STACK_FONT_KEY, STACK_FONT_OPTIONS, getStoredStackFont } from "../../utils/stackFont";
1112

1213
const PLAY_INTERVAL_MS = 700;
1314
const API_URL_KEY = "one-ui.customDebuggerApiUrl";
@@ -83,6 +84,7 @@ const CustomDebugger = ({ onClose }: { onClose: () => void }) => {
8384
const [error, setError] = useState<string | null>(null);
8485

8586
const [stepIndex, setStepIndex] = useState(0);
87+
const [stackFont, setStackFont] = useState(getStoredStackFont);
8688
const [isPlaying, setIsPlaying] = useState(false);
8789

8890
const instanceEditorRef = useRef<MonacoEditor.IStandaloneCodeEditor | null>(null);
@@ -315,7 +317,7 @@ const CustomDebugger = ({ onClose }: { onClose: () => void }) => {
315317
value={schemaText}
316318
onChange={(value) => setSchemaText(value ?? "")}
317319
onMount={(editorInstance) => (schemaEditorRef.current = editorInstance)}
318-
options={{ minimap: { enabled: false }, fontSize: 12.5, stickyScroll: { enabled: false } }}
320+
options={{ ...ONE_UI_EDITOR_FONT_OPTIONS, minimap: { enabled: false }, fontSize: 13.5, stickyScroll: { enabled: false } }}
319321
/>
320322
</div>
321323
</div>
@@ -337,18 +339,35 @@ const CustomDebugger = ({ onClose }: { onClose: () => void }) => {
337339
value={instanceText}
338340
onChange={(value) => setInstanceText(value ?? "")}
339341
onMount={(editorInstance) => (instanceEditorRef.current = editorInstance)}
340-
options={{ minimap: { enabled: false }, fontSize: 12.5, stickyScroll: { enabled: false } }}
342+
options={{ ...ONE_UI_EDITOR_FONT_OPTIONS, minimap: { enabled: false }, fontSize: 13.5, stickyScroll: { enabled: false } }}
341343
/>
342344
</div>
343345
</div>
344346

345347
<div className="w-80 shrink-0 flex flex-col rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] overflow-hidden">
346348
<div className="px-3 py-1.5 border-b border-[var(--border)]">
347-
<div className="text-xs text-[var(--text-secondary)]">Call Stack</div>
348-
<div className="text-[10px] text-[var(--text-secondary)] opacity-70 mt-0.5">
349+
<div className="flex items-center justify-between gap-2">
350+
<div className="text-sm text-[var(--text-secondary)]">Call Stack</div>
351+
<select
352+
value={stackFont}
353+
onChange={(e) => {
354+
setStackFont(e.target.value);
355+
localStorage.setItem(STACK_FONT_KEY, e.target.value);
356+
}}
357+
title="Font for the stack frame cards"
358+
className="text-xs rounded-[var(--radius-sm)] border border-[var(--border-strong)] bg-[var(--bg-inset)] text-[var(--text-secondary)] px-1 py-0.5 focus:outline-none focus:border-[var(--accent)]"
359+
>
360+
{STACK_FONT_OPTIONS.map((option) => (
361+
<option key={option.value} value={option.value}>
362+
{option.label}
363+
</option>
364+
))}
365+
</select>
366+
</div>
367+
<div className="text-xs text-[var(--text-secondary)] opacity-70 mt-0.5">
349368
Rules currently being checked, deepest on top
350369
</div>
351-
<div className="flex items-center gap-3 mt-1.5 text-[10px]">
370+
<div className="flex items-center gap-3 mt-1.5 text-xs">
352371
<span className="flex items-center gap-1">
353372
<span className="w-2 h-2 rounded-full bg-[var(--border-strong)] inline-block" />
354373
checking
@@ -368,14 +387,14 @@ const CustomDebugger = ({ onClose }: { onClose: () => void }) => {
368387
</div>
369388
{dynamicScope.length > 1 && (
370389
<div className="mt-2 pt-2 border-t border-[var(--border)]">
371-
<div className="text-[10px] text-[var(--text-secondary)] opacity-70">
390+
<div className="text-xs text-[var(--text-secondary)] opacity-70">
372391
Dynamic scope
373392
</div>
374393
<div className="flex flex-col gap-0.5 mt-1">
375394
{dynamicScope.map((resource, i) => (
376395
<span
377396
key={i}
378-
className="text-[10px] font-mono truncate text-[var(--accent)]"
397+
className="text-xs truncate text-[var(--accent)]"
379398
>
380399
{resource || "(this schema)"}
381400
</span>
@@ -385,20 +404,18 @@ const CustomDebugger = ({ onClose }: { onClose: () => void }) => {
385404
)}
386405
</div>
387406
{traceResult ? (
388-
<StackVisualizer frames={openFrames} />
407+
<StackVisualizer frames={openFrames} fontFamily={stackFont} />
389408
) : (
390409
<div className="flex-1 flex items-center justify-center p-4 text-center text-xs text-[var(--text-secondary)]">
391410
Click "Compile & Trace" to run the real Blaze evaluator on your pasted schema and instance.
392411
</div>
393412
)}
394413
</div>
395414

396-
{traceResult && (
397-
<AnnotationsPanel
398-
annotations={collectedAnnotations}
399-
currentInstanceLocation={currentStep?.instanceLocation}
400-
/>
401-
)}
415+
<AnnotationsPanel
416+
annotations={collectedAnnotations}
417+
currentInstanceLocation={currentStep?.instanceLocation}
418+
/>
402419
</div>
403420

404421
{traceResult && (

‎src/components/DetailPanel.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const DetailPanel = () => {
5959
/>
6060
</div>
6161

62-
<div className="p-2">
62+
<div className="p-2 h-48 min-h-32 max-h-128 resize-y overflow-y-auto">
6363
{detailLoading && (
6464
<p className="text-xs text-[var(--text-secondary)] px-1">
6565
Loading…

‎src/components/DirectoryNode.tsx‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useContext, useState } from "react";
22
import { AppContext } from "../contexts/AppContext";
33
import { listDirectory } from "../api/one";
44
import type { DirectoryEntry } from "../types/one";
5-
import HealthBadge from "./HealthBadge";
65

76
const DirectoryNode = ({
87
entry,
@@ -33,7 +32,6 @@ const DirectoryNode = ({
3332
title={entry.path}
3433
>
3534
<span className="truncate">📄 {entry.name}</span>
36-
<HealthBadge health={entry.health} />
3735
</button>
3836
);
3937
}
@@ -70,7 +68,6 @@ const DirectoryNode = ({
7068
<span className="text-[var(--text-secondary)] text-xs">
7169
{entry.schemas}
7270
</span>
73-
<HealthBadge health={entry.health} />
7471
</span>
7572
</button>
7673
{expanded && loading && (

‎src/components/InstanceEditor.tsx‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Editor from "@monaco-editor/react";
33
import { AppContext } from "../contexts/AppContext";
44
import MetadataTable from "./MetadataTable";
55
import DetailPanel from "./DetailPanel";
6-
import { defineMonacoTheme, ONE_UI_MONACO_THEME } from "../utils/monacoTheme";
6+
import { defineMonacoTheme, ONE_UI_EDITOR_FONT_OPTIONS, ONE_UI_MONACO_THEME } from "../utils/monacoTheme";
77
import IdleState from "./IdleState";
88

99
const InstanceEditor = () => {
@@ -111,9 +111,10 @@ const InstanceEditor = () => {
111111
beforeMount={defineMonacoTheme}
112112
value={schemaContent ?? ""}
113113
options={{
114+
...ONE_UI_EDITOR_FONT_OPTIONS,
114115
readOnly: true,
115116
minimap: { enabled: false },
116-
fontSize: 13,
117+
fontSize: 14,
117118
scrollBeyondLastLine: false,
118119
stickyScroll: { enabled: false },
119120
}}
@@ -126,8 +127,9 @@ const InstanceEditor = () => {
126127
value={instanceText}
127128
onChange={(value) => setInstanceText(value ?? "")}
128129
options={{
130+
...ONE_UI_EDITOR_FONT_OPTIONS,
129131
minimap: { enabled: false },
130-
fontSize: 13,
132+
fontSize: 14,
131133
scrollBeyondLastLine: false,
132134
stickyScroll: { enabled: false },
133135
}}

‎src/components/ResultPanel.tsx‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,22 @@ import { useContext } from "react";
22
import { AppContext } from "../contexts/AppContext";
33
import type { TraceStep } from "../types/one";
44

5-
const stepStyle: Record<TraceStep["type"], string> = {
6-
push: "text-[var(--text-secondary)] border-[var(--border)]",
7-
pass: "text-[var(--success)] border-[var(--success)]/40 bg-[var(--success-soft)]",
8-
fail: "text-[var(--danger)] border-[var(--danger)]/40 bg-[var(--danger-soft)]",
9-
};
5+
const stepStyle =
6+
"text-[var(--text-secondary)] border-[var(--border)] bg-[var(--bg-inset)]/50";
107

118
const badgeStyle: Record<TraceStep["type"], string> = {
12-
push: "text-[var(--text-secondary)] bg-[var(--bg-inset)] border-[var(--border-strong)]/60",
13-
pass: "text-[var(--success)] bg-[var(--success)]/15 border-[var(--success)]/40",
14-
fail: "text-[var(--danger)] bg-[var(--danger)]/15 border-[var(--danger)]/40",
9+
push: "text-[var(--text-secondary)] bg-[var(--bg-inset)] border-[var(--border-strong)]",
10+
pass: "text-[var(--success)] bg-[var(--success)]/20 border-[var(--success)]/60",
11+
fail: "text-[var(--danger)] bg-[var(--danger)]/20 border-[var(--danger)]/60",
1512
};
1613

1714
const TraceStepRow = ({ step, index }: { step: TraceStep; index: number }) => (
1815
<div
19-
className={`text-xs border rounded-[var(--radius-sm)] px-2 py-1.5 ${stepStyle[step.type]}`}
16+
className={`text-xs border rounded-[var(--radius-sm)] px-2 py-1.5 ${stepStyle}`}
2017
>
2118
<div className="flex items-center gap-2">
2219
<span
23-
className={`uppercase font-mono text-[10px] font-semibold tracking-wide px-1.5 py-0.5 rounded-full border shrink-0 ${badgeStyle[step.type]}`}
20+
className={`uppercase text-xs font-bold tracking-wide px-2.5 py-1 rounded-full border shrink-0 ${badgeStyle[step.type]}`}
2421
>
2522
{step.type}
2623
</span>

‎src/components/TraceDebugger/StackVisualizer.tsx‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ const statusStyle: Record<OpenFrame["status"], string> = {
99
const annotationStyle =
1010
"border-[var(--info)] bg-[var(--info-soft)] text-[var(--info)]";
1111

12-
const StackVisualizer = ({ frames }: { frames: OpenFrame[] }) => (
12+
const StackVisualizer = ({
13+
frames,
14+
fontFamily,
15+
}: {
16+
frames: OpenFrame[];
17+
fontFamily?: string;
18+
}) => (
1319
<div
1420
className="relative flex-1 min-h-0 flex flex-col-reverse items-center justify-start gap-0 py-8 overflow-hidden"
1521
style={{ perspective: "900px" }}
@@ -25,24 +31,25 @@ const StackVisualizer = ({ frames }: { frames: OpenFrame[] }) => (
2531
return (
2632
<div
2733
key={frame.pushIndex}
28-
className={`w-[min(90%,26rem)] shrink-0 rounded-[var(--radius-sm)] border px-3 py-2 text-xs font-mono shadow-[var(--shadow-md)] transition-all duration-300 ease-out ${hasAnnotation ? annotationStyle : statusStyle[frame.status]}`}
34+
className={`w-[min(92%,28rem)] shrink-0 rounded-[var(--radius-sm)] border px-4 py-3 text-sm shadow-[var(--shadow-md)] transition-all duration-300 ease-out ${hasAnnotation ? annotationStyle : statusStyle[frame.status]}`}
2935
style={{
36+
fontFamily,
3037
transform: `translateZ(${-distanceFromTop * 34}px) translateY(${-distanceFromTop * 10}px) scale(${Math.max(1 - distanceFromTop * 0.035, 0.7)})`,
3138
opacity: Math.max(1 - distanceFromTop * 0.08, 0.35),
32-
marginTop: depth === 0 ? 0 : -28,
39+
marginTop: depth === 0 ? 0 : -30,
3340
zIndex: depth + 1,
3441
}}
3542
>
3643
<div className="flex items-center justify-between gap-2">
37-
<span className="uppercase text-[10px] tracking-wide opacity-70">
44+
<span className="uppercase text-xs tracking-wide opacity-70">
3845
{hasAnnotation ? "annotation" : frame.status}
3946
</span>
40-
<span className="text-[10px] opacity-50">#{frame.pushIndex + 1}</span>
47+
<span className="text-xs opacity-50">#{frame.pushIndex + 1}</span>
4148
</div>
42-
<div className="truncate font-semibold">{frame.name}</div>
49+
<div className="truncate font-semibold text-base mt-0.5">{frame.name}</div>
4350
<div className="truncate opacity-70">{frame.evaluatePath}</div>
4451
{hasAnnotation && (
45-
<div className="truncate mt-0.5 text-[10px] opacity-90">
52+
<div className="truncate mt-1 text-xs opacity-90">
4653
→ {JSON.stringify(frame.annotation)}
4754
</div>
4855
)}

‎src/components/TraceDebugger/TraceDebugger.tsx‎

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import type { editor as MonacoEditor } from "monaco-editor";
44
import { AppContext } from "../../contexts/AppContext";
55
import { getSchemaPositions } from "../../api/one";
66
import type { SchemaPositions } from "../../types/one";
7-
import { defineMonacoTheme, ONE_UI_MONACO_THEME } from "../../utils/monacoTheme";
7+
import { defineMonacoTheme, ONE_UI_EDITOR_FONT_OPTIONS, ONE_UI_MONACO_THEME } from "../../utils/monacoTheme";
88
import { getCollectedAnnotations, getDynamicScope, getOpenFrames } from "../../utils/traceStack";
99
import StackVisualizer from "./StackVisualizer";
1010
import AnnotationsPanel from "../AnnotationsPanel";
11+
import { STACK_FONT_KEY, STACK_FONT_OPTIONS, getStoredStackFont } from "../../utils/stackFont";
1112

1213
const PLAY_INTERVAL_MS = 700;
1314

@@ -39,6 +40,7 @@ const TraceDebugger = () => {
3940
} = useContext(AppContext);
4041

4142
const [stepIndex, setStepIndex] = useState(0);
43+
const [stackFont, setStackFont] = useState(getStoredStackFont);
4244
const [isPlaying, setIsPlaying] = useState(false);
4345
const [schemaPositions, setSchemaPositions] = useState<SchemaPositions | null>(null);
4446

@@ -245,7 +247,7 @@ const TraceDebugger = () => {
245247
beforeMount={beforeMount}
246248
value={schemaContent ?? ""}
247249
onMount={handleSchemaMount}
248-
options={{ readOnly: true, minimap: { enabled: false }, fontSize: 12.5, stickyScroll: { enabled: false } }}
250+
options={{ ...ONE_UI_EDITOR_FONT_OPTIONS, readOnly: true, minimap: { enabled: false }, fontSize: 13.5, stickyScroll: { enabled: false } }}
249251
/>
250252
</div>
251253
</div>
@@ -266,20 +268,37 @@ const TraceDebugger = () => {
266268
beforeMount={beforeMount}
267269
value={instanceText}
268270
onMount={handleInstanceMount}
269-
options={{ readOnly: true, minimap: { enabled: false }, fontSize: 12.5, stickyScroll: { enabled: false } }}
271+
options={{ ...ONE_UI_EDITOR_FONT_OPTIONS, readOnly: true, minimap: { enabled: false }, fontSize: 13.5, stickyScroll: { enabled: false } }}
270272
/>
271273
</div>
272274
</div>
273275

274276
<div className="w-80 shrink-0 flex flex-col rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] overflow-hidden">
275277
<div className="px-3 py-1.5 border-b border-[var(--border)]">
276-
<div className="text-xs text-[var(--text-secondary)]">
277-
Call Stack
278+
<div className="flex items-center justify-between gap-2">
279+
<div className="text-sm text-[var(--text-secondary)]">
280+
Call Stack
281+
</div>
282+
<select
283+
value={stackFont}
284+
onChange={(e) => {
285+
setStackFont(e.target.value);
286+
localStorage.setItem(STACK_FONT_KEY, e.target.value);
287+
}}
288+
title="Font for the stack frame cards"
289+
className="text-xs rounded-[var(--radius-sm)] border border-[var(--border-strong)] bg-[var(--bg-inset)] text-[var(--text-secondary)] px-1 py-0.5 focus:outline-none focus:border-[var(--accent)]"
290+
>
291+
{STACK_FONT_OPTIONS.map((option) => (
292+
<option key={option.value} value={option.value}>
293+
{option.label}
294+
</option>
295+
))}
296+
</select>
278297
</div>
279-
<div className="text-[10px] text-[var(--text-secondary)] opacity-70 mt-0.5">
298+
<div className="text-xs text-[var(--text-secondary)] opacity-70 mt-0.5">
280299
Rules currently being checked, deepest on top
281300
</div>
282-
<div className="flex items-center gap-3 mt-1.5 text-[10px]">
301+
<div className="flex items-center gap-3 mt-1.5 text-xs">
283302
<span className="flex items-center gap-1">
284303
<span className="w-2 h-2 rounded-full bg-[var(--border-strong)] inline-block" />
285304
checking
@@ -299,14 +318,14 @@ const TraceDebugger = () => {
299318
</div>
300319
{dynamicScope.length > 1 && (
301320
<div className="mt-2 pt-2 border-t border-[var(--border)]">
302-
<div className="text-[10px] text-[var(--text-secondary)] opacity-70">
321+
<div className="text-xs text-[var(--text-secondary)] opacity-70">
303322
Dynamic scope
304323
</div>
305324
<div className="flex flex-col gap-0.5 mt-1">
306325
{dynamicScope.map((resource, i) => (
307326
<span
308327
key={i}
309-
className="text-[10px] font-mono truncate text-[var(--accent)]"
328+
className="text-xs truncate text-[var(--accent)]"
310329
>
311330
{resource || "(this schema)"}
312331
</span>
@@ -315,7 +334,7 @@ const TraceDebugger = () => {
315334
</div>
316335
)}
317336
</div>
318-
<StackVisualizer frames={openFrames} />
337+
<StackVisualizer frames={openFrames} fontFamily={stackFont} />
319338
</div>
320339

321340
<AnnotationsPanel

0 commit comments

Comments
 (0)