Skip to content

fix: Revert #1244 to address regression w/ Button and DropdownItem #1298

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

Conversation

rnicholus
Copy link
Contributor

@rnicholus rnicholus commented Mar 14, 2024

In #1244, the return type of Button and DropdownItem was changed to ReactNode. This is not an acceptable return type for functional components. The correct return type is JSX.Element. This change fixes the regression from that PR (introduced in v0.7.3) by reverting that PR and accounting for related changes that followed that PR. Also fixes #962.

Perhaps there is a way to fulfill the goals of #1244 and solve this regression, but I wasn't able to find time to address that, and #1244 seems flawed enough that perhaps it just needs to be redesigned.

Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copy link

vercel bot commented Mar 14, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
flowbite-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 19, 2024 1:44pm

Copy link

codecov bot commented Mar 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.54%. Comparing base (7461173) to head (9447658).
Report is 203 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1298      +/-   ##
==========================================
- Coverage   99.54%   95.54%   -4.01%     
==========================================
  Files         163      218      +55     
  Lines        6621     9691    +3070     
  Branches      401      560     +159     
==========================================
+ Hits         6591     9259    +2668     
- Misses         30      432     +402     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rluders
Copy link
Collaborator

rluders commented Mar 15, 2024

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Mar 15, 2024

Walkthrough

This update focuses on improving type inference and component refactoring within a React project. It addresses as inference issues in Button and DropdownItem components when used with Link components, by adding temporary @ts-expect-error comments alongside TODO notes for future fixes. Additionally, it introduces a genericForwardRef function to better handle refs with generic components, and refactors Button components to utilize this new approach, enhancing code maintainability and readability.

Changes

Files Changes
.../homepage/...
examples/button/...
examples/dropdown/dropdown.customItem.tsx
Added @ts-expect-error with TODO notes for as inference issues.
src/components/Button/... Refactored Button components, updated types, and utilized genericForwardRef.
src/components/Dropdown/... Fixed a typo, added RefCallback import, and refactored DropdownItem component.
src/helpers/generic-forward-ref.ts Introduced genericForwardRef function.

🐇💻✨
In the land of code, where components intertwine,
A rabbit hopped, fixing types, making them align.
With a flick of its tail, errors began to fade,
Refs and props, in harmony, beautifully made.
🌟🚀🐾
"To the future," it whispered, under the moon's glow,
Where code runs smooth, and development can flow.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

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>.
    • Generate unit-tests 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 tests 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 31c9d9d and d129ac5.
Files selected for processing (11)
  • components/homepage/components-section.tsx (1 hunks)
  • components/homepage/hero-section/hero-section.tsx (1 hunks)
  • components/homepage/react-section.tsx (1 hunks)
  • examples/button/button.polymorph.tsx (1 hunks)
  • examples/dropdown/dropdown.customItem.tsx (1 hunks)
  • src/components/Button/Button.tsx (3 hunks)
  • src/components/Button/ButtonBase.tsx (1 hunks)
  • src/components/Dropdown/Dropdown.spec.tsx (1 hunks)
  • src/components/Dropdown/Dropdown.tsx (2 hunks)
  • src/components/Dropdown/DropdownItem.tsx (1 hunks)
  • src/helpers/generic-forward-ref.ts (1 hunks)
Additional comments: 12
src/helpers/generic-forward-ref.ts (2)
  • 6-9: The use of @typescript-eslint/ban-types and {} in the type definition of FixedForwardRef is necessary for the functionality but could benefit from a comment explaining why this approach was chosen and the implications it might have on type safety.
  • 11-11: The implementation of genericForwardRef as a type-casted version of forwardRef is a clever solution to enable generic component forwarding. This change looks good and should facilitate the refactoring of components like Button and DropdownItem.
src/components/Button/ButtonBase.tsx (1)
  • 9-15: The refactoring of ButtonBase into ButtonBaseComponent and its export using genericForwardRef is a significant improvement in terms of type safety and component flexibility. Ensure that the use of generics and props spreading is thoroughly tested to prevent any potential issues with type inference.
Verification successful

Given the lack of output from the ast-grep command, it's necessary to explore alternative methods to verify the usage of ButtonBaseComponent and its type safety. I will now use ripgrep (rg) to search for textual occurrences of ButtonBaseComponent in the codebase to ensure a more comprehensive search.


The search results indicate that ButtonBaseComponent is defined and exported within src/components/Button/ButtonBase.tsx, with no direct evidence of its usage with various as props across the codebase. This limits our ability to verify the type safety and flexibility of ButtonBaseComponent in different usage scenarios directly. However, the importance of thorough testing, as mentioned in the initial review comment, to ensure type safety and flexibility, especially when using generics and props spreading, remains critical. It's advisable to conduct comprehensive testing, particularly in scenarios where ButtonBaseComponent might be used with different as props in the future.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify the usage of ButtonBaseComponent with various `as` props and ensure type safety.
ast-grep --lang typescript --pattern $'ButtonBaseComponent<$$_>({ as: $$_, ... })'

Length of output: 83



Script:

#!/bin/bash
# Search for textual occurrences of ButtonBaseComponent to verify its usage.
rg "ButtonBaseComponent"

Length of output: 228

src/components/Dropdown/DropdownItem.tsx (2)
  • 17-24: The simplification of the DropdownItemProps interface is a positive change that enhances readability and maintainability. However, ensure that this simplification does not limit the component's flexibility or its ability to be used in various contexts.
  • 26-59: The refactoring of the DropdownItem component, including the use of context hooks and theme customization, is well-implemented. It's important to perform performance testing, especially for the deep merging of themes, to ensure that there are no significant impacts on rendering times.
src/components/Button/Button.tsx (4)
  • 1-4: The imports have been updated to include ComponentPropsWithoutRef, ElementType, ForwardedRef from 'react', and genericForwardRef from '../../helpers/generic-forward-ref'. Ensure that these changes align with the new implementation requirements and that there are no unused imports.
  • 70-87: The ButtonProps type has been refactored to include ComponentPropsWithoutRef<T>. This change enhances the type safety and flexibility of the Button component by allowing it to accept all props valid for the element type specified by as prop, excluding ref. Ensure that all usages of ButtonProps throughout the codebase are updated to reflect this change.
  • 89-163: The ButtonComponentFn function has been updated to use a generic type parameter and ForwardedRef<T>. This change improves the component's ability to forward refs correctly and supports generic type usage. Additionally, the function now directly returns the ButtonBase component wrapped in JSX, which simplifies the component structure. Ensure that the ref forwarding functionality is tested, especially in scenarios where the Button component is used with different as props.
  • 167-169: The addition of genericForwardRef and the creation of ButtonComponent using it is a significant improvement. This approach allows for forwarding refs in a type-safe manner for generic components. Verify that genericForwardRef is implemented correctly and that it handles all edge cases, such as when the ref is not provided or when the component is used with different element types.
src/components/Dropdown/Dropdown.spec.tsx (1)
  • 170-170: The typo in the test description has been corrected from "Dropdownn.Item" to "Dropdown.Item". This change improves the readability and accuracy of the test descriptions. Ensure that similar typos are corrected throughout the test suite to maintain consistency and clarity.
src/components/Dropdown/Dropdown.tsx (2)
  • 13-13: The import of RefCallback from 'react' has been added. This type is used to specify a callback function that receives a DOM element or a component instance as its argument. Ensure that this import is used correctly in the context of ref forwarding within the Dropdown component.
  • 101-107: The ref prop in the Button component within the Dropdown component has been updated to use refs.setReference as RefCallback<'button'>. This change ensures that the ref is correctly typed and forwarded, improving the component's interoperability and type safety. Verify that this change does not introduce any regressions in the behavior of the Dropdown component, especially in scenarios where the Button component is used with different element types or in complex layouts.

@rnicholus
Copy link
Contributor Author

Uh, whatever AI you’ve unleashed on this PR is pretty low-quality. All I’ve done here is ‘git revert’ 1 set of changes and partially revert another.

@SutuSebastian
Copy link
Collaborator

Uh, whatever AI you’ve unleashed on this PR is pretty low-quality. All I’ve done here is ‘git revert’ 1 set of changes and partially revert another.

Yep, I know that, but seems like the AI does not

@rluders
Copy link
Collaborator

rluders commented Mar 15, 2024

@rnicholus AI is just an tool, we still reviewing as humans. 😁

@rnicholus
Copy link
Contributor Author

Is there anything else i can do to ensure this change is merged & released?

@@ -25,6 +25,7 @@ export const ComponentsSection: FC = () => {
))}
</div>
<div className="mb-4 flex w-full justify-center text-center">
{/* @ts-expect-error TODO: fix `as` inference */}
Copy link
Collaborator

Choose a reason for hiding this comment

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

As you are fixing #962, is it necessary to have these @ts-expect-error comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is needed since the fix is reverting #1244.

@rluders
Copy link
Collaborator

rluders commented Mar 19, 2024

@rnicholus please, no merge with main... rebase it instead!

@rnicholus
Copy link
Contributor Author

@rnicholus please, no merge with main... rebase it instead!

this can all be squashed on merge, correct?

@rluders
Copy link
Collaborator

rluders commented Mar 19, 2024

@rnicholus yes, but it is preferable to rebase with the main instead of merging it. But, anyway...

I'm wondering if this PR is actually fixing the issue, and not just reverting for some broken state. Isn't better if we could address the problem with a definitive fix? What would be the pros and cons of accepting this to fix #962 and reverting the fix for #1002 and #1107?

@rnicholus
Copy link
Contributor Author

@rnicholus yes, but it is preferable to rebase with the main instead of merging it. But, anyway...

I'm wondering if this PR is actually fixing the issue, and not just reverting for some broken state. Isn't better if we could address the problem with a definitive fix? What would be the pros and cons of accepting this to fix #962 and reverting the fix for #1002 and #1107?

I'm not sure. My motivation here was to fix the typing issue without having to resort to ts-ignore in my project, and i suspect a bunch of other users are in the same boat.

Isn't better if we could address the problem with a definitive fix?

absolutely, but i'm not sure what that fix is as i don't really have the cycles to investigate

@SutuSebastian
Copy link
Collaborator

Closed in favor of #1308

@rnicholus rnicholus deleted the fix/button-and-dropdown-typescript-regression branch March 27, 2024 21:29
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.

Button can't be rendered as it's return type is ReactNode.
4 participants