Skip to content

Commit

Permalink
Merge pull request #763 from petermakowski/feat-tooltip-on-click-shou…
Browse files Browse the repository at this point in the history
…ld-remain-open-until-dismissed-759

fix: tooltip on click should remain open until dismissed
  • Loading branch information
petermakowski authored Apr 19, 2022
2 parents 7bcdff0 + 48002a5 commit e3f24ad
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
31 changes: 31 additions & 0 deletions cypress/integration/tooltip.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,35 @@ context("Tooltip", () => {
cy.findByRole("button", { name: /Hover over me!/ }).click();
cy.findByRole("tooltip").should("be.visible");
});

it("hovering the child button element opens the tooltip", () => {
cy.findByRole("tooltip").should("not.be.visible");
cy.findByRole("button", { name: /Hover over me!/ }).trigger("mouseover");
cy.findByRole("tooltip").should("be.visible");
});

it("when activated on click tooltip remains open when the cursor is moved outside", () => {
cy.findByRole("tooltip").should("not.be.visible");
cy.findByRole("button", { name: /Hover over me!/ }).click();
cy.get("body").trigger("mousemove", { clientX: 0, clientY: 0 });
cy.findByRole("tooltip").should("be.visible");
cy.get("body").type("{esc}");
cy.findByRole("tooltip").should("not.be.visible");
});

it("when activated on click tooltip can be closed with an ESC key", () => {
cy.findByRole("tooltip").should("not.be.visible");
cy.findByRole("button", { name: /Hover over me!/ }).click();
cy.findByRole("tooltip").should("be.visible");
cy.get("body").type("{esc}");
cy.findByRole("tooltip").should("not.be.visible");
});

it("when activated on click tooltip can be closed by clicking outside of it", () => {
cy.findByRole("tooltip").should("not.be.visible");
cy.findByRole("button", { name: /Hover over me!/ }).click();
cy.findByRole("tooltip").should("be.visible");
cy.get("body").click(0, 0);
cy.findByRole("tooltip").should("not.be.visible");
});
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@
"test-cypress": "concurrently 'yarn run docs' 'yarn run cypress:test' -k -s first",
"unlink-packages": "yarn unlink && cd node_modules/react && yarn unlink && cd ../react-dom && yarn unlink",
"cypress:test": "wait-on http://localhost:${PORT:-9009} && cypress run --env port=${PORT:-9009}",
"cypress:run": "cypress run",
"cypress:open": "cypress open"
"cypress:run": "cypress run --env port=${PORT:-9009}",
"cypress:open": "cypress open --env port=${PORT:-9009}"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
31 changes: 31 additions & 0 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,28 @@ const Tooltip = ({
autoAdjust && followMouse
);

const handleKeyPress = useCallback(
(event: KeyboardEvent) => {
if (event.key === "Escape") {
closePortal();
}
},
[closePortal]
);

useEffect(() => {
window.addEventListener("keypress", handleKeyPress);
return () => {
window.removeEventListener("keypress", handleKeyPress);
};
}, [handleKeyPress]);

const handleBlur = (e) => {
// do not close if the focus is within the tooltip wrapper
if (wrapperRef?.current?.contains(document.activeElement)) {
return;
}

if (
e.relatedTarget
? !messageRef.current?.contains(e.relatedTarget)
Expand All @@ -253,12 +274,22 @@ const Tooltip = ({
}
};

const handleClick = (e) => {
// ignore clicks within the tooltip message
if (messageRef.current?.contains(e.target)) {
return;
}
e.target.focus();
openPortal();
};

return (
<>
{message ? (
<span
className={className}
onBlur={handleBlur}
onClick={handleClick}
onFocus={openPortal}
onMouseOut={handleBlur}
onMouseOver={openPortal}
Expand Down

0 comments on commit e3f24ad

Please sign in to comment.