UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

98 lines (97 loc) 4 kB
"use strict"; 'use client'; Object.defineProperty(exports, "__esModule", { value: true }); exports.useTabsIndicator = useTabsIndicator; var React = _interopRequireWildcard(require("react")); var _mergeReactProps = require("../../utils/mergeReactProps"); var _useForcedRerendering = require("../../utils/useForcedRerendering"); var _TabsIndicatorCssVars = require("./TabsIndicatorCssVars"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function round(value) { return Math.round(value * 100) * 0.01; } function useTabsIndicator(parameters) { const { value, tabsListRef, getTabElementBySelectedValue } = parameters; const rerender = (0, _useForcedRerendering.useForcedRerendering)(); React.useEffect(() => { if (value != null && tabsListRef.current != null && typeof ResizeObserver !== 'undefined') { const resizeObserver = new ResizeObserver(() => { rerender(); }); resizeObserver.observe(tabsListRef.current); return () => { resizeObserver.disconnect(); }; } return undefined; }, [value, tabsListRef, rerender]); let left = 0; let right = 0; let top = 0; let bottom = 0; let width = 0; let height = 0; let isTabSelected = false; if (value != null && tabsListRef.current != null) { const selectedTabElement = getTabElementBySelectedValue(value); isTabSelected = true; if (selectedTabElement != null) { const { left: tabLeft, right: tabRight, bottom: tabBottom, top: tabTop } = selectedTabElement.getBoundingClientRect(); const { left: listLeft, right: listRight, top: listTop, bottom: listBottom } = tabsListRef.current.getBoundingClientRect(); left = round(tabLeft - listLeft); right = round(listRight - tabRight); top = round(tabTop - listTop); bottom = round(listBottom - tabBottom); width = round(tabRight - tabLeft); height = round(tabBottom - tabTop); } } const activeTabPosition = React.useMemo(() => isTabSelected ? { left, right, top, bottom } : null, [left, right, top, bottom, isTabSelected]); const style = React.useMemo(() => { if (!isTabSelected) { return undefined; } return { [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabLeft]: `${left}px`, [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabRight]: `${right}px`, [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabTop]: `${top}px`, [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabBottom]: `${bottom}px`, [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabWidth]: `${width}px`, [_TabsIndicatorCssVars.TabsIndicatorCssVars.activeTabHeight]: `${height}px` }; }, [left, right, top, bottom, width, height, isTabSelected]); const displayIndicator = isTabSelected && width > 0 && height > 0; const getRootProps = React.useCallback((externalProps = {}) => { return (0, _mergeReactProps.mergeReactProps)(externalProps, { role: 'presentation', style, hidden: !displayIndicator // do not display the indicator before the layout is settled }); }, [style, displayIndicator]); return { getRootProps, activeTabPosition }; }