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

fix: upgrade react types to fix component type from memo wrapper #2144

Merged
merged 6 commits into from
Mar 12, 2024

Conversation

chrispulsinelli-okta
Copy link
Contributor

@chrispulsinelli-okta chrispulsinelli-okta commented Feb 21, 2024

OKTA-699592

Summary

Testing & Screenshots

  • I have confirmed this change with my designer and the Odyssey Design Team.

@chrispulsinelli-okta chrispulsinelli-okta marked this pull request as ready for review February 22, 2024 19:34
@chrispulsinelli-okta chrispulsinelli-okta requested a review from a team as a code owner February 22, 2024 19:34
Copy link
Contributor

@jordankoschei-okta jordankoschei-okta left a comment

Choose a reason for hiding this comment

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

Approved, pending a response about those commented-out lines

packages/odyssey-react-mui/src/OdysseyThemeProvider.tsx Outdated Show resolved Hide resolved
| NullElement
>
| NullElement;
children: ReactNode | NullElement;
Copy link
Contributor

Choose a reason for hiding this comment

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

@chrispulsinelli-okta What problem are we solving here exactly? Conditional rendering? Are we cool with allowing anything to be rendered in the menu item list?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A couple of things, actually.
From my usage of this, ReactElement<typeof MenuItem | typeof Divider | typeof ListSubheader> doesn't actually restrict one from using a Button, for example, where we think the generic typing restricts it.

Also, this doesn't allow for null or undefined to be passed in, which are valid JSX values to be passed to render.

ReactNode is a bit more lax in what it allows, allows for nullish values, and also arrays.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right on. Just wanted to touch base since it was making things more permissive. I don't disagree with the change. Just figured it was worth having a quick touch base about.

Copy link
Contributor

Choose a reason for hiding this comment

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

Part of the reason we used specific types for children is to ensure other devs know what we expect to be passed in.

Using ReactNode (we shouldn't need NullElement in that case) opens it up so devs can pass anything and won't know exactly what we expect without looking at Storybook.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've mentioned this in another comment in this PR, but will address it here as well.

Part of the reason we used specific types for children is to ensure other devs know what we expect to be passed in.

Understood and I agree with the sentiments that we should be clear about what we expect our users to provide here, but this expression of the type is both hard to read and doesn't actually restrict users to provide the explicit types of react elements listed here.

Personally, I believe it's best to document the expectations in comments and stories and make it much easier to read the type.

Using ReactNode (we shouldn't need NullElement in that case) opens it up so devs can pass anything and won't know exactly what we expect without looking at Storybook.

Using ReactElement also allows users to pass any component of generic type ReactElement. We actually are not preventing them from passing in any other components than the ones explicitly mentioned here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused by your statement. I get that the TS doesn't work correctly, but you wrote ReactElement at the end, not ReactNode like the code.

ReactElement is for React components, but I don't think it works for HTML.

ReactNode is any valid React component, HTML element, null, and false if I'm remembering correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a bit confused by your statement. I get that the TS doesn't work correctly, but you wrote ReactElement at the end, not ReactNode like the code.

Sorry for the confusion. I'm simply trying to make the point that using ReactElement<typeof FooComponent> doesn't guarantee us that users will provide and only provide a FooComponent.

@KevinGhadyani-Okta
Copy link
Contributor

@chrispulsinelli-okta Is this something we missed in the last upgrade pass on Odyssey?

Comment on lines +293 to +309
const AutocompleteOuterContainer = styled("div")({
display: "flex",
gap: "2",
alignItems: "flex-end",
});

const AutocompleteInnerContainer = styled("div")({
width: "100%",
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we purposefully removing the alignItems: "flex-end"; from the previous changes for some reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't remove flex-end alignment.. I actually removed center.
This:

align-items: center;
alignitems: "flex-end";

became this:

alignItems: "flex-end",

(The browser would have cascaded the styles and removed align-items: center anyways)

@@ -29,7 +29,7 @@ export type RadioGroupProps = {
/**
* The Radio components within the group. Must include two or more.
*/
children: Array<ReactElement<typeof Radio>>;
children: ReactNode;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we making this change to ReactNode from specifying Radio component types as children?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Basically, ReactElement<typeof Radio> does nothing to prevent a user from providing something else, like ReactElement<typeof Chekbox>, as a member of the collection provided to the children prop of this RadioGroup.

ReactNode gives us everything Array<ReactElement<typeof Radio>> gives us, as well as the ability to provide undefined and null as values to children, which is the real motivation for my change.

TS doesn't actually enforce the collection of children to be react element's of type Radio; I can provide Checkbox components in lieu of Radio and according to TS, nothing would be wrong with this.

Personally, I'd like for us to recognize that the current provided type isn't actually limiting users to what we want them to provide and is actually making it more difficult to provide actual nullish values that React allows users to provide as children.

Here's how MUI does this, with their expectation of users in a comment, rather than by a type that doesn't work:
image

@chrispulsinelli-okta chrispulsinelli-okta force-pushed the cp-OKTA-699592-fix-memo-return-type branch from d3ec769 to 88c29bc Compare March 11, 2024 15:02
@chrispulsinelli-okta
Copy link
Contributor Author

@KevinGhadyani-Okta Yea, this is an incremental update to things we upgraded previously that would help adoption of Odyssey. I was finding these things as part of my work to upgrade Odyssey in admin ui.

@chrispulsinelli-okta chrispulsinelli-okta merged commit ead53ee into main Mar 12, 2024
1 of 2 checks passed
@chrispulsinelli-okta chrispulsinelli-okta deleted the cp-OKTA-699592-fix-memo-return-type branch March 12, 2024 20:28
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.

None yet

4 participants