UNPKG

28.3 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.js","sources":["../src/hooks/usePortal.tsx","../src/hooks/useResizeObserver.tsx","../src/utils/utils.ts","../src/components/ModalGate/ModalGate.tsx","../src/hooks/useEscKeydown.tsx","../src/hooks/useLockScroll.tsx","../src/components/PopoverGate/PopoverGate.tsx","../src/components/TooltipGate/TooltipGate.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\r\n\r\n/**\r\n * Creates DOM element to be used as React root.\r\n * @returns {HTMLElement}\r\n */\r\nconst createRootElement = (id: string): HTMLDivElement => {\r\n const rootContainer = document.createElement('div');\r\n rootContainer.setAttribute('id', id);\r\n return rootContainer;\r\n};\r\n\r\n/**\r\n * Appends element as last child of body.\r\n * @param {Element} rootElem\r\n */\r\nconst addRootElement = (rootElem: Element): void => {\r\n if (document.body.lastElementChild) {\r\n document.body.insertBefore(\r\n rootElem,\r\n document.body.lastElementChild.nextElementSibling\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * Hook to create a React Portal.\r\n * Automatically handles creating and tearing-down the root elements (no SRR\r\n * makes this trivial), so there is no need to ensure the parent target already exists.\r\n * @example\r\n * const target = usePortal(id, [id]);\r\n * return createPortal(children, target);\r\n * @param {String} id The id of the target container, e.g 'portal-root'\r\n * @returns {HTMLDivElement} The DOM node to use as the Portal target.\r\n */\r\nconst usePortal = (id: string): HTMLDivElement => {\r\n const rootElemRef = useRef<HTMLDivElement | null>(null);\r\n\r\n useEffect(() => {\r\n // Look for existing target dom element to append to\r\n const existingParent = document.querySelector(`#${id}`);\r\n // Parent is either a new root or the existing dom element\r\n const parentElem = existingParent || createRootElement(id);\r\n\r\n // If there is no existing DOM element, add a new one\r\n if (!existingParent) {\r\n addRootElement(parentElem);\r\n }\r\n\r\n // Add the detached element to the parent\r\n if (rootElemRef.current) {\r\n parentElem.appendChild(rootElemRef.current);\r\n }\r\n\r\n return () => {\r\n if (rootElemRef.current) rootElemRef.current.remove();\r\n if (parentElem.childNodes.length === -1) {\r\n parentElem.remove();\r\n }\r\n };\r\n }, [id]);\r\n\r\n /**\r\n * It's important we evaluate this lazily:\r\n * - We need first render to contain the DOM element, so it shouldn't happen in useEffect. We would normally put this in the constructor().\r\n * - We can't do 'const rootElemRef = useRef(document.createElement('div))', since this will run every single render.\r\n * - We want the ref to consistently point to the same DOM element and only ever run once.\r\n * @link https://reactjs.org/docs/hooks-faq.html#how-to-create-expensive-objects-lazily\r\n */\r\n const getRootElem = () => {\r\n if (!rootElemRef.current) {\r\n rootElemRef.current = document.createElement('div');\r\n }\r\n return rootElemRef.current;\r\n };\r\n\r\n return getRootElem();\r\n};\r\n\r\nexport default usePortal;\r\n","import { useRef, useLayoutEffect } from 'react';\r\n\r\nconst useResizeObserver = (target: Element, onResize: { (): void }): void => {\r\n const resizeObserver = useRef<ResizeObserver | null>(null);\r\n\r\n useLayoutEffect(() => {\r\n resizeObserver.current = new ResizeObserver(() => {\r\n onResize && onResize();\r\n });\r\n\r\n resizeObserver.current.observe(target);\r\n\r\n return () => {\r\n if (resizeObserver.current) {\r\n resizeObserver.current.disconnect();\r\n }\r\n };\r\n }, [onResize, target]);\r\n};\r\n\r\nexport default useResizeObserver;\r\n","import { PositionAttrs, PositionParams } from '../types/types';\r\n\r\nexport const calculatePosition = ({\r\n triggerRef,\r\n portalRef,\r\n arrowRef,\r\n place,\r\n offset,\r\n}: PositionParams): PositionAttrs => {\r\n let top = 0;\r\n let left = 0;\r\n let arrowTop = 0;\r\n let arrowLeft = 0;\r\n let newPlace = place;\r\n\r\n if (!portalRef?.current || !triggerRef?.current || !arrowRef?.current) {\r\n return {\r\n top,\r\n left,\r\n arrowTop,\r\n arrowLeft,\r\n place: newPlace,\r\n };\r\n }\r\n\r\n const docWidth = document.documentElement.clientWidth;\r\n const docHeight = document.documentElement.clientHeight;\r\n const trRect = (triggerRef.current as Element).getBoundingClientRect();\r\n const ttRect = portalRef.current.getBoundingClientRect();\r\n const arrRect = arrowRef.current.getBoundingClientRect();\r\n\r\n const rx = trRect.x + trRect.width; // most right x\r\n const lx = trRect.x; // most left x\r\n const ty = trRect.y; // most top y\r\n const by = trRect.y + trRect.height; // most bottom y\r\n\r\n const { scrollX, scrollY } = window;\r\n\r\n if (\r\n Number.isNaN(rx) ||\r\n Number.isNaN(lx) ||\r\n Number.isNaN(ty) ||\r\n Number.isNaN(by)\r\n ) {\r\n return {\r\n top,\r\n left,\r\n arrowTop,\r\n arrowLeft,\r\n place: newPlace,\r\n };\r\n }\r\n\r\n const bRight = rx + ttRect.width + offset + scrollX <= scrollX + docWidth;\r\n const bLeft = lx - ttRect.width >= 0;\r\n const bAbove = ty - ttRect.height >= 0;\r\n const bBelow = by + ttRect.height + offset + scrollY <= scrollY + docHeight;\r\n\r\n switch (place) {\r\n case 'top':\r\n if (bAbove) {\r\n top = ty - ttRect.height - offset + scrollY;\r\n arrowTop = top + ttRect.height;\r\n } else {\r\n top = by + offset + scrollY;\r\n arrowTop = top - arrRect.height;\r\n newPlace = 'bottom';\r\n }\r\n // Initial left position for tooltip\r\n left = lx + scrollX + (trRect.width - ttRect.width) / 2;\r\n arrowLeft = lx + scrollX + (trRect.width - arrRect.width) / 2;\r\n\r\n // Check if it will render outside the window and recalculate\r\n if (left + ttRect.width > docWidth + scrollX) {\r\n left = rx - ttRect.width + scrollX;\r\n } else if (left < 0) {\r\n left = lx + scrollX;\r\n }\r\n\r\n break;\r\n\r\n case 'bottom':\r\n if (bBelow) {\r\n top = by + offset + scrollY;\r\n arrowTop = top - arrRect.height;\r\n } else {\r\n top = ty - ttRect.height - offset + scrollY;\r\n arrowTop = top + ttRect.height;\r\n newPlace = 'top';\r\n }\r\n // Initial left position for tooltip\r\n left = lx + scrollX + (trRect.width - ttRect.width) / 2;\r\n arrowLeft = lx + scrollX + (trRect.width - arrRect.width) / 2;\r\n\r\n // Check if it will render outside the window and recalculate\r\n if (left + ttRect.width > docWidth + scrollX) {\r\n left = rx - ttRect.width + scrollX;\r\n } else if (left < 0) {\r\n left = lx + scrollX;\r\n }\r\n\r\n break;\r\n\r\n case 'left':\r\n if (bLeft) {\r\n left = lx - ttRect.width - offset + scrollX;\r\n arrowLeft = left + ttRect.width;\r\n } else {\r\n left = rx + offset + scrollX;\r\n arrowLeft = left - arrRect.width;\r\n newPlace = 'right';\r\n }\r\n // Initial top position for tooltip\r\n top = ty + scrollY + (trRect.height - ttRect.height) / 2;\r\n arrowTop = ty + scrollY + (trRect.height - arrRect.height) / 2;\r\n\r\n // Check if it will render outside the window and recalculate\r\n if (top + ttRect.height > docHeight + scrollY) {\r\n top = by - ttRect.height + scrollY;\r\n } else if (top < 0) {\r\n top = ty + scrollY;\r\n }\r\n\r\n break;\r\n\r\n case 'right':\r\n if (bRight) {\r\n left = rx + offset + scrollX;\r\n arrowLeft = left - arrRect.width;\r\n } else {\r\n left = lx - ttRect.width - offset + scrollX;\r\n arrowLeft = left + ttRect.width;\r\n newPlace = 'left';\r\n }\r\n // Initial top position for tooltip\r\n top = ty + scrollY + (trRect.height - ttRect.height) / 2;\r\n arrowTop = ty + scrollY + (trRect.height - arrRect.height) / 2;\r\n\r\n // Check if it will render outside the window and recalculate\r\n if (top + ttRect.height > docHeight + scrollY) {\r\n top = by - ttRect.height + scrollY;\r\n } else if (top < 0) {\r\n top = ty + scrollY;\r\n }\r\n\r\n break;\r\n\r\n default:\r\n break;\r\n }\r\n\r\n return {\r\n top,\r\n left,\r\n arrowTop,\r\n arrowLeft,\r\n place: newPlace,\r\n };\r\n};\r\n","import * as React from 'react';\r\nimport { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\n/** Hooks */\r\nimport usePortal from '../../hooks/usePortal';\r\nimport useEscKeydown from '../../hooks/useEscKeydown';\r\nimport useLockScroll from '../../hooks/useLockScroll';\r\n/** Styles */\r\nimport './ModalGate.scss';\r\n\r\nexport type ModalGateProps = {\r\n id: string;\r\n isOpen: boolean;\r\n rootId?: string;\r\n className?: string;\r\n closeWhenClickOutside?: boolean;\r\n onClose: () => void;\r\n};\r\n\r\nconst ModalGate: React.FC<ModalGateProps> = ({\r\n id,\r\n isOpen,\r\n rootId = 'portal-root',\r\n className,\r\n closeWhenClickOutside = true,\r\n onClose,\r\n children,\r\n}) => {\r\n const [isActive, setIsActive] = useState<boolean>(false);\r\n const modalRef = useRef<HTMLDivElement>(null);\r\n const target = usePortal(rootId);\r\n useEscKeydown(onClose);\r\n useLockScroll(isActive);\r\n\r\n useEffect(() => {\r\n if (isOpen) {\r\n setIsActive(true);\r\n }\r\n }, [isOpen]);\r\n\r\n const handleCloseWhenClickOutside = useCallback(\r\n (e: React.MouseEvent<HTMLElement, MouseEvent>) => {\r\n if (closeWhenClickOutside && e.target === modalRef.current) {\r\n onClose && onClose();\r\n }\r\n },\r\n [closeWhenClickOutside, onClose]\r\n );\r\n\r\n const handleTransitionEnd = useCallback(() => {\r\n if (!isOpen) {\r\n setIsActive(false);\r\n }\r\n }, [isOpen]);\r\n\r\n return isOpen || isActive\r\n ? createPortal(\r\n <div\r\n id={id}\r\n ref={modalRef}\r\n data-testid=\"modal_backdrop\"\r\n className={`modal__backdrop${\r\n isOpen && isActive ? ' modal__backdrop--active' : ''\r\n } ${className || ''}`}\r\n role=\"dialog\"\r\n aria-labelledby={`modal_gate_${id}`}\r\n aria-modal=\"true\"\r\n onClick={handleCloseWhenClickOutside}\r\n onTransitionEnd={handleTransitionEnd}\r\n >\r\n <div className=\"modal__content\">{children}</div>\r\n </div>,\r\n target\r\n )\r\n : null;\r\n};\r\n\r\nexport default ModalGate;\r\n","import { useCallback, useEffect } from 'react';\r\n\r\nconst useEscKeydown = (onEscKeydown: { (): void }): void => {\r\n const onEscKeyDownCallback = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (event.key !== 'Escape') return;\r\n onEscKeydown && onEscKeydown();\r\n },\r\n [onEscKeydown]\r\n );\r\n\r\n useEffect(() => {\r\n window.addEventListener('keydown', onEscKeyDownCallback);\r\n\r\n return () => {\r\n window.removeEventListener('keydown', onEscKeyDownCallback);\r\n };\r\n }, [onEscKeyDownCallback]);\r\n};\r\n\r\nexport default useEscKeydown;\r\n","import { useRef, useLayoutEffect } from 'react';\r\n\r\nconst useLockScroll = (\r\n enableLockScroll = false,\r\n target: HTMLElement = document.body\r\n): void => {\r\n const overflowStyleRef = useRef('');\r\n\r\n useLayoutEffect(() => {\r\n if (enableLockScroll && !overflowStyleRef.current) {\r\n // Save the original body overflow and prevent scrolling\r\n overflowStyleRef.current = window.getComputedStyle(target).overflow;\r\n target.style.overflow = 'hidden';\r\n } else if (!enableLockScroll && overflowStyleRef.current) {\r\n // Re-enable scrolling\r\n target.style.overflow = overflowStyleRef.current;\r\n overflowStyleRef.current = '';\r\n }\r\n }, [enableLockScroll, target]);\r\n};\r\n\r\nexport default useLockScroll;\r\n","import * as React from 'react';\r\nimport {\r\n useState,\r\n useEffect,\r\n useLayoutEffect,\r\n useRef,\r\n useCallback,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\n/** Hooks */\r\nimport usePortal from '../../hooks/usePortal';\r\nimport useResizeObserver from '../../hooks/useResizeObserver';\r\n/** Utils */\r\nimport { calculatePosition } from '../../utils/utils';\r\n/** Types */\r\nimport { PositionAttrs, Place, Mode, Theme } from '../../types/types';\r\n/** Styles */\r\nimport './PopoverGate.scss';\r\n\r\nexport type PopoverGateProps = {\r\n rootId?: string;\r\n className?: string;\r\n content: string | JSX.Element;\r\n place?: Place;\r\n mode?: Mode;\r\n closeWhenClickOutside?: boolean;\r\n theme?: Theme;\r\n offset?: number;\r\n};\r\n\r\nconst PopoverGate: React.FC<PopoverGateProps> = ({\r\n rootId = 'portal-root',\r\n className,\r\n content,\r\n place = 'top',\r\n mode = 'click',\r\n closeWhenClickOutside = true,\r\n theme = 'dark',\r\n offset = 10,\r\n children,\r\n}) => {\r\n const [showPopover, setShowPopover] = useState(false);\r\n const [coords, setCoords] = useState({ top: -99999, left: -99999 });\r\n const [arrowCoords, setArrowCords] = useState({ top: -99999, left: -99999 });\r\n const [placePopover, setPlacePopover] = useState(place);\r\n const popoverRef = useRef<HTMLDivElement>(null);\r\n const arrowRef = useRef<HTMLDivElement>(null);\r\n const triggerRef = useRef<JSX.Element>(null);\r\n const target = usePortal(rootId);\r\n\r\n const handleCloseWhenClickOutside = useCallback(\r\n (e) => {\r\n if (\r\n closeWhenClickOutside &&\r\n triggerRef.current !== e.target &&\r\n !popoverRef.current?.contains(e.target)\r\n ) {\r\n setShowPopover(false);\r\n }\r\n },\r\n [closeWhenClickOutside]\r\n );\r\n\r\n const updatePosition = useCallback(() => {\r\n if (triggerRef.current) {\r\n const {\r\n top,\r\n left,\r\n arrowTop,\r\n arrowLeft,\r\n place: newPlace,\r\n }: PositionAttrs = calculatePosition({\r\n triggerRef,\r\n portalRef: popoverRef,\r\n arrowRef,\r\n place,\r\n offset,\r\n });\r\n setCoords({ top, left });\r\n setArrowCords({ top: arrowTop, left: arrowLeft });\r\n setPlacePopover(newPlace);\r\n }\r\n }, [place, offset]);\r\n\r\n useResizeObserver(document.body, updatePosition);\r\n\r\n useLayoutEffect(() => {\r\n if (popoverRef.current) {\r\n updatePosition();\r\n }\r\n }, [showPopover, updatePosition]);\r\n\r\n useEffect(() => {\r\n if (mode === 'click') {\r\n window.addEventListener('click', handleCloseWhenClickOutside);\r\n }\r\n\r\n return () => {\r\n if (mode === 'click') {\r\n window.removeEventListener('click', handleCloseWhenClickOutside);\r\n }\r\n };\r\n }, [mode, handleCloseWhenClickOutside]);\r\n\r\n const popoverEvents = useCallback(() => {\r\n switch (mode) {\r\n case 'click':\r\n default:\r\n return {\r\n onClick: () => {\r\n setShowPopover((showPopoverState) => !showPopoverState);\r\n },\r\n };\r\n case 'hover':\r\n return {\r\n onMouseEnter: () => {\r\n setShowPopover(true);\r\n },\r\n onMouseLeave: () => {\r\n setShowPopover(false);\r\n },\r\n };\r\n }\r\n }, [mode]);\r\n\r\n return (\r\n <>\r\n {React.cloneElement(children as JSX.Element, {\r\n ...popoverEvents(),\r\n 'data-testid': 'popover_trigger',\r\n ref: triggerRef,\r\n })}\r\n {showPopover &&\r\n createPortal(\r\n <div className={`${theme} ${className || ''}`}>\r\n <div\r\n ref={popoverRef}\r\n className={`popover__container popover__container--${placePopover}`}\r\n style={{ ...coords }}\r\n role=\"tooltip\"\r\n >\r\n <div className=\"popover__inner\">{content}</div>\r\n </div>\r\n <div\r\n ref={arrowRef}\r\n className={`popover__arrow popover__arrow--${placePopover}`}\r\n style={{ ...arrowCoords }}\r\n />\r\n <div\r\n className={`tooltip__arrow tooltip__arrow-border tooltip__arrow--${placePopover}`}\r\n style={{ ...arrowCoords }}\r\n />\r\n </div>,\r\n target\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default PopoverGate;\r\n","import * as React from 'react';\r\nimport { useState, useRef, useCallback, useLayoutEffect } from 'react';\r\nimport { createPortal } from 'react-dom';\r\n/** Hooks */\r\nimport usePortal from '../../hooks/usePortal';\r\nimport useResizeObserver from '../../hooks/useResizeObserver';\r\n/** Utils */\r\nimport { calculatePosition } from '../../utils/utils';\r\n/** Types */\r\nimport { PositionAttrs, Place, Theme } from '../../types/types';\r\n/** Styles */\r\nimport './TooltipGate.scss';\r\n\r\nexport type TooltipGateProps = {\r\n rootId?: string;\r\n className?: string;\r\n content: string | JSX.Element;\r\n place?: Place;\r\n theme?: Theme;\r\n offset?: number;\r\n};\r\n\r\nconst TooltipGate: React.FC<TooltipGateProps> = ({\r\n rootId = 'portal-root',\r\n className,\r\n content,\r\n place = 'top',\r\n theme = 'dark',\r\n offset = 10,\r\n children,\r\n}) => {\r\n const [showTooltip, setShowTooltip] = useState(false);\r\n const [coords, setCoords] = useState({ top: -99999, left: -99999 });\r\n const [arrowCoords, setArrowCords] = useState({ top: -99999, left: -99999 });\r\n const [placeTooltip, setPlaceTooltip] = useState(place);\r\n const tooltipRef = useRef<HTMLDivElement>(null);\r\n const arrowRef = useRef<HTMLDivElement>(null);\r\n const triggerRef = useRef<JSX.Element>(null);\r\n const target = usePortal(rootId);\r\n\r\n const updatePosition = useCallback(() => {\r\n if (triggerRef.current) {\r\n const {\r\n top,\r\n left,\r\n arrowTop,\r\n arrowLeft,\r\n place: newPlace,\r\n }: PositionAttrs = calculatePosition({\r\n triggerRef,\r\n portalRef: tooltipRef,\r\n arrowRef,\r\n place,\r\n offset,\r\n });\r\n setCoords({ top, left });\r\n setArrowCords({ top: arrowTop, left: arrowLeft });\r\n setPlaceTooltip(newPlace);\r\n }\r\n }, [place, offset]);\r\n\r\n useResizeObserver(document.body, updatePosition);\r\n\r\n useLayoutEffect(() => {\r\n if (tooltipRef.current) {\r\n updatePosition();\r\n }\r\n }, [showTooltip, updatePosition]);\r\n\r\n return (\r\n <>\r\n {React.cloneElement(children as JSX.Element, {\r\n onMouseEnter: () => {\r\n setShowTooltip(true);\r\n },\r\n onMouseLeave: () => {\r\n setShowTooltip(false);\r\n },\r\n 'data-testid': 'tooltip_trigger',\r\n ref: triggerRef,\r\n })}\r\n {showTooltip &&\r\n createPortal(\r\n <div className={`${theme} ${className || ''}`}>\r\n <div\r\n ref={tooltipRef}\r\n className={`tooltip__container tooltip__container--${placeTooltip}`}\r\n style={{ ...coords }}\r\n >\r\n <div className=\"tooltip__inner\">{content}</div>\r\n </div>\r\n <div\r\n ref={arrowRef}\r\n className={`tooltip__arrow tooltip__arrow--${placeTooltip}`}\r\n style={{ ...arrowCoords }}\r\n />\r\n <div\r\n className={`tooltip__arrow tooltip__arrow-border tooltip__arrow--${placeTooltip}`}\r\n style={{ ...arrowCoords }}\r\n />\r\n </div>,\r\n target\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default TooltipGate;\r\n"],"names":["usePortal","id","rootElemRef","useRef","useEffect","rootElem","existingParent","document","querySelector","parentElem","rootContainer","createElement","setAttribute","createRootElement","body","lastElementChild","insertBefore","nextElementSibling","current","appendChild","remove","childNodes","length","useResizeObserver","target","onResize","resizeObserver","useLayoutEffect","ResizeObserver","observe","disconnect","calculatePosition","_a","triggerRef","portalRef","arrowRef","place","offset","top","left","arrowTop","arrowLeft","newPlace","docWidth","documentElement","clientWidth","docHeight","clientHeight","trRect","getBoundingClientRect","ttRect","arrRect","rx","x","width","lx","ty","y","by","height","scrollX","window","scrollY","Number","isNaN","bRight","bLeft","bAbove","bBelow","onEscKeydown","onEscKeyDownCallback","isOpen","_b","rootId","className","_c","closeWhenClickOutside","onClose","children","_d","useState","isActive","setIsActive","modalRef","useCallback","event","key","addEventListener","removeEventListener","enableLockScroll","overflowStyleRef","getComputedStyle","overflow","style","useLockScroll","handleCloseWhenClickOutside","e","handleTransitionEnd","createPortal","React","ref","role","onClick","onTransitionEnd","content","mode","_e","_f","theme","_g","_h","showPopover","setShowPopover","_j","coords","setCoords","_k","arrowCoords","setArrowCords","_l","placePopover","setPlacePopover","popoverRef","contains","updatePosition","top_1","popoverEvents","showPopoverState","onMouseEnter","onMouseLeave","cloneElement","data-testid","showTooltip","setShowTooltip","placeTooltip","setPlaceTooltip","tooltipRef"],"mappings":"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"}
\No newline at end of file