fumadocs-ui
Version:
The Radix UI version of Fumadocs UI
86 lines (85 loc) • 3.35 kB
JavaScript
"use client";
import { cn } from "../../../utils/cn.js";
import { Popover, PopoverContent, PopoverTrigger } from "../../../components/ui/popover.js";
import { isLayoutTabActive } from "../../shared/index.js";
import Link from "fumadocs-core/link";
import { usePathname } from "fumadocs-core/framework";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { Check, ChevronsUpDown } from "lucide-react";
import { useMemo, useState } from "react";
import { AnimatePresence, motion } from "motion/react";
//#region src/layouts/flux/slots/tab-dropdown.tsx
function TabDropdown({ tabs, placeholder, className, ...props }) {
const [open, setOpen] = useState(false);
const pathname = usePathname();
const selectedIdx = useMemo(() => {
return tabs.findLastIndex((item) => isLayoutTabActive(item, pathname));
}, [tabs, pathname]);
const selected = selectedIdx !== -1 ? tabs[selectedIdx] : void 0;
const onClick = () => {
setOpen(false);
};
const item = selected ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
className: "size-4.5 shrink-0 empty:hidden",
children: selected.icon
}), /* @__PURE__ */ jsx("p", {
className: "font-medium",
children: selected.title
})] }) : placeholder;
return /* @__PURE__ */ jsxs(Popover, {
open,
onOpenChange: setOpen,
children: [item && /* @__PURE__ */ jsxs(PopoverTrigger, {
className: cn("flex items-center gap-2 rounded-xl overflow-hidden p-1.5 border shadow-sm text-sm text-start transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground data-[state=open]:bg-fd-accent data-[state=open]:text-fd-accent-foreground", className),
...props,
children: [/* @__PURE__ */ jsx(AnimatePresence, {
mode: "popLayout",
children: /* @__PURE__ */ jsx(motion.span, {
className: "flex w-full min-w-0 overflow-hidden items-center text-nowrap gap-1.5",
initial: {
opacity: 0,
y: "100%"
},
animate: {
opacity: 1,
y: 0
},
exit: {
opacity: 0,
y: "-100%"
},
children: item
}, selectedIdx)
}), /* @__PURE__ */ jsx(ChevronsUpDown, { className: "shrink-0 ms-auto size-4 text-fd-muted-foreground" })]
}), /* @__PURE__ */ jsx(PopoverContent, {
align: "start",
className: "flex flex-col gap-1 max-w-svw p-1 fd-scroll-container",
children: tabs.map((item, i) => {
const isActive = i === selectedIdx;
if (!isActive && item.unlisted) return;
return /* @__PURE__ */ jsxs(Link, {
href: item.url,
onClick,
...item.props,
className: cn("flex items-center gap-1.5 rounded-lg p-1.5 hover:bg-fd-accent hover:text-fd-accent-foreground", item.props?.className),
children: [
/* @__PURE__ */ jsx("div", {
className: "shrink-0 mb-auto size-4.5 empty:hidden",
children: item.icon
}),
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
className: "text-sm font-medium leading-none",
children: item.title
}), /* @__PURE__ */ jsx("p", {
className: "text-[0.8125rem] text-fd-muted-foreground mt-1 empty:hidden",
children: item.description
})] }),
/* @__PURE__ */ jsx(Check, { className: cn("shrink-0 ms-auto size-3.5 text-fd-primary", !isActive && "invisible") })
]
}, item.url);
})
})]
});
}
//#endregion
export { TabDropdown };