-
Notifications
You must be signed in to change notification settings - Fork 17
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
Converts Icon to TypeScript #2225
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2225 +/- ##
=====================================
Coverage 97.95 97.95
=====================================
Files 698 698
Lines 7939 7948 +9
Branches 1890 1893 +3
=====================================
+ Hits 7776 7785 +9
Misses 161 161
Partials 2 2
Continue to review full report in Codecov by Sentry.
|
Codecov Report
@@ Coverage Diff @@
## main #2225 +/- ##
=======================================
Coverage 97.94% 97.94%
=======================================
Files 698 698
Lines 7939 7948 +9
Branches 1890 1893 +3
=======================================
+ Hits 7776 7785 +9
Misses 161 161
Partials 2 2 Continue to review full report in Codecov by Sentry.
|
✅ Deploy Preview for gazebo-staging ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
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.
Quick change to have the types be narrowed to the given variant so we will get errors if we're trying to access a icon that does not belong to the given variant.
src/ui/Icon/Icon.tsx
Outdated
interface IconProps { | ||
name: Name | ||
variant?: Variant | ||
size?: 'sm' | 'md' | 'lg' | 'flex' | ||
label?: string | ||
} | ||
|
||
function Icon({ | ||
name, | ||
variant = 'outline', | ||
size = 'md', | ||
label = '', | ||
}: IconProps) { | ||
const IconSvg = get(iconComponentCollection, variant, name) | ||
if (!IconSvg || !isValidKey(iconClasses, size)) return null | ||
|
||
return ( | ||
<IconSvg | ||
data-testid={label} | ||
data-icon={label} | ||
className={iconClasses[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.
Just to take this to the next TypeScript level and make sure we don't introduce any errors because the variants don't have all of the same values for name, can you switch the props to the following so when you set the variant to developer
you'll only see the names that are possible for it:
interface CommonProps {
size?: 'sm' | 'md' | 'lg' | 'flex'
label?: string
}
type DeveloperIconProps = {
name: keyof DeveloperIconCollection
variant?: 'developer'
}
type OutlineIconProps = {
name: keyof OutlineIconCollection
variant?: 'outline'
}
type SolidIconProps = {
name: keyof SolidIconCollection
variant?: 'solid'
}
type IconProps = (DeveloperIconProps | OutlineIconProps | SolidIconProps) &
CommonProps
function Icon({
name,
variant = 'outline',
size = 'md',
label = '',
}: IconProps) {
const IconSvg = get(iconComponentCollection, variant, name)
if (!IconSvg || !isValidKey(iconClasses, size)) return null
return (
<IconSvg
data-testid={label}
data-icon={label}
className={iconClasses[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.
I wasn't able to get the type narrowing working correctly with type IconProps = (DeveloperIconProps | OutlineIconProps | SolidIconProps) & CommonProps
but moving the intersection CommonProps up to each IconProps and unioning them seemed to have done the trick.
type OutlineIconProps = {
name: keyof OutlineIconCollection
variant: 'outline'
} & CommonProps
If anyone can why explain why this makes the difference to me that would be great. I would have assumed both ways were equivalent.
…ion in an icon collection.
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.
Quick change is needed to fix the build.
src/ui/Icon/Icon.tsx
Outdated
type OutlineIconProps = { | ||
name: keyof OutlineIconCollection | ||
variant: 'outline' | ||
} & CommonProps | ||
|
||
type SolidIconProps = { | ||
name: keyof SolidIconCollection | ||
variant: 'solid' | ||
} & CommonProps | ||
|
||
type DeveloperIconProps = { | ||
name: keyof DeveloperIconCollection | ||
variant: 'developer' | ||
} & CommonProps |
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 will need to set variant
here as optional with ?:
or you'll get build errors wherever a variant isn't passed in. Unless you want to force a variant to be passed.
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.
Whoops my bad, on it.
…iling tsx post updating against main.
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.
LGTM
Description
A fully typed Icon component. Kicking off the TS rust!
Code Example
Notable Changes
Screenshots
Legal Boilerplate
Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.