v0.16.0
puckeditor/puckv0.16.0Sep 17, 2024by chrisvxd
AI Summary
A major release introducing a comprehensive permissions system, new overrides for the action bar and iframe, history management APIs, and the ability to react to internal actions.
Key Highlights
- New Permissions API for toggling features like duplication and deletion
- Action bar override and new ActionBar component for customization
- iframe override for style injection and Emotion-cache plugin
- History injection APIs via initialHistory prop
- onAction callback to track and react to Puck's internal actions
Breaking Changes
- history.data is now history.state
- history.id is now optional (TypeScript)
- lastData is now returned as null instead of {} when empty in resolvers
New Features
- Permissions API
- Action bar override
- iframe override
- History injection
- onAction callback
- Emotion-cache plugin
- Optional fields
Full Release Notes
We're celebrating 5,000 stars on GitHub! Thank you to our wonderful community! :star_struck:
[Puck v0.16](https://github.com/measuredco/puck/releases) is a big release, introducing the headline permissions API and — you guessed it — quality of life improvements. This one took a while to put together, and we appreciate your patience and support :pray:
## TLDR
- [**Permissions**](https://puckeditor.com/docs/integrating-puck/feature-toggling): Toggle Puck features like duplication, dragging, deletion through the new permissions and resolvePermissions APIs.
- [**Action bar override**](https://puckeditor.com/docs/api-reference/overrides/action-bar): Create custom action bars using the `actionBar` override, or extend the default one using the new [`<ActionBar>` component](https://puckeditor.com/docs/api-reference/components/action-bar).
- [**iframe style injection**](https://puckeditor.com/docs/api-reference/overrides/iframe): Access the iframe document to inject styles directly, or make other changes, via the new `iframe` override. We also introduced the [`emotion-cache` plugin](https://github.com/measuredco/puck/tree/main/packages/plugin-emotion-cache) for the common Emotion use-case.
- [**History injection**](https://puckeditor.com/docs/api-reference/components/puck#initialhistory): Inject the undo/redo history via the a series of new APIs
- [**React to actions**](https://puckeditor.com/docs/api-reference/components/puck#onactionaction-appstate-prevappstate): React to actions dispatched by Puck via the `onAction` callback.
- **Optional fields**: Optional props are no longer required to define in fields, since they may be defined
## Highlights
### :closed_lock_with_key: Permissions
[Permissions](https://puckeditor.com/docs/api-reference/permissions) enable you to [toggle core Puck functionality](https://puckeditor.com/docs/integrating-puck/feature-toggling) globally, on a per-component basis or dynamically. Huge thanks to @xaviemirmon for his efforts on this.
```tsx
export function Editor() {
return (
<Puck
permissions={{
delete: false,
duplicate: true
}}
/>
);
}
```
### :screwdriver: Action bar override
The new [`actionBar` override](https://puckeditor.com/docs/api-reference/overrides/action-bar) enables you to create a custom action bar overlay, or extend the default one using the [`<ActionBar>` component](https://puckeditor.com/docs/api-reference/components/action-bar):
```tsx
const overrides = {
actionBar: ({ children }) => (
<ActionBar label="Actions">
{/* Render default actions */}
<ActionBar.Group>{children}</ActionBar.Group>
{/* Render new actions */}
<ActionBar.Group>
<ActionBar.Action onClick={() => console.log("Clicked!")}>
★
</ActionBar.Action>
</ActionBar.Group>
</ActionBar>
),
};
```
### :nail_care: iframe style injection
The [`iframe` override](https://puckeditor.com/docs/api-reference/overrides/iframe) enables you to access the iframe `document`, making it possible to inject styles into the head:
```tsx
const overrides = {
iframe: ({ children, document }) => {
useEffect(() => {
if (document) {
document.body.setAttribute("style", "background: hotpink;");
}
}, [document]);
return <>{children}</>;
},
};
```
The new [`emotion-cache` plugin](https://github.com/measuredco/puck/tree/main/packages/plugin-emotion-cache) uses this API to create an emotion cache inside the iframe, making Puck easy to use with any Emotion-based component library.
### :scroll: History injection
Use the new history injection APIs to provide your own undo/redo history via the [`initialHistory` prop](https://puckeditor.com/docs/api-reference/components/puck#initialhistory), or dynamically via the [`setHistories` and `setHistoryIndex` functions](https://puckeditor.com/docs/api-reference/functions/use-puck#sethistories) from `usePuck().history`.
```tsx
const historyState = {
data: {
root: {
props: { title: "My History" },
},
},
};
export function Editor() {
return (
<Puck
initialHistory={{
histories: [{ state: historyState }],
index: 0,
}}
// ...
/>
);
}
```
### React to actions
The [`onAction` API](https://puckeditor.com/docs/api-reference/components/puck#onactionaction-appstate-prevappstate) enables you to react to Puck’s internal actions as they’re dispatched:
```tsx
export function Editor() {
return (
<Puck
onAction={(action, appState, prevAppState) => {
if (action.type === "insert") {
console.log("New component was inserted", appState);
}
}}
/>
);
}
```
## Breaking changes
### `history.data` is now `history.state`
When using the usePuck `history` API, `data` is now renamed `state`.
### `history.id` is now optional (TypeScript)
When using the usePuck `history` API `id` is now optional. Puck will always generate an `id`, but TypeScript may complain.
### `lastData` is now returned as `null` instead of `{}` when empty in resolvers
When using the `lastData` option provided to `resolveData` or `resolveFields` functions, and there is no previous data, `lastData` will now be `null` instead of `{}`.
## Full changelog
### Features
* add actionBar override for adding component controls ([48ec0d7](https://github.com/measuredco/puck/commit/48ec0d786c7c589efc8b97152a5e1a4c065c0312))
* add automatic RSC export, replacing /rsc bundle ([d21eba6](https://github.com/measuredco/puck/commit/d21eba6185da8efcbcb5458eaaa5be6c321b3d1a))
* add isDisabled prop to Drawer.Item ([cad95b8](https://github.com/measuredco/puck/commit/cad95b887c6b06a41a2bacf28792fd4dbc808d72))
* add generic type to usePuck hook ([01703a9](https://github.com/measuredco/puck/commit/01703a95093413a57af1314b1f31cc34f85c38e0))
* add iframe override for style injection ([7cac376](https://github.com/measuredco/puck/commit/7cac3764d1f9336776b97fa08cbd48bec95e6a10))
* add initialHistory prop to Puck ([54b5a87](https://github.com/measuredco/puck/commit/54b5a871570120a3d0d55e96738746ec375dee0d))
* add onAction API to track and react to state changes ([c7007ac](https://github.com/measuredco/puck/commit/c7007acab334ec2d08f95669d685edb8c3947bcc))
* add permissions API ([a43914d](https://github.com/measuredco/puck/commit/a43914dc36e70c5596c186d3c63b9497949365a9))
* add plugin for injecting Emotion cache ([f8a88b9](https://github.com/measuredco/puck/commit/f8a88b9c2447c76f2f7a00ce5705f8fae07be58c))
* add resolvePermissions API ([f0655f0](https://github.com/measuredco/puck/commit/f0655f08a96b853cf18d681025f40e8d30df3013))
* add waitForStyles option to iframe config ([bc81d9c](https://github.com/measuredco/puck/commit/bc81d9c7de671fea0bc155911ee11598a1b920c2))
* call resolveData when new item inserted ([3298831](https://github.com/measuredco/puck/commit/329883165c9e428b9f291add7b6009ba29680146))
* don't mandate fields for optional props ([5a219ef](https://github.com/measuredco/puck/commit/5a219eff0c2f4763ec1d9f48f45fe684e6482b8f))
* export ActionBar component for use in overrides ([04fd6c5](https://github.com/measuredco/puck/commit/04fd6c5c7a65fc3ec9a05da277865341efe229af))
* infer Data type from user config ([50045bb](https://github.com/measuredco/puck/commit/50045bbda2cf3b64e37e0e6bedcfce14f680cda1))
* make ID optional in History type (BREAKING CHANGE) ([d917229](https://github.com/measuredco/puck/commit/d917229ae4f553bb54a420e1c708c1a509431106))
* provide ES Module build ([ff9076b](https://github.com/measuredco/puck/commit/ff9076b9d24d030ad47619b6a359b1f120422d70))
* rename history.data to history.state (BREAKING CHANGE) ([b09244c](https://github.com/measuredco/puck/commit/b09244c864fd049ceeda2b7eb20ec6cab9f40054))
* show spinner if iframe load takes over 500ms ([cfecf54](https://github.com/measuredco/puck/commit/cfecf5499d06b8e90438dc151e5e915da06ccb87))
* streamline usePuck history API ([c8b2807](https://github.com/measuredco/puck/commit/c8b28075fde0081b8ac824eb256114c9b8836f9e))
* upgrade "next" recipe to typescript@5.5.4 ([60fe631](https://github.com/measuredco/puck/commit/60fe63113f8ad8bbce52d8457ee4372aa4b09509))
### Bug Fixes
* add favicon to next recipe to prevent Puck 404 ([2c52d27](https://github.com/measuredco/puck/commit/2c52d271c6c20e9368a59eb1f2a5df184cef72bc))
* add missing readOnly state to External fields ([bf1449d](https://github.com/measuredco/puck/commit/bf1449dd8b299a4f469986d94f8986b02b79a688))
* always record history on component insert ([88c5ab6](https://github.com/measuredco/puck/commit/88c5ab6b545ecbd045de3ee0d43801c48f50e8b0))
* don't cache /edit route in Next recipe ([94f16b2](https://github.com/measuredco/puck/commit/94f16b25efea86ff475683d3a21f5937e07b201c))
* don't submit buttons if Puck used in form ([f761e5f](https://github.com/measuredco/puck/commit/f761e5fed63fc698e3a9d6ba94607364ed46f31b))
* ensure demo types are satisfied with TypeScript@5 ([958dc25](https://github.com/measuredco/puck/commit/958dc255ac5d285f98b6b592df677883b74e2830))
* export missing Plugin type ([eb42734](https://github.com/measuredco/puck/commit/eb427343fd58752861cac850f59c1098cf473f50))
* fix crash if component in data is missing from config ([0daf478](https://github.com/measuredco/puck/commit/0daf478d9ad8b14d2844ff6ae2db9bd72970d680))
* improve resiliency of iframe CSS for some frameworks, like Mantine ([538cb05](https://github.com/measuredco/puck/commit/538cb05606126c338e97c047b97065463e618d36))
* make Config and Data types more robust ([6bcf555](https://github.com/measuredco/puck/commit/6bcf555da74d54d70f00f37878d35fa166bb7e4c))
* prevent infinite loop when using plugins with some frameworks ([3870871](https://github.com/measuredco/puck/commit/38708716f32d65a9131b87fe664ba96b32aead15))
* prevent Tailwind from clashing with viewport zoom select ([9151255](https://github.com/measuredco/puck/commit/91512553430b295c37c80a935f0db929bb37870c))
* remove body margin in remix recipe ([0898b26](https://github.com/measuredco/puck/commit/0898b26cd021680dfb77a439b04140ce2fb8cb2c))
* resize viewport when changed via app state ([14419ec](https://github.com/measuredco/puck/commit/14419ecf1c606e6fa0d6d9c5198401eb01bc72dd))
* resolve fields when switching between items of same type ([a3518ca](https://github.com/measuredco/puck/commit/a3518ca8560ba9fcdbe5086220490920ecf24fc0))
* return lastData as null instead of empty object in resolvers (BREAKING CHANGE) ([648eb92](https://github.com/measuredco/puck/commit/648eb92b3d2c5be8f5fc99a22db5eff64cefb155))
* show warning if heading-analyzer styles aren't loaded ([4e7110b](https://github.com/measuredco/puck/commit/4e7110b591a4a12e2b3c89eb1fa98faf5f9338d4))
* use correct color in FieldLabel labels ([b0469a1](https://github.com/measuredco/puck/commit/b0469a1134ac8eafc9a3b16de4d7805241127947))
## New Contributors
* @mkilpatrick made their first contribution in https://github.com/measuredco/puck/pull/505
* @nova4u made their first contribution in https://github.com/measuredco/puck/pull/538
* @antonmalyavkin made their first contribution in https://github.com/measuredco/puck/pull/585
**Full Changelog**: https://github.com/measuredco/puck/compare/v0.15.0...v0.16.0