Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add custom component by id #3740

Merged
merged 10 commits into from Jul 3, 2023

Conversation

lironhl
Copy link
Contributor

@lironhl lironhl commented Jun 24, 2023

Reasons for making this change

Hi!
I added a feature that let's you render a custom field component for a schema, according to a schema $id
I added this feature because in my use case I had two string fields that needed to be rendered in different ways -
Let me demonstrate, suppose I have this json-schema:

{
  "type": "object",
  "properties": {
    "customerName": {
      "type": "string"
    },
    "firstDish": {
      "type": "string"
    },
    "seconDish": {
      "type": "string"
    }
  }
}

Let's treat this json-schema as json-schema that represents a customer order in my restaurant website.
I'd want react-jsonschema-form to render the first property customerName as regular field of string input.
But to maximize the customer UX I'd want react-jsonschema-form to be able to let me render the fields firstDish and secondDish with custom components that also auto-complete the user input with dishes name from the restaurant.

In the current way of using react-jsonschema-form I suppose I could achieve this behaviour by iterating over my json-schema and building uiSchema according to my wishes.
But I find iterating over json-schema hard because of ref keyword and it's general nested structure.
I thought that because of the reason that react-jsonschema-form has option to render custom field according to schema type, a good and valuable addition would be to render custom field according to schema $id.

So now instead of the json-schema above, you could enter this json-schema:

{
 "type": "object",
 "definitions": {
   "dish": {
       "$id": "/schemas/dish",
       "type": "string"
   }
 },
 "properties": {
   "customerName": {
     "type": "string"
   },
   "firstDish": {
     "$ref": "#/definitions/dish"
   },
   "seconDish": {
     "$ref": "#/definitions/dish"
   }
 },
}

And add this prop to the Form component:

<Form
  fields={{  "/schemas/dish": DishComponent }}
>

And then have the customerName field render as planned and firstDish and secondDish render differently as planned.

I'd love to hear feedback and change my code if needed :)

Screencast.from.24-06-23.16.13.45.webm

How do I added it to the Agenda? I'll leave a message about this PR on the discord community

Checklist

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

@nickgros
Copy link
Contributor

Hi @lironhl this is a great idea! Can you fix the lint errors and add a test to SchemaField.test.jsx to verify that a custom field that matches an ID is used?

@heath-freenome
Copy link
Member

Hi @lironhl this is a great idea! Can you fix the lint errors and add a test to SchemaField.test.jsx to verify that a custom field that matches an ID is used?

I agree! Also please update the CHANGELOG.md file to add 5.10.0 for this feature

@lironhl
Copy link
Contributor Author

lironhl commented Jun 30, 2023

Thanks! I really appreciate the encouragement guys!
I think I applied all the changes you wanted, let me know if any further action is needed from my side :)
I even tried to document the change in the docs.

Copy link
Member

@heath-freenome heath-freenome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lironhl Looks good, I'll let @nickgros also take a peek and give his approval

CHANGELOG.md Outdated Show resolved Hide resolved
@lironhl
Copy link
Contributor Author

lironhl commented Jul 1, 2023

Also if you want to rephrase my English you're more than welcome :)

@nickgros
Copy link
Contributor

nickgros commented Jul 3, 2023

@lironhl I made a few small changes on the typos and docs but this looks great to me! I'll merge as soon as the build passes.

@@ -134,6 +134,41 @@ describe('SchemaField', () => {
});
});

describe('Custom type component', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, thanks for adding this missing test!

@nickgros nickgros merged commit 0d30be8 into rjsf-team:main Jul 3, 2023
4 checks passed
@lironhl lironhl deleted the feature/component-by-id branch October 6, 2023 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core feature Is a feature request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants