diff --git a/src/edit.js b/src/edit.js index 4bf015d0..bd509981 100644 --- a/src/edit.js +++ b/src/edit.js @@ -1,15 +1,21 @@ -import { TextControl } from "@wordpress/components"; +// This import is needed to ensure that the `wp.blockEditor` global is available +// by the time this component gets loaded. The `Title` component consumes the +// global but cannot import it because it shouldn't be loaded on the frontend of +// the site. +import "@wordpress/block-editor"; + import { useBlockProps, InnerBlocks } from "@wordpress/block-editor"; +import Title from "./frontend/title"; export default function Edit({ attributes, setAttributes }) { const blockProps = useBlockProps(); return ( <>
- setAttributes({ message: val })} + placeholder="Enter the Title" />
diff --git a/src/framework/view.js b/src/framework/view.js index 8303fd1a..13a3c6f8 100644 --- a/src/framework/view.js +++ b/src/framework/view.js @@ -1,4 +1,4 @@ -import { hydrate } from "./wordpress-element"; +import { hydrate, EnvContext } from "./wordpress-element"; const blockTypes = new Map(); @@ -30,16 +30,18 @@ class GutenbergBlock extends HTMLElement { const innerBlocks = this.querySelector("gutenberg-inner-blocks"); const Comp = blockTypes.get(blockType); hydrate( - - + - , + > + + + , this ); }); diff --git a/src/framework/wordpress-blockeditor.js b/src/framework/wordpress-blockeditor.js new file mode 100644 index 00000000..042ec3c8 --- /dev/null +++ b/src/framework/wordpress-blockeditor.js @@ -0,0 +1,9 @@ +import { useBlockEnvironment } from "./wordpress-element"; + +export const RichText = ({ tagName: Tag, children, ...props }) => { + return useBlockEnvironment() === "edit" ? ( + + ) : ( + {children} + ); +}; diff --git a/src/framework/wordpress-element.js b/src/framework/wordpress-element.js index 4b8af41f..06a189f0 100644 --- a/src/framework/wordpress-element.js +++ b/src/framework/wordpress-element.js @@ -1,14 +1,36 @@ import { useState as useReactState, useEffect as useReactEffect, + useContext as useReactContext, + createContext, } from "@wordpress/element"; export { hydrate } from "react-dom"; -// Dirty dirty trick -export const isView = !window.wp.blockEditor; +export const EnvContext = createContext(null); + +/** + * A React hook that returns the name of the environment. + * + * This is still a bit hacky. Ideally, Save components should support React + * hooks and all the environments (Edit, Save and Frontend) should populate a + * normal context. Also, more environments could be added in the future. + * + * @returns {"edit" | "save" | "frontend"} + */ +export const useBlockEnvironment = () => { + try { + const env = useReactContext(EnvContext); + if (env === "frontend") return "frontend"; + return "edit"; + } catch (e) { + return "save"; + } +}; const noop = () => {}; -export const useState = (init) => (isView ? useReactState(init) : [init, noop]); +export const useState = (init) => + useBlockEnvironment() !== "save" ? useReactState(init) : [init, noop]; -export const useEffect = (...args) => (isView ? useReactEffect(...args) : noop); +export const useEffect = (...args) => + useBlockEnvironment() !== "save" ? useReactEffect(...args) : noop; diff --git a/src/frontend/title.js b/src/frontend/title.js index 729fdc06..8433daff 100644 --- a/src/frontend/title.js +++ b/src/frontend/title.js @@ -1,3 +1,9 @@ -const Title = ({ message }) =>

{message}

; +import { RichText } from "../framework/wordpress-blockeditor"; + +const Title = ({ message, ...props }) => ( + + {message} + +); export default Title;