animated-tabs
ui-layouts/animated-tabsFreeComponent
ui-layouts publishes no description for this item.
Install it
npx shadcn@latest add https://www.ui-layouts.com/r/animated-tabs.jsonSource
1'use client';23import { cn } from '@/lib/utils';4import { AnimatePresence, motion } from 'motion/react';5import React, {6 createContext,7 isValidElement,8 type ReactNode,9 useCallback,10 useContext,11 useMemo,12 useState,13} from 'react';1415// Improved TypeScript interfaces with more specific types16interface TabContextType {17 activeTab: string;18 setActiveTab: (value: string) => void;19 wobbly: boolean;20 hover: boolean;21 defaultValue: string;22 prevIndex: number;23 setPrevIndex: (value: number) => void;24 tabsOrder: string[];25}2627const TabContext = createContext<TabContextType | undefined>(undefined);2829// Custom hook with memoization30export const useTabs = () => {31 const context = useContext(TabContext);32 if (!context) {33 throw new Error('useTabs must be used within a TabsProvider');34 }35 return context;36};3738// Props interfaces with more specific types39interface TabsProviderProps {40 children: ReactNode;41 defaultValue: string;42 wobbly?: boolean;43 hover?: boolean;44}4546interface TabsBtnProps {47 children: ReactNode;48 className?: string;49 value: string;50}5152interface TabsContentProps {53 children: ReactNode;54 className?: string;55 value: string;56 yValue?: boolean;57}5859export const TabsProvider: React.FC<TabsProviderProps> = React.memo(60 ({ children, defaultValue, wobbly = true, hover = false }) => {61 // Use useCallback to memoize state setters62 const [activeTab, setActiveTab] = useState(defaultValue);63 const [prevIndex, setPrevIndex] = useState(0);6465 // Memoize tabs order to prevent unnecessary recalculations66 const tabsOrder = useMemo(() => {67 return React.Children.toArray(children)68 .filter((child) => isValidElement(child) && child.type === TabsContent)69 .map((child) => (child as React.ReactElement<any>).props.value);70 }, [children]);7172 // Memoize context value to prevent unnecessary re-renders73 const contextValue = useMemo(74 () => ({75 activeTab,76 setActiveTab,77 wobbly,78 hover,79 defaultValue,80 setPrevIndex,81 prevIndex,82 tabsOrder,83 }),84 [activeTab, setActiveTab, wobbly, hover, defaultValue, prevIndex, tabsOrder]85 );8687 return <TabContext.Provider value={contextValue}>{children}</TabContext.Provider>;88 }89);9091// Memoized TabsBtn component92export const TabsBtn: React.FC<TabsBtnProps> = React.memo(({ children, className, value }) => {93 const { activeTab, setPrevIndex, setActiveTab, defaultValue, hover, wobbly, tabsOrder } =94// … truncated
What it pulls in
npm packages
Files it writes
More from ui-layouts
All 1 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3d-marquee3d-marquee | ui-layouts | Components | Free | no deps · 2 files | |
| accordionaccordion | ui-layouts | Components | Free | no deps | |
| align-slideralign-slider | ui-layouts | Components | Free | 6 deps · 2 files | |
| animal-imagemaskinganimal-imagemasking | ui-layouts | Components | Free | 1 dep | |
| animated-beamanimated-beam | ui-layouts | Components | Free | no deps | |
| animated-beam-bidirectionalanimated-beam-bidirectional | ui-layouts | Components | Free | no deps | |
| animated-beam-defaultanimated-beam-default | ui-layouts | Components | Free | no deps | |
| animated-beam-multiple-inputanimated-beam-multiple-input | ui-layouts | Components | Free | no deps |
