fumadocs-ui
Version:
The Radix UI version of Fumadocs UI
81 lines (78 loc) • 2.7 kB
JavaScript
'use client';
import { jsx } from "react/jsx-runtime";
import { createContext, use, useEffectEvent, useLayoutEffect, useMemo, useRef, useState } from "react";
import * as Primitive from "@radix-ui/react-tabs";
import { mergeRefs } from "@fumadocs/ui/merge-refs";
//#region src/components/ui/tabs.tsx
const listeners = /* @__PURE__ */ new Map();
const TabsContext = createContext(null);
function useTabContext() {
const ctx = use(TabsContext);
if (!ctx) throw new Error("You must wrap your component in <Tabs>");
return ctx;
}
const TabsList = Primitive.TabsList;
const TabsTrigger = Primitive.TabsTrigger;
function Tabs({ ref, groupId, persist = false, updateAnchor = false, defaultValue, value: _value, onValueChange: _onValueChange, ...props }) {
const tabsRef = useRef(null);
const valueToIdMap = useMemo(() => /* @__PURE__ */ new Map(), []);
const [value, setValue] = _value === void 0 ? useState(defaultValue) : [_value, useEffectEvent((v) => _onValueChange?.(v))];
useLayoutEffect(() => {
if (!groupId) return;
let previous = sessionStorage.getItem(groupId);
if (persist) previous ??= localStorage.getItem(groupId);
if (previous) setValue(previous);
const groupListeners = listeners.get(groupId) ?? /* @__PURE__ */ new Set();
groupListeners.add(setValue);
listeners.set(groupId, groupListeners);
return () => {
groupListeners.delete(setValue);
};
}, [
groupId,
persist,
setValue
]);
useLayoutEffect(() => {
const hash = window.location.hash.slice(1);
if (!hash) return;
for (const [value$1, id] of valueToIdMap.entries()) if (id === hash) {
setValue(value$1);
tabsRef.current?.scrollIntoView();
break;
}
}, [setValue, valueToIdMap]);
return /* @__PURE__ */ jsx(Primitive.Tabs, {
ref: mergeRefs(ref, tabsRef),
value,
onValueChange: (v) => {
if (updateAnchor) {
const id = valueToIdMap.get(v);
if (id) window.history.replaceState(null, "", `#${id}`);
}
if (groupId) {
const groupListeners = listeners.get(groupId);
if (groupListeners) for (const listener of groupListeners) listener(v);
sessionStorage.setItem(groupId, v);
if (persist) localStorage.setItem(groupId, v);
} else setValue(v);
},
...props,
children: /* @__PURE__ */ jsx(TabsContext, {
value: useMemo(() => ({ valueToIdMap }), [valueToIdMap]),
children: props.children
})
});
}
function TabsContent({ value, ...props }) {
const { valueToIdMap } = useTabContext();
if (props.id) valueToIdMap.set(value, props.id);
return /* @__PURE__ */ jsx(Primitive.TabsContent, {
value,
...props,
children: props.children
});
}
//#endregion
export { Tabs, TabsContent, TabsList, TabsTrigger };
//# sourceMappingURL=tabs.js.map