UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.

120 lines 4.76 kB
import * as React from "react"; import cx from "clsx"; import { usePopper } from "react-popper"; import useClickOutside from "../../hooks/useClickOutside"; import KEY_CODE_MAP from "../../common/keyMaps"; import handleKeyDown from "../../utils/handleKeyDown"; import CloseIcon from "../../icons/Close"; import useTheme from "../../hooks/useTheme"; import useMediaQuery from "../../hooks/useMediaQuery"; const ErrorFormTooltip = ({ onShown, dataTest, helpClosable, children, shown, referenceElement, inlineLabel, isHelp = false, id }) => { const contentRef = React.useRef(null); const tooltipRef = React.useRef(null); const [arrowRef, setArrowRef] = React.useState(null); const { rtl } = useTheme(); const { isDesktop } = useMediaQuery(); const { styles, attributes: attrs, update } = usePopper(referenceElement?.current, tooltipRef.current, { placement: rtl ? "top-end" : "top-start", modifiers: [{ name: "offset", options: { offset: [inlineLabel || isDesktop ? 0 : 4, 3] } }, { name: "flip", enabled: false }, { name: "arrow", options: { element: arrowRef } }, { name: "eventListeners", options: { scroll: false } }] }); const { popper } = styles; useClickOutside(tooltipRef, () => { onShown(false); }); React.useEffect(() => { if (update) update(); }, [update, shown]); React.useEffect(() => { const link = tooltipRef.current?.querySelector("a"); const handleTab = ev => { if (isHelp) return; if (ev.keyCode === KEY_CODE_MAP.TAB && link) { onShown(true); if (document.activeElement === link) { onShown(false); } } else { onShown(false); } }; window.addEventListener("keydown", handleTab); return () => { window.removeEventListener("keydown", handleTab); }; }, [onShown, isHelp, helpClosable]); const isVertical = attrs.popper && (attrs.popper["data-popper-placement"] === "top-start" || attrs.popper["data-popper-placement"] === "top-end") ? "bottom" : "top"; const cssVars = { "--error-form-tooltip-position": popper.position, "--error-form-tooltip-top": popper.top, "--error-form-tooltip-left": popper.left, "--error-form-tooltip-right": popper.right, "--error-form-tooltip-bottom": popper.bottom, "--error-form-tooltip-transform": popper.transform }; return /*#__PURE__*/React.createElement("div", { id: id, ref: tooltipRef, "aria-live": "polite", "data-test": dataTest, className: cx("flex justify-between overflow-visible", "rounded-large py-xs px-sm z-10 box-border", "max-h-none w-[min(calc(100%-20px),_100vw)]", isHelp ? "pe-sm bg-blue-normal" : "bg-red-normal", shown ? "visible opacity-100" : "invisible opacity-0", "duration-fast transition-[opacity,visibility] ease-in-out", "bottom-[var(--error-form-tooltip-bottom)] left-[var(--error-form-tooltip-left)] right-[var(--error-form-tooltip-right)] top-[var(--error-form-tooltip-top)] [position:var(--error-form-tooltip-position)] [transform:var(--error-form-tooltip-transform)]", "lm:w-auto tb:rounded-normal", "[&>img]:max-w-full"), style: cssVars }, /*#__PURE__*/React.createElement("div", { className: cx("start-xs rtl:de:start-0 absolute", isVertical ? "bottom-xxxs" : "top-xxxs", inlineLabel && "rtl:start-0", isHelp ? "before:bg-blue-normal" : "before:bg-red-normal", "before:h-xs before:w-xs before:absolute before:-translate-x-1/2 before:-translate-y-1/2 before:rotate-45"), ref: setArrowRef }), /*#__PURE__*/React.createElement("div", { className: cx("font-base text-normal leading-small text-white-normal flex h-full items-center font-normal", "[&_.orbit-text]:text-white-normal [&_.orbit-text]:text-normal hover:[&_.orbit-text]:text-white-normal focus:[&_.orbit-text]:text-white-normal [&_.orbit-text]:font-normal", "[&_.orbit-list-item]:text-white-normal [&_.orbit-list-item]:text-normal hover:[&_.orbit-list-item]:text-white-normal focus:[&_.orbit-list-item]:text-white-normal [&_.orbit-list-item]:font-normal", "[&_a]:text-white-normal [&_a]:text-normal hover:[&_a]:text-white-normal focus:[&_a]:text-white-normal [&_a]:font-normal"), ref: contentRef }, children), isHelp && helpClosable && /*#__PURE__*/React.createElement("button", { type: "button", className: "text-white-normal ms-sm flex cursor-pointer", tabIndex: 0 // @ts-expect-error TODO , onKeyDown: handleKeyDown(onShown), onClick: ev => { ev.preventDefault(); if (shown) onShown(false); } }, /*#__PURE__*/React.createElement(CloseIcon, { ariaLabel: "close" }))); }; export default ErrorFormTooltip;