Skip to content

fix(settings): scope Escape to the open modal and polish shared UI - #2163

Closed
cpvalente wants to merge 2 commits into
claude/editor-settings-ui-ux-ny3twofrom
claude/settings-ux-review-71yk48
Closed

fix(settings): scope Escape to the open modal and polish shared UI#2163
cpvalente wants to merge 2 commits into
claude/editor-settings-ui-ux-ny3twofrom
claude/settings-ux-review-71yk48

Conversation

@cpvalente

Copy link
Copy Markdown
Owner

Summary

Follow-up fixes on top of #2154, found during review:

  • Escape key regression: the modals introduced in refactor(settings): improve navigation and polish UI #2154 (trigger, URL preset, custom field, custom view, rundown rename, project merge, automation forms) dropped the preventEscape guard the inline forms used to stop Escape from also closing the whole settings panel. Base UI's dialog dismiss and the settings panel's own Escape listener both sit on document, so stopPropagation from one doesn't reach the other — both would fire. Added a small overlayStore that Modal/Dialog register into while open, and the settings panel now disables its own Escape handler while any overlay is open.
  • Tag: reserved a transparent border on the base class so the active variant's border doesn't resize the tag.
  • Modal: moved width off the base .modal class onto explicit .default/.compact/.small/.wide classes, removing dead min-width: 0 resets and a .default gap that left style[size] unresolved on the default path.
  • useAppSettingsMenu: search query is now normalised once (normaliseSettingsQuery) at the call sites instead of being re-trimmed/re-lowercased inside matchesSettingsOptionQuery and again in the submit handler.
  • TriggersList: the delete error banner now renders once per list instead of once per row.
  • Panel.Field: description is optional, so AppVersion's error state no longer passes an empty string for it.

Test plan

  • pnpm typecheck — clean
  • pnpm lint — 0 errors, 119 warnings (same as base)
  • pnpm build — verified .default/.compact/.small/.wide all emit in the built Modal CSS, and Tag's .active border-color renders correctly
  • pnpm test — 223/223 passing
  • Manual: open a settings modal (e.g. edit a trigger), press Escape — only the modal should close, not the whole settings panel

Generated by Claude Code

Modals inside the settings panel replaced inline forms that used
preventEscape to stop Escape reaching the panel. Base UI dismisses its own
popup and calls stopPropagation, but the panel handler listens on the same
document node, so stopPropagation cannot reach it and both fire in
registration order. Track open overlays instead and stand the panel handler
down while one is open.

Also:
- give Tag a transparent border so the active variant does not resize it
- move the modal width onto explicit size classes, dropping the dead
  min-width resets and the missing default class
- normalise the settings search query once at the entry points
- render the trigger delete error once rather than after every row
- let Panel.Field omit its description

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNZdnMwj99B7xxGB8xqhyY
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a7d145d-c0fd-4505-900a-195174f966fb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The Escape-key count only needs to be read at the moment a key is pressed,
not rendered — a plain module counter does the job without a store,
subscriptions, or the isDisabled indirection through useKeyDown. AppSettings
now wraps `close` itself and checks the counter synchronously.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNZdnMwj99B7xxGB8xqhyY
@cpvalente

Copy link
Copy Markdown
Owner Author

we have no evidence of the issue

@cpvalente cpvalente closed this Aug 2, 2026
@cpvalente
cpvalente deleted the claude/settings-ux-review-71yk48 branch August 2, 2026 08:39
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