Skip to content

fix(canvas): Focus mode dims the connections outside the focus set (v0.21.1) - #331

Merged
MerciHanrim merged 1 commit into
mainfrom
fix/focus-edge-dimming
Oct 7, 2026
Merged

MerciHanrim merged 1 commit into
mainfrom
fix/focus-edge-dimming

Conversation

@MerciHanrim

@MerciHanrim MerciHanrim commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Part of #330. A bug fix for the problem reported in #329, released as v0.21.1 (the release date is set to the actual merge day before merging). It is the prerequisite of the play execution visualization work.

The bug

With Focus mode on, the nodes outside the focus set were dimmed as docs/large-graph-readability.md §LGR3.1 specifies, but the connections outside it were drawn at full strength. Measured on main 6de1852 and on production v0.21.0: every connection outside the set had the lgr-deemph class, and its path's computed opacity was 1, at rest and during a played step.

Cause

  • src/components/edges/LoopEdge.tsx passed opacity: activatorOn === false ? 0.5 : 1 as an inline style on every connection path (since e7a401d).
  • The Focus rule .react-flow__edge.lgr-deemph .react-flow__edge-path { opacity: 0.26 } came later (986eed5). An inline style beats a stylesheet rule, so it never applied.
  • The tests asserted the class on a connection, not its drawn opacity.

The fix

  • The unsatisfied activator's 0.5 is now the .edge-activator-off class in src/index.css; the inline opacity is gone. The Focus rule has the higher specificity, so it wins.
  • Under forced colours a dimmed connection gets opacity: 1; the existing sparse 1 5 dash stays its tell.
light and dark forced colours
outside the focus set 0.26, path and arrowhead 1, with the 1 5 dash
outside, unsatisfied activator 0.26 (Focus wins over 0.5) 1, with the 1 5 dash
inside, unsatisfied activator 0.5, as before 0.5, as before
inside, satisfied or no activator 1, as before 1, as before

Labels, the selection underlay, nodes, the playback tokens and cues, files, digests, the engine and the simulation are unchanged.

Before and after

  • Measured with the same script on the same dev server, before on main 6de1852 and after on this branch, in light, dark and forced colours: a state graph with one satisfied and one unsatisfied activator, Focus anchored on each side; two isolated connections for the arrowhead; and a played step paused mid-travel.
  • The only differences are the dimmed paths' opacity, the removed inline value, the new class and the arrowhead pixels (dimmed in light and dark with the path, since it is the path's own marker). Labels (48 readings), nodes (66), dashes, strokes, and the playback tokens' opacity and colour are identical.
  • The first comparison had no selected connection, so it held no selection underlay sample. That was measured separately, on the old and the new code: a selected connection's underlay is 1 inside the focus set and 0.26 outside it, in the same colour, before and after, in all three themes.

Visual baselines

No baseline changes, and none was updated. No existing baseline is taken with Focus mode on: the one screenshot test that turns Focus on turns it off before its shot, and an unsatisfied activator draws at the same 0.5 as before. Every screenshot spec on chromium and mobile passed without an update: 321 passed, 5 skipped by design.

Tests

  • e2e/focus-edge-dimming.spec.ts (4) reads the drawn opacity: Focus inside and outside times activator satisfied and unsatisfied, in light and dark; forced colours (opacity 1 and the 1 5 dash); and a played step, where the dimmed path is 0.26 while the token keeps its opacity and colour. All four fail on the old code and pass on the fix, three repeats in a row.
  • e2e/whats-new.spec.ts pins 0.21.1.
  • Copy guards move only their exact pins: catalog 1030 to 1033, runtime 1252 to 1255, pt-PT's difference from pt-BR 275 to 277, two new ё words for ru. No bound is widened. pt-PT's difference outside the password keys is now 249 against its quarter bound of 249.75; one of the three release-note lines reads the same in pt-BR and pt-PT to keep it there.

Release

  • Version 0.21.1, .changes/focus-edge-dimming.json, release note release:0.21.1 with three lines in 18 languages, 16 without native review.
  • Docs: docs/large-graph-readability.md §LGR3.1, CHANGELOG.md, README.md.

Verification (local, at the head commit)

  • npx tsc -b, oxlint (39 warnings, the existing baseline, 0 errors), 3,207 unit tests, all 21 source checks of the CI checks job, and the list of 1,997 tests in exactly one of the 5 shards.
  • End to end in Chrome on a freshly started dev server, without retries: the new spec and What's new 100 passed; every screenshot spec on chromium and mobile 321 passed, 5 skipped by design; the whole mobile project 109 passed, 4 skipped by design; i18n-vi 26 passed; the playback, Focus, state, routing and forced-colours specs 309 passed; the portable file 16 of 16, the production bundle 16 of 16, the PWA 19 of 19.

CI

  • Run 37587632467 at 29dec5d, the head: every job passed and the union is exact (1,997: 1,990 passed, 7 skipped by design, 0 failed, 0 retried).
  • The Cloudflare preview of the head serves v0.21.1 · build 29dec5d, and its automated check through the real UI passed 21 of 21 with no page error, in light, dark and forced colours: no inline opacity left; the four Focus x activator combinations (outside 0.26 in light and dark, 1 with the 1 5 dash under forced colours; an unsatisfied activator 0.5 inside and Focus winning outside); the dimmed arrowhead painted fainter with its path in light and dark and not faded under forced colours; the selection underlay 1 inside the focus set and 0.26 outside, as on main; and, during a played step, the dimmed paths dimmed while every token keeps opacity 1 and one colour.

Not claimed

  • No manual check of this pull request's preview; its Cloudflare preview is checked by automation.
  • No manual screen-reader check; this changes no text in the canvas and no accessibility tree.
  • 16 of the 18 languages have not been reviewed by a native speaker.

…0.21.1)

The bug reported in #329; part of #330. Version 0.21.1.

Cause: src/components/edges/LoopEdge.tsx passed `opacity: activatorOn === false ? 0.5 : 1` as an inline style on every connection path (since e7a401d). The Focus rule `.react-flow__edge.lgr-deemph .react-flow__edge-path { opacity: 0.26 }` came later (986eed5), and an inline style beats a stylesheet rule, so a connection outside the focus set was never dimmed; only the nodes were. The tests asserted the class, not the drawn opacity.

Fix: the unsatisfied activator's 0.5 is now the `.edge-activator-off` class (src/index.css), and the inline `opacity` is gone. The Focus rule has the higher specificity, so a connection outside the focus set is 0.26, its path and its arrowhead (the arrowhead is the path's own marker), whatever its activator says; an unsatisfied activator inside the focus set keeps its 0.5. Under forced colours a dimmed connection is not faded: opacity 1, and the existing sparse `1 5` dash stays its tell. Labels, the selection underlay, nodes, the playback tokens and cues, files, digests and the simulation are unchanged.

Measured before and after on the same dev server with the same script, light, dark and forced colours: the only differences are the dimmed paths' opacity (1 to 0.26 in light and dark; an unsatisfied activator outside the focus set 0.5 to 0.26, and 0.5 to 1 under forced colours), the removed inline value, the new class and the arrowhead pixels. The first comparison had no selected connection, so the selection underlay was measured separately on the old and the new code: unchanged in all three (1 inside the focus set, 0.26 outside, same colour).

Tests: e2e/focus-edge-dimming.spec.ts reads the drawn opacity: Focus inside and outside times activator satisfied and unsatisfied in light and dark, forced colours (opacity 1 and the `1 5` dash), and a played step (the dimmed path at 0.26 while the token keeps its opacity and colour). All four fail on the old code. e2e/whats-new.spec.ts pins 0.21.1. No visual baseline changes: no existing baseline is taken with Focus mode on.

Release: three release-note lines in 18 languages, 16 without native review; the copy guards move only their exact pins (catalog 1030 to 1033, runtime 1252 to 1255, pt-PT's difference from pt-BR 275 to 277, two new ё words for ru), no bound widened. pt-PT's difference outside the password keys is now 249 against its quarter bound of 249.75; one of the three lines reads the same in pt-BR and pt-PT so it stays there. Docs: docs/large-graph-readability.md §LGR3.1, CHANGELOG.md and README.md.
@MerciHanrim MerciHanrim added the bug Something isn't working label Oct 7, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying cozy-loop-studio with  Cloudflare Pages  Cloudflare Pages

Latest commit: 29dec5d
Status: ✅  Deploy successful!
Preview URL: https://693239dd.cozy-loop-studio.pages.dev
Branch Preview URL: https://fix-focus-edge-dimming.cozy-loop-studio.pages.dev

View logs

@MerciHanrim
MerciHanrim merged commit 7e66da2 into main Oct 7, 2026
10 checks passed
@MerciHanrim
MerciHanrim deleted the fix/focus-edge-dimming branch October 7, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant