From a29bc08f84889d93ce360de1e27bb00318e11b2b Mon Sep 17 00:00:00 2001 From: Balsa Asanovic Date: Wed, 19 Jul 2023 23:00:13 +0200 Subject: [PATCH 1/4] closes dropdown on any click outside of it --- web/src/components/core/PageOptions.jsx | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/web/src/components/core/PageOptions.jsx b/web/src/components/core/PageOptions.jsx index a25a5a264e..8e1a0aba13 100644 --- a/web/src/components/core/PageOptions.jsx +++ b/web/src/components/core/PageOptions.jsx @@ -19,7 +19,7 @@ * find current contact information at www.suse.com. */ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { Button, Dropdown, DropdownItem, DropdownGroup } from '@patternfly/react-core'; import { Icon, PageOptions as PageOptionsSlot } from "~/components/layout"; @@ -114,20 +114,40 @@ const Item = ({ children, ...props }) => { */ const PageOptions = ({ children }) => { const [isOpen, setIsOpen] = useState(false); + const dropdownRef = useRef(null); + const onToggle = () => setIsOpen(!isOpen); const onSelect = () => setIsOpen(false); + useEffect(() => { + const handleClickOutside = (event) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + setIsOpen(false); + } + }; + + if (isOpen) { + document.addEventListener('click', handleClickOutside); + } + + return () => { + document.removeEventListener('click', handleClickOutside); + }; + }, [isOpen]); + return ( - } - onSelect={onSelect} - dropdownItems={Array(children)} - position="right" - className="page-options" - isGrouped - /> + + } + onSelect={onSelect} + dropdownItems={Array(children)} + position="right" + className="page-options" + isGrouped + /> + ); }; From 13300791c4ed2276e63fd00f5ed05894d57b0d2a Mon Sep 17 00:00:00 2001 From: Balsa Asanovic Date: Wed, 19 Jul 2023 23:00:50 +0200 Subject: [PATCH 2/4] add unit test for dropdown close on outside click --- web/src/components/core/PageOptions.test.jsx | 24 +++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/web/src/components/core/PageOptions.test.jsx b/web/src/components/core/PageOptions.test.jsx index 00c26aaafa..31576c26dd 100644 --- a/web/src/components/core/PageOptions.test.jsx +++ b/web/src/components/core/PageOptions.test.jsx @@ -20,7 +20,7 @@ */ import React from "react"; -import { screen } from "@testing-library/react"; +import { screen, fireEvent } from "@testing-library/react"; import { plainRender, mockLayout } from "~/test-utils"; import { PageOptions } from "~/components/core"; @@ -74,3 +74,25 @@ it("hide the component content when the user clicks on one of its actions", asyn expect(screen.queryByRole("menuitem", { name: "A dummy action" })).toBeNull(); }); + +it('should close the dropdown on click outside', async () => { + const { user } = plainRender( + + <>Item 1 + <>Item 2 + + ); + + // Open the dropdown + const toggler = screen.getByRole("button"); + await user.click(toggler); + + // Ensure the dropdown is open + screen.getByRole("menuitem", { name: "Item 2" }); + + // Click outside the dropdown + fireEvent.click(document); + + // Ensure the dropdown is closed + expect(screen.queryByRole("menuitem", { name: "Item 2" })).toBeNull(); +}); From 05e1706d0ada59eb17a0752d0cefe0d4874e3817 Mon Sep 17 00:00:00 2001 From: Balsa Asanovic Date: Wed, 19 Jul 2023 23:21:27 +0200 Subject: [PATCH 3/4] added entry to changes file --- web/package/cockpit-agama.changes | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/package/cockpit-agama.changes b/web/package/cockpit-agama.changes index ce1167cdc9..0c943f9e54 100644 --- a/web/package/cockpit-agama.changes +++ b/web/package/cockpit-agama.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Wed Jul 19 21:21:15 UTC 2023 - Balsa Asanovic + +- Introduced functionality to close Dropdown automatically + when the user clicks outside of it. + (gh#openSUSE/agama#552). + ------------------------------------------------------------------- Mon Jul 17 09:16:38 UTC 2023 - Josef Reidinger From 5807b4518b0d1afb1d648588ad439ebed856c548 Mon Sep 17 00:00:00 2001 From: Balsa Asanovic Date: Wed, 2 Aug 2023 19:35:08 +0200 Subject: [PATCH 4/4] changed span to div for better comptability --- web/src/components/core/PageOptions.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/core/PageOptions.jsx b/web/src/components/core/PageOptions.jsx index 8e1a0aba13..cf3c9d3de0 100644 --- a/web/src/components/core/PageOptions.jsx +++ b/web/src/components/core/PageOptions.jsx @@ -137,7 +137,7 @@ const PageOptions = ({ children }) => { return ( - +
} @@ -147,7 +147,7 @@ const PageOptions = ({ children }) => { className="page-options" isGrouped /> - +
); };