PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.18.0
GiveWP – Donation Plugin and Fundraising Platform v4.18.0
4.18.0 4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 All 257 releases
give / src / DonationForms / resources / shared / EmbedFrame / index.tsx

index.tsx in GiveWP – Donation Plugin and Fundraising Platform 4.18.0, at src/DonationForms/resources/shared/EmbedFrame/index.tsx

114 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import {useEffect, useState} from '@wordpress/element';
2 import {__} from '@wordpress/i18n';
3 import IframeResizer from 'iframe-resizer-react';
4 import {Interweave} from 'interweave';
5 import './styles.scss';
6
7 /**
8 * How long the embed waits for the form to announce itself before it starts offering a link to
9 * the standalone form alongside the placeholder. The iframe keeps loading either way.
10 *
11 * @since 4.17.0
12 */
13 export const LOAD_TIMEOUT_MS = 10000;
14
15 /**
16 * @since 4.17.0
17 */
18 type EmbedFrameState = 'loading' | 'slow' | 'ready';
19
20 /**
21 * @since 4.17.0
22 */
23 type EmbedFrameProps = {
24 src: string;
25 embedId: string;
26 fallbackUrl: string;
27 /**
28 * The skeleton RenderFormSkeleton printed on the server, with its inline styles. When present a
29 * sketch of the form holds the space instead of a spinner.
30 */
31 skeletonHtml?: string;
32 onReady?: () => void;
33 onSlow?: () => void;
34 };
35
36 /**
37 * The iframe every on-site embed renders the form into, wrapped in a loading state.
38 *
39 * Browsers fire `load` for error pages too, so the signal that the form is actually running is the
40 * iframe-resizer handshake (`onInit`). Until it arrives a placeholder holds the space. There is no
41 * reliable failure signal, so a slow handshake is never treated as one: the iframe stays mounted and
42 * after LOAD_TIMEOUT_MS a link to the standalone form fades in over the placeholder, in case the
43 * form never arrives. It overlays the top of the frame rather than sitting under it, because a
44 * skeleton can run past the fold.
45 *
46 * @since 4.17.0
47 */
48 export default function EmbedFrame({src, embedId, fallbackUrl, skeletonHtml, onReady, onSlow}: EmbedFrameProps) {
49 const [state, setState] = useState<EmbedFrameState>('loading');
50 const showSkeleton = Boolean(skeletonHtml);
51
52 useEffect(() => {
53 if (state !== 'loading') {
54 return;
55 }
56
57 const timeout = window.setTimeout(() => {
58 setState('slow');
59 onSlow?.();
60 }, LOAD_TIMEOUT_MS);
61
62 return () => window.clearTimeout(timeout);
63 }, [state]);
64
65 return (
66 <div className="givewp-embed-frame" data-state={state} data-placeholder={showSkeleton ? 'skeleton' : 'spinner'}>
67 {state !== 'ready' && (
68 <div
69 className="givewp-embed-frame__loading"
70 role="status"
71 aria-label={__('Loading donation form', 'give')}
72 >
73 {showSkeleton ? (
74 /*
75 * The server's markup, read back from the root it was printed into. Interweave
76 * drops the inline style element that came with it; by now the block stylesheet,
77 * which carries the same rules, has loaded.
78 */
79 <Interweave content={skeletonHtml} noWrap disableLineBreaks />
80 ) : (
81 <span className="givewp-embed-frame__spinner" />
82 )}
83 </div>
84 )}
85 {state === 'slow' && (
86 <p className="givewp-embed-frame__fallback" role="status">
87 {__('The form is taking longer than usual to load.', 'give')}
88 <a
89 className="givewp-donation-form-link"
90 href={fallbackUrl}
91 target="_blank"
92 rel="noopener noreferrer"
93 >
94 {__('Open the form on its own page', 'give')}
95 </a>
96 </p>
97 )}
98 <IframeResizer
99 title={__('Donation Form', 'give')}
100 id={embedId}
101 src={src}
102 className="givewp-embed-frame__iframe"
103 checkOrigin={false}
104 heightCalculationMethod="taggedElement"
105 onInit={(iframe) => {
106 iframe.iFrameResizer.resize();
107 setState('ready');
108 onReady?.();
109 }}
110 />
111 </div>
112 );
113 }
114