UNPKG

@alice-ui/react

Version:
76 lines (74 loc) 2.87 kB
// src/tabs/tabs.tsx import { useIsMounted } from "@alice-ui/hooks"; import { clsx } from "@alice-ui/shared-utils"; import { filterVariantProps, tabs } from "@alice-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, ...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, 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 }), style: (styleProps) => styleProps.isHovered && !styleProps.isSelected ? { opacity: 0.5 } : {}, 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 };