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

fix(dropdown): respect closeOnSelect prop on DropdownItem(#2290) #2598

Open
wants to merge 8 commits into
base: canary
Choose a base branch
from

Conversation

gtoxlili
Copy link

@gtoxlili gtoxlili commented Mar 27, 2024

Closes #2290

📝 Description

This PR fixes an issue where the closeOnSelect prop on DropdownItem was being overridden by the DropdownMenu settings, causing the dropdown to close even when closeOnSelect was set to false on an individual DropdownItem.

⛳️ Current behavior (updates)

Currently, setting closeOnSelect to false on a DropdownItem does not prevent the dropdown from closing when that item is selected. This is because the onAction event handler on DropdownItem is deprecated and the closing behavior is controlled by the DropdownMenu settings.

🚀 New behavior

The logic has been updated to respect the closeOnSelect prop on DropdownItem. Now, if closeOnSelect is set to false on a DropdownItem, selecting that item will not close the dropdown menu.

The relevant changes are:

+ const onAction = (key: Key) => {
+   if (closeOnSelect) {
+     onTopAction?.(key);
+   }
+ };

💣 Is this a breaking change (Yes/No):

No

📝 Additional Information

N/A

Summary by CodeRabbit

  • Refactor
    • Enhanced key action handling in the menu component.
    • Improved function names for clarity and added a new function for better menu item selection.

Copy link

changeset-bot bot commented Mar 27, 2024

🦋 Changeset detected

Latest commit: 4b39f0b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@nextui-org/menu Patch
@nextui-org/dropdown Patch
@nextui-org/react Patch

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

Copy link

vercel bot commented Mar 27, 2024

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

Name Status Preview Comments Updated (UTC)
nextui-storybook-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 8, 2024 7:09am

Copy link
Contributor

coderabbitai bot commented Mar 27, 2024

Walkthrough

The update to menu.tsx enhances the handling of item selection in dropdown menus, particularly addressing an issue where the dropdown would close unexpectedly despite the closeOnSelect property being set to false. By refining the import statements and modifying the onAction functions, the changes aim to ensure that dropdown behavior aligns more closely with user expectations and configuration.

Changes

File Change Summary
packages/components/menu/src/menu.tsx - Added Key type import from React
- Renamed onAction to onTopAction
- Added new onAction for key actions

Assessment against linked issues

Objective Addressed Explanation
Dropdown closes on item selection despite closeOnSelect being false (#2290)

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

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

vercel bot commented Mar 27, 2024

@gtoxlili is attempting to deploy a commit to the NextUI Inc Team on Vercel.

A member of the Team first needs to authorize it.

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: 0

Configuration used: .coderabbit.yaml

Commits Files that changed from the base of the PR and between cf0d4e4 and 8e21dc2.
Files selected for processing (1)
  • packages/components/menu/src/menu.tsx (3 hunks)
Additional comments: 3
packages/components/menu/src/menu.tsx (3)
  • 2-2: The import statement has been updated to include the Key type from React, which is utilized in the newly added onAction function. This change is necessary for the implementation and ensures that the Key type is available for use within the file.
  • 21-21: The onAction function has been renamed to onTopAction. This renaming is part of the changes to ensure that the closeOnSelect property functions as expected. It's important to verify that all references to the old onAction function within this file and potentially in other parts of the codebase have been updated to reflect this change.
Verification successful

The search results indicate that references to onAction are still present throughout the project, not only within the menu component but also in other components like listbox, dropdown, breadcrumbs, and their respective stories, tests, and documentation. This suggests that the renaming of onAction to onTopAction was specific to the menu.tsx file and does not imply that all occurrences of onAction across the project should have been renamed. The presence of onAction in other components and contexts appears to be intentional and unrelated to the change made in menu.tsx.

Given this context, the review comment about verifying that all references to the old onAction function within this file and potentially in other parts of the codebase have been updated to reflect this change is partially correct. It is accurate in the sense that within menu.tsx, the renaming to onTopAction should be consistent. However, the comment may imply a broader scope of renaming across the project, which is not supported by the evidence from the search results. The references to onAction in other components and documentation are valid and expected to remain unchanged.

Therefore, the verification process concludes that the review comment is correct regarding the need to ensure consistency within the menu.tsx file but may be misleading if interpreted as applying to the entire codebase. The renaming to onTopAction seems to be a specific change within the menu component to address a particular issue, and the presence of onAction in other parts of the codebase does not contradict this change.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for any remaining references to the old `onAction` function name within the project.
rg --type tsx 'onAction' 

Length of output: 52



Script:

#!/bin/bash
# Search for any remaining references to the old `onAction` function name within the project, without specifying file type.
rg 'onAction'

Length of output: 7457

* 30-34: The addition of the new `onAction` function is a key part of the fix for the `closeOnSelect` issue. This function checks the `closeOnSelect` property's value and conditionally triggers `onTopAction` if `closeOnSelect` is true. This implementation allows individual `DropdownItem`s to override the default closing behavior of the dropdown menu. It's crucial to ensure that this new logic does not introduce any side effects, especially in scenarios where `closeOnSelect` might be dynamically changed or in complex dropdown structures.

Copy link
Member

@wingkwong wingkwong left a comment

Choose a reason for hiding this comment

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

  1. please add a changeset
  2. please provide before & after videos to demonstrate if possible

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: 1

Configuration used: .coderabbit.yaml

Commits Files that changed from the base of the PR and between 8e21dc2 and e65e9fa.
Files selected for processing (1)
  • .changeset/warm-planets-smile.md (1 hunks)

.changeset/warm-planets-smile.md Show resolved Hide resolved
@gtoxlili
Copy link
Author

  1. please add a changeset
  2. please provide before & after videos to demonstrate if possible

Thanks for the reminder, I've added the changeset.

@KoJem9Ka
Copy link

Really waiting for this fix in the release)

Copy link
Member

@wingkwong wingkwong left a comment

Choose a reason for hiding this comment

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

Just tested with the same code from the issue, the menu is still closed after clicking New file. Also please add tests to cover this case.

<Dropdown>
  <DropdownTrigger>
    <Button variant="bordered">Open Menu</Button>
  </DropdownTrigger>
  <DropdownMenu aria-label="Static Actions">
    <DropdownItem key="new" closeOnSelect={false}>
      New file
    </DropdownItem>
    <DropdownItem key="copy">Copy link</DropdownItem>
    <DropdownItem key="edit">Edit file</DropdownItem>
    <DropdownItem key="delete" className="text-danger" color="danger">
      Delete file
    </DropdownItem>
  </DropdownMenu>
</Dropdown>

@gtoxlili
Copy link
Author

Currently, if a DropdownItem has closeOnSelect explicitly set to false, the menu will remain open when that item is selected. Otherwise, it follows the DropdownMenu's closeOnSelect setting.

I have added the relevant templates. Please test the changes based on the provided templates.

@wingkwong

@wingkwong
Copy link
Member

@gtoxlili apart from storybook, I was asking for tests to be added in /packages/components/dropdown/__tests__/dropdown.test.tsx

@gtoxlili
Copy link
Author

@gtoxlili apart from storybook, I was asking for tests to be added in /packages/components/dropdown/__tests__/dropdown.test.tsx

Added

Copy link
Member

@wingkwong wingkwong left a comment

Choose a reason for hiding this comment

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

Tests are not passing. Please check.

@gtoxlili
Copy link
Author

gtoxlili commented May 3, 2024

Tests are not passing. Please check.

It passes on my local machine, can you show me your test cases?

@wingkwong
Copy link
Member

@gtoxlili just look at the QA / Tests (pull_request). Already tried rerunning few times. I think your branch is out of sync. Please sync once with canary and re-run the tests.

image

@gtoxlili
Copy link
Author

gtoxlili commented May 6, 2024

@gtoxlili just look at the QA / Tests (pull_request). Already tried rerunning few times. I think your branch is out of sync. Please sync once with canary and re-run the tests.

image

I have already merged the canary branch into my fix branch and re-executed all the tests for the dropdown. These are the results on my local machine, and I still haven't found any errors. I don't have any clue how to solve this problem. If possible, perhaps you could provide me with some more detailed information?

CleanShot 2024-05-06 at 18 34 49@2x

@gtoxlili
Copy link
Author

gtoxlili commented May 8, 2024

The previous changes I proposed indeed had some issues. I have fixed them, uploaded the updated version, and conducted further testing. @wingkwong

@gtoxlili
Copy link
Author

gtoxlili commented May 8, 2024

The main reason for the issue is that the component's previous design coupled the onAction and closeOnSelect behaviors.

const getMenuProps = <T>(
  props?: Partial<MenuProps<T>>,
  _ref: Ref<any> | null | undefined = null,
) => {
  return {
    ref: mergeRefs(_ref, menuRef),
    menuProps,
    closeOnSelect,
    ...mergeProps(props, {
      onAction: () => onMenuAction(props?.closeOnSelect),
      onClose: state.close,
    }),
  } as MenuProps;
};

In the previous design, the user-provided onAction was merged with the close event based on DropdownMenu's closeOnSelect using mergeProps. The merged onAction was then passed to the item. When the event was triggered, the item directly executed the onAction method passed from the menu. (This is also the reason why the closeOnSelect of the item component was ineffective.)

My previous modification did not consider the possibility of the user passing their own onAction. So, I chose to directly skip executing the onAction passed from DropdownMenu if the item had closeOnSelect. (I assumed mergeProps was an override-like setting, but it turned out to execute all events with the same name in sequence.)

Now, I have changed the close event to:

onAction: (key: any) => {
  // @ts-ignore
  const item = props?.children?.find((item) => item.key === key);

  if (item?.props?.closeOnSelect === false) {
    onMenuAction(false);

    return;
  }
  onMenuAction(props?.closeOnSelect);
}

Since the item passes its key when triggering onAction, I try to find whether it has closeOnSelect based on the key. I think this logic should be correct now (although the logic is still messy, mainly because this coupled design is not a good design).

@wingkwong wingkwong self-assigned this May 8, 2024
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.

Dropdown Unexpectedly Closes on Item Selection Despite closeOnSelect Being Set to False
3 participants