Skip to content

refactor: dedupe Settings segmented fieldsets into OptionGroup - #692

Closed
enaboapps wants to merge 1 commit into
refactor/settings-module-683from
refactor/settings-optiongroup-684
Closed

enaboapps wants to merge 1 commit into
refactor/settings-module-683from
refactor/settings-optiongroup-684

Conversation

@enaboapps

Copy link
Copy Markdown
Contributor

Closes #684.

Stacked on #691 — base is refactor/settings-module-683, so review this after that merges (or review just the two-file diff here).

The eight segmented option fieldsets in SettingsView were hand-rolled copies of the same fieldset > legend > div.segmented > button[aria-pressed] structure. This replaces them with one OptionGroup.

Added to controls.tsx

  • OptionGroup — generic over string | number option values, with an optional columns modifier (three / four / five, omitted entirely for the one group that has no column class) and a children slot for the trailing note that the overlay-visibility fieldset renders inside its fieldset.
  • secondsOptions — builds the {value / 1000}s labels shared by the movement, scroll, key and dwell interval groups. Returns the label as a fragment so the button keeps its two text nodes rather than collapsing to one.
  • overlayVisibilityOptions, overlaySizeOptions.

SettingsView.tsx: 82 → 70 lines.

The pointer-speed fieldset is deliberately untouched

Its buttons carry per-option aria-labels and it renders an exact-speed select plus a movement-values readout, so it is not the same structure. Folding it in would have meant changing DOM.

Byte-identical DOM — verified, not assumed

Rather than relying on the tests passing, I dumped the rendered Settings view innerHTML on the parent commit and on this one and diffed them:

State Result
Default settings identical
Every feature toggle enabled, non-default selections across all eight groups identical

The second case matters because it exercises the aria-pressed and disabled states that the default dump leaves uniform. The dump harness was temporary and is not committed.

Validation

Check Result
npm run lint pass
npm test pass — 75 tests, no test file changed
npm run build pass
cargo fmt --check exit 0
cargo clippy --all-targets -- -D warnings exit 0
cargo test exit 0 — 263 + 7 tests

No Rust files are touched; the Rust gates are run per AGENTS.md.

🤖 Generated with Claude Code

The eight segmented option fieldsets in SettingsView were hand-rolled
copies of the same fieldset > legend > div.segmented > button[aria-pressed]
structure. Replace them with a single OptionGroup component.

Adds to controls.tsx:
- OptionGroup, generic over string | number option values, with an optional
  columns modifier and a children slot for the trailing note that the
  overlay-visibility fieldset renders inside its fieldset
- secondsOptions, which builds the {value / 1000}s labels shared by the
  movement, scroll, key and dwell interval groups
- overlayVisibilityOptions and overlaySizeOptions

The DOM is byte-identical. Verified empirically by dumping the rendered
Settings view innerHTML on the parent commit and on this one and diffing:
identical at default settings, and identical again with every feature
toggle enabled and non-default selections across all eight groups.

The pointer-speed fieldset is left alone; its buttons carry per-option
aria-labels and it renders extra content, so it is not the same structure.

SettingsView.tsx: 82 -> 70 lines. Tests unchanged, 75 passing.

Refs #684

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@enaboapps
enaboapps marked this pull request as ready for review September 8, 2026 13:14
@enaboapps
enaboapps deleted the branch refactor/settings-module-683 September 8, 2026 13:28
@enaboapps enaboapps closed this Sep 8, 2026
@enaboapps

Copy link
Copy Markdown
Contributor Author

Superseded by the reopened PR against main — this one was auto-closed when its base branch was deleted on merge of #691.

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.

2 participants