Skip to content

feat(ui): direction D design and a light theme - #300

Merged
sunerpy merged 6 commits into
mainfrom
feat/ui-design-d
Oct 3, 2026
Merged

sunerpy merged 6 commits into
mainfrom
feat/ui-design-d

Conversation

@sunerpy

@sunerpy sunerpy commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

Phase 1, part B of the browser viewer: the upstream frontend that PR #298 serves, redrawn in the design the owner selected (docs/design/viewer-d.md, Penpot direction D), with a dark and a light theme. The server, the wire contract and the models' behaviour are untouched. This is a frontend-only change plus the committed bundle and docs.

  • Tokens. ui/src/lib/theme.css defines:

    • both token sets — Nebula (dark, §3.1) and Daylight (light, §3.6) — under the same 39 names, plus the 15 §3.2 aliases, so upstream rules paint with D;
    • effects (§4) as named shadow and glow variables, with the light set's softer values;
    • the four gradients and the canvas;
    • type roles (§5) as font shorthands.

    Upstream's global border-radius: 0 !important is gone.

  • Theme choice. prefers-color-scheme by default. A System / Dark / Light control stores the choice in localStorage under codegraph-ui.theme and applies it as data-theme on <html>, using upstream's own mechanism. It sits in the nav-rail foot on desktop and tablet, and in the More sheet on the phone. ui/tests/theme-contrast.test.ts parses both sets from theme.css and fails if any declared pair drops below 4.5:1. It also pins that the four copies of the sets agree and that the SVG export's palettes are the same colours.

  • Type and icons. Inter and JetBrains Mono come from @fontsource-variable (OFL), normal style only; Archivo and IBM Plex Mono are dropped and the bundle shrinks. Ligatures are off, so -> reads as written. Lucide 0.544 icon geometry (ISC, notice kept) is inlined in ui/src/lib/icons.ts and drawn as CSS masks, so icons add no SVG nodes.

  • Shell (§2).

    • 64 px icon nav rail;
    • 56 px command bar with the ⌘K / Ctrl+K palette, which dims the page;
    • 40 px trail ribbon with a +N fold for earlier hops and a read-only pill in place of Save;
    • 8 px-gapped islands with radius 12.
  • Views (§8).

    • Start is the D-01 dashboard, fed by /api/stats, /api/entrypoints and /api/trails.
    • Symbol (D-02):
      • the rails are 288 and 320 px wide;
      • callee rows are 44 px, placed by y = max(lineY − 22, previous + 52);
      • the code card has call capsules, ports and a hot line;
      • Blast radius is drawn as stat tiles at the foot of the Called by island;
      • a "Filter callers" box narrows the Called by rail.
    • File (D-03), Flow (D-04, with the Every hop table), Map (D-05: inspector tabs, toolbar, minimap, one-line key), Type hierarchy (D-06) and Dead code (D-07) follow their boards.
    • Entry points, saved trails and the whole-file source view use the same recipes.
    • Screens and Steps keep upstream's empty and "cannot draw steps" states, restyled. Their populated canvases are phase 3.
  • States (§9).

    • loading skeletons;
    • the amber drift callout;
    • an error card with the remedy command and Retry;
    • long-name truncation with a tooltip;
    • the empty palette with its scrim;
    • the keyboard focus ring;
    • the read-only pill.
  • Responsive (§10).

    • Up to 1023 px: a 56 px rail; Called by becomes a drawer behind a header button.
    • Up to 599 px: a bottom tab bar (Start / Map / Symbol / Flow / More); a Code / Called by / Calls segmented control; tapping a call opens a bottom sheet with Open and Read as flow.
  • Measured constants. The Inter and JetBrains Mono advances were measured in Chrome. Results:

    • map label 7.81 → 7.2;
    • map meta 5.9 → 5.5;
    • flow label 6.65 → 6.6;
    • screens pill 6.3 (unchanged).

    Layout constants that moved with the design are pinned by name in the suites: hierarchy rows and indent, outline pitch, and map node height and gaps.

  • Export. export-svg.ts carries both palettes as literal hex. Copy image and Download SVG paint the theme on screen, and light remains the function default.

  • Docs.

    • docs/ui.md gains "Look and themes" and "Direction D as built", a 偏离 table of every place the build differs from the boards;
    • the imported ui/README.md now points at docs/ui.md, and its font, geometry and export passages match the build;
    • UPSTREAM.md gains a dated entry, because the restyle is a local layer a later upstream ui/ sync must re-apply.

Tests moved, and why

  • ui-steps-model: a test computed the row pitch with the literal 40, which was upstream's map node height. It now uses NODE_HEIGHT, so the assertion ("at most three lines") is unchanged.
  • ui-export-svg: the font assertion now expects 'JetBrains Mono' instead of 'IBM Plex Mono'.
  • ui-hierarchy-model, ui-map-model and ui-file-model pin the moved constants by name and pass unchanged.

New suites:

  • theme-contrast — the declared pairs on both sets, block agreement, and export palettes;
  • ui-d-symbol-rails — the caller filter and the callee-row placement;
  • ui-d-highlight — syn-type and syn-punct classing.

Verification (evidence under /tmp/evidence-ui/)

  • make pre-ci exited 0 on the head cfb9dd9, run by the pre-push hook, and on af64bc7 (pre-ci-b2.log):

    • fmt, oxfmt, docs-check, actionlint, shellcheck and clippy -D warnings all pass;
    • 4343 Rust tests passed, 0 failed;
    • guardrail passes;
    • make ui-check passes: npm ci, svelte-check with 0 errors, vitest 20 files / 569 tests, and a fresh build byte-identical to the committed bundle;
    • the release-archive smoke passes.

    PR-B changes no Rust source (git diff 143752a..cfb9dd9 -- crates ':!crates/codegraph-ui/viewer' is empty), so golden output cannot move.

  • Every commit was checked out alone in a throwaway worktree: svelte-check reports 0 errors at each, and vitest passes 560, 560, 569, 569, 569 and 569 tests.

  • The contrast suite fails when a pair is weakened. Daylight fg-3 set to #8a93a6 failed 8 cases; the original value is restored and passes.

  • Browser acceptance, bound to the head:

    • release binary built from the head cfb9dd9 (sha256 27dc6775…30e3, byte-identical to af64bc7's: the last commit is docs and comments only);
    • git archive cfb9dd9 indexed by it (690 files, 22,471 nodes), plus the NestJS routed fixture;
    • headless Chrome over CDP, with every report carrying meta.head, the tree and the binary sha256;
    • 13 routes on the repository (Start, Entry, Symbol, hierarchy, File, whole-file source, Flow, Map, Dead code, Screens, Steps, a missing symbol and an unknown route) and 4 on the routed fixture;
    • each at 375 / 768 / 1280 / 1440, in dark and in light: 136 page loads with 0 console errors, 0 exceptions, 0 failed requests and no horizontal overflow (accept-b-{repo,routed}-{dark,light}.json, screenshots shots-b/).
  • State captures (states-b/, release binary at the head):

    • the read-only pill, from a --read-only server, in both themes;
    • the drift callout, from a copy edited after indexing, in both themes;
    • loading skeletons;
    • the empty palette with its scrim;
    • the keyboard focus ring;
    • long-name truncation with its tooltip, in both themes;
    • the theme menu;
    • the phone More sheet and line sheet;
    • the tablet Called by drawer.

🤖 Generated with Claude Code

CodeGraph Test added 5 commits October 3, 2026 07:00
Replace upstream's paper/ink tokens with the two sets of the selected
design (docs/design/viewer-d.md): Nebula for dark and Daylight for light,
under the same names, with the spec's effects, gradients, canvas and type
roles, and upstream's names kept as aliases so every existing rule paints
with them. Drop the global square-corner rule.

The viewer follows prefers-color-scheme until the reader picks System,
Dark or Light; the choice is stored under codegraph-ui.theme and applied
as data-theme on the page. A contrast suite reads both sets from
theme.css and fails on any declared pair under 4.5:1.

Bundle Inter and JetBrains Mono instead of Archivo and IBM Plex Mono,
turn ligatures off, draw Lucide icons as masks, colour kind tiles by
family, and let the SVG export paint either set.
Replace the top tab bar with the design's icon nav rail, the command bar
with its search palette and index status, and the trail ribbon, with the
theme switch, the shortcut sheet and the viewer facts in the rail's foot.
Below 1024px the rail narrows and search folds into a button; below 600px
a bottom tab bar and a More sheet take the rail's place. Add the error
card and the amber drift callout the views share.
Lay every view out as the design's islands: Start as a dashboard of what
the index holds, Symbol with its line-anchored Calls rail, code card,
caller filter and blast radius tiles, File, Flow with an Every hop table,
Map with a tabbed inspector, Type hierarchy, Dead code, Entry points and
saved trails, and the Screens and Steps empty states.

Draw the loading, drift, error, long-name, empty-search, keyboard-focus
and read-only states, the tablet drawer and the phone panes and sheet.
Layout constants measured against the old fonts and geometry move with
the design, each pinned by name in the suites.
Describe the shell, the breakpoints, the two themes and how one is
chosen, and list every place the build differs from the boards. Record
the restyle in the upstream ledger as a local layer a later ui/ sync
re-applies.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af64bc75ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

label: 'Start',
short: 'Start',
icon: 'layout-dashboard',
href: '#/',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Give Start a route that does not alias Screens

When the indexed graph contains any navigates edge, hasScreens becomes true and App.svelte renders ScreensView for the home route. Consequently this #/ href makes the new Start destination, brand link, and project link all reopen Screens instead of the dashboard, leaving HomeView unreachable for exactly those projects; use a distinct dashboard route or stop overloading home.

Useful? React with 👍 / 👎.

Comment on lines +205 to +206
{:else}
{@render skeleton(6)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop treating failed dashboard requests as loading

If /api/entrypoints fails, the palette store sets entriesFailure and entriesSettled while leaving entries null, but this branch and the other entry-backed cards continue rendering skeletons indefinitely. The Entry view already distinguishes that settled failure, so the Start dashboard should surface it (and a retry) rather than presenting a completed request as perpetual loading.

Useful? React with 👍 / 👎.

Comment thread docs/ui.md
written. The icons are Lucide (ISC) geometry, copied into
`ui/src/lib/icons.ts` with its notice.

### Direction D as built — 偏离(画板 vs 落地,供 owner 复核)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the canonical heading in English

docs/ui.md is the canonical technical reference, but this heading includes Chinese text; replace it with an English-only heading so the page follows the repository's explicit canonical-documentation language rule.

AGENTS.md reference: docs/AGENTS.md:L5-L6

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Oct 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #300   +/-   ##
=======================================
  Coverage   95.05%   95.05%           
=======================================
  Files         197      197           
  Lines      108387   108387           
=======================================
  Hits       103023   103023           
  Misses       5364     5364           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The imported ui/README.md and the package comment still described
upstream's fonts, rail geometry and always-light exports. Point the
README at docs/ui.md and the design spec, correct those passages, and
note that the end-cap width estimate was re-measured against Inter.
@sunerpy
sunerpy merged commit fee9ae7 into main Oct 3, 2026
19 of 20 checks passed
@sunerpy
sunerpy deleted the feat/ui-design-d branch October 3, 2026 00:01
@github-actions github-actions Bot mentioned this pull request Oct 3, 2026
sunerpy added a commit that referenced this pull request Oct 3, 2026
The spec now says the viewer is built to its numbers since #300 and points at the deviation log in docs/ui.md; §13 records that §3.6 settled the light variant and that the build turned ligatures off for the owner to review.
sunerpy added a commit that referenced this pull request Oct 3, 2026
The release record for #298, #300 and #303: the release PR merge and its tag
SHA, the workflow run, the published digest, and the black-box acceptance
against v0.52.2. Current alignment now lists v0.53.0 and marks the viewer as
shipped.

Co-authored-by: CodeGraph Test <codegraph@example.invalid>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant