{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n FocusableElement,\n getActiveElement,\n getAllFocusable,\n isTabbable,\n} from \"@chakra-ui/dom-utils\"\nimport { useEventListener } from \"@chakra-ui/react-use-event-listener\"\nimport { useSafeLayoutEffect } from \"@chakra-ui/react-use-safe-layout-effect\"\nimport { useUpdateEffect } from \"@chakra-ui/react-use-update-effect\"\nimport type { RefObject } from \"react\"\nimport { useCallback, useRef } from \"react\"\n\nexport interface UseFocusOnHideOptions {\n focusRef: RefObject\n shouldFocus?: boolean\n visible?: boolean\n}\n\nfunction preventReturnFocus(containerRef: React.RefObject) {\n const el = containerRef.current\n if (!el) return false\n\n const activeElement = getActiveElement(el)\n\n if (!activeElement) return false\n if (el.contains(activeElement)) return false\n if (isTabbable(activeElement)) return true\n\n return false\n}\n\n/**\n * Popover hook to manage the focus when the popover closes or hides.\n *\n * We either want to return focus back to the popover trigger or\n * let focus proceed normally if user moved to another interactive\n * element in the viewport.\n */\nexport function useFocusOnHide(\n containerRef: RefObject,\n options: UseFocusOnHideOptions,\n) {\n const { shouldFocus: shouldFocusProp, visible, focusRef } = options\n\n const shouldFocus = shouldFocusProp && !visible\n\n useUpdateEffect(() => {\n if (!shouldFocus) return\n\n if (preventReturnFocus(containerRef)) {\n return\n }\n\n const el = focusRef?.current || containerRef.current\n\n let rafId: number\n\n if (el) {\n rafId = requestAnimationFrame(() => {\n el.focus({ preventScroll: true })\n })\n return () => {\n cancelAnimationFrame(rafId)\n }\n }\n }, [shouldFocus, containerRef, focusRef])\n}\n\nexport interface UseFocusOnShowOptions {\n visible?: boolean\n shouldFocus?: boolean\n preventScroll?: boolean\n focusRef?: React.RefObject\n}\n\nconst defaultOptions: UseFocusOnShowOptions = {\n preventScroll: true,\n shouldFocus: false,\n}\n\nexport function useFocusOnShow(\n target: React.RefObject | T,\n options = defaultOptions,\n) {\n const { focusRef, preventScroll, shouldFocus, visible } = options\n const element = isRefObject(target) ? target.current : target\n\n const autoFocusValue = shouldFocus && visible\n const autoFocusRef = useRef(autoFocusValue)\n const lastVisibleRef = useRef(visible)\n\n useSafeLayoutEffect(() => {\n if (!lastVisibleRef.current && visible) {\n autoFocusRef.current = autoFocusValue\n }\n lastVisibleRef.current = visible\n }, [visible, autoFocusValue])\n\n const onFocus = useCallback(() => {\n if (!visible || !element || !autoFocusRef.current) return\n autoFocusRef.current = false\n\n if (element.contains(document.activeElement as HTMLElement)) return\n\n if (focusRef?.current) {\n requestAnimationFrame(() => {\n focusRef.current?.focus({ preventScroll })\n })\n } else {\n const tabbableEls = getAllFocusable(element)\n if (tabbableEls.length > 0) {\n requestAnimationFrame(() => {\n tabbableEls[0].focus({ preventScroll })\n })\n }\n }\n }, [visible, preventScroll, element, focusRef])\n\n useUpdateEffect(() => {\n onFocus()\n }, [onFocus])\n\n useEventListener(element, \"transitionend\", onFocus)\n}\n\nfunction isRefObject(val: any): val is { current: any } {\n return \"current\" in val\n}\n"],"mappings":";;;AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAEhC,SAAS,aAAa,cAAc;AAQpC,SAAS,mBAAmB,cAA4C;AACtE,QAAM,KAAK,aAAa;AACxB,MAAI,CAAC;AAAI,WAAO;AAEhB,QAAM,gBAAgB,iBAAiB,EAAE;AAEzC,MAAI,CAAC;AAAe,WAAO;AAC3B,MAAI,GAAG,SAAS,aAAa;AAAG,WAAO;AACvC,MAAI,WAAW,aAAa;AAAG,WAAO;AAEtC,SAAO;AACT;AASO,SAAS,eACd,cACA,SACA;AACA,QAAM,EAAE,aAAa,iBAAiB,SAAS,SAAS,IAAI;AAE5D,QAAM,cAAc,mBAAmB,CAAC;AAExC,kBAAgB,MAAM;AACpB,QAAI,CAAC;AAAa;AAElB,QAAI,mBAAmB,YAAY,GAAG;AACpC;AAAA,IACF;AAEA,UAAM,MAAK,qCAAU,YAAW,aAAa;AAE7C,QAAI;AAEJ,QAAI,IAAI;AACN,cAAQ,sBAAsB,MAAM;AAClC,WAAG,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,MAClC,CAAC;AACD,aAAO,MAAM;AACX,6BAAqB,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,QAAQ,CAAC;AAC1C;AASA,IAAM,iBAAwC;AAAA,EAC5C,eAAe;AAAA,EACf,aAAa;AACf;AAEO,SAAS,eACd,QACA,UAAU,gBACV;AACA,QAAM,EAAE,UAAU,eAAe,aAAa,QAAQ,IAAI;AAC1D,QAAM,UAAU,YAAY,MAAM,IAAI,OAAO,UAAU;AAEvD,QAAM,iBAAiB,eAAe;AACtC,QAAM,eAAe,OAAO,cAAc;AAC1C,QAAM,iBAAiB,OAAO,OAAO;AAErC,sBAAoB,MAAM;AACxB,QAAI,CAAC,eAAe,WAAW,SAAS;AACtC,mBAAa,UAAU;AAAA,IACzB;AACA,mBAAe,UAAU;AAAA,EAC3B,GAAG,CAAC,SAAS,cAAc,CAAC;AAE5B,QAAM,UAAU,YAAY,MAAM;AAChC,QAAI,CAAC,WAAW,CAAC,WAAW,CAAC,aAAa;AAAS;AACnD,iBAAa,UAAU;AAEvB,QAAI,QAAQ,SAAS,SAAS,aAA4B;AAAG;AAE7D,QAAI,qCAAU,SAAS;AACrB,4BAAsB,MAAM;AAzGlC;AA0GQ,uBAAS,YAAT,mBAAkB,MAAM,EAAE,cAAc;AAAA,MAC1C,CAAC;AAAA,IACH,OAAO;AACL,YAAM,cAAc,gBAAgB,OAAO;AAC3C,UAAI,YAAY,SAAS,GAAG;AAC1B,8BAAsB,MAAM;AAC1B,sBAAY,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,SAAS,eAAe,SAAS,QAAQ,CAAC;AAE9C,kBAAgB,MAAM;AACpB,YAAQ;AAAA,EACV,GAAG,CAAC,OAAO,CAAC;AAEZ,mBAAiB,SAAS,iBAAiB,OAAO;AACpD;AAEA,SAAS,YAAY,KAAmC;AACtD,SAAO,aAAa;AACtB;","names":[]}