Skip to content

Modal hygiene: Escape, focus trap, and dialog semantics on hand-rolled pickers #86

Description

@ApocDev

Several hand-rolled overlay components are missing basic modal behavior. The item/goal pickers on the block page (routes/block.$id.tsx) and the modules modal (lib/modules-modal.tsx) have no Escape-to-close handler, no focus trap, and no role="dialog"/aria-modal — only autoFocus on their search input. components/drift-modal.tsx handles Escape and sets the dialog role but doesn't contain focus.

What to do

  • Either migrate these overlays to the shadcn/Radix Dialog/Popover primitives already in the app (which give Escape, focus trapping, and semantics for free), or wrap them in a tiny shared modal shell that provides those behaviors.
  • Escape-to-close is the user-facing win — it's a daily papercut when a picker is open — and consistent behavior here matters more once global hotkeys exist (Command palette: Ctrl+K / / search-everything #78), since key handling and open overlays need to agree on who owns the keyboard.

Part of the polish epic #35.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: webWeb UI (React/TanStack/vite-plus)enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions