Improve interoperability with custom elements for block edit and save #17360
Labels
[Feature] Extensibility
The ability to extend blocks or the editing experience
Framework
Issues related to broader framework topics, especially as it relates to javascript
[Type] Enhancement
A suggestion for improvement.
Is your feature request related to a problem? Please describe.
Custom elements (often referred to under their umbrella term of "Web components" are a browser-native way to define custom HTML tags with custom behavior, appearance and semantic meaning. At a high level, they offer similar features to React components, with the difference that they don't require a framework to be loaded.
Several popular frameworks like Vue and Polymer already support or are even built on the technology. The key here is that custom elements are standardized and by that provide a great opportunity for all the different frameworks to become more interoperable.
Since custom elements are basically HTML tags, you can already place them within React components. You can also add attributes to them too, however HTML attributes do not support anything but string or boolean values. That means that today you can only use custom elements to render them, but not for any interaction. Reacts synthetic event system works very different from DOM events, so listening to an event fired by a custom element is not straightforward. However, you could achieve a similar goal by passing a callback function to the custom element (e.g. in an
onChange
prop), just like you would to a React component.Describe the solution you'd like
I suggest introducing an interoperability layer like what was previously explored in #2791, so that Gutenberg and custom elements can bidirectionally communicate with each other, while preserving React paradigms. The
ComponentInterop
component implemented in the PR already makes that available. It allows differentiating between what should be passed to the custom element as an attribute vs as a property (relevant since properties do support arbitrary data structures and functions). This way you could for example pass a block'ssetAttributes()
function to the custom element and thus allow it to render an editing UI and inform the editor of these changes. For easier understanding, here is @aduth's original example code.The PR adds support for specifying a custom element's tag name (as string) in the
edit
property of a block type definition, making it straightforward to use a custom element there. There's one addition though that I'd like to suggest: We should also make theComponentInterop
component (btw I think we should re-evaluate that name) available for direct usage (e.g. onwp.components
). By passingattributes
and other props, this would allow someone to use a custom element at almost any point in the virtual DOM hierarchy. For example, you might only want to use a custom element for a part of the edit component. Or you might want to use a custom element to implement a Gutenberg sidebar.I'd like to clarify that this is not about rewriting anything in Gutenberg using custom elements. This is purely about allowing plugin developers to leverage different paradigms and potentially different frameworks of their choice to work with Gutenberg. Improving interoperability here would also pave the way to a tighter integration between how something is implemented in the frontend of a WordPress site vs in the editor because custom elements can easily be used in either scenario without a dependency.
cc @aduth
The text was updated successfully, but these errors were encountered: