github measuredco/puck v0.13.0

latest releases: v0.18.2, v0.18.1, v0.18.0...
14 months ago

Puck v0.13.0 introduces some of our most powerful APIs yet, enabling completely custom interfaces, adding support for object fields and mechanisms to restrict DropZones.

TLDR

  1. Custom interfaces: Take complete control of the Puck UI with the new custom interface APIs.
  2. Object fields: Represent objects as fields with the new object field type.
  3. DropZone restrictions: The new allow and disallow props allow you to restrict which components can be dropped into DropZones.
  4. New plugin API (Breaking Change): The plugin API has been updated to align with the new custom interfaces API. This is a breaking change. The plugin API remains experimental.
  5. New transformProps API: The new transformProps API makes it easier to rename props on your components without breaking your payload.
  6. New ui prop: Set the initial UI state for the Puck editor on render.
  7. Add search to external fields: Show a search input in the external field modal, enabling the user to query your external API.

Highlights

🎨 Custom interfaces

It's now possible to create completely custom Puck interfaces to integrate more deeply with your own UI and create a seamless experience for your users.

image

This can be achieved by passing children to the <Puck> component.

import { Puck } from "@measured/puck";

export function Editor() {
  return (
    <Puck>
      <div style={{ background: "hotpink" }}>
        <Puck.Preview />
      </div>
    </Puck>
  );
}

See demo.

🪝 The usePuck hook

Access Puck's internals using the usePuck hook to extend Puck's functionality with powerful custom components.

import { Puck, usePuck } from "@measured/puck";

const JSONRenderer = () => {
  const { appState } = usePuck();

  return <div>{JSON.stringify(appState.data)}</div>;
};

export function Editor() {
  return (
    <Puck>
      <JSONRenderer />
    </Puck>
  );
}

🗃️ Object fields

Object fields enable you to represent your object types with the fields API. No more flattening your props!

const config = {
  components: {
    Example: {
      fields: {
        params: {
          type: "object",
          objectFields: {
            title: { type: "text" },
          },
        },
      },
      render: ({ params }) => {
        return <p>{params.title}</p>;
      },
    },
  },
};

🙅 DropZone restrictions

Restrict which components can be passed into a DropZone component with the allow and disallow props.

const MyComponent = () => (
  <DropZone zone="my-content" allow={["HeadingBlock"]} />
);

Deprecations

renderHeader deprecated

The renderHeader prop has been deprecated in favor of the overrides API.

// Before
export function Editor() {
  return (
    <Puck
      renderHeader={({ appState, dispatch }) => ()}
    />
  );
}

// After
export function Editor() {
  return (
    <Puck
      overrides={{
        header: ({ appState, dispatch }) => ()
      }}
    />
  );
}

renderHeaderActions deprecated

The renderHeaderActions prop has been deprecated in favor of the overrides API.

// Before
export function Editor() {
  return (
    <Puck
      renderHeaderActions={({ appState, dispatch }) => ()}
    />
  );
}

// After
export function Editor() {
  return (
    <Puck
      overrides={{
        headerActions: ({ appState, dispatch }) => ()
      }}
    />
  );
}

Breaking changes

renderComponentList removed

The renderComponentList prop has been removed in favor of the overrides API.

// Before
export function Editor() {
  return (
    <Puck
      renderComponentList={({ appState, dispatch }) => ()}
    />
  );
}

// After
export function Editor() {
  return (
    <Puck
      overrides={{
        componentList: ({ appState, dispatch }) => ()
      }}
    />
  );
}

Plugin API revamped

The plugin API has been significantly revamped to match the overrides API.

// Before
export function Editor() {
  return (
    <Puck
      plugins={[
        { renderFields: ({ appState, dispatch }) => () }
      ]}
    />
  );
}

// After
export function Editor() {
  return (
    <Puck
      plugins={[
        overrides: {
          form: ({ appState, dispatch }) => ()
        }
      ]}
    />
  );
}

Changelog

Features

  • add "ui" prop to Puck to set the initial state (71f8b2f)
  • add APIs to restrict components dropped in DropZones (28f24f9)
  • add data migration API (f987324)
  • add generic Config type to Puck and Render components (1c4b97f)
  • add object field type (243278b)
  • add Puck class to outer div (0698a12)
  • add search to external fields (fe3b439)
  • add transformProps lib to migrate component props (1ec2a78)
  • add usePuck hook (13f3ccb)
  • introduce UI overrides API (8a7c325)
  • make onPublish prop optional (60f317f)
  • remove renderComponentList in favour of overrides API (97f65e3)
  • replace existing plugin API with plugin overrides (46cca26)
  • support compositional Puck (22f053f)
  • track isDragging in app state (841ae12)

Bug Fixes

  • don't crash when loading external data into array field items (d13d00b)
  • enable user to pass in config without casting (ee211e2), closes #185
  • fix broken nested array fields (7a3949f)
  • fix initial UI state on mobile (3aa0057)
  • prevent pollution of global styles into component overlay (3fcf8e3)
  • record history when a user selects an item (3a649c9)
  • remove packages triggering superficial security warning (0f52b61)
  • respect label in radio fields (fe550d7)
  • set aria-label on all loaders (9adca27)
  • stop color pollution in external field modals (2e1b5ef)
  • use correct title path in recipes (60244ba)
  • watch puck.config.tsx in Remix recipe (ecb276c)

New Contributors

Full Changelog: v0.12.0...v0.13.0

Don't miss a new puck release

NewReleases is sending notifications on new releases.