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

bootstrap-4 TextWidget wrappers now pull from registry, add rootSchema to Registry, Fix FieldProps.onFocus type to match WidgetProps #2519

Conversation

heath-freenome
Copy link
Member

@heath-freenome heath-freenome commented Aug 17, 2021

Reasons for making this change

  • These changes allow all of these TextWidget wrappers (like EmailWidget, etc...) to immediately use a custom TextWidget class
  • Updated the Registry type in the core/index.d.ts file to add rootSchema and fix the indenting
    • This fixed a TODO and avoids the need to cast registry to any in the three typescript ArrayFieldTemplate implementations
    • Replaced the usage FieldProps['registry'] with Registry now that a separate type exists
  • Also updated WidgetProps to add a generic [prop: string]: any just like FieldProps has
    • This eliminated the custom TextWidgetProps for bootstrap-4 which prevented a previous PR from converting the TextWidget wrappers
  • Finally, made the FieldProps.onFocus match the definition of WidgetProps.onFocus to avoid type conversion error when creating custom Field components that pass onFocus to a Widget
  • Updated all of the bootstrap-4 widgets to use TextWidget from the registry, using simple WidgetProps
    • Updated TextWidget to remove TextWidgetProps and to simply use WidgetProps
  • Updated the material-ui UpDownWidget tests to add a blank rootSchema to the registry
  • Updated the bootstrap-4 createMock() to add a blank rootSchema to the registry as well as adding TextWidget to the registry.widgets

If this is related to existing tickets, include links to them as well. Use the syntax fixes #[issue number] (ex: fixes #123).
Fixes #2512 for bootstrap-4

Checklist

  • I'm updating documentation
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

…port `TextWidget` from the source hierarchy, instead pull from the `registry.widgets`

- These changes allow all of these `TextWidget` wrappers (like `EmailWidget`, etc...) to immediately use a custom `TextWidget` class
- Updated the `Registry` type in the `core/index.d.ts` file to add `rootSchema`
  - This fixed a TODO and avoids the need to cast `registry` to any in the three typescript `ArrayFieldTemplate` implementations
- Also updated `WidgetProps` to add an optional `type`
  - This eliminated the custom `TextWidgetProps` for `bootstrap-4` which prevented a previous PR from converting the `TextWidget` wrappers
- Updated all of the `bootstrap-4` widgets to use `TextWidget` from the registry, using simple `WidgetProps`
  - Updated `TextWidget` to remove `TextWidgetProps` and to simply use `WidgetProps`
- Updated the `material-ui` `UpDownWidget` tests to add a blank `rootSchema` to the `registry`
- Updated the `bootstrap-4` `createMock()` to add a blank `rootSchema` to the `registry` as well as adding `TextWidget` to the `registry.widgets`
@heath-freenome
Copy link
Member Author

@epicfaace I figured out how to fix bootstrap-4 for #2512 assuming the change I made to WidgetProps is acceptable.

packages/core/index.d.ts Outdated Show resolved Hide resolved
- Made the `FieldProps.onFocus` match the definition of `WidgetProps.onFocus` to avoid type conversion error when creating custom components
@heath-freenome heath-freenome changed the title bootstrap-4 TextWidget wrappers now pull from registry, add rootSchema to Registry bootstrap-4 TextWidget wrappers now pull from registry, add rootSchema to Registry, Fix FieldProps.onFocus type to match WidgetProps Aug 17, 2021
@heath-freenome
Copy link
Member Author

@epicfaace I imagine you are rather busy... Is there another person who you know of who can complete this review?

@epicfaace
Copy link
Member

epicfaace commented Aug 19, 2021 via email

@heath-freenome
Copy link
Member Author

@epicfaace or @jimmycallin I'd love to be able to merge these changes. I hope one of you two can complete the review soon

@heath-freenome
Copy link
Member Author

@epicfaace Is there one or two other PRs that I could review for you in return for a review on this? Are you worried about the type changes causing problems?

@@ -36,7 +32,7 @@ const TextWidget = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const inputType = (type || schema.type) === 'string' ? 'text' : `${type || schema.type}`
Copy link
Member

Choose a reason for hiding this comment

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

The one thing remaining is that I'm a bit confused as to why TextWidget uses the type prop, but only in the bootstrap-4 theme. Could you point me to the code that actually passes the type prop? And would it be better / equivalent / more consistent to change this line of code to not use type, in favor of something like this (https://github.com/rjsf-team/react-jsonschema-form/blob/master/packages/fluent-ui/src/TextWidget/TextWidget.tsx#L73)?

Copy link
Member Author

Choose a reason for hiding this comment

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

The type prop is also used in the @material-ui theme... but the TextWidgetProps there have been expanded to include the @material-ui TextField props, so passing type in works there (sadly I spent a decent amount of time trying to apply a similar solution to bootstrap-4 with no success :( ). See https://github.com/rjsf-team/react-jsonschema-form/blob/master/packages/material-ui/src/TextWidget/TextWidget.tsx#L11. I'm not against doing what fluent-ui does with type for bootstrap-4 if that feels more comfortable for you.

Copy link
Member Author

Choose a reason for hiding this comment

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

I am curious if you feel like the WidgetProps should be restricted to only those current props defined on it, unlike the FieldProps which has the catch-all "other props" [prop: string]: any; defined on it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Honestly, with the change to WidgetProps that I'm proposing, I could probably remove the override that material-ui has since the catch-all would do the same thing. Heck, most of the code between the three packages for the TextWidget overrides could probably be standardized into the same exact code (most of which very closely matches how core does it)... which makes me wonder whether it makes sense to do a bit more work in core to use TextWidget rather than BaseInput... or make all three Typescript implementations simple provide their TextWidget implementation as the BaseInput and remove all the overrides that are simply the override the "type" since thats what core already does.

Copy link
Member

Choose a reason for hiding this comment

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

I am curious if you feel like the WidgetProps should be restricted to only those current props defined on it, unlike the FieldProps which has the catch-all "other props" [prop: string]: any; defined on it?

I think using the catch-all is OK for this PR.

Honestly, with the change to WidgetProps that I'm proposing, I could probably remove the override that material-ui has since the catch-all would do the same thing. Heck, most of the code between the three packages for the TextWidget overrides could probably be standardized into the same exact code (most of which very closely matches how core does it)... which makes me wonder whether it makes sense to do a bit more work in core to use TextWidget rather than BaseInput... or make all three Typescript implementations simple provide their TextWidget implementation as the BaseInput and remove all the overrides that are simply the override the "type" since thats what core already does.

Yeah, if you'd like to do additional refactoring, that would also be good. Let's not do it in this PR, though, maybe in a separate PR if you are interested in doing it.

const URLWidget = (props: TextWidgetProps) => {
const URLWidget = (props: WidgetProps) => {
const { registry } = props;
const { TextWidget } = registry.widgets;
return <TextWidget {...props} type="url" />;
Copy link
Member Author

Choose a reason for hiding this comment

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

@epicfaace This is one place where type is passed... material-ui uses the same exact pattern. fluent-ui chose to put type into the ui:options.props and then extracts it on the line above what you mentioned, filters out non-fluent props and spreads it over the default type that is being extracted on the line you mentioned.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, this makes sense now

const URLWidget = (props: TextWidgetProps) => {
const URLWidget = (props: WidgetProps) => {
const { registry } = props;
const { TextWidget } = registry.widgets;
return <TextWidget {...props} type="url" />;
Copy link
Member

Choose a reason for hiding this comment

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

Thanks, this makes sense now

@@ -36,7 +32,7 @@ const TextWidget = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const inputType = (type || schema.type) === 'string' ? 'text' : `${type || schema.type}`
Copy link
Member

Choose a reason for hiding this comment

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

I am curious if you feel like the WidgetProps should be restricted to only those current props defined on it, unlike the FieldProps which has the catch-all "other props" [prop: string]: any; defined on it?

I think using the catch-all is OK for this PR.

Honestly, with the change to WidgetProps that I'm proposing, I could probably remove the override that material-ui has since the catch-all would do the same thing. Heck, most of the code between the three packages for the TextWidget overrides could probably be standardized into the same exact code (most of which very closely matches how core does it)... which makes me wonder whether it makes sense to do a bit more work in core to use TextWidget rather than BaseInput... or make all three Typescript implementations simple provide their TextWidget implementation as the BaseInput and remove all the overrides that are simply the override the "type" since thats what core already does.

Yeah, if you'd like to do additional refactoring, that would also be good. Let's not do it in this PR, though, maybe in a separate PR if you are interested in doing it.

@epicfaace epicfaace merged commit 9c0dd42 into rjsf-team:master Aug 26, 2021
@heath-freenome
Copy link
Member Author

Yeah, if you'd like to do additional refactoring, that would also be good. Let's not do it in this PR, though, maybe in a separate PR if you are interested in doing it.

I am interested in doing it... Do I need an issue for that or just push a PR when it's ready?

@epicfaace
Copy link
Member

That'd be great! An issue is not required, but it might be nice to make an issue if it doesn't take too much time so it's easier to organize what work is going to be done.

@heath-freenome heath-freenome deleted the bootstrap-4-pulls-TextWidget-from-registry branch February 22, 2022 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Customizing @material-ui TextWidget requires me to customize ALL of the TextWidget wrapped widgets
2 participants