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

Converts Icon to TypeScript #2225

Merged
merged 6 commits into from
Sep 11, 2023
Merged

Converts Icon to TypeScript #2225

merged 6 commits into from
Sep 11, 2023

Conversation

terry-codecov
Copy link
Contributor

@terry-codecov terry-codecov commented Aug 29, 2023

Description

A fully typed Icon component. Kicking off the TS rust!

Code Example

<Icon name="search" />

Notable Changes

  • To make use of type inference/auto complete I'm dropping support for camel case variations on the name prop.
  • I updated TSX components using Icon to be camel case. Once we're fully over to TypeScript we can remove the camelCase function from Icon.
  • Added data-icon for use with the new Table component. Not used in this pr.
  • Fixed the svg module to correctly type .svg files, they're named exports not default exports.

Screenshots

Screenshot 2023-08-29 at 6 50 35 PM
Screenshot 2023-08-29 at 6 51 08 PM
Screenshot 2023-08-29 at 6 51 30 PM
Screenshot 2023-08-29 at 6 52 14 PM

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.

@codecov
Copy link

codecov bot commented Aug 29, 2023

Codecov Report

Merging #2225 (547a7fa) into main (0af295f) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@          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           
Files Changed Coverage Δ
src/layouts/LoginLayout/LoginLayout.tsx 100.00% <ø> (ø)
...tOrgSelector/GitHubHelpBanner/GitHubHelpBanner.jsx 100.00% <ø> (ø)
...elPlanPage/subRoutes/SpecialOffer/SpecialOffer.jsx 100.00% <ø> (ø)
...dePlanPage/UpgradeForm/TotalBanner/TotalBanner.tsx 100.00% <ø> (ø)
...red/GlobalTopBanners/TrialBanner/ExpiredBanner.tsx 100.00% <ø> (ø)
src/shared/ListRepo/ReposTable/InactiveRepo.jsx 100.00% <ø> (ø)
src/ui/Icon/Icon.tsx 100.00% <100.00%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0af295f...547a7fa. Read the comment docs.

@codecov-staging
Copy link

codecov-staging bot commented Aug 29, 2023

Codecov Report

Merging #2225 (547a7fa) into main (0af295f) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           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           
Files Changed Coverage
src/layouts/LoginLayout/LoginLayout.tsx ø
...tOrgSelector/GitHubHelpBanner/GitHubHelpBanner.jsx ø
...elPlanPage/subRoutes/SpecialOffer/SpecialOffer.jsx ø
...dePlanPage/UpgradeForm/TotalBanner/TotalBanner.tsx ø
...red/GlobalTopBanners/TrialBanner/ExpiredBanner.tsx ø
src/shared/ListRepo/ReposTable/InactiveRepo.jsx ø
src/ui/Icon/Icon.tsx 100.00%

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0af295f...547a7fa. Read the comment docs.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for gazebo-staging ready!

Name Link
🔨 Latest commit 547a7fa
🔍 Latest deploy log https://app.netlify.com/sites/gazebo-staging/deploys/64ff29d1f748e80008ae5a11
😎 Deploy Preview https://deploy-preview-2225--gazebo-staging.netlify.app/
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@nicholas-codecov nicholas-codecov left a 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.

Comment on lines 51 to 74
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]}
/>
)
}
Copy link
Contributor

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]}
    />
  )
}

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 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.

Copy link
Contributor

@nicholas-codecov nicholas-codecov left a 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.

Comment on lines 56 to 69
type OutlineIconProps = {
name: keyof OutlineIconCollection
variant: 'outline'
} & CommonProps

type SolidIconProps = {
name: keyof SolidIconCollection
variant: 'solid'
} & CommonProps

type DeveloperIconProps = {
name: keyof DeveloperIconCollection
variant: 'developer'
} & CommonProps
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@nicholas-codecov nicholas-codecov left a comment

Choose a reason for hiding this comment

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

LGTM :shipit:

@terry-codecov terry-codecov merged commit a404179 into main Sep 11, 2023
15 checks passed
@terry-codecov terry-codecov deleted the convert-icon-to-typescript branch September 11, 2023 14:59
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

2 participants