1
+ import type { Meta , StoryObj } from "@storybook/react" ;
2
+
3
+ import { CrossfadeTabPanels as CrossfadeTabPanelsComponent } from "./index.jsx" ;
4
+ import { TabList } from "../TabList/index.jsx" ;
5
+ import { Tabs } from "../unstyled/Tabs/index.jsx" ;
6
+ import styles from "./index.stories.module.scss" ;
7
+
8
+ const meta = {
9
+ component : CrossfadeTabPanelsComponent ,
10
+ parameters : {
11
+ docs : {
12
+ description : {
13
+ component :
14
+ "CrossfadeTabPanels provides animated transitions between tab panels using a crossfade effect. It must be used within a Tabs context." ,
15
+ } ,
16
+ } ,
17
+ } ,
18
+ argTypes : {
19
+ items : {
20
+ description : "Array of tab panel items with id, optional className, and children" ,
21
+ table : {
22
+ category : "Props" ,
23
+ } ,
24
+ } ,
25
+ } ,
26
+ tags : [ "autodocs" ] ,
27
+ } satisfies Meta < typeof CrossfadeTabPanelsComponent > ;
28
+ export default meta ;
29
+
30
+ type Story = StoryObj < typeof CrossfadeTabPanelsComponent > ;
31
+
32
+ export const Default : Story = {
33
+ render : ( ) => (
34
+ < Tabs defaultSelectedKey = "tab1" >
35
+ < TabList
36
+ label = "Example tabs"
37
+ items = { [
38
+ { id : "tab1" , children : "Tab 1" } ,
39
+ { id : "tab2" , children : "Tab 2" } ,
40
+ { id : "tab3" , children : "Tab 3" } ,
41
+ ] }
42
+ />
43
+ < CrossfadeTabPanelsComponent
44
+ items = { [
45
+ {
46
+ id : "tab1" ,
47
+ children : (
48
+ < div className = { styles . tabContent } >
49
+ < h2 className = { styles . heading } > Tab 1 Content</ h2 >
50
+ < p > This is the content for the first tab.</ p >
51
+ </ div >
52
+ ) ,
53
+ } ,
54
+ {
55
+ id : "tab2" ,
56
+ children : (
57
+ < div className = { styles . tabContent } >
58
+ < h2 className = { styles . heading } > Tab 2 Content</ h2 >
59
+ < p > This is the content for the second tab.</ p >
60
+ < p > Notice how it crossfades when switching tabs.</ p >
61
+ </ div >
62
+ ) ,
63
+ } ,
64
+ {
65
+ id : "tab3" ,
66
+ children : (
67
+ < div className = { styles . tabContent } >
68
+ < h2 className = { styles . heading } > Tab 3 Content</ h2 >
69
+ < p > This is the content for the third tab.</ p >
70
+ < ul className = { styles . list } >
71
+ < li > Item 1</ li >
72
+ < li > Item 2</ li >
73
+ < li > Item 3</ li >
74
+ </ ul >
75
+ </ div >
76
+ ) ,
77
+ } ,
78
+ ] }
79
+ />
80
+ </ Tabs >
81
+ ) ,
82
+ } ;
83
+
84
+ export const WithCustomStyling : Story = {
85
+ render : ( ) => (
86
+ < Tabs defaultSelectedKey = "home" >
87
+ < TabList
88
+ label = "Navigation tabs"
89
+ items = { [
90
+ { id : "home" , children : "Home" } ,
91
+ { id : "about" , children : "About" } ,
92
+ { id : "contact" , children : "Contact" } ,
93
+ ] }
94
+ />
95
+ < CrossfadeTabPanelsComponent
96
+ items = { [
97
+ {
98
+ id : "home" ,
99
+ children : (
100
+ < div className = { styles . homePanel } >
101
+ < h2 className = { styles . heading } > Welcome Home</ h2 >
102
+ < p > This panel has custom styling with a blue theme.</ p >
103
+ </ div >
104
+ ) ,
105
+ } ,
106
+ {
107
+ id : "about" ,
108
+ children : (
109
+ < div className = { styles . aboutPanel } >
110
+ < h2 className = { styles . heading } > About Us</ h2 >
111
+ < p > This panel has custom styling with a green theme.</ p >
112
+ </ div >
113
+ ) ,
114
+ } ,
115
+ {
116
+ id : "contact" ,
117
+ children : (
118
+ < div className = { styles . contactPanel } >
119
+ < h2 className = { styles . heading } > Contact Us</ h2 >
120
+ < p > This panel has custom styling with a yellow theme.</ p >
121
+ </ div >
122
+ ) ,
123
+ } ,
124
+ ] }
125
+ />
126
+ </ Tabs >
127
+ ) ,
128
+ } ;
129
+
130
+ export const DifferentHeights : Story = {
131
+ render : ( ) => (
132
+ < Tabs defaultSelectedKey = "short" >
133
+ < TabList
134
+ label = "Content tabs"
135
+ items = { [
136
+ { id : "short" , children : "Short Content" } ,
137
+ { id : "medium" , children : "Medium Content" } ,
138
+ { id : "long" , children : "Long Content" } ,
139
+ ] }
140
+ />
141
+ < CrossfadeTabPanelsComponent
142
+ items = { [
143
+ {
144
+ id : "short" ,
145
+ children : (
146
+ < div className = { styles . tabContent } >
147
+ < h2 className = { styles . heading } > Short Content</ h2 >
148
+ < p > Just a single paragraph here.</ p >
149
+ </ div >
150
+ ) ,
151
+ } ,
152
+ {
153
+ id : "medium" ,
154
+ children : (
155
+ < div className = { styles . tabContent } >
156
+ < h2 className = { styles . heading } > Medium Content</ h2 >
157
+ < p > This tab has more content than the first one.</ p >
158
+ < p > It includes multiple paragraphs to show how the crossfade handles different heights.</ p >
159
+ < p > The animation should smoothly transition between different content sizes.</ p >
160
+ </ div >
161
+ ) ,
162
+ } ,
163
+ {
164
+ id : "long" ,
165
+ children : (
166
+ < div className = { styles . tabContent } >
167
+ < h2 className = { styles . heading } > Long Content</ h2 >
168
+ < p > This tab contains the most content to demonstrate height transitions.</ p >
169
+ < h3 > Section 1</ h3 >
170
+ < p > Lorem ipsum dolor sit amet, consectetur adipiscing elit.</ p >
171
+ < h3 > Section 2</ h3 >
172
+ < p > Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</ p >
173
+ < h3 > Section 3</ h3 >
174
+ < p > Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</ p >
175
+ </ div >
176
+ ) ,
177
+ } ,
178
+ ] }
179
+ />
180
+ </ Tabs >
181
+ ) ,
182
+ } ;
183
+
184
+ export const ComplexContent : Story = {
185
+ render : ( ) => (
186
+ < Tabs defaultSelectedKey = "dashboard" >
187
+ < TabList
188
+ label = "Application sections"
189
+ items = { [
190
+ { id : "dashboard" , children : "Dashboard" } ,
191
+ { id : "analytics" , children : "Analytics" } ,
192
+ { id : "settings" , children : "Settings" } ,
193
+ ] }
194
+ />
195
+ < CrossfadeTabPanelsComponent
196
+ items = { [
197
+ {
198
+ id : "dashboard" ,
199
+ children : (
200
+ < div className = { styles . tabContent } >
201
+ < h2 className = { styles . heading } > Dashboard</ h2 >
202
+ < div className = { styles . grid } >
203
+ < div className = { styles . widget } >
204
+ < h3 > Widget 1</ h3 >
205
+ < p > Some dashboard content</ p >
206
+ </ div >
207
+ < div className = { styles . widget } >
208
+ < h3 > Widget 2</ h3 >
209
+ < p > More dashboard content</ p >
210
+ </ div >
211
+ </ div >
212
+ </ div >
213
+ ) ,
214
+ } ,
215
+ {
216
+ id : "analytics" ,
217
+ children : (
218
+ < div className = { styles . tabContent } >
219
+ < h2 className = { styles . heading } > Analytics</ h2 >
220
+ < div className = { styles . section } >
221
+ < div className = { styles . chartPlaceholder } >
222
+ < h3 > Chart Placeholder</ h3 >
223
+ < div className = { styles . chart } >
224
+ Chart would go here
225
+ </ div >
226
+ </ div >
227
+ < p > Analytics data and insights would be displayed in this panel.</ p >
228
+ </ div >
229
+ </ div >
230
+ ) ,
231
+ } ,
232
+ {
233
+ id : "settings" ,
234
+ children : (
235
+ < div className = { styles . tabContent } >
236
+ < h2 className = { styles . heading } > Settings</ h2 >
237
+ < form className = { styles . form } >
238
+ < div className = { styles . formField } >
239
+ < label className = { styles . label } > Setting 1</ label >
240
+ < input type = "text" className = { styles . input } />
241
+ </ div >
242
+ < div className = { styles . formField } >
243
+ < label className = { styles . label } > Setting 2</ label >
244
+ < select className = { styles . select } >
245
+ < option > Option 1</ option >
246
+ < option > Option 2</ option >
247
+ </ select >
248
+ </ div >
249
+ < button type = "button" className = { styles . button } >
250
+ Save Settings
251
+ </ button >
252
+ </ form >
253
+ </ div >
254
+ ) ,
255
+ } ,
256
+ ] }
257
+ />
258
+ </ Tabs >
259
+ ) ,
260
+ } ;
0 commit comments