 Chris Villa
Chris VillaWe’re celebrating 5,000 stars on GitHub! Thank you to our wonderful community!
Puck 0.16 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.
actionBar override, or extend the default one using the new <ActionBar> component.iframe override. We also introduced the emotion-cache plugin for the common Emotion use-case.onAction callback.Upgrade today or get started with:
npx create-puck-app@latestPermissions enable you to toggle core Puck functionality globally, on a per-component basis or dynamically. Huge thanks to @xaviemirmon for his efforts on this.
export function Editor() {
  return (
    <Puck
      permissions={{
        delete: false,
        duplicate: true,
      }}
    />
  );
}The new actionBar override enables you to create a custom action bar overlay, or extend the default one using the <ActionBar> component:
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>
  ),
};The iframe override enables you to access the iframe document, making it possible to inject styles into the head:
const overrides = {
  iframe: ({ children, document }) => {
    useEffect(() => {
      if (document) {
        document.body.setAttribute("style", "background: hotpink;");
      }
    }, [document]);
 
    return <>{children}</>;
  },
};The new emotion-cache plugin uses this API to create an emotion cache inside the iframe, making Puck easy to use with any Emotion-based component library.
Use the new history injection APIs to provide your own undo/redo history via the initialHistory prop, or dynamically via the setHistories and setHistoryIndex functions from usePuck().history.
const historyState = {
  data: {
    root: {
      props: { title: "My History" },
    },
  },
};
 
export function Editor() {
  return (
    <Puck
      initialHistory={{
        histories: [{ state: historyState }],
        index: 0,
      }}
      // ...
    />
  );
}The onAction API enables you to react to Puck’s internal actions as they’re dispatched:
export function Editor() {
  return (
    <Puck
      onAction={(action, appState, prevAppState) => {
        if (action.type === "insert") {
          console.log("New component was inserted", appState);
        }
      }}
    />
  );
}history.data is now history.stateWhen 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 resolversWhen 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: https://github.com/puckeditor/puck/compare/v0.15.0…v0.16.0
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!