| "use strict"; |
| "use client"; |
| var __create = Object.create; |
| var __defProp = Object.defineProperty; |
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
| var __getOwnPropNames = Object.getOwnPropertyNames; |
| var __getProtoOf = Object.getPrototypeOf; |
| var __hasOwnProp = Object.prototype.hasOwnProperty; |
| var __export = (target, all) => { |
| for (var name in all) |
| __defProp(target, name, { get: all[name], enumerable: true }); |
| }; |
| var __copyProps = (to, from, except, desc) => { |
| if (from && typeof from === "object" || typeof from === "function") { |
| for (let key of __getOwnPropNames(from)) |
| if (!__hasOwnProp.call(to, key) && key !== except) |
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); |
| } |
| return to; |
| }; |
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
| |
| |
| |
| |
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
| mod |
| )); |
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
|
|
| |
| var src_exports = {}; |
| __export(src_exports, { |
| FocusScope: () => FocusScope, |
| Root: () => Root |
| }); |
| module.exports = __toCommonJS(src_exports); |
|
|
| |
| var React = __toESM(require("react")); |
| var import_react_compose_refs = require("@radix-ui/react-compose-refs"); |
| var import_react_primitive = require("@radix-ui/react-primitive"); |
| var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref"); |
| var import_jsx_runtime = require("react/jsx-runtime"); |
| var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount"; |
| var AUTOFOCUS_ON_UNMOUNT = "focusScope.autoFocusOnUnmount"; |
| var EVENT_OPTIONS = { bubbles: false, cancelable: true }; |
| var FOCUS_SCOPE_NAME = "FocusScope"; |
| var FocusScope = React.forwardRef((props, forwardedRef) => { |
| const { |
| loop = false, |
| trapped = false, |
| onMountAutoFocus: onMountAutoFocusProp, |
| onUnmountAutoFocus: onUnmountAutoFocusProp, |
| ...scopeProps |
| } = props; |
| const [container, setContainer] = React.useState(null); |
| const onMountAutoFocus = (0, import_react_use_callback_ref.useCallbackRef)(onMountAutoFocusProp); |
| const onUnmountAutoFocus = (0, import_react_use_callback_ref.useCallbackRef)(onUnmountAutoFocusProp); |
| const lastFocusedElementRef = React.useRef(null); |
| const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node) => setContainer(node)); |
| const focusScope = React.useRef({ |
| paused: false, |
| pause() { |
| this.paused = true; |
| }, |
| resume() { |
| this.paused = false; |
| } |
| }).current; |
| React.useEffect(() => { |
| if (trapped) { |
| let handleFocusIn2 = function(event) { |
| if (focusScope.paused || !container) return; |
| const target = event.target; |
| if (container.contains(target)) { |
| lastFocusedElementRef.current = target; |
| } else { |
| focus(lastFocusedElementRef.current, { select: true }); |
| } |
| }, handleFocusOut2 = function(event) { |
| if (focusScope.paused || !container) return; |
| const relatedTarget = event.relatedTarget; |
| if (relatedTarget === null) return; |
| if (!container.contains(relatedTarget)) { |
| focus(lastFocusedElementRef.current, { select: true }); |
| } |
| }, handleMutations2 = function(mutations) { |
| const focusedElement = document.activeElement; |
| if (focusedElement !== document.body) return; |
| for (const mutation of mutations) { |
| if (mutation.removedNodes.length > 0) focus(container); |
| } |
| }; |
| var handleFocusIn = handleFocusIn2, handleFocusOut = handleFocusOut2, handleMutations = handleMutations2; |
| document.addEventListener("focusin", handleFocusIn2); |
| document.addEventListener("focusout", handleFocusOut2); |
| const mutationObserver = new MutationObserver(handleMutations2); |
| if (container) mutationObserver.observe(container, { childList: true, subtree: true }); |
| return () => { |
| document.removeEventListener("focusin", handleFocusIn2); |
| document.removeEventListener("focusout", handleFocusOut2); |
| mutationObserver.disconnect(); |
| }; |
| } |
| }, [trapped, container, focusScope.paused]); |
| React.useEffect(() => { |
| if (container) { |
| focusScopesStack.add(focusScope); |
| const previouslyFocusedElement = document.activeElement; |
| const hasFocusedCandidate = container.contains(previouslyFocusedElement); |
| if (!hasFocusedCandidate) { |
| const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS); |
| container.addEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus); |
| container.dispatchEvent(mountEvent); |
| if (!mountEvent.defaultPrevented) { |
| focusFirst(removeLinks(getTabbableCandidates(container)), { select: true }); |
| if (document.activeElement === previouslyFocusedElement) { |
| focus(container); |
| } |
| } |
| } |
| return () => { |
| container.removeEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus); |
| setTimeout(() => { |
| const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS); |
| container.addEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus); |
| container.dispatchEvent(unmountEvent); |
| if (!unmountEvent.defaultPrevented) { |
| focus(previouslyFocusedElement ?? document.body, { select: true }); |
| } |
| container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus); |
| focusScopesStack.remove(focusScope); |
| }, 0); |
| }; |
| } |
| }, [container, onMountAutoFocus, onUnmountAutoFocus, focusScope]); |
| const handleKeyDown = React.useCallback( |
| (event) => { |
| if (!loop && !trapped) return; |
| if (focusScope.paused) return; |
| const isTabKey = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey; |
| const focusedElement = document.activeElement; |
| if (isTabKey && focusedElement) { |
| const container2 = event.currentTarget; |
| const [first, last] = getTabbableEdges(container2); |
| const hasTabbableElementsInside = first && last; |
| if (!hasTabbableElementsInside) { |
| if (focusedElement === container2) event.preventDefault(); |
| } else { |
| if (!event.shiftKey && focusedElement === last) { |
| event.preventDefault(); |
| if (loop) focus(first, { select: true }); |
| } else if (event.shiftKey && focusedElement === first) { |
| event.preventDefault(); |
| if (loop) focus(last, { select: true }); |
| } |
| } |
| } |
| }, |
| [loop, trapped, focusScope.paused] |
| ); |
| return (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown }); |
| }); |
| FocusScope.displayName = FOCUS_SCOPE_NAME; |
| function focusFirst(candidates, { select = false } = {}) { |
| const previouslyFocusedElement = document.activeElement; |
| for (const candidate of candidates) { |
| focus(candidate, { select }); |
| if (document.activeElement !== previouslyFocusedElement) return; |
| } |
| } |
| function getTabbableEdges(container) { |
| const candidates = getTabbableCandidates(container); |
| const first = findVisible(candidates, container); |
| const last = findVisible(candidates.reverse(), container); |
| return [first, last]; |
| } |
| function getTabbableCandidates(container) { |
| const nodes = []; |
| const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, { |
| acceptNode: (node) => { |
| const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden"; |
| if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP; |
| return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; |
| } |
| }); |
| while (walker.nextNode()) nodes.push(walker.currentNode); |
| return nodes; |
| } |
| function findVisible(elements, container) { |
| for (const element of elements) { |
| if (!isHidden(element, { upTo: container })) return element; |
| } |
| } |
| function isHidden(node, { upTo }) { |
| if (getComputedStyle(node).visibility === "hidden") return true; |
| while (node) { |
| if (upTo !== void 0 && node === upTo) return false; |
| if (getComputedStyle(node).display === "none") return true; |
| node = node.parentElement; |
| } |
| return false; |
| } |
| function isSelectableInput(element) { |
| return element instanceof HTMLInputElement && "select" in element; |
| } |
| function focus(element, { select = false } = {}) { |
| if (element && element.focus) { |
| const previouslyFocusedElement = document.activeElement; |
| element.focus({ preventScroll: true }); |
| if (element !== previouslyFocusedElement && isSelectableInput(element) && select) |
| element.select(); |
| } |
| } |
| var focusScopesStack = createFocusScopesStack(); |
| function createFocusScopesStack() { |
| let stack = []; |
| return { |
| add(focusScope) { |
| const activeFocusScope = stack[0]; |
| if (focusScope !== activeFocusScope) { |
| activeFocusScope?.pause(); |
| } |
| stack = arrayRemove(stack, focusScope); |
| stack.unshift(focusScope); |
| }, |
| remove(focusScope) { |
| stack = arrayRemove(stack, focusScope); |
| stack[0]?.resume(); |
| } |
| }; |
| } |
| function arrayRemove(array, item) { |
| const updatedArray = [...array]; |
| const index = updatedArray.indexOf(item); |
| if (index !== -1) { |
| updatedArray.splice(index, 1); |
| } |
| return updatedArray; |
| } |
| function removeLinks(items) { |
| return items.filter((item) => item.tagName !== "A"); |
| } |
| var Root = FocusScope; |
| |
|
|