-
Notifications
You must be signed in to change notification settings - Fork 534
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 TextInput types #1959
Fix TextInput types #1959
Conversation
🦋 Changeset detectedLatest commit: ac292b3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
size-limit report 📦
|
> | ||
|
||
// Note: using ComponentProps instead of ComponentPropsWithoutRef here would cause a type issue where `css` is a required prop. | ||
type TextInputInternalProps = Merge<React.ComponentPropsWithoutRef<typeof UnstyledTextInput>, NonPassthroughProps> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line was the root of the problem. Passing a styled component type to React.ComponentPropsWithoutRef
yields an any
type
import styled from 'styled-components'
import React from 'react'
const StyledComponent = styled.div`...`
type Props =
React.ComponentPropsWithoutRef<typeof StyledComponent>
// any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know so we don't make this mistake in the future.
| 'minWidth' | ||
| 'variant' | ||
| 'size' | ||
| 'validationStatus' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type was missing validationStatus
/** @deprecated Use `leadingVisual` or `trailingVisual` prop instead */ | ||
icon?: React.ComponentType<{className?: string}> | ||
leadingVisual?: string | React.ComponentType<{className?: string}> | ||
trailingVisual?: string | React.ComponentType<{className?: string}> | ||
} & Pick< | ||
ComponentProps<typeof TextInputWrapper>, | ||
'block' | 'contrast' | 'disabled' | 'monospace' | 'sx' | 'width' | 'maxWidth' | 'minWidth' | 'variant' | 'size' | ||
StyledWrapperProps, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ComponentProps<>
wasn't necessary here. We should avoid using ComponentProps<>
when possible because it can yield unexpected results somtimes.
@@ -78,13 +87,12 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputInternalProps>( | |||
</TextInputWrapper> | |||
) | |||
} | |||
) | |||
) as PolymorphicForwardRefComponent<'input', TextInputProps> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the polymorphic type utility from Radix here to implement correct types for the as
prop.
Eventually, we should deprecate the as
prop for TextInput. I can't think of a good use case for it now that we have the Textarea
component
@@ -53,7 +52,7 @@ type TextInputWithTokensInternalProps<TokenComponentType extends AnyReactCompone | |||
* The number of tokens to display before truncating | |||
*/ | |||
visibleTokenCount?: number | |||
} & TextInputProps | |||
} & Omit<TextInputProps, 'size'> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The size
prop from TextInputProps
was clashing with the size
prop defined above
}: TextInputWithTokensInternalProps<TokenComponentType> & { | ||
selectedTokenIndex: number | undefined | ||
setSelectedTokenIndex: React.Dispatch<React.SetStateAction<number | undefined>> | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think selectedTokenIndex
and setSelectedTokenIndex
are props that we use in this component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I'm not sure how these types made it here 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing all of these. Code looks good, and everything in the preview deployment looks good
@@ -311,7 +311,7 @@ export const NestedOverlays = () => { | |||
Create a list to organize your starred repositories. | |||
</Text> | |||
<TextInput placeholder="Name this list" sx={{mb: 2}} /> | |||
<TextInput as="textarea" placeholder="Write a description" rows="3" sx={{mb: 2, textarea: {p: 2}}} /> | |||
<TextInput as="textarea" placeholder="Write a description" rows={3} sx={{mb: 2, textarea: {p: 2}}} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we just change this to a Textarea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but until we deprecate the as
prop for TextInput I think consumers will still do this. If people do this in their apps, I like that we are type-checking this use-case in our codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok. Let's keep it as-is then.
* Add failing TextInput type test * Create loud-schools-own.md * Update TextInput types * Add another TextInput type test * Update TextInput props type * Update TextInputWithTokens types * Fix incorrect uses of TextInputWithTokens * Update SelectMenu types test * Fix TextInput tests * Update snapshot tests * autocomplete -> autoComplete * Remove theme prop SelectMenuFilter * Fix TextInput in Overlay story * Fix TextInputWithTokens stories
Problem
The type for
TextInput
props was resolving toany
, causing a bad developer experience for consumers.After doing some digging, I found that the issue was caused by this line:
Passing a styled component type to
React.ComponentPropsWithoutRef
yields anany
type.Solution
I fixed the type issue by rewriting the
TextInputProps
to avoid usingReact.ComponentPropsWithoutRef
with a styled component.Fixing the
TextInput
type revealed 50+ type errors in our codebase 😅 I fixed those errors in this PR as well.Closes #1948