@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.
- package/dist/blocks/dashboard/index.d.ts +4 -1
- package/dist/blocks/empty-states/index.d.ts +4 -1
- package/dist/blocks/error-pages/index.d.ts +4 -1
- package/dist/blocks/index.d.ts +1 -1
- package/dist/blocks/landing/index.d.ts +4 -1
- package/dist/blocks/pricing/index.d.ts +5 -1
- package/dist/blocks/sidebar/index.d.ts +5 -1
- package/dist/index.cjs.js +130 -130
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +7905 -7856
- package/dist/stories/Button.d.ts +14 -0
- package/dist/stories/Button.stories.d.ts +8 -0
- package/dist/stories/Header.d.ts +11 -0
- package/dist/stories/Header.stories.d.ts +6 -0
- package/dist/stories/Page.d.ts +2 -0
- package/dist/stories/Page.stories.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/link.d.ts +23 -0
- package/package.json +11 -3
- package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
- package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
- package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
- package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
- package/src/blocks/chat/Chat.stories.tsx +466 -0
- package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
- package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
- package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
- package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
- package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
- package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
- package/src/blocks/dashboard/index.tsx +68 -27
- package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
- package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
- package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
- package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
- package/src/blocks/empty-states/index.tsx +26 -8
- package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
- package/src/blocks/error-pages/index.tsx +26 -8
- package/src/blocks/faq/FAQ.stories.tsx +416 -0
- package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
- package/src/blocks/footer/Footer.stories.tsx +328 -0
- package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
- package/src/blocks/header/WakaHeader.stories.tsx +455 -0
- package/src/blocks/headtab/Headtab.stories.tsx +369 -0
- package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
- package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
- package/src/blocks/index.ts +1 -1
- package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
- package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
- package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
- package/src/blocks/landing/index.tsx +125 -66
- package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
- package/src/blocks/layout/Layout.stories.tsx +373 -0
- package/src/blocks/login/Login.stories.tsx +443 -0
- package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
- package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
- package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
- package/src/blocks/pricing/index.tsx +38 -4
- package/src/blocks/profile/Profile.stories.tsx +371 -0
- package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
- package/src/blocks/settings/Settings.stories.tsx +520 -0
- package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
- package/src/blocks/sidebar/index.tsx +49 -20
- package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
- package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
- package/src/blocks/wizard/Wizard.stories.tsx +683 -0
- package/src/components/accordion/Accordion.stories.tsx +93 -0
- package/src/components/alert/Alert.stories.tsx +95 -0
- package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
- package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
- package/src/components/avatar/Avatar.stories.tsx +104 -0
- package/src/components/button/Button.stories.tsx +12 -1
- package/src/components/calendar/Calendar.stories.tsx +102 -0
- package/src/components/card/Card.stories.tsx +125 -0
- package/src/components/checkbox/Checkbox.stories.tsx +100 -0
- package/src/components/code/Code.stories.tsx +402 -0
- package/src/components/collapsible/Collapsible.stories.tsx +123 -0
- package/src/components/command/Command.stories.tsx +207 -0
- package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
- package/src/components/dialog/Dialog.stories.tsx +157 -0
- package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
- package/src/components/form/Form.stories.tsx +413 -0
- package/src/components/hover-card/HoverCard.stories.tsx +148 -0
- package/src/components/input-otp/InputOTP.stories.tsx +255 -0
- package/src/components/label/Label.stories.tsx +68 -0
- package/src/components/menubar/Menubar.stories.tsx +278 -0
- package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
- package/src/components/popover/Popover.stories.tsx +199 -0
- package/src/components/progress/Progress.stories.tsx +104 -0
- package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
- package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
- package/src/components/select/Select.stories.tsx +146 -0
- package/src/components/separator/Separator.stories.tsx +117 -0
- package/src/components/sheet/Sheet.stories.tsx +195 -0
- package/src/components/skeleton/Skeleton.stories.tsx +114 -0
- package/src/components/slider/Slider.stories.tsx +157 -0
- package/src/components/switch/Switch.stories.tsx +114 -0
- package/src/components/table/Table.stories.tsx +153 -0
- package/src/components/tabs/Tabs.stories.tsx +155 -0
- package/src/components/textarea/Textarea.stories.tsx +116 -0
- package/src/components/toast/Toast.stories.tsx +160 -0
- package/src/components/toggle/Toggle.stories.tsx +125 -0
- package/src/components/tooltip/Tooltip.stories.tsx +133 -0
- package/src/components/typography/Typography.stories.tsx +207 -0
- package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
- package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
- package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
- package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
- package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
- package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
- package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
- package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
- package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
- package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
- package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
- package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
- package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
- package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
- package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
- package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
- package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
- package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
- package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
- package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
- package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
- package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
- package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
- package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
- package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
- package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
- package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
- package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
- package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
- package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
- package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
- package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
- package/src/components/waka-image/WakaImage.stories.tsx +255 -0
- package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
- package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
- package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
- package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
- package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
- package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
- package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
- package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
- package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
- package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
- package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
- package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
- package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
- package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
- package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
- package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
- package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
- package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
- package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
- package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
- package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
- package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
- package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
- package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
- package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
- package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
- package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
- package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
- package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
- package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
- package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
- package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
- package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
- package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
- package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
- package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
- package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
- package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
- package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
- package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
- package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
- package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
- package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
- package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
- package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
- package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
- package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
- package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
- package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
- package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
- package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
- package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
- package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
- package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
- package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
- package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
- 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
|
+
}
|