Skip to content

Commit

Permalink
feat: close tracing dropdown on clicking away (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
albertfolch-redeemeum authored Jun 1, 2022
1 parent 8c50c3b commit 33311f9
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 12 deletions.
22 changes: 22 additions & 0 deletions e2e-tests/Landing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,28 @@ test.describe("Root page (Landing page)", () => {

await expect(headerDropdown).not.toBeVisible();
});
test("should close opened tracing dropdown when clicking away", async ({
page
}) => {
await mockSubgraph({
page
});
await page.goto("/");
const settings = page.locator("[data-testid=settings]");

await expect(settings).toBeVisible();

await settings.click();

const headerDropdown = page.locator("[data-testid=header-dropdown]");

await expect(headerDropdown).toBeVisible();
await page.pause();
const h2 = page.locator("h2");
await h2.click();

await expect(headerDropdown).not.toBeVisible();
});
test("should display an error when typing a wrong url into the tracing url dropdown", async ({
page
}) => {
Expand Down
50 changes: 38 additions & 12 deletions src/components/header/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Sentry from "@sentry/react";
import { BrowserTracing } from "@sentry/tracing";
import React, { useEffect, useReducer, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { IoIosSave, IoMdSettings } from "react-icons/io";
import { usePopper } from "react-popper";
import {
Expand Down Expand Up @@ -107,7 +107,8 @@ export default function Settings() {
);
const [tracingUrl, setTracingUrl] = useState<string>(sentryTracingUrl);
const [sentryError, setSentryError] = useState<string>("");

const dropRef = useRef<HTMLDivElement | null>(null);
const settingsRef = useRef<HTMLButtonElement | null>(null);
const [referenceElement, setReferenceElement] =
useState<HTMLButtonElement | null>(null);
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(
Expand All @@ -131,10 +132,12 @@ export default function Settings() {
placement: "bottom",
modifiers: [{ name: "arrow", options: { element: saveButtonArrow } }]
});
const [isDropdownVisible, toggleDropdownVisibility] = useReducer(
(state) => !state,
false
);
const [isDropdownVisible, setDropdownVisibility] = useState<boolean>(false);
const toggleDropdown = () => {
setDropdownVisibility(!isDropdownVisible);
// tell popper to recalculate the position as the dropdown wasn't rendered
saveButtonUpdate?.();
};
useEffect(() => {
try {
Sentry.init({
Expand All @@ -161,21 +164,44 @@ export default function Settings() {
}
}, [sentryTracingUrl]);

useEffect(() => {
function handleClickOutside(event: MouseEvent) {
const isClickingOnDropdown =
dropRef.current && dropRef?.current.contains(event.target as Node);
const isClickingOnSettingsButton =
settingsRef.current &&
settingsRef?.current.contains(event.target as Node);
if (
isDropdownVisible &&
!isClickingOnDropdown &&
!isClickingOnSettingsButton
) {
setDropdownVisibility(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [dropRef, isDropdownVisible]);

return (
<>
<SettingsSvgIcon
data-testid="settings"
ref={setReferenceElement}
onClick={() => {
toggleDropdownVisibility();
// tell popper to recalculate the position as the dropdown wasn't rendered
saveButtonUpdate?.();
ref={(ref) => {
settingsRef.current = ref;
setReferenceElement(ref);
}}
onClick={toggleDropdown}
>
<SettingsIcon />
</SettingsSvgIcon>
<DropdownItem
ref={setPopperElement}
ref={(ref) => {
dropRef.current = ref;
setPopperElement(ref);
}}
style={styles.popper}
{...attributes.popper}
hidden={!isDropdownVisible}
Expand Down

0 comments on commit 33311f9

Please sign in to comment.