Skip to content

Map and book: a one-row local graph toolbar, links between the cards, splitter grips - #803

Merged
Deicyde merged 12 commits into
mainfrom
feat/local-graph-readability
Nov 13, 2026
Merged

Deicyde merged 12 commits into
mainfrom
feat/local-graph-readability

Conversation

@Deicyde

@Deicyde Deicyde commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Premise

  • User: a reader who opens a result's local dependency graph on the map or in the book, and resizes the book's panes.
  • Problem:
    1. The panel over a local graph took a corner of the stage with the result's title, the level buttons, a sentence of counts and a Back button, over the graph's top-left cards.
    2. The graph's links were curves that crossed the cards between their ends. At level 3 they ran across each other and behind cards.
    3. The book's pane splitters were 8px wide for a mouse and showed nothing until hovered, so a reader could not see where to drag.
  • Replaces: nothing. The level rules from Local graph: a level that adds nothing can't be chosen #793 and Local graph: pressing the level drawn in place of the chosen one makes it the choice #797 are unchanged.

What changes

  • Toolbar. showLocalPanel builds one row:

    • ← Map, labelled "Back to the map";
    • the level buttons, under main's rules (a level that adds nothing is disabled, and there are no levels where none adds anything);
    • the count, N / M, with the full sentence as its title (a result that builds on nothing says so in words);
    • a Details button (aria-expanded) that shows the title and the hub chips below the row.

    It is a button rather than <details> because Material draws a <details> in the book as a note box. Details stays open when the focus or the level changes.

  • Links. AutoformMapLayout.routeColumns(routes, boxes) routes a local graph's links through the gaps between its columns and cards. It transposes the boxes and reuses routeThroughGaps, which already routes the whole-project map's links between rows. localLink draws the routed path and puts a "via n" label at the route's midpoint by length. Links that don't touch the focus are drawn at 40%, and 80% on hover.

    • A link between two cards side by side runs straight. The sweep that keeps ports across a corridor a lane apart no longer moves a route's own end away from its start; this holds on the whole-project map too.
    • A link that skips a column with one or two cards passes just above or below that column's cards (localEnds), not round the top or bottom of the whole graph.
  • Splitters.

    • Each is 20px wide with a grip at its middle, in GrayText and Highlight under forced colours. The line still shows only while the splitter is hovered or dragged.
    • Where the browser refuses pointer capture, the drag continues through window listeners for the dragging pointer away from the splitter. Any release the splitter itself hears ends the drag, as before.
    • Its focus ring is drawn inside the part that takes presses.
    • Over a shut map, for a mouse, the reader's splitter narrows to 8px without the grip. The map's and Contents' tabs under it stay clickable, and a drag at its middle still opens the map. A finger's 24px splitter still sits under the raised tabs.
  • Bundle. blueprint-explorer.min.js is rebuilt from blueprint-dag.js.

  • CHANGELOG. Two Changed entries and one Fixed entry.

Left as is

  • At the opening zoom, a long chain's far end is off the stage, because the camera keeps titles readable and anchors on the focus; zooming out shows it. This is unchanged from main.
  • The arrowheads of several links into the focus meet close together at its left edge.
  • A long title on the focus card is cut with an ellipsis, as on main.

Checks

  • Tests for new behavior, a CHANGELOG line for each user-visible change.
    • tests/ui/test_project_map_browser.py:
      • test_local_graph_controls_are_compact_and_details_are_optional: one row under 72px; Details shows the title; Back closes the graph.
      • test_rendered_local_connections_do_not_cross_unrelated_result_cards: a 16-result chain at level 3, zoomed out, draws all 17 links, and none runs through a card it doesn't join.
      • The levels browser test reads the compact count.
    • tests/ui/test_dag_viewer_browser.py: test_pane_dividers_can_be_grabbed_on_both_sides_of_the_visible_border (4 cases) and test_pane_drag_continues_if_the_browser_refuses_pointer_capture (2 cases).
    • tests/ui/test_local_graph_routes.py: routes on a layered grid cross no card they don't join, and a link between two cards side by side is one straight segment.
    • tests/ui/test_project_map_client.py:
    • tests/ui/test_graph_view_rendering.py: the grip and its forced-colours rules.
  • A scratch copy of this head passed every job: https://github.com/facebookresearch/autoform-bot/actions/runs/43447723705
  • Screenshots, before (main) and after, of a 24-result fixture, in the screenshots artifact of each run:

Posted by Claude Code, at Jack's request.

Deicyde and others added 8 commits November 12, 2026 23:25
- A drag ends on any release the splitter hears, as before the grip change;
  the window only hears the dragging pointer away from the splitter, where
  the browser gave no pointer capture. A browser taking the pointer back sent
  pointerId 0 and left the drag running.
- The map's and Contents' tabs over a shut map's edge stand above the reader's
  splitter, as they did for touch: at 20px it covered their middle.
- The splitter's line is shown again only while hovered or dragged; the grip
  marks it, and keeps a system colour in forced colours.
- The routing test zooms out to the whole level-3 graph and counts all 17
  links; at the opening zoom the chain's far end is off the stage.
At 20px and above the tabs, the reader's splitter could not be dragged at
its middle, where the map's tab sits, so a drag there opened nothing. Over
a shut map it now narrows to its old 8px, without the grip, and the tabs
stand under it again, as before the grip change; a finger's 24px splitter
still sits under them.
In the book, Material drew the panel's <details> as a note box, with an
icon and a border, which made the panel taller than the one it replaced.
Details is now a button in the toolbar row that shows the title and the
hub chips below it. Links that don't touch the focus were drawn at 14%,
too faint to follow; they are at 40%. The CHANGELOG says what changed.
- Details kept its state in a variable that showLocalPanel declared again
  for the chips' "+N more" button. With more than 12 hubs, a press on
  Details marked "+1 more" expanded and left Details collapsed, and the
  next redraw closed it. The toggle has its own name and class now, and the
  hubs test checks its state before and after a chip opens another graph.
- A splitter 20px wide took presses 10px into Contents and into the
  statement list, over their scrollbars. It now takes presses only 4px into
  the pane on its left, as the 8px splitter did, and the grab test checks
  that a press 7px in reaches the pane.
- A dotted via link between two results off the focus is drawn as faint as
  a plain one.
- The keyboard chip test opens Details before it reaches a chip.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 13, 2026
@Deicyde

Deicyde commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

Review at ab9dfa7: no blockers.

The before and after screenshots, against Jack's three complaints:

  • The panel: it is now one row (← Map, the levels, 5 / 18, Details), where before it was a 160px card over the graph's corner.
  • Dragging panes: both splitters show a grip. The drag tests cover each side of the border and a refused pointer capture.
  • The lines: no link crosses a card now. At level 3, though, the faint links off the focus still loop above and below the middle column (map-sylow-level3.png). Jack should judge that one against "lines going everywhere".

The bundle diff is only the blueprint-dag change. Of the bundle's three inputs, only blueprint-dag.js changed. At both the base (9e1d2b7, 81,720 bytes) and the head (82,138 bytes), the committed bundle rebuilds byte for byte with esbuild 0.28.2 and Terser 5.51.2 (node scripts/build-explorer.mjs --check). 53f16c8, which came after the screenshots, changes no layout: only the splitter's hit area, a rename, and the opacity of via links off the focus.

Nits:

  • A link between two cards in one row steps down a few pixels halfway, as from the focus to "No simple pq" on the map and in the book.
  • The splitter's clip-path also cuts off the left side of the focus ring that its CSS comment promises.

Posted by Claude Code, at Jack's request.

- A link between two cards side by side stepped a lane halfway: the sweep
  that keeps ports across a corridor apart also moved a route's own end
  away from its start. A route's two ends may now share a line, on the
  whole-project map too, and the link runs straight.
- A link skipping a column with one or two cards went round it at the top
  or bottom of the whole graph. Local graphs now also pass a column just
  past its own first and last cards, where it leaves room.
- The splitter draws its focus ring inside the part that takes presses;
  the clip cut off its left side.
@Deicyde

Deicyde commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

Blockers-only check at d05bda2: no blockers.

  • Both nits are fixed. The straight pair route is one segment, and the new routeColumns test pins it. The splitter's focus ring is now drawn 8px inside the splitter, within the part its clip keeps (2px inside on the 8px splitter over a shut map).
  • Level 3: in the new screenshot, the faint links pass just beside the middle column instead of looping round the graph.

The whole-project map is not byte-identical, though:

  • localEnds is local-only.
  • The change that lets a route's own two ends meet applies to every caller of routeThroughGaps.
  • Across 357 random layouts built the way layoutCommunity builds them (3,983 routes), 55 routes change. Every one is a route between adjacent rows that now runs straight where before it stepped a lane. No other route moves, and comparing the old version with itself changes nothing.

That is the same fix, applied to the whole map. If it's meant, the CHANGELOG could say so.

No bundle rebuild is needed: none of the bundle's three inputs changed, and no built asset embeds project-map-layout.js. Checks are green at d05bda2.

Posted by Claude Code, at Jack's request.

@Deicyde
Deicyde marked this pull request as ready for review November 13, 2026 21:24
@Deicyde
Deicyde merged commit 2e0724f into main Nov 13, 2026
9 checks passed
@Deicyde
Deicyde deleted the feat/local-graph-readability branch November 13, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant