Skip to content

feat: add keepMounted prop - #577

Closed
pradel wants to merge 1 commit into
masterfrom
feat/keep-mounted
Closed

pradel wants to merge 1 commit into
masterfrom
feat/keep-mounted

Conversation

@pradel

@pradel pradel commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Closes #233. Supersedes #516.

Problem

When the modal is closed it is unmounted from the DOM, so any state held by its content (e.g. an uncontrolled input value) is lost.

Solution

New optional keepMounted?: boolean prop (default false). When enabled, the portal stays mounted while closed:

  • The modal is still animated out, then hidden with a visibility: hidden transition delayed by animationDuration, so it is removed from the a11y tree/tab order and cannot be clicked while hidden. Reopening reveals it instantly.
  • onAnimationEnd still fires on close.
  • The focus trap is unmounted while hidden, so focus is restored on close and set again on open.
  • Scroll lock, esc handling and overlay clicks are unchanged and stay disabled while the modal is not open.

No new state or effects are needed: mounting is driven by open || keepMounted, and hiding is CSS-driven.

Tests

  • modal stays mounted and hidden when closed
  • shown again on reopen
  • DOM state (input value) preserved across close/reopen
  • onAnimationEnd still fires without unmounting
  • esc does not close the hidden modal

Also adds a "Keeping the modal mounted" docs section with a live example.

�[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.11 �[39m�[90m/Users/leo/dev/pradel/react-responsive-modal�[39m

�[32m✓�[39m react-responsive-modal/tests/ssr.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m
�[31m❯�[39m react-responsive-modal/tests/index.test.tsx �[2m(�[22m�[2m0 test�[22m�[2m)�[22m

�[2m Test Files �[22m �[1m�[31m1 failed�[39m�[22m�[2m | �[22m�[1m�[32m1 passed�[39m�[22m�[90m (2)�[39m
�[2m Tests �[22m �[1m�[32m3 passed�[39m�[22m�[90m (3)�[39m
�[2m Start at �[22m 22:23:54
�[2m Duration �[22m 228ms�[2m (transform 98ms, setup 0ms, import 88ms, tests 5ms, environment 0ms)�[22m 63 passed, pass: All 57 files are correctly formatted (244ms, 10 threads)
pass: Found no warnings, lint errors, or type errors in 36 files (331ms, 10 threads) clean, website build passes, size 2.8/2.9 kB ESM and 3.51/3.6 kB CJS.

Keep the modal mounted in the DOM when it is closed so the state of the
content inside it is preserved.

The modal is still animated out and hidden once the closing animation
finishes using a delayed visibility transition, then revealed again on
open. While hidden the focus trap is unmounted so focus is restored on
close and set again on open, and scroll lock, esc handling and overlay
clicks stay disabled since the modal is no longer open.

Closes #233
@codecov

codecov Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.06%. Comparing base (b69f310) to head (8ec1fb7).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #577      +/-   ##
==========================================
+ Coverage   80.69%   81.06%   +0.37%     
==========================================
  Files           7        7              
  Lines         202      206       +4     
  Branches       74       78       +4     
==========================================
+ Hits          163      167       +4     
  Misses         29       29              
  Partials       10       10              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pradel pradel closed this Sep 25, 2026
@pradel
pradel deleted the feat/keep-mounted branch September 25, 2026 09:08
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.

Save state DOM tree

1 participant