puck icon indicating copy to clipboard operation
puck copied to clipboard

Expanding composition API

Open jeroenrinzema opened this issue 1 month ago • 3 comments

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:

  • Canvas
  • FieldsSidebar
  • Header

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_DURATION should 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>

jeroenrinzema avatar Nov 25 '25 14:11 jeroenrinzema

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.

FedericoBonel avatar Nov 26 '25 04:11 FedericoBonel

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?

jeroenrinzema avatar Nov 26 '25 11:11 jeroenrinzema

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.SidebarSwitch
  • Puck.UndoRedo
  • Puck.RootTitle
  • Puck.HeaderActions

That way you can rebuild the Header in your own layout.

FedericoBonel avatar Nov 28 '25 07:11 FedericoBonel