Skip to content

fix(registry): make every Fortal focus ring follow the focus ring tokens - #320

Open
leoafarias wants to merge 3 commits into
mainfrom
fix/registry-fortal-focus-ring-tokens
Open

leoafarias wants to merge 3 commits into
mainfrom
fix/registry-fortal-focus-ring-tokens

Conversation

@leoafarias

@leoafarias leoafarias commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Fortal defines focusRingWidth and focusRingOffset, but several focus rings ignored them, so overriding the tokens in a scope moved only some controls. Every Fortal focus ring now reads the width token, and every ring whose Radix gap is the shared 2px also reads the offset token. The defaults (width 2, offset 2) equal Radix Themes 3.3.0, so default rendering is unchanged.

  • Outlines: fortalFocusOutline reads the width token. Checkbox, radio, switch, card, and link no longer hard-code width 2 or offset 2. Outward rings (checkbox, radio, switch, link, classic and solid buttons) read focusRingOffset; inset rings keep Radix's -1.
  • Select trigger: the pair of 1px box shadows becomes fortalFocusOutline(focus8, offset: -1), Radix's outline: 2px solid var(--focus-8); outline-offset: -1px.
  • Slider thumb: keeps Radix's 3px accent-3 halo and draws the ring as a token-width outline at the halo's edge (0 0 0 3px accent-3, 0 0 0 5px focus-8). The 3px halo is a Radix literal, not focusRingOffset.
  • Errored text field: its always-on error-8 outline is also the only ring while the field is focused, so its width reads the token too.
  • Registry templates and the demo and dashboard installed copies are regenerated.

Out of scope and tracked separately: the border-drawn rings (toggle, toggle-group item, tab, disclosure and accordion triggers) still grow when focused, which needs containerEffects on those Remix stylers; the soft radio ring colour; the dashboard swatch ring; slider thumb edge layering; a nested FortalTheme resetting ring-token overrides; sortable data-table headers without a ring.

Validation

  • focus_outline_tokens_test.dart resolves every ring at the default tokens (must equal Radix) and at width 3.5 / offset 5.0 (must follow): buttons, icon buttons, checkbox, radio, switch, link, text field (focused, disabled, errored), card, segmented control item, the three select variants, the slider thumb, and the border rings.
  • The select, slider, and errored-field assertions fail on main; for sites that already read the token, planting a literal width at the site fails the test.
  • Rendering at default tokens: focused select and slider rendered at 4x before and after are identical apart from anti-aliased curve edges.
  • registry_source suite (1396), Fortal parity check, dart analyze on registry_source and both apps, apps/demo (64) and apps/dashboard (84) tests, open-code:registry:build drift check, open-code:apps:check, root dart format check, melos run ci:checks: passed.

Related Issues

None.


Checklist

  • My PR includes unit or integration tests for all changed/updated/fixed behaviors.
  • I have updated or added relevant documentation (doc comments with ///).
  • I am prepared to follow up on review comments in a timely manner.

Breaking Change

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

Fortal defines focusRingWidth and focusRingOffset, but the checkbox, radio,
switch, card and link outlines and the shared fortalFocusOutline hard-coded
width 2 and offset 2, so overriding the tokens changed nothing for them.
Outward rings (checkbox, radio, switch, link, classic and solid buttons) now
read both tokens and every outline reads the width token; inset rings keep
their -1 offset. Default token values are 2 and 2, so rendering is unchanged.

The registry templates and the demo and dashboard installed copies are
regenerated to match.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T18:24:11.007068Z 7f5cafb New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

The first pass moved the Fortal outlines onto focusRingWidth and
focusRingOffset, but the select trigger and the slider thumb still drew their
rings from hard-coded box shadows.

The select trigger now uses fortalFocusOutline with Radix's inset -1px offset
(`outline: 2px solid focus-8; outline-offset: -1px`), replacing the outer plus
inset spread-1 shadow pair that painted the same band. The slider thumb keeps
Radix's 3px accent-3 halo and draws the ring as a token-width outline starting
where the halo ends (`0 0 0 3px accent-3, 0 0 0 5px focus-8`). The halo stays a
3px literal: it is not the 2px outline-offset of the other outward rings.

Default tokens give the same bands as before. Tests now cover every ring:
outlines (including select), the slider thumb, and the inside-border rings
(toggle, toggle group item, tabs, disclosure, accordion trigger).

Registry templates and the demo and dashboard installed copies are
regenerated to match.
An errored Fortal text field keeps an error-8 outline whether or not it is
focused, merged after the focus ring, so it is also the only ring drawn while
the field has focus. Its width was a literal 2, so overriding focusRingWidth
did nothing for errored fields. It now reads the token, keeping the -1 offset
and the inset shadow, so default rendering is unchanged.

The token test now also covers the segmented control item, the solid and soft
icon buttons, the disabled field's gray-8 ring and the errored field (idle and
focused), and checks that the inside-border rings use the focus colour. The
slider assertion that restated the offset and width checks is removed, and the
fortalFocusOutline doc comment now says which offsets follow the offset token.

Registry templates and the demo and dashboard installed copies are regenerated.
@leoafarias leoafarias changed the title fix(registry): drive Fortal focus outlines from the focus ring tokens fix(registry): make every Fortal focus ring follow the focus ring tokens Oct 26, 2026

This branch has not been deployed

No deployments
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