Expanding composition API
Description
Puck currently exposes Components, Fields, Outline, and Preview.
To build a fully custom editor UI, it would be extremely helpful if Puck also exposed:
CanvasFieldsSidebarHeader
These components are already part of the internal editor structure but not available for reuse. Exposing them would allow implementers to combine existing editor primitives with their own layout, styling, and navigation patterns.
Considerations
- We have to consider how custom classes and styles are applied to the components
- Potentially exposing additional state (e.g.,
viewport, drag info, history events) as props or via context. - Internal constants like
TRANSITION_DURATIONshould ideally be exported or made configurable.
Proposals
Proposal 1
Expose the components as-is, mirroring how existing components (Components, Preview, Outline) are already exported.
<Puck>
<Puck.Header />
<Puck.Canvas />
<Puck.FieldsSidebar />
</Puck>
Hey @jeroenrinzema!
Thanks for opening this request 🙏. I believe it is related to issue #1227, which is about providing access to the viewport controls for composition.
Some of the components you mentioned are indeed not exported because they make several assumptions about the editor layout and styles. In a fully custom UI, those assumptions are not guaranteed to hold.
The most problematic component in this case is the Canvas. We could explore ways to make it more reusable outside the default layout, or at least provide APIs that help guide the implementation.
Hi @FedericoBonel, I agree I think there is some overlap with #1227. #1227 could potentially expose the viewport controls through one of the proposed options and avoid having to expose the Canvas component.
What are your thoughts on the Header and Fields components?
We do expose Fields as a component under Puck.Fields, but I'm guessing you're referring to the sidebar as a whole.
You can use Puck.Fields and wrap it with your own sidebar component, but similar to the Viewports controls, you'd probably want the resizable logic included. I don't think exposing a Puck.Sidebar would be a bad idea, though we’d need to refactor the current component. Maybe we could make it usable like this?
<Puck.Sidebar {...somePropsHere}>
<Puck.Fields />
</Puck.Sidebar>
That way, you could wrap whatever you want inside it.
Regarding Header, it's not too difficult to implement. You can check how we do it here.
(Keep in mind we have to handle some extra steps for things like overrides, which you likely won't need.)
But, maybe we could consider exposing some more granular ones like:
Puck.SidebarSwitchPuck.UndoRedoPuck.RootTitlePuck.HeaderActions
That way you can rebuild the Header in your own layout.