diff --git a/docs/docs/options.mdx b/docs/docs/options.mdx index d60f755e..26ef8dbc 100644 --- a/docs/docs/options.mdx +++ b/docs/docs/options.mdx @@ -69,6 +69,7 @@ import 'react-tooltip/dist/react-tooltip.css' | float | boolean | false | `false` | `true` `false` | tooltip will follow the mouse position when it moves inside the anchor element (same as V4's `effect="float"`) | | noArrow | boolean | false | `false` | `true` `false` | tooltip arrow will not be shown | | clickable | boolean | false | `false` | `true` `false` | allow interaction with elements inside the tooltip. useful when using buttons and inputs | +| closeOnEsc | boolean | false | `false` | `true` `false` | pressing escape key will close the tooltip | | style | CSSProperties | false | | any React inline style | add styles directly to the component by `style` attribute | | position | `{ x: number; y: number }` | false | | any `number` value for both `x` and `y` | override the tooltip position on the viewport | | isOpen | boolen | false | handled by internal state | `true` `false` | the tooltip can be controlled or uncontrolled, this attribute can be used to handle show and hide tooltip outside tooltip (can be used **without** `setIsOpen`) | diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index e729322a..11623803 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -26,6 +26,7 @@ const Tooltip = ({ float = false, noArrow = false, clickable = false, + closeOnEsc = false, style: externalStyles, position, afterShow, @@ -190,6 +191,13 @@ const Tooltip = ({ handleShow(false) } + const handleEsc = (event: KeyboardEvent) => { + if (event.key !== 'Escape') { + return + } + handleShow(false) + } + // debounce handler to prevent call twice when // mouse enter and focus events being triggered toggether const debouncedHandleShowTooltip = debounce(handleShowTooltip, 50) @@ -210,6 +218,10 @@ const Tooltip = ({ return () => null } + if (closeOnEsc) { + window.addEventListener('keydown', handleEsc) + } + const enabledEvents: { event: string; listener: (event?: Event) => void }[] = [] if (events.find((event: string) => event === 'click')) { @@ -252,7 +264,12 @@ const Tooltip = ({ }) return () => { - window.removeEventListener('click', handleClickOutsideAnchor) + if (events.find((event: string) => event === 'click')) { + window.removeEventListener('click', handleClickOutsideAnchor) + } + if (closeOnEsc) { + window.removeEventListener('keydown', handleEsc) + } if (clickable) { tooltipRef.current?.removeEventListener('mouseenter', handleMouseEnterTooltip) tooltipRef.current?.removeEventListener('mouseleave', handleMouseLeaveTooltip) @@ -263,7 +280,7 @@ const Tooltip = ({ }) }) } - }, [anchorRefs, activeAnchor, anchorId, events, delayHide, delayShow]) + }, [anchorRefs, activeAnchor, closeOnEsc, anchorId, events, delayHide, delayShow]) useEffect(() => { if (position) { diff --git a/src/components/Tooltip/TooltipTypes.d.ts b/src/components/Tooltip/TooltipTypes.d.ts index 1e03cca2..809eff35 100644 --- a/src/components/Tooltip/TooltipTypes.d.ts +++ b/src/components/Tooltip/TooltipTypes.d.ts @@ -53,6 +53,7 @@ export interface ITooltip { float?: boolean noArrow?: boolean clickable?: boolean + closeOnEsc?: boolean style?: CSSProperties position?: IPosition isOpen?: boolean diff --git a/src/components/TooltipController/TooltipController.tsx b/src/components/TooltipController/TooltipController.tsx index 6fdf5c6c..f93c69c6 100644 --- a/src/components/TooltipController/TooltipController.tsx +++ b/src/components/TooltipController/TooltipController.tsx @@ -32,6 +32,7 @@ const TooltipController = ({ float = false, noArrow = false, clickable = false, + closeOnEsc = false, style, position, isOpen, @@ -187,6 +188,7 @@ const TooltipController = ({ float: tooltipFloat, noArrow, clickable, + closeOnEsc, style, position, isOpen, diff --git a/src/components/TooltipController/TooltipControllerTypes.d.ts b/src/components/TooltipController/TooltipControllerTypes.d.ts index 27ad5c8d..80dbcd94 100644 --- a/src/components/TooltipController/TooltipControllerTypes.d.ts +++ b/src/components/TooltipController/TooltipControllerTypes.d.ts @@ -31,6 +31,7 @@ export interface ITooltipController { float?: boolean noArrow?: boolean clickable?: boolean + closeOnEsc?: boolean style?: CSSProperties position?: IPosition isOpen?: boolean