From eaeecdddf9ff4a8485c38f0cfe452a183e1a03e1 Mon Sep 17 00:00:00 2001 From: Joshua Dinh <75056371+JoshuaHungDinh@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:32:09 -0700 Subject: [PATCH] Fix: Modal rendering across different Iframe contexts (#7435) --- .../templates/fields/Consent/ConsentModal.tsx | 23 ++--- .../fields/Consent/createIframePortal.tsx | 92 +++++++++++++++++++ .../templates/fields/Consent/styles.scss | 8 +- .../fields/terms-and-conditions/Edit.tsx | 2 +- .../fields/terms-and-conditions/settings.tsx | 7 +- 5 files changed, 108 insertions(+), 24 deletions(-) create mode 100644 src/DonationForms/resources/registrars/templates/fields/Consent/createIframePortal.tsx diff --git a/src/DonationForms/resources/registrars/templates/fields/Consent/ConsentModal.tsx b/src/DonationForms/resources/registrars/templates/fields/Consent/ConsentModal.tsx index bac500ee3e..461884087c 100644 --- a/src/DonationForms/resources/registrars/templates/fields/Consent/ConsentModal.tsx +++ b/src/DonationForms/resources/registrars/templates/fields/Consent/ConsentModal.tsx @@ -1,25 +1,14 @@ import {__} from '@wordpress/i18n'; -import {createPortal} from 'react-dom'; import {Markup} from 'interweave'; import {Button} from '@wordpress/components'; +import createIframePortal from './createIframePortal'; import './styles.scss'; export default function ConsentModal({setShowModal, modalHeading, modalAcceptanceText, agreementText, acceptTerms}) { - const scrollModalIntoView = (element) => { - if (element) { - element.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'}); - } - }; - - return createPortal( + return createIframePortal(
-
{ - element && scrollModalIntoView(element); - }} - > +

{modalHeading}

@@ -30,10 +19,12 @@ export default function ConsentModal({setShowModal, modalHeading, modalAcceptanc - +
, - document.body + window.top.document.body ); } diff --git a/src/DonationForms/resources/registrars/templates/fields/Consent/createIframePortal.tsx b/src/DonationForms/resources/registrars/templates/fields/Consent/createIframePortal.tsx new file mode 100644 index 0000000000..73062ac3c5 --- /dev/null +++ b/src/DonationForms/resources/registrars/templates/fields/Consent/createIframePortal.tsx @@ -0,0 +1,92 @@ +import {createPortal, render} from 'react-dom'; +import {useEffect, useRef} from 'react'; + +import './styles.scss'; + +/** + * @unreleased + * Creates a portal to the Top Level document, rendering children elements within an iframe. + */ +export default function createIframePortal(children, targetElement = window.top.document.body) { + const iframeRef = useRef(null); + + useEffect(() => { + const iframe = iframeRef.current; + const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; + + if (iframe) { + // Clear existing content. + iframeDoc.head.innerHTML = ''; + iframeDoc.body.innerHTML = ''; + + async function renderContent() { + try { + await fetchStylesheets(iframeDoc); + render(children, iframeDoc.body); + } catch (error) { + console.error('Error loading stylesheets:', error); + } + } + + renderContent(); + } + }, []); + + return createPortal( +