UNPKG

@arolariu/components

Version:

🎨 70+ beautiful, accessible React components built on Base UI. TypeScript-first, CSS Modules styling, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡

70 lines (69 loc) • 2.85 kB
"use client"; import { jsx } from "react/jsx-runtime"; import { cn } from "../../lib/utilities.js"; import focus_scope_module from "./focus-scope.module.js"; import * as __rspack_external_react from "react"; const FOCUSABLE_SELECTOR = 'a[href], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"]), [contenteditable]'; function getFocusableElements(container) { return [ ...container.querySelectorAll(FOCUSABLE_SELECTOR) ].filter((element)=>!element.hasAttribute("disabled") && element.tabIndex >= 0); } const FocusScope = /*#__PURE__*/ __rspack_external_react.forwardRef(({ contain = true, restoreFocus = true, autoFocus = false, children, className, ...props }, ref)=>{ const containerRef = __rspack_external_react.useRef(null); const previousFocusRef = __rspack_external_react.useRef(null); __rspack_external_react.useEffect(()=>{ previousFocusRef.current = document.activeElement; if (autoFocus && containerRef.current) { const focusable = getFocusableElements(containerRef.current); focusable[0]?.focus(); } return ()=>{ if (restoreFocus && previousFocusRef.current instanceof HTMLElement) previousFocusRef.current.focus(); }; }, [ autoFocus, restoreFocus ]); __rspack_external_react.useEffect(()=>{ const container = containerRef.current; if (!container) return; const handleKeyDown = (event)=>{ if (!contain || "Tab" !== event.key) return; const focusable = getFocusableElements(container); if (0 === focusable.length) return; const [first] = focusable; const last = focusable.at(-1); if (event.shiftKey && first?.isSameNode(document.activeElement)) { event.preventDefault(); last?.focus(); return; } if (!event.shiftKey && last?.isSameNode(document.activeElement)) { event.preventDefault(); first?.focus(); } }; container.addEventListener("keydown", handleKeyDown); return ()=>{ container.removeEventListener("keydown", handleKeyDown); }; }, [ contain ]); return /*#__PURE__*/ jsx("div", { ref: (node)=>{ containerRef.current = node; if ("function" == typeof ref) return void ref(node); if (ref) ref.current = node; }, className: cn(focus_scope_module.scope, className), role: props.role ?? "group", tabIndex: props.tabIndex ?? -1, ...props, children: children }); }); FocusScope.displayName = "FocusScope"; export { FocusScope }; //# sourceMappingURL=focus-scope.js.map