Skip to content

[ER-49165] Fix focus recursion between Drawer and Modal#4951

Draft
rafael-anachoreta wants to merge 2 commits into
masterfrom
er-49165-drawer-modal-focus-recursion
Draft

[ER-49165] Fix focus recursion between Drawer and Modal#4951
rafael-anachoreta wants to merge 2 commits into
masterfrom
er-49165-drawer-modal-focus-recursion

Conversation

@rafael-anachoreta
Copy link
Copy Markdown
Contributor

@rafael-anachoreta rafael-anachoreta commented May 12, 2026

ER-49165

Description

When a Drawer is opened from inside an open Modal and the Modal is later closed, the browser console fills with RangeError: Maximum call stack size exceeded or too much recursion. Modal opts out of MUI's FocusTrap and uses its own document-level focus listener; Drawer keeps MUI's FocusTrap active. With both open, the two focus mechanisms recurse on .focus() indefinitely.

This PR lifts Modal's private ModalManager singleton into picasso-utils (as defaultModalManager) and has Drawer register with it on open. Modal's focus listener already bails when it isn't the topmost overlay; now that Drawer registers above it, the bailout actually fires and the recursion is broken.

How to test

  1. Open the Drawer story Default example in Storybook: https://picasso.toptal.net/?path=/story/components-drawer--drawer#default
  2. Click "Edit code" and paste the reproduction snippet from ER-49165 (a Modal that opens a Drawer).
  3. Click 1. Show Modal2. Open Drawer3. Close Modal.
  4. Browser console should stay clean

Screenshots

Before After
image image

Development checks

  • Add changeset according to guidelines (if needed)
  • Double check if picasso-tailwind-merge requires major update (check its README.md)
  • Read CONTRIBUTING.md and Component API principles
  • Make sure that additions and changes on the design follow Toptal's BASE design, and it's been already discussed with designers at #-base-core
  • Annotate all props in component with documentation
  • Create examples for component
  • Ensure that deployed demo has expected results and good examples
  • Ensure the changed/created components have not caused accessibility issues. How to use accessibility plugin in storybook.
  • Self reviewed
  • Covered with tests (visual tests included)

Breaking change

  • N/A codemod is created and showcased in the changeset
  • N/A test alpha package of Picasso in StaffPortal

All development checks should be done and set checked to pass the
GitHub Bot: TODOLess action

Alpha packages

Manually trigger the publish.yml workflow to publish alpha packages. Specify pull request number as a parameter (only digits, e.g. 123).

PR Review Guidelines

When to approve? ✅

You are OK with merging this PR and

  1. You have no extra requests.
  2. You have optional requests.
    1. Add nit: to your comment. (ex. nit: I'd rename this variable from makeCircle to getCircle)

When to request changes? ❌

You are not OK with merging this PR because

  1. Something is broken after the changes.
  2. Acceptance criteria is not reached.
  3. Code is dirty.

When to comment (neither ✅ nor ❌)

You want your comments to be addressed before merging this PR in cases like:

  1. There are leftovers like unnecessary logs, comments, etc.
  2. You have an opinionated comment regarding the code that requires a discussion.
  3. You have questions.

How to handle the comments?

  1. An owner of a comment is the only one who can resolve it.
  2. An owner of a comment must resolve it when it's addressed.
  3. A PR owner must reply with ✅ when a comment is addressed.

@rafael-anachoreta rafael-anachoreta self-assigned this May 12, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

🦋 Changeset detected

Latest commit: 5d6d6f9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 82 packages
Name Type
@toptal/picasso-drawer Patch
@toptal/picasso-modal Patch
@toptal/picasso-utils Minor
@toptal/picasso Patch
@toptal/picasso-rich-text-editor Patch
@toptal/picasso-prompt-modal Patch
@toptal/picasso-charts Patch
@toptal/picasso-forms Patch
@toptal/picasso-pictograms Patch
@toptal/picasso-query-builder Patch
@toptal/picasso-tailwind-merge Patch
@topkit/analytics-charts Patch
@toptal/picasso-accordion Patch
@toptal/picasso-account-select Patch
@toptal/picasso-alert Patch
@toptal/picasso-amount Patch
@toptal/picasso-application-update-notification Patch
@toptal/picasso-autocomplete Patch
@toptal/picasso-avatar Patch
@toptal/picasso-avatar-upload Patch
@toptal/picasso-backdrop Patch
@toptal/picasso-badge Patch
@toptal/picasso-breadcrumbs Patch
@toptal/picasso-button Patch
@toptal/picasso-calendar Patch
@toptal/picasso-carousel Patch
@toptal/picasso-checkbox Patch
@toptal/picasso-collapse Patch
@toptal/picasso-container Patch
@toptal/picasso-date-picker Patch
@toptal/picasso-date-select Patch
@toptal/picasso-dropdown Patch
@toptal/picasso-dropzone Patch
@toptal/picasso-fade Patch
@toptal/picasso-file-input Patch
@toptal/picasso-form Patch
@toptal/picasso-form-label Patch
@toptal/picasso-form-layout Patch
@toptal/picasso-grid Patch
@toptal/picasso-helpbox Patch
@toptal/picasso-icons Patch
@toptal/picasso-image Patch
@toptal/picasso-input Patch
@toptal/picasso-input-adornment Patch
@toptal/picasso-link Patch
@toptal/picasso-list Patch
@toptal/picasso-loader Patch
@toptal/picasso-logo Patch
@toptal/picasso-menu Patch
@toptal/picasso-notification Patch
@toptal/picasso-number-input Patch
@toptal/picasso-outlined-input Patch
@toptal/picasso-overview-block Patch
@toptal/picasso-page Patch
@toptal/picasso-pagination Patch
@toptal/picasso-paper Patch
@toptal/picasso-password-input Patch
@toptal/picasso-popper Patch
@toptal/picasso-radio Patch
@toptal/picasso-rating Patch
@toptal/picasso-section Patch
@toptal/picasso-select Patch
@toptal/picasso-skeleton-loader Patch
@toptal/picasso-slide Patch
@toptal/picasso-slider Patch
@toptal/picasso-step Patch
@toptal/picasso-table Patch
@toptal/picasso-tabs Patch
@toptal/picasso-tag Patch
@toptal/picasso-tagselector Patch
@toptal/picasso-timeline Patch
@toptal/picasso-timepicker Patch
@toptal/picasso-tooltip Patch
@toptal/picasso-tree-view Patch
@toptal/picasso-typography Patch
@toptal/picasso-typography-overflow Patch
@toptal/picasso-user-badge Patch
@toptal/picasso-note Patch
@toptal/picasso-show-more Patch
@toptal/picasso-empty-state Patch
@toptal/picasso-quote Patch
@toptal/picasso-switch Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4951/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 12, 2026
@rafael-anachoreta rafael-anachoreta added the Bugfix Something isn't working label May 12, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4951/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bugfix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant