UNPKG

@stratakit/structures

Version:

Medium-sized component structures for the Strata design system

99 lines (98 loc) 2.79 kB
import { jsx } from "react/jsx-runtime"; import { useStoreState } from "@ariakit/react/store"; import * as AkTab from "@ariakit/react/tab"; import { forwardRef, isBrowser, useUnreactiveCallback } from "@stratakit/foundations/secret-internals"; import cx from "classnames"; const supportsAnchorPositioning = isBrowser && CSS?.supports("anchor-name: --foo"); const prefersReducedMotion = () => isBrowser && window.matchMedia("(prefers-reduced-motion)").matches; function Tabs(props) { const { defaultSelectedId, selectedId, setSelectedId, selectOnMove, children } = props; const store = AkTab.useTabStore({ defaultSelectedId }); const tablist = useStoreState(store, "baseElement"); const selectedIdFromStore = useStoreState(store, "selectedId"); const flipAnimateStripe = (newSelectedId) => { if (!supportsAnchorPositioning) return; const rootNode = tablist?.getRootNode(); if (!rootNode || !selectedIdFromStore || !newSelectedId) return; const previousTabRect = rootNode.getElementById?.(selectedIdFromStore)?.getBoundingClientRect(); const nextTabRect = rootNode.getElementById?.(newSelectedId)?.getBoundingClientRect(); if (!previousTabRect || !nextTabRect) return; const deltaX = previousTabRect.left - nextTabRect.left; const deltaWidth = previousTabRect.width / nextTabRect.width; tablist?.animate( [ { transform: `translateX(${deltaX}px) scaleX(${deltaWidth})` }, { transform: "none" } ], { pseudoElement: "::after", duration: 150, easing: "ease-in-out" } ); }; return /* @__PURE__ */ jsx( AkTab.TabProvider, { store, selectedId, setSelectedId: useUnreactiveCallback( (newSelectedId) => { if (!prefersReducedMotion()) flipAnimateStripe(newSelectedId); setSelectedId?.(newSelectedId); } ), selectOnMove, children } ); } const TabList = forwardRef((props, forwardedRef) => { const { tone = "neutral", ...rest } = props; return /* @__PURE__ */ jsx( AkTab.TabList, { ...rest, "data-kiwi-tone": tone, className: cx("\u{1F95D}-tab-list", props.className), ref: forwardedRef } ); }); const Tab = forwardRef((props, forwardedRef) => { return /* @__PURE__ */ jsx( AkTab.Tab, { accessibleWhenDisabled: true, ...props, className: cx("\u{1F95D}-tab", props.className), ref: forwardedRef } ); }); const TabPanel = forwardRef((props, forwardedRef) => { return /* @__PURE__ */ jsx( AkTab.TabPanel, { ...props, className: cx("\u{1F95D}-tab-panel", props.className), ref: forwardedRef } ); }); export { Tabs as Root, Tab, TabList, TabPanel };