From 8f55799c5cca3b35ad722a00e4ad9c04627c2d23 Mon Sep 17 00:00:00 2001 From: Daniel Sil Date: Wed, 11 Dec 2024 09:52:03 +0100 Subject: [PATCH 1/2] chore: extract TooltipWrapper to a new file Just minor code organization --- .../MobileDialogPrimitive/index.tsx | 2 +- .../components/TooltipWrapper.tsx | 32 +++++++++++++++++++ .../src/primitives/TooltipPrimitive/index.tsx | 30 ++--------------- 3 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 packages/orbit-components/src/primitives/TooltipPrimitive/components/TooltipWrapper.tsx diff --git a/packages/orbit-components/src/primitives/MobileDialogPrimitive/index.tsx b/packages/orbit-components/src/primitives/MobileDialogPrimitive/index.tsx index ca4a3531c6..db98219579 100644 --- a/packages/orbit-components/src/primitives/MobileDialogPrimitive/index.tsx +++ b/packages/orbit-components/src/primitives/MobileDialogPrimitive/index.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import useRandomId from "../../hooks/useRandomId"; import useStateWithTimeout from "../../hooks/useStateWithTimeout"; import Portal from "../../Portal"; -import { TooltipWrapper } from "../TooltipPrimitive"; +import TooltipWrapper from "../TooltipPrimitive/components/TooltipWrapper"; import DialogContent from "./components/DialogContent"; import type { Props } from "./types"; diff --git a/packages/orbit-components/src/primitives/TooltipPrimitive/components/TooltipWrapper.tsx b/packages/orbit-components/src/primitives/TooltipPrimitive/components/TooltipWrapper.tsx new file mode 100644 index 0000000000..97df94b7f4 --- /dev/null +++ b/packages/orbit-components/src/primitives/TooltipPrimitive/components/TooltipWrapper.tsx @@ -0,0 +1,32 @@ +import * as React from "react"; +import cx from "clsx"; + +import type { Props } from "../types"; + +const TooltipWrapper = React.forwardRef< + HTMLSpanElement, + React.HTMLProps & { + block?: Props["block"]; + enabled?: Props["enabled"]; + removeUnderlinedText?: Props["removeUnderlinedText"]; + } +>(({ block, enabled, removeUnderlinedText, ...props }, ref) => { + return ( + + ); +}); + +export default TooltipWrapper; diff --git a/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx b/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx index cdceffd3a7..4ee276c444 100644 --- a/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx +++ b/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx @@ -1,38 +1,12 @@ import * as React from "react"; -import cx from "clsx"; import { FloatingPortal } from "@floating-ui/react"; import useRandomId from "../../hooks/useRandomId"; -import TooltipContent from "./components/TooltipContent"; import useStateWithTimeout from "../../hooks/useStateWithTimeout"; +import TooltipContent from "./components/TooltipContent"; +import TooltipWrapper from "./components/TooltipWrapper"; import type { Props } from "./types"; -export const TooltipWrapper = React.forwardRef< - HTMLSpanElement, - React.HTMLProps & { - block?: Props["block"]; - enabled?: Props["enabled"]; - removeUnderlinedText?: Props["removeUnderlinedText"]; - } ->(({ block, enabled, removeUnderlinedText, ...props }, ref) => { - return ( - - ); -}); - const TooltipPrimitive = ({ children, enabled = true, From 2961407c985cab7e86f328814fa43d48ec7e7ad8 Mon Sep 17 00:00:00 2001 From: Daniel Sil Date: Thu, 12 Dec 2024 10:04:41 +0100 Subject: [PATCH 2/2] fix(TooltipPrimitive): tooltip now closes on pressing ESC key --- .../TooltipPrimitive/__tests__/index.test.tsx | 20 ++++++++++++--- .../src/primitives/TooltipPrimitive/index.tsx | 25 ++++++++++++++----- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/packages/orbit-components/src/primitives/TooltipPrimitive/__tests__/index.test.tsx b/packages/orbit-components/src/primitives/TooltipPrimitive/__tests__/index.test.tsx index 29f6e2a0b6..2730f3b8f0 100644 --- a/packages/orbit-components/src/primitives/TooltipPrimitive/__tests__/index.test.tsx +++ b/packages/orbit-components/src/primitives/TooltipPrimitive/__tests__/index.test.tsx @@ -1,13 +1,13 @@ import * as React from "react"; import userEvent from "@testing-library/user-event"; -import { render, screen } from "../../../test-utils"; +import { fireEvent, render, screen } from "../../../test-utils"; import Tooltip from ".."; describe("Tooltip", () => { const user = userEvent.setup(); - it("it should render on hover", async () => { + it("should render on hover", async () => { const content = "Write some message to the user"; render( @@ -17,7 +17,21 @@ describe("Tooltip", () => { expect(screen.queryByText(content)).not.toBeInTheDocument(); await user.hover(screen.getByText("Some text")); - expect(screen.queryByText(content)).toBeInTheDocument(); + expect(screen.queryByText(content)).toBeVisible(); + }); + + it("should close on ESC click", async () => { + const content = "Write some message to the user"; + render( + +

Some text

+
, + ); + + await user.hover(screen.getByText("Some text")); + expect(screen.queryByText(content)).toBeVisible(); + fireEvent.keyDown(document, { key: "Escape" }); + expect(screen.queryByText(content)).not.toBeVisible(); }); it("should call onClick 1 time", async () => { diff --git a/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx b/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx index 4ee276c444..8259a61227 100644 --- a/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx +++ b/packages/orbit-components/src/primitives/TooltipPrimitive/index.tsx @@ -35,17 +35,30 @@ const TooltipPrimitive = ({ const tooltipId = useRandomId(); + const handleEsc = React.useCallback( + (ev: { key: string }) => { + if (ev.key === "Escape") { + setShown(false); + setRenderWithTimeout(false); + document.removeEventListener("keydown", handleEsc); + } + }, + [setRenderWithTimeout], + ); + + const handleOut = React.useCallback(() => { + setShown(false); + setRenderWithTimeout(false); + document.removeEventListener("keydown", handleEsc); + }, [handleEsc, setRenderWithTimeout]); + const handleIn = React.useCallback(() => { setRender(true); setShown(true); if (onShow) onShow(); clearRenderTimeout(); - }, [clearRenderTimeout, setRender, onShow]); - - const handleOut = React.useCallback(() => { - setShown(false); - setRenderWithTimeout(false); - }, [setRenderWithTimeout]); + document.addEventListener("keydown", handleEsc); + }, [setRender, onShow, clearRenderTimeout, handleEsc]); const handleClick = React.useCallback( (ev: React.MouseEvent) => {