Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: POC for isHidden prop on ModalDialog #2431

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

adamstankiewicz
Copy link
Member

@adamstankiewicz adamstankiewicz commented Jul 11, 2023

Description

Demos a proof-of-concept of updating the ModalDialog component to introduce an isHidden prop for the following types of use cases:

By default, ModalDialog only renders its modal contents to the DOM when the modal is explicitly marked as open via the isOpen prop. However, in some cases, needing to re-render the contents of the modal body each and every time the modal closes and re-opens can be expensive and/or a poor user experience (UX), e.g. if the modal contents are dynamic and loaded from an external source like some iframed content or a slow loading API request.

To mitigate these performance concerns, ModalDialog supports an optional isHidden prop that when used in conjunction with isOpen, would result in the modal contents and the backdrop still being kept in the React Portal DOM, but visually hidden in the UI.

Deploy Preview

https://deploy-preview-2431--paragon-openedx.netlify.app/components/modal/modal-dialog/

Testing instructions:

  • Observe on page load of above URL, there is already a div in the DOM with an id of paragon-portal-root containing a hidden modal with the isHidden prop. Even though its in the DOM, it's not visible on the screen until the isHidden prop is changed from truthy to falsey.
  • Observe that having multiple modals rendering the paragon-portal-root React portal DOM element seems to be OK but would likely need more confirmation.

Merge Checklist

  • If your update includes visual changes, have they been reviewed by a designer? Send them a link to the Netlify deploy preview, if applicable.
  • Does your change adhere to the documented style conventions?
  • Do any prop types have missing descriptions in the Props API tables in the documentation site (check deploy preview)?
  • Were your changes tested using all available themes (see theme switcher in the header of the deploy preview, under the "Settings" icon)?
  • Were your changes tested in the example app?
  • Is there adequate test coverage for your changes?
  • Consider whether this change needs to reviewed/QA'ed for accessibility (a11y). If so, please add wittjeff and adamstankiewicz as reviewers on this PR.

Post-merge Checklist

  • Verify your changes were released to NPM at the expected version.
  • If you'd like, share your contribution in #show-and-tell.
  • 🎉 🙌 Celebrate! Thanks for your contribution.

@netlify
Copy link

netlify bot commented Jul 11, 2023

Deploy Preview for paragon-openedx ready!

Name Link
🔨 Latest commit 713934d
🔍 Latest deploy log https://app.netlify.com/sites/paragon-openedx/deploys/64adadca0da5b800089a95fb
😎 Deploy Preview https://deploy-preview-2431--paragon-openedx.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

<ModalBackdrop onClick={onClickOutside} />
{children}
{!isHidden && <ModalBackdrop onClick={onClickOutside} />}
<div className={classNames({ 'd-none': isHidden })}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: we should avoid using CSS utility classes with !important in Paragon components; define a custom .pgn__ namespaced class name to use instead with display: none; to be more theme-able.

zIndex ? `zindex-${zIndex}` : '',
)}
className={classNames({
'pgn__modal-layer': isOpen && !isHidden,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[inform] Conditionally include the pgn__modal-layer class name only when the modal contents and the backdrop should actually be visible. Without making this class name conditional, the resulting div from FocusOn acts a non-clickable overlay.

@@ -52,29 +52,31 @@ function ModalLayer({
};
}, [isOpen]);

if (!isOpen) {
if (!isOpen && !isHidden) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[consideration] It's possible this conditional could remain unchanged given isOpen would need to be truthy for isHidden to work anyways.

<Portal>
<FocusOn
allowPinchZoom
scrollLock
enabled={isOpen}
enabled={isOpen && !isHidden}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FocusOn is used in ModalDialog to handle the accessibility of auto-focus on the first interactive element in the modal and handling the Esc keypress or backdrop click.

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.

None yet

1 participant