UNPKG

@ariakit/react-core

Version:

Ariakit React core

184 lines (182 loc) 5.55 kB
"use client"; import { TabScopedContextProvider, useTabProviderContext } from "../__chunks/T3X6WUOS.js"; import { useDisclosureContent } from "../__chunks/HAX24JB7.js"; import { useDisclosureStore } from "../__chunks/33YRLYNQ.js"; import { useCollectionItem } from "../__chunks/DTXGDDAC.js"; import "../__chunks/63N3TCQX.js"; import "../__chunks/FFSBKSAM.js"; import "../__chunks/72IB6YNO.js"; import { useFocusable } from "../__chunks/US3TW2XI.js"; import "../__chunks/SWN3JYXT.js"; import { useStoreState } from "../__chunks/Q3KUZPD7.js"; import "../__chunks/45YOMIF3.js"; import { createElement, createHook, forwardRef } from "../__chunks/ILRXHV7V.js"; import { useEvent, useId, useMergeRefs, useWrapElement } from "../__chunks/K2XTQB3X.js"; import "../__chunks/YXGXYGQX.js"; // src/tab/tab-panel.tsx import { getAllTabbableIn } from "@ariakit/core/utils/focus"; import { invariant } from "@ariakit/core/utils/misc"; import { useCallback, useEffect, useRef, useState } from "react"; import { jsx } from "react/jsx-runtime"; var TagName = "div"; var useTabPanel = createHook( function useTabPanel2({ store, unmountOnHide, tabId: tabIdProp, getItem: getItemProp, scrollRestoration, scrollElement, ...props }) { const context = useTabProviderContext(); store = store || context; invariant( store, process.env.NODE_ENV !== "production" && "TabPanel must receive a `store` prop or be wrapped in a TabProvider component." ); const ref = useRef(null); const id = useId(props.id); const tabId = useStoreState( store.panels, () => { var _a; return tabIdProp || ((_a = store == null ? void 0 : store.panels.item(id)) == null ? void 0 : _a.tabId); } ); const open = useStoreState( store, (state) => !!tabId && state.selectedId === tabId ); const disclosure = useDisclosureStore({ open }); const mounted = useStoreState(disclosure, "mounted"); const scrollPositionRef = useRef( /* @__PURE__ */ new Map() ); const getScrollElement = useEvent(() => { const panelElement = ref.current; if (!panelElement) return null; if (!scrollElement) return panelElement; if (typeof scrollElement === "function") { return scrollElement(panelElement); } if ("current" in scrollElement) { return scrollElement.current; } return scrollElement; }); useEffect(() => { var _a, _b; if (!scrollRestoration) return; if (!mounted) return; const element = getScrollElement(); if (!element) return; if (scrollRestoration === "reset") { element.scroll(0, 0); return; } if (!tabId) return; const position = scrollPositionRef.current.get(tabId); element.scroll((_a = position == null ? void 0 : position.x) != null ? _a : 0, (_b = position == null ? void 0 : position.y) != null ? _b : 0); const onScroll = () => { scrollPositionRef.current.set(tabId, { x: element.scrollLeft, y: element.scrollTop }); }; element.addEventListener("scroll", onScroll); return () => { element.removeEventListener("scroll", onScroll); }; }, [scrollRestoration, mounted, tabId, getScrollElement, store]); const [hasTabbableChildren, setHasTabbableChildren] = useState(false); useEffect(() => { const element = ref.current; if (!element) return; const tabbable = getAllTabbableIn(element); setHasTabbableChildren(!!tabbable.length); }, []); const getItem = useCallback( (item) => { const nextItem = { ...item, id: id || item.id, tabId: tabIdProp }; if (getItemProp) { return getItemProp(nextItem); } return nextItem; }, [id, tabIdProp, getItemProp] ); const onKeyDownProp = props.onKeyDown; const onKeyDown = useEvent((event) => { onKeyDownProp == null ? void 0 : onKeyDownProp(event); if (event.defaultPrevented) return; if (!(store == null ? void 0 : store.composite)) return; const keyMap = { ArrowLeft: store.previous, ArrowRight: store.next, Home: store.first, End: store.last }; const action = keyMap[event.key]; if (!action) return; const { selectedId } = store.getState(); const nextId = action({ activeId: selectedId }); if (!nextId) return; event.preventDefault(); store.move(nextId); }); props = useWrapElement( props, (element) => /* @__PURE__ */ jsx(TabScopedContextProvider, { value: store, children: element }), [store] ); props = { id, role: "tabpanel", "aria-labelledby": tabId || void 0, ...props, children: unmountOnHide && !mounted ? null : props.children, ref: useMergeRefs(ref, props.ref), onKeyDown }; props = useFocusable({ // If the tab panel is rendered as part of another composite widget such // as combobox, it should not be focusable. focusable: !store.composite && !hasTabbableChildren, ...props }); props = useDisclosureContent({ store: disclosure, ...props }); props = useCollectionItem({ store: store.panels, ...props, getItem }); return props; } ); var TabPanel = forwardRef(function TabPanel2(props) { const htmlProps = useTabPanel(props); return createElement(TagName, htmlProps); }); export { TabPanel, useTabPanel };