From 78c09280e30113bd648057ad64ad6198d1e5d58f Mon Sep 17 00:00:00 2001 From: Junior Garcia Date: Tue, 10 Dec 2024 18:01:39 -0300 Subject: [PATCH] fix: on click event on interactive elements (#4322) --- .changeset/two-flies-design.md | 15 + .../button/__tests__/button.test.tsx | 12 + packages/components/button/src/use-button.ts | 3 +- .../button/stories/button.stories.tsx | 11 +- .../components/card/__tests__/card.test.tsx | 21 +- packages/components/card/src/use-card.ts | 11 +- .../components/card/stories/card.stories.tsx | 30 ++ .../dropdown/stories/dropdown.stories.tsx | 4 +- .../components/link/__tests__/link.test.tsx | 29 ++ packages/components/link/src/use-link.ts | 7 + .../components/link/stories/link.stories.tsx | 29 +- .../listbox/src/base/listbox-item-base.tsx | 11 +- .../listbox/src/use-listbox-item.ts | 15 +- .../listbox/stories/listbox.stories.tsx | 4 +- .../components/menu/__tests__/menu.test.tsx | 14 +- packages/components/menu/package.json | 1 - .../menu/src/base/menu-item-base.tsx | 13 +- packages/components/menu/src/menu.tsx | 2 - packages/components/menu/src/use-menu-item.ts | 22 +- packages/components/menu/src/use-menu.ts | 3 +- .../components/menu/stories/menu.stories.tsx | 4 +- packages/components/navbar/package.json | 2 +- .../navbar/src/navbar-menu-toggle.tsx | 2 +- packages/hooks/use-aria-button/package.json | 1 + packages/hooks/use-aria-button/src/index.ts | 34 +- packages/hooks/use-aria-link/package.json | 1 + packages/hooks/use-aria-link/src/index.ts | 38 +- packages/hooks/use-aria-menu/CHANGELOG.md | 145 ------- packages/hooks/use-aria-menu/README.md | 24 -- packages/hooks/use-aria-menu/package.json | 64 --- packages/hooks/use-aria-menu/src/index.ts | 5 - .../hooks/use-aria-menu/src/use-menu-item.ts | 369 ------------------ packages/hooks/use-aria-menu/src/use-menu.ts | 83 ---- packages/hooks/use-aria-menu/tsconfig.json | 4 - .../hooks/use-aria-modal-overlay/src/index.ts | 8 + .../hooks/use-aria-toggle-button/CHANGELOG.md | 240 ------------ .../hooks/use-aria-toggle-button/README.md | 24 -- .../hooks/use-aria-toggle-button/package.json | 59 --- .../hooks/use-aria-toggle-button/src/index.ts | 85 ---- .../use-aria-toggle-button/tsconfig.json | 4 - .../src/overlays/ariaHideOutside.ts | 15 +- pnpm-lock.yaml | 131 +++---- 42 files changed, 366 insertions(+), 1233 deletions(-) create mode 100644 .changeset/two-flies-design.md delete mode 100644 packages/hooks/use-aria-menu/CHANGELOG.md delete mode 100644 packages/hooks/use-aria-menu/README.md delete mode 100644 packages/hooks/use-aria-menu/package.json delete mode 100644 packages/hooks/use-aria-menu/src/index.ts delete mode 100644 packages/hooks/use-aria-menu/src/use-menu-item.ts delete mode 100644 packages/hooks/use-aria-menu/src/use-menu.ts delete mode 100644 packages/hooks/use-aria-menu/tsconfig.json delete mode 100644 packages/hooks/use-aria-toggle-button/CHANGELOG.md delete mode 100644 packages/hooks/use-aria-toggle-button/README.md delete mode 100644 packages/hooks/use-aria-toggle-button/package.json delete mode 100644 packages/hooks/use-aria-toggle-button/src/index.ts delete mode 100644 packages/hooks/use-aria-toggle-button/tsconfig.json diff --git a/.changeset/two-flies-design.md b/.changeset/two-flies-design.md new file mode 100644 index 0000000000..490475d26e --- /dev/null +++ b/.changeset/two-flies-design.md @@ -0,0 +1,15 @@ +--- +"@nextui-org/use-aria-modal-overlay": patch +"@nextui-org/use-aria-button": patch +"@nextui-org/aria-utils": patch +"@nextui-org/dropdown": patch +"@nextui-org/use-aria-link": patch +"@nextui-org/listbox": patch +"@nextui-org/button": patch +"@nextui-org/navbar": patch +"@nextui-org/card": patch +"@nextui-org/link": patch +"@nextui-org/menu": patch +--- + +Fix #4292 interactive elements were not responding to "onClick" event diff --git a/packages/components/button/__tests__/button.test.tsx b/packages/components/button/__tests__/button.test.tsx index 4d55de3e25..e019b4dd23 100644 --- a/packages/components/button/__tests__/button.test.tsx +++ b/packages/components/button/__tests__/button.test.tsx @@ -1,3 +1,4 @@ +import "@testing-library/jest-dom"; import * as React from "react"; import {render} from "@testing-library/react"; import userEvent, {UserEvent} from "@testing-library/user-event"; @@ -35,6 +36,17 @@ describe("Button", () => { expect(onPress).toHaveBeenCalled(); }); + it("should trigger onClick function", async () => { + const onClick = jest.fn(); + const {getByRole} = render( ); diff --git a/packages/components/card/__tests__/card.test.tsx b/packages/components/card/__tests__/card.test.tsx index 089f63486a..ab0b9c642c 100644 --- a/packages/components/card/__tests__/card.test.tsx +++ b/packages/components/card/__tests__/card.test.tsx @@ -1,10 +1,16 @@ import * as React from "react"; import {render} from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; +import userEvent, {UserEvent} from "@testing-library/user-event"; import {Card} from "../src"; describe("Card", () => { + let user: UserEvent; + + beforeEach(() => { + user = userEvent.setup(); + }); + it("should render correctly", () => { const wrapper = render(); @@ -30,13 +36,22 @@ describe("Card", () => { const button = getByRole("button"); - const user = userEvent.setup(); - await user.click(button); expect(onPress).toHaveBeenCalled(); }); + it("should trigger onClick function", async () => { + const onClick = jest.fn(); + const {getByRole} = render(); + + const button = getByRole("button"); + + await user.click(button); + + expect(onClick).toHaveBeenCalled(); + }); + it("should render correctly when nested", () => { const wrapper = render( diff --git a/packages/components/card/src/use-card.ts b/packages/components/card/src/use-card.ts index ceb0f7f2c8..7974550c5d 100644 --- a/packages/components/card/src/use-card.ts +++ b/packages/components/card/src/use-card.ts @@ -4,7 +4,7 @@ import type {AriaButtonProps} from "@nextui-org/use-aria-button"; import type {RippleProps} from "@nextui-org/ripple"; import {card} from "@nextui-org/theme"; -import {ReactNode, useCallback, useMemo} from "react"; +import {MouseEventHandler, ReactNode, useCallback, useMemo} from "react"; import {chain, mergeProps} from "@react-aria/utils"; import {useFocusRing} from "@react-aria/focus"; import {PressEvent, useHover} from "@react-aria/interactions"; @@ -20,7 +20,7 @@ import {ReactRef, filterDOMProps} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils"; import {useRipple} from "@nextui-org/ripple"; -export interface Props extends HTMLNextUIProps<"div"> { +export interface Props extends Omit, "onClick"> { /** * Ref to the DOM node. */ @@ -34,12 +34,17 @@ export interface Props extends HTMLNextUIProps<"div"> { * @default false */ disableRipple?: boolean; - /** * Whether the card should allow text selection on press. (only for pressable cards) * @default true */ allowTextSelectionOnPress?: boolean; + /** + * The native button click event handler. + * use `onPress` instead. + * @deprecated + */ + onClick?: MouseEventHandler; /** * Classname or List of classes to change the classNames of the element. * if `className` is passed, it will be added to the base slot. diff --git a/packages/components/card/stories/card.stories.tsx b/packages/components/card/stories/card.stories.tsx index 09a501bb3f..cd68e757b9 100644 --- a/packages/components/card/stories/card.stories.tsx +++ b/packages/components/card/stories/card.stories.tsx @@ -348,6 +348,28 @@ const PrimaryActionTemplate = (args: CardProps) => { ); }; +const PressableTemplate = (args: CardProps) => { + // Both events should be fired when clicking on the card + + const handlePress = () => { + // eslint-disable-next-line no-console + alert("card pressed"); + }; + + const onClick = () => { + // eslint-disable-next-line no-console + alert("card clicked"); + }; + + return ( + + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+
+ ); +}; + const CenterImgWithHeaderTemplate = (args: CardProps) => { const list = [ { @@ -414,6 +436,14 @@ export const Default = { }, }; +export const Pressable = { + render: PressableTemplate, + + args: { + ...defaultProps, + }, +}; + export const WithDivider = { render: WithDividerTemplate, diff --git a/packages/components/dropdown/stories/dropdown.stories.tsx b/packages/components/dropdown/stories/dropdown.stories.tsx index 6a4f7c6939..12d1379d23 100644 --- a/packages/components/dropdown/stories/dropdown.stories.tsx +++ b/packages/components/dropdown/stories/dropdown.stories.tsx @@ -148,7 +148,9 @@ const Template = ({ - New file + alert("New file")}> + New file + Copy link Edit file diff --git a/packages/components/link/__tests__/link.test.tsx b/packages/components/link/__tests__/link.test.tsx index 2d4c7137f4..b9c5e92731 100644 --- a/packages/components/link/__tests__/link.test.tsx +++ b/packages/components/link/__tests__/link.test.tsx @@ -1,9 +1,16 @@ import * as React from "react"; import {render} from "@testing-library/react"; +import userEvent, {UserEvent} from "@testing-library/user-event"; import {Link} from "../src"; describe("Link", () => { + let user: UserEvent; + + beforeEach(() => { + user = userEvent.setup(); + }); + it("should render correctly", () => { const wrapper = render(); @@ -33,6 +40,28 @@ describe("Link", () => { expect(container.querySelector("svg")).not.toBeNull(); }); + it("should trigger onPress function", async () => { + const onPress = jest.fn(); + const {getByRole} = render(); + + const link = getByRole("link"); + + await user.click(link); + + expect(onPress).toHaveBeenCalled(); + }); + + it("should trigger onClick function", async () => { + const onClick = jest.fn(); + const {getByRole} = render(); + + const link = getByRole("link"); + + await user.click(link); + + expect(onClick).toHaveBeenCalled(); + }); + it('should have target="_blank" and rel="noopener noreferrer" when "isExternal" is true', () => { const {container} = render( diff --git a/packages/components/link/src/use-link.ts b/packages/components/link/src/use-link.ts index 619f84a6c9..1cb9b29b1d 100644 --- a/packages/components/link/src/use-link.ts +++ b/packages/components/link/src/use-link.ts @@ -1,5 +1,6 @@ import type {AriaLinkProps} from "@react-types/link"; import type {LinkVariantProps} from "@nextui-org/theme"; +import type {MouseEventHandler} from "react"; import {link} from "@nextui-org/theme"; import {useAriaLink} from "@nextui-org/use-aria-link"; @@ -36,6 +37,12 @@ interface Props extends HTMLNextUIProps<"a">, LinkVariantProps { * @default */ anchorIcon?: React.ReactNode; + /** + * The native link click event handler. + * use `onPress` instead. + * @deprecated + */ + onClick?: MouseEventHandler; } export type UseLinkProps = Props & AriaLinkProps; diff --git a/packages/components/link/stories/link.stories.tsx b/packages/components/link/stories/link.stories.tsx index ace335a612..9a56a60a42 100644 --- a/packages/components/link/stories/link.stories.tsx +++ b/packages/components/link/stories/link.stories.tsx @@ -1,7 +1,7 @@ import type {VariantProps} from "@nextui-org/theme"; import {Meta} from "@storybook/react"; -import React from "react"; +import React, {useState} from "react"; import {tv} from "@nextui-org/theme"; import {link} from "@nextui-org/theme"; @@ -48,6 +48,22 @@ const defaultProps = { const Template = (args: LinkProps) => ; +const PressableTemplate = (args: LinkProps) => { + const [isOpen, setIsOpen] = useState(false); + const handlePress = (e: any) => { + // eslint-disable-next-line no-console + console.log("Pressed", e); + + setIsOpen(!isOpen); + }; + + return ( + + {isOpen ? "Open" : "Close"} + + ); +}; + export const Default = { render: Template, @@ -59,6 +75,17 @@ export const Default = { }, }; +export const Pressable = { + render: PressableTemplate, + + args: { + ...defaultProps, + isDisabled: false, + color: "foreground", + size: "md", + }, +}; + export const Underline = Template.bind({}) as any; Underline.args = { ...defaultProps, diff --git a/packages/components/listbox/src/base/listbox-item-base.tsx b/packages/components/listbox/src/base/listbox-item-base.tsx index e5283f3ff1..571929b34e 100644 --- a/packages/components/listbox/src/base/listbox-item-base.tsx +++ b/packages/components/listbox/src/base/listbox-item-base.tsx @@ -89,11 +89,18 @@ interface Props extends Omit, "childre classNames?: SlotsToClasses; } -export type ListboxItemBaseProps = Props & +export type ListboxItemBaseProps = Omit, "onClick"> & Omit & Omit & FocusableProps & - PressEvents; + PressEvents & { + /** + * The native click event handler. + * use `onPress` instead. + * @deprecated + */ + onClick?: (e: React.MouseEvent) => void; + }; const ListboxItemBase = BaseItem as ( props: ListboxItemBaseProps, diff --git a/packages/components/listbox/src/use-listbox-item.ts b/packages/components/listbox/src/use-listbox-item.ts index 5364c773dc..22f462d17a 100644 --- a/packages/components/listbox/src/use-listbox-item.ts +++ b/packages/components/listbox/src/use-listbox-item.ts @@ -12,7 +12,7 @@ import { import {useFocusRing} from "@react-aria/focus"; import {Node} from "@react-types/shared"; import {filterDOMProps} from "@nextui-org/react-utils"; -import {clsx, dataAttr, objectToDeps, removeEvents} from "@nextui-org/shared-utils"; +import {clsx, dataAttr, objectToDeps, removeEvents, warn} from "@nextui-org/shared-utils"; import {useOption} from "@react-aria/listbox"; import {mergeProps} from "@react-aria/utils"; import {useHover, usePress} from "@react-aria/interactions"; @@ -46,7 +46,7 @@ export function useListboxItem(originalProps: UseListboxItemPr classNames, autoFocus, onPress, - onClick, + onClick: deprecatedOnClick, shouldHighlightOnFocus, hideSelectedIcon = false, isReadOnly = false, @@ -68,6 +68,13 @@ export function useListboxItem(originalProps: UseListboxItemPr const isMobile = useIsMobile(); + if (deprecatedOnClick && typeof deprecatedOnClick === "function") { + warn( + "onClick is deprecated, please use onPress instead. See: https://github.com/nextui-org/nextui/issues/4292", + "ListboxItem", + ); + } + const {pressProps, isPressed} = usePress({ ref: domRef, isDisabled: isDisabled, @@ -120,7 +127,9 @@ export function useListboxItem(originalProps: UseListboxItemPr const getItemProps: PropGetter = (props = {}) => ({ ref: domRef, ...mergeProps( - {onClick}, + { + onClick: deprecatedOnClick, + }, itemProps, isReadOnly ? {} : mergeProps(focusProps, pressProps), hoverProps, diff --git a/packages/components/listbox/stories/listbox.stories.tsx b/packages/components/listbox/stories/listbox.stories.tsx index c670e57621..38fb8147e1 100644 --- a/packages/components/listbox/stories/listbox.stories.tsx +++ b/packages/components/listbox/stories/listbox.stories.tsx @@ -174,7 +174,9 @@ const Template = ({color, variant, ...args}: ListboxProps) => ( onAction={(key: Key) => alert(key)} {...args} > - New file + alert("[onClick] New file")}> + New file + Copy link Edit file diff --git a/packages/components/menu/__tests__/menu.test.tsx b/packages/components/menu/__tests__/menu.test.tsx index eeaa3eb068..698eaa59e4 100644 --- a/packages/components/menu/__tests__/menu.test.tsx +++ b/packages/components/menu/__tests__/menu.test.tsx @@ -347,7 +347,9 @@ describe("Menu", () => { it("should menuItem classNames work", () => { const wrapper = render( - New file + + New file + , ); const menuItem = wrapper.getByText("New file"); @@ -358,7 +360,9 @@ describe("Menu", () => { it("should menuItem classNames override menu itemClasses", () => { const wrapper = render( - New file + + New file + , ); const menuItem = wrapper.getByText("New file"); @@ -368,8 +372,10 @@ describe("Menu", () => { it("should merge menu item classNames with itemClasses", () => { const wrapper = render( - New file - Delete file + + New file + + Delete file , ); diff --git a/packages/components/menu/package.json b/packages/components/menu/package.json index dd5a4e0bff..25deb69f9f 100644 --- a/packages/components/menu/package.json +++ b/packages/components/menu/package.json @@ -45,7 +45,6 @@ "@nextui-org/use-is-mobile": "workspace:*", "@nextui-org/shared-utils": "workspace:*", "@nextui-org/react-utils": "workspace:*", - "@nextui-org/use-aria-menu": "workspace:*", "@react-aria/focus": "3.19.0", "@react-aria/interactions": "3.22.5", "@react-aria/menu": "3.16.0", diff --git a/packages/components/menu/src/base/menu-item-base.tsx b/packages/components/menu/src/base/menu-item-base.tsx index 693ab6d53f..0a4c7e4184 100644 --- a/packages/components/menu/src/base/menu-item-base.tsx +++ b/packages/components/menu/src/base/menu-item-base.tsx @@ -3,7 +3,7 @@ import type {AriaMenuItemProps} from "@react-aria/menu"; import type {FocusableProps, PressEvents} from "@react-types/shared"; import {BaseItem, ItemProps} from "@nextui-org/aria-utils"; -import {ReactNode} from "react"; +import {MouseEventHandler, ReactNode} from "react"; export type MenuItemSelectedIconProps = { /** @@ -88,11 +88,18 @@ interface Props extends Omit, "childre classNames?: SlotsToClasses; } -export type MenuItemBaseProps = Props & +export type MenuItemBaseProps = Omit, "onClick"> & Omit & AriaMenuItemProps & FocusableProps & - PressEvents; + PressEvents & { + /** + * The native click event handler. + * use `onPress` instead. + * @deprecated + */ + onClick?: MouseEventHandler; + }; const MenuItemBase = BaseItem as (props: MenuItemBaseProps) => JSX.Element; diff --git a/packages/components/menu/src/menu.tsx b/packages/components/menu/src/menu.tsx index 95711afc8e..d08399b001 100644 --- a/packages/components/menu/src/menu.tsx +++ b/packages/components/menu/src/menu.tsx @@ -24,7 +24,6 @@ const Menu = forwardRef(function Menu( hideEmptyContent, variant, onClose, - onAction, topContent, bottomContent, itemClasses, @@ -49,7 +48,6 @@ const Menu = forwardRef(function Menu( state, variant, onClose, - onAction, hideSelectedIcon, ...item.props, }; diff --git a/packages/components/menu/src/use-menu-item.ts b/packages/components/menu/src/use-menu-item.ts index b493e50bd5..4aaeb274ec 100644 --- a/packages/components/menu/src/use-menu-item.ts +++ b/packages/components/menu/src/use-menu-item.ts @@ -1,6 +1,6 @@ import type {MenuItemBaseProps} from "./base/menu-item-base"; import type {MenuItemVariantProps} from "@nextui-org/theme"; -import type {Node} from "@react-types/shared"; +import type {Node, PressEvent} from "@react-types/shared"; import {useMemo, useRef, useCallback} from "react"; import {menuItem} from "@nextui-org/theme"; @@ -12,7 +12,7 @@ import { } from "@nextui-org/system"; import {useFocusRing} from "@react-aria/focus"; import {TreeState} from "@react-stately/tree"; -import {clsx, dataAttr, objectToDeps, removeEvents} from "@nextui-org/shared-utils"; +import {clsx, dataAttr, objectToDeps, removeEvents, warn} from "@nextui-org/shared-utils"; import {useMenuItem as useAriaMenuItem} from "@react-aria/menu"; import {isFocusVisible as AriaIsFocusVisible, useHover} from "@react-aria/interactions"; import {mergeProps} from "@react-aria/utils"; @@ -59,6 +59,7 @@ export function useMenuItem(originalProps: UseMenuItemProps isReadOnly = false, closeOnSelect, onClose, + onClick: deprecatedOnClick, ...otherProps } = props; @@ -81,6 +82,21 @@ export function useMenuItem(originalProps: UseMenuItemProps autoFocus, }); + if (deprecatedOnClick && typeof deprecatedOnClick === "function") { + warn( + "onClick is deprecated, please use onPress instead. See: https://github.com/nextui-org/nextui/issues/4292", + "MenuItem", + ); + } + + const handlePress = useCallback( + (e: PressEvent) => { + deprecatedOnClick?.(e as unknown as React.MouseEvent); + onPress?.(e); + }, + [deprecatedOnClick, onPress], + ); + const { isPressed, isFocused, @@ -95,7 +111,7 @@ export function useMenuItem(originalProps: UseMenuItemProps key, onClose, isDisabled: isDisabledProp, - onPress, + onPress: handlePress, onPressStart, onPressUp, onPressEnd, diff --git a/packages/components/menu/src/use-menu.ts b/packages/components/menu/src/use-menu.ts index 9b6efd8151..535eca044c 100644 --- a/packages/components/menu/src/use-menu.ts +++ b/packages/components/menu/src/use-menu.ts @@ -129,7 +129,7 @@ export function useMenu(props: UseMenuProps) { const state = propState || innerState; - const {menuProps} = useAriaMenu({...otherProps, ...userMenuProps}, state, domRef); + const {menuProps} = useAriaMenu({...otherProps, ...userMenuProps, onAction}, state, domRef); const slots = useMemo(() => menu({className}), [className]); const baseStyles = clsx(classNames?.base, className); @@ -169,7 +169,6 @@ export function useMenu(props: UseMenuProps) { variant, color, disableAnimation, - onAction, onClose, topContent, bottomContent, diff --git a/packages/components/menu/stories/menu.stories.tsx b/packages/components/menu/stories/menu.stories.tsx index 486b54e074..0b026b22f7 100644 --- a/packages/components/menu/stories/menu.stories.tsx +++ b/packages/components/menu/stories/menu.stories.tsx @@ -45,7 +45,9 @@ const defaultProps = { const Template = ({color, variant, ...args}: MenuProps) => ( - New file + alert("[onClick] New file")}> + New file + Copy link Edit file diff --git a/packages/components/navbar/package.json b/packages/components/navbar/package.json index 6cc43ec278..868a4b22db 100644 --- a/packages/components/navbar/package.json +++ b/packages/components/navbar/package.json @@ -44,11 +44,11 @@ "@nextui-org/shared-utils": "workspace:*", "@nextui-org/react-utils": "workspace:*", "@nextui-org/framer-utils": "workspace:*", - "@nextui-org/use-aria-toggle-button": "workspace:*", "@nextui-org/use-scroll-position": "workspace:*", "@nextui-org/dom-animation": "workspace:*", "@react-aria/focus": "3.19.0", "@react-aria/interactions": "3.22.5", + "@react-aria/button": "3.11.0", "@react-aria/overlays": "3.24.0", "@react-aria/utils": "3.26.0", "@react-stately/toggle": "3.8.0", diff --git a/packages/components/navbar/src/navbar-menu-toggle.tsx b/packages/components/navbar/src/navbar-menu-toggle.tsx index 540da68368..d870ef70bd 100644 --- a/packages/components/navbar/src/navbar-menu-toggle.tsx +++ b/packages/components/navbar/src/navbar-menu-toggle.tsx @@ -1,4 +1,4 @@ -import {AriaToggleButtonProps, useAriaToggleButton} from "@nextui-org/use-aria-toggle-button"; +import {AriaToggleButtonProps, useToggleButton as useAriaToggleButton} from "@react-aria/button"; import {forwardRef, HTMLNextUIProps} from "@nextui-org/system"; import {useDOMRef} from "@nextui-org/react-utils"; import {clsx, dataAttr} from "@nextui-org/shared-utils"; diff --git a/packages/hooks/use-aria-button/package.json b/packages/hooks/use-aria-button/package.json index 468a67b9a8..dd12604cfe 100644 --- a/packages/hooks/use-aria-button/package.json +++ b/packages/hooks/use-aria-button/package.json @@ -37,6 +37,7 @@ "react": ">=18 || >=19.0.0-rc.0" }, "dependencies": { + "@nextui-org/shared-utils": "workspace:*", "@react-aria/focus": "3.19.0", "@react-aria/interactions": "3.22.5", "@react-aria/utils": "3.26.0", diff --git a/packages/hooks/use-aria-button/src/index.ts b/packages/hooks/use-aria-button/src/index.ts index 21b9cac6c1..03593113b0 100644 --- a/packages/hooks/use-aria-button/src/index.ts +++ b/packages/hooks/use-aria-button/src/index.ts @@ -10,8 +10,9 @@ import { RefObject, } from "react"; import {AriaButtonProps as BaseAriaButtonProps} from "@react-types/button"; -import {DOMAttributes} from "@react-types/shared"; -import {filterDOMProps, mergeProps} from "@react-aria/utils"; +import {DOMAttributes, PressEvent} from "@react-types/shared"; +import {warn} from "@nextui-org/shared-utils"; +import {filterDOMProps, isAndroid, isIOS, mergeProps} from "@react-aria/utils"; import {useFocusable} from "@react-aria/focus"; import {usePress} from "@react-aria/interactions"; @@ -92,7 +93,7 @@ export function useAriaButton( additionalProps = { role: "button", tabIndex: isDisabled ? undefined : 0, - href: elementType === "a" && isDisabled ? undefined : href, + href: elementType === "a" && !isDisabled ? href : undefined, target: elementType === "a" ? target : undefined, type: elementType === "input" ? type : undefined, disabled: elementType === "input" ? isDisabled : undefined, @@ -101,11 +102,31 @@ export function useAriaButton( }; } + let isMobile = isIOS() || isAndroid(); + + if (deprecatedOnClick && typeof deprecatedOnClick === "function") { + warn( + "onClick is deprecated, please use onPress instead. See: https://github.com/nextui-org/nextui/issues/4292", + "useButton", + ); + } + + const handlePress = (e: PressEvent) => { + // On mobile devices, we need to call onClick directly since react-aria's usePress hook + // only supports onPress events as of https://github.com/adobe/react-spectrum/commit/1d5def8a + // This ensures backwards compatibility for onClick handlers on mobile + // See: https://github.com/nextui-org/nextui/issues/4292 + if (isMobile) { + deprecatedOnClick?.(e as unknown as React.MouseEvent); + } + onPress?.(e); + }; + let {pressProps, isPressed} = usePress({ onPressStart, onPressEnd, onPressChange, - onPress, + onPress: handlePress, isDisabled, preventFocusOnPress, allowTextSelectionOnPress, @@ -131,6 +152,11 @@ export function useAriaButton( "aria-controls": props["aria-controls"], "aria-pressed": props["aria-pressed"], onClick: (e: React.MouseEvent) => { + if (type === "button" && isMobile) { + // Avoid firing onClick event twice since it's handled in handlePress + return; + } + deprecatedOnClick?.(e); }, }), diff --git a/packages/hooks/use-aria-link/package.json b/packages/hooks/use-aria-link/package.json index fcfd368965..070d4bc17d 100644 --- a/packages/hooks/use-aria-link/package.json +++ b/packages/hooks/use-aria-link/package.json @@ -37,6 +37,7 @@ "react": ">=18 || >=19.0.0-rc.0" }, "dependencies": { + "@nextui-org/shared-utils": "workspace:*", "@react-aria/focus": "3.19.0", "@react-aria/interactions": "3.22.5", "@react-aria/utils": "3.26.0", diff --git a/packages/hooks/use-aria-link/src/index.ts b/packages/hooks/use-aria-link/src/index.ts index 008cf95b9e..e47e0d1692 100644 --- a/packages/hooks/use-aria-link/src/index.ts +++ b/packages/hooks/use-aria-link/src/index.ts @@ -1,13 +1,16 @@ import {AriaLinkProps} from "@react-types/link"; -import {DOMAttributes, FocusableElement} from "@react-types/shared"; +import {DOMAttributes, FocusableElement, PressEvent} from "@react-types/shared"; import { filterDOMProps, mergeProps, useRouter, shouldClientNavigate, useLinkProps, + isAndroid, + isIOS, } from "@react-aria/utils"; import {RefObject} from "react"; +import {warn} from "@nextui-org/shared-utils"; import {useFocusable} from "@react-aria/focus"; import {usePress} from "@react-aria/interactions"; @@ -55,8 +58,35 @@ export function useAriaLink(props: AriaLinkOptions, ref: RefObject { + // On mobile devices, we need to call onClick directly since react-aria's usePress hook + // only supports onPress events as of https://github.com/adobe/react-spectrum/commit/1d5def8a + // This ensures backwards compatibility for onClick handlers on mobile + // See: https://github.com/nextui-org/nextui/issues/4292 + if (isMobile) { + deprecatedOnClick?.(e as unknown as React.MouseEvent); + } + onPress?.(e); + }; + let {focusableProps} = useFocusable(props, ref); - let {pressProps, isPressed} = usePress({onPress, onPressStart, onPressEnd, isDisabled, ref}); + let {pressProps, isPressed} = usePress({ + onPress: handlePress, + onPressStart, + onPressEnd, + isDisabled, + ref, + }); let domProps = filterDOMProps(otherProps, {labelable: true, isLink: elementType === "a"}); let interactionHandlers = mergeProps(focusableProps, pressProps); let router = useRouter(); @@ -71,7 +101,9 @@ export function useAriaLink(props: AriaLinkOptions, ref: RefObject) => { pressProps.onClick?.(e); - if (deprecatedOnClick) { + + // The `isMobile` check is to avoid firing onClick event twice since it's handled in handlePress + if (!isMobile && deprecatedOnClick) { deprecatedOnClick(e); } diff --git a/packages/hooks/use-aria-menu/CHANGELOG.md b/packages/hooks/use-aria-menu/CHANGELOG.md deleted file mode 100644 index 2a3878fef4..0000000000 --- a/packages/hooks/use-aria-menu/CHANGELOG.md +++ /dev/null @@ -1,145 +0,0 @@ -# @nextui-org/use-aria-menu - -## 2.2.2 - -### Patch Changes - -- [#4258](https://github.com/nextui-org/nextui/pull/4258) [`1031e98`](https://github.com/nextui-org/nextui/commit/1031e985b71e69b8a7189ea049b9616257f820b3) Thanks [@wingkwong](https://github.com/wingkwong)! - sync with upstream RA versions - -## 2.2.1 - -### Patch Changes - -- [`d6eee4a`](https://github.com/nextui-org/nextui/commit/d6eee4a8767556152f47f06dcf04940951abc5af) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - v2.6.2 - -## 2.2.0 - -### Minor Changes - -- [`5786897`](https://github.com/nextui-org/nextui/commit/5786897b9950d95c12351dacd2fb41bb1e298201) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - This release includes several improvements and bug fixes: - - - Updated react-aria version across all components - - Improved Drawer styles and transitions - - Fixed missing peer dependencies for framer-motion - - Fixed menu item classNames functionality - - Added isClearable prop to Textarea component - - Fixed label placement issues in Input and Select components - - Improved table keyboard navigation with new isKeyboardNavigationDisabled prop - - Fixed UI sliding issues with helper wrapper in Input and Select - - Updated use-image hook to avoid Next.js hydration issues - - Replaced RTL-specific styles with logical properties - - Fixed textarea label squish issue - - Bumped tailwind-merge version - - Applied tw nested group fixes - - Fixed fullWidth variant in input and select components - - Moved circular-progress tv to progress - - Changed ListboxItem key to optional - - Fixed autocomplete clear button behavior - - Updated Select label placement logic - - Added missing framer-motion peer dependencies - - Removed layoutNode prop from Table due to react-aria update - - Virtualization added to Autocomplete - -### Patch Changes - -- [#4226](https://github.com/nextui-org/nextui/pull/4226) [`6c0213d`](https://github.com/nextui-org/nextui/commit/6c0213dfc805aa3c793763c0b25f53b2b80c24dc) Thanks [@wingkwong](https://github.com/wingkwong)! - bump `@react-aria/utils` version (#4212) - -## 2.1.0-beta.8 - -### Patch Changes - -- [`9869f2b91`](https://github.com/nextui-org/nextui/commit/9869f2b91d0829f9c7f0500ba05745707820bf27) Thanks [@wingkwong](https://github.com/wingkwong)! - bump version - -## 2.1.0-beta.7 - -### Patch Changes - -- [#3036](https://github.com/nextui-org/nextui/pull/3036) [`eafdb7d47`](https://github.com/nextui-org/nextui/commit/eafdb7d475a7fcaa7671af77e86fcdf62f14ae00) Thanks [@ryo-manba](https://github.com/ryo-manba)! - update react-aria version - -## 2.1.0-beta.6 - -### Patch Changes - -- [#4092](https://github.com/nextui-org/nextui/pull/4092) [`528668db8`](https://github.com/nextui-org/nextui/commit/528668db85b98b46473cb1e214780b7468cdadba) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Test new runner - -## 2.1.0-beta.5 - -### Patch Changes - -- [#4086](https://github.com/nextui-org/nextui/pull/4086) [`f69fe47b5`](https://github.com/nextui-org/nextui/commit/f69fe47b5b8f6f3a77a7a8c20d8715263fa32acb) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Pnpm clean - -## 2.1.0-beta.4 - -### Patch Changes - -- [#4083](https://github.com/nextui-org/nextui/pull/4083) [`35058262c`](https://github.com/nextui-org/nextui/commit/35058262c61628fb42907f529c4417886aa12bb2) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Fix build - -## 2.1.0-beta.3 - -### Patch Changes - -- [#4010](https://github.com/nextui-org/nextui/pull/4010) [`ef432eb53`](https://github.com/nextui-org/nextui/commit/ef432eb539714fded6cab86a2185956fb103e0df) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - framer-motion alpha version added - -## 2.1.0-beta.2 - -### Patch Changes - -- [#4008](https://github.com/nextui-org/nextui/pull/4008) [`7c1c0dd8f`](https://github.com/nextui-org/nextui/commit/7c1c0dd8fef3ea72996c1095b919574c4b7f9b89) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - React 19 added to peerDeps - -## 2.1.0-beta.1 - -### Patch Changes - -- [#3990](https://github.com/nextui-org/nextui/pull/3990) [`cb5bc4c74`](https://github.com/nextui-org/nextui/commit/cb5bc4c74f00caaee80dca89c1f02038db315b85) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Beta 1 - -## 2.1.0-beta.0 - -### Minor Changes - -- [#3732](https://github.com/nextui-org/nextui/pull/3732) [`67ea2f65e`](https://github.com/nextui-org/nextui/commit/67ea2f65e17f913bdffae4690586a6ae202c8f7d) Thanks [@ryo-manba](https://github.com/ryo-manba)! - update react-aria version - -## 2.0.7 - -### Patch Changes - -- [#3762](https://github.com/nextui-org/nextui/pull/3762) [`8fecb5afa`](https://github.com/nextui-org/nextui/commit/8fecb5afa9aabe73e32243ca313f97856da8aa08) Thanks [@wingkwong](https://github.com/wingkwong)! - fixed `_a2.find` is not a function (#3761) - -## 2.0.6 - -### Patch Changes - -- [#3512](https://github.com/nextui-org/nextui/pull/3512) [`2d2d300a1`](https://github.com/nextui-org/nextui/commit/2d2d300a12dbe20ca7ebd125daf3dce74efcbf34) Thanks [@wingkwong](https://github.com/wingkwong)! - fix conflicting versions in npm - -## 2.0.5 - -### Patch Changes - -- [#3229](https://github.com/nextui-org/nextui/pull/3229) [`5b9e317a8`](https://github.com/nextui-org/nextui/commit/5b9e317a80dacad09a3fc3c5b762729cd10b2bb3) Thanks [@wingkwong](https://github.com/wingkwong)! - fix link logic in useMenuItem (#2935) - -- [#3240](https://github.com/nextui-org/nextui/pull/3240) [`47c2472fb`](https://github.com/nextui-org/nextui/commit/47c2472fb22bfe1c0c357b5ba12e5606eba0d65b) Thanks [@wingkwong](https://github.com/wingkwong)! - bump react-aria dependencies - -## 2.0.4 - -### Patch Changes - -- [#3119](https://github.com/nextui-org/nextui/pull/3119) [`685995a12`](https://github.com/nextui-org/nextui/commit/685995a125cc3db26c6adb67ed9f7245b87e792a) Thanks [@wingkwong](https://github.com/wingkwong)! - bump `@react-aria/utils` version to `3.24.1` and bump `@react-types/shared` to `3.23.1` - -- [#3119](https://github.com/nextui-org/nextui/pull/3119) [`685995a12`](https://github.com/nextui-org/nextui/commit/685995a125cc3db26c6adb67ed9f7245b87e792a) Thanks [@wingkwong](https://github.com/wingkwong)! - Add missing router.open parameters due to router change - -## 2.0.3 - -### Patch Changes - -- [#3064](https://github.com/nextui-org/nextui/pull/3064) [`f24a97311`](https://github.com/nextui-org/nextui/commit/f24a97311ab4dd16dafb56d35fe7c6db81798129) Thanks [@Gaic4o](https://github.com/Gaic4o)! - Fixed a type error in the onKeyDown event handler for the menu component - -## 2.0.2 - -### Patch Changes - -- [#2862](https://github.com/nextui-org/nextui/pull/2862) [`b8e6b2fe2`](https://github.com/nextui-org/nextui/commit/b8e6b2fe25bbbf52f656bbcac52fc00714f464bc) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Add react-dom as peerDependency to user-aria-menu hook - -## 2.0.1 - -### Patch Changes - -- [#2746](https://github.com/nextui-org/nextui/pull/2746) [`6b56e43a3`](https://github.com/nextui-org/nextui/commit/6b56e43a350d045c36eb9983c7f48ba61db7cdd2) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Fix #2743 #2751 internal react-aria use-menu hooks implemented to pass down the press events and control the pressUp one diff --git a/packages/hooks/use-aria-menu/README.md b/packages/hooks/use-aria-menu/README.md deleted file mode 100644 index b0e31c23d8..0000000000 --- a/packages/hooks/use-aria-menu/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# @nextui-org/use-aria-menu-item - -A Quick description of the component - -> This is an internal utility, not intended for public usage. - -## Installation - -```sh -yarn add @nextui-org/use-aria-menu-item -# or -npm i @nextui-org/use-aria-menu-item -``` - -## Contribution - -Yes please! See the -[contributing guidelines](https://github.com/nextui-org/nextui/blob/master/CONTRIBUTING.md) -for details. - -## License - -This project is licensed under the terms of the -[MIT license](https://github.com/nextui-org/nextui/blob/master/LICENSE). diff --git a/packages/hooks/use-aria-menu/package.json b/packages/hooks/use-aria-menu/package.json deleted file mode 100644 index cbeabbd6fe..0000000000 --- a/packages/hooks/use-aria-menu/package.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "@nextui-org/use-aria-menu", - "version": "2.2.2", - "description": "React-aria useMenu hooks with custom implementations", - "keywords": [ - "use-aria-menu" - ], - "author": "Junior Garcia ", - "homepage": "https://nextui.org", - "license": "MIT", - "main": "src/index.ts", - "sideEffects": false, - "files": [ - "dist" - ], - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/nextui-org/nextui.git", - "directory": "packages/hooks/use-aria-menu" - }, - "bugs": { - "url": "https://github.com/nextui-org/nextui/issues" - }, - "scripts": { - "build": "tsup src --dts", - "build:fast": "tsup src", - "dev": "pnpm build:fast --watch", - "clean": "rimraf dist .turbo", - "typecheck": "tsc --noEmit", - "prepack": "clean-package", - "postpack": "clean-package restore" - }, - "peerDependencies": { - "react": ">=18 || >=19.0.0-rc.0", - "react-dom": ">=18 || >=19.0.0-rc.0" - }, - "dependencies": { - "@react-aria/utils": "3.26.0", - "@react-types/shared": "3.26.0", - "@react-aria/menu": "3.16.0", - "@react-aria/interactions": "3.22.5", - "@react-stately/tree": "3.8.6", - "@react-aria/i18n": "3.12.4", - "@react-aria/selection": "3.21.0", - "@react-stately/collections": "3.12.0", - "@react-types/menu": "3.9.13" - }, - "devDependencies": { - "clean-package": "2.2.0", - "react": "^18.0.0" - }, - "clean-package": "../../../clean-package.config.json", - "tsup": { - "clean": true, - "target": "es2019", - "format": [ - "cjs", - "esm" - ] - } -} \ No newline at end of file diff --git a/packages/hooks/use-aria-menu/src/index.ts b/packages/hooks/use-aria-menu/src/index.ts deleted file mode 100644 index 448ede3174..0000000000 --- a/packages/hooks/use-aria-menu/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export {menuData, useMenu as useAriaMenu} from "./use-menu"; -export {useMenuItem as useAriaMenuItem} from "./use-menu-item"; - -export type {AriaMenuOptions, MenuAria} from "./use-menu"; -export type {AriaMenuItemProps, MenuItemAria} from "./use-menu-item"; diff --git a/packages/hooks/use-aria-menu/src/use-menu-item.ts b/packages/hooks/use-aria-menu/src/use-menu-item.ts deleted file mode 100644 index ccc346c767..0000000000 --- a/packages/hooks/use-aria-menu/src/use-menu-item.ts +++ /dev/null @@ -1,369 +0,0 @@ -import { - DOMAttributes, - DOMProps, - FocusableElement, - FocusEvents, - HoverEvents, - Key, - KeyboardEvents, - PressEvent, - PressEvents, - RouterOptions, -} from "@react-types/shared"; -import { - chain, - filterDOMProps, - mergeProps, - useLinkProps, - useRouter, - useSlotId, -} from "@react-aria/utils"; -import {getItemCount} from "@react-stately/collections"; -import {isFocusVisible, useFocus, useHover, useKeyboard, usePress} from "@react-aria/interactions"; -import {RefObject} from "react"; -import {TreeState} from "@react-stately/tree"; -import {useSelectableItem} from "@react-aria/selection"; - -import {menuData} from "./use-menu"; - -export interface MenuItemAria { - /** Props for the menu item element. */ - menuItemProps: DOMAttributes; - - /** Props for the main text element inside the menu item. */ - labelProps: DOMAttributes; - - /** Props for the description text element inside the menu item, if any. */ - descriptionProps: DOMAttributes; - - /** Props for the keyboard shortcut text element inside the item, if any. */ - keyboardShortcutProps: DOMAttributes; - - /** Whether the item is currently hovered. */ - isHovered: boolean; - /** Whether the item is currently focused. */ - isFocused: boolean; - /** Whether the item is currently selected. */ - isSelected: boolean; - /** Whether the item is currently in a pressed state. */ - isPressed: boolean; - /** Whether the item is disabled. */ - isDisabled: boolean; -} - -export interface AriaMenuItemProps - extends DOMProps, - PressEvents, - HoverEvents, - KeyboardEvents, - FocusEvents { - /** - * Whether the menu item is disabled. - * @deprecated - pass disabledKeys to useTreeState instead. - */ - isDisabled?: boolean; - - /** - * Whether the menu item is selected. - * @deprecated - pass selectedKeys to useTreeState instead. - */ - isSelected?: boolean; - - /** A screen reader only label for the menu item. */ - "aria-label"?: string; - - /** The unique key for the menu item. */ - key?: Key; - - /** - * Handler that is called when the menu should close after selecting an item. - * @deprecated - pass to the menu instead. - */ - onClose?: () => void; - - /** - * Whether the menu should close when the menu item is selected. - * @default true - */ - closeOnSelect?: boolean; - - /** Whether the menu item is contained in a virtual scrolling menu. */ - isVirtualized?: boolean; - - /** - * Handler that is called when the user activates the item. - * @deprecated - pass to the menu instead. - */ - onAction?: (key: Key, item: any) => void; - - /** - * The native button click event handler - * @deprecated - use `onAction` instead. - */ - onClick?: DOMAttributes["onClick"]; - - /** What kind of popup the item opens. */ - "aria-haspopup"?: "menu" | "dialog"; - - /** Indicates whether the menu item's popup element is expanded or collapsed. */ - "aria-expanded"?: boolean | "true" | "false"; - - /** Identifies the menu item's popup element whose contents or presence is controlled by the menu item. */ - "aria-controls"?: string; -} - -/** - * Provides the behavior and accessibility implementation for an item in a menu. - * See `useMenu` for more details about menus. - * @param props - Props for the item. - * @param state - State for the menu, as returned by `useTreeState`. - */ -export function useMenuItem( - props: AriaMenuItemProps, - state: TreeState, - ref: RefObject, -): MenuItemAria { - let { - key, - closeOnSelect, - isVirtualized, - "aria-haspopup": hasPopup, - onPressStart: pressStartProp, - onPressUp: pressUpProp, - onPress, - onPressChange, - onPressEnd, - onHoverStart: hoverStartProp, - onHoverChange, - onHoverEnd, - onKeyDown, - onKeyUp, - onFocus, - onFocusChange, - onBlur, - onClick, - } = props; - - let isTrigger = !!hasPopup; - // @ts-ignore - let isDisabled = props.isDisabled ?? state.selectionManager.isDisabled(key); - // @ts-ignore - let isSelected = props.isSelected ?? state.selectionManager.isSelected(key); - let data = menuData.get(state); - // @ts-ignore - let item = state.collection.getItem(key); - // @ts-ignore - let onClose = props.onClose || data.onClose; - // @ts-ignore - let router = useRouter(); - let performAction = (e: PressEvent) => { - if (isTrigger) { - return; - } - - if (item?.props?.onAction) { - item.props.onAction(); - } - - if (props.onAction) { - // @ts-ignore - props.onAction(key, item); - // @ts-ignore - } else if (data.onAction) { - // @ts-ignore - data.onAction(key, item); - } - - if (e.target instanceof HTMLAnchorElement) { - // @ts-ignore - router.open(e.target, e, item.props.href, item.props.routerOptions as RouterOptions); - } - }; - - let role = "menuitem"; - - if (!isTrigger) { - if (state.selectionManager.selectionMode === "single") { - role = "menuitemradio"; - } else if (state.selectionManager.selectionMode === "multiple") { - role = "menuitemcheckbox"; - } - } - - let labelId = useSlotId(); - let descriptionId = useSlotId(); - let keyboardId = useSlotId(); - - let ariaProps = { - "aria-disabled": isDisabled || undefined, - role, - "aria-label": props["aria-label"], - "aria-labelledby": labelId, - "aria-describedby": [descriptionId, keyboardId].filter(Boolean).join(" ") || undefined, - "aria-controls": props["aria-controls"], - "aria-haspopup": hasPopup, - "aria-expanded": props["aria-expanded"], - }; - - if (state.selectionManager.selectionMode !== "none" && !isTrigger) { - // @ts-ignore - ariaProps["aria-checked"] = isSelected; - } - - if (isVirtualized) { - // @ts-ignore - ariaProps["aria-posinset"] = item?.index; - // @ts-ignore - ariaProps["aria-setsize"] = getItemCount(state.collection); - } - - let onPressStart = (e: PressEvent) => { - if (e.pointerType === "keyboard") { - performAction(e); - } - - pressStartProp?.(e); - }; - - let onPressUp = (e: PressEvent) => { - if (e.pointerType !== "keyboard") { - setTimeout(() => { - performAction(e); - }); - // // Pressing a menu item should close by default in single selection mode but not multiple - // // selection mode, except if overridden by the closeOnSelect prop. - if ( - !isTrigger && - onClose && - (closeOnSelect ?? - (state.selectionManager.selectionMode !== "multiple" || - // @ts-ignore - state.selectionManager.isLink(key))) - ) { - setTimeout(() => { - onClose?.(); - }); - } - } - - pressUpProp?.(e); - }; - - let {itemProps, isFocused} = useSelectableItem({ - selectionManager: state.selectionManager, - // @ts-ignore - key, - ref, - shouldSelectOnPressUp: true, - allowsDifferentPressOrigin: true, - // Disable all handling of links in useSelectable item - // because we handle it ourselves. The behavior of menus - // is slightly different from other collections because - // actions are performed on key down rather than key up. - linkBehavior: "none", - }); - - let {pressProps, isPressed} = usePress({ - onPressStart, - onPress, - onPressUp, - onPressChange, - onPressEnd, - isDisabled, - }); - - let {isHovered, hoverProps} = useHover({ - isDisabled, - onHoverStart(e) { - if (!isFocusVisible()) { - state.selectionManager.setFocused(true); - // @ts-ignore - state.selectionManager.setFocusedKey(key); - } - hoverStartProp?.(e); - }, - onHoverChange, - onHoverEnd, - }); - - let {keyboardProps} = useKeyboard({ - onKeyDown: (e) => { - // Ignore repeating events, which may have started on the menu trigger before moving - // focus to the menu item. We want to wait for a second complete key press sequence. - if (e.repeat) { - e.continuePropagation(); - - return; - } - - switch (e.key) { - case " ": - if ( - !isDisabled && - state.selectionManager.selectionMode === "none" && - !isTrigger && - closeOnSelect !== false && - onClose - ) { - onClose(); - } - break; - case "Enter": - // The Enter key should always close on select, except if overridden. - if (!isDisabled && closeOnSelect !== false && !isTrigger && onClose) { - onClose(); - } - break; - default: - if (!isTrigger) { - e.continuePropagation(); - } - - onKeyDown?.(e); - break; - } - }, - onKeyUp, - }); - - let {focusProps} = useFocus({onBlur, onFocus, onFocusChange}); - // @ts-ignore - let domProps = filterDOMProps(item.props); - - delete domProps.id; - // @ts-ignore - let linkProps = useLinkProps(item.props); - - return { - menuItemProps: { - ...ariaProps, - ...mergeProps( - domProps, - linkProps, - isTrigger ? {onFocus: itemProps.onFocus} : itemProps, - pressProps, - hoverProps, - keyboardProps, - focusProps, - { - onClick: chain(onClick, pressProps.onClick), - }, - ), - tabIndex: itemProps.tabIndex != null ? -1 : undefined, - }, - labelProps: { - id: labelId, - }, - descriptionProps: { - id: descriptionId, - }, - keyboardShortcutProps: { - id: keyboardId, - }, - isHovered, - isFocused, - isSelected, - isPressed, - isDisabled, - }; -} diff --git a/packages/hooks/use-aria-menu/src/use-menu.ts b/packages/hooks/use-aria-menu/src/use-menu.ts deleted file mode 100644 index 220b4fae05..0000000000 --- a/packages/hooks/use-aria-menu/src/use-menu.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-console */ -import {AriaMenuProps} from "@react-types/menu"; -import {DOMAttributes, Key, KeyboardDelegate, KeyboardEvents} from "@react-types/shared"; -import {filterDOMProps, mergeProps} from "@react-aria/utils"; -import {RefObject, KeyboardEvent as ReactKeyboardEvent} from "react"; -import {TreeState} from "@react-stately/tree"; -import {useSelectableList} from "@react-aria/selection"; - -export interface MenuAria { - /** Props for the menu element. */ - menuProps: DOMAttributes; -} - -export interface AriaMenuOptions extends Omit, "children">, KeyboardEvents { - /** Whether the menu uses virtual scrolling. */ - isVirtualized?: boolean; - - /** - * An optional keyboard delegate implementation for type to select, - * to override the default. - */ - keyboardDelegate?: KeyboardDelegate; -} - -interface MenuData { - onClose?: () => void; - onAction?: (key: Key, item: any) => void; -} - -export const menuData = new WeakMap, MenuData>(); - -/** - * Provides the behavior and accessibility implementation for a menu component. - * A menu displays a list of actions or options that a user can choose. - * @param props - Props for the menu. - * @param state - State for the menu, as returned by `useListState`. - */ -export function useMenu( - props: AriaMenuOptions, - state: TreeState, - ref: RefObject, -): MenuAria { - let {shouldFocusWrap = true, onKeyDown, onKeyUp, ...otherProps} = props; - - if (!props["aria-label"] && !props["aria-labelledby"]) { - console.warn("An aria-label or aria-labelledby prop is required for accessibility."); - } - - let domProps = filterDOMProps(props, {labelable: true}); - let {listProps} = useSelectableList({ - ...otherProps, - ref, - selectionManager: state.selectionManager, - collection: state.collection, - disabledKeys: state.disabledKeys, - shouldFocusWrap, - linkBehavior: "override", - }); - - menuData.set(state, { - onClose: props.onClose, - onAction: props.onAction, - }); - - return { - menuProps: mergeProps( - domProps, - {onKeyDown, onKeyUp}, - { - role: "menu", - ...listProps, - onKeyDown: (event: ReactKeyboardEvent) => { - // don't clear the menu selected keys if the user is presses escape since escape closes the menu - if (event.key !== "Escape") { - if (listProps.onKeyDown) { - listProps.onKeyDown(event); - } - } - }, - }, - ), - }; -} diff --git a/packages/hooks/use-aria-menu/tsconfig.json b/packages/hooks/use-aria-menu/tsconfig.json deleted file mode 100644 index 46e3b466c2..0000000000 --- a/packages/hooks/use-aria-menu/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "include": ["src", "index.ts"] -} diff --git a/packages/hooks/use-aria-modal-overlay/src/index.ts b/packages/hooks/use-aria-modal-overlay/src/index.ts index 87d3b4cae8..4cc67a9a0b 100644 --- a/packages/hooks/use-aria-modal-overlay/src/index.ts +++ b/packages/hooks/use-aria-modal-overlay/src/index.ts @@ -12,6 +12,14 @@ import {RefObject, useEffect} from "react"; export interface UseAriaModalOverlayProps extends AriaModalOverlayProps {} +/** + * Provides the behavior and accessibility implementation for a modal component. + * A modal is an overlay element which blocks interaction with elements outside it. + * + * This is a modified version from https://vscode.dev/github/adobe/react-spectrum/blob/main/packages/%40react-aria/overlays/src/useModalOverlay.ts#L46 + * + * This implementation disables the prevent scroll when `shouldBlockScroll` prop is false. + */ export function useAriaModalOverlay( props: UseAriaModalOverlayProps & { shouldBlockScroll?: boolean; diff --git a/packages/hooks/use-aria-toggle-button/CHANGELOG.md b/packages/hooks/use-aria-toggle-button/CHANGELOG.md deleted file mode 100644 index 7094e10cb5..0000000000 --- a/packages/hooks/use-aria-toggle-button/CHANGELOG.md +++ /dev/null @@ -1,240 +0,0 @@ -# @nextui-org/use-aria-toggle-button - -## 2.2.2 - -### Patch Changes - -- [#4258](https://github.com/nextui-org/nextui/pull/4258) [`1031e98`](https://github.com/nextui-org/nextui/commit/1031e985b71e69b8a7189ea049b9616257f820b3) Thanks [@wingkwong](https://github.com/wingkwong)! - sync with upstream RA versions - -- Updated dependencies [[`1031e98`](https://github.com/nextui-org/nextui/commit/1031e985b71e69b8a7189ea049b9616257f820b3)]: - - @nextui-org/use-aria-button@2.2.2 - -## 2.2.1 - -### Patch Changes - -- [`d6eee4a`](https://github.com/nextui-org/nextui/commit/d6eee4a8767556152f47f06dcf04940951abc5af) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - v2.6.2 - -- Updated dependencies [[`d6eee4a`](https://github.com/nextui-org/nextui/commit/d6eee4a8767556152f47f06dcf04940951abc5af)]: - - @nextui-org/use-aria-button@2.2.1 - -## 2.2.0 - -### Minor Changes - -- [`5786897`](https://github.com/nextui-org/nextui/commit/5786897b9950d95c12351dacd2fb41bb1e298201) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - This release includes several improvements and bug fixes: - - - Updated react-aria version across all components - - Improved Drawer styles and transitions - - Fixed missing peer dependencies for framer-motion - - Fixed menu item classNames functionality - - Added isClearable prop to Textarea component - - Fixed label placement issues in Input and Select components - - Improved table keyboard navigation with new isKeyboardNavigationDisabled prop - - Fixed UI sliding issues with helper wrapper in Input and Select - - Updated use-image hook to avoid Next.js hydration issues - - Replaced RTL-specific styles with logical properties - - Fixed textarea label squish issue - - Bumped tailwind-merge version - - Applied tw nested group fixes - - Fixed fullWidth variant in input and select components - - Moved circular-progress tv to progress - - Changed ListboxItem key to optional - - Fixed autocomplete clear button behavior - - Updated Select label placement logic - - Added missing framer-motion peer dependencies - - Removed layoutNode prop from Table due to react-aria update - - Virtualization added to Autocomplete - -### Patch Changes - -- [#4226](https://github.com/nextui-org/nextui/pull/4226) [`6c0213d`](https://github.com/nextui-org/nextui/commit/6c0213dfc805aa3c793763c0b25f53b2b80c24dc) Thanks [@wingkwong](https://github.com/wingkwong)! - bump `@react-aria/utils` version (#4212) - -- Updated dependencies [[`6c0213d`](https://github.com/nextui-org/nextui/commit/6c0213dfc805aa3c793763c0b25f53b2b80c24dc), [`5786897`](https://github.com/nextui-org/nextui/commit/5786897b9950d95c12351dacd2fb41bb1e298201)]: - - @nextui-org/use-aria-button@2.2.0 - -## 2.1.0-beta.8 - -### Patch Changes - -- [`9869f2b91`](https://github.com/nextui-org/nextui/commit/9869f2b91d0829f9c7f0500ba05745707820bf27) Thanks [@wingkwong](https://github.com/wingkwong)! - bump version - -- Updated dependencies [[`9869f2b91`](https://github.com/nextui-org/nextui/commit/9869f2b91d0829f9c7f0500ba05745707820bf27)]: - - @nextui-org/use-aria-button@2.1.0-beta.8 - -## 2.1.0-beta.7 - -### Patch Changes - -- [#3036](https://github.com/nextui-org/nextui/pull/3036) [`eafdb7d47`](https://github.com/nextui-org/nextui/commit/eafdb7d475a7fcaa7671af77e86fcdf62f14ae00) Thanks [@ryo-manba](https://github.com/ryo-manba)! - update react-aria version - -- Updated dependencies [[`eafdb7d47`](https://github.com/nextui-org/nextui/commit/eafdb7d475a7fcaa7671af77e86fcdf62f14ae00)]: - - @nextui-org/use-aria-button@2.1.0-beta.7 - -## 2.1.0-beta.6 - -### Patch Changes - -- [#4092](https://github.com/nextui-org/nextui/pull/4092) [`528668db8`](https://github.com/nextui-org/nextui/commit/528668db85b98b46473cb1e214780b7468cdadba) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Test new runner - -- Updated dependencies [[`528668db8`](https://github.com/nextui-org/nextui/commit/528668db85b98b46473cb1e214780b7468cdadba)]: - - @nextui-org/use-aria-button@2.1.0-beta.6 - -## 2.1.0-beta.5 - -### Patch Changes - -- [#4086](https://github.com/nextui-org/nextui/pull/4086) [`f69fe47b5`](https://github.com/nextui-org/nextui/commit/f69fe47b5b8f6f3a77a7a8c20d8715263fa32acb) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Pnpm clean - -- Updated dependencies [[`f69fe47b5`](https://github.com/nextui-org/nextui/commit/f69fe47b5b8f6f3a77a7a8c20d8715263fa32acb)]: - - @nextui-org/use-aria-button@2.1.0-beta.5 - -## 2.1.0-beta.4 - -### Patch Changes - -- [#4083](https://github.com/nextui-org/nextui/pull/4083) [`35058262c`](https://github.com/nextui-org/nextui/commit/35058262c61628fb42907f529c4417886aa12bb2) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Fix build - -- Updated dependencies [[`35058262c`](https://github.com/nextui-org/nextui/commit/35058262c61628fb42907f529c4417886aa12bb2)]: - - @nextui-org/use-aria-button@2.1.0-beta.4 - -## 2.1.0-beta.3 - -### Patch Changes - -- [#4010](https://github.com/nextui-org/nextui/pull/4010) [`ef432eb53`](https://github.com/nextui-org/nextui/commit/ef432eb539714fded6cab86a2185956fb103e0df) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - framer-motion alpha version added - -- Updated dependencies [[`ef432eb53`](https://github.com/nextui-org/nextui/commit/ef432eb539714fded6cab86a2185956fb103e0df)]: - - @nextui-org/use-aria-button@2.1.0-beta.3 - -## 2.1.0-beta.2 - -### Patch Changes - -- [#4008](https://github.com/nextui-org/nextui/pull/4008) [`7c1c0dd8f`](https://github.com/nextui-org/nextui/commit/7c1c0dd8fef3ea72996c1095b919574c4b7f9b89) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - React 19 added to peerDeps - -- Updated dependencies [[`7c1c0dd8f`](https://github.com/nextui-org/nextui/commit/7c1c0dd8fef3ea72996c1095b919574c4b7f9b89)]: - - @nextui-org/use-aria-button@2.1.0-beta.2 - -## 2.1.0-beta.1 - -### Patch Changes - -- [#3990](https://github.com/nextui-org/nextui/pull/3990) [`cb5bc4c74`](https://github.com/nextui-org/nextui/commit/cb5bc4c74f00caaee80dca89c1f02038db315b85) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Beta 1 - -- Updated dependencies [[`cb5bc4c74`](https://github.com/nextui-org/nextui/commit/cb5bc4c74f00caaee80dca89c1f02038db315b85)]: - - @nextui-org/use-aria-button@2.1.0-beta.1 - -## 2.1.0-beta.0 - -### Minor Changes - -- [#3732](https://github.com/nextui-org/nextui/pull/3732) [`67ea2f65e`](https://github.com/nextui-org/nextui/commit/67ea2f65e17f913bdffae4690586a6ae202c8f7d) Thanks [@ryo-manba](https://github.com/ryo-manba)! - update react-aria version - -### Patch Changes - -- Updated dependencies [[`67ea2f65e`](https://github.com/nextui-org/nextui/commit/67ea2f65e17f913bdffae4690586a6ae202c8f7d)]: - - @nextui-org/use-aria-button@2.1.0-beta.0 - -## 2.0.10 - -### Patch Changes - -- [#3512](https://github.com/nextui-org/nextui/pull/3512) [`2d2d300a1`](https://github.com/nextui-org/nextui/commit/2d2d300a12dbe20ca7ebd125daf3dce74efcbf34) Thanks [@wingkwong](https://github.com/wingkwong)! - fix conflicting versions in npm - -- Updated dependencies [[`2d2d300a1`](https://github.com/nextui-org/nextui/commit/2d2d300a12dbe20ca7ebd125daf3dce74efcbf34)]: - - @nextui-org/use-aria-button@2.0.10 - -## 2.0.9 - -### Patch Changes - -- [#3240](https://github.com/nextui-org/nextui/pull/3240) [`47c2472fb`](https://github.com/nextui-org/nextui/commit/47c2472fb22bfe1c0c357b5ba12e5606eba0d65b) Thanks [@wingkwong](https://github.com/wingkwong)! - bump react-aria dependencies - -- Updated dependencies [[`47c2472fb`](https://github.com/nextui-org/nextui/commit/47c2472fb22bfe1c0c357b5ba12e5606eba0d65b)]: - - @nextui-org/use-aria-button@2.0.9 - -## 2.0.8 - -### Patch Changes - -- [#3119](https://github.com/nextui-org/nextui/pull/3119) [`685995a12`](https://github.com/nextui-org/nextui/commit/685995a125cc3db26c6adb67ed9f7245b87e792a) Thanks [@wingkwong](https://github.com/wingkwong)! - bump `@react-aria/utils` version to `3.24.1` and bump `@react-types/shared` to `3.23.1` - -- Updated dependencies [[`685995a12`](https://github.com/nextui-org/nextui/commit/685995a125cc3db26c6adb67ed9f7245b87e792a)]: - - @nextui-org/use-aria-button@2.0.8 - -## 2.0.7 - -### Patch Changes - -- [#2618](https://github.com/nextui-org/nextui/pull/2618) [`dc0bcf13a`](https://github.com/nextui-org/nextui/commit/dc0bcf13a5e9aa0450938bcca47cd4c696066f14) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - v2.3.0 - -- [#2618](https://github.com/nextui-org/nextui/pull/2618) [`dc0bcf13a`](https://github.com/nextui-org/nextui/commit/dc0bcf13a5e9aa0450938bcca47cd4c696066f14) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - - Calendar component added - - objectToDeps function applied all across components - - `useMeasure` hook added - - `useIntersectionObserver` hook added - - `framer-transitions` renamed to `framer-utils` - - `ResizablePanel` component added to `framer-utils` - - `test-utils` updated -- Updated dependencies [[`dc0bcf13a`](https://github.com/nextui-org/nextui/commit/dc0bcf13a5e9aa0450938bcca47cd4c696066f14), [`dc0bcf13a`](https://github.com/nextui-org/nextui/commit/dc0bcf13a5e9aa0450938bcca47cd4c696066f14)]: - - @nextui-org/use-aria-button@2.0.7 - -## 2.0.6 - -### Patch Changes - -- [`25e86fb41`](https://github.com/nextui-org/nextui/commit/25e86fb41770d3cdae6dfdb79306b78fa02d8187) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - New version v2.2.0 - -- Updated dependencies [[`25e86fb41`](https://github.com/nextui-org/nextui/commit/25e86fb41770d3cdae6dfdb79306b78fa02d8187)]: - - @nextui-org/use-aria-button@2.0.6 - -## 2.0.5 - -### Patch Changes - -- [#1600](https://github.com/nextui-org/nextui/pull/1600) [`b1b30b797`](https://github.com/nextui-org/nextui/commit/b1b30b7976f1d6652808fbf12ffde044f0861572) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Fix npm deploy - -- Updated dependencies [[`b1b30b797`](https://github.com/nextui-org/nextui/commit/b1b30b7976f1d6652808fbf12ffde044f0861572)]: - - @nextui-org/use-aria-button@2.0.5 - -## 2.0.4 - -### Patch Changes - -- [#1589](https://github.com/nextui-org/nextui/pull/1589) [`1612532ee`](https://github.com/nextui-org/nextui/commit/1612532eeeabbc49165546b1a2e7aebf89e7a1c2) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - React aria packages upgraded - -- Updated dependencies [[`1612532ee`](https://github.com/nextui-org/nextui/commit/1612532eeeabbc49165546b1a2e7aebf89e7a1c2)]: - - @nextui-org/use-aria-button@2.0.4 - -## 2.0.3 - -### Patch Changes - -- [#1359](https://github.com/nextui-org/nextui/pull/1359) [`a30cec48`](https://github.com/nextui-org/nextui/commit/a30cec4810988fb1962f3a61e0fc0362de08b171) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - \n - - - react-aria packages upgraded to the latest version - - image storybooks fixed - - other bug fixes.. - -- Updated dependencies [[`a30cec48`](https://github.com/nextui-org/nextui/commit/a30cec4810988fb1962f3a61e0fc0362de08b171)]: - - @nextui-org/use-aria-button@2.0.3 - -## 2.0.2 - -### Patch Changes - -- [`e3e13a09`](https://github.com/nextui-org/nextui/commit/e3e13a095f2347ff279c85e6a5d3798f36c6533f) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - New package created to exports system RSC-compatible functions - Component exports changed to named exports -- Updated dependencies [[`e3e13a09`](https://github.com/nextui-org/nextui/commit/e3e13a095f2347ff279c85e6a5d3798f36c6533f)]: - - @nextui-org/use-aria-button@2.0.2 - -## 2.0.1 - -### Patch Changes - -- [`e940ec06`](https://github.com/nextui-org/nextui/commit/e940ec06ac5e46340d5956fb7c455a6ab3de3140) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Introducing NextUI v2.0 - -- [`e940ec06`](https://github.com/nextui-org/nextui/commit/e940ec06ac5e46340d5956fb7c455a6ab3de3140) Thanks [@jrgarciadev](https://github.com/jrgarciadev)! - Introducing v2 - Readmes updated - -- Updated dependencies [[`e940ec06`](https://github.com/nextui-org/nextui/commit/e940ec06ac5e46340d5956fb7c455a6ab3de3140), [`e940ec06`](https://github.com/nextui-org/nextui/commit/e940ec06ac5e46340d5956fb7c455a6ab3de3140)]: - - @nextui-org/use-aria-button@2.0.1 diff --git a/packages/hooks/use-aria-toggle-button/README.md b/packages/hooks/use-aria-toggle-button/README.md deleted file mode 100644 index 5cfeb3c336..0000000000 --- a/packages/hooks/use-aria-toggle-button/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# @nextui-org/use-aria-toggle-button - -A Quick description of the component - -> This is an internal utility, not intended for public usage. - -## Installation - -```sh -yarn add @nextui-org/use-aria-toggle-button -# or -npm i @nextui-org/use-aria-toggle-button -``` - -## Contribution - -Yes please! See the -[contributing guidelines](https://github.com/nextui-org/nextui/blob/master/CONTRIBUTING.md) -for details. - -## License - -This project is licensed under the terms of the -[MIT license](https://github.com/nextui-org/nextui/blob/master/LICENSE). diff --git a/packages/hooks/use-aria-toggle-button/package.json b/packages/hooks/use-aria-toggle-button/package.json deleted file mode 100644 index 69a93ff39a..0000000000 --- a/packages/hooks/use-aria-toggle-button/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@nextui-org/use-aria-toggle-button", - "version": "2.2.2", - "description": "Internal hook to handle button a11y and events, this is based on react-aria button hook but without the onClick warning", - "keywords": [ - "use-aria-toggle-button" - ], - "author": "Junior Garcia ", - "homepage": "https://nextui.org", - "license": "MIT", - "main": "src/index.ts", - "sideEffects": false, - "files": [ - "dist" - ], - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/nextui-org/nextui.git", - "directory": "packages/hooks/use-aria-toggle-button" - }, - "bugs": { - "url": "https://github.com/nextui-org/nextui/issues" - }, - "scripts": { - "build": "tsup src --dts", - "build:fast": "tsup src", - "dev": "pnpm build:fast --watch", - "clean": "rimraf dist .turbo", - "typecheck": "tsc --noEmit", - "prepack": "clean-package", - "postpack": "clean-package restore" - }, - "peerDependencies": { - "react": ">=18 || >=19.0.0-rc.0" - }, - "dependencies": { - "@nextui-org/use-aria-button": "workspace:*", - "@react-aria/utils": "3.26.0", - "@react-stately/toggle": "3.8.0", - "@react-types/button": "3.10.1", - "@react-types/shared": "3.26.0" - }, - "devDependencies": { - "clean-package": "2.2.0", - "react": "^18.0.0" - }, - "clean-package": "../../../clean-package.config.json", - "tsup": { - "clean": true, - "target": "es2019", - "format": [ - "cjs", - "esm" - ] - } -} \ No newline at end of file diff --git a/packages/hooks/use-aria-toggle-button/src/index.ts b/packages/hooks/use-aria-toggle-button/src/index.ts deleted file mode 100644 index ca30aeee56..0000000000 --- a/packages/hooks/use-aria-toggle-button/src/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2020 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ - -import { - AnchorHTMLAttributes, - ButtonHTMLAttributes, - ElementType, - HTMLAttributes, - InputHTMLAttributes, - RefObject, -} from "react"; -import {AriaToggleButtonProps} from "@react-types/button"; -import {chain} from "@react-aria/utils"; -import {DOMAttributes} from "@react-types/shared"; -import {mergeProps} from "@react-aria/utils"; -import {ToggleState} from "@react-stately/toggle"; -import {ButtonAria, useAriaButton} from "@nextui-org/use-aria-button"; - -export type {AriaToggleButtonProps}; - -// Order with overrides is important: 'button' should be default -export function useAriaToggleButton( - props: AriaToggleButtonProps<"button">, - state: ToggleState, - ref: RefObject, -): ButtonAria>; -export function useAriaToggleButton( - props: AriaToggleButtonProps<"a">, - state: ToggleState, - ref: RefObject, -): ButtonAria>; -export function useAriaToggleButton( - props: AriaToggleButtonProps<"div">, - state: ToggleState, - ref: RefObject, -): ButtonAria>; -export function useAriaToggleButton( - props: AriaToggleButtonProps<"input">, - state: ToggleState, - ref: RefObject, -): ButtonAria>; -export function useAriaToggleButton( - props: AriaToggleButtonProps<"span">, - state: ToggleState, - ref: RefObject, -): ButtonAria>; -export function useAriaToggleButton( - props: AriaToggleButtonProps, - state: ToggleState, - ref: RefObject, -): ButtonAria; -/** - * Provides the behavior and accessibility implementation for a toggle button component. - * ToggleButtons allow users to toggle a selection on or off, for example switching between two states or modes. - */ -export function useAriaToggleButton( - props: AriaToggleButtonProps, - state: ToggleState, - ref: RefObject, -): ButtonAria> { - const {isSelected} = state; - const {isPressed, buttonProps} = useAriaButton( - { - ...props, - onPress: chain(state.toggle, props.onPress), - }, - ref, - ); - - return { - isPressed, - buttonProps: mergeProps(buttonProps, { - "aria-pressed": isSelected, - }), - }; -} diff --git a/packages/hooks/use-aria-toggle-button/tsconfig.json b/packages/hooks/use-aria-toggle-button/tsconfig.json deleted file mode 100644 index 46e3b466c2..0000000000 --- a/packages/hooks/use-aria-toggle-button/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "include": ["src", "index.ts"] -} diff --git a/packages/utilities/aria-utils/src/overlays/ariaHideOutside.ts b/packages/utilities/aria-utils/src/overlays/ariaHideOutside.ts index e38956efe6..1066b0470b 100644 --- a/packages/utilities/aria-utils/src/overlays/ariaHideOutside.ts +++ b/packages/utilities/aria-utils/src/overlays/ariaHideOutside.ts @@ -5,7 +5,13 @@ // Keeps a ref count of all hidden elements. Added to when hiding an element, and // subtracted from when showing it again. When it reaches zero, aria-hidden is removed. let refCountMap = new WeakMap(); -let observerStack: any = []; + +interface ObserverWrapper { + observe: () => void; + disconnect: () => void; +} + +let observerStack: Array = []; /** * Hides all elements in the DOM outside the given targets from screen readers using aria-hidden, @@ -29,15 +35,15 @@ export function ariaHideOutside(targets: Element[], root = document.body) { } let acceptNode = (node: Element) => { - const parentElement = node.parentElement as HTMLElement; - // Skip this node and its children if it is one of the target nodes, or a live announcer. // Also skip children of already hidden nodes, as aria-hidden is recursive. An exception is // made for elements with role="row" since VoiceOver on iOS has issues hiding elements with role="row". // For that case we want to hide the cells inside as well (https://bugs.webkit.org/show_bug.cgi?id=222623). if ( visibleNodes.has(node) || - (hiddenNodes.has(parentElement) && parentElement.getAttribute("role") !== "row") + (node.parentElement && + hiddenNodes.has(node.parentElement) && + node.parentElement.getAttribute("role") !== "row") ) { return NodeFilter.FILTER_REJECT; } @@ -51,7 +57,6 @@ export function ariaHideOutside(targets: Element[], root = document.body) { return NodeFilter.FILTER_ACCEPT; }; - let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {acceptNode}); // TreeWalker does not include the root. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc45050dad..b8977ba878 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1973,9 +1973,6 @@ importers: '@nextui-org/shared-utils': specifier: workspace:* version: link:../../utilities/shared-utils - '@nextui-org/use-aria-menu': - specifier: workspace:* - version: link:../../hooks/use-aria-menu '@nextui-org/use-is-mobile': specifier: workspace:* version: link:../../hooks/use-is-mobile @@ -2128,12 +2125,12 @@ importers: '@nextui-org/shared-utils': specifier: workspace:* version: link:../../utilities/shared-utils - '@nextui-org/use-aria-toggle-button': - specifier: workspace:* - version: link:../../hooks/use-aria-toggle-button '@nextui-org/use-scroll-position': specifier: workspace:* version: link:../../hooks/use-scroll-position + '@react-aria/button': + specifier: 3.11.0 + version: 3.11.0(react@18.2.0) '@react-aria/focus': specifier: 3.19.0 version: 3.19.0(react@18.2.0) @@ -3321,7 +3318,7 @@ importers: version: 18.2.0 tailwind-variants: specifier: ^0.1.20 - version: 0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3))) + version: 0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5))) packages/core/theme: dependencies: @@ -3348,7 +3345,7 @@ importers: version: 2.5.4 tailwind-variants: specifier: ^0.1.20 - version: 0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3))) + version: 0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5))) devDependencies: '@types/color': specifier: ^3.0.3 @@ -3361,7 +3358,7 @@ importers: version: 2.2.0 tailwindcss: specifier: ^3.4.0 - version: 3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3)) + version: 3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5)) packages/hooks/use-aria-accordion: dependencies: @@ -3418,6 +3415,9 @@ importers: packages/hooks/use-aria-button: dependencies: + '@nextui-org/shared-utils': + specifier: workspace:* + version: link:../../utilities/shared-utils '@react-aria/focus': specifier: 3.19.0 version: 3.19.0(react@18.2.0) @@ -3443,6 +3443,9 @@ importers: packages/hooks/use-aria-link: dependencies: + '@nextui-org/shared-utils': + specifier: workspace:* + version: link:../../utilities/shared-utils '@react-aria/focus': specifier: 3.19.0 version: 3.19.0(react@18.2.0) @@ -3466,46 +3469,6 @@ importers: specifier: 18.2.0 version: 18.2.0 - packages/hooks/use-aria-menu: - dependencies: - '@react-aria/i18n': - specifier: 3.12.4 - version: 3.12.4(react@18.2.0) - '@react-aria/interactions': - specifier: 3.22.5 - version: 3.22.5(react@18.2.0) - '@react-aria/menu': - specifier: 3.16.0 - version: 3.16.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@react-aria/selection': - specifier: 3.21.0 - version: 3.21.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@react-aria/utils': - specifier: 3.26.0 - version: 3.26.0(react@18.2.0) - '@react-stately/collections': - specifier: 3.12.0 - version: 3.12.0(react@18.2.0) - '@react-stately/tree': - specifier: 3.8.6 - version: 3.8.6(react@18.2.0) - '@react-types/menu': - specifier: 3.9.13 - version: 3.9.13(react@18.2.0) - '@react-types/shared': - specifier: 3.26.0 - version: 3.26.0(react@18.2.0) - react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - clean-package: - specifier: 2.2.0 - version: 2.2.0 - react: - specifier: 18.2.0 - version: 18.2.0 - packages/hooks/use-aria-modal-overlay: dependencies: '@react-aria/overlays': @@ -3586,31 +3549,6 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) - packages/hooks/use-aria-toggle-button: - dependencies: - '@nextui-org/use-aria-button': - specifier: workspace:* - version: link:../use-aria-button - '@react-aria/utils': - specifier: 3.26.0 - version: 3.26.0(react@18.2.0) - '@react-stately/toggle': - specifier: 3.8.0 - version: 3.8.0(react@18.2.0) - '@react-types/button': - specifier: 3.10.1 - version: 3.10.1(react@18.2.0) - '@react-types/shared': - specifier: 3.26.0 - version: 3.26.0(react@18.2.0) - devDependencies: - clean-package: - specifier: 2.2.0 - version: 2.2.0 - react: - specifier: 18.2.0 - version: 18.2.0 - packages/hooks/use-callback-ref: dependencies: '@nextui-org/use-safe-layout-effect': @@ -26226,6 +26164,14 @@ snapshots: postcss: 8.4.49 ts-node: 10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5) + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5)): + dependencies: + lilconfig: 3.1.2 + yaml: 2.6.1 + optionalDependencies: + postcss: 8.4.49 + ts-node: 10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5) + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.2.5)(typescript@5.6.3)): dependencies: lilconfig: 3.1.2 @@ -27777,10 +27723,10 @@ snapshots: tailwind-merge: 1.14.0 tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.2.5)(typescript@5.6.3)) - tailwind-variants@0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3))): + tailwind-variants@0.1.20(tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5))): dependencies: tailwind-merge: 1.14.0 - tailwindcss: 3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3)) + tailwindcss: 3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5)) tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.2.5)(typescript@5.6.3)): dependencies: @@ -27809,6 +27755,33 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.49 + postcss-import: 15.1.0(postcss@8.4.49) + postcss-js: 4.0.1(postcss@8.4.49) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@15.14.9)(typescript@4.9.5)) + postcss-nested: 6.2.0(postcss@8.4.49) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + tailwindcss@3.4.15(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.15))(@types/node@20.5.1)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 @@ -27896,14 +27869,14 @@ snapshots: '@swc/core': 1.9.2(@swc/helpers@0.5.15) esbuild: 0.15.18 - terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.15.18)(webpack-cli@3.3.12)): + terser-webpack-plugin@5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack-cli@3.3.12(webpack@5.96.1))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 - webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.15.18)(webpack-cli@3.3.12) + webpack: 5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack-cli@3.3.12(webpack@5.96.1)) optionalDependencies: '@swc/core': 1.9.2(@swc/helpers@0.5.15) esbuild: 0.21.5 @@ -28710,7 +28683,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.15.18)(webpack-cli@3.3.12)) + terser-webpack-plugin: 5.3.10(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack@5.96.1(@swc/core@1.9.2(@swc/helpers@0.5.15))(esbuild@0.21.5)(webpack-cli@3.3.12(webpack@5.96.1))) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: