Tabs
poyraz/tabsFreeComponent
Poyraz Soft Glass tabs component with standardized floating and overlay behavior.
Install it
npx shadcn@latest add https://ui.poyrazavsever.com/r/tabs.jsonSource
1"use client";23import * as React from "react";4import * as TabsPrimitive from "@radix-ui/react-tabs";56import { cn } from "@/lib/utils";7import { floatingSurfaceVariants, type FloatingSurfaceProps } from "@/components/ui/recipes";89type TabsVariant = "line" | "soft" | "glass";10const TabsStyleContext = React.createContext<{ variant: TabsVariant }>({ variant: "line" });1112const Tabs = TabsPrimitive.Root;1314const TabsList = React.forwardRef<15 React.ElementRef<typeof TabsPrimitive.List>,16 React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> & {17 variant?: TabsVariant;18 radius?: "none" | "sm" | "md" | "lg" | "full";19 }20>(({ className, variant = "line", radius = "lg", children, ...props }, forwardedRef) => {21 const listRef = React.useRef<React.ElementRef<typeof TabsPrimitive.List>>(null);22 const [indicator, setIndicator] = React.useState({ left: 0, width: 0, visible: false });2324 React.useImperativeHandle(25 forwardedRef,26 () => listRef.current as React.ElementRef<typeof TabsPrimitive.List>,27 );2829 React.useLayoutEffect(() => {30 const list = listRef.current;31 if (!list || variant !== "line") return;3233 const update = () => {34 const active = list.querySelector<HTMLElement>('[role="tab"][data-state="active"]');35 if (!active) {36 setIndicator((current) => ({ ...current, visible: false }));37 return;38 }39 setIndicator({ left: active.offsetLeft, width: active.offsetWidth, visible: true });40 };4142 update();43 const mutationObserver = new MutationObserver(update);44 mutationObserver.observe(list, {45 attributes: true,46 subtree: true,47 attributeFilter: ["data-state"],48 });49 const resizeObserver = new ResizeObserver(update);50 resizeObserver.observe(list);51 list52 .querySelectorAll<HTMLElement>('[role="tab"]')53 .forEach((tab) => resizeObserver.observe(tab));5455 return () => {56 mutationObserver.disconnect();57 resizeObserver.disconnect();58 };59 }, [variant, children]);6061 return (62 <TabsStyleContext.Provider value={{ variant }}>63 <TabsPrimitive.List64 ref={listRef}65 className={cn(66 "relative inline-flex min-h-10 max-w-full items-center overflow-x-auto overflow-y-clip p-1 text-muted-foreground [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",67 "transition-[color,background-color,border-color] duration-[var(--poyraz-motion-duration-fast)]",68// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from poyraz
All 71 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | poyraz | Components | Free | 2 deps | |
| Alertalert | poyraz | Components | Free | 2 deps | |
| Announcement Barannouncement-bar | poyraz | Components | Free | 2 deps | |
| Autocompleteautocomplete | poyraz | Components | Free | 1 dep | |
| Avataravatar | poyraz | Components | Free | 2 deps | |
| Badgebadge | poyraz | Components | Free | 1 dep | |
| Bg Patternbg-pattern | poyraz | Components | Free | no deps | |
| Breadcrumbbreadcrumb | poyraz | Components | Free | 1 dep |
