,
- 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(
+ ,
+ targetElement
+ );
+}
+
+/**
+ * @unreleased
+ * Fetches stylesheets from the originating document and injects them into the new iframe document's head.
+ * This allows user provided styles to be applied to the iframe content.
+ * Returns a promise that resolves when all stylesheets are loaded.
+ */
+export async function fetchStylesheets(iframeDoc: Document) {
+ const styleSheets = Array.from(document.styleSheets);
+
+ // Promisify the loading of each stylesheet
+ const loadStylesheet = (styleSheet) => {
+ return new Promise((resolve, reject) => {
+ try {
+ if (styleSheet.href) {
+ // For external stylesheets
+ const newLink = document.createElement('link');
+ newLink.rel = 'stylesheet';
+ newLink.href = styleSheet.href;
+ newLink.onload = () => resolve();
+ newLink.onerror = reject;
+ iframeDoc.head.appendChild(newLink);
+ } else if (styleSheet.cssRules) {
+ // For tags
+ const newStyle = document.createElement('style');
+ Array.from(styleSheet.cssRules).forEach((rule: {cssText: string}) => {
+ newStyle.appendChild(document.createTextNode(rule.cssText));
+ });
+ iframeDoc.head.appendChild(newStyle);
+ resolve();
+ }
+ } catch (error) {
+ reject(error);
+ }
+ });
+ };
+
+ const promises = styleSheets.map(loadStylesheet);
+ return await Promise.all(promises);
+}
diff --git a/src/DonationForms/resources/registrars/templates/fields/Consent/styles.scss b/src/DonationForms/resources/registrars/templates/fields/Consent/styles.scss
index 481c404fd5..ba3c992cbb 100644
--- a/src/DonationForms/resources/registrars/templates/fields/Consent/styles.scss
+++ b/src/DonationForms/resources/registrars/templates/fields/Consent/styles.scss
@@ -7,7 +7,7 @@
}
&-modal {
- position: absolute;
+ position: fixed;
top: 0;
left: 0;
bottom: 0;
@@ -17,9 +17,9 @@
justify-content: center;
background: transparent;
backdrop-filter: blur(2px);
- z-index: 999;
&-content {
+ max-width: 48rem;
background: var(--givep-shades-white, #fff);
padding: 2.5rem 3.5rem;
width: calc(min(100%, 51.5rem) + 2rem);
@@ -41,8 +41,7 @@
display: flex;
gap: 1rem;
- > button {
- margin: 0;
+ button:first-child {
background: transparent;
color: var(--givewp-primary-color);
border: 1px solid var(--givewp-primary-color);
@@ -66,4 +65,3 @@
}
}
}
-
diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/terms-and-conditions/Edit.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/terms-and-conditions/Edit.tsx
index ee4835b344..b727e699fe 100644
--- a/src/FormBuilder/resources/js/form-builder/src/blocks/fields/terms-and-conditions/Edit.tsx
+++ b/src/FormBuilder/resources/js/form-builder/src/blocks/fields/terms-and-conditions/Edit.tsx
@@ -103,7 +103,7 @@ export default function Edit({
/>
- {isLinkDisplay && (
+ {(isLinkDisplay || isModalDisplay) && (
Acceptance of any contribution, gift or grant is at the discretion of the GiveWP. The GiveWP will not accept any gift unless it can be used or expended consistently with the purpose and mission of the GiveWP. No irrevocable gift, whether outright or life-income in character, will be accepted if under any reasonable set of circumstances the gift would jeopardize the donor’s financial security.The GiveWP will refrain from providing advice about the tax or other treatment of gifts and will encourage donors to seek guidance from their own professional advisers to assist them in the process of making their donation.',
+ '
Acceptance of any contribution, gift or grant is at the discretion of the GiveWP.
' +
+ '
The GiveWP will not accept any gift unless it can be used or expended consistently with the purpose and mission of the GiveWP.
' +
+ '
No irrevocable gift, whether outright or life-income in character, will be accepted if under any reasonable set of circumstances the gift would jeopardize the donor’s financial security.
' +
+ '
The GiveWP will refrain from providing advice about the tax or other treatment of gifts and will encourage donors to seek guidance from their own professional advisers to assist them in the process of making their donation.