diff --git a/packages/lib/src/dropdown/Dropdown.test.tsx b/packages/lib/src/dropdown/Dropdown.test.tsx
index de333c8eb..1ea059b96 100644
--- a/packages/lib/src/dropdown/Dropdown.test.tsx
+++ b/packages/lib/src/dropdown/Dropdown.test.tsx
@@ -49,22 +49,6 @@ describe("Dropdown component tests", () => {
expect(menu.getAttribute("aria-labelledby")).toBe(dropdown.id);
expect(getAllByRole("menuitem").length).toBe(4);
});
- test("Button trigger opens and closes the menu options when clicked", () => {
- const onSelectOption = jest.fn();
- const { getByRole, queryByRole, getByText } = render(
-
- );
- const dropdown = getByRole("button");
- expect(queryByRole("menu")).toBeFalsy();
- userEvent.click(dropdown);
- expect(queryByRole("menu")).toBeTruthy();
- expect(getByText("Amazon")).toBeTruthy();
- expect(getByText("Ebay")).toBeTruthy();
- expect(getByText("Wallapop")).toBeTruthy();
- expect(getByText("Aliexpress")).toBeTruthy();
- userEvent.click(dropdown);
- expect(queryByRole("menu")).toBeFalsy();
- });
test("Button trigger is not interactive when disabled", () => {
const onSelectOption = jest.fn();
const { getByRole, queryByRole, queryByText } = render(
@@ -90,30 +74,6 @@ describe("Dropdown component tests", () => {
userEvent.click(option);
expect(onSelectOption).toHaveBeenCalledWith("4");
});
- test("When expandOnHover is true, the dropdown trigger shows and hides the menu when it is hovered", () => {
- const onSelectOption = jest.fn();
- const { queryByText, getByRole, queryByRole } = render(
-
- );
- expect(queryByText("option-test")).toBeFalsy();
- expect(queryByRole("menu")).toBeFalsy();
- fireEvent.mouseOver(getByRole("button"));
- const menu = getByRole("menu");
- expect(menu).toBeTruthy();
- expect(document.activeElement === menu).toBeTruthy();
- expect(menu.getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-0`);
- });
- test("The menu is closed when the dropdown loses the focus (blur)", () => {
- const onSelectOption = jest.fn();
- const { getByRole, queryByRole } = render(
-
- );
- const dropdown = getByRole("button");
- userEvent.click(dropdown);
- expect(getByRole("menu")).toBeTruthy();
- fireEvent.blur(getByRole("menu"));
- expect(queryByRole("menu")).toBeFalsy();
- });
test("Menu button key events — Arrow up opens the list and moves the focus to the last menu item", () => {
const onSelectOption = jest.fn();
const { getByRole } = render(
@@ -128,7 +88,6 @@ describe("Dropdown component tests", () => {
});
const menu = getByRole("menu");
expect(menu).toBeTruthy();
- expect(document.activeElement === menu).toBeTruthy();
expect(getByRole("menu").getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-3`);
});
test("Menu button key events — Arrow down opens the list and moves the focus to the first menu item", () => {
@@ -145,7 +104,6 @@ describe("Dropdown component tests", () => {
});
const menu = getByRole("menu");
expect(menu).toBeTruthy();
- expect(document.activeElement === menu).toBeTruthy();
expect(getByRole("menu").getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-0`);
});
test("Menu button key events — Enter opens the list and moves the focus to the first menu item", () => {
@@ -162,7 +120,6 @@ describe("Dropdown component tests", () => {
});
const menu = getByRole("menu");
expect(menu).toBeTruthy();
- expect(document.activeElement === menu).toBeTruthy();
expect(getByRole("menu").getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-0`);
});
test("Menu button key events — Space opens the list and moves the focus to the first menu item", () => {
@@ -179,7 +136,6 @@ describe("Dropdown component tests", () => {
});
const menu = getByRole("menu");
expect(menu).toBeTruthy();
- expect(document.activeElement === menu).toBeTruthy();
expect(getByRole("menu").getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-0`);
});
test("Menu key events — Arrow up moves the focus to the previous menu item", () => {
@@ -200,7 +156,6 @@ describe("Dropdown component tests", () => {
keyCode: 38,
charCode: 38,
});
- expect(document.activeElement === menu).toBeTruthy();
expect(menu.getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-2`);
fireEvent.keyDown(menu, {
key: "Enter",
@@ -223,7 +178,6 @@ describe("Dropdown component tests", () => {
keyCode: 38,
charCode: 38,
});
- expect(document.activeElement === menu).toBeTruthy();
expect(menu.getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-3`);
fireEvent.keyDown(menu, {
key: "Enter",
@@ -252,7 +206,6 @@ describe("Dropdown component tests", () => {
keyCode: 40,
charCode: 40,
});
- expect(document.activeElement === menu).toBeTruthy();
expect(menu.getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-2`);
fireEvent.keyDown(menu, {
key: "Enter",
@@ -280,7 +233,6 @@ describe("Dropdown component tests", () => {
keyCode: 40,
charCode: 40,
});
- expect(document.activeElement === menu).toBeTruthy();
expect(menu.getAttribute("aria-activedescendant")).toBe(`${menu.id}-option-0`);
fireEvent.keyDown(menu, {
key: "Enter",
diff --git a/packages/lib/src/dropdown/Dropdown.tsx b/packages/lib/src/dropdown/Dropdown.tsx
index c67357e45..59ba44143 100644
--- a/packages/lib/src/dropdown/Dropdown.tsx
+++ b/packages/lib/src/dropdown/Dropdown.tsx
@@ -1,5 +1,4 @@
-import * as Popover from "@radix-ui/react-popover";
-import { FocusEvent, KeyboardEvent, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
+import { KeyboardEvent, useCallback, useId, useLayoutEffect, useRef, useState } from "react";
import styled from "@emotion/styled";
import { getMargin } from "../common/utils";
import { spaces } from "../common/variables";
@@ -7,7 +6,7 @@ import DxcIcon from "../icon/Icon";
import useWidth from "../utils/useWidth";
import DropdownMenu from "./DropdownMenu";
import DropdownPropsType from "./types";
-import { Tooltip } from "../tooltip/Tooltip";
+import DxcPopover from "../popover/Popover";
const sizes = {
small: "60px",
@@ -131,10 +130,6 @@ const DxcDropdown = ({
const menuId = `menu-${id}`;
const [isOpen, changeIsOpen] = useState(false);
const [visualFocusIndex, setVisualFocusIndex] = useState(0);
- const [portalContainer, setPortalContainer] = useState(null);
- useEffect(() => {
- setPortalContainer(document?.getElementById(`${id}-portal`));
- }, []);
const triggerRef = useRef(null);
const menuRef = useRef(null);
@@ -157,11 +152,6 @@ const DxcDropdown = ({
},
[onSelectOption]
);
- const handleOnBlur = (event: FocusEvent) => {
- if (!event.currentTarget.contains(event.relatedTarget)) {
- handleOnCloseMenu();
- }
- };
const handleTriggerOnClick = () => {
changeIsOpen((isCurrentlyOpen) => !isCurrentlyOpen);
@@ -256,76 +246,70 @@ const DxcDropdown = ({
return (
<>
-
-
-
-
- {
- event.stopPropagation();
- }}
- disabled={disabled}
- label={label}
- margin={margin}
- size={size}
- id={triggerId}
- aria-haspopup="true"
- aria-controls={isOpen ? menuId : undefined}
- aria-expanded={isOpen ? true : undefined}
- aria-label="Show options"
- tabIndex={tabIndex}
- ref={triggerRef}
- type="button"
- >
-
- {icon && (
-
- {typeof icon === "string" ? : icon}
-
- )}
- {label && {label}}
-
- {!caretHidden && (
-
-
-
- )}
-
-
-
- {portalContainer && (
-
-
-
-
-
- )}
-
+
+ {
+ menuRef.current?.focus();
+ }}
+ actionToOpen={expandOnHover ? "hover" : "click"}
+ popoverContent={
+
+ }
+ >
+ {
+ event.stopPropagation();
+ }}
+ disabled={disabled}
+ label={label}
+ margin={margin}
+ size={size}
+ id={triggerId}
+ aria-haspopup="true"
+ aria-controls={isOpen ? menuId : undefined}
+ aria-expanded={isOpen ? true : undefined}
+ aria-label="Show options"
+ tabIndex={tabIndex}
+ ref={triggerRef}
+ type="button"
+ title={title}
+ >
+
+ {icon && (
+
+ {typeof icon === "string" ? : icon}
+
+ )}
+ {label && {label}}
+
+ {!caretHidden && (
+
+
+
+ )}
+
+
-
-
>
);
};
diff --git a/packages/lib/src/dropdown/DropdownMenu.tsx b/packages/lib/src/dropdown/DropdownMenu.tsx
index a1587d9d6..8e8f7b700 100644
--- a/packages/lib/src/dropdown/DropdownMenu.tsx
+++ b/packages/lib/src/dropdown/DropdownMenu.tsx
@@ -3,53 +3,50 @@ import styled from "@emotion/styled";
import DropdownMenuItem from "./DropdownMenuItem";
import { DropdownMenuProps } from "./types";
import scrollbarStyles from "../styles/scroll";
+import DxcBleed from "../bleed/Bleed";
const DropdownMenuContainer = styled.ul`
max-height: 230px;
min-width: min-content;
padding: 0;
margin: 0;
- background-color: var(--color-bg-neutral-lightest);
- border-radius: var(--border-radius-s);
- box-shadow: var(--shadow-100);
outline: none;
overflow-y: auto;
- z-index: var(--z-dropdown);
${scrollbarStyles}
`;
const DropdownMenu = forwardRef(
({ id, dropdownTriggerId, iconsPosition, visualFocusIndex, menuItemOnClick, onKeyDown, options, styles }, ref) => (
- {
- // Prevent the onBlur event from closing menu when clicking on the menu since
- // it is implemented with a Portal and the menu is not a direct child of the container
- event.preventDefault();
- }}
- onKeyDown={onKeyDown}
- id={id}
- role="menu"
- aria-labelledby={dropdownTriggerId}
- aria-orientation="vertical"
- aria-activedescendant={visualFocusIndex !== -1 ? `${id}-option-${visualFocusIndex}` : undefined}
- tabIndex={-1}
- ref={ref}
- style={styles}
- >
- {options.map((option, index) => (
-
- ))}
-
+
+ {
+ // Prevent the onBlur event from closing menu when clicking on the menu since
+ // it is implemented with a Portal and the menu is not a direct child of the container
+ event.preventDefault();
+ }}
+ onKeyDown={onKeyDown}
+ id={id}
+ role="menu"
+ aria-labelledby={dropdownTriggerId}
+ aria-orientation="vertical"
+ aria-activedescendant={visualFocusIndex !== -1 ? `${id}-option-${visualFocusIndex}` : undefined}
+ tabIndex={0}
+ ref={ref}
+ style={styles}
+ >
+ {options.map((option, index) => (
+
+ ))}
+
+
)
);
-DropdownMenu.displayName = "DropdownMenu";
-
export default memo(DropdownMenu);