@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,365 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { WakaFlowDiagram, useFlowDiagram } from './index'
|
|
3
|
+
import type { FlowNode, FlowConnection } from './index'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
import { PlayCircle, CheckCircle2, XCircle, Mail, Database, Code } from 'lucide-react'
|
|
6
|
+
|
|
7
|
+
const basicNodes: FlowNode[] = [
|
|
8
|
+
{ id: 'start', type: 'start', label: 'Start', position: { x: 100, y: 200 } },
|
|
9
|
+
{ id: 'process1', type: 'process', label: 'Process Data', position: { x: 300, y: 200 } },
|
|
10
|
+
{ id: 'decision', type: 'decision', label: 'Valid?', position: { x: 500, y: 200 } },
|
|
11
|
+
{ id: 'success', type: 'action', label: 'Save', position: { x: 700, y: 150 } },
|
|
12
|
+
{ id: 'error', type: 'action', label: 'Log Error', position: { x: 700, y: 280 } },
|
|
13
|
+
{ id: 'end', type: 'end', label: 'End', position: { x: 900, y: 200 } },
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
const basicConnections: FlowConnection[] = [
|
|
17
|
+
{ id: 'conn1', from: 'start', to: 'process1' },
|
|
18
|
+
{ id: 'conn2', from: 'process1', to: 'decision' },
|
|
19
|
+
{ id: 'conn3', from: 'decision', to: 'success', label: 'Yes' },
|
|
20
|
+
{ id: 'conn4', from: 'decision', to: 'error', label: 'No' },
|
|
21
|
+
{ id: 'conn5', from: 'success', to: 'end' },
|
|
22
|
+
{ id: 'conn6', from: 'error', to: 'end' },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const cicdNodes: FlowNode[] = [
|
|
26
|
+
{ id: 'commit', type: 'start', label: 'Git Commit', position: { x: 100, y: 200 }, icon: <Code className="h-4 w-4" /> },
|
|
27
|
+
{ id: 'build', type: 'process', label: 'Build', position: { x: 280, y: 200 } },
|
|
28
|
+
{ id: 'test', type: 'process', label: 'Run Tests', position: { x: 460, y: 200 } },
|
|
29
|
+
{ id: 'testPass', type: 'decision', label: 'Pass?', position: { x: 640, y: 200 } },
|
|
30
|
+
{ id: 'deploy', type: 'action', label: 'Deploy', position: { x: 820, y: 150 } },
|
|
31
|
+
{ id: 'notify', type: 'action', label: 'Notify', position: { x: 820, y: 280 }, icon: <Mail className="h-4 w-4" /> },
|
|
32
|
+
{ id: 'done', type: 'end', label: 'Done', position: { x: 1000, y: 200 } },
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
const cicdConnections: FlowConnection[] = [
|
|
36
|
+
{ id: 'c1', from: 'commit', to: 'build', animated: true },
|
|
37
|
+
{ id: 'c2', from: 'build', to: 'test', animated: true },
|
|
38
|
+
{ id: 'c3', from: 'test', to: 'testPass', animated: true },
|
|
39
|
+
{ id: 'c4', from: 'testPass', to: 'deploy', label: 'Yes', color: '#22c55e' },
|
|
40
|
+
{ id: 'c5', from: 'testPass', to: 'notify', label: 'No', color: '#ef4444' },
|
|
41
|
+
{ id: 'c6', from: 'deploy', to: 'done' },
|
|
42
|
+
{ id: 'c7', from: 'notify', to: 'done' },
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
const approvalNodes: FlowNode[] = [
|
|
46
|
+
{ id: 'submit', type: 'start', label: 'Submit Request', position: { x: 150, y: 200 } },
|
|
47
|
+
{ id: 'review', type: 'process', label: 'Manager Review', position: { x: 350, y: 200 } },
|
|
48
|
+
{ id: 'approved', type: 'decision', label: 'Approved?', position: { x: 550, y: 200 } },
|
|
49
|
+
{ id: 'implement', type: 'action', label: 'Implement', position: { x: 750, y: 100 } },
|
|
50
|
+
{ id: 'revise', type: 'action', label: 'Revise', position: { x: 750, y: 300 } },
|
|
51
|
+
{ id: 'complete', type: 'end', label: 'Complete', position: { x: 950, y: 200 } },
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
const approvalConnections: FlowConnection[] = [
|
|
55
|
+
{ id: 'a1', from: 'submit', to: 'review' },
|
|
56
|
+
{ id: 'a2', from: 'review', to: 'approved' },
|
|
57
|
+
{ id: 'a3', from: 'approved', to: 'implement', label: 'Yes', color: '#22c55e' },
|
|
58
|
+
{ id: 'a4', from: 'approved', to: 'revise', label: 'No', color: '#f59e0b' },
|
|
59
|
+
{ id: 'a5', from: 'implement', to: 'complete' },
|
|
60
|
+
{ id: 'a6', from: 'revise', to: 'review', label: 'Resubmit' },
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
const meta: Meta<typeof WakaFlowDiagram> = {
|
|
64
|
+
title: 'Components/Charts/WakaFlowDiagram',
|
|
65
|
+
component: WakaFlowDiagram,
|
|
66
|
+
parameters: {
|
|
67
|
+
layout: 'centered',
|
|
68
|
+
docs: {
|
|
69
|
+
description: {
|
|
70
|
+
component: 'A flow diagram component for visualizing processes, workflows, and decision trees with draggable nodes and customizable connections.',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
tags: ['autodocs'],
|
|
75
|
+
argTypes: {
|
|
76
|
+
draggable: {
|
|
77
|
+
control: 'boolean',
|
|
78
|
+
description: 'Enable node dragging',
|
|
79
|
+
},
|
|
80
|
+
editable: {
|
|
81
|
+
control: 'boolean',
|
|
82
|
+
description: 'Enable editing (add/remove nodes)',
|
|
83
|
+
},
|
|
84
|
+
zoom: {
|
|
85
|
+
control: { type: 'range', min: 0.5, max: 2, step: 0.1 },
|
|
86
|
+
description: 'Zoom level',
|
|
87
|
+
},
|
|
88
|
+
gridSize: {
|
|
89
|
+
control: { type: 'range', min: 10, max: 50, step: 5 },
|
|
90
|
+
description: 'Grid size for snapping',
|
|
91
|
+
},
|
|
92
|
+
showGrid: {
|
|
93
|
+
control: 'boolean',
|
|
94
|
+
description: 'Show grid background',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default meta
|
|
100
|
+
type Story = StoryObj<typeof WakaFlowDiagram>
|
|
101
|
+
|
|
102
|
+
export const Default: Story = {
|
|
103
|
+
args: {
|
|
104
|
+
nodes: basicNodes,
|
|
105
|
+
connections: basicConnections,
|
|
106
|
+
},
|
|
107
|
+
render: (args) => (
|
|
108
|
+
<div className="w-[1000px] h-[400px]">
|
|
109
|
+
<WakaFlowDiagram {...args} />
|
|
110
|
+
</div>
|
|
111
|
+
),
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const CICDPipeline: Story = {
|
|
115
|
+
render: () => (
|
|
116
|
+
<div className="w-[1100px] h-[400px]">
|
|
117
|
+
<WakaFlowDiagram
|
|
118
|
+
nodes={cicdNodes}
|
|
119
|
+
connections={cicdConnections}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const ApprovalWorkflow: Story = {
|
|
126
|
+
render: () => (
|
|
127
|
+
<div className="w-[1100px] h-[450px]">
|
|
128
|
+
<WakaFlowDiagram
|
|
129
|
+
nodes={approvalNodes}
|
|
130
|
+
connections={approvalConnections}
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
),
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const NoDragging: Story = {
|
|
137
|
+
render: () => (
|
|
138
|
+
<div className="w-[1000px] h-[400px]">
|
|
139
|
+
<WakaFlowDiagram
|
|
140
|
+
nodes={basicNodes}
|
|
141
|
+
connections={basicConnections}
|
|
142
|
+
draggable={false}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
),
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const NoEditing: Story = {
|
|
149
|
+
render: () => (
|
|
150
|
+
<div className="w-[1000px] h-[400px]">
|
|
151
|
+
<WakaFlowDiagram
|
|
152
|
+
nodes={basicNodes}
|
|
153
|
+
connections={basicConnections}
|
|
154
|
+
editable={false}
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
),
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const NoGrid: Story = {
|
|
161
|
+
render: () => (
|
|
162
|
+
<div className="w-[1000px] h-[400px]">
|
|
163
|
+
<WakaFlowDiagram
|
|
164
|
+
nodes={basicNodes}
|
|
165
|
+
connections={basicConnections}
|
|
166
|
+
showGrid={false}
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
),
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export const ZoomLevels: Story = {
|
|
173
|
+
render: () => (
|
|
174
|
+
<div className="space-y-8">
|
|
175
|
+
<div>
|
|
176
|
+
<p className="text-sm text-muted-foreground mb-2">Zoom: 0.75x</p>
|
|
177
|
+
<div className="w-[800px] h-[300px] border rounded">
|
|
178
|
+
<WakaFlowDiagram
|
|
179
|
+
nodes={basicNodes}
|
|
180
|
+
connections={basicConnections}
|
|
181
|
+
zoom={0.75}
|
|
182
|
+
editable={false}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
<div>
|
|
187
|
+
<p className="text-sm text-muted-foreground mb-2">Zoom: 1.25x</p>
|
|
188
|
+
<div className="w-[800px] h-[400px] border rounded overflow-hidden">
|
|
189
|
+
<WakaFlowDiagram
|
|
190
|
+
nodes={basicNodes}
|
|
191
|
+
connections={basicConnections}
|
|
192
|
+
zoom={1.25}
|
|
193
|
+
editable={false}
|
|
194
|
+
/>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
),
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export const GridSizes: Story = {
|
|
202
|
+
render: () => (
|
|
203
|
+
<div className="space-y-8">
|
|
204
|
+
<div>
|
|
205
|
+
<p className="text-sm text-muted-foreground mb-2">Grid: 10px (fine)</p>
|
|
206
|
+
<div className="w-[600px] h-[250px]">
|
|
207
|
+
<WakaFlowDiagram
|
|
208
|
+
nodes={basicNodes.slice(0, 3)}
|
|
209
|
+
connections={basicConnections.slice(0, 2)}
|
|
210
|
+
gridSize={10}
|
|
211
|
+
editable={false}
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div>
|
|
216
|
+
<p className="text-sm text-muted-foreground mb-2">Grid: 40px (coarse)</p>
|
|
217
|
+
<div className="w-[600px] h-[250px]">
|
|
218
|
+
<WakaFlowDiagram
|
|
219
|
+
nodes={basicNodes.slice(0, 3)}
|
|
220
|
+
connections={basicConnections.slice(0, 2)}
|
|
221
|
+
gridSize={40}
|
|
222
|
+
editable={false}
|
|
223
|
+
/>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
),
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export const WithHook: Story = {
|
|
231
|
+
render: () => {
|
|
232
|
+
const { nodes, connections, addNode, addConnection, removeNode, clear } = useFlowDiagram(
|
|
233
|
+
basicNodes.slice(0, 3),
|
|
234
|
+
basicConnections.slice(0, 2)
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<div className="space-y-4">
|
|
239
|
+
<div className="flex gap-2 flex-wrap">
|
|
240
|
+
<button
|
|
241
|
+
onClick={() => {
|
|
242
|
+
const newNode = addNode({
|
|
243
|
+
type: 'action',
|
|
244
|
+
label: `Action ${nodes.length + 1}`,
|
|
245
|
+
position: { x: 200 + nodes.length * 100, y: 100 + Math.random() * 200 },
|
|
246
|
+
})
|
|
247
|
+
}}
|
|
248
|
+
className="px-3 py-1 text-sm border rounded hover:bg-muted"
|
|
249
|
+
>
|
|
250
|
+
Add Action Node
|
|
251
|
+
</button>
|
|
252
|
+
<button
|
|
253
|
+
onClick={() => {
|
|
254
|
+
addNode({
|
|
255
|
+
type: 'decision',
|
|
256
|
+
label: `Decision ${nodes.length + 1}`,
|
|
257
|
+
position: { x: 300 + nodes.length * 80, y: 150 + Math.random() * 150 },
|
|
258
|
+
})
|
|
259
|
+
}}
|
|
260
|
+
className="px-3 py-1 text-sm border rounded hover:bg-muted"
|
|
261
|
+
>
|
|
262
|
+
Add Decision Node
|
|
263
|
+
</button>
|
|
264
|
+
<button
|
|
265
|
+
onClick={clear}
|
|
266
|
+
className="px-3 py-1 text-sm border rounded hover:bg-muted text-red-600"
|
|
267
|
+
>
|
|
268
|
+
Clear All
|
|
269
|
+
</button>
|
|
270
|
+
</div>
|
|
271
|
+
<div className="w-[900px] h-[400px]">
|
|
272
|
+
<WakaFlowDiagram
|
|
273
|
+
nodes={nodes}
|
|
274
|
+
connections={connections}
|
|
275
|
+
onNodesChange={(n) => console.log('Nodes changed:', n)}
|
|
276
|
+
onConnectionsChange={(c) => console.log('Connections changed:', c)}
|
|
277
|
+
/>
|
|
278
|
+
</div>
|
|
279
|
+
<p className="text-sm text-muted-foreground">
|
|
280
|
+
Nodes: {nodes.length} | Connections: {connections.length}
|
|
281
|
+
</p>
|
|
282
|
+
</div>
|
|
283
|
+
)
|
|
284
|
+
},
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export const Interactive: Story = {
|
|
288
|
+
render: () => {
|
|
289
|
+
const [selectedNode, setSelectedNode] = React.useState<FlowNode | null>(null)
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<div className="space-y-4">
|
|
293
|
+
<div className="w-[1000px] h-[400px]">
|
|
294
|
+
<WakaFlowDiagram
|
|
295
|
+
nodes={cicdNodes}
|
|
296
|
+
connections={cicdConnections}
|
|
297
|
+
onNodeClick={(node) => setSelectedNode(node)}
|
|
298
|
+
/>
|
|
299
|
+
</div>
|
|
300
|
+
{selectedNode && (
|
|
301
|
+
<div className="p-4 border rounded-lg bg-muted/50">
|
|
302
|
+
<h4 className="font-semibold">{selectedNode.label}</h4>
|
|
303
|
+
<p className="text-sm text-muted-foreground">Type: {selectedNode.type}</p>
|
|
304
|
+
<p className="text-sm text-muted-foreground">
|
|
305
|
+
Position: ({selectedNode.position.x}, {selectedNode.position.y})
|
|
306
|
+
</p>
|
|
307
|
+
{selectedNode.description && (
|
|
308
|
+
<p className="text-sm mt-2">{selectedNode.description}</p>
|
|
309
|
+
)}
|
|
310
|
+
</div>
|
|
311
|
+
)}
|
|
312
|
+
</div>
|
|
313
|
+
)
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export const PipelineDashboard: Story = {
|
|
318
|
+
render: () => (
|
|
319
|
+
<div className="w-[1150px] p-6 border rounded-lg">
|
|
320
|
+
<div className="flex justify-between items-start mb-4">
|
|
321
|
+
<div>
|
|
322
|
+
<h3 className="text-xl font-semibold">CI/CD Pipeline</h3>
|
|
323
|
+
<p className="text-sm text-muted-foreground">main branch • Last run: 2 minutes ago</p>
|
|
324
|
+
</div>
|
|
325
|
+
<div className="flex items-center gap-2">
|
|
326
|
+
<div className="w-3 h-3 rounded-full bg-green-500 animate-pulse" />
|
|
327
|
+
<span className="text-sm text-green-600 font-medium">Running</span>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
<div className="h-[350px]">
|
|
331
|
+
<WakaFlowDiagram
|
|
332
|
+
nodes={cicdNodes}
|
|
333
|
+
connections={cicdConnections}
|
|
334
|
+
editable={false}
|
|
335
|
+
draggable={false}
|
|
336
|
+
/>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
),
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export const NodeTypes: Story = {
|
|
343
|
+
render: () => {
|
|
344
|
+
const typeNodes: FlowNode[] = [
|
|
345
|
+
{ id: 'start', type: 'start', label: 'Start', position: { x: 100, y: 100 } },
|
|
346
|
+
{ id: 'end', type: 'end', label: 'End', position: { x: 300, y: 100 } },
|
|
347
|
+
{ id: 'action', type: 'action', label: 'Action', position: { x: 100, y: 220 } },
|
|
348
|
+
{ id: 'process', type: 'process', label: 'Process', position: { x: 300, y: 220 } },
|
|
349
|
+
{ id: 'decision', type: 'decision', label: 'Decision', position: { x: 200, y: 340 } },
|
|
350
|
+
]
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<div className="space-y-4">
|
|
354
|
+
<p className="text-sm text-muted-foreground">Available node types:</p>
|
|
355
|
+
<div className="w-[500px] h-[450px]">
|
|
356
|
+
<WakaFlowDiagram
|
|
357
|
+
nodes={typeNodes}
|
|
358
|
+
connections={[]}
|
|
359
|
+
editable={false}
|
|
360
|
+
/>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
)
|
|
364
|
+
},
|
|
365
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { WakaFunnelChart, useFunnelChart } from './index'
|
|
3
|
+
import type { FunnelStage } from './index'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
|
|
6
|
+
const conversionData: FunnelStage[] = [
|
|
7
|
+
{ id: 'visitors', label: 'Visitors', value: 10000 },
|
|
8
|
+
{ id: 'signups', label: 'Sign Ups', value: 4500 },
|
|
9
|
+
{ id: 'trials', label: 'Free Trials', value: 2000 },
|
|
10
|
+
{ id: 'purchases', label: 'Purchases', value: 800 },
|
|
11
|
+
{ id: 'retention', label: 'Retained', value: 600 },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
const salesPipelineData: FunnelStage[] = [
|
|
15
|
+
{ id: 'leads', label: 'Leads', value: 5000, color: '#3b82f6' },
|
|
16
|
+
{ id: 'qualified', label: 'Qualified', value: 2500, color: '#8b5cf6' },
|
|
17
|
+
{ id: 'proposals', label: 'Proposals', value: 1200, color: '#ec4899' },
|
|
18
|
+
{ id: 'negotiations', label: 'Negotiations', value: 600, color: '#f59e0b' },
|
|
19
|
+
{ id: 'closed', label: 'Closed Won', value: 300, color: '#22c55e' },
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const recruitmentData: FunnelStage[] = [
|
|
23
|
+
{ id: 'applications', label: 'Applications', value: 1000 },
|
|
24
|
+
{ id: 'screening', label: 'Phone Screening', value: 350 },
|
|
25
|
+
{ id: 'interviews', label: 'Interviews', value: 120 },
|
|
26
|
+
{ id: 'offers', label: 'Offers Made', value: 40 },
|
|
27
|
+
{ id: 'hired', label: 'Hired', value: 25 },
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
const meta: Meta<typeof WakaFunnelChart> = {
|
|
31
|
+
title: 'Components/Charts/WakaFunnelChart',
|
|
32
|
+
component: WakaFunnelChart,
|
|
33
|
+
parameters: {
|
|
34
|
+
layout: 'centered',
|
|
35
|
+
docs: {
|
|
36
|
+
description: {
|
|
37
|
+
component: 'A funnel chart for visualizing conversion rates and process flows with smooth transitions between stages.',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
tags: ['autodocs'],
|
|
42
|
+
argTypes: {
|
|
43
|
+
orientation: {
|
|
44
|
+
control: 'select',
|
|
45
|
+
options: ['vertical', 'horizontal'],
|
|
46
|
+
description: 'Funnel orientation',
|
|
47
|
+
},
|
|
48
|
+
showLabels: {
|
|
49
|
+
control: 'boolean',
|
|
50
|
+
description: 'Show stage labels',
|
|
51
|
+
},
|
|
52
|
+
showValues: {
|
|
53
|
+
control: 'boolean',
|
|
54
|
+
description: 'Show stage values',
|
|
55
|
+
},
|
|
56
|
+
showPercentages: {
|
|
57
|
+
control: 'boolean',
|
|
58
|
+
description: 'Show conversion percentages',
|
|
59
|
+
},
|
|
60
|
+
animated: {
|
|
61
|
+
control: 'boolean',
|
|
62
|
+
description: 'Enable animations',
|
|
63
|
+
},
|
|
64
|
+
curved: {
|
|
65
|
+
control: 'boolean',
|
|
66
|
+
description: 'Use curved edges',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default meta
|
|
72
|
+
type Story = StoryObj<typeof WakaFunnelChart>
|
|
73
|
+
|
|
74
|
+
export const Default: Story = {
|
|
75
|
+
args: {
|
|
76
|
+
data: conversionData,
|
|
77
|
+
},
|
|
78
|
+
render: (args) => <WakaFunnelChart {...args} />,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const Orientations: Story = {
|
|
82
|
+
render: () => (
|
|
83
|
+
<div className="space-y-8">
|
|
84
|
+
<div>
|
|
85
|
+
<p className="text-sm text-muted-foreground mb-2">Vertical (Default)</p>
|
|
86
|
+
<WakaFunnelChart data={conversionData} orientation="vertical" width={400} height={300} />
|
|
87
|
+
</div>
|
|
88
|
+
<div>
|
|
89
|
+
<p className="text-sm text-muted-foreground mb-2">Horizontal</p>
|
|
90
|
+
<WakaFunnelChart data={conversionData} orientation="horizontal" width={600} height={200} />
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const WithCustomColors: Story = {
|
|
97
|
+
render: () => <WakaFunnelChart data={salesPipelineData} width={400} height={350} />,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const CurvedEdges: Story = {
|
|
101
|
+
render: () => (
|
|
102
|
+
<div className="flex gap-8">
|
|
103
|
+
<div className="text-center">
|
|
104
|
+
<WakaFunnelChart data={conversionData} curved={false} width={300} height={280} />
|
|
105
|
+
<p className="text-sm text-muted-foreground mt-2">Sharp Edges</p>
|
|
106
|
+
</div>
|
|
107
|
+
<div className="text-center">
|
|
108
|
+
<WakaFunnelChart data={conversionData} curved width={300} height={280} />
|
|
109
|
+
<p className="text-sm text-muted-foreground mt-2">Curved Edges</p>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
),
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const ShowPercentages: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<WakaFunnelChart
|
|
118
|
+
data={conversionData}
|
|
119
|
+
showPercentages
|
|
120
|
+
width={450}
|
|
121
|
+
height={350}
|
|
122
|
+
/>
|
|
123
|
+
),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const HideLabels: Story = {
|
|
127
|
+
render: () => (
|
|
128
|
+
<div className="flex gap-8">
|
|
129
|
+
<div className="text-center">
|
|
130
|
+
<WakaFunnelChart data={conversionData} showLabels={false} width={250} height={250} />
|
|
131
|
+
<p className="text-sm text-muted-foreground mt-2">No Labels</p>
|
|
132
|
+
</div>
|
|
133
|
+
<div className="text-center">
|
|
134
|
+
<WakaFunnelChart data={conversionData} showValues={false} width={250} height={250} />
|
|
135
|
+
<p className="text-sm text-muted-foreground mt-2">No Values</p>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const Sizes: Story = {
|
|
142
|
+
render: () => (
|
|
143
|
+
<div className="flex items-end gap-8">
|
|
144
|
+
<div className="text-center">
|
|
145
|
+
<WakaFunnelChart data={conversionData} width={200} height={180} />
|
|
146
|
+
<p className="text-sm text-muted-foreground mt-2">Small</p>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="text-center">
|
|
149
|
+
<WakaFunnelChart data={conversionData} width={350} height={300} />
|
|
150
|
+
<p className="text-sm text-muted-foreground mt-2">Medium</p>
|
|
151
|
+
</div>
|
|
152
|
+
<div className="text-center">
|
|
153
|
+
<WakaFunnelChart data={conversionData} width={500} height={400} />
|
|
154
|
+
<p className="text-sm text-muted-foreground mt-2">Large</p>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
),
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const Interactive: Story = {
|
|
161
|
+
render: () => {
|
|
162
|
+
const [selectedStage, setSelectedStage] = React.useState<FunnelStage | null>(null)
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div className="space-y-4">
|
|
166
|
+
<WakaFunnelChart
|
|
167
|
+
data={salesPipelineData}
|
|
168
|
+
width={450}
|
|
169
|
+
height={350}
|
|
170
|
+
onStageClick={(stage) => setSelectedStage(stage)}
|
|
171
|
+
showPercentages
|
|
172
|
+
/>
|
|
173
|
+
{selectedStage && (
|
|
174
|
+
<div className="p-4 border rounded-lg bg-muted/50">
|
|
175
|
+
<h4 className="font-semibold">{selectedStage.label}</h4>
|
|
176
|
+
<p className="text-2xl font-bold text-primary">{selectedStage.value.toLocaleString()}</p>
|
|
177
|
+
<p className="text-sm text-muted-foreground">
|
|
178
|
+
{((selectedStage.value / salesPipelineData[0].value) * 100).toFixed(1)}% of total leads
|
|
179
|
+
</p>
|
|
180
|
+
</div>
|
|
181
|
+
)}
|
|
182
|
+
</div>
|
|
183
|
+
)
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const WithHook: Story = {
|
|
188
|
+
render: () => {
|
|
189
|
+
const { highlightedStage, setHighlightedStage, reset, getConversionRate } = useFunnelChart()
|
|
190
|
+
|
|
191
|
+
return (
|
|
192
|
+
<div className="space-y-4">
|
|
193
|
+
<div className="flex gap-2 flex-wrap">
|
|
194
|
+
{conversionData.map((stage, index) => (
|
|
195
|
+
<button
|
|
196
|
+
key={stage.id}
|
|
197
|
+
onClick={() => setHighlightedStage(stage.id)}
|
|
198
|
+
className={`px-3 py-1 text-sm border rounded transition-colors ${
|
|
199
|
+
highlightedStage === stage.id ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'
|
|
200
|
+
}`}
|
|
201
|
+
>
|
|
202
|
+
{stage.label}
|
|
203
|
+
</button>
|
|
204
|
+
))}
|
|
205
|
+
<button onClick={reset} className="px-3 py-1 text-sm border rounded hover:bg-muted">
|
|
206
|
+
Reset
|
|
207
|
+
</button>
|
|
208
|
+
</div>
|
|
209
|
+
<WakaFunnelChart data={conversionData} width={400} height={300} />
|
|
210
|
+
<div className="grid grid-cols-2 gap-4 text-sm">
|
|
211
|
+
{conversionData.slice(1).map((stage, index) => (
|
|
212
|
+
<div key={stage.id} className="p-2 bg-muted/30 rounded">
|
|
213
|
+
<span className="text-muted-foreground">
|
|
214
|
+
{conversionData[index].label} → {stage.label}:
|
|
215
|
+
</span>{' '}
|
|
216
|
+
<span className="font-semibold">
|
|
217
|
+
{getConversionRate(conversionData[index].value, stage.value)}%
|
|
218
|
+
</span>
|
|
219
|
+
</div>
|
|
220
|
+
))}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
)
|
|
224
|
+
},
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export const RecruitmentFunnel: Story = {
|
|
228
|
+
render: () => (
|
|
229
|
+
<div className="w-[500px] p-6 border rounded-lg">
|
|
230
|
+
<h3 className="text-lg font-semibold mb-1">Recruitment Pipeline</h3>
|
|
231
|
+
<p className="text-sm text-muted-foreground mb-4">Q4 2024 Hiring Campaign</p>
|
|
232
|
+
<WakaFunnelChart
|
|
233
|
+
data={recruitmentData}
|
|
234
|
+
width={450}
|
|
235
|
+
height={350}
|
|
236
|
+
showPercentages
|
|
237
|
+
curved
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
),
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export const CompactFunnel: Story = {
|
|
244
|
+
render: () => (
|
|
245
|
+
<div className="flex gap-6">
|
|
246
|
+
<div className="p-4 border rounded-lg">
|
|
247
|
+
<h4 className="text-sm font-medium mb-2">Marketing Funnel</h4>
|
|
248
|
+
<WakaFunnelChart
|
|
249
|
+
data={conversionData.slice(0, 3)}
|
|
250
|
+
width={180}
|
|
251
|
+
height={150}
|
|
252
|
+
showLabels={false}
|
|
253
|
+
/>
|
|
254
|
+
</div>
|
|
255
|
+
<div className="p-4 border rounded-lg">
|
|
256
|
+
<h4 className="text-sm font-medium mb-2">Sales Funnel</h4>
|
|
257
|
+
<WakaFunnelChart
|
|
258
|
+
data={salesPipelineData.slice(0, 3)}
|
|
259
|
+
width={180}
|
|
260
|
+
height={150}
|
|
261
|
+
showLabels={false}
|
|
262
|
+
/>
|
|
263
|
+
</div>
|
|
264
|
+
<div className="p-4 border rounded-lg">
|
|
265
|
+
<h4 className="text-sm font-medium mb-2">Hiring Funnel</h4>
|
|
266
|
+
<WakaFunnelChart
|
|
267
|
+
data={recruitmentData.slice(0, 3)}
|
|
268
|
+
width={180}
|
|
269
|
+
height={150}
|
|
270
|
+
showLabels={false}
|
|
271
|
+
/>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
),
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const NoAnimation: Story = {
|
|
278
|
+
render: () => (
|
|
279
|
+
<WakaFunnelChart data={conversionData} animated={false} width={400} height={300} />
|
|
280
|
+
),
|
|
281
|
+
}
|