sticky-shadcn-tabs
v0.1.0
Published
Sticky animated tabs with shadcn style, fully customizable for React + Radix UI + Tailwind CSS
Maintainers
Readme
Sticky Shadcn Tabs
Sticky Shadcn Tabs is a modern, fully customizable sticky tabs component for React, built on top of Radix UI Tabs and Framer Motion. Designed for seamless integration with Tailwind CSS, it allows smooth sticky behavior with blur, shadow, gradient fade, and full motion customization.
Features
- Sticky
TabsListthat sticks to the top of the viewport when scrolling. - Optional backdrop blur with customizable intensity.
- Shadow and gradient fade effects for polished UI.
- Fully customizable animations via
motionVariantsandmotionConfig. - Supports offsets for fixed headers.
- Works with nested tabs.
- Tailwind-friendly, fully controllable via className props.
Installation
npm install sticky-shadcn-tabs
# or
yarn add sticky-shadcn-tabs
# or
bun add sticky-shadcn-tabsPeer Dependencies:
react>= 18react-dom>= 18@radix-ui/react-tabs>= 1.0.0framer-motion>= 10.0.0tailwindcss(optional, recommended for styling)
Usage
'use client'
import { StickyShadcnTabs } from 'sticky-shadcn-tabs'
import { TabsTrigger, TabsContent } from './BaseTabs'
export default function Example() {
return (
<StickyShadcnTabs
defaultValue="overview"
offset={64}
enableBlur
enableShadow
enableFade
blurAmount={16}
gradientHeight={12}
gradientColors="from-background/90 to-transparent"
triggers={[
<TabsTrigger key="overview" value="overview">Overview</TabsTrigger>,
<TabsTrigger key="details" value="details">Details</TabsTrigger>,
<TabsTrigger key="settings" value="settings">Settings</TabsTrigger>
]}
>
<TabsContent value="overview">
<div className="h-[2000px] p-4">Overview content here...</div>
</TabsContent>
<TabsContent value="details">
<div className="h-[2000px] p-4">Details content here...</div>
</TabsContent>
<TabsContent value="settings">
<div className="h-[2000px] p-4">Settings content here...</div>
</TabsContent>
</StickyShadcnTabs>
)
}Props
| Prop | Type | Default | Description |
| -------------------- | --------------------------------- | ------------------------------------- | ---------------------------------------------------------------------- |
| triggers | ReactNode[] | required | Array of TabsTrigger elements to render inside the sticky tab list. |
| children | ReactNode | required | TabsContent components. |
| offset | number | 0 | Vertical offset in pixels for sticky tabs (useful with fixed headers). |
| enableBlur | boolean | true | Enable backdrop blur for sticky tabs. |
| blurAmount | number | 12 | Amount of blur in pixels. |
| enableShadow | boolean | true | Add shadow to sticky tabs. |
| enableFade | boolean | true | Enable gradient fade below the sticky tabs. |
| gradientHeight | number | 8 | Height of the gradient fade in pixels. |
| gradientColors | string | 'from-background/80 to-transparent' | Tailwind gradient classes for fade. |
| motionConfig | MotionProps['transition'] | { duration: 0.3, ease: 'easeOut' } | Default Framer Motion transition configuration. |
| motionVariants | { container?, overlay?, fade? } | undefined | Custom Framer Motion variants for container, overlay, or fade. |
| listClassName | string | '' | Additional Tailwind classes for TabsList. |
| containerClassName | string | '' | Tailwind classes for the sticky container. |
| overlayClassName | string | '' | Tailwind classes for the offset overlay (top space). |
| fadeClassName | string | '' | Tailwind classes for gradient fade. |
| style | CSSProperties | undefined | Inline styles for the sticky container. |
Motion Customization
You can fully override the animations using motionVariants:
motionVariants={{
container: {
initial: { opacity: 0, y: -20 },
animate: { opacity: 1, y: 0, transition: { duration: 0.5 } },
exit: { opacity: 0, y: -20 }
},
overlay: { initial: { opacity: 0 }, animate: { opacity: 1 } },
fade: { initial: { opacity: 0 }, animate: { opacity: 0.8 } }
}}Or adjust global timing via motionConfig:
motionConfig={{ duration: 0.4, ease: 'easeInOut' }}Styling
The component is fully compatible with Tailwind CSS. You can style all elements via:
listClassName→TabsListcontainerClassName→ sticky containeroverlayClassName→ top offset overlayfadeClassName→ gradient fade
Example:
<StickyShadcnTabs
listClassName="bg-muted text-muted-foreground rounded-lg p-1"
containerClassName="border border-gray-200 shadow-lg"
overlayClassName="bg-gray-50"
fadeClassName="bg-gradient-to-b from-gray-100 to-transparent"
/>Advanced Usage
Nested tabs work seamlessly. Sticky behavior is automatically scoped to each StickyShadcnTabs instance:
<StickyShadcnTabs triggers={[...]} offset={64}>
<TabsContent value="main">
<StickyShadcnTabs triggers={[...]} offset={0}>
<TabsContent value="nested">Nested content</TabsContent>
</StickyShadcnTabs>
</TabsContent>
</StickyShadcnTabs>