@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,282 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaNumberInput } from './index'
3
+ import * as React from 'react'
4
+
5
+ const meta: Meta<typeof WakaNumberInput> = {
6
+ title: 'Components/Forms/WakaNumberInput',
7
+ component: WakaNumberInput,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A number input component with increment/decrement buttons and various layouts.',
13
+ },
14
+ },
15
+ },
16
+ tags: ['autodocs'],
17
+ argTypes: {
18
+ size: {
19
+ control: 'select',
20
+ options: ['sm', 'md', 'lg'],
21
+ description: 'Size of the component',
22
+ },
23
+ buttonPosition: {
24
+ control: 'select',
25
+ options: ['sides', 'right', 'none'],
26
+ description: 'Position of increment/decrement buttons',
27
+ },
28
+ disabled: {
29
+ control: 'boolean',
30
+ description: 'Disable the component',
31
+ },
32
+ error: {
33
+ control: 'boolean',
34
+ description: 'Show error state',
35
+ },
36
+ },
37
+ }
38
+
39
+ export default meta
40
+ type Story = StoryObj<typeof WakaNumberInput>
41
+
42
+ export const Default: Story = {
43
+ render: function NumberInputDemo() {
44
+ const [value, setValue] = React.useState<number | undefined>(0)
45
+
46
+ return (
47
+ <div className="w-[200px]">
48
+ <WakaNumberInput value={value} onChange={setValue} />
49
+ </div>
50
+ )
51
+ },
52
+ }
53
+
54
+ export const WithMinMax: Story = {
55
+ render: function MinMaxDemo() {
56
+ const [value, setValue] = React.useState<number | undefined>(5)
57
+
58
+ return (
59
+ <div className="w-[200px]">
60
+ <WakaNumberInput
61
+ value={value}
62
+ onChange={setValue}
63
+ min={0}
64
+ max={10}
65
+ placeholder="0-10"
66
+ />
67
+ <p className="text-xs text-muted-foreground mt-2">Range: 0 to 10</p>
68
+ </div>
69
+ )
70
+ },
71
+ }
72
+
73
+ export const WithStep: Story = {
74
+ render: function StepDemo() {
75
+ const [value, setValue] = React.useState<number | undefined>(0)
76
+
77
+ return (
78
+ <div className="w-[200px]">
79
+ <WakaNumberInput
80
+ value={value}
81
+ onChange={setValue}
82
+ step={5}
83
+ placeholder="Step: 5"
84
+ />
85
+ <p className="text-xs text-muted-foreground mt-2">Step: 5</p>
86
+ </div>
87
+ )
88
+ },
89
+ }
90
+
91
+ export const DecimalPrecision: Story = {
92
+ render: function DecimalDemo() {
93
+ const [value, setValue] = React.useState<number | undefined>(0.5)
94
+
95
+ return (
96
+ <div className="w-[200px]">
97
+ <WakaNumberInput
98
+ value={value}
99
+ onChange={setValue}
100
+ step={0.1}
101
+ precision={2}
102
+ min={0}
103
+ max={1}
104
+ />
105
+ <p className="text-xs text-muted-foreground mt-2">
106
+ Decimal with 2 digit precision
107
+ </p>
108
+ </div>
109
+ )
110
+ },
111
+ }
112
+
113
+ export const ButtonPositions: Story = {
114
+ render: function ButtonPositionsDemo() {
115
+ const [value1, setValue1] = React.useState<number | undefined>(0)
116
+ const [value2, setValue2] = React.useState<number | undefined>(0)
117
+ const [value3, setValue3] = React.useState<number | undefined>(0)
118
+
119
+ return (
120
+ <div className="space-y-4 w-[200px]">
121
+ <div>
122
+ <p className="text-sm text-muted-foreground mb-1">Sides (default)</p>
123
+ <WakaNumberInput
124
+ value={value1}
125
+ onChange={setValue1}
126
+ buttonPosition="sides"
127
+ />
128
+ </div>
129
+ <div>
130
+ <p className="text-sm text-muted-foreground mb-1">Right</p>
131
+ <WakaNumberInput
132
+ value={value2}
133
+ onChange={setValue2}
134
+ buttonPosition="right"
135
+ />
136
+ </div>
137
+ <div>
138
+ <p className="text-sm text-muted-foreground mb-1">No buttons</p>
139
+ <WakaNumberInput
140
+ value={value3}
141
+ onChange={setValue3}
142
+ buttonPosition="none"
143
+ />
144
+ </div>
145
+ </div>
146
+ )
147
+ },
148
+ }
149
+
150
+ export const Sizes: Story = {
151
+ render: function SizesDemo() {
152
+ const [value, setValue] = React.useState<number | undefined>(42)
153
+
154
+ return (
155
+ <div className="space-y-4 w-[200px]">
156
+ <div>
157
+ <p className="text-sm text-muted-foreground mb-1">Small</p>
158
+ <WakaNumberInput value={value} onChange={setValue} size="sm" />
159
+ </div>
160
+ <div>
161
+ <p className="text-sm text-muted-foreground mb-1">Medium</p>
162
+ <WakaNumberInput value={value} onChange={setValue} size="md" />
163
+ </div>
164
+ <div>
165
+ <p className="text-sm text-muted-foreground mb-1">Large</p>
166
+ <WakaNumberInput value={value} onChange={setValue} size="lg" />
167
+ </div>
168
+ </div>
169
+ )
170
+ },
171
+ }
172
+
173
+ export const CurrencyFormat: Story = {
174
+ render: function CurrencyDemo() {
175
+ const [value, setValue] = React.useState<number | undefined>(1999.99)
176
+
177
+ return (
178
+ <div className="w-[200px]">
179
+ <WakaNumberInput
180
+ value={value}
181
+ onChange={setValue}
182
+ precision={2}
183
+ step={0.01}
184
+ min={0}
185
+ formatValue={(v) => `$${v.toFixed(2)}`}
186
+ parseValue={(v) => parseFloat(v.replace(/[^0-9.-]/g, ''))}
187
+ />
188
+ <p className="text-xs text-muted-foreground mt-2">
189
+ Currency formatting
190
+ </p>
191
+ </div>
192
+ )
193
+ },
194
+ }
195
+
196
+ export const PercentFormat: Story = {
197
+ render: function PercentDemo() {
198
+ const [value, setValue] = React.useState<number | undefined>(75)
199
+
200
+ return (
201
+ <div className="w-[200px]">
202
+ <WakaNumberInput
203
+ value={value}
204
+ onChange={setValue}
205
+ min={0}
206
+ max={100}
207
+ formatValue={(v) => `${v}%`}
208
+ parseValue={(v) => parseFloat(v.replace('%', ''))}
209
+ />
210
+ <p className="text-xs text-muted-foreground mt-2">
211
+ Percentage formatting
212
+ </p>
213
+ </div>
214
+ )
215
+ },
216
+ }
217
+
218
+ export const AllowEmpty: Story = {
219
+ render: function AllowEmptyDemo() {
220
+ const [value, setValue] = React.useState<number | undefined>()
221
+
222
+ return (
223
+ <div className="w-[200px]">
224
+ <WakaNumberInput
225
+ value={value}
226
+ onChange={setValue}
227
+ allowEmpty
228
+ placeholder="Optional"
229
+ />
230
+ <p className="text-xs text-muted-foreground mt-2">
231
+ Value: {value === undefined ? 'empty' : value}
232
+ </p>
233
+ </div>
234
+ )
235
+ },
236
+ }
237
+
238
+ export const WithError: Story = {
239
+ render: () => (
240
+ <div className="w-[200px]">
241
+ <WakaNumberInput value={150} error />
242
+ <p className="text-sm text-destructive mt-1">
243
+ Value must be less than 100
244
+ </p>
245
+ </div>
246
+ ),
247
+ }
248
+
249
+ export const Disabled: Story = {
250
+ render: () => (
251
+ <div className="w-[200px]">
252
+ <WakaNumberInput value={42} disabled />
253
+ </div>
254
+ ),
255
+ }
256
+
257
+ export const QuantitySelector: Story = {
258
+ render: function QuantitySelectorDemo() {
259
+ const [quantity, setQuantity] = React.useState<number | undefined>(1)
260
+
261
+ return (
262
+ <div className="flex items-center gap-4 p-4 border rounded-lg">
263
+ <img
264
+ src="https://via.placeholder.com/80"
265
+ alt="Product"
266
+ className="w-20 h-20 rounded"
267
+ />
268
+ <div className="flex-1">
269
+ <h4 className="font-medium">Product Name</h4>
270
+ <p className="text-sm text-muted-foreground">$29.99</p>
271
+ </div>
272
+ <WakaNumberInput
273
+ value={quantity}
274
+ onChange={setQuantity}
275
+ min={1}
276
+ max={99}
277
+ className="w-[120px]"
278
+ />
279
+ </div>
280
+ )
281
+ },
282
+ }
@@ -0,0 +1,328 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WakaPagination, usePagination } from './index'
3
+ import * as React from 'react'
4
+
5
+ const meta: Meta<typeof WakaPagination> = {
6
+ title: 'Components/Display/WakaPagination',
7
+ component: WakaPagination,
8
+ parameters: {
9
+ layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: 'A pagination component with page navigation, size selection, and item information display.',
13
+ },
14
+ },
15
+ },
16
+ tags: ['autodocs'],
17
+ argTypes: {
18
+ size: {
19
+ control: 'select',
20
+ options: ['sm', 'md', 'lg'],
21
+ description: 'Size of the buttons',
22
+ },
23
+ variant: {
24
+ control: 'select',
25
+ options: ['default', 'outline', 'ghost'],
26
+ description: 'Visual variant',
27
+ },
28
+ showFirstLast: {
29
+ control: 'boolean',
30
+ description: 'Show first/last page buttons',
31
+ },
32
+ showPageSizeSelector: {
33
+ control: 'boolean',
34
+ description: 'Show page size selector',
35
+ },
36
+ showItemsInfo: {
37
+ control: 'boolean',
38
+ description: 'Show items information',
39
+ },
40
+ },
41
+ }
42
+
43
+ export default meta
44
+ type Story = StoryObj<typeof WakaPagination>
45
+
46
+ export const Default: Story = {
47
+ args: {
48
+ totalPages: 10,
49
+ },
50
+ render: (args) => {
51
+ const [page, setPage] = React.useState(1)
52
+ return (
53
+ <WakaPagination
54
+ {...args}
55
+ page={page}
56
+ onPageChange={setPage}
57
+ />
58
+ )
59
+ },
60
+ }
61
+
62
+ export const WithItemsInfo: Story = {
63
+ render: () => {
64
+ const [page, setPage] = React.useState(1)
65
+ return (
66
+ <WakaPagination
67
+ page={page}
68
+ totalPages={10}
69
+ totalItems={95}
70
+ pageSize={10}
71
+ onPageChange={setPage}
72
+ showItemsInfo
73
+ />
74
+ )
75
+ },
76
+ }
77
+
78
+ export const WithPageSizeSelector: Story = {
79
+ render: () => {
80
+ const [page, setPage] = React.useState(1)
81
+ const [pageSize, setPageSize] = React.useState(10)
82
+ const totalItems = 247
83
+ const totalPages = Math.ceil(totalItems / pageSize)
84
+
85
+ return (
86
+ <WakaPagination
87
+ page={page}
88
+ totalPages={totalPages}
89
+ totalItems={totalItems}
90
+ pageSize={pageSize}
91
+ onPageChange={setPage}
92
+ onPageSizeChange={(size) => {
93
+ setPageSize(size)
94
+ setPage(1)
95
+ }}
96
+ showPageSizeSelector
97
+ showItemsInfo
98
+ />
99
+ )
100
+ },
101
+ }
102
+
103
+ export const Sizes: Story = {
104
+ render: () => {
105
+ const [page, setPage] = React.useState(5)
106
+
107
+ return (
108
+ <div className="space-y-8">
109
+ <div>
110
+ <p className="text-sm text-muted-foreground mb-2">Small</p>
111
+ <WakaPagination
112
+ page={page}
113
+ totalPages={10}
114
+ onPageChange={setPage}
115
+ size="sm"
116
+ />
117
+ </div>
118
+ <div>
119
+ <p className="text-sm text-muted-foreground mb-2">Medium (Default)</p>
120
+ <WakaPagination
121
+ page={page}
122
+ totalPages={10}
123
+ onPageChange={setPage}
124
+ size="md"
125
+ />
126
+ </div>
127
+ <div>
128
+ <p className="text-sm text-muted-foreground mb-2">Large</p>
129
+ <WakaPagination
130
+ page={page}
131
+ totalPages={10}
132
+ onPageChange={setPage}
133
+ size="lg"
134
+ />
135
+ </div>
136
+ </div>
137
+ )
138
+ },
139
+ }
140
+
141
+ export const Variants: Story = {
142
+ render: () => {
143
+ const [page, setPage] = React.useState(5)
144
+
145
+ return (
146
+ <div className="space-y-8">
147
+ <div>
148
+ <p className="text-sm text-muted-foreground mb-2">Default</p>
149
+ <WakaPagination
150
+ page={page}
151
+ totalPages={10}
152
+ onPageChange={setPage}
153
+ variant="default"
154
+ />
155
+ </div>
156
+ <div>
157
+ <p className="text-sm text-muted-foreground mb-2">Outline</p>
158
+ <WakaPagination
159
+ page={page}
160
+ totalPages={10}
161
+ onPageChange={setPage}
162
+ variant="outline"
163
+ />
164
+ </div>
165
+ <div>
166
+ <p className="text-sm text-muted-foreground mb-2">Ghost</p>
167
+ <WakaPagination
168
+ page={page}
169
+ totalPages={10}
170
+ onPageChange={setPage}
171
+ variant="ghost"
172
+ />
173
+ </div>
174
+ </div>
175
+ )
176
+ },
177
+ }
178
+
179
+ export const ManyPages: Story = {
180
+ render: () => {
181
+ const [page, setPage] = React.useState(50)
182
+ return (
183
+ <WakaPagination
184
+ page={page}
185
+ totalPages={100}
186
+ onPageChange={setPage}
187
+ maxVisiblePages={7}
188
+ />
189
+ )
190
+ },
191
+ }
192
+
193
+ export const FewPages: Story = {
194
+ render: () => {
195
+ const [page, setPage] = React.useState(2)
196
+ return (
197
+ <WakaPagination
198
+ page={page}
199
+ totalPages={3}
200
+ onPageChange={setPage}
201
+ />
202
+ )
203
+ },
204
+ }
205
+
206
+ export const NoFirstLast: Story = {
207
+ render: () => {
208
+ const [page, setPage] = React.useState(5)
209
+ return (
210
+ <WakaPagination
211
+ page={page}
212
+ totalPages={10}
213
+ onPageChange={setPage}
214
+ showFirstLast={false}
215
+ />
216
+ )
217
+ },
218
+ }
219
+
220
+ export const WithHook: Story = {
221
+ render: () => {
222
+ const pagination = usePagination({
223
+ totalItems: 156,
224
+ initialPageSize: 10,
225
+ initialPage: 1,
226
+ })
227
+
228
+ return (
229
+ <div className="space-y-4">
230
+ <WakaPagination
231
+ page={pagination.page}
232
+ totalPages={pagination.totalPages}
233
+ totalItems={156}
234
+ pageSize={pagination.pageSize}
235
+ onPageChange={pagination.setPage}
236
+ onPageSizeChange={pagination.setPageSize}
237
+ showPageSizeSelector
238
+ showItemsInfo
239
+ />
240
+ <div className="text-sm text-muted-foreground">
241
+ Showing items {pagination.startIndex + 1} to {pagination.endIndex + 1}
242
+ </div>
243
+ </div>
244
+ )
245
+ },
246
+ }
247
+
248
+ export const TableExample: Story = {
249
+ render: () => {
250
+ const allData = Array.from({ length: 47 }, (_, i) => ({
251
+ id: i + 1,
252
+ name: `User ${i + 1}`,
253
+ email: `user${i + 1}@example.com`,
254
+ role: ['Admin', 'Editor', 'Viewer'][i % 3],
255
+ }))
256
+
257
+ const pagination = usePagination({
258
+ totalItems: allData.length,
259
+ initialPageSize: 10,
260
+ })
261
+
262
+ const visibleData = allData.slice(pagination.startIndex, pagination.endIndex + 1)
263
+
264
+ return (
265
+ <div className="w-[600px] border rounded-lg">
266
+ <table className="w-full">
267
+ <thead className="bg-muted">
268
+ <tr>
269
+ <th className="px-4 py-2 text-left text-sm">ID</th>
270
+ <th className="px-4 py-2 text-left text-sm">Name</th>
271
+ <th className="px-4 py-2 text-left text-sm">Email</th>
272
+ <th className="px-4 py-2 text-left text-sm">Role</th>
273
+ </tr>
274
+ </thead>
275
+ <tbody>
276
+ {visibleData.map((row) => (
277
+ <tr key={row.id} className="border-t">
278
+ <td className="px-4 py-2 text-sm">{row.id}</td>
279
+ <td className="px-4 py-2 text-sm">{row.name}</td>
280
+ <td className="px-4 py-2 text-sm text-muted-foreground">{row.email}</td>
281
+ <td className="px-4 py-2 text-sm">{row.role}</td>
282
+ </tr>
283
+ ))}
284
+ </tbody>
285
+ </table>
286
+ <div className="border-t p-4">
287
+ <WakaPagination
288
+ page={pagination.page}
289
+ totalPages={pagination.totalPages}
290
+ totalItems={allData.length}
291
+ pageSize={pagination.pageSize}
292
+ onPageChange={pagination.setPage}
293
+ onPageSizeChange={pagination.setPageSize}
294
+ showPageSizeSelector
295
+ showItemsInfo
296
+ pageSizeOptions={[5, 10, 20]}
297
+ />
298
+ </div>
299
+ </div>
300
+ )
301
+ },
302
+ }
303
+
304
+ export const CustomLabels: Story = {
305
+ render: () => {
306
+ const [page, setPage] = React.useState(1)
307
+ return (
308
+ <WakaPagination
309
+ page={page}
310
+ totalPages={10}
311
+ totalItems={95}
312
+ pageSize={10}
313
+ onPageChange={setPage}
314
+ showItemsInfo
315
+ labels={{
316
+ page: 'Page',
317
+ of: 'of',
318
+ items: 'results',
319
+ itemsPerPage: 'Per page',
320
+ first: 'Go to first',
321
+ previous: 'Previous',
322
+ next: 'Next',
323
+ last: 'Go to last',
324
+ }}
325
+ />
326
+ )
327
+ },
328
+ }