-
Notifications
You must be signed in to change notification settings - Fork 11
Reuse the same RichText component across the different environments (Edit, Save and Frontend) #2
Reuse the same RichText component across the different environments (Edit, Save and Frontend) #2
Conversation
The Title Component gets used both in the editor and on the frontend to output the correct markup for either a contenteditable area or the rendered component
Thanks for the PR, Fabian 🙂 Even though this technically works, we can't import I agree that having a context-aware version of primitive components like The current WordPress dependency system is based on globals, and not tree-shakable friendly. We would probably need to:
Maybe we could try to do accomplish it first here in isolation, with a fake I'm not an expert in tree-shaking, to be honest, so we may learn some things 🙂 |
Yeah completely agree on the size here (y) I think this current state is the proof of concept of what I would love the user experience and developer experience of hydrated blocks to be like. And yeah the three goals you have outlined are spot on. This here is all the So I think it should be feasible to create a shim for that for the frontend to ressolve some of these pains |
But you don't even need that because the |
🤦 Yeah, you are right 👍 I cannot think of other use cases. |
Still, it would be really interesting to reuse components like |
The commit I just pushed adds a shim for I've solved that for now with an unused import in the |
That's a nice trick 😄 But yes, it can easily break if devs forget or accidentally delete the "unrelated" import, as you mentioned. Another idea could be to use different entry points. For example:
In the packages, add the correct sideEffects configuration and export the different versions of each primitive. Then, use different bundling aliases for each context: // Config for Save bundle
{
"resolve": {
"alias": {
"@wordpress/block": "@wordpress/block/save",
}
}
}
// Config for Frontend bundle
{
"resolve": {
"alias": {
"@wordpress/block": "@wordpress/block/frontend",
}
}
} This approach could also work with import maps: <script type="importmap">
{
"imports": {
"@wordpress/block": "https://cdn.skypack.dev/@wordpress/block@^X.X.X/frontend",
}
}
</script> Both approaches (env variable or alias) require configuration. But I guess people are relying more and more on |
I've asked if there's a way to distinguish between Edit and Save in Slack. |
> | ||
<Children | ||
value={innerBlocks && innerBlocks.innerHTML} | ||
<EnvContext.Provider value="frontend"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, I think we could add one provider to each environment like this one with the correct value, so users only have to do this on their code:
const env = useContext(EnvContext); // "edit", "save" or "frontend"
or even expose a hook:
const env = useBlockEnv(); // "edit", "save" or "frontend"
I've used a @fabiankaegy let me know what you think! |
|
||
export const RichText = ({ tagName: Tag, children, ...props }) => { | ||
return useBlockEnvironment() === "edit" ? ( | ||
<window.wp.blockEditor.RichText value={children} tagName={Tag} {...props} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still using your trick to solve the bundling issue. We can explore solutions to this in a different PR.
@Mamaduka suggested us in Slack to explore useBlockEditContext as well, which returns |
@luisherranz thinking about it more using the |
But outside of that hook I think this is in a great spot to get merged in and refined in follow up PR's |
Perfect. Merging this 🙂 👏 |
The Title component now gets used both in the editor and on the frontend to output the correct markup for either a
contenteditable
area or the rendered component.