Pluggables framework
Contents
Pluggables framework#
The Pluggables framework give you insertion points to push components to other
components in an "out of tree" fashion, like React's <Portal>
component, but with vitamins.
In almost any case, <Pluggable>
is a better solution than a <Portal>
. Some benefits include:
the
<Pluggable>
(the target destination) can pass parameters to the<Plug>
(the inserted)any
<Plug>
can be overridden, based on theid
(you can't do that with<Portal>
)you can plug multiple
Plugs
into a<Pluggable>
and you can control the order they appear
To understand how they work, it's useful to look at the architecture:
First, we need to wrap all of our React component tree in a
<PluggablesProvider>
(this needs to be done only once in Volto, and it's there in place already atApp.jsx
component level), so you don't have to do it:
<PluggablesProvider>
...
</PluggablesProvider>
This Provider
acts like a centralized place where "insertion points" and
"plugins to the insertion points" can be registered. It achieves that by
using a dedicated React context.
Now, somewhere inside the children tree of <PluggablesProvider>
, we can create some
"insertion points":
<Pluggable name="left-column" />
Then we can plug things as children to the <Pluggable>
with some <Plug>
components:
<Plug pluggable="left-column" id="navigation">relevant nav stuff</Plug>
Declaring a <Plug>
with the same id
twice will make the second one (in
terms of rendering order) replace the first one.
Internally, the <PluggablesProvider>
keeps a record of Pluggables
and Plug
and
this is achieved by having the <Pluggables>
and <Plug>
components register
themselves with the Provider via React context.
Customize the rendering of plugs#
You can customize the rendering of pluggables. The <Pluggable>
component can take a function as a child and use that function to describe the rendering of pluggables.
<Pluggable name="block-toolbar">
{(pluggables) => pluggables.map((p) => (<>{p()}</>))}
</Pluggable>
Passing parameters from the Pluggable to the Plugs#
You can also pass options to the Plugs
, to enable inter-component communication:
<Pluggable name="block-toolbar" params={...blockProps} />
To use the passed params, you can do:
<Plug pluggable="block-toolbar" id="style">
{({options}) => {
console.log(options);
return <Button>Click me</Button>
}}
</Plug>