@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,317 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaDateTimePicker } from './index'
3
+ import * as React from 'react'
4
+
5
+ const meta: Meta<typeof WakaDateTimePicker> = {
6
+ title: 'Components/Forms/WakaDateTimePicker',
7
+ component: WakaDateTimePicker,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A comprehensive date/time picker with single date, range, multiple selection, presets and validation.',
13
+ },
14
+ },
15
+ },
16
+ tags: ['autodocs'],
17
+ argTypes: {
18
+ variant: {
19
+ control: 'select',
20
+ options: ['date', 'time', 'datetime', 'range', 'multiple'],
21
+ description: 'Picker variant',
22
+ },
23
+ size: {
24
+ control: 'select',
25
+ options: ['sm', 'md', 'lg'],
26
+ description: 'Size of the component',
27
+ },
28
+ locale: {
29
+ control: 'select',
30
+ options: ['fr', 'en', 'es', 'de'],
31
+ description: 'Locale for date formatting',
32
+ },
33
+ timeFormat: {
34
+ control: 'select',
35
+ options: ['12h', '24h'],
36
+ description: 'Time format',
37
+ },
38
+ disabled: {
39
+ control: 'boolean',
40
+ description: 'Disable the picker',
41
+ },
42
+ },
43
+ }
44
+
45
+ export default meta
46
+ type Story = StoryObj<typeof WakaDateTimePicker>
47
+
48
+ export const Default: Story = {
49
+ render: function DatePickerDemo() {
50
+ const [date, setDate] = React.useState<Date | null>(null)
51
+
52
+ return (
53
+ <div className="w-[300px]">
54
+ <WakaDateTimePicker
55
+ value={date}
56
+ onChange={(d) => setDate(d as Date | null)}
57
+ label="Select Date"
58
+ placeholder="Pick a date"
59
+ />
60
+ </div>
61
+ )
62
+ },
63
+ }
64
+
65
+ export const DateOnly: Story = {
66
+ render: function DateOnlyDemo() {
67
+ const [date, setDate] = React.useState<Date | null>(new Date())
68
+
69
+ return (
70
+ <div className="w-[300px]">
71
+ <WakaDateTimePicker
72
+ value={date}
73
+ onChange={(d) => setDate(d as Date | null)}
74
+ variant="date"
75
+ label="Date"
76
+ />
77
+ </div>
78
+ )
79
+ },
80
+ }
81
+
82
+ export const TimeOnly: Story = {
83
+ render: function TimeOnlyDemo() {
84
+ const [time, setTime] = React.useState<Date | null>(new Date())
85
+
86
+ return (
87
+ <div className="w-[300px]">
88
+ <WakaDateTimePicker
89
+ value={time}
90
+ onChange={(t) => setTime(t as Date | null)}
91
+ variant="time"
92
+ label="Time"
93
+ timeFormat="24h"
94
+ />
95
+ </div>
96
+ )
97
+ },
98
+ }
99
+
100
+ export const DateTime: Story = {
101
+ render: function DateTimeDemo() {
102
+ const [datetime, setDatetime] = React.useState<Date | null>(new Date())
103
+
104
+ return (
105
+ <div className="w-[300px]">
106
+ <WakaDateTimePicker
107
+ value={datetime}
108
+ onChange={(dt) => setDatetime(dt as Date | null)}
109
+ variant="datetime"
110
+ label="Date & Time"
111
+ showSeconds={false}
112
+ />
113
+ </div>
114
+ )
115
+ },
116
+ }
117
+
118
+ export const DateRange: Story = {
119
+ render: function DateRangeDemo() {
120
+ const [range, setRange] = React.useState<{ from?: Date; to?: Date } | null>(null)
121
+
122
+ return (
123
+ <div className="w-[400px]">
124
+ <WakaDateTimePicker
125
+ value={range}
126
+ onChange={(r) => setRange(r as { from?: Date; to?: Date } | null)}
127
+ variant="range"
128
+ label="Date Range"
129
+ monthsShown={2}
130
+ />
131
+ </div>
132
+ )
133
+ },
134
+ }
135
+
136
+ export const WithPresets: Story = {
137
+ render: function PresetsDemo() {
138
+ const [range, setRange] = React.useState<{ from?: Date; to?: Date } | null>(null)
139
+
140
+ return (
141
+ <div className="w-[400px]">
142
+ <WakaDateTimePicker
143
+ value={range}
144
+ onChange={(r) => setRange(r as { from?: Date; to?: Date } | null)}
145
+ variant="range"
146
+ label="Date Range with Presets"
147
+ showPresets
148
+ monthsShown={2}
149
+ />
150
+ </div>
151
+ )
152
+ },
153
+ }
154
+
155
+ export const MultipleDates: Story = {
156
+ render: function MultipleDatesDemo() {
157
+ const [dates, setDates] = React.useState<Date[] | null>([])
158
+
159
+ return (
160
+ <div className="w-[300px]">
161
+ <WakaDateTimePicker
162
+ value={dates}
163
+ onChange={(d) => setDates(d as Date[] | null)}
164
+ variant="multiple"
165
+ label="Select Multiple Dates"
166
+ />
167
+ </div>
168
+ )
169
+ },
170
+ }
171
+
172
+ export const WithMinMax: Story = {
173
+ render: function MinMaxDemo() {
174
+ const [date, setDate] = React.useState<Date | null>(null)
175
+ const today = new Date()
176
+ const minDate = new Date(today.getFullYear(), today.getMonth(), 1)
177
+ const maxDate = new Date(today.getFullYear(), today.getMonth() + 1, 0)
178
+
179
+ return (
180
+ <div className="w-[300px]">
181
+ <WakaDateTimePicker
182
+ value={date}
183
+ onChange={(d) => setDate(d as Date | null)}
184
+ label="Select Date (This Month Only)"
185
+ minDate={minDate}
186
+ maxDate={maxDate}
187
+ />
188
+ </div>
189
+ )
190
+ },
191
+ }
192
+
193
+ export const WithValidation: Story = {
194
+ render: function ValidationDemo() {
195
+ const [date, setDate] = React.useState<Date | null>(null)
196
+
197
+ return (
198
+ <div className="w-[300px]">
199
+ <WakaDateTimePicker
200
+ value={date}
201
+ onChange={(d) => setDate(d as Date | null)}
202
+ label="No Weekends"
203
+ validation={{
204
+ disabledDaysOfWeek: [0, 6],
205
+ message: 'Weekends are not available',
206
+ }}
207
+ />
208
+ </div>
209
+ )
210
+ },
211
+ }
212
+
213
+ export const Inline: Story = {
214
+ render: function InlineDemo() {
215
+ const [date, setDate] = React.useState<Date | null>(new Date())
216
+
217
+ return (
218
+ <div className="w-[350px]">
219
+ <WakaDateTimePicker
220
+ value={date}
221
+ onChange={(d) => setDate(d as Date | null)}
222
+ label="Inline Calendar"
223
+ inline
224
+ />
225
+ </div>
226
+ )
227
+ },
228
+ }
229
+
230
+ export const Sizes: Story = {
231
+ render: function SizesDemo() {
232
+ return (
233
+ <div className="space-y-4 w-[300px]">
234
+ <WakaDateTimePicker
235
+ value={new Date()}
236
+ size="sm"
237
+ label="Small"
238
+ />
239
+ <WakaDateTimePicker
240
+ value={new Date()}
241
+ size="md"
242
+ label="Medium"
243
+ />
244
+ <WakaDateTimePicker
245
+ value={new Date()}
246
+ size="lg"
247
+ label="Large"
248
+ />
249
+ </div>
250
+ )
251
+ },
252
+ }
253
+
254
+ export const Locales: Story = {
255
+ render: function LocalesDemo() {
256
+ const [date, setDate] = React.useState<Date | null>(new Date())
257
+
258
+ return (
259
+ <div className="space-y-4 w-[300px]">
260
+ <WakaDateTimePicker
261
+ value={date}
262
+ onChange={(d) => setDate(d as Date | null)}
263
+ locale="fr"
264
+ label="French"
265
+ />
266
+ <WakaDateTimePicker
267
+ value={date}
268
+ onChange={(d) => setDate(d as Date | null)}
269
+ locale="en"
270
+ label="English"
271
+ />
272
+ <WakaDateTimePicker
273
+ value={date}
274
+ onChange={(d) => setDate(d as Date | null)}
275
+ locale="de"
276
+ label="German"
277
+ />
278
+ </div>
279
+ )
280
+ },
281
+ }
282
+
283
+ export const WithError: Story = {
284
+ render: () => (
285
+ <div className="w-[300px]">
286
+ <WakaDateTimePicker
287
+ label="Required Date"
288
+ required
289
+ error="This field is required"
290
+ />
291
+ </div>
292
+ ),
293
+ }
294
+
295
+ export const Disabled: Story = {
296
+ render: () => (
297
+ <div className="w-[300px]">
298
+ <WakaDateTimePicker
299
+ value={new Date()}
300
+ label="Disabled"
301
+ disabled
302
+ />
303
+ </div>
304
+ ),
305
+ }
306
+
307
+ export const ReadOnly: Story = {
308
+ render: () => (
309
+ <div className="w-[300px]">
310
+ <WakaDateTimePicker
311
+ value={new Date()}
312
+ label="Read Only"
313
+ readOnly
314
+ />
315
+ </div>
316
+ ),
317
+ }
@@ -0,0 +1,292 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaDeploymentLane, useDeploymentLane } from './index'
3
+ import type { Environment, Deployment } from './index'
4
+ import * as React from 'react'
5
+
6
+ const sampleEnvironments: Environment[] = [
7
+ {
8
+ id: 'dev',
9
+ name: 'Development',
10
+ deployments: [
11
+ { id: 'deploy-1', version: '2.1.0', commit: 'abc123f', status: 'running', deployedAt: new Date(Date.now() - 30 * 60 * 1000), deployedBy: 'john.doe' },
12
+ { id: 'deploy-2', version: '2.0.5', commit: 'def456a', status: 'stopped', deployedAt: new Date(Date.now() - 2 * 60 * 60 * 1000), deployedBy: 'jane.smith' },
13
+ ],
14
+ },
15
+ {
16
+ id: 'staging',
17
+ name: 'Staging',
18
+ deployments: [
19
+ { id: 'deploy-3', version: '2.0.5', commit: 'def456a', status: 'running', deployedAt: new Date(Date.now() - 4 * 60 * 60 * 1000), deployedBy: 'jane.smith' },
20
+ ],
21
+ },
22
+ {
23
+ id: 'prod',
24
+ name: 'Production',
25
+ requiresApproval: true,
26
+ approvers: ['admin', 'tech-lead', 'cto'],
27
+ deployments: [
28
+ { id: 'deploy-4', version: '2.0.4', commit: 'ghi789b', status: 'running', deployedAt: new Date(Date.now() - 24 * 60 * 60 * 1000), deployedBy: 'admin' },
29
+ ],
30
+ },
31
+ ]
32
+
33
+ const deployingEnvironments: Environment[] = [
34
+ {
35
+ id: 'dev',
36
+ name: 'Development',
37
+ deployments: [
38
+ { id: 'deploy-1', version: '2.1.1', commit: 'xyz789c', status: 'deploying', deployedAt: new Date(), deployedBy: 'dev-bot' },
39
+ { id: 'deploy-2', version: '2.1.0', commit: 'abc123f', status: 'running', deployedAt: new Date(Date.now() - 30 * 60 * 1000), deployedBy: 'john.doe' },
40
+ ],
41
+ },
42
+ {
43
+ id: 'staging',
44
+ name: 'Staging',
45
+ deployments: [
46
+ { id: 'deploy-3', version: '2.1.0', commit: 'abc123f', status: 'running', deployedAt: new Date(Date.now() - 60 * 60 * 1000) },
47
+ ],
48
+ },
49
+ {
50
+ id: 'prod',
51
+ name: 'Production',
52
+ requiresApproval: true,
53
+ deployments: [
54
+ { id: 'deploy-4', version: '2.0.5', commit: 'def456a', status: 'running', deployedAt: new Date(Date.now() - 12 * 60 * 60 * 1000) },
55
+ ],
56
+ },
57
+ ]
58
+
59
+ const failedEnvironments: Environment[] = [
60
+ {
61
+ id: 'dev',
62
+ name: 'Development',
63
+ deployments: [
64
+ { id: 'deploy-1', version: '2.1.1', commit: 'xyz789c', status: 'failed', deployedAt: new Date(Date.now() - 15 * 60 * 1000), deployedBy: 'dev-bot' },
65
+ { id: 'deploy-2', version: '2.1.0', commit: 'abc123f', status: 'running', deployedAt: new Date(Date.now() - 60 * 60 * 1000) },
66
+ ],
67
+ },
68
+ {
69
+ id: 'staging',
70
+ name: 'Staging',
71
+ deployments: [
72
+ { id: 'deploy-3', version: '2.1.0', commit: 'abc123f', status: 'running', deployedAt: new Date(Date.now() - 2 * 60 * 60 * 1000) },
73
+ ],
74
+ },
75
+ {
76
+ id: 'prod',
77
+ name: 'Production',
78
+ requiresApproval: true,
79
+ deployments: [],
80
+ },
81
+ ]
82
+
83
+ const meta: Meta<typeof WakaDeploymentLane> = {
84
+ title: 'Components/DevOps/WakaDeploymentLane',
85
+ component: WakaDeploymentLane,
86
+ parameters: {
87
+ layout: 'centered',
88
+ docs: {
89
+ description: {
90
+ component: 'A deployment lane visualization with environment stages, version tracking, promotion workflow, approval gates, and drag-and-drop support.',
91
+ },
92
+ },
93
+ },
94
+ tags: ['autodocs'],
95
+ argTypes: {
96
+ draggable: {
97
+ control: 'boolean',
98
+ description: 'Enable drag and drop between environments',
99
+ },
100
+ },
101
+ }
102
+
103
+ export default meta
104
+ type Story = StoryObj<typeof WakaDeploymentLane>
105
+
106
+ export const Default: Story = {
107
+ args: {
108
+ environments: sampleEnvironments,
109
+ },
110
+ render: (args) => (
111
+ <WakaDeploymentLane
112
+ {...args}
113
+ onPromote={(deploymentId, fromEnv, toEnv) => console.log('Promote:', deploymentId, fromEnv, '->', toEnv)}
114
+ onRollback={(deploymentId, envId) => console.log('Rollback:', deploymentId, 'in', envId)}
115
+ />
116
+ ),
117
+ }
118
+
119
+ export const Deploying: Story = {
120
+ render: () => (
121
+ <WakaDeploymentLane
122
+ environments={deployingEnvironments}
123
+ onPromote={(deploymentId, fromEnv, toEnv) => console.log('Promote:', deploymentId, fromEnv, '->', toEnv)}
124
+ />
125
+ ),
126
+ }
127
+
128
+ export const WithFailure: Story = {
129
+ render: () => (
130
+ <WakaDeploymentLane
131
+ environments={failedEnvironments}
132
+ onPromote={(deploymentId, fromEnv, toEnv) => console.log('Promote:', deploymentId, fromEnv, '->', toEnv)}
133
+ onRollback={(deploymentId, envId) => console.log('Rollback:', deploymentId, 'in', envId)}
134
+ />
135
+ ),
136
+ }
137
+
138
+ export const NoDragDrop: Story = {
139
+ render: () => (
140
+ <WakaDeploymentLane
141
+ environments={sampleEnvironments}
142
+ draggable={false}
143
+ onPromote={(deploymentId, fromEnv, toEnv) => console.log('Promote:', deploymentId, fromEnv, '->', toEnv)}
144
+ />
145
+ ),
146
+ }
147
+
148
+ export const WithHook: Story = {
149
+ render: () => {
150
+ const {
151
+ environments,
152
+ promoteDeployment,
153
+ rollbackDeployment,
154
+ addDeployment,
155
+ updateDeploymentStatus,
156
+ } = useDeploymentLane(sampleEnvironments)
157
+
158
+ const handlePromote = (deploymentId: string, fromEnv: string, toEnv: string) => {
159
+ promoteDeployment(deploymentId, fromEnv, toEnv)
160
+ // Simulate deployment completion
161
+ setTimeout(() => {
162
+ const newDeploymentId = `${deploymentId}-${toEnv}`
163
+ updateDeploymentStatus(newDeploymentId, toEnv, 'running')
164
+ }, 2000)
165
+ }
166
+
167
+ const handleDeploy = () => {
168
+ const version = `2.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 10)}`
169
+ addDeployment('dev', {
170
+ version,
171
+ commit: Math.random().toString(36).substring(2, 9),
172
+ status: 'deploying',
173
+ deployedAt: new Date(),
174
+ deployedBy: 'demo-user',
175
+ })
176
+ }
177
+
178
+ return (
179
+ <div className="space-y-4">
180
+ <WakaDeploymentLane
181
+ environments={environments}
182
+ onPromote={handlePromote}
183
+ onRollback={rollbackDeployment}
184
+ />
185
+
186
+ <div className="flex gap-2">
187
+ <button
188
+ onClick={handleDeploy}
189
+ className="px-4 py-2 text-sm rounded bg-primary text-primary-foreground"
190
+ >
191
+ Deploy New Version
192
+ </button>
193
+ </div>
194
+ </div>
195
+ )
196
+ },
197
+ }
198
+
199
+ export const ManyEnvironments: Story = {
200
+ render: () => {
201
+ const manyEnvs: Environment[] = [
202
+ {
203
+ id: 'dev',
204
+ name: 'Development',
205
+ deployments: [{ id: '1', version: '3.0.0', status: 'running', deployedAt: new Date() }],
206
+ },
207
+ {
208
+ id: 'test',
209
+ name: 'Testing',
210
+ deployments: [{ id: '2', version: '2.9.5', status: 'running', deployedAt: new Date(Date.now() - 60 * 60 * 1000) }],
211
+ },
212
+ {
213
+ id: 'qa',
214
+ name: 'QA',
215
+ requiresApproval: true,
216
+ approvers: ['qa-lead'],
217
+ deployments: [{ id: '3', version: '2.9.4', status: 'running', deployedAt: new Date(Date.now() - 4 * 60 * 60 * 1000) }],
218
+ },
219
+ {
220
+ id: 'staging',
221
+ name: 'Staging',
222
+ deployments: [{ id: '4', version: '2.9.3', status: 'running', deployedAt: new Date(Date.now() - 12 * 60 * 60 * 1000) }],
223
+ },
224
+ {
225
+ id: 'prod',
226
+ name: 'Production',
227
+ requiresApproval: true,
228
+ approvers: ['cto', 'tech-lead', 'devops'],
229
+ deployments: [{ id: '5', version: '2.9.2', status: 'running', deployedAt: new Date(Date.now() - 24 * 60 * 60 * 1000) }],
230
+ },
231
+ ]
232
+
233
+ return (
234
+ <div className="overflow-x-auto pb-4">
235
+ <WakaDeploymentLane environments={manyEnvs} />
236
+ </div>
237
+ )
238
+ },
239
+ }
240
+
241
+ export const EmptyEnvironments: Story = {
242
+ render: () => {
243
+ const emptyEnvs: Environment[] = [
244
+ { id: 'dev', name: 'Development', deployments: [] },
245
+ { id: 'staging', name: 'Staging', deployments: [] },
246
+ { id: 'prod', name: 'Production', requiresApproval: true, deployments: [] },
247
+ ]
248
+
249
+ return <WakaDeploymentLane environments={emptyEnvs} />
250
+ },
251
+ }
252
+
253
+ export const SingleEnvironment: Story = {
254
+ render: () => {
255
+ const singleEnv: Environment[] = [
256
+ {
257
+ id: 'prod',
258
+ name: 'Production',
259
+ deployments: [
260
+ { id: '1', version: '2.5.0', commit: 'abc123f', status: 'running', deployedAt: new Date(), deployedBy: 'admin' },
261
+ { id: '2', version: '2.4.5', commit: 'def456a', status: 'stopped', deployedAt: new Date(Date.now() - 24 * 60 * 60 * 1000) },
262
+ { id: '3', version: '2.4.4', commit: 'ghi789b', status: 'stopped', deployedAt: new Date(Date.now() - 48 * 60 * 60 * 1000) },
263
+ ],
264
+ },
265
+ ]
266
+
267
+ return <WakaDeploymentLane environments={singleEnv} />
268
+ },
269
+ }
270
+
271
+ export const CICDDashboard: Story = {
272
+ render: () => (
273
+ <div className="p-6 rounded-xl border bg-card">
274
+ <div className="flex items-center justify-between mb-6">
275
+ <div>
276
+ <h2 className="text-xl font-bold">Deployment Pipeline</h2>
277
+ <p className="text-sm text-muted-foreground">my-app / main branch</p>
278
+ </div>
279
+ <div className="flex items-center gap-2">
280
+ <div className="w-2 h-2 rounded-full bg-green-500" />
281
+ <span className="text-sm text-muted-foreground">All systems operational</span>
282
+ </div>
283
+ </div>
284
+
285
+ <WakaDeploymentLane
286
+ environments={sampleEnvironments}
287
+ onPromote={(deploymentId, fromEnv, toEnv) => console.log('Promote:', deploymentId, fromEnv, '->', toEnv)}
288
+ onRollback={(deploymentId, envId) => console.log('Rollback:', deploymentId, 'in', envId)}
289
+ />
290
+ </div>
291
+ ),
292
+ }