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

[WEB-4025] Assert presence of units in Icon size prop values #527

Merged
merged 1 commit into from
Nov 1, 2024

Conversation

jamiehenson
Copy link
Member

@jamiehenson jamiehenson commented Oct 30, 2024

Jira Ticket Link / Motivation

Follows on from this, which fixes the most obvious Icon problems in Firefox by making sure proper units are provided with values given to size on Icon.

This PR adds some safeguards in to assert this in future, by adding a type to size on Icon, as well as fixing a subsequent, smaller issue with EncapsulatedIcon relating to this.

Example: <Icon size={16} /> will not work, but <Icon size='16px' /> will.

Summary of changes

How do you manually test this?

Reviewer Tasks (optional)

Merge/Deploy Checklist

  • Written automated tests for implemented features/fixed bugs
  • Rebased and squashed commits
  • Commits have clear descriptions of their changes
  • Checked for any performance regressions

Frontend Checklist

  • No frontend changes in this PR
  • Added before/after screenshots for changes
  • Tested on different platforms/browsers with Browserstack
  • Compared with the initial design / our brand guidelines
  • Checked the code for accessibility issues (VoiceOver User Guide)?

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a new IconSize type for more flexible icon size definitions.
    • Enhanced the EncapsulatedIcon component to improve icon size handling and type safety.
  • Bug Fixes

    • Updated the size property in the Icon component for better type alignment.
  • Documentation

    • Clarified type definitions for icon properties to ensure consistency and usability.

Copy link
Contributor

coderabbitai bot commented Oct 30, 2024

Walkthrough

The changes involve modifications to the Icon component and its related types in the src/core directory. The IconProps and EncapsulatedIconProps types have been updated to use a new IconSize type instead of a string for the size and iconSize properties, enhancing type safety. The IconSize type supports various size formats, including pixel and rem units. Additionally, the logic for computing icon sizes in the EncapsulatedIcon component has been revised to improve handling of size values.

Changes

File Change Summary
src/core/Icon.tsx Updated IconProps type: changed size?: string to size?: IconSize; modified import to include IconSize.
src/core/Icon/EncapsulatedIcon.tsx Updated EncapsulatedIconProps type: changed iconSize?: string to iconSize?: IconSize; revised size computation logic.
src/core/Icon/types.ts Introduced new type IconSize to support flexible size definitions (px, em, rem, calc).

Assessment against linked issues

Objective Addressed Explanation
Update icon size handling (WEB-4025)
Improve type safety for icon properties (WEB-4025)

Possibly related PRs

  • [WEB-3979] Additional modification props for Encapsulated icons #488: This PR modifies the EncapsulatedIcon component in src/core/Icon/EncapsulatedIcon.tsx, updating the iconSize property to use the IconSize type, which is directly related to the changes made in the main PR regarding the IconProps type in Icon.tsx.
  • [WEB-4025] Autogenerate icon manifests #512: This PR introduces a feature to automate the generation of icon manifests, which involves changes to the Icon/types.ts file. The main PR also modifies this file by introducing the IconSize type, indicating a connection in terms of type definitions.
  • [WEB-4025] Rectify IconName type generation #513: This PR updates the IconName type in src/core/Icon/types.ts, which is relevant to the changes in the main PR that also involve modifications to types in the same file.
  • [WEB-4025] 14.7.6 - fix: explicitly set Icon size units #525: This PR explicitly sets icon size units in various components, including changes to the Icon component's size properties. This is directly related to the main PR's focus on enhancing type safety for the size property in IconProps.

Suggested labels

review

Suggested reviewers

  • aralovelace

Poem

🐇 In the garden where icons play,
Sizes now have a structured way.
From strings to types, we’ve made the leap,
Ensuring our icons are safe to keep.
With rems and pixels, they dance and twirl,
A safer world for every icon swirl! 🌼


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3df125b and e2bcb3f.

📒 Files selected for processing (3)
  • src/core/Icon.tsx (1 hunks)
  • src/core/Icon/EncapsulatedIcon.tsx (2 hunks)
  • src/core/Icon/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/core/Icon.tsx
  • src/core/Icon/EncapsulatedIcon.tsx
  • src/core/Icon/types.ts

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
src/core/Icon/types.ts (1)

20-24: Consider enhancing type documentation and coverage.

While the current implementation covers the most common units, consider:

  1. Adding JSDoc comments explaining the purpose and usage of this type
  2. Including additional valid CSS units like vh, vw, and % if they might be useful in your context
+/**
+ * Represents valid size values for Icon components.
+ * Enforces the presence of units to prevent browser compatibility issues.
+ * @example
+ * - "16px"
+ * - "1.5rem"
+ * - "calc(100% - 20px)"
+ */
 export type IconSize =
   | `${number}px`
   | `${number}em`
   | `${number}rem`
+  | `${number}vh`
+  | `${number}vw`
+  | `${number}%`
   | `calc(${string})`;
src/core/Icon.tsx (1)

Line range hint 1-38: Consider adding runtime validation for size values.

Given the history of browser compatibility issues with icon sizes (ref: PR #525), consider adding runtime validation to ensure size values always include valid units. This could prevent similar issues in the future, especially for non-TypeScript consumers.

Suggestions:

  1. Add a runtime validator function for size values
  2. Add JSDoc comments documenting supported units and browser compatibility notes
  3. Consider adding a set of predefined size constants to encourage consistent usage

Would you like me to provide an example implementation of these suggestions?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d0f0d47 and 3df125b.

📒 Files selected for processing (3)
  • src/core/Icon.tsx (1 hunks)
  • src/core/Icon/EncapsulatedIcon.tsx (2 hunks)
  • src/core/Icon/types.ts (1 hunks)
🔇 Additional comments (7)
src/core/Icon/types.ts (1)

20-24: LGTM! The IconSize type effectively enforces proper units.

The type implementation using template literals ensures that size values always include units, preventing the Firefox-related issues mentioned in the PR objectives.

src/core/Icon.tsx (3)

3-3: LGTM: Import statement updated correctly.

The addition of IconSize import aligns with the PR objective of adding type safety to icon size values.


Line range hint 16-16: Verify type compatibility of default size value.

Please ensure that the default value "0.75rem" matches the IconSize type definition. Consider adding a type assertion or constant to make this relationship explicit.

Let's check the IconSize type definition:

✅ Verification successful

Default size value "0.75rem" is compatible with IconSize type

The type definition in src/core/Icon/types.ts shows that IconSize accepts string values in the format ${number}rem, making "0.75rem" a valid value. The implementation correctly uses this typed value directly in the style object for width and height properties.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for IconSize type definition
ast-grep --pattern 'type IconSize = $_'

Length of output: 81


Script:

#!/bin/bash
# Let's try different approaches to find IconSize type definition
# Search for type definition in the same file
rg -A 5 "type IconSize" src/core/Icon.tsx

# Search for exported type definition
rg -A 5 "export.*type IconSize"

# Search for any usage of IconSize
rg "IconSize"

# Look at the entire Icon.tsx file to understand the context
cat src/core/Icon.tsx

Length of output: 1925


9-9: Verify impact of type change on existing consumers.

The type change from string to IconSize improves type safety but could potentially break existing implementations.

Let's check for any existing string literals being passed to the size prop:

✅ Verification successful

Type change from string to IconSize is safe for existing consumers

The change from string to IconSize type is non-breaking as:

  1. The IconSize type allows all current usage patterns found in the codebase (px, em, rem, calc values)
  2. All existing usages in the codebase follow the correct format:
    • "32px", "1rem", "1.5rem", "2.5rem", "3rem" etc.
  3. The new type actually matches the existing usage patterns, providing better type safety without breaking changes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Icon component usage with string literals in size prop
ast-grep --pattern 'Icon $$$size="$_"'

# Search for Icon component usage with numeric literals in size prop
ast-grep --pattern 'Icon $$$size={$_}'

Length of output: 81


Script:

#!/bin/bash
# Let's try a more comprehensive search for Icon usage patterns
# Search for any Icon component usage with size prop
rg -U "Icon.*size.*" -A 2

# Also search for potential imports of Icon to ensure we're looking at the right component
rg "import.*Icon" 

# And let's check the IconSize type definition to understand valid values
fd -e ts -e tsx | xargs rg "type IconSize|enum IconSize"

Length of output: 14071


Script:

#!/bin/bash
# Let's check the IconSize type definition content
cat src/core/Icon/types.ts

# Also search for any numeric values being passed to size prop
rg -U "size=\{[0-9]+" -A 1

Length of output: 673

src/core/Icon/EncapsulatedIcon.tsx (3)

5-5: LGTM: Type safety improvements

The change from string to IconSize type enhances type safety by ensuring proper unit inclusion in size values, which aligns with the PR objective to prevent browser compatibility issues.

Also applies to: 11-11


40-40: LGTM: Clean implementation of size values

The size values are correctly applied to create the visual hierarchy:

  • Outer div maintains original size
  • Inner div uses computed height
  • Icon uses computed size

Also applies to: 44-44, 46-46


Line range hint 1-52: Verify EncapsulatedIcon usage patterns

Let's ensure all usages of EncapsulatedIcon are compatible with the new size computation logic.

✅ Verification successful

Based on the search results, I can see that EncapsulatedIcon is used in ProductTile.tsx and Icon.stories.tsx, and none of these usages explicitly set the size prop, meaning they rely on the default value of "40px". The new size computation logic in EncapsulatedIcon maintains backward compatibility by:

  1. Using a default size of "40px"
  2. Properly handling pixel values with the -12px and -2px adjustments
  3. Supporting the new iconSize prop as an optional parameter

No compatibility issues found with EncapsulatedIcon usage patterns

The changes to size computation are safe as they maintain backward compatibility with existing usage patterns. All current implementations will continue to work as expected with the default size value.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for EncapsulatedIcon usage patterns
echo "Checking EncapsulatedIcon usage patterns..."
rg "EncapsulatedIcon" -A 3 -B 1

# Look for potential size prop values
echo "Checking size prop values..."
ast-grep --pattern '<EncapsulatedIcon $$$size={$_}$$$>'

Length of output: 4142

src/core/Icon/EncapsulatedIcon.tsx Outdated Show resolved Hide resolved
@jamiehenson jamiehenson force-pushed the assert-icon-size-units branch from 9967684 to 723446c Compare October 30, 2024 14:29
Copy link
Member

@kennethkalmer kennethkalmer left a comment

Choose a reason for hiding this comment

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

LGTM 🔐

@@ -16,3 +16,9 @@ export type IconName =
| (typeof iconNames.other)[number]
| (typeof iconNames.tech)[number]
| (typeof iconNames.product)[number];

export type IconSize =
Copy link
Member

Choose a reason for hiding this comment

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

TIL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants