Releases: puckeditor/puck
v0.19.1
v0.19.0
Puck 0.19 introduces the Slots API for nesting components using fields, along with major performance optimizations, a new metadata API, and various quality-of-life improvements.
Read the Puck 0.19 release post for a list of all the new features, and the Puck 0.19 upgrade guide for upgrading from Puck 0.18.3.
Summary
- Slots API:
slot
is a new field type you can use to nest components. Since slots are fields, you can fully leverage APIs likedefaultProps
andresolveData
to programmatically control nested content. walkTree
: a utility function for recursively traversing and updating the entire data payload, or just a singleComponentData
node. It can be used to inspect, update, or validate nested components.- Metadata API: inject data into all components in your config without using React context. The injected data is available in both
render
andresolveData
. - Selectors for
usePuck
: subscribe to the parts of the internal Puck API you need in order to avoid unnecessary re-renders using thecreateUsePuck
factory. useGetPuck
: access the latest Puck API within callbacks without triggering re-renders.
Full changelog
Features
- add convenience metadata API to fields (5fe936e)
- add getItem helpers to usePuck (ad947d8)
- add labelIcon param to all fields for custom label icons (24030a9)
- add mapSlots helper function for manipulating slot data (a27944f)
- add metadata API for passing data to every component (b9add22)
- add placeholder param for text, textarea and number fields (32a6f78)
- add react-router v7 recipe (706ea0c)
- add replaceRoot action to dispatcher (586eccd)
- add selector to usePuck for improved performance (8976e5f)
- add slots API (40bc2ee)
- add step parameter to number fields (0ea6ce4)
- add useGetPuck hook for getting latest internal PuckApi (1d9a47d)
- add visible param to show/hide fields (e5911f3)
- deprecate DropZone component (d54145d)
- export package.json for module federation (b918900)
- expose CustomFieldRender type for custom field render functions (8d459e4)
- expose RootConfig type (638e066)
- expose WithSlotProps type (6dc5101)
- provide
trigger
event to resolveData parameters (55b42ae) - rename mapSlots to walkTree (427e686)
- support slots in transformProps via optional config arg (7d59b94)
Performance Improvements
Bug Fixes
- account for transforms in overlays (22f5e3a)
- add missing
id
to changed type for resolvers (eb4f9d8) - avoid query selector collision with multiple iframes (2c1db86)
- bind array item to correct field when using multiple arrays (7e231b7)
- deeply check items before populating resolveData changed (db75e42)
- don't artificially constrain array items to container (36b5713)
- don't collide with parent if component contains drop zone (e7d2371)
- don't render array item until dropped (1dfc1b3)
- don't reset old values when modifying fields in other array items (ad78e98)
- don't track dragged headings in heading-outline-analyzer (2e1a24e)
- ensure array items can be opened on mobile (a60c81e)
- ensure file inputs work inside array fields (83f8f2d)
- ensure nested array fields are draggable (af4f756)
- export migrate util in RSC bundle (2568ac3)
- expose transformProps in server bundle (020071e)
- fix undo/redo hotkeys for Windows (a994207)
- prevent ActionBar clipping if it exceeds top bounds (56f23e8)
- prevent horizontal scroll on touch devices (cb4b6ee)
- prevent input-type fields from exceeding container boundaries (b22833e)
- prevent item from sometimes sticking to window during drag (e62832e)
- reflect resolveData value changes in fields (69dd799)
- remove erroneous React 17 from supported peer dependencies (46212f0)
- remove unexpected license from recipes (7010bdc)
- reorder array items more predictably (64c65c3)
- reset stacking context in Puck entry (6bf9c99)
- restore ability to drop between sibling zones (2807cba)
- restore field values during undo/redo (6917928)
- retain minimum height when ActionBar is empty (a52ccb9)
- set ready status more reliably when using strict mode (5a526d0)
- show correct styles when insert permission is disabled (f19cdca)
- show top border on array bu...
v0.18.3
Bug Fixes
- bind array item to correct field when using multiple arrays (934cfae)
- don't artificially constrain array items to container (648a235)
- don't render array item until dropped (94f5e23)
- don't reset old values when modifying fields in other array items (73c17b3)
- don't track dragged headings in heading-outline-analyzer (3c16391)
- ensure file inputs work inside array fields (746033f)
- ensure nested array fields are draggable (0bdd243)
- expose transformProps in server bundle (d234345)
- prevent ActionBar clipping if it exceeds top bounds (e8355f0)
- remove erroneous React 17 from supported peer dependencies (98ad734)
- reorder array items more predictably (659f2d8)
- show top border on array button when array empty (7442118)
New Contributors
- @christian-tchaikovsky made their first contribution in #956
v0.18.2
Bug Fixes
- add missing types for root render method (0f52caf)
- address ownerDocument permission error in Firefox (c22b3a9)
- address prop name collision regression (3a69ad4)
- correctly infer types when using Render with RSC (ad7fbf4)
- don't jump to end of textarea fields during change (36c27a9)
- don't trigger clicks when dropping array items (29a7f1d)
- don't trigger drag when interacting with array fields (c7cd341)
- ensure ctrl+i interactive toggle hotkey works on Windows (5db6f4d)
- ensure renderDropZone provided correctly to root render (b9ce5b7)
- fix RTL drag-and-drop behaviour (28f518a)
- improve behaviour of array drag-and-drop (565fabd)
- provide empty readOnly object instead of undefined to root resolveFields (8992a94)
- provide updated props to resolveFields (b7ff689)
- reinstate padding for external field filters (28ccfda)
- tidy up stale items on drag cancellation (de48691)
- update styles for RTL (23c8dda)
- use correct type for onChange args when overriding fieldTypes (daff71e)
New Contributors
- @FedericoBonel made their first contribution in #842
- @rv-bparise made their first contribution in #834
Full Changelog: v0.18.0...v0.18.2
v0.18.1
v0.18.0
Puck 0.18 introduces a new drag-and-drop engine with native support for CSS grid and flexbox, enabling you to embed a design-in-browser experience directly within your React application or page builder.
TLDR
- New drag-and-drop engine: Multi-dimensional drag-and-drop across any CSS layout to create a sophisticated page building experience. Read the docs.
- Dynamic DropZone height: DropZones now shrink to the height of their children, with a configurable height when empty.
- Toggle interactive hotkey: Make your components interactive in Preview mode with the
cmd+i
hotkey. - Parent selector: A new action allows you to quickly select the component's parent directly from the action bar.
- No more
position: fixed
: We've removed this pesky style from the default layout so it's easier to embed in your app. - New ActionBar.Label component: Create sections in your action bar with the new <ActionBar.Label> component.
Highlights
New drag-and-drop engine
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! 🙏
Fluid layouts
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.
Remove wrapping elements
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>
),
},
},
};
Dragging between nested DropZones
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.
Dynamic DropZone height
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
/>
The <ActionBar.Label>
component
The 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>

Parent selector
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.
Toggle interactive hotkey
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.
No more 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
🥂
Breaking changes
React 17 no longer supported
Due to upstream dependency changes, React 17 is no longer supported.
Drawer direction
no longer has any effect
The 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>
DropZones are consistently wrapped in a div
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>
Deprecations
- The
index
prop onDrawer.Item
is no longer required and will be removed in a future version. - The
droppableId
prop onDrawer
is no longer required and will be removed in a future version.
Full changelog
Features
- add action to select parent component to ActionBar (7c910d5)
- add ActionBar.Label component for adding labels to action bars (d2645fd)
- add DropZone collisionAxis API for forcing collision direction (ba68732)
- add meta+i hotkey and previewMode state to toggle interactivity (ec1eba5)
- add wrapFields prop to control padding of fields in Puck.Fields (30f9a92)
- control empty DropZone height with minEmptyHeight prop (96f8340)
- deselect item on viewport change (e35585d)
- forward the ref to the DropZone component (676aa1c)
- introduce new drag-and-drop engine (6ebb3b8)
- reduce DropZone to height of items unless empty (2b2595a)
- remove
position: fixed;
from Puck layout (5deb774) - support inline Drawers, deprecating unnecessary props (f93b71e)
Bug Fixes
v0.17.4
v0.17.3
0.17.2
Bug Fixes
- always respect history hotkeys inside iframes (1134e8b)
- clear old readOnly data when running resolveData (3e91adc)
- don't trigger move action if source / destination the same (8a0b811)
- ensure parent is not null on first render in resolveFields (773a81a)
- factor in border when setting viewport size (cc3b3b8)
- fix plugin-emotion-cache style sync when using initialData (ac8679c)
- fix readOnly behaviour in nested fields (f6ab512)
- remove unnecessary transpile from next recipe (a5f2d08)
- respect min/max for freeform input in number field (715710a)
- use correct label for array and object subfields (c00ea00)
Full Changelog: v0.17.1...v0.17.2