@wakastellar/ui 2.3.4 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/dist/blocks/dashboard/index.d.ts +4 -1
  2. package/dist/blocks/empty-states/index.d.ts +4 -1
  3. package/dist/blocks/error-pages/index.d.ts +4 -1
  4. package/dist/blocks/index.d.ts +1 -1
  5. package/dist/blocks/landing/index.d.ts +4 -1
  6. package/dist/blocks/pricing/index.d.ts +5 -1
  7. package/dist/blocks/sidebar/index.d.ts +5 -1
  8. package/dist/index.cjs.js +130 -130
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.es.js +7905 -7856
  11. package/dist/stories/Button.d.ts +14 -0
  12. package/dist/stories/Button.stories.d.ts +8 -0
  13. package/dist/stories/Header.d.ts +11 -0
  14. package/dist/stories/Header.stories.d.ts +6 -0
  15. package/dist/stories/Page.d.ts +2 -0
  16. package/dist/stories/Page.stories.d.ts +6 -0
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/link.d.ts +23 -0
  19. package/package.json +11 -3
  20. package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
  21. package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
  22. package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
  23. package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
  24. package/src/blocks/chat/Chat.stories.tsx +466 -0
  25. package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
  26. package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
  27. package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
  28. package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
  29. package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
  30. package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
  31. package/src/blocks/dashboard/index.tsx +68 -27
  32. package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
  33. package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
  34. package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
  35. package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
  36. package/src/blocks/empty-states/index.tsx +26 -8
  37. package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
  38. package/src/blocks/error-pages/index.tsx +26 -8
  39. package/src/blocks/faq/FAQ.stories.tsx +416 -0
  40. package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
  41. package/src/blocks/footer/Footer.stories.tsx +328 -0
  42. package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
  43. package/src/blocks/header/WakaHeader.stories.tsx +455 -0
  44. package/src/blocks/headtab/Headtab.stories.tsx +369 -0
  45. package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
  46. package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
  47. package/src/blocks/index.ts +1 -1
  48. package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
  49. package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
  50. package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
  51. package/src/blocks/landing/index.tsx +125 -66
  52. package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
  53. package/src/blocks/layout/Layout.stories.tsx +373 -0
  54. package/src/blocks/login/Login.stories.tsx +443 -0
  55. package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
  56. package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
  57. package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
  58. package/src/blocks/pricing/index.tsx +38 -4
  59. package/src/blocks/profile/Profile.stories.tsx +371 -0
  60. package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
  61. package/src/blocks/settings/Settings.stories.tsx +520 -0
  62. package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
  63. package/src/blocks/sidebar/index.tsx +49 -20
  64. package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
  65. package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
  66. package/src/blocks/wizard/Wizard.stories.tsx +683 -0
  67. package/src/components/accordion/Accordion.stories.tsx +93 -0
  68. package/src/components/alert/Alert.stories.tsx +95 -0
  69. package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
  70. package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
  71. package/src/components/avatar/Avatar.stories.tsx +104 -0
  72. package/src/components/button/Button.stories.tsx +12 -1
  73. package/src/components/calendar/Calendar.stories.tsx +102 -0
  74. package/src/components/card/Card.stories.tsx +125 -0
  75. package/src/components/checkbox/Checkbox.stories.tsx +100 -0
  76. package/src/components/code/Code.stories.tsx +402 -0
  77. package/src/components/collapsible/Collapsible.stories.tsx +123 -0
  78. package/src/components/command/Command.stories.tsx +207 -0
  79. package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
  80. package/src/components/dialog/Dialog.stories.tsx +157 -0
  81. package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
  82. package/src/components/form/Form.stories.tsx +413 -0
  83. package/src/components/hover-card/HoverCard.stories.tsx +148 -0
  84. package/src/components/input-otp/InputOTP.stories.tsx +255 -0
  85. package/src/components/label/Label.stories.tsx +68 -0
  86. package/src/components/menubar/Menubar.stories.tsx +278 -0
  87. package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
  88. package/src/components/popover/Popover.stories.tsx +199 -0
  89. package/src/components/progress/Progress.stories.tsx +104 -0
  90. package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
  91. package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
  92. package/src/components/select/Select.stories.tsx +146 -0
  93. package/src/components/separator/Separator.stories.tsx +117 -0
  94. package/src/components/sheet/Sheet.stories.tsx +195 -0
  95. package/src/components/skeleton/Skeleton.stories.tsx +114 -0
  96. package/src/components/slider/Slider.stories.tsx +157 -0
  97. package/src/components/switch/Switch.stories.tsx +114 -0
  98. package/src/components/table/Table.stories.tsx +153 -0
  99. package/src/components/tabs/Tabs.stories.tsx +155 -0
  100. package/src/components/textarea/Textarea.stories.tsx +116 -0
  101. package/src/components/toast/Toast.stories.tsx +160 -0
  102. package/src/components/toggle/Toggle.stories.tsx +125 -0
  103. package/src/components/tooltip/Tooltip.stories.tsx +133 -0
  104. package/src/components/typography/Typography.stories.tsx +207 -0
  105. package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
  106. package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
  107. package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
  108. package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
  109. package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
  110. package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
  111. package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
  112. package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
  113. package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
  114. package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
  115. package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
  116. package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
  117. package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
  118. package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
  119. package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
  120. package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
  121. package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
  122. package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
  123. package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
  124. package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
  125. package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
  126. package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
  127. package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
  128. package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
  129. package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
  130. package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
  131. package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
  132. package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
  133. package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
  134. package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
  135. package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
  136. package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
  137. package/src/components/waka-image/WakaImage.stories.tsx +255 -0
  138. package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
  139. package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
  140. package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
  141. package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
  142. package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
  143. package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
  144. package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
  145. package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
  146. package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
  147. package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
  148. package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
  149. package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
  150. package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
  151. package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
  152. package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
  153. package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
  154. package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
  155. package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
  156. package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
  157. package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
  158. package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
  159. package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
  160. package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
  161. package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
  162. package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
  163. package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
  164. package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
  165. package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
  166. package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
  167. package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
  168. package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
  169. package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
  170. package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
  171. package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
  172. package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
  173. package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
  174. package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
  175. package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
  176. package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
  177. package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
  178. package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
  179. package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
  180. package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
  181. package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
  182. package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
  183. package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
  184. package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
  185. package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
  186. package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
  187. package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
  188. package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
  189. package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
  190. package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
  191. package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
  192. package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
  193. package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
  194. package/src/components/waka-xp-bar/WakaXPBar.stories.tsx +305 -0
@@ -0,0 +1,471 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaTabsMorph, WakaTabPanel, useTabs } from './index'
3
+ import type { TabItem } from './index'
4
+ import * as React from 'react'
5
+ import { Home, User, Settings, Bell, Mail, Heart, Star, Zap, Inbox, Archive, Trash2 } from 'lucide-react'
6
+
7
+ const meta: Meta<typeof WakaTabsMorph> = {
8
+ title: 'Components/Effects/WakaTabsMorph',
9
+ component: WakaTabsMorph,
10
+ parameters: {
11
+ layout: 'centered',
12
+ docs: {
13
+ description: {
14
+ component: 'Animated tabs component with morphing indicator that smoothly transitions between tabs.',
15
+ },
16
+ },
17
+ },
18
+ tags: ['autodocs'],
19
+ argTypes: {
20
+ variant: {
21
+ control: 'select',
22
+ options: ['default', 'pills', 'underline', 'enclosed'],
23
+ description: 'Tab style variant',
24
+ },
25
+ size: {
26
+ control: 'select',
27
+ options: ['sm', 'md', 'lg'],
28
+ description: 'Tab size',
29
+ },
30
+ orientation: {
31
+ control: 'select',
32
+ options: ['horizontal', 'vertical'],
33
+ description: 'Tab orientation',
34
+ },
35
+ fullWidth: {
36
+ control: 'boolean',
37
+ description: 'Full width tabs',
38
+ },
39
+ animationDuration: {
40
+ control: { type: 'range', min: 100, max: 500, step: 50 },
41
+ description: 'Animation duration in ms',
42
+ },
43
+ },
44
+ }
45
+
46
+ export default meta
47
+ type Story = StoryObj<typeof WakaTabsMorph>
48
+
49
+ const basicTabs: TabItem[] = [
50
+ { id: 'tab1', label: 'Overview' },
51
+ { id: 'tab2', label: 'Analytics' },
52
+ { id: 'tab3', label: 'Settings' },
53
+ ]
54
+
55
+ export const Default: Story = {
56
+ args: {
57
+ tabs: basicTabs,
58
+ },
59
+ render: (args) => <WakaTabsMorph {...args} />,
60
+ }
61
+
62
+ export const Variants: Story = {
63
+ render: () => (
64
+ <div className="space-y-8">
65
+ <div>
66
+ <p className="text-sm text-muted-foreground mb-2">Default</p>
67
+ <WakaTabsMorph tabs={basicTabs} variant="default" />
68
+ </div>
69
+ <div>
70
+ <p className="text-sm text-muted-foreground mb-2">Pills</p>
71
+ <WakaTabsMorph tabs={basicTabs} variant="pills" />
72
+ </div>
73
+ <div>
74
+ <p className="text-sm text-muted-foreground mb-2">Underline</p>
75
+ <WakaTabsMorph tabs={basicTabs} variant="underline" />
76
+ </div>
77
+ <div>
78
+ <p className="text-sm text-muted-foreground mb-2">Enclosed</p>
79
+ <WakaTabsMorph tabs={basicTabs} variant="enclosed" />
80
+ </div>
81
+ </div>
82
+ ),
83
+ }
84
+
85
+ export const Sizes: Story = {
86
+ render: () => (
87
+ <div className="space-y-8">
88
+ <div>
89
+ <p className="text-sm text-muted-foreground mb-2">Small</p>
90
+ <WakaTabsMorph tabs={basicTabs} size="sm" />
91
+ </div>
92
+ <div>
93
+ <p className="text-sm text-muted-foreground mb-2">Medium</p>
94
+ <WakaTabsMorph tabs={basicTabs} size="md" />
95
+ </div>
96
+ <div>
97
+ <p className="text-sm text-muted-foreground mb-2">Large</p>
98
+ <WakaTabsMorph tabs={basicTabs} size="lg" />
99
+ </div>
100
+ </div>
101
+ ),
102
+ }
103
+
104
+ export const WithIcons: Story = {
105
+ render: () => {
106
+ const iconTabs: TabItem[] = [
107
+ { id: 'home', label: 'Home', icon: <Home className="h-4 w-4" /> },
108
+ { id: 'profile', label: 'Profile', icon: <User className="h-4 w-4" /> },
109
+ { id: 'settings', label: 'Settings', icon: <Settings className="h-4 w-4" /> },
110
+ ]
111
+
112
+ return <WakaTabsMorph tabs={iconTabs} />
113
+ },
114
+ }
115
+
116
+ export const WithBadges: Story = {
117
+ render: () => {
118
+ const badgeTabs: TabItem[] = [
119
+ { id: 'inbox', label: 'Inbox', icon: <Inbox className="h-4 w-4" />, badge: 5 },
120
+ { id: 'archive', label: 'Archive', icon: <Archive className="h-4 w-4" />, badge: 12 },
121
+ { id: 'trash', label: 'Trash', icon: <Trash2 className="h-4 w-4" /> },
122
+ ]
123
+
124
+ return (
125
+ <div className="space-y-8">
126
+ <div>
127
+ <p className="text-sm text-muted-foreground mb-2">Default with badges</p>
128
+ <WakaTabsMorph tabs={badgeTabs} />
129
+ </div>
130
+ <div>
131
+ <p className="text-sm text-muted-foreground mb-2">Pills with badges</p>
132
+ <WakaTabsMorph tabs={badgeTabs} variant="pills" />
133
+ </div>
134
+ </div>
135
+ )
136
+ },
137
+ }
138
+
139
+ export const WithContent: Story = {
140
+ render: () => {
141
+ const contentTabs: TabItem[] = [
142
+ {
143
+ id: 'overview',
144
+ label: 'Overview',
145
+ icon: <Home className="h-4 w-4" />,
146
+ content: (
147
+ <div className="p-4 border rounded-lg mt-4">
148
+ <h3 className="font-semibold mb-2">Overview</h3>
149
+ <p className="text-muted-foreground">
150
+ This is the overview content. It provides a general summary of your dashboard.
151
+ </p>
152
+ </div>
153
+ ),
154
+ },
155
+ {
156
+ id: 'analytics',
157
+ label: 'Analytics',
158
+ icon: <Zap className="h-4 w-4" />,
159
+ content: (
160
+ <div className="p-4 border rounded-lg mt-4">
161
+ <h3 className="font-semibold mb-2">Analytics</h3>
162
+ <p className="text-muted-foreground">
163
+ View your analytics data and insights here.
164
+ </p>
165
+ </div>
166
+ ),
167
+ },
168
+ {
169
+ id: 'settings',
170
+ label: 'Settings',
171
+ icon: <Settings className="h-4 w-4" />,
172
+ content: (
173
+ <div className="p-4 border rounded-lg mt-4">
174
+ <h3 className="font-semibold mb-2">Settings</h3>
175
+ <p className="text-muted-foreground">
176
+ Configure your preferences and account settings.
177
+ </p>
178
+ </div>
179
+ ),
180
+ },
181
+ ]
182
+
183
+ return (
184
+ <div className="w-[500px]">
185
+ <WakaTabsMorph tabs={contentTabs} />
186
+ </div>
187
+ )
188
+ },
189
+ }
190
+
191
+ export const FullWidth: Story = {
192
+ render: () => (
193
+ <div className="w-[500px]">
194
+ <WakaTabsMorph tabs={basicTabs} fullWidth />
195
+ </div>
196
+ ),
197
+ }
198
+
199
+ export const VerticalOrientation: Story = {
200
+ render: () => {
201
+ const verticalTabs: TabItem[] = [
202
+ { id: 'general', label: 'General', icon: <Settings className="h-4 w-4" /> },
203
+ { id: 'notifications', label: 'Notifications', icon: <Bell className="h-4 w-4" /> },
204
+ { id: 'email', label: 'Email', icon: <Mail className="h-4 w-4" /> },
205
+ { id: 'privacy', label: 'Privacy', icon: <User className="h-4 w-4" /> },
206
+ ]
207
+
208
+ return (
209
+ <div className="w-[400px]">
210
+ <WakaTabsMorph
211
+ tabs={verticalTabs}
212
+ orientation="vertical"
213
+ renderContent={(tab) => (
214
+ <div className="p-4 border rounded-lg flex-1">
215
+ <h3 className="font-semibold mb-2">{tab.label} Settings</h3>
216
+ <p className="text-muted-foreground">
217
+ Configure your {tab.label.toLowerCase()} preferences here.
218
+ </p>
219
+ </div>
220
+ )}
221
+ />
222
+ </div>
223
+ )
224
+ },
225
+ }
226
+
227
+ export const VerticalVariants: Story = {
228
+ render: () => {
229
+ const verticalTabs: TabItem[] = [
230
+ { id: 'tab1', label: 'First' },
231
+ { id: 'tab2', label: 'Second' },
232
+ { id: 'tab3', label: 'Third' },
233
+ ]
234
+
235
+ return (
236
+ <div className="flex gap-12">
237
+ <div>
238
+ <p className="text-sm text-muted-foreground mb-2">Default</p>
239
+ <WakaTabsMorph tabs={verticalTabs} orientation="vertical" variant="default" />
240
+ </div>
241
+ <div>
242
+ <p className="text-sm text-muted-foreground mb-2">Pills</p>
243
+ <WakaTabsMorph tabs={verticalTabs} orientation="vertical" variant="pills" />
244
+ </div>
245
+ <div>
246
+ <p className="text-sm text-muted-foreground mb-2">Underline</p>
247
+ <WakaTabsMorph tabs={verticalTabs} orientation="vertical" variant="underline" />
248
+ </div>
249
+ </div>
250
+ )
251
+ },
252
+ }
253
+
254
+ export const DisabledTabs: Story = {
255
+ render: () => {
256
+ const tabsWithDisabled: TabItem[] = [
257
+ { id: 'active1', label: 'Active' },
258
+ { id: 'disabled', label: 'Disabled', disabled: true },
259
+ { id: 'active2', label: 'Also Active' },
260
+ ]
261
+
262
+ return <WakaTabsMorph tabs={tabsWithDisabled} />
263
+ },
264
+ }
265
+
266
+ export const Controlled: Story = {
267
+ render: () => {
268
+ const [activeTab, setActiveTab] = React.useState('tab2')
269
+
270
+ return (
271
+ <div className="space-y-4">
272
+ <WakaTabsMorph
273
+ tabs={basicTabs}
274
+ activeTab={activeTab}
275
+ onChange={setActiveTab}
276
+ />
277
+ <p className="text-sm text-muted-foreground">
278
+ Active tab: {activeTab}
279
+ </p>
280
+ <div className="flex gap-2">
281
+ {basicTabs.map((tab) => (
282
+ <button
283
+ key={tab.id}
284
+ onClick={() => setActiveTab(tab.id)}
285
+ className="px-3 py-1 text-sm border rounded hover:bg-muted"
286
+ >
287
+ Go to {tab.label}
288
+ </button>
289
+ ))}
290
+ </div>
291
+ </div>
292
+ )
293
+ },
294
+ }
295
+
296
+ export const WithHook: Story = {
297
+ render: () => {
298
+ const tabs: TabItem[] = [
299
+ { id: 'home', label: 'Home', icon: <Home className="h-4 w-4" /> },
300
+ { id: 'favorites', label: 'Favorites', icon: <Heart className="h-4 w-4" /> },
301
+ { id: 'starred', label: 'Starred', icon: <Star className="h-4 w-4" /> },
302
+ ]
303
+
304
+ const {
305
+ activeTab,
306
+ activeTabData,
307
+ setActiveTab,
308
+ goToNext,
309
+ goToPrevious,
310
+ goToFirst,
311
+ goToLast,
312
+ } = useTabs(tabs)
313
+
314
+ return (
315
+ <div className="space-y-4">
316
+ <WakaTabsMorph tabs={tabs} activeTab={activeTab} onChange={setActiveTab} />
317
+ <div className="p-4 border rounded-lg">
318
+ <p className="text-sm">
319
+ Active: <strong>{activeTabData?.label}</strong>
320
+ </p>
321
+ </div>
322
+ <div className="flex flex-wrap gap-2">
323
+ <button
324
+ onClick={goToFirst}
325
+ className="px-3 py-1 text-sm border rounded hover:bg-muted"
326
+ >
327
+ First
328
+ </button>
329
+ <button
330
+ onClick={goToPrevious}
331
+ className="px-3 py-1 text-sm border rounded hover:bg-muted"
332
+ >
333
+ Previous
334
+ </button>
335
+ <button
336
+ onClick={goToNext}
337
+ className="px-3 py-1 text-sm border rounded hover:bg-muted"
338
+ >
339
+ Next
340
+ </button>
341
+ <button
342
+ onClick={goToLast}
343
+ className="px-3 py-1 text-sm border rounded hover:bg-muted"
344
+ >
345
+ Last
346
+ </button>
347
+ </div>
348
+ </div>
349
+ )
350
+ },
351
+ }
352
+
353
+ export const WithTabPanel: Story = {
354
+ render: () => {
355
+ const tabs: TabItem[] = [
356
+ { id: 'photos', label: 'Photos', icon: <Heart className="h-4 w-4" /> },
357
+ { id: 'videos', label: 'Videos', icon: <Star className="h-4 w-4" /> },
358
+ { id: 'music', label: 'Music', icon: <Zap className="h-4 w-4" /> },
359
+ ]
360
+
361
+ const [activeTab, setActiveTab] = React.useState('photos')
362
+
363
+ return (
364
+ <div className="w-[400px]">
365
+ <WakaTabsMorph tabs={tabs} activeTab={activeTab} onChange={setActiveTab} />
366
+ <div className="mt-4">
367
+ <WakaTabPanel tabId="photos" activeTab={activeTab}>
368
+ <div className="p-4 border rounded-lg">
369
+ <h3 className="font-semibold mb-2">Photos</h3>
370
+ <p className="text-muted-foreground">Your photo library</p>
371
+ </div>
372
+ </WakaTabPanel>
373
+ <WakaTabPanel tabId="videos" activeTab={activeTab}>
374
+ <div className="p-4 border rounded-lg">
375
+ <h3 className="font-semibold mb-2">Videos</h3>
376
+ <p className="text-muted-foreground">Your video collection</p>
377
+ </div>
378
+ </WakaTabPanel>
379
+ <WakaTabPanel tabId="music" activeTab={activeTab}>
380
+ <div className="p-4 border rounded-lg">
381
+ <h3 className="font-semibold mb-2">Music</h3>
382
+ <p className="text-muted-foreground">Your music library</p>
383
+ </div>
384
+ </WakaTabPanel>
385
+ </div>
386
+ </div>
387
+ )
388
+ },
389
+ }
390
+
391
+ export const RenderContentFunction: Story = {
392
+ render: () => {
393
+ const tabs: TabItem[] = [
394
+ { id: 'overview', label: 'Overview' },
395
+ { id: 'metrics', label: 'Metrics' },
396
+ { id: 'logs', label: 'Logs' },
397
+ ]
398
+
399
+ return (
400
+ <div className="w-[500px]">
401
+ <WakaTabsMorph
402
+ tabs={tabs}
403
+ variant="underline"
404
+ renderContent={(tab) => (
405
+ <div className="p-4 mt-4 border rounded-lg bg-muted/30">
406
+ <h3 className="font-semibold mb-2">{tab.label}</h3>
407
+ <p className="text-muted-foreground">
408
+ Content for the {tab.label.toLowerCase()} tab. This is rendered dynamically.
409
+ </p>
410
+ </div>
411
+ )}
412
+ />
413
+ </div>
414
+ )
415
+ },
416
+ }
417
+
418
+ export const ManyTabs: Story = {
419
+ render: () => {
420
+ const manyTabs: TabItem[] = Array.from({ length: 7 }, (_, i) => ({
421
+ id: `tab${i + 1}`,
422
+ label: `Tab ${i + 1}`,
423
+ }))
424
+
425
+ return (
426
+ <div className="w-[600px]">
427
+ <WakaTabsMorph tabs={manyTabs} variant="underline" />
428
+ </div>
429
+ )
430
+ },
431
+ }
432
+
433
+ export const SettingsPage: Story = {
434
+ render: () => {
435
+ const settingsTabs: TabItem[] = [
436
+ { id: 'profile', label: 'Profile', icon: <User className="h-4 w-4" /> },
437
+ { id: 'account', label: 'Account', icon: <Settings className="h-4 w-4" /> },
438
+ { id: 'notifications', label: 'Notifications', icon: <Bell className="h-4 w-4" />, badge: 3 },
439
+ { id: 'security', label: 'Security', icon: <Zap className="h-4 w-4" /> },
440
+ ]
441
+
442
+ return (
443
+ <div className="w-[600px] border rounded-lg p-6">
444
+ <h2 className="text-2xl font-bold mb-6">Settings</h2>
445
+ <WakaTabsMorph
446
+ tabs={settingsTabs}
447
+ variant="enclosed"
448
+ renderContent={(tab) => (
449
+ <div className="p-4 mt-4">
450
+ <h3 className="text-lg font-semibold mb-4">{tab.label}</h3>
451
+ <div className="space-y-4">
452
+ <div className="flex items-center justify-between p-3 bg-muted/50 rounded-md">
453
+ <span>Option 1</span>
454
+ <button className="px-3 py-1 text-sm bg-primary text-primary-foreground rounded">
455
+ Edit
456
+ </button>
457
+ </div>
458
+ <div className="flex items-center justify-between p-3 bg-muted/50 rounded-md">
459
+ <span>Option 2</span>
460
+ <button className="px-3 py-1 text-sm bg-primary text-primary-foreground rounded">
461
+ Edit
462
+ </button>
463
+ </div>
464
+ </div>
465
+ </div>
466
+ )}
467
+ />
468
+ </div>
469
+ )
470
+ },
471
+ }