puck icon indicating copy to clipboard operation
puck copied to clipboard

Cannot override custom field type

Open shannonhochkins opened this issue 1 month ago • 3 comments

Description

The code here doesn't allow us to "override" the custom field type.

The reason this is useful, is let's say you want all fields wrapped in a certain component to handle custom logic that all field types inherit, we can't do this currently with custom fields as it's bypassed in the link above.

For example:

import { Config, Plugin, FieldRenderFunctions } from '@measured/puck';
import { FieldDefinition } from '...';
type AllFieldRenderers = FieldRenderFunctions<
  Config<{
    fields: FieldDefinition;
  }>
>;

// Props accepted by any field renderer in fieldTypes (union of all variants)
type FieldWrapperProps = Parameters<AllFieldRenderers[keyof AllFieldRenderers]>[0];

const FieldWrapperInner = ({ field, name, onChange, value, id }: FieldWrapperProps) => {
  return (
    <StandardFieldWrapper
      field={field as StandardFieldComponentProps['field']}
      name={name}
      onChange={onChange}
      value={value}
      id={id ?? name}
    />
  );
};

export const createPuckOverridesPlugin = (): Plugin<
  Config<{
    fields: FieldDefinition;
  }>
> => {
  return {
    overrides: {
      ...
      fieldTypes: {
        unit: FieldWrapper,
        switch: FieldWrapper,
        custom: FieldWrapper,
    },
  };
};

Environment

  • Puck version: [latest]

Steps to reproduce

  1. Simply provide "custom" as a key in the overrides, and a generic function, it'll never execute the function.

export const createPuckOverridesPlugin = () => {
  return {
    overrides: {
      fieldTypes: {
        custom:() => {
             alert('yeah nah');
        },
    },
  };
};

What happens

Nothing :D

What I expect to happen

Internally, puck should allow overrides of the custom field type.

shannonhochkins avatar Oct 28 '25 03:10 shannonhochkins

Hey @shannonhochkins! Sorry for the long delay in getting back to you on this, I'll keep my eye on this from now on.

I think I understand what you mean, you basically want to wrap custom fields.

Would using more specific user-defined field types (which are not greatly documented) meet that need? Something like this:

const myConfig = {
  components: {
    MyComponent: {
      fields: {
        example: {
          type: "myFieldType",
          someCustomFieldConfig: "custom-value"
        }
      }
    }
  }
};

<Puck
  config={myConfig}
  overrides={{
    fieldTypes: {
      myFieldType: (props) => {
        return (
          <MyWrapper>
            Field for: {props.name}
            {/* props.field includes the `someCustomFieldConfig` property */}
            <MyCustomField
              field={props.field}
              value={props.value}
              onChange={props.onChange}
            />
          </MyWrapper>
        );
      },
    },
  }}
/>

The reason I suggest this approach is that custom fields are mostly meant for one-offs. Adding a global custom field override could potentially break existing usage in your app unless you explicitly call field.render, and even then, there might be side effects (like fields unmounting and losing focus or internal state) if it's not memoized properly. Using the override as a function is finicky.

Not completely against the idea, just wondering if the existing API might be a better fit for your use case.

FedericoBonel avatar Nov 18 '25 06:11 FedericoBonel

Hey!

I already have multiple custom fields declared the way you've written them above, however I have custom functionality that's automatically attached to every field types via the overrides, for example i have "device values" as a toggle that can be enabled for every field, allowing different values per breakpoint, which is a pain to wire up, and I'm also using module federation for community plugins, users wouldn't know how to wire it up

I could get around this with a different name other than "custom" as the field type, and just call the custom field internally, but just feels a bit messy and will over complicate the types that's all

shannonhochkins avatar Nov 18 '25 06:11 shannonhochkins

Hey @FedericoBonel Just wondering if this will be implemented, if not i'll have to introduce a new field type to achieve this, but would rather re-use the standard "custom" field type if possible, but would like to know if you guys think this will make it into puck before i do anything :)

shannonhochkins avatar Nov 29 '25 23:11 shannonhochkins

@shannonhochkins sorry for the delay - we plan on having another look at your PR shortly.

chrisvxd avatar Dec 04 '25 10:12 chrisvxd

All good my man! I have a few other bits and pieces to work on anyways :)

shannonhochkins avatar Dec 05 '25 01:12 shannonhochkins