Slot

Define a drag-and-drop area containing nested components.

This field does render any UI in the form section.

Interactive Demo
Example
const config = {
  components: {
    Example: {
      fields: {
        content: {
          type: "slot",
        },
      },
      render: ({ content: Content }) => {
        return <Content />;
      },
    },
    Card: {
      render: () => <div>Hello, world</div>,
    },
  },
};

TypeScript

When using TypeScript, make sure to use the Slot type so the render prop is correctly transformed.

import { Slot } from "@measured/puck";
 
type Props = {
  Example: {
    content: Slot; // Converted from the ComponentData[] type into a render function
  };
};

Params

ParamExampleTypeStatus
typetype: "slot"”slot”Required

Required params

type

The type of the field. Must be "slot" for Slot fields.

const config = {
  components: {
    Example: {
      fields: {
        content: {
          type: "slot",
        },
      },
      // ...
    },
  },
};

Render function

Slot data is provided to render() as a render function (or component). Provide props to this function to customize the behavior of the slot at render-time.

ParamExampleTypeStatus
allowallow: ["HeadingBlock"]Array-
classNameclassName: "MyClass"String-
collisionAxiscollisionAxis: "x"String-
disallowdisallow: ["HeadingBlock"]Array-
minEmptyHeightminEmptyHeight: 256Number-
refref: refRef-
stylestyle: {display: "flex"}CSSProperties-

allow

Only allow specific components to be dragged into the slot:

const config = {
  components: {
    Example: {
      render: ({ content: Content }) => {
        return <Content allow={["HeadingBlock"]} />;
      },
    },
  },
};

className

Provide a className to the rendered element. The default styles will still be applied.

const config = {
  components: {
    Example: {
      render: ({ content: Content }) => {
        return <Content className="MyComponent" />;
      },
    },
  },
};

collisionAxis

Configure which axis Puck will use for overlap collision detection.

Options:

  • x - detect collisions based their x-axis overlap
  • y - detect collisions based their y-axis overlap
  • dynamic - automatically choose an axis based on the direction of travel

The defaults are set based on the CSS layout of the parent:

  • grid: dynamic
  • flex (row): x
  • inline/inline-block: x
  • Everything else: y
const config = {
  components: {
    Example: {
      render: ({ content: Content }) => {
        return <Content collisionAxis="dynamic" />;
      },
    },
  },
};

disallow

Allow all but specific components to be dragged into the slot. Any items in allow will override disallow.

const config = {
  components: {
    Example: {
      render: ({ content }) => {
        return <Content disallow={["HeadingBlock"]} />;
      },
    },
  },
};

minEmptyHeight

The minimum height of the slot when empty, in pixels. Defaults to 128.

const config = {
  components: {
    Example: {
      render: () => {
        return <Content minEmptyHeight={256} />;
      },
    },
  },
};

ref

A React ref, assigned to the root node of the slot.

const config = {
  components: {
    Example: {
      render: ({ content: Content }) => {
        const ref = useRef();
 
        return <Content ref={ref} />;
      },
    },
  },
};

style

Provide a style attribute to the slot. The default styles will still be applied.

const config = {
  components: {
    Example: {
      render: ({ content: Content }) => {
        return <Content style={{ display: "flex" }} />;
      },
    },
  },
};