@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
95 lines (94 loc) • 3.88 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useState } from "react";
import classNames from "classnames";
import TabsContext from "./TabsContext.js";
import WidthOverflow from "./WidthOverflow.internal.js";
/**
* Tabs component - switch between different content
*/ const Tabs = /*#__PURE__*/ forwardRef(({ variant = "default", noPadding = false, noBackground = false, contentBackground = "base", contentProps, radius = false, radiusTop = false, radiusBottom = false, className, children, ...props }, ref)=>{
const [active, setActive] = useState(null);
const [contentContainerRef, setContentContainerRef] = useState(null);
const tabBarStyle = {
...props.style
};
const contentStyle = {
...contentProps?.style
};
if (radius || radiusTop) {
if (radius === true || radiusTop === true) {
tabBarStyle.borderTopLeftRadius = "var(--bf-radius)";
tabBarStyle.borderTopRightRadius = "var(--bf-radius)";
} else {
tabBarStyle.borderTopLeftRadius = `var(--bf-radius-${radiusTop ?? radius})`;
tabBarStyle.borderTopRightRadius = `var(--bf-radius-${radiusTop ?? radius})`;
}
}
if (radius || radiusBottom) {
if (radius === true || radiusBottom === true) {
contentStyle.borderBottomLeftRadius = "var(--bf-radius)";
contentStyle.borderBottomRightRadius = "var(--bf-radius)";
} else {
contentStyle.borderBottomLeftRadius = `var(--bf-radius-${radiusTop ?? radius})`;
contentStyle.borderBottomRightRadius = `var(--bf-radius-${radiusTop ?? radius})`;
}
}
// `contentBackground` is used for both the content area background and
// "styled" variant active tab background color.
if (contentBackground === "transparent") {
contentStyle["--bf-tabs-content-bg"] = "transparent";
tabBarStyle["--bf-tabs-content-bg"] = "transparent";
} else if (contentBackground) {
contentStyle["--bf-tabs-content-bg"] = `var(--bfc-${contentBackground})`;
tabBarStyle["--bf-tabs-content-bg"] = `var(--bfc-${contentBackground})`;
}
let currentRenderFirstCaller = null;
const isActive = (id, disabled)=>{
if (disabled) {
return false;
}
if (active) {
return active === id;
}
// When no tab is active in shared state
// store the first caller of isActive to a variable.
// Has to be re-calculated each render (don't store in ref)
// to avoid StrictMode re-rendering and remounting
if (!currentRenderFirstCaller) {
currentRenderFirstCaller = id;
}
return currentRenderFirstCaller === id;
};
return /*#__PURE__*/ _jsxs(TabsContext.Provider, {
value: {
portal: contentContainerRef,
isActive,
setActive
},
children: [
/*#__PURE__*/ _jsx(WidthOverflow, {
...props,
className: classNames(className, "bf-tabs-container", {
"bf-tabs-styled": variant === "styled",
"bf-tabs-no-background": noBackground
}),
style: tabBarStyle,
contentProps: {
className: classNames("bf-tabs", {
"bf-tabs-no-padding": noPadding
})
},
ref: ref,
children: children
}),
/*#__PURE__*/ _jsx("div", {
...contentProps,
className: classNames("bf-tab-content", contentProps?.className),
style: contentStyle,
ref: setContentContainerRef
})
]
});
});
Tabs.displayName = "Tabs";
export default Tabs;