#Slot TypeScript issue: <Content /> works in config render but not in separate component

1 messages ยท Page 1 of 1 (latest)

willow junco
#

Hi Puck team! ๐Ÿ‘‹

I'm experiencing a TypeScript issue when using Slot fields in separate component files, following the documentation example.

Documentation example (works perfectly):

const config = {
  components: {
    Example: {
      fields: {
        content: {
          type: "slot",
        },
      },
      render: ({ content: Content }) => {
        return <Content />; // โœ… This works fine
      },
    },
  },
};

My issue - trying to extract to separate component:

// Following the TypeScript section in docs
import { Slot } from "@measured/puck";

type BgContainerProps = {
  Content: Slot; // Using Slot type as documented
  bgColor: string;
};

export function BgContainer({ Content, bgColor }: BgContainerProps) {
  return (
    <div style={{ backgroundColor: bgColor }}>
      <Content /> {/* โŒ TypeScript error: 'Content' cannot be used as JSX component */}
    </div>
  );
}

Current workaround:

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

export function BgContainer({ Content, bgColor }: WithSlotProps<BgContainerProps>) {
  const RenderContent = Content as unknown as React.ComponentType;
  return (
    <div style={{ backgroundColor: bgColor }}>
      <RenderContent />
    </div>
  );
}

Question:
The docs show <Content /> working directly in config render functions, but the same syntax fails in separate components even when using the Slot type. Is there a recommended pattern for extracting slot-based components, or should the TypeScript definitions be updated to handle this case?

Using Puck 0.19.1. Thanks for the amazing work on this library! ๐Ÿš€

lime merlin
#

Hey! Yeah, you need to type things separately when you split up your component. This isn't very well documented. Related: https://github.com/puckeditor/puck/issues/1102

This is probably a more suitable workaround using PuckComponent type:

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

export const BgContainer: PuckComponent<BgContainerProps> = ({ Content, bgColor } => {
  return (
    <div style={{ backgroundColor: bgColor }}>
      <Content />
    </div>
  );
}
GitHub

When passing a slot to a composable function like renderChild, I encountered a type mismatch error: export const renderChild = ( { type, props }: ChildrenType, puck: PuckContext, slotItem: Slot, zo...