diff --git a/.changeset/witty-socks-bathe.md b/.changeset/witty-socks-bathe.md new file mode 100644 index 0000000000..ff37b1abd8 --- /dev/null +++ b/.changeset/witty-socks-bathe.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/theme": patch +--- + +add missing `data-[hover=true]:` for ghost button with danger color diff --git a/apps/docs/app/examples/perf/page.tsx b/apps/docs/app/examples/perf/page.tsx index cc70cf7c80..79ab457b0a 100644 --- a/apps/docs/app/examples/perf/page.tsx +++ b/apps/docs/app/examples/perf/page.tsx @@ -106,7 +106,7 @@ const MyInput = extendVariants(Input, { "focus-within:bg-zinc-100", "data-[hover=true]:border-zinc-600", "data-[hover=true]:bg-zinc-100", - "group-data-[focus=true]/input:border-zinc-600", + "group-data-[focus=true]:border-zinc-600", // dark theme "dark:bg-zinc-900", "dark:border-zinc-800", diff --git a/apps/docs/components/marketing/hero/floating-components.tsx b/apps/docs/components/marketing/hero/floating-components.tsx index a50b39ca47..ef7baec19f 100644 --- a/apps/docs/components/marketing/hero/floating-components.tsx +++ b/apps/docs/components/marketing/hero/floating-components.tsx @@ -110,7 +110,6 @@ export const FloatingComponents: React.FC<{}> = () => { content="Developers love Next.js" isOpen={!isTablet} placement="top" - shouldBlockScroll={false} style={{ zIndex: 39, }} diff --git a/apps/docs/components/theme-switch.tsx b/apps/docs/components/theme-switch.tsx index 5554dbe3ef..33da930e3c 100644 --- a/apps/docs/components/theme-switch.tsx +++ b/apps/docs/components/theme-switch.tsx @@ -57,7 +57,7 @@ export const ThemeSwitch: FC = ({className, classNames}) => { "bg-transparent", "rounded-lg", "flex items-center justify-center", - "group-data-[selected=true]/toggle:bg-transparent", + "group-data-[selected=true]:bg-transparent", "!text-default-600 dark:!text-default-500", "pt-px", "px-0", diff --git a/apps/docs/content/components/input/custom-styles.ts b/apps/docs/content/components/input/custom-styles.ts index 5b8d511c3f..3908b17561 100644 --- a/apps/docs/content/components/input/custom-styles.ts +++ b/apps/docs/content/components/input/custom-styles.ts @@ -52,8 +52,8 @@ export default function App() { "backdrop-saturate-200", "hover:bg-default-200/70", "dark:hover:bg-default/70", - "group-data-[focus=true]/input:bg-default-200/50", - "dark:group-data-[focus=true]/input:bg-default/60", + "group-data-[focus=true]:bg-default-200/50", + "dark:group-data-[focus=true]:bg-default/60", "!cursor-text", ], }} diff --git a/apps/docs/content/components/select/custom-styles.ts b/apps/docs/content/components/select/custom-styles.ts index bd7b963f58..ae2db45e8a 100644 --- a/apps/docs/content/components/select/custom-styles.ts +++ b/apps/docs/content/components/select/custom-styles.ts @@ -212,7 +212,7 @@ export default function App() { className="max-w-xs" variant="bordered" classNames={{ - label: "group-data-[filled=true]/select:-translate-y-5", + label: "group-data-[filled=true]:-translate-y-5", trigger: "min-h-16", listboxWrapper: "max-h-[400px]", }} diff --git a/apps/docs/content/components/switch/custom-styles.ts b/apps/docs/content/components/switch/custom-styles.ts index 20537838f9..c4470a56e0 100644 --- a/apps/docs/content/components/switch/custom-styles.ts +++ b/apps/docs/content/components/switch/custom-styles.ts @@ -11,12 +11,12 @@ export default function App() { ), wrapper: "p-0 h-4 overflow-visible", thumb: cn("w-6 h-6 border-2 shadow-lg", - "group-data-[hover=true]/toggle:border-primary", + "group-data-[hover=true]:border-primary", //selected - "group-data-[selected=true]/toggle:ml-6", + "group-data-[selected=true]:ml-6", // pressed - "group-data-[pressed=true]/toggle:w-7", - "group-data-[selected]:group-data-[pressed]/toggle:ml-4", + "group-data-[pressed=true]:w-7", + "group-data-[selected]:group-data-[pressed]:ml-4", ), }} > diff --git a/apps/docs/content/customization/custom-variants/slots-component.ts b/apps/docs/content/customization/custom-variants/slots-component.ts index 1fd09f9273..c1fd3c86cd 100644 --- a/apps/docs/content/customization/custom-variants/slots-component.ts +++ b/apps/docs/content/customization/custom-variants/slots-component.ts @@ -47,7 +47,7 @@ const MyInput = extendVariants(Input, { "focus-within:bg-zinc-100", "data-[hover=true]:border-zinc-600", "data-[hover=true]:bg-zinc-100", - "group-data-[focus=true]/input:border-zinc-600", + "group-data-[focus=true]:border-zinc-600", "dark:bg-zinc-900", "dark:border-zinc-800", "dark:data-[hover=true]:bg-zinc-900", diff --git a/apps/docs/content/docs/customization/custom-variants.mdx b/apps/docs/content/docs/customization/custom-variants.mdx index 6d81ec297d..2c5b0314d5 100644 --- a/apps/docs/content/docs/customization/custom-variants.mdx +++ b/apps/docs/content/docs/customization/custom-variants.mdx @@ -133,7 +133,7 @@ const MyInput = extendVariants(Input, { "focus-within:bg-zinc-100", "data-[hover=true]:border-zinc-600", "data-[hover=true]:bg-zinc-100", - "group-data-[focus=true]/input:border-zinc-600", + "group-data-[focus=true]:border-zinc-600", // dark theme "dark:bg-zinc-900", "dark:border-zinc-800", diff --git a/packages/components/accordion/CHANGELOG.md b/packages/components/accordion/CHANGELOG.md index 70b0c7cff8..4f44a353a2 100644 --- a/packages/components/accordion/CHANGELOG.md +++ b/packages/components/accordion/CHANGELOG.md @@ -1,5 +1,13 @@ # @nextui-org/accordion +## 2.0.40 + +### Patch Changes + +- Updated dependencies [[`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/divider@2.0.32 + ## 2.0.39 ### Patch Changes diff --git a/packages/components/accordion/package.json b/packages/components/accordion/package.json index cc8e9432a6..4a16c9f627 100644 --- a/packages/components/accordion/package.json +++ b/packages/components/accordion/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/accordion", - "version": "2.0.39", + "version": "2.0.40", "description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.", "keywords": [ "react", diff --git a/packages/components/autocomplete/CHANGELOG.md b/packages/components/autocomplete/CHANGELOG.md index d2d3df93c5..77ddeded3b 100644 --- a/packages/components/autocomplete/CHANGELOG.md +++ b/packages/components/autocomplete/CHANGELOG.md @@ -1,5 +1,20 @@ # @nextui-org/autocomplete +## 2.1.7 + +### Patch Changes + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`4c01d1824`](https://github.com/nextui-org/nextui/commit/4c01d1824d4dde22d89232968a3a4c48fe04678f), [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/popover@2.1.29 + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/button@2.0.38 + - @nextui-org/input@2.2.5 + - @nextui-org/listbox@2.1.27 + - @nextui-org/scroll-shadow@2.1.20 + - @nextui-org/spinner@2.0.34 + ## 2.1.6 ### Patch Changes diff --git a/packages/components/autocomplete/package.json b/packages/components/autocomplete/package.json index aaf4d9b426..4982dad45a 100644 --- a/packages/components/autocomplete/package.json +++ b/packages/components/autocomplete/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/autocomplete", - "version": "2.1.6", + "version": "2.1.7", "description": "An autocomplete combines a text input with a listbox, allowing users to filter a list of options to items matching a query.", "keywords": [ "autocomplete" @@ -41,6 +41,7 @@ "react-dom": ">=18" }, "dependencies": { + "@nextui-org/aria-utils": "workspace:*", "@nextui-org/button": "workspace:*", "@nextui-org/input": "workspace:*", "@nextui-org/listbox": "workspace:*", diff --git a/packages/components/autocomplete/src/use-autocomplete.ts b/packages/components/autocomplete/src/use-autocomplete.ts index bb96df6505..d1cae053f3 100644 --- a/packages/components/autocomplete/src/use-autocomplete.ts +++ b/packages/components/autocomplete/src/use-autocomplete.ts @@ -18,6 +18,7 @@ import {chain, mergeProps} from "@react-aria/utils"; import {ButtonProps} from "@nextui-org/button"; import {AsyncLoadable, PressEvent} from "@react-types/shared"; import {useComboBox} from "@react-aria/combobox"; +import {ariaShouldCloseOnInteractOutside} from "@nextui-org/aria-utils"; interface Props extends Omit, keyof ComboBoxProps> { /** @@ -443,6 +444,9 @@ export function useAutocomplete(originalProps: UseAutocomplete ), }), }, + shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside + ? popoverProps.shouldCloseOnInteractOutside + : (element: Element) => ariaShouldCloseOnInteractOutside(element, inputWrapperRef, state), // when the popover is open, the focus should be on input instead of dialog // therefore, we skip dialog focus here disableDialogFocus: true, diff --git a/packages/components/date-picker/CHANGELOG.md b/packages/components/date-picker/CHANGELOG.md index e375bc6c93..bcc2096ee9 100644 --- a/packages/components/date-picker/CHANGELOG.md +++ b/packages/components/date-picker/CHANGELOG.md @@ -1,5 +1,18 @@ # @nextui-org/date-picker +## 2.1.8 + +### Patch Changes + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`4c01d1824`](https://github.com/nextui-org/nextui/commit/4c01d1824d4dde22d89232968a3a4c48fe04678f), [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/popover@2.1.29 + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/button@2.0.38 + - @nextui-org/calendar@2.0.12 + - @nextui-org/date-input@2.1.4 + ## 2.1.7 ### Patch Changes diff --git a/packages/components/date-picker/package.json b/packages/components/date-picker/package.json index a4ebcb8f4f..a2c281231c 100644 --- a/packages/components/date-picker/package.json +++ b/packages/components/date-picker/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/date-picker", - "version": "2.1.7", + "version": "2.1.8", "description": "A date picker combines a DateInput and a Calendar popover to allow users to enter or select a date and time value.", "keywords": [ "date-picker" @@ -41,6 +41,7 @@ }, "dependencies": { "@internationalized/date": "^3.5.4", + "@nextui-org/aria-utils": "workspace:*", "@nextui-org/button": "workspace:*", "@nextui-org/calendar": "workspace:*", "@nextui-org/date-input": "workspace:*", diff --git a/packages/components/date-picker/src/use-date-picker.ts b/packages/components/date-picker/src/use-date-picker.ts index aeb0337f04..5f7ebd0245 100644 --- a/packages/components/date-picker/src/use-date-picker.ts +++ b/packages/components/date-picker/src/use-date-picker.ts @@ -15,6 +15,7 @@ import {useDatePickerState} from "@react-stately/datepicker"; import {AriaDatePickerProps, useDatePicker as useAriaDatePicker} from "@react-aria/datepicker"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {mergeProps} from "@react-aria/utils"; +import {ariaShouldCloseOnInteractOutside} from "@nextui-org/aria-utils"; import {useDatePickerBase} from "./use-date-picker-base"; @@ -192,6 +193,9 @@ export function useDatePicker({ ), }), }, + shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside + ? popoverProps.shouldCloseOnInteractOutside + : (element: Element) => ariaShouldCloseOnInteractOutside(element, popoverTriggerRef, state), }; }; diff --git a/packages/components/date-picker/src/use-date-range-picker.ts b/packages/components/date-picker/src/use-date-range-picker.ts index 372bb6e323..6e45597178 100644 --- a/packages/components/date-picker/src/use-date-range-picker.ts +++ b/packages/components/date-picker/src/use-date-range-picker.ts @@ -21,6 +21,7 @@ import {useDateRangePicker as useAriaDateRangePicker} from "@react-aria/datepick import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {mergeProps} from "@react-aria/utils"; import {dateRangePicker, dateInput, cn} from "@nextui-org/theme"; +import {ariaShouldCloseOnInteractOutside} from "@nextui-org/aria-utils"; import {useDatePickerBase} from "./use-date-picker-base"; interface Props @@ -214,6 +215,10 @@ export function useDateRangePicker({ props.className, ), }), + shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside + ? popoverProps.shouldCloseOnInteractOutside + : (element: Element) => + ariaShouldCloseOnInteractOutside(element, popoverTriggerRef, state), }, } as PopoverProps; }; diff --git a/packages/components/dropdown/CHANGELOG.md b/packages/components/dropdown/CHANGELOG.md index 7c117d8ff8..3f59691259 100644 --- a/packages/components/dropdown/CHANGELOG.md +++ b/packages/components/dropdown/CHANGELOG.md @@ -1,5 +1,18 @@ # @nextui-org/dropdown +## 2.1.31 + +### 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) + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`4c01d1824`](https://github.com/nextui-org/nextui/commit/4c01d1824d4dde22d89232968a3a4c48fe04678f), [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/popover@2.1.29 + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/menu@2.0.30 + ## 2.1.30 ### Patch Changes diff --git a/packages/components/dropdown/__tests__/dropdown.test.tsx b/packages/components/dropdown/__tests__/dropdown.test.tsx index b719db3c0c..359e337116 100644 --- a/packages/components/dropdown/__tests__/dropdown.test.tsx +++ b/packages/components/dropdown/__tests__/dropdown.test.tsx @@ -796,7 +796,7 @@ describe("Keyboard interactions", () => { logSpy.mockRestore(); }); - it("should respect closeOnSelect setting of DropdownItem", async () => { + it("should respect closeOnSelect setting of DropdownItem (static)", async () => { const onOpenChange = jest.fn(); const wrapper = render( @@ -831,4 +831,51 @@ describe("Keyboard interactions", () => { expect(onOpenChange).toBeCalledTimes(2); }); }); + + it("should respect closeOnSelect setting of DropdownItem (dynamic)", async () => { + const onOpenChange = jest.fn(); + const items = [ + { + key: "new", + label: "New file", + }, + { + key: "copy", + label: "Copy link", + }, + ]; + const wrapper = render( + + + + + + {(item) => ( + + {item.label} + + )} + + , + ); + + let triggerButton = wrapper.getByTestId("trigger-test"); + + act(() => { + triggerButton.click(); + }); + expect(onOpenChange).toBeCalledTimes(1); + + let menuItems = wrapper.getAllByRole("menuitem"); + + await act(async () => { + await userEvent.click(menuItems[0]); + expect(onOpenChange).toBeCalledTimes(1); + }); + + await act(async () => { + await userEvent.click(menuItems[1]); + expect(onOpenChange).toBeCalledTimes(2); + }); + }); }); diff --git a/packages/components/dropdown/package.json b/packages/components/dropdown/package.json index c31c63efb2..7542abbf0f 100644 --- a/packages/components/dropdown/package.json +++ b/packages/components/dropdown/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/dropdown", - "version": "2.1.30", + "version": "2.1.31", "description": "A dropdown displays a list of actions or options that a user can choose.", "keywords": [ "dropdown" @@ -41,6 +41,7 @@ "react-dom": ">=18" }, "dependencies": { + "@nextui-org/aria-utils": "workspace:*", "@nextui-org/menu": "workspace:*", "@nextui-org/popover": "workspace:*", "@nextui-org/react-utils": "workspace:*", diff --git a/packages/components/dropdown/src/use-dropdown.ts b/packages/components/dropdown/src/use-dropdown.ts index 0ff834f135..cff1cc1b9e 100644 --- a/packages/components/dropdown/src/use-dropdown.ts +++ b/packages/components/dropdown/src/use-dropdown.ts @@ -9,9 +9,11 @@ import {useMenuTrigger} from "@react-aria/menu"; import {dropdown} from "@nextui-org/theme"; import {clsx} from "@nextui-org/shared-utils"; import {ReactRef, mergeRefs} from "@nextui-org/react-utils"; +import {ariaShouldCloseOnInteractOutside} from "@nextui-org/aria-utils"; import {useMemo, useRef} from "react"; import {mergeProps} from "@react-aria/utils"; import {MenuProps} from "@nextui-org/menu"; +import {CollectionElement} from "@react-types/shared"; interface Props extends HTMLNextUIProps<"div"> { /** @@ -41,6 +43,40 @@ interface Props extends HTMLNextUIProps<"div"> { export type UseDropdownProps = Props & Omit; +const getMenuItem = (props: Partial> | undefined, key: string) => { + if (props) { + const mergedChildren = Array.isArray(props.children) + ? props.children + : [...(props?.items || [])]; + + if (mergedChildren && mergedChildren.length) { + const item = ((mergedChildren as CollectionElement[]).find((item) => { + if (item.key === key) { + return item; + } + }) || {}) as {props: MenuProps}; + + return item; + } + } + + return null; +}; + +const getCloseOnSelect = ( + props: Partial> | undefined, + key: string, + item?: any, +) => { + const mergedItem = item || getMenuItem(props, key); + + if (mergedItem && mergedItem.props && "closeOnSelect" in mergedItem.props) { + return mergedItem.props.closeOnSelect; + } + + return props?.closeOnSelect; +}; + export function useDropdown(props: UseDropdownProps) { const globalContext = useProviderContext(); @@ -122,6 +158,9 @@ export function useDropdown(props: UseDropdownProps) { ...props.classNames, content: clsx(classNames, classNamesProp?.content, props.className), }, + shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside + ? popoverProps.shouldCloseOnInteractOutside + : (element: Element) => ariaShouldCloseOnInteractOutside(element, triggerRef, state), }; }; @@ -148,16 +187,10 @@ export function useDropdown(props: UseDropdownProps) { menuProps, closeOnSelect, ...mergeProps(props, { - onAction: (key: any) => { - // @ts-ignore - const item = props?.children?.find((item) => item.key === key); - - if (item?.props?.closeOnSelect === false) { - onMenuAction(false); + onAction: (key: any, item?: any) => { + const closeOnSelect = getCloseOnSelect(props, key, item); - return; - } - onMenuAction(props?.closeOnSelect); + onMenuAction(closeOnSelect); }, onClose: state.close, }), diff --git a/packages/components/listbox/CHANGELOG.md b/packages/components/listbox/CHANGELOG.md index 553d944d6a..57aabd1196 100644 --- a/packages/components/listbox/CHANGELOG.md +++ b/packages/components/listbox/CHANGELOG.md @@ -1,5 +1,13 @@ # @nextui-org/listbox +## 2.1.27 + +### Patch Changes + +- Updated dependencies [[`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/divider@2.0.32 + ## 2.1.26 ### Patch Changes diff --git a/packages/components/listbox/package.json b/packages/components/listbox/package.json index 5611b6efb0..92e365524e 100644 --- a/packages/components/listbox/package.json +++ b/packages/components/listbox/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/listbox", - "version": "2.1.26", + "version": "2.1.27", "description": "A listbox displays a list of options and allows a user to select one or more of them.", "keywords": [ "listbox" diff --git a/packages/components/menu/CHANGELOG.md b/packages/components/menu/CHANGELOG.md index 7088476447..0bea78939a 100644 --- a/packages/components/menu/CHANGELOG.md +++ b/packages/components/menu/CHANGELOG.md @@ -1,5 +1,14 @@ # @nextui-org/menu +## 2.0.30 + +### Patch Changes + +- Updated dependencies [[`8fecb5afa`](https://github.com/nextui-org/nextui/commit/8fecb5afa9aabe73e32243ca313f97856da8aa08), [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/use-aria-menu@2.0.7 + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/divider@2.0.32 + ## 2.0.29 ### Patch Changes diff --git a/packages/components/menu/package.json b/packages/components/menu/package.json index 76c69c4923..b84d9ea432 100644 --- a/packages/components/menu/package.json +++ b/packages/components/menu/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/menu", - "version": "2.0.29", + "version": "2.0.30", "description": "A menu displays a list of options and allows a user to select one or more of them.", "keywords": [ "menu" diff --git a/packages/components/modal/CHANGELOG.md b/packages/components/modal/CHANGELOG.md index 1e8e43247a..a3d7fe7a52 100644 --- a/packages/components/modal/CHANGELOG.md +++ b/packages/components/modal/CHANGELOG.md @@ -1,5 +1,14 @@ # @nextui-org/modal +## 2.0.41 + +### Patch Changes + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/use-aria-modal-overlay@2.0.13 + ## 2.0.40 ### Patch Changes diff --git a/packages/components/modal/__tests__/modal.test.tsx b/packages/components/modal/__tests__/modal.test.tsx index 2221f981b8..70b5225690 100644 --- a/packages/components/modal/__tests__/modal.test.tsx +++ b/packages/components/modal/__tests__/modal.test.tsx @@ -1,6 +1,5 @@ import * as React from "react"; import {act, render, fireEvent} from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; import {Modal, ModalContent, ModalBody, ModalHeader, ModalFooter} from "../src"; @@ -109,38 +108,4 @@ describe("Modal", () => { fireEvent.keyDown(modal, {key: "Escape"}); expect(onClose).toHaveBeenCalledTimes(1); }); - - it("should only hide the top-most modal", async () => { - const onClose1 = jest.fn(); - const onClose2 = jest.fn(); - - render( - - - Modal header - Modal body - Modal footer - - , - ); - - const wrapper2 = render( - - - Modal header - Modal body - Modal footer - - , - ); - - await userEvent.click(document.body); - expect(onClose1).not.toHaveBeenCalled(); - expect(onClose2).toHaveBeenCalledTimes(1); - - wrapper2.unmount(); - - await userEvent.click(document.body); - expect(onClose1).toHaveBeenCalledTimes(1); - }); }); diff --git a/packages/components/modal/package.json b/packages/components/modal/package.json index 959c5acca1..45a18dcb0a 100644 --- a/packages/components/modal/package.json +++ b/packages/components/modal/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/modal", - "version": "2.0.40", + "version": "2.0.41", "description": "Displays a dialog with a custom content that requires attention or provides additional information.", "keywords": [ "modal" diff --git a/packages/components/modal/src/use-modal.ts b/packages/components/modal/src/use-modal.ts index ef05dcad14..66b6f7be63 100644 --- a/packages/components/modal/src/use-modal.ts +++ b/packages/components/modal/src/use-modal.ts @@ -169,6 +169,7 @@ export function useModal(originalProps: UseModalProps) { const getBackdropProps = useCallback( (props = {}) => ({ className: slots.backdrop({class: classNames?.backdrop}), + onClick: () => state.close(), ...underlayProps, ...props, }), diff --git a/packages/components/popover/CHANGELOG.md b/packages/components/popover/CHANGELOG.md index 74b4dec1a9..538fa5372b 100644 --- a/packages/components/popover/CHANGELOG.md +++ b/packages/components/popover/CHANGELOG.md @@ -1,5 +1,17 @@ # @nextui-org/popover +## 2.1.29 + +### Patch Changes + +- [#3756](https://github.com/nextui-org/nextui/pull/3756) [`4c01d1824`](https://github.com/nextui-org/nextui/commit/4c01d1824d4dde22d89232968a3a4c48fe04678f) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback PR3307. rescheduled to v2.5.0. + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/button@2.0.38 + ## 2.1.28 ### Patch Changes diff --git a/packages/components/popover/package.json b/packages/components/popover/package.json index 9b1aa3df46..df41f38a46 100644 --- a/packages/components/popover/package.json +++ b/packages/components/popover/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/popover", - "version": "2.1.28", + "version": "2.1.29", "description": "A popover is an overlay element positioned relative to a trigger.", "keywords": [ "popover" @@ -47,7 +47,6 @@ "@nextui-org/react-utils": "workspace:*", "@nextui-org/shared-utils": "workspace:*", "@nextui-org/use-aria-button": "workspace:*", - "@nextui-org/use-aria-overlay": "workspace:*", "@nextui-org/use-safe-layout-effect": "workspace:*", "@react-aria/dialog": "3.5.14", "@react-aria/focus": "3.17.1", @@ -56,7 +55,8 @@ "@react-aria/utils": "3.24.1", "@react-stately/overlays": "3.6.7", "@react-types/button": "3.9.4", - "@react-types/overlays": "3.8.7" + "@react-types/overlays": "3.8.7", + "react-remove-scroll": "^2.5.6" }, "devDependencies": { "@nextui-org/card": "workspace:*", diff --git a/packages/components/popover/src/popover-content.tsx b/packages/components/popover/src/popover-content.tsx index f4eccd096f..ff4c4c0bc3 100644 --- a/packages/components/popover/src/popover-content.tsx +++ b/packages/components/popover/src/popover-content.tsx @@ -3,6 +3,7 @@ import type {HTMLMotionProps} from "framer-motion"; import {DOMAttributes, ReactNode, useMemo, useRef} from "react"; import {forwardRef} from "@nextui-org/system"; +import {RemoveScroll} from "react-remove-scroll"; import {DismissButton} from "@react-aria/overlays"; import {TRANSITION_VARIANTS} from "@nextui-org/framer-utils"; import {m, domAnimation, LazyMotion} from "framer-motion"; @@ -23,10 +24,12 @@ const PopoverContent = forwardRef<"div", PopoverContentProps>((props, _) => { const { Component: OverlayComponent, + isOpen, placement, backdrop, motionProps, disableAnimation, + shouldBlockScroll, getPopoverProps, getDialogProps, getBackdropProps, @@ -79,23 +82,27 @@ const PopoverContent = forwardRef<"div", PopoverContentProps>((props, _) => { ); }, [backdrop, disableAnimation, getBackdropProps]); - const contents = disableAnimation ? ( - content - ) : ( - - - {content} - - + const contents = ( + + {disableAnimation ? ( + content + ) : ( + + + {content} + + + )} + ); return ( diff --git a/packages/components/popover/src/use-aria-popover.ts b/packages/components/popover/src/use-aria-popover.ts index ebac5f83c4..e8d0873634 100644 --- a/packages/components/popover/src/use-aria-popover.ts +++ b/packages/components/popover/src/use-aria-popover.ts @@ -1,15 +1,20 @@ import {RefObject, useEffect} from "react"; import { + useOverlay, AriaPopoverProps, PopoverAria, useOverlayPosition, AriaOverlayProps, } from "@react-aria/overlays"; -import {OverlayPlacement, ariaHideOutside, toReactAriaPlacement} from "@nextui-org/aria-utils"; +import { + OverlayPlacement, + ariaHideOutside, + toReactAriaPlacement, + ariaShouldCloseOnInteractOutside, +} from "@nextui-org/aria-utils"; import {OverlayTriggerState} from "@react-stately/overlays"; import {mergeProps} from "@react-aria/utils"; import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect"; -import {useAriaOverlay} from "@nextui-org/use-aria-overlay"; export interface Props { /** @@ -66,16 +71,16 @@ export function useReactAriaPopover( const isNonModal = isNonModalProp ?? true; - const {overlayProps, underlayProps} = useAriaOverlay( + const {overlayProps, underlayProps} = useOverlay( { isOpen: state.isOpen, onClose: state.close, shouldCloseOnBlur, isDismissable, isKeyboardDismissDisabled, - shouldCloseOnInteractOutside: - shouldCloseOnInteractOutside || ((el) => !triggerRef.current?.contains(el)), - disableOutsideEvents: !isNonModal, + shouldCloseOnInteractOutside: shouldCloseOnInteractOutside + ? shouldCloseOnInteractOutside + : (element: Element) => ariaShouldCloseOnInteractOutside(element, triggerRef, state), }, popoverRef, ); diff --git a/packages/components/popover/src/use-popover.ts b/packages/components/popover/src/use-popover.ts index 6741a7e06f..8f91399e42 100644 --- a/packages/components/popover/src/use-popover.ts +++ b/packages/components/popover/src/use-popover.ts @@ -2,11 +2,11 @@ import type {PopoverVariantProps, SlotsToClasses, PopoverSlots} from "@nextui-or import type {HTMLMotionProps} from "framer-motion"; import type {PressEvent} from "@react-types/shared"; -import {RefObject, Ref} from "react"; +import {RefObject, Ref, useEffect} from "react"; import {ReactRef, useDOMRef} from "@nextui-org/react-utils"; import {OverlayTriggerState, useOverlayTriggerState} from "@react-stately/overlays"; import {useFocusRing} from "@react-aria/focus"; -import {useOverlayTrigger, usePreventScroll} from "@react-aria/overlays"; +import {ariaHideOutside, useOverlayTrigger} from "@react-aria/overlays"; import {OverlayTriggerProps} from "@react-types/overlays"; import { HTMLNextUIProps, @@ -298,9 +298,11 @@ export function usePopover(originalProps: UsePopoverProps) { [slots, state.isOpen, classNames, underlayProps], ); - usePreventScroll({ - isDisabled: !(shouldBlockScroll && state.isOpen), - }); + useEffect(() => { + if (state.isOpen && domRef?.current) { + return ariaHideOutside([domRef?.current]); + } + }, [state.isOpen, domRef]); return { state, @@ -316,6 +318,7 @@ export function usePopover(originalProps: UsePopoverProps) { isOpen: state.isOpen, onClose: state.close, disableAnimation, + shouldBlockScroll, backdrop: originalProps.backdrop ?? "transparent", motionProps, getBackdropProps, diff --git a/packages/components/select/CHANGELOG.md b/packages/components/select/CHANGELOG.md index a11f0be9e1..ab1e4eb8f9 100644 --- a/packages/components/select/CHANGELOG.md +++ b/packages/components/select/CHANGELOG.md @@ -1,5 +1,19 @@ # @nextui-org/select +## 2.2.7 + +### Patch Changes + +- [#3759](https://github.com/nextui-org/nextui/pull/3759) [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14) Thanks [@wingkwong](https://github.com/wingkwong)! - rollback pr3467. rescheduled to v2.5.0. + +- Updated dependencies [[`4c01d1824`](https://github.com/nextui-org/nextui/commit/4c01d1824d4dde22d89232968a3a4c48fe04678f), [`229388422`](https://github.com/nextui-org/nextui/commit/2293884229541e363b1983fea88ba6e3bee6be14)]: + - @nextui-org/popover@2.1.29 + - @nextui-org/use-aria-multiselect@2.2.5 + - @nextui-org/aria-utils@2.0.26 + - @nextui-org/listbox@2.1.27 + - @nextui-org/scroll-shadow@2.1.20 + - @nextui-org/spinner@2.0.34 + ## 2.2.6 ### Patch Changes diff --git a/packages/components/select/package.json b/packages/components/select/package.json index adddba9fe2..7c2bf17fa8 100644 --- a/packages/components/select/package.json +++ b/packages/components/select/package.json @@ -1,6 +1,6 @@ { "name": "@nextui-org/select", - "version": "2.2.6", + "version": "2.2.7", "description": "A select displays a collapsible list of options and allows a user to select one of them.", "keywords": [ "select" @@ -41,6 +41,7 @@ "react-dom": ">=18" }, "dependencies": { + "@nextui-org/aria-utils": "workspace:*", "@nextui-org/listbox": "workspace:*", "@nextui-org/popover": "workspace:*", "@nextui-org/react-utils": "workspace:*", diff --git a/packages/components/select/src/use-select.ts b/packages/components/select/src/use-select.ts index 3988c43f2f..0c8d31733b 100644 --- a/packages/components/select/src/use-select.ts +++ b/packages/components/select/src/use-select.ts @@ -28,6 +28,7 @@ import { } from "@nextui-org/use-aria-multiselect"; import {SpinnerProps} from "@nextui-org/spinner"; import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect"; +import {ariaShouldCloseOnInteractOutside} from "@nextui-org/aria-utils"; import {CollectionChildren} from "@react-types/shared"; export type SelectedItemProps = { @@ -529,6 +530,9 @@ export function useSelect(originalProps: UseSelectProps) { ? // forces the popover to update its position when the selected items change state.selectedItems.length * 0.00000001 + (slotsProps.popoverProps?.offset || 0) : slotsProps.popoverProps?.offset, + shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside + ? popoverProps.shouldCloseOnInteractOutside + : (element: Element) => ariaShouldCloseOnInteractOutside(element, domRef, state), } as PopoverProps; }, [ diff --git a/packages/components/select/stories/select.stories.tsx b/packages/components/select/stories/select.stories.tsx index a7bb0c53d1..0a58ad10a3 100644 --- a/packages/components/select/stories/select.stories.tsx +++ b/packages/components/select/stories/select.stories.tsx @@ -505,7 +505,7 @@ const CustomStylesTemplate = ({color, variant, ...args}: SelectProps) => {