@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,203 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaVideo } from './index'
3
+
4
+ const meta: Meta<typeof WakaVideo> = {
5
+ title: 'Components/Display/WakaVideo',
6
+ component: WakaVideo,
7
+ parameters: {
8
+ layout: 'centered',
9
+ docs: {
10
+ description: {
11
+ component: 'A video player component with custom controls, fullscreen support, and playback speed options.',
12
+ },
13
+ },
14
+ },
15
+ tags: ['autodocs'],
16
+ argTypes: {
17
+ autoPlay: {
18
+ control: 'boolean',
19
+ description: 'Auto-play the video',
20
+ },
21
+ loop: {
22
+ control: 'boolean',
23
+ description: 'Loop the video',
24
+ },
25
+ muted: {
26
+ control: 'boolean',
27
+ description: 'Mute the video',
28
+ },
29
+ controls: {
30
+ control: 'boolean',
31
+ description: 'Show video controls',
32
+ },
33
+ showFullscreen: {
34
+ control: 'boolean',
35
+ description: 'Show fullscreen button',
36
+ },
37
+ showPlaybackSpeed: {
38
+ control: 'boolean',
39
+ description: 'Show playback speed selector',
40
+ },
41
+ },
42
+ }
43
+
44
+ export default meta
45
+ type Story = StoryObj<typeof WakaVideo>
46
+
47
+ // Sample video URL (Big Buck Bunny - open source)
48
+ const sampleVideoUrl = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
49
+ const samplePosterUrl = 'https://images.unsplash.com/photo-1536440136628-849c177e76a1?w=800&q=80'
50
+
51
+ export const Default: Story = {
52
+ args: {
53
+ src: sampleVideoUrl,
54
+ poster: samplePosterUrl,
55
+ width: 640,
56
+ },
57
+ }
58
+
59
+ export const WithPoster: Story = {
60
+ args: {
61
+ src: sampleVideoUrl,
62
+ poster: samplePosterUrl,
63
+ width: 640,
64
+ },
65
+ }
66
+
67
+ export const AutoPlay: Story = {
68
+ args: {
69
+ src: sampleVideoUrl,
70
+ autoPlay: true,
71
+ muted: true,
72
+ width: 640,
73
+ },
74
+ }
75
+
76
+ export const Looping: Story = {
77
+ args: {
78
+ src: sampleVideoUrl,
79
+ loop: true,
80
+ autoPlay: true,
81
+ muted: true,
82
+ width: 640,
83
+ },
84
+ }
85
+
86
+ export const NoControls: Story = {
87
+ render: () => (
88
+ <div className="space-y-4">
89
+ <p className="text-sm text-muted-foreground">Video without custom controls (click to play/pause)</p>
90
+ <WakaVideo
91
+ src={sampleVideoUrl}
92
+ poster={samplePosterUrl}
93
+ controls={false}
94
+ width={640}
95
+ />
96
+ </div>
97
+ ),
98
+ }
99
+
100
+ export const AspectRatios: Story = {
101
+ render: () => (
102
+ <div className="space-y-8">
103
+ <div>
104
+ <p className="text-sm text-muted-foreground mb-2">16:9 (Default)</p>
105
+ <WakaVideo
106
+ src={sampleVideoUrl}
107
+ poster={samplePosterUrl}
108
+ width={500}
109
+ aspectRatio="16/9"
110
+ />
111
+ </div>
112
+ <div>
113
+ <p className="text-sm text-muted-foreground mb-2">4:3</p>
114
+ <WakaVideo
115
+ src={sampleVideoUrl}
116
+ poster={samplePosterUrl}
117
+ width={500}
118
+ aspectRatio="4/3"
119
+ />
120
+ </div>
121
+ <div>
122
+ <p className="text-sm text-muted-foreground mb-2">1:1 (Square)</p>
123
+ <WakaVideo
124
+ src={sampleVideoUrl}
125
+ poster={samplePosterUrl}
126
+ width={400}
127
+ aspectRatio="1/1"
128
+ />
129
+ </div>
130
+ </div>
131
+ ),
132
+ }
133
+
134
+ export const MinimalControls: Story = {
135
+ args: {
136
+ src: sampleVideoUrl,
137
+ poster: samplePosterUrl,
138
+ width: 640,
139
+ showFullscreen: false,
140
+ showPlaybackSpeed: false,
141
+ },
142
+ }
143
+
144
+ export const WithCallbacks: Story = {
145
+ render: () => (
146
+ <div className="space-y-4">
147
+ <p className="text-sm text-muted-foreground">Check console for callback events</p>
148
+ <WakaVideo
149
+ src={sampleVideoUrl}
150
+ poster={samplePosterUrl}
151
+ width={640}
152
+ onReady={() => console.log('Video ready')}
153
+ onPlay={() => console.log('Video playing')}
154
+ onPause={() => console.log('Video paused')}
155
+ onEnded={() => console.log('Video ended')}
156
+ onTimeUpdate={(time) => console.log('Current time:', time.toFixed(2))}
157
+ />
158
+ </div>
159
+ ),
160
+ }
161
+
162
+ export const VideoInCard: Story = {
163
+ render: () => (
164
+ <div className="w-[500px] border rounded-lg overflow-hidden">
165
+ <WakaVideo
166
+ src={sampleVideoUrl}
167
+ poster={samplePosterUrl}
168
+ className="rounded-none"
169
+ />
170
+ <div className="p-4">
171
+ <h3 className="font-semibold">Big Buck Bunny</h3>
172
+ <p className="text-sm text-muted-foreground mt-1">
173
+ A short animated film by the Blender Institute
174
+ </p>
175
+ <div className="flex gap-2 mt-3">
176
+ <span className="text-xs bg-muted px-2 py-1 rounded">Animation</span>
177
+ <span className="text-xs bg-muted px-2 py-1 rounded">Comedy</span>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ ),
182
+ }
183
+
184
+ export const ResponsiveVideo: Story = {
185
+ render: () => (
186
+ <div className="w-full max-w-[800px]">
187
+ <WakaVideo
188
+ src={sampleVideoUrl}
189
+ poster={samplePosterUrl}
190
+ width="100%"
191
+ />
192
+ </div>
193
+ ),
194
+ }
195
+
196
+ export const FixedHeight: Story = {
197
+ args: {
198
+ src: sampleVideoUrl,
199
+ poster: samplePosterUrl,
200
+ width: 640,
201
+ height: 300,
202
+ },
203
+ }
@@ -0,0 +1,273 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaVirtualList } from './index'
3
+ import * as React from 'react'
4
+
5
+ const meta: Meta<typeof WakaVirtualList> = {
6
+ title: 'Components/Display/WakaVirtualList',
7
+ component: WakaVirtualList,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A virtualized list component for efficiently rendering large datasets with support for variable heights and infinite scrolling.',
13
+ },
14
+ },
15
+ },
16
+ tags: ['autodocs'],
17
+ argTypes: {
18
+ height: {
19
+ control: { type: 'number' },
20
+ description: 'Container height in pixels',
21
+ },
22
+ overscan: {
23
+ control: { type: 'number' },
24
+ description: 'Number of items to pre-render',
25
+ },
26
+ },
27
+ }
28
+
29
+ export default meta
30
+ type Story = StoryObj<typeof WakaVirtualList>
31
+
32
+ // Generate mock data
33
+ const generateItems = (count: number) =>
34
+ Array.from({ length: count }, (_, i) => ({
35
+ id: i + 1,
36
+ title: `Item ${i + 1}`,
37
+ description: `This is the description for item ${i + 1}`,
38
+ }))
39
+
40
+ const items1000 = generateItems(1000)
41
+ const items10000 = generateItems(10000)
42
+
43
+ export const Default: Story = {
44
+ args: {
45
+ items: items1000,
46
+ itemHeight: 60,
47
+ height: 400,
48
+ },
49
+ render: (args) => (
50
+ <div className="border rounded-lg overflow-hidden w-[400px]">
51
+ <WakaVirtualList
52
+ {...args}
53
+ renderItem={(item, index, style) => (
54
+ <div style={style} className="px-4 py-2 border-b hover:bg-muted/50">
55
+ <div className="font-medium">{item.title}</div>
56
+ <div className="text-sm text-muted-foreground">{item.description}</div>
57
+ </div>
58
+ )}
59
+ />
60
+ </div>
61
+ ),
62
+ }
63
+
64
+ export const LargeDataset: Story = {
65
+ render: () => (
66
+ <div className="border rounded-lg overflow-hidden w-[400px]">
67
+ <div className="p-2 bg-muted text-sm text-center">
68
+ 10,000 items - Scroll to see virtualization
69
+ </div>
70
+ <WakaVirtualList
71
+ items={items10000}
72
+ itemHeight={50}
73
+ height={500}
74
+ renderItem={(item, index, style) => (
75
+ <div
76
+ style={style}
77
+ className={`px-4 py-2 border-b ${index % 2 === 0 ? 'bg-background' : 'bg-muted/30'}`}
78
+ >
79
+ <div className="flex items-center justify-between">
80
+ <span className="font-medium">{item.title}</span>
81
+ <span className="text-xs text-muted-foreground">#{item.id}</span>
82
+ </div>
83
+ </div>
84
+ )}
85
+ />
86
+ </div>
87
+ ),
88
+ }
89
+
90
+ export const VariableHeight: Story = {
91
+ render: () => {
92
+ const variableItems = generateItems(500).map((item, i) => ({
93
+ ...item,
94
+ expanded: i % 5 === 0,
95
+ }))
96
+
97
+ return (
98
+ <div className="border rounded-lg overflow-hidden w-[400px]">
99
+ <WakaVirtualList
100
+ items={variableItems}
101
+ itemHeight={(item) => (item.expanded ? 100 : 50)}
102
+ height={400}
103
+ renderItem={(item, index, style) => (
104
+ <div
105
+ style={style}
106
+ className="px-4 py-2 border-b hover:bg-muted/50"
107
+ >
108
+ <div className="font-medium">{item.title}</div>
109
+ {item.expanded && (
110
+ <div className="mt-2 text-sm text-muted-foreground">
111
+ <p>This item has expanded content with more details.</p>
112
+ <p>Additional information goes here.</p>
113
+ </div>
114
+ )}
115
+ </div>
116
+ )}
117
+ />
118
+ </div>
119
+ )
120
+ },
121
+ }
122
+
123
+ export const WithInfiniteScroll: Story = {
124
+ render: () => {
125
+ const [items, setItems] = React.useState(() => generateItems(50))
126
+ const [isLoading, setIsLoading] = React.useState(false)
127
+
128
+ const loadMore = () => {
129
+ if (isLoading) return
130
+ setIsLoading(true)
131
+ setTimeout(() => {
132
+ const newItems = generateItems(50).map((item) => ({
133
+ ...item,
134
+ id: items.length + item.id,
135
+ title: `Item ${items.length + item.id}`,
136
+ }))
137
+ setItems(prev => [...prev, ...newItems])
138
+ setIsLoading(false)
139
+ }, 1000)
140
+ }
141
+
142
+ return (
143
+ <div className="border rounded-lg overflow-hidden w-[400px]">
144
+ <div className="p-2 bg-muted text-sm text-center">
145
+ Loaded: {items.length} items - Scroll to load more
146
+ </div>
147
+ <WakaVirtualList
148
+ items={items}
149
+ itemHeight={60}
150
+ height={400}
151
+ onEndReached={loadMore}
152
+ endReachedThreshold={300}
153
+ isLoading={isLoading}
154
+ loadingElement={
155
+ <div className="flex items-center justify-center gap-2 text-sm text-muted-foreground">
156
+ <div className="h-4 w-4 border-2 border-primary border-t-transparent rounded-full animate-spin" />
157
+ Loading more items...
158
+ </div>
159
+ }
160
+ renderItem={(item, index, style) => (
161
+ <div style={style} className="px-4 py-2 border-b hover:bg-muted/50">
162
+ <div className="font-medium">{item.title}</div>
163
+ <div className="text-sm text-muted-foreground">{item.description}</div>
164
+ </div>
165
+ )}
166
+ />
167
+ </div>
168
+ )
169
+ },
170
+ }
171
+
172
+ export const EmptyState: Story = {
173
+ render: () => (
174
+ <div className="border rounded-lg overflow-hidden w-[400px]">
175
+ <WakaVirtualList
176
+ items={[]}
177
+ itemHeight={60}
178
+ height={300}
179
+ emptyElement={
180
+ <div className="text-center">
181
+ <p className="text-muted-foreground">No items to display</p>
182
+ <p className="text-sm text-muted-foreground mt-1">Add some items to see them here</p>
183
+ </div>
184
+ }
185
+ renderItem={() => null}
186
+ />
187
+ </div>
188
+ ),
189
+ }
190
+
191
+ export const ContactList: Story = {
192
+ render: () => {
193
+ const contacts = Array.from({ length: 200 }, (_, i) => ({
194
+ id: i + 1,
195
+ name: `Contact ${i + 1}`,
196
+ email: `contact${i + 1}@example.com`,
197
+ avatar: `https://i.pravatar.cc/40?img=${(i % 70) + 1}`,
198
+ }))
199
+
200
+ return (
201
+ <div className="border rounded-lg overflow-hidden w-[350px]">
202
+ <div className="p-3 border-b bg-muted/50">
203
+ <h3 className="font-semibold">Contacts</h3>
204
+ <p className="text-sm text-muted-foreground">{contacts.length} people</p>
205
+ </div>
206
+ <WakaVirtualList
207
+ items={contacts}
208
+ itemHeight={64}
209
+ height={400}
210
+ renderItem={(contact, index, style) => (
211
+ <div
212
+ style={style}
213
+ className="flex items-center gap-3 px-4 py-2 border-b hover:bg-muted/50 cursor-pointer"
214
+ >
215
+ <img
216
+ src={contact.avatar}
217
+ alt={contact.name}
218
+ className="w-10 h-10 rounded-full"
219
+ />
220
+ <div>
221
+ <div className="font-medium">{contact.name}</div>
222
+ <div className="text-sm text-muted-foreground">{contact.email}</div>
223
+ </div>
224
+ </div>
225
+ )}
226
+ />
227
+ </div>
228
+ )
229
+ },
230
+ }
231
+
232
+ export const TableLike: Story = {
233
+ render: () => {
234
+ const data = Array.from({ length: 500 }, (_, i) => ({
235
+ id: i + 1,
236
+ name: `Product ${i + 1}`,
237
+ category: ['Electronics', 'Clothing', 'Books', 'Home'][i % 4],
238
+ price: (Math.random() * 100 + 10).toFixed(2),
239
+ stock: Math.floor(Math.random() * 100),
240
+ }))
241
+
242
+ return (
243
+ <div className="border rounded-lg overflow-hidden w-[600px]">
244
+ <div className="grid grid-cols-5 gap-2 px-4 py-2 bg-muted font-medium text-sm border-b">
245
+ <div>ID</div>
246
+ <div>Name</div>
247
+ <div>Category</div>
248
+ <div>Price</div>
249
+ <div>Stock</div>
250
+ </div>
251
+ <WakaVirtualList
252
+ items={data}
253
+ itemHeight={44}
254
+ height={400}
255
+ renderItem={(row, index, style) => (
256
+ <div
257
+ style={style}
258
+ className={`grid grid-cols-5 gap-2 px-4 py-2 border-b text-sm ${
259
+ index % 2 === 0 ? 'bg-background' : 'bg-muted/20'
260
+ }`}
261
+ >
262
+ <div className="text-muted-foreground">#{row.id}</div>
263
+ <div>{row.name}</div>
264
+ <div>{row.category}</div>
265
+ <div>${row.price}</div>
266
+ <div>{row.stock}</div>
267
+ </div>
268
+ )}
269
+ />
270
+ </div>
271
+ )
272
+ },
273
+ }