UNPKG

@trail-ui/react

Version:
76 lines (74 loc) 2.8 kB
// src/tabs/tabs.tsx import { useIsMounted } from "@trail-ui/hooks"; import { clsx } from "@trail-ui/shared-utils"; import { filterVariantProps, tabs } from "@trail-ui/theme"; import { cloneElement, createContext, isValidElement, useContext, useMemo } from "react"; import { Tab as AriaTab, TabList as AriaTabList, TabPanel as AriaTabPanel, Tabs as AriaTabs } from "react-aria-components"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var InternalTabsContext = createContext( {} ); function Tabs(props) { const { className, classNames, indicator, onSelectionChange, ...otherProps } = props; const variantProps = filterVariantProps(props, tabs.variantKeys); const slots = useMemo(() => tabs({ ...variantProps }), [variantProps]); const baseStyles = clsx(classNames == null ? void 0 : classNames.base, className); return /* @__PURE__ */ jsx(InternalTabsContext.Provider, { value: { slots, classNames, indicator }, children: /* @__PURE__ */ jsx( AriaTabs, { ...otherProps, onSelectionChange, className: slots.base({ class: baseStyles }) } ) }); } function TabList(props) { const { slots, classNames } = useContext(InternalTabsContext); return /* @__PURE__ */ jsx(AriaTabList, { ...props, className: slots.tabList({ class: classNames == null ? void 0 : classNames.tabList }) }); } function Tab(props) { const { slots, classNames, indicator } = useContext(InternalTabsContext); const { children } = props; const [, isMounted] = useIsMounted({ rerender: true }); const getIndicatoContent = () => { if (indicator === null) { return null; } if (indicator) { if (!isValidElement(indicator)) return null; return cloneElement(indicator, { className: slots.cursor({ class: classNames == null ? void 0 : classNames.cursor }) }); } return /* @__PURE__ */ jsx("span", { className: slots.cursor({ class: classNames == null ? void 0 : classNames.cursor }) }); }; return /* @__PURE__ */ jsx(AriaTab, { ...props, className: slots.tab({ class: classNames == null ? void 0 : classNames.tab }), children: (renderProps) => /* @__PURE__ */ jsxs(Fragment, { children: [ renderProps.isSelected && isMounted ? getIndicatoContent() : null, /* @__PURE__ */ jsx("div", { className: slots.tabContent({ class: classNames == null ? void 0 : classNames.tabContent }), children: typeof children === "function" ? children(renderProps) : children }) ] }) }); } function TabPanel(props) { const { slots, classNames } = useContext(InternalTabsContext); return /* @__PURE__ */ jsx(AriaTabPanel, { ...props, className: slots.panel({ class: classNames == null ? void 0 : classNames.panel }) }); } export { InternalTabsContext, Tabs, TabList, Tab, TabPanel };