Custom Fields
Puck can be extended with completely custom fields for different use-cases.
Creating a custom field
Creating a custom field is possible using the custom
field type:
const config = {
components: {
Example: {
fields: {
title: {
type: "custom",
render: ({ name, onChange, value }) => (
<input
defaultValue={value}
name={name}
onChange={(e) => onChange(e.currentTarget.value)}
style={{ border: "1px solid black", padding: 4 }}
/>
),
},
},
render: ({ title }) => {
return <p>{title}</p>;
},
},
},
};
The onChange
function updates the Puck data payload for the field name, in this case "title".
Example
Hello, world
Adding a label
You can add your own label, but it's recommended to use the <FieldLabel>
component provided by Puck to seamlessly integrate into the Puck field UI.
import { FieldLabel } from "@measured/puck";
const config = {
components: {
Example: {
fields: {
title: {
type: "custom",
label: "Label Example"
render: ({ field }) => (
<FieldLabel label={field.label}>
<input {/*...*/} />
</FieldLabel>
),
},
},
// ...
},
},
};
Example
Hello, world
Updating the UI state
The onChange
function can also be used to modify the Puck UI state at the same time as updating the field value:
const config = {
components: {
Example: {
fields: {
title: {
type: "custom",
render: ({ name, onChange, value }) => (
<input
defaultValue={value}
name={name}
onChange={(e) =>
onChange(
e.currentTarget.value,
// Close the left side bar when this field is changed
{ leftSideBarVisible: false }
)
}
style={{ border: "1px solid black", padding: 4 }}
/>
),
},
},
render: ({ title }) => {
return <p>{title}</p>;
},
},
},
};