Animated Tabs

Image tabs (or FAQs) where users navigate through images using tabs

How do UI components improve UX?

UI components can improve UX by providing familiar, consistent interactions that make it easy for users to navigate and interact with an application.

How do UI components improve UX?

Important of UI component.

Is UI and UX Same?

Installation

npm install framer-motion
base
<TabsProvider defaultValue="01" className="md:grid md:grid-cols-12">
  <TabList className="md:col-span-5">
    <TabItem value={'01'}>
      <TabHeader value={'01'}>title01</TabHeader>
      <TabDes value={'01'}>description</TabDes>
    </TabItem>
    <TabItem value={'02'}>
      <TabHeader value={'02'}>title02</TabHeader>
      <TabDes value={'02'}>description</TabDes>
    </TabItem>
    <TabItem value={'03'}>
      <TabHeader value={'03'}>title03</TabHeader>
      <TabDes value={'03'}>description</TabDes>
    </TabItem>
  </TabList>
  <TabImageContainer className="md:col-span-7">
    <TabImage value={'01'}>
      <img src={''} alt={''} />
    </TabImage>
    <TabImage value={'02'}>
      <img src={''} alt={''} />
    </TabImage>
    <TabImage value={'03'}>
      <img src={''} alt={''} />
    </TabImage>
  </TabImageContainer>
</TabsProvider>
tab.tsx
'use client'
import React, { ReactNode, useState, createContext, useContext } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { cn } from '@/lib/utils'
import { useMediaQuery } from '@/hooks/use-media-query'
 
interface Tab {
  id: string
  title: string
  description: string
  imageUrl: string
}
 
interface TabsContextType {
  activeTab: string
  setActiveTab: (id: string) => void
  isDesktop: boolean
}
 
const TabsContext = createContext<TabsContextType | undefined>(undefined)
 
const useTabs = () => {
  const context = useContext(TabsContext)
  if (!context) {
    throw new Error('Tabs components must be used within a TabsProvider')
  }
  return context
}
 
export function TabsProvider({
  children,
  defaultValue,
  className,
}: {
  children: ReactNode
  defaultValue: string
  className?: string
}) {
  const [activeTab, setActiveTab] = useState(defaultValue)
  const isDesktop = useMediaQuery('(min-width: 768px)')
  return (
    <TabsContext.Provider value={{ activeTab, setActiveTab, isDesktop }}>
      <div className={cn('w-full h-full', className)}>{children}</div>
    </TabsContext.Provider>
  )
}
 
export function TabList({
  children,
  className,
}: {
  children: ReactNode
  className?: string
}) {
  return <div className={cn('rounded-sm h-fit', className)}>{children}</div>
}
 
export function TabItem({
  children,
  value,
  index,
}: {
  children: ReactNode
  value: string
  index: number
}) {
  const { activeTab, setActiveTab } = useTabs()
 
  return (
    <motion.div
      className={`rounded-lg overflow-hidden mb-2 ${
        activeTab === value
          ? 'active border-2 dark:border-[#656fe2] border-[#F2F2F2] dark:bg-[#E0ECFB] bg-[#F2F2F2]'
          : 'bg-transparent border-2 dark:hover:border-[#656fe2]'
      }`}
      onClick={() => setActiveTab(value)}
    >
      {children}
    </motion.div>
  )
}
 
export function TabHeader({
  children,
  value,
}: {
  children: ReactNode
  value: string
}) {
  const { activeTab } = useTabs()
  return (
    <h3
      className={`p-4 cursor-pointer transition-all font-semibold dark:text-white text-black dark:hover:bg-[#1e2a78] hover:bg-[#F2F2F2] dark:hover:text-white hover:text-black flex justify-between items-center ${
        activeTab === value
          ? 'active dark:bg-[#1e2a78] bg-[#F2F2F2]'
          : 'dark:bg-[#11112b] bg-white'
      }`}
    >
      {children}
    </h3>
  )
}
 
export function TabDes({
  children,
  value,
}: {
  children: ReactNode
  value: string
}) {
  const { activeTab } = useTabs()
  return (
    <AnimatePresence mode="sync">
      {activeTab === value && (
        <motion.div
          initial={{ height: 0, opacity: 0 }}
          animate={{ height: 'auto', opacity: 1 }}
          exit={{ height: 0, opacity: 0 }}
          transition={{
            duration: 0.3,
            ease: 'easeInOut',
            delay: 0.14,
          }}
        >
          <p className={`dark:bg-white bg-[#F2F2F2] text-black p-3`}>
            {children}
          </p>
        </motion.div>
      )}
    </AnimatePresence>
  )
}
 
export function TabImageContainer({
  children,
  className,
}: {
  children: ReactNode
  className?: string
}) {
  return (
    <div className={cn('', className)}>
      <AnimatePresence mode="popLayout">{children}</AnimatePresence>
    </div>
  )
}
 
export function TabImage({
  children,
  value,
  index,
}: {
  children: ReactNode
  value: string
  index: number
}) {
  const { activeTab, isDesktop } = useTabs()
 
  if (activeTab !== value || !isDesktop) return null
 
  return (
    <motion.div className="p-4 h-[400px] overflow-hidden">
      <motion.div
        initial={{ opacity: 0, overflow: 'hidden' }}
        animate={{ opacity: 1, overflow: 'hidden' }}
        exit={{ opacity: 0, overflow: 'hidden' }}
        transition={{
          duration: 0.4,
          delay: 0.2,
        }}
      >
        {children}
      </motion.div>
    </motion.div>
  )
}

Example

How do UI components improve UX?

UI components can improve UX by providing familiar, consistent interactions that make it easy for users to navigate and interact with an application.

How do UI components improve UX?

Important of UI component.

Is UI and UX Same?

withtout components

How do UI components improve UX?

UI components can improve UX by providing familiar, consistent interactions that make it easy for users to navigate and interact with an application.

How do UI components improve UX?

Important of UI component.

Is UI and UX Same?