@carbon/ibm-products
Version:
Carbon for IBM Products
67 lines (65 loc) • 2.35 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useIsomorphicEffect } from "../../../global/js/hooks/useIsomorphicEffect.js";
import "./enums.js";
import { useEffect, useRef } from "react";
//#region src/components/Coachmark/utils/hooks.js
/**
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Detects when a user clicks outside of the element
* @param {object} coachmarkRef - The ref to the React element for the Coachmark to detect when the user clicks outside of its bounds.
* @param {object} overlayRef - The ref to the React element for the CoachmarkOverlay to detect when the user clicks outside of its bounds.
* @param {string} overlayKind - The overlayKind prop from the Coachmark. @see COACHMARK_OVERLAY_KIND
* @param {Function} callback The callback to call when the user mouses down.
*/
function useClickOutsideElement(coachmarkRef, overlayRef, overlayKind, callback) {
const cb = useRef(void 0);
const isTooltip = overlayKind === "tooltip";
useIsomorphicEffect(() => {
cb.current = callback;
}, [callback]);
useIsomorphicEffect(() => {
function handleClickOutside(event) {
const isOverlayOutside = overlayRef.current && !overlayRef.current.contains(event.target);
const isOutsideCoachmark = coachmarkRef.current && !coachmarkRef.current.contains(event.target);
if (isOverlayOutside && isOutsideCoachmark) callCallback();
}
function callCallback() {
if (isTooltip) cb.current();
}
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [
coachmarkRef,
overlayRef,
isTooltip
]);
}
const useWindowEvent = (eventName, callback) => {
const savedCallback = useRef(null);
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
function handler(event) {
if (savedCallback.current) savedCallback.current(event);
}
window.addEventListener(eventName, handler);
return () => {
window.removeEventListener(eventName, handler);
};
}, [eventName]);
};
//#endregion
export { useClickOutsideElement, useWindowEvent };