react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

feat(templates): Allow customization per-field by using Registry string key

Open nagaozen opened this issue 1 year ago • 15 comments

Fixes #3695

Reasons for making this change

Currently, to per-field customize the template, it is necessary to send the function/class of the component in the uiSchema, breaking the JSON nature of the uiSchema. It's not possible to provide just the registration key.

This PR fixes this issue by allowing the consumer of the library (the one with access to changing only schema, uiSchema and formData) to choose a different template provided to the form by the developer.

@ahkhanjani, could you please review?

Checklist

  • [x] I'm updating documentation
  • [x] I'm adding or updating code
    • [x] I've added and/or updated tests. I've run npm run test:update to update snapshots, if needed.
    • [x] I've updated docs if needed
    • [x] I've updated the changelog with a description of the PR
  • [x] I'm adding a new feature
    • [x] I've updated the playground with an example use of the feature

nagaozen avatar Sep 26 '23 15:09 nagaozen

Anyone to help the review this PR? @heath-freenome?

nagaozen avatar Sep 27 '23 15:09 nagaozen

@nagaozen This fix makes sense in the basic form, only it doesn't really help the situation where someone wants to build multiple templates to override. Because, currently, the TemplateTypes interface only supports the known template names, by simply adding a new (say) ObjectFieldTemplate to the template prop in the Form ALL ObjectFieldTemplates will now use this implementation. So basically, by simply adding the updated implemention as the ObjectFieldTemplate in templates it will replace the OOTB implementation provided by core or the theme you are using. So picking the name inside of a uiSchema is effectively the same as not providing it at all.

If what you are hoping to support is something like how fields and widgets work (i.e. allowing a user to build several ObjectFieldTemplate implementations and override the uiSchema to select from one of the implementations), then more work is necessary.

For one, you will have to extend the TemplateTypes interface to support custom named templates for a specific type (note fields and widgets all have the same Typescript type where as templates have unique Typescript types). This is no easy task and requires an enhancement to the design of the templates scheme in RJSF. Come to the next weekly meeting if you'd like to talk about it.

heath-freenome avatar Oct 06 '23 20:10 heath-freenome

@nagaozen This fix makes sense in the basic form, only it doesn't really help the situation where someone wants to build multiple templates to override. Because, currently, the TemplateTypes interface only supports the known template names, by simply adding a new (say) ObjectFieldTemplate to the template prop in the Form ALL ObjectFieldTemplates will now use this implementation. So basically, by simply adding the updated implemention as the ObjectFieldTemplate in templates it will replace the OOTB implementation provided by core or the theme you are using. So picking the name inside of a uiSchema is effectively the same as not providing it at all.

If what you are hoping to support is something like how fields and widgets work (i.e. allowing a user to build several ObjectFieldTemplate implementations and override the uiSchema to select from one of the implementations), then more work is necessary.

For one, you will have to extend the TemplateTypes interface to support custom named templates for a specific type (note fields and widgets all have the same Typescript type where as templates have unique Typescript types). This is no easy task and requires an enhancement to the design of the templates scheme in RJSF. Come to the next weekly meeting if you'd like to talk about it.

@heath-freenome, thank you for your response. My idea with this patch is to use the existing mechanism for customizing templates per field as described in https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/docs/docs/advanced-customization/custom-templates.md. The difference is that, instead of receiving the function directly in the uiSchema body, the developer can choose to insert another key in the template registry that can be used instead of manually sending the entire component manually (think about using the same customized template in different fields). I'm sure the patch works as we are already running it on production. For example, see how we are using the layout template at https://actions.looplex.com/code/custom-widgets-showcase for both Shipping Address object and Strings. There's also an example of our autofill field working: try to type "01302001" on the CEP field and TAB for the next field :-)

image

I'll be glad to expose the reasoning behind the patch in the next weekly. Thank you for the invitation.

nagaozen avatar Oct 09 '23 16:10 nagaozen

@nagaozen This fix makes sense in the basic form, only it doesn't really help the situation where someone wants to build multiple templates to override. Because, currently, the TemplateTypes interface only supports the known template names, by simply adding a new (say) ObjectFieldTemplate to the template prop in the Form ALL ObjectFieldTemplates will now use this implementation. So basically, by simply adding the updated implemention as the ObjectFieldTemplate in templates it will replace the OOTB implementation provided by core or the theme you are using. So picking the name inside of a uiSchema is effectively the same as not providing it at all. If what you are hoping to support is something like how fields and widgets work (i.e. allowing a user to build several ObjectFieldTemplate implementations and override the uiSchema to select from one of the implementations), then more work is necessary. For one, you will have to extend the TemplateTypes interface to support custom named templates for a specific type (note fields and widgets all have the same Typescript type where as templates have unique Typescript types). This is no easy task and requires an enhancement to the design of the templates scheme in RJSF. Come to the next weekly meeting if you'd like to talk about it.

@heath-freenome, thank you for your response. My idea with this patch is to use the existing mechanism for customizing templates per field as described in https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/docs/docs/advanced-customization/custom-templates.md. The difference is that, instead of receiving the function directly in the uiSchema body, the developer can choose to insert another key in the template registry that can be used instead of manually sending the entire component manually (think about using the same customized template in different fields). I'm sure the patch works as we are already running it on production. For example, see how we are using the layout template at https://actions.looplex.com/code/custom-widgets-showcase for both Shipping Address object and Strings. There's also an example of our autofill field working: try to type "01302001" on the CEP field and TAB for the next field :-)

image

I'll be glad to expose the reasoning behind the patch in the next weekly. Thank you for the invitation.

After thinking more about it, I believe that changing the TemplateType and the associated types like I've noted above will be enough

heath-freenome avatar Oct 13 '23 19:10 heath-freenome

@nagaozen Any progress on this?

heath-freenome avatar Nov 15 '23 19:11 heath-freenome

@nagaozen Any progress on this?

Hi @heath-freenome ! I am deep diving in a vital feature in my business, but asked if someone in my team could implement the static typing requirements for us. If nobody cares to conclude the ticket I'll come to finish it asap. Thanks for the insights

nagaozen avatar Nov 15 '23 21:11 nagaozen

@nagaozen there's a similar request in #3962 with a slightly different API than you've proposed. What do you think of this?

nickgros avatar Nov 17 '23 21:11 nickgros

@nagaozen there's a similar request in #3962 with a slightly different API than you've proposed. What do you think of this?

Hi @nickgros,

Ultimately, the goal is the same: "Customize the ObjectFieldTemplate through the uiSchema." The use case presented by @elevesque-nexapp is similar to what we are facing here: "The backend is produced by an engineering team and the frontend developer provides only the schema, uiSchema, and formData." This segregation of concern is what makes this feature necessary. Because backend developers can document these alternatives so that frontend engineers can use them. As for the suggested approach (nesting the options in objects), it differs from how the library already handles custom widgets and fields. Therefore I believe this current approach superior in terms of DX.

nagaozen avatar Nov 18 '23 03:11 nagaozen

I agree the solution proposed here is better aligned with how customization works for other fields. I'd be perfectly happy to see this solution merged!

elevesque-nexapp avatar Nov 20 '23 13:11 elevesque-nexapp

@nagaozen Seems like your solution is the winner. Let's get those typing changes made and then we complete your PR

heath-freenome avatar Nov 27 '23 17:11 heath-freenome

@nagaozen Do you think you will have time for this?

Maybe I can play with this to see if I can get it to a mergeable state

smithaitufe avatar Feb 26 '24 13:02 smithaitufe

@nagaozen Do you think you will have time for this?

Maybe I can play with this to see if I can get it to a mergeable state

Oh, please be my guest. Its on my todo list for a considerable time. I believe this will greatly improve the library.

nagaozen avatar Feb 26 '24 13:02 nagaozen

Hello, any news about this PR ?

lucasmcht avatar Jun 02 '24 17:06 lucasmcht

@nagaozen Do you think you will have time for this? Maybe I can play with this to see if I can get it to a mergeable state

Oh, please be my guest. Its on my todo list for a considerable time. I believe this will greatly improve the library.

I would gladly make the required changes but I don't have the rights to update your branch

lucasmcht avatar Jun 04 '24 13:06 lucasmcht

@Oddwerth You could create your own fork and then cherry pick these changes from theirs

heath-freenome avatar Jun 06 '24 00:06 heath-freenome