IframeEmotionCacheProvider.js
31 lines
| 1 | import { useState } from '@wordpress/element'; |
| 2 | import { useRefEffect } from '@wordpress/compose'; |
| 3 | import createCache from '@emotion/cache'; |
| 4 | import { CacheProvider } from '@emotion/react'; |
| 5 | |
| 6 | // WordPress 6.9+ renders blocks inside an iframe when every registered block |
| 7 | // declares apiVersion >= 3. Emotion's default cache injects <style> tags into |
| 8 | // the parent document's <head>, so styled components rendered inside the iframe |
| 9 | // appear unstyled. This provider builds an Emotion cache whose container is |
| 10 | // the iframe document's <head> and wraps children in <CacheProvider> so all |
| 11 | // styled components within it land their CSS in the correct document. |
| 12 | export default function IframeEmotionCacheProvider( { children } ) { |
| 13 | const [ cache, setCache ] = useState( null ); |
| 14 | |
| 15 | const ref = useRefEffect( ( element ) => { |
| 16 | const doc = element.ownerDocument; |
| 17 | setCache( |
| 18 | createCache( { |
| 19 | key: 'latepoint-block', |
| 20 | container: doc.head, |
| 21 | } ) |
| 22 | ); |
| 23 | }, [] ); |
| 24 | |
| 25 | return ( |
| 26 | <div ref={ ref } className="latepoint-block-iframe-cache-host"> |
| 27 | { cache && <CacheProvider value={ cache }>{ children }</CacheProvider> } |
| 28 | </div> |
| 29 | ); |
| 30 | } |
| 31 |