AutoField unconditionally overrides custom id prop instead of falling back like AutoFieldInternal
Description
FieldProps defines an optional id?: string prop for fields. However, <AutoField /> unconditionally generates a new ID with const id = useSafeId() and passes id={id} after {...props}, overriding any custom id supplied by the caller.
In contrast, AutoFieldInternal respects an existing id prop with fallback:
const { id, Label = FieldLabelInternal } = props;
const defaultId = useSafeId();
const resolvedId = id || defaultId;Because fields like ArrayField and ObjectField now read their state from fieldStore using name (which defaults to id), AutoField needs the store key in <fieldContextStore.Provider value={{ [id]: props.value }}> to match the id passed to <AutoFieldPublicInternal />. However, doing const id = props.id || useSafeId() would keep fieldContextStore and child fields in sync while still allowing custom IDs to be preserved.
Is there a specific reason why AutoField overrides potential incoming IDs rather than resolving them with a fallback like AutoFieldInternal?
Environment
- Puck version: since 0.21.0
Steps to reproduce
- Render an
<AutoField />and pass an explicitid:
<AutoField
field={{
type: "text",
label: "Custom Field",
}}
value={value}
onChange={setValue}
id="my-custom-id"
/>- Inspect the rendered DOM elements or field store key.
What happens
The provided id="my-custom-id" is completely ignored.
In packages/core/components/AutoField/index.tsx:
export function AutoField<
ValueType = any,
FieldType extends FieldNoLabel<ValueType> = FieldNoLabel<ValueType>
>(props: FieldProps<FieldType, ValueType> & { value: any }) {
const id = useSafeId();
if (props.field.type === "slot") {
return null;
}
return (
<fieldContextStore.Provider value={{ [id]: props.value }}>
<AutoFieldPublicInternal<ValueType, FieldType> {...props} id={id} />
</fieldContextStore.Provider>
);
}Because id={id} is spread after {...props}, the newly generated useSafeId() always clobbers props.id.
What I expect to happen
AutoField should honor props.id when provided, falling back to useSafeId() only if props.id is undefined.
Additional Media
Source: puckeditor/puck