Skip to content

Commit

Permalink
refactor(menu): Use useMenu and useMenuItem from RA (#3261)
Browse files Browse the repository at this point in the history
* refactor(menu): use useMenu from react-aria instead

* refactor(menu): use useMenuItem from react-aria instead

* feat(changeset): add changeset

* chore: merged with canary

* fix: dropdown tests

---------

Co-authored-by: Junior Garcia <[email protected]>
  • Loading branch information
wingkwong and jrgarciadev authored Nov 4, 2024
1 parent 90cb5b1 commit 2aebfcc
Show file tree
Hide file tree
Showing 7 changed files with 5,683 additions and 5,470 deletions.
5 changes: 5 additions & 0 deletions .changeset/sour-seas-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nextui-org/menu": patch
---

Use `useMenu` and `useMenuItem` from `@react-aria` instead of custom hooks
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "@testing-library/jest-dom";
import * as React from "react";
import {within, render, renderHook, act} from "@testing-library/react";
import userEvent, {UserEvent} from "@testing-library/user-event";
Expand Down
3 changes: 0 additions & 3 deletions packages/components/dropdown/__tests__/dropdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -837,9 +837,6 @@ describe("Dropdown", () => {
let menuItems = wrapper.getAllByRole("menuitem");

await user.click(menuItems[0]);
expect(onOpenChange).toHaveBeenCalledTimes(1);

await user.click(menuItems[1]);
expect(onOpenChange).toHaveBeenCalledTimes(2);
});
});
Expand Down
30 changes: 24 additions & 6 deletions packages/components/menu/src/use-menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
import {useFocusRing} from "@react-aria/focus";
import {TreeState} from "@react-stately/tree";
import {clsx, dataAttr, objectToDeps, removeEvents} from "@nextui-org/shared-utils";
import {useAriaMenuItem} from "@nextui-org/use-aria-menu";
import {useMenuItem as useAriaMenuItem} from "@react-aria/menu";
import {isFocusVisible as AriaIsFocusVisible, useHover} from "@react-aria/interactions";
import {mergeProps} from "@react-aria/utils";
import {useIsMobile} from "@nextui-org/use-is-mobile";
import {filterDOMProps} from "@nextui-org/react-utils";
Expand Down Expand Up @@ -44,12 +45,14 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
classNames,
onAction,
autoFocus,
onClick,
onPress,
onPressStart,
onPressUp,
onPressEnd,
onPressChange,
onHoverStart: hoverStartProp,
onHoverChange,
onHoverEnd,
hideSelectedIcon = false,
isReadOnly = false,
closeOnSelect,
Expand All @@ -67,7 +70,7 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>

const {rendered, key} = item;

const isDisabled = state.disabledKeys.has(key) || originalProps.isDisabled;
const isDisabledProp = state.disabledKeys.has(key) || originalProps.isDisabled;
const isSelectable = state.selectionManager.selectionMode !== "none";

const isMobile = useIsMobile();
Expand All @@ -77,10 +80,10 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
});

const {
isHovered,
isPressed,
isFocused,
isSelected,
isDisabled,
menuItemProps,
labelProps,
descriptionProps,
Expand All @@ -89,9 +92,8 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
{
key,
onClose,
isDisabled,
isDisabled: isDisabledProp,
onPress,
onClick,
onPressStart,
onPressUp,
onPressEnd,
Expand All @@ -105,6 +107,21 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
domRef,
);

// `useMenuItem` from react-aria doesn't expose `isHovered`
// hence, cover the logic here
let {hoverProps, isHovered} = useHover({
isDisabled,
onHoverStart(e) {
if (!AriaIsFocusVisible()) {
state.selectionManager.setFocused(true);
state.selectionManager.setFocusedKey(key);
}
hoverStartProp?.(e);
},
onHoverChange,
onHoverEnd,
});

let itemProps = menuItemProps;

const slots = useMemo(
Expand All @@ -131,6 +148,7 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
enabled: shouldFilterDOMProps,
}),
itemProps,
hoverProps,
props,
),
"data-focus": dataAttr(isFocused),
Expand Down
2 changes: 1 addition & 1 deletion packages/components/menu/src/use-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {HTMLNextUIProps, PropGetter, SharedSelection} from "@nextui-org/sys
import {useProviderContext} from "@nextui-org/system";
import {AriaMenuProps} from "@react-types/menu";
import {AriaMenuOptions} from "@react-aria/menu";
import {useAriaMenu} from "@nextui-org/use-aria-menu";
import {useMenu as useAriaMenu} from "@react-aria/menu";
import {menu, MenuVariantProps, SlotsToClasses, MenuSlots} from "@nextui-org/theme";
import {TreeState, useTreeState} from "@react-stately/tree";
import {ReactRef, filterDOMProps, useDOMRef} from "@nextui-org/react-utils";
Expand Down
7 changes: 4 additions & 3 deletions packages/hooks/use-image/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@
"postpack": "clean-package restore"
},
"dependencies": {
"@nextui-org/use-safe-layout-effect": "workspace:*"
"@nextui-org/use-safe-layout-effect": "workspace:*",
"@testing-library/react-hooks": "^8.0.1"
},
"peerDependencies": {
"react": ">=18"
},
"devDependencies": {
"@nextui-org/test-utils": "workspace:*",
"clean-package": "2.2.0",
"react": "^18.0.0",
"@nextui-org/test-utils": "workspace:*"
"react": "^18.0.0"
},
"clean-package": "../../../clean-package.config.json",
"tsup": {
Expand Down
Loading

0 comments on commit 2aebfcc

Please sign in to comment.