Should we bring back native element prop getters? #1145
Replies: 2 comments
-
|
Thank you very much for the detailed write-up! Do you want the props getter back?Adding to what's already been mentioned, another nuance worth mentioning is that React's const forms = configureForms({
extendFieldMetadata(metadata) {
return {
get selectProps() {
return {
defaultValue: metadata.multiple // <---
? metadata.defaultOptions // <---
: metadata.defaultValue, // <---
form: metadata.formId,
id: metadata.id,
name: metadata.name,
required: metadata.required,
} satisfies SelectProps;
},
};
},
});Such logic is best kept in a prop getter. Would a CLI that scaffolds the config for you solve this, or is there value in having it built-in?If a CLI emits code that users keep under version control, the users take ownership of their scaffolds, which allows them to modify the form configs. Future versions of Conform might add new props, but users who use a modified scaffold would then be faced with friction to keep their modifications in sync with the latest version of Conform's scaffold. Merging scaffolds tends to involve regenerating the scaffold to another file, diffing the new scaffold against the old user-modified scaffold, and then spend some time working out what needs to go where. This could be avoided by creating boundaries that isolate library code from user code. Prop getters could achieve this and make updates smoother: import { getTextFieldProps } from "@conform-to/react/future/material-ui";
import type { ComponentProps } from "react";
import type { TextField } from "@mui/material";
const forms = configureForms({
extendFieldMetadata(metadata) {
return {
get textFieldProps() {
return {
...getTextFieldProps(metadata),
variant: "filled"
} satisfies ComponentProps<TextField>;
},
};
},
});If we add built-in native prop getters alongside custom metadata, do you think it would be confusing?Code structuring (and docs, to a lesser degree) are very much key. Something like the code above, where you import UI-library-specific getters, should also be tree-shakable and help keep things structured. If the prop getters were all accessible through My conclusionI believe that separate helpers promise the best DX, and also the fastest UX through smallest bundle size. |
Beta Was this translation helpful? Give feedback.
-
|
Hey,
Do you want the props getter back?Built-in native props getters were useful, as sometimes the IU library version is not used, and going back to the native HTML element is required. Keeping them separated seems cleaner, imo. The v1 API was great when no customisation was needed. It also leaves the possibility of writing a "custom native" getter anyway if it seems more appropriate. const forms = configureForms({
extendFieldMetadata(metadata){
get racSelectProps () {
// React aria components logic
}
get nativeSelectProps () {
return getSelectProps(metadata)
}
}
})Would a CLI that scaffolds the config for you solve this, or is there value in having it built-in?I like the idea of built-in helpers for different UI libraries, but I am curious about what will be inside those helpers, as UI libraries are more and more headless, and component composition and props wiring are more and more up to the developer. The maintained examples were a great addition to the documentation, providing a basis for building and adapting to the specificity of each code base, where v1 props getters were not enough. Built-in helper might not be relevant when UI library version brings a breaking change (for example, for the multi-selection in React Aria, here). Listing the example in the If we add built-in native prop getters alongside custom metadata, do you think it would be confusing?It might not be confusing with clear |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
In v1, Conform had built-in prop getters like
getInputProps()andgetSelectProps()for native HTML elements. The newconfigureFormsAPI takes a different approach withextendFieldMetadata: you define exactly what props you need for your components, and they become available on the field metadata.The reason I moved away from built-in getters is that in practice, people often spread them onto UI library components, not native elements. UI libraries have their own naming conventions, and TypeScript won't warn about extra props when spreading. They just silently pass through.
The feedback
In #1131, someone raised a few good points:
extendFieldMetadata, you need to know which validation attributes apply to which element (e.g.min/maxfor<input>but not<select>). Built-in getters handled this for you.My thoughts
I understand the friction. You shouldn't have to think about which validation attributes apply to which element type. That's something the library can handle for you.
That said, if both
nativeInputPropsand custominputPropsexist on metadata, it could confuse developers who just build forms but didn't set up the config. "Which one should I use?"One idea I'm considering is a CLI that scaffolds the config for you:
It would generate a
forms.tswith the fullextendFieldMetadatasetup for your chosen UI library. We already maintain examples for shadcn, chakra, material-ui, etc. This would just make them easier to use as starting points.You'd own the code and can customize it, but you get a working config without having to think about which attributes apply to which element. The setup is a one-time thing, and most projects don't have that many input types.
If we bring them back
If we do bring back native prop getters, there are two main approaches:
Always available on metadata
Simple and discoverable, but could be confusing alongside custom props from extendFieldMetadata.
Separate helper functions (like v1)
Clear separation from custom metadata, but a different API style.
Open questions
Would love to hear your thoughts.
3 votes ·
Beta Was this translation helpful? Give feedback.
All reactions