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
1
<TabsProvider defaultValue='01' className='md:grid md:grid-cols-12'>
2
<TabList className='md:col-span-5'>
3
<TabItem value={'01'}>
4
<TabHeader value={'01'}>title01</TabHeader>
5
<TabDes value={'01'}>description</TabDes>
6
</TabItem>
7
<TabItem value={'02'}>
8
<TabHeader value={'02'}>title02</TabHeader>
9
<TabDes value={'02'}>description</TabDes>
10
</TabItem>
11
<TabItem value={'03'}>
12
<TabHeader value={'03'}>title03</TabHeader>
13
<TabDes value={'03'}>description</TabDes>
14
</TabItem>
15
</TabList>
16
<TabImageContainer className='md:col-span-7'>
17
<TabImage value={'01'}>
18
<img src={''} alt={''} />
19
</TabImage>
20
<TabImage value={'02'}>
21
<img src={''} alt={''} />
22
</TabImage>
23
<TabImage value={'03'}>
24
<img src={''} alt={''} />
25
</TabImage>
26
</TabImageContainer>
27
</TabsProvider>
image-tab.tsx
1
'use client';
2
import React, { ReactNode, useState, createContext, useContext } from 'react';
3
import { AnimatePresence, motion } from 'framer-motion';
4
import { cn } from '@/lib/utils';
5
import { useMediaQuery } from '@/hooks/use-media-query';
6
7
interface Tab {
8
id: string;
9
title: string;
10
description: string;
11
imageUrl: string;
12
}
13
14
interface TabsContextType {
15
activeTab: string;
16
setActiveTab: (id: string) => void;
17
isDesktop: boolean;
18
}
19
20
const TabsContext = createContext<TabsContextType | undefined>(undefined);
21
22
const useTabs = () => {
23
const context = useContext(TabsContext);
24
if (!context) {
25
throw new Error('Tabs components must be used within a TabsProvider');
26
}
27
return context;
28
};
29
30
export function TabsProvider({
31
children,
32
defaultValue,
33
className,
34
}: {
35
children: ReactNode;
36
defaultValue: string;
37
className?: string;
38
}) {
39
const [activeTab, setActiveTab] = useState(defaultValue);
40
const isDesktop = useMediaQuery('(min-width: 768px)');
41
return (
42
<TabsContext.Provider value={{ activeTab, setActiveTab, isDesktop }}>
43
<div className={cn('w-full h-full', className)}>{children}</div>
44
</TabsContext.Provider>
45
);
46
}
47
48
export function TabList({
49
children,
50
className,
51
}: {
52
children: ReactNode;
53
className?: string;
54
}) {
55
return <div className={cn('rounded-sm h-fit', className)}>{children}</div>;
56
}
57
58
export function TabItem({
59
children,
60
value,
61
index,
62
}: {
63
children: ReactNode;
64
value: string;
65
index: number;
66
}) {
67
const { activeTab, setActiveTab } = useTabs();
68
69
return (
70
<motion.div
71
className={`rounded-lg overflow-hidden mb-2 ${
72
activeTab === value
73
? 'active border-2 dark:border-[#656fe2] border-[#F2F2F2] dark:bg-[#E0ECFB] bg-[#F2F2F2]'
74
: 'bg-transparent border-2 dark:hover:border-[#656fe2]'
75
}`}
76
onClick={() => setActiveTab(value)}
77
>
78
{children}
79
</motion.div>
80
);
81
}
82
83
export function TabHeader({
84
children,
85
value,
86
}: {
87
children: ReactNode;
88
value: string;
89
}) {
90
const { activeTab } = useTabs();
91
return (
92
<h3
93
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 ${
94
activeTab === value
95
? 'active dark:bg-[#1e2a78] bg-[#F2F2F2]'
96
: 'dark:bg-[#11112b] bg-white'
97
}`}
98
>
99
{children}
100
</h3>
101
);
102
}
103
104
export function TabDes({
105
children,
106
value,
107
}: {
108
children: ReactNode;
109
value: string;
110
}) {
111
const { activeTab } = useTabs();
112
return (
113
<AnimatePresence mode='sync'>
114
{activeTab === value && (
115
<motion.div
116
initial={{ height: 0, opacity: 0 }}
117
animate={{ height: 'auto', opacity: 1 }}
118
exit={{ height: 0, opacity: 0 }}
119
transition={{
120
duration: 0.3,
121
ease: 'easeInOut',
122
delay: 0.14,
123
}}
124
>
125
<p className={`dark:bg-white bg-[#F2F2F2] text-black p-3`}>
126
{children}
127
</p>
128
</motion.div>
129
)}
130
</AnimatePresence>
131
);
132
}
133
134
export function TabImageContainer({
135
children,
136
className,
137
}: {
138
children: ReactNode;
139
className?: string;
140
}) {
141
return (
142
<div className={cn('', className)}>
143
<AnimatePresence mode='popLayout'>{children}</AnimatePresence>
144
</div>
145
);
146
}
147
148
export function TabImage({
149
children,
150
value,
151
index,
152
}: {
153
children: ReactNode;
154
value: string;
155
index: number;
156
}) {
157
const { activeTab, isDesktop } = useTabs();
158
159
if (activeTab !== value || !isDesktop) return null;
160
161
return (
162
<motion.div className='p-4 h-[400px] overflow-hidden'>
163
<motion.div
164
initial={{ opacity: 0, overflow: 'hidden' }}
165
animate={{ opacity: 1, overflow: 'hidden' }}
166
exit={{ opacity: 0, overflow: 'hidden' }}
167
transition={{
168
duration: 0.4,
169
delay: 0.2,
170
}}
171
>
172
{children}
173
</motion.div>
174
</motion.div>
175
);
176
}

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?

Without 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?