@wakastellar/ui 2.3.5 → 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 (175) hide show
  1. package/dist/stories/Button.d.ts +14 -0
  2. package/dist/stories/Button.stories.d.ts +8 -0
  3. package/dist/stories/Header.d.ts +11 -0
  4. package/dist/stories/Header.stories.d.ts +6 -0
  5. package/dist/stories/Page.d.ts +2 -0
  6. package/dist/stories/Page.stories.d.ts +6 -0
  7. package/package.json +11 -3
  8. package/src/blocks/activity-timeline/ActivityTimeline.stories.tsx +460 -0
  9. package/src/blocks/apm-overview/APMOverview.stories.tsx +435 -0
  10. package/src/blocks/auth-2fa/Auth2FA.stories.tsx +308 -0
  11. package/src/blocks/calendar-view/CalendarView.stories.tsx +398 -0
  12. package/src/blocks/chat/Chat.stories.tsx +466 -0
  13. package/src/blocks/chat-interface/ChatInterface.stories.tsx +412 -0
  14. package/src/blocks/checkout-flow/CheckoutFlow.stories.tsx +408 -0
  15. package/src/blocks/cicd-builder/CICDBuilder.stories.tsx +499 -0
  16. package/src/blocks/cloud-cost-dashboard/CloudCostDashboard.stories.tsx +356 -0
  17. package/src/blocks/container-orchestrator/ContainerOrchestrator.stories.tsx +461 -0
  18. package/src/blocks/dashboard/Dashboard.stories.tsx +559 -0
  19. package/src/blocks/dashboard-kpi/DashboardKPI.stories.tsx +422 -0
  20. package/src/blocks/database-admin/DatabaseAdmin.stories.tsx +393 -0
  21. package/src/blocks/deployment-dashboard/DeploymentDashboard.stories.tsx +457 -0
  22. package/src/blocks/empty-states/EmptyStates.stories.tsx +467 -0
  23. package/src/blocks/error-pages/ErrorPages.stories.tsx +401 -0
  24. package/src/blocks/faq/FAQ.stories.tsx +416 -0
  25. package/src/blocks/file-manager/FileManager.stories.tsx +413 -0
  26. package/src/blocks/footer/Footer.stories.tsx +328 -0
  27. package/src/blocks/gitops-sync-status/GitOpsSyncStatus.stories.tsx +529 -0
  28. package/src/blocks/header/WakaHeader.stories.tsx +455 -0
  29. package/src/blocks/headtab/Headtab.stories.tsx +369 -0
  30. package/src/blocks/i18n-editor/I18nEditor.stories.tsx +451 -0
  31. package/src/blocks/incident-manager/IncidentManager.stories.tsx +464 -0
  32. package/src/blocks/infrastructure-map/InfrastructureMap.stories.tsx +533 -0
  33. package/src/blocks/kanban-board/KanbanBoard.stories.tsx +494 -0
  34. package/src/blocks/landing/WakaLanding.stories.tsx +449 -0
  35. package/src/blocks/language-selector/LanguageSelector.stories.tsx +345 -0
  36. package/src/blocks/layout/Layout.stories.tsx +373 -0
  37. package/src/blocks/login/Login.stories.tsx +443 -0
  38. package/src/blocks/on-call-schedule/OnCallSchedule.stories.tsx +381 -0
  39. package/src/blocks/player-profile/PlayerProfile.stories.tsx +316 -0
  40. package/src/blocks/pricing/WakaPricing.stories.tsx +530 -0
  41. package/src/blocks/profile/Profile.stories.tsx +371 -0
  42. package/src/blocks/release-notes/ReleaseNotes.stories.tsx +431 -0
  43. package/src/blocks/settings/Settings.stories.tsx +520 -0
  44. package/src/blocks/sidebar/WakaSidebar.stories.tsx +513 -0
  45. package/src/blocks/theme-creator-block/ThemeCreatorBlock.stories.tsx +370 -0
  46. package/src/blocks/user-management/UserManagement.stories.tsx +411 -0
  47. package/src/blocks/wizard/Wizard.stories.tsx +683 -0
  48. package/src/components/accordion/Accordion.stories.tsx +93 -0
  49. package/src/components/alert/Alert.stories.tsx +95 -0
  50. package/src/components/alert-dialog/AlertDialog.stories.tsx +126 -0
  51. package/src/components/aspect-ratio/AspectRatio.stories.tsx +118 -0
  52. package/src/components/avatar/Avatar.stories.tsx +104 -0
  53. package/src/components/button/Button.stories.tsx +12 -1
  54. package/src/components/calendar/Calendar.stories.tsx +102 -0
  55. package/src/components/card/Card.stories.tsx +125 -0
  56. package/src/components/checkbox/Checkbox.stories.tsx +100 -0
  57. package/src/components/code/Code.stories.tsx +402 -0
  58. package/src/components/collapsible/Collapsible.stories.tsx +123 -0
  59. package/src/components/command/Command.stories.tsx +207 -0
  60. package/src/components/context-menu/ContextMenu.stories.tsx +220 -0
  61. package/src/components/dialog/Dialog.stories.tsx +157 -0
  62. package/src/components/dropdown-menu/DropdownMenu.stories.tsx +225 -0
  63. package/src/components/form/Form.stories.tsx +413 -0
  64. package/src/components/hover-card/HoverCard.stories.tsx +148 -0
  65. package/src/components/input-otp/InputOTP.stories.tsx +255 -0
  66. package/src/components/label/Label.stories.tsx +68 -0
  67. package/src/components/menubar/Menubar.stories.tsx +278 -0
  68. package/src/components/navigation-menu/NavigationMenu.stories.tsx +202 -0
  69. package/src/components/popover/Popover.stories.tsx +199 -0
  70. package/src/components/progress/Progress.stories.tsx +104 -0
  71. package/src/components/radio-group/RadioGroup.stories.tsx +138 -0
  72. package/src/components/scroll-area/ScrollArea.stories.tsx +153 -0
  73. package/src/components/select/Select.stories.tsx +146 -0
  74. package/src/components/separator/Separator.stories.tsx +117 -0
  75. package/src/components/sheet/Sheet.stories.tsx +195 -0
  76. package/src/components/skeleton/Skeleton.stories.tsx +114 -0
  77. package/src/components/slider/Slider.stories.tsx +157 -0
  78. package/src/components/switch/Switch.stories.tsx +114 -0
  79. package/src/components/table/Table.stories.tsx +153 -0
  80. package/src/components/tabs/Tabs.stories.tsx +155 -0
  81. package/src/components/textarea/Textarea.stories.tsx +116 -0
  82. package/src/components/toast/Toast.stories.tsx +160 -0
  83. package/src/components/toggle/Toggle.stories.tsx +125 -0
  84. package/src/components/tooltip/Tooltip.stories.tsx +133 -0
  85. package/src/components/typography/Typography.stories.tsx +207 -0
  86. package/src/components/waka-3d-pie-chart/Waka3DPieChart.stories.tsx +308 -0
  87. package/src/components/waka-achievement-unlock/WakaAchievementUnlock.stories.tsx +353 -0
  88. package/src/components/waka-artifact-list/WakaArtifactList.stories.tsx +258 -0
  89. package/src/components/waka-autocomplete/WakaAutocomplete.stories.tsx +224 -0
  90. package/src/components/waka-badge-showcase/WakaBadgeShowcase.stories.tsx +269 -0
  91. package/src/components/waka-barcode/WakaBarcode.stories.tsx +227 -0
  92. package/src/components/waka-bottom-sheet/WakaBottomSheet.stories.tsx +408 -0
  93. package/src/components/waka-breadcrumb/WakaBreadcrumb.stories.tsx +237 -0
  94. package/src/components/waka-build-matrix/WakaBuildMatrix.stories.tsx +328 -0
  95. package/src/components/waka-carousel/WakaCarousel.stories.tsx +296 -0
  96. package/src/components/waka-charts/WakaCharts.stories.tsx +519 -0
  97. package/src/components/waka-color-picker/WakaColorPicker.stories.tsx +200 -0
  98. package/src/components/waka-combobox/WakaCombobox.stories.tsx +250 -0
  99. package/src/components/waka-container-list/WakaContainerList.stories.tsx +315 -0
  100. package/src/components/waka-contribution-graph/WakaContributionGraph.stories.tsx +354 -0
  101. package/src/components/waka-cost-breakdown/WakaCostBreakdown.stories.tsx +348 -0
  102. package/src/components/waka-daily-reward/WakaDailyReward.stories.tsx +365 -0
  103. package/src/components/waka-database-card/WakaDatabaseCard.stories.tsx +306 -0
  104. package/src/components/waka-date-range-picker/WakaDateRangePicker.stories.tsx +339 -0
  105. package/src/components/waka-datetime-picker/WakaDateTimePicker.stories.tsx +317 -0
  106. package/src/components/waka-deployment-lane/WakaDeploymentLane.stories.tsx +292 -0
  107. package/src/components/waka-dock/WakaDock.stories.tsx +332 -0
  108. package/src/components/waka-drawer/WakaDrawer.stories.tsx +437 -0
  109. package/src/components/waka-env-var-editor/WakaEnvVarEditor.stories.tsx +263 -0
  110. package/src/components/waka-error-shake/WakaErrorShake.stories.tsx +410 -0
  111. package/src/components/waka-file-upload/WakaFileUpload.stories.tsx +239 -0
  112. package/src/components/waka-flow-diagram/WakaFlowDiagram.stories.tsx +365 -0
  113. package/src/components/waka-funnel-chart/WakaFunnelChart.stories.tsx +281 -0
  114. package/src/components/waka-glow-card/WakaGlowCard.stories.tsx +274 -0
  115. package/src/components/waka-haptic-button/WakaHapticButton.stories.tsx +349 -0
  116. package/src/components/waka-health-pulse/WakaHealthPulse.stories.tsx +293 -0
  117. package/src/components/waka-heatmap/WakaHeatmap.stories.tsx +376 -0
  118. package/src/components/waka-image/WakaImage.stories.tsx +255 -0
  119. package/src/components/waka-incident-timeline/WakaIncidentTimeline.stories.tsx +300 -0
  120. package/src/components/waka-kanban/WakaKanban.stories.tsx +399 -0
  121. package/src/components/waka-kubernetes-overview/WakaKubernetesOverview.stories.tsx +281 -0
  122. package/src/components/waka-leaderboard/WakaLeaderboard.stories.tsx +300 -0
  123. package/src/components/waka-level-progress/WakaLevelProgress.stories.tsx +313 -0
  124. package/src/components/waka-loading-orbit/WakaLoadingOrbit.stories.tsx +413 -0
  125. package/src/components/waka-log-viewer/WakaLogViewer.stories.tsx +312 -0
  126. package/src/components/waka-loot-box/WakaLootBox.stories.tsx +374 -0
  127. package/src/components/waka-metric-sparkline/WakaMetricSparkline.stories.tsx +312 -0
  128. package/src/components/waka-migration-list/WakaMigrationList.stories.tsx +289 -0
  129. package/src/components/waka-modal/WakaModal.stories.tsx +434 -0
  130. package/src/components/waka-morph-button/WakaMorphButton.stories.tsx +405 -0
  131. package/src/components/waka-network-topology/WakaNetworkTopology.stories.tsx +364 -0
  132. package/src/components/waka-notifications/WakaNotifications.stories.tsx +290 -0
  133. package/src/components/waka-number-input/WakaNumberInput.stories.tsx +282 -0
  134. package/src/components/waka-pagination/WakaPagination.stories.tsx +328 -0
  135. package/src/components/waka-password-strength/WakaPasswordStrength.stories.tsx +318 -0
  136. package/src/components/waka-pipeline-view/WakaPipelineView.stories.tsx +386 -0
  137. package/src/components/waka-player-card/WakaPlayerCard.stories.tsx +333 -0
  138. package/src/components/waka-pod-card/WakaPodCard.stories.tsx +435 -0
  139. package/src/components/waka-qrcode/WakaQRCode.stories.tsx +232 -0
  140. package/src/components/waka-query-explain/WakaQueryExplain.stories.tsx +407 -0
  141. package/src/components/waka-quest-card/WakaQuestCard.stories.tsx +394 -0
  142. package/src/components/waka-quota-bar/WakaQuotaBar.stories.tsx +435 -0
  143. package/src/components/waka-radar-score/WakaRadarScore.stories.tsx +372 -0
  144. package/src/components/waka-resource-gauge/WakaResourceGauge.stories.tsx +366 -0
  145. package/src/components/waka-rich-text-editor/WakaRichTextEditor.stories.tsx +238 -0
  146. package/src/components/waka-sankey-diagram/WakaSankeyDiagram.stories.tsx +389 -0
  147. package/src/components/waka-scratch-card/WakaScratchCard.stories.tsx +388 -0
  148. package/src/components/waka-secret-card/WakaSecretCard.stories.tsx +314 -0
  149. package/src/components/waka-segmented-control/WakaSegmentedControl.stories.tsx +309 -0
  150. package/src/components/waka-server-rack/WakaServerRack.stories.tsx +382 -0
  151. package/src/components/waka-service-graph/WakaServiceGraph.stories.tsx +262 -0
  152. package/src/components/waka-skeleton-wave/WakaSkeletonWave.stories.tsx +321 -0
  153. package/src/components/waka-skill-tree/WakaSkillTree.stories.tsx +308 -0
  154. package/src/components/waka-spin-wheel/WakaSpinWheel.stories.tsx +368 -0
  155. package/src/components/waka-spinner/WakaSpinner.stories.tsx +156 -0
  156. package/src/components/waka-stat/WakaStat.stories.tsx +334 -0
  157. package/src/components/waka-status-matrix/WakaStatusMatrix.stories.tsx +331 -0
  158. package/src/components/waka-stepper/WakaStepper.stories.tsx +468 -0
  159. package/src/components/waka-streak-counter/WakaStreakCounter.stories.tsx +235 -0
  160. package/src/components/waka-success-explosion/WakaSuccessExplosion.stories.tsx +389 -0
  161. package/src/components/waka-tabs-morph/WakaTabsMorph.stories.tsx +471 -0
  162. package/src/components/waka-terminal-output/WakaTerminalOutput.stories.tsx +351 -0
  163. package/src/components/waka-test-report/WakaTestReport.stories.tsx +322 -0
  164. package/src/components/waka-tilt-card/WakaTiltCard.stories.tsx +300 -0
  165. package/src/components/waka-time-picker/WakaTimePicker.stories.tsx +227 -0
  166. package/src/components/waka-timeline/WakaTimeline.stories.tsx +383 -0
  167. package/src/components/waka-tournament-bracket/WakaTournamentBracket.stories.tsx +375 -0
  168. package/src/components/waka-trace-viewer/WakaTraceViewer.stories.tsx +445 -0
  169. package/src/components/waka-tree/WakaTree.stories.tsx +359 -0
  170. package/src/components/waka-treemap-chart/WakaTreemapChart.stories.tsx +378 -0
  171. package/src/components/waka-typewriter/WakaTypewriter.stories.tsx +366 -0
  172. package/src/components/waka-versus-card/WakaVersusCard.stories.tsx +530 -0
  173. package/src/components/waka-video/WakaVideo.stories.tsx +203 -0
  174. package/src/components/waka-virtual-list/WakaVirtualList.stories.tsx +273 -0
  175. package/src/components/waka-xp-bar/WakaXPBar.stories.tsx +305 -0
@@ -0,0 +1,14 @@
1
+ export interface ButtonProps {
2
+ /** Is this the principal call to action on the page? */
3
+ primary?: boolean;
4
+ /** What background color to use */
5
+ backgroundColor?: string;
6
+ /** How large should the button be? */
7
+ size?: 'small' | 'medium' | 'large';
8
+ /** Button contents */
9
+ label: string;
10
+ /** Optional click handler */
11
+ onClick?: () => void;
12
+ }
13
+ /** Primary UI component for user interaction */
14
+ export declare const Button: ({ primary, size, backgroundColor, label, ...props }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { StoryObj } from '@storybook/react-vite';
2
+ declare const meta: Meta<({ primary, size, backgroundColor, label, ...props }: import('./Button').ButtonProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default meta;
4
+ type Story = StoryObj<typeof meta>;
5
+ export declare const Primary: Story;
6
+ export declare const Secondary: Story;
7
+ export declare const Large: Story;
8
+ export declare const Small: Story;
@@ -0,0 +1,11 @@
1
+ type User = {
2
+ name: string;
3
+ };
4
+ export interface HeaderProps {
5
+ user?: User;
6
+ onLogin?: () => void;
7
+ onLogout?: () => void;
8
+ onCreateAccount?: () => void;
9
+ }
10
+ export declare const Header: ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,6 @@
1
+ import { StoryObj } from '@storybook/react-vite';
2
+ declare const meta: Meta<({ user, onLogin, onLogout, onCreateAccount }: import('./Header').HeaderProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default meta;
4
+ type Story = StoryObj<typeof meta>;
5
+ export declare const LoggedIn: Story;
6
+ export declare const LoggedOut: Story;
@@ -0,0 +1,2 @@
1
+ import { default as React } from 'react';
2
+ export declare const Page: React.FC;
@@ -0,0 +1,6 @@
1
+ import { StoryObj } from '@storybook/react-vite';
2
+ declare const meta: Meta<import('react').FC<{}>>;
3
+ export default meta;
4
+ type Story = StoryObj<typeof meta>;
5
+ export declare const LoggedOut: Story;
6
+ export declare const LoggedIn: Story;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wakastellar/ui",
3
- "version": "2.3.5",
3
+ "version": "2.4.0",
4
4
  "description": "Zero-config UI Library for Next.js with TweakCN theming and i18n support",
5
5
  "keywords": [
6
6
  "ui",
@@ -151,6 +151,12 @@
151
151
  },
152
152
  "devDependencies": {
153
153
  "@chromatic-com/storybook": "^4.1.1",
154
+ "@storybook/addon-a11y": "^10.1.11",
155
+ "@storybook/addon-docs": "^10.1.11",
156
+ "@storybook/addon-onboarding": "^10.1.11",
157
+ "@storybook/addon-vitest": "^10.1.11",
158
+ "@storybook/react-vite": "^10.1.11",
159
+ "@tailwindcss/vite": "^4.1.18",
154
160
  "@testing-library/jest-dom": "^6.1.5",
155
161
  "@testing-library/react": "^14.1.2",
156
162
  "@testing-library/user-event": "^14.5.1",
@@ -170,7 +176,7 @@
170
176
  "playwright": "^1.56.0",
171
177
  "postcss": "^8.4.31",
172
178
  "react-hook-form": "^7.70.0",
173
- "storybook": "^9.1.17",
179
+ "storybook": "^10.1.11",
174
180
  "tailwindcss": "^4.1.8",
175
181
  "typescript": "^5.5.0",
176
182
  "vite": "^7.1.9",
@@ -187,6 +193,8 @@
187
193
  "test": "vitest --config vitest.config.unit.ts",
188
194
  "test:watch": "vitest --config vitest.config.unit.ts --watch",
189
195
  "test:coverage": "vitest --config vitest.config.unit.ts --coverage",
190
- "test:ui": "vitest --config vitest.config.unit.ts --ui"
196
+ "test:ui": "vitest --config vitest.config.unit.ts --ui",
197
+ "storybook": "storybook dev -p 6006",
198
+ "build-storybook": "storybook build"
191
199
  }
192
200
  }
@@ -0,0 +1,460 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaActivityTimeline, defaultActivities, defaultActivityFilters } from './index'
3
+ import type { ActivityItem, ActivityFilter } from './index'
4
+ import * as React from 'react'
5
+ import { Bell, Star, MessageSquare, Upload } from 'lucide-react'
6
+
7
+ const meta: Meta<typeof WakaActivityTimeline> = {
8
+ title: 'Blocks/ActivityTimeline',
9
+ component: WakaActivityTimeline,
10
+ parameters: {
11
+ layout: 'centered',
12
+ docs: {
13
+ description: {
14
+ component:
15
+ 'An activity timeline component with filtering, search, grouping by day, and multiple layout options (timeline, feed, compact).',
16
+ },
17
+ },
18
+ },
19
+ tags: ['autodocs'],
20
+ argTypes: {
21
+ layout: {
22
+ control: 'select',
23
+ options: ['timeline', 'feed', 'compact'],
24
+ },
25
+ showSearch: {
26
+ control: 'boolean',
27
+ },
28
+ showFilters: {
29
+ control: 'boolean',
30
+ },
31
+ showRefresh: {
32
+ control: 'boolean',
33
+ },
34
+ groupByDay: {
35
+ control: 'boolean',
36
+ },
37
+ showAvatars: {
38
+ control: 'boolean',
39
+ },
40
+ relativeTime: {
41
+ control: 'boolean',
42
+ },
43
+ loading: {
44
+ control: 'boolean',
45
+ },
46
+ },
47
+ }
48
+
49
+ export default meta
50
+ type Story = StoryObj<typeof WakaActivityTimeline>
51
+
52
+ export const Default: Story = {
53
+ render: () => (
54
+ <div className="w-[600px]">
55
+ <WakaActivityTimeline
56
+ activities={defaultActivities}
57
+ filters={defaultActivityFilters}
58
+ onFilterChange={(filter) => console.log('Filter:', filter)}
59
+ onRefresh={() => console.log('Refresh')}
60
+ />
61
+ </div>
62
+ ),
63
+ }
64
+
65
+ export const TimelineLayout: Story = {
66
+ render: () => (
67
+ <div className="w-[600px]">
68
+ <WakaActivityTimeline
69
+ activities={defaultActivities}
70
+ layout="timeline"
71
+ title="Activity Timeline"
72
+ />
73
+ </div>
74
+ ),
75
+ }
76
+
77
+ export const FeedLayout: Story = {
78
+ render: () => (
79
+ <div className="w-[600px]">
80
+ <WakaActivityTimeline
81
+ activities={defaultActivities}
82
+ layout="feed"
83
+ title="Activity Feed"
84
+ />
85
+ </div>
86
+ ),
87
+ }
88
+
89
+ export const CompactLayout: Story = {
90
+ render: () => (
91
+ <div className="w-[400px]">
92
+ <WakaActivityTimeline
93
+ activities={defaultActivities}
94
+ layout="compact"
95
+ title="Recent Activity"
96
+ showSearch={false}
97
+ showFilters={false}
98
+ />
99
+ </div>
100
+ ),
101
+ }
102
+
103
+ export const WithFilters: Story = {
104
+ render: () => {
105
+ const [activeFilter, setActiveFilter] = React.useState<string | null>(null)
106
+
107
+ return (
108
+ <div className="w-[600px]">
109
+ <WakaActivityTimeline
110
+ activities={defaultActivities}
111
+ filters={defaultActivityFilters}
112
+ activeFilter={activeFilter ?? undefined}
113
+ onFilterChange={setActiveFilter}
114
+ title="Filtered Activity"
115
+ />
116
+ </div>
117
+ )
118
+ },
119
+ }
120
+
121
+ export const ManyActivities: Story = {
122
+ render: () => {
123
+ const manyActivities: ActivityItem[] = [
124
+ // Today
125
+ {
126
+ id: '1',
127
+ type: 'created',
128
+ title: 'a créé le projet "Dashboard v2"',
129
+ user: { id: '1', name: 'Marie Dupont' },
130
+ timestamp: new Date(Date.now() - 1000 * 60 * 5),
131
+ },
132
+ {
133
+ id: '2',
134
+ type: 'commented',
135
+ title: 'a commenté sur "API Integration"',
136
+ user: { id: '2', name: 'Pierre Martin' },
137
+ timestamp: new Date(Date.now() - 1000 * 60 * 30),
138
+ metadata: { comment: 'Excellent travail sur cette partie!' },
139
+ },
140
+ {
141
+ id: '3',
142
+ type: 'uploaded',
143
+ title: 'a uploadé 5 fichiers',
144
+ user: { id: '3', name: 'Sophie Bernard' },
145
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2),
146
+ },
147
+ {
148
+ id: '4',
149
+ type: 'approved',
150
+ title: 'a approuvé la PR #123',
151
+ user: { id: '1', name: 'Marie Dupont' },
152
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 4),
153
+ },
154
+ // Yesterday
155
+ {
156
+ id: '5',
157
+ type: 'assigned',
158
+ title: 'a assigné "Bug fix" à Pierre',
159
+ user: { id: '4', name: 'Jean Dubois' },
160
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24),
161
+ },
162
+ {
163
+ id: '6',
164
+ type: 'completed',
165
+ title: 'a terminé la tâche "Design mockups"',
166
+ user: { id: '3', name: 'Sophie Bernard' },
167
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 26),
168
+ },
169
+ {
170
+ id: '7',
171
+ type: 'updated',
172
+ title: 'a mis à jour les spécifications',
173
+ user: { id: '2', name: 'Pierre Martin' },
174
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 28),
175
+ },
176
+ // 2 days ago
177
+ {
178
+ id: '8',
179
+ type: 'deleted',
180
+ title: 'a supprimé "Old Draft"',
181
+ user: { id: '1', name: 'Marie Dupont' },
182
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 48),
183
+ },
184
+ {
185
+ id: '9',
186
+ type: 'shared',
187
+ title: 'a partagé le document avec l\'équipe',
188
+ user: { id: '4', name: 'Jean Dubois' },
189
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 50),
190
+ },
191
+ {
192
+ id: '10',
193
+ type: 'mentioned',
194
+ title: 'vous a mentionné dans un commentaire',
195
+ user: { id: '3', name: 'Sophie Bernard' },
196
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 52),
197
+ },
198
+ ]
199
+
200
+ return (
201
+ <div className="w-[600px]">
202
+ <WakaActivityTimeline
203
+ activities={manyActivities}
204
+ filters={defaultActivityFilters}
205
+ groupByDay
206
+ showLoadMore
207
+ onLoadMore={() => console.log('Load more')}
208
+ onRefresh={() => console.log('Refresh')}
209
+ />
210
+ </div>
211
+ )
212
+ },
213
+ }
214
+
215
+ export const WithCustomIcons: Story = {
216
+ render: () => {
217
+ const customActivities: ActivityItem[] = [
218
+ {
219
+ id: '1',
220
+ type: 'custom',
221
+ title: 'Nouvelle notification importante',
222
+ description: 'Vous avez une mise à jour système en attente',
223
+ user: { id: '1', name: 'Système' },
224
+ timestamp: new Date(Date.now() - 1000 * 60 * 10),
225
+ icon: <Bell className="h-4 w-4" />,
226
+ color: 'text-yellow-500',
227
+ },
228
+ {
229
+ id: '2',
230
+ type: 'custom',
231
+ title: 'Projet marqué comme favori',
232
+ user: { id: '2', name: 'Marie Dupont' },
233
+ timestamp: new Date(Date.now() - 1000 * 60 * 60),
234
+ icon: <Star className="h-4 w-4" />,
235
+ color: 'text-orange-500',
236
+ },
237
+ {
238
+ id: '3',
239
+ type: 'custom',
240
+ title: 'Nouveau message dans le chat',
241
+ description: 'Pierre a envoyé un message',
242
+ user: { id: '3', name: 'Pierre Martin' },
243
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 3),
244
+ icon: <MessageSquare className="h-4 w-4" />,
245
+ color: 'text-blue-500',
246
+ },
247
+ {
248
+ id: '4',
249
+ type: 'custom',
250
+ title: 'Fichier synchronisé',
251
+ user: { id: '1', name: 'Système' },
252
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 5),
253
+ icon: <Upload className="h-4 w-4" />,
254
+ color: 'text-green-500',
255
+ },
256
+ ]
257
+
258
+ return (
259
+ <div className="w-[600px]">
260
+ <WakaActivityTimeline
261
+ activities={customActivities}
262
+ title="Custom Activity"
263
+ showFilters={false}
264
+ />
265
+ </div>
266
+ )
267
+ },
268
+ }
269
+
270
+ export const NoGrouping: Story = {
271
+ render: () => (
272
+ <div className="w-[600px]">
273
+ <WakaActivityTimeline
274
+ activities={defaultActivities}
275
+ groupByDay={false}
276
+ title="Ungrouped Activity"
277
+ />
278
+ </div>
279
+ ),
280
+ }
281
+
282
+ export const AbsoluteTime: Story = {
283
+ render: () => (
284
+ <div className="w-[600px]">
285
+ <WakaActivityTimeline
286
+ activities={defaultActivities}
287
+ relativeTime={false}
288
+ title="Absolute Timestamps"
289
+ />
290
+ </div>
291
+ ),
292
+ }
293
+
294
+ export const NoAvatars: Story = {
295
+ render: () => (
296
+ <div className="w-[600px]">
297
+ <WakaActivityTimeline
298
+ activities={defaultActivities}
299
+ showAvatars={false}
300
+ title="Without Avatars"
301
+ />
302
+ </div>
303
+ ),
304
+ }
305
+
306
+ export const Loading: Story = {
307
+ render: () => (
308
+ <div className="w-[600px]">
309
+ <WakaActivityTimeline
310
+ activities={[]}
311
+ loading
312
+ title="Loading..."
313
+ />
314
+ </div>
315
+ ),
316
+ }
317
+
318
+ export const LoadingMore: Story = {
319
+ render: () => (
320
+ <div className="w-[600px]">
321
+ <WakaActivityTimeline
322
+ activities={defaultActivities}
323
+ showLoadMore
324
+ loadingMore
325
+ onLoadMore={() => console.log('Load more')}
326
+ />
327
+ </div>
328
+ ),
329
+ }
330
+
331
+ export const Empty: Story = {
332
+ render: () => (
333
+ <div className="w-[600px]">
334
+ <WakaActivityTimeline
335
+ activities={[]}
336
+ title="No Activity"
337
+ />
338
+ </div>
339
+ ),
340
+ }
341
+
342
+ export const WithSearchAndFilters: Story = {
343
+ render: () => {
344
+ const [activeFilter, setActiveFilter] = React.useState<string | null>(null)
345
+
346
+ return (
347
+ <div className="w-[600px]">
348
+ <WakaActivityTimeline
349
+ activities={defaultActivities}
350
+ filters={defaultActivityFilters}
351
+ activeFilter={activeFilter ?? undefined}
352
+ onFilterChange={setActiveFilter}
353
+ showSearch
354
+ showFilters
355
+ showRefresh
356
+ onRefresh={() => console.log('Refresh')}
357
+ title="Searchable Activity"
358
+ />
359
+ </div>
360
+ )
361
+ },
362
+ }
363
+
364
+ export const MinimalUI: Story = {
365
+ render: () => (
366
+ <div className="w-[400px]">
367
+ <WakaActivityTimeline
368
+ activities={defaultActivities.slice(0, 3)}
369
+ layout="compact"
370
+ showSearch={false}
371
+ showFilters={false}
372
+ showRefresh={false}
373
+ groupByDay={false}
374
+ showAvatars={false}
375
+ />
376
+ </div>
377
+ ),
378
+ }
379
+
380
+ export const InSidebar: Story = {
381
+ render: () => (
382
+ <div className="w-[300px] border rounded-lg p-4">
383
+ <WakaActivityTimeline
384
+ activities={defaultActivities}
385
+ layout="compact"
386
+ showSearch={false}
387
+ showFilters={false}
388
+ showRefresh={false}
389
+ groupByDay={false}
390
+ title="Recent"
391
+ />
392
+ </div>
393
+ ),
394
+ }
395
+
396
+ export const ProjectActivity: Story = {
397
+ render: () => {
398
+ const projectActivities: ActivityItem[] = [
399
+ {
400
+ id: '1',
401
+ type: 'created',
402
+ title: 'a créé la branche feature/auth',
403
+ user: { id: '1', name: 'Alice', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Alice' },
404
+ timestamp: new Date(Date.now() - 1000 * 60 * 15),
405
+ },
406
+ {
407
+ id: '2',
408
+ type: 'approved',
409
+ title: 'a mergé PR #456 dans main',
410
+ user: { id: '2', name: 'Bob', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Bob' },
411
+ timestamp: new Date(Date.now() - 1000 * 60 * 45),
412
+ },
413
+ {
414
+ id: '3',
415
+ type: 'commented',
416
+ title: 'a commenté sur PR #457',
417
+ user: { id: '3', name: 'Carol', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Carol' },
418
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2),
419
+ metadata: { comment: 'LGTM! Just one small suggestion on line 42.' },
420
+ },
421
+ {
422
+ id: '4',
423
+ type: 'rejected',
424
+ title: 'a demandé des changements sur PR #458',
425
+ user: { id: '1', name: 'Alice', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Alice' },
426
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 4),
427
+ },
428
+ {
429
+ id: '5',
430
+ type: 'completed',
431
+ title: 'a fermé l\'issue #123',
432
+ user: { id: '2', name: 'Bob', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Bob' },
433
+ timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24),
434
+ },
435
+ ]
436
+
437
+ return (
438
+ <div className="min-h-screen bg-muted/30">
439
+ <header className="bg-background border-b px-6 py-4">
440
+ <h1 className="font-bold text-xl">Project Activity</h1>
441
+ <p className="text-sm text-muted-foreground">my-org/my-repo</p>
442
+ </header>
443
+ <main className="p-6 max-w-3xl mx-auto">
444
+ <WakaActivityTimeline
445
+ activities={projectActivities}
446
+ layout="feed"
447
+ filters={[
448
+ { id: 'prs', label: 'Pull Requests', types: ['approved', 'rejected', 'commented'] },
449
+ { id: 'branches', label: 'Branches', types: ['created', 'deleted'] },
450
+ { id: 'issues', label: 'Issues', types: ['completed', 'assigned'] },
451
+ ]}
452
+ onRefresh={() => console.log('Refresh')}
453
+ showLoadMore
454
+ onLoadMore={() => console.log('Load more')}
455
+ />
456
+ </main>
457
+ </div>
458
+ )
459
+ },
460
+ }