With native support for CSS grid and flexbox, Puck 0.18 enables powerful new paradigms for creating design-in-browser experiences directly within your React application.
cmd+i
hotkey.position: fixed
: Weāve removed this pesky style from the default layout so itās easier to embed in your app.<ActionBar.Label>
component.Our flagship feature is a new drag-and-drop engine for Puck with full CSS grid & flexbox support to enable advanced layouts. We call these fluid layouts, and they are fully backwards compatible.
Thanks to @clauderic at dnd-kit for all the support in making this possible, and the Puck community for all the feedback! š
To implement a fluid layout, add your display property of choice (e.g. display: flex
) to your DropZone via the style
or className
props and off you goāPuck will gracefully handle drag-and-drop across all dimensions.
const config = {
components: {
Example: {
render: () => (
<DropZone
zone="my-content"
style={{ display: "flex" }} // Use flexbox in this DropZone
/>
),
},
Card: {
render: ({ text }) => <div>{text}</div>,
},
},
};
See the Multi-column Layouts docs for the full documentation.
The new inline
and dragRef
APIs enable you to remove the wrapping element from Puck components entirely, which can be useful if you need to treat your component as a direct descendant of its parent (such as if you need to use CSS properties like flex-grow
).
Hereās an example implementing an advanced grid layout, where the children can specify their position using the grid-column
and grid-row
properties:
const config = {
components: {
Example: {
render: () => (
<DropZone
zone="my-content"
style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr" }} // Use CSS grid in this DropZone
/>
),
},
Card: {
inline: true, // Enable inline mode, removing the Puck wrapper
render: ({ text, puck }) => (
<div
ref={puck.dragRef} // Let Puck know this element is draggable
style={{ gridColumn: `span ${spanCol}`, gridRow: `span ${spanRow}` }} // Apply styles
>
{text}
</div>
),
},
},
};
The new engine makes it possible to drag between nested DropZones, which resolves one of the longest standing limitations of Puckās drag-and-drop experience.
DropZones now shrink to the height of their children so that the preview is a faithful representation of the final output, with a new configurable height when empty.
<DropZone
zone="my-content"
minEmptyHeight={256} // The DropZone will grow to 256px when empty
/>
<ActionBar.Label>
componentThe new <ActionBar.Label>
component enables you to to label areas within a custom ActionBar:
<ActionBar>
<ActionBar.Label label="Label 1" />
<ActionBar.Group>
<ActionBar.Label label="Label 2" />
<ActionBar.Action>ā
</ActionBar.Action>
</ActionBar.Group>
</ActionBar>
A new action allows you to quickly select the componentās parent directly from the action bar. Tap the arrow to the left of the component label to jump to the parent.
Make your components interactive directly within Preview mode with the cmd+i
(or ctrl+i
on Windows) hotkey.
This can be programatically set via the new previewMode
parameter on the app state.
position:fixed
Weāve removed this pesky style from the default layout so itās easier to embed in your app. Not much to show here, but letās pour one out for position:fixed
š„
Due to upstream dependency changes, React 17 is no longer supported.
direction
no longer has any effectThe direction
prop on Drawer
no longer has any effect. Instead, use it to wrap a div
with your chosen display mode:
<Drawer>
<div style={{ display: "flex" }}>
<Drawer.Item name="Orange" />
</div>
</Drawer>
Previously, DropZones were only wrapped in a div within the editor (<Puck>
) environment, whereas the render (<Render>
) environment used a fragment. This could result in unexpected rendering differences between environments.
Now, both environments use a div. If you were relying on the render environment behaving like a Fragment, you may need to adjust your styles. This can be done by applying your styles directly to the DropZone.
Before
<div style={{ display: "flex" }}>
<DropZone zone="my-zone">
{/* Previously rendered as a fragment in <Render>, but div in <Puck> */}
<div>Item 1</div>
<div>Item 2</div>
</DropZone>
</div>
After
<DropZone zone="my-zone" style={{ display: "flex" }}>
{/* Now consistently renders as a div - apply your styles or class directly */}
<div>Item 1</div>
<div>Item 2</div>
</DropZone>
index
prop on Drawer.Item
is no longer required and will be removed in a future version.droppableId
prop on Drawer
is no longer required and will be removed in a future version.position: fixed;
from Puck layout (5deb774)Thanks to our contributors and sponsors for making this huge milestone possible. New contributors:
See the full changelog via GitHub: https://github.com/puckeditor/puck/compare/v0.17.1ā¦v0.18.0 f
If youāre interested in learning more about Puck, check out the demo or read the docs. If you like what you see, please give us a star on GitHub to help others find Puck too!