nextworks 0.2.0-alpha.11 → 0.2.0-alpha.13
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/README.md +283 -282
- package/dist/cli_manifests/blocks_manifest.json +198 -175
- package/dist/kits/blocks/.nextworks/docs/BLOCKS_QUICKSTART.md +101 -100
- package/dist/kits/blocks/.nextworks/docs/BLOCKS_README.md +105 -104
- package/dist/kits/blocks/.nextworks/docs/THEME_GUIDE.md +1 -1
- package/dist/kits/blocks/app/templates/aiworkflow/PresetThemeVars.tsx +58 -0
- package/dist/kits/blocks/app/templates/aiworkflow/README.md +46 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/CTA.tsx +44 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Contact.tsx +105 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/FAQ.tsx +63 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Features.tsx +65 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Footer.tsx +109 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Hero.tsx +636 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Navbar.tsx +90 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Pricing.tsx +86 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/ProcessTimeline.tsx +103 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Testimonials.tsx +56 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/TrustBadges.tsx +59 -0
- package/dist/kits/blocks/app/templates/aiworkflow/page.tsx +43 -0
- package/dist/kits/blocks/app/templates/digitalagency/PresetThemeVars.tsx +80 -80
- package/dist/kits/blocks/app/templates/digitalagency/README.md +42 -42
- package/dist/kits/blocks/app/templates/digitalagency/components/Pricing.tsx +114 -114
- package/dist/kits/blocks/app/templates/digitalagency/components/Process.tsx +59 -59
- package/dist/kits/blocks/app/templates/digitalagency/components/Services.tsx +55 -55
- package/dist/kits/blocks/app/templates/digitalagency/components/Team.tsx +28 -28
- package/dist/kits/blocks/app/templates/digitalagency/components/Testimonials.tsx +65 -65
- package/dist/kits/blocks/app/templates/digitalagency/page.tsx +38 -38
- package/dist/kits/blocks/app/templates/gallery/PresetThemeVars.tsx +84 -84
- package/dist/kits/blocks/app/templates/productlaunch/PresetThemeVars.tsx +75 -75
- package/dist/kits/blocks/app/templates/productlaunch/README.md +62 -62
- package/dist/kits/blocks/app/templates/productlaunch/components/About.tsx +84 -84
- package/dist/kits/blocks/app/templates/productlaunch/components/CTA.tsx +50 -50
- package/dist/kits/blocks/app/templates/productlaunch/components/Contact.tsx +231 -231
- package/dist/kits/blocks/app/templates/productlaunch/components/FAQ.tsx +86 -86
- package/dist/kits/blocks/app/templates/productlaunch/components/Features.tsx +83 -83
- package/dist/kits/blocks/app/templates/productlaunch/components/Footer.tsx +132 -132
- package/dist/kits/blocks/app/templates/productlaunch/components/Hero.tsx +88 -88
- package/dist/kits/blocks/app/templates/productlaunch/components/Navbar.tsx +116 -116
- package/dist/kits/blocks/app/templates/productlaunch/components/Pricing.tsx +106 -106
- package/dist/kits/blocks/app/templates/productlaunch/components/ProcessTimeline.tsx +110 -110
- package/dist/kits/blocks/app/templates/productlaunch/components/ServicesGrid.tsx +68 -68
- package/dist/kits/blocks/app/templates/productlaunch/components/Team.tsx +104 -104
- package/dist/kits/blocks/app/templates/productlaunch/components/Testimonials.tsx +90 -90
- package/dist/kits/blocks/app/templates/productlaunch/components/TrustBadges.tsx +76 -76
- package/dist/kits/blocks/app/templates/productlaunch/page.tsx +43 -43
- package/dist/kits/blocks/app/templates/saasdashboard/PresetThemeVars.tsx +80 -80
- package/dist/kits/blocks/app/templates/saasdashboard/README.md +44 -44
- package/dist/kits/blocks/app/templates/saasdashboard/components/Contact.tsx +129 -129
- package/dist/kits/blocks/app/templates/saasdashboard/components/Dashboard.tsx +293 -293
- package/dist/kits/blocks/app/templates/saasdashboard/components/FAQ.tsx +55 -55
- package/dist/kits/blocks/app/templates/saasdashboard/components/Features.tsx +90 -90
- package/dist/kits/blocks/app/templates/saasdashboard/components/Footer.tsx +77 -77
- package/dist/kits/blocks/app/templates/saasdashboard/components/Hero.tsx +104 -104
- package/dist/kits/blocks/app/templates/saasdashboard/components/Hero_mask.tsx +126 -126
- package/dist/kits/blocks/app/templates/saasdashboard/components/Navbar.tsx +117 -117
- package/dist/kits/blocks/app/templates/saasdashboard/components/Pricing.tsx +90 -90
- package/dist/kits/blocks/app/templates/saasdashboard/components/SmoothScroll.tsx +96 -96
- package/dist/kits/blocks/app/templates/saasdashboard/components/Testimonials.tsx +72 -72
- package/dist/kits/blocks/app/templates/saasdashboard/components/TrustBadges.tsx +53 -53
- package/dist/kits/blocks/app/templates/saasdashboard/page.tsx +39 -39
- package/dist/kits/blocks/components/enhanced-theme-provider.tsx +195 -195
- package/dist/kits/blocks/components/providers/BlocksAppProviders.tsx +27 -27
- package/dist/kits/blocks/components/sections/About.tsx +291 -291
- package/dist/kits/blocks/components/sections/CTA.tsx +257 -257
- package/dist/kits/blocks/components/sections/Contact.tsx +267 -267
- package/dist/kits/blocks/components/sections/FAQ.tsx +214 -214
- package/dist/kits/blocks/components/sections/Features.tsx +268 -268
- package/dist/kits/blocks/components/sections/Footer.tsx +302 -302
- package/dist/kits/blocks/components/sections/HeroMotion.tsx +308 -308
- package/dist/kits/blocks/components/sections/HeroOverlay.tsx +358 -358
- package/dist/kits/blocks/components/sections/HeroProductDemo.tsx +236 -0
- package/dist/kits/blocks/components/sections/HeroSplit.tsx +352 -352
- package/dist/kits/blocks/components/sections/Navbar.tsx +350 -350
- package/dist/kits/blocks/components/sections/PortfolioSimple.tsx +549 -549
- package/dist/kits/blocks/components/sections/Pricing.tsx +264 -264
- package/dist/kits/blocks/components/sections/ProcessTimeline.tsx +325 -325
- package/dist/kits/blocks/components/sections/ServicesGrid.tsx +210 -210
- package/dist/kits/blocks/components/sections/Team.tsx +309 -309
- package/dist/kits/blocks/components/sections/Testimonials.tsx +158 -158
- package/dist/kits/blocks/components/sections/TrustBadges.tsx +162 -162
- package/dist/kits/blocks/components/sections/product-demo/ApprovalInboxPanel.tsx +125 -0
- package/dist/kits/blocks/components/sections/product-demo/DemoStage.tsx +397 -0
- package/dist/kits/blocks/components/sections/product-demo/DemoWindow.tsx +128 -0
- package/dist/kits/blocks/components/sections/product-demo/KnowledgePanel.tsx +127 -0
- package/dist/kits/blocks/components/sections/product-demo/RunConsolePanel.tsx +150 -0
- package/dist/kits/blocks/components/sections/product-demo/WorkflowStudioPanel.tsx +191 -0
- package/dist/kits/blocks/components/sections/product-demo/types.ts +193 -0
- package/dist/kits/blocks/components/theme-provider.tsx +1 -1
- package/dist/kits/blocks/components/ui/alert-dialog.tsx +134 -134
- package/dist/kits/blocks/components/ui/brand-node.tsx +121 -121
- package/dist/kits/blocks/components/ui/button.tsx +122 -122
- package/dist/kits/blocks/components/ui/card.tsx +95 -95
- package/dist/kits/blocks/components/ui/checkbox.tsx +30 -30
- package/dist/kits/blocks/components/ui/cta-button.tsx +125 -125
- package/dist/kits/blocks/components/ui/dropdown-menu.tsx +201 -201
- package/dist/kits/blocks/components/ui/feature-card.tsx +91 -91
- package/dist/kits/blocks/components/ui/input.tsx +27 -27
- package/dist/kits/blocks/components/ui/label.tsx +29 -29
- package/dist/kits/blocks/components/ui/pricing-card.tsx +120 -120
- package/dist/kits/blocks/components/ui/select.tsx +25 -25
- package/dist/kits/blocks/components/ui/skeleton.tsx +13 -13
- package/dist/kits/blocks/components/ui/table.tsx +98 -98
- package/dist/kits/blocks/components/ui/testimonial-card.tsx +108 -108
- package/dist/kits/blocks/components/ui/textarea.tsx +26 -26
- package/dist/kits/blocks/components/ui/theme-selector.tsx +243 -243
- package/dist/kits/blocks/components/ui/theme-toggle.tsx +74 -74
- package/dist/kits/blocks/components/ui/toaster.tsx +7 -7
- package/dist/kits/blocks/lib/themes.ts +400 -400
- package/dist/kits/blocks/lib/utils.ts +6 -6
- package/dist/kits/blocks/package-deps.json +3 -3
- package/package.json +1 -1
|
@@ -1,325 +1,325 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Interface for individual process steps.
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export interface ProcessStep {
|
|
11
|
-
/** Ordinal step number starting at 1 */
|
|
12
|
-
stepNumber: number;
|
|
13
|
-
/** Short title for the step */
|
|
14
|
-
title: string;
|
|
15
|
-
/** Description of what happens in this step */
|
|
16
|
-
description: string;
|
|
17
|
-
/** Optional icon or emoji to visually represent the step */
|
|
18
|
-
icon?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Props for configuring the ProcessTimeline component (slot-style + cn).
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* - Styling: exposes slot-style className overrides; consumer classes merge
|
|
26
|
-
* after defaults via cn().
|
|
27
|
-
* - Layout: renders a horizontal timeline on desktop and vertical on mobile.
|
|
28
|
-
* - Accessibility: semantic <section> with aria-label.
|
|
29
|
-
*/
|
|
30
|
-
export interface ProcessTimelineProps {
|
|
31
|
-
/** Optional id on root */
|
|
32
|
-
id?: string;
|
|
33
|
-
/** Root className merged into section slot */
|
|
34
|
-
className?: string;
|
|
35
|
-
|
|
36
|
-
/** Array of steps to render. @defaultValue a 4-step discovery-to-launch flow */
|
|
37
|
-
steps?: ProcessStep[];
|
|
38
|
-
/** Section heading text. @defaultValue "Our Process" */
|
|
39
|
-
heading?: string;
|
|
40
|
-
/** Optional subheading text */
|
|
41
|
-
subheading?: string;
|
|
42
|
-
|
|
43
|
-
/** Styling configuration objects */
|
|
44
|
-
section?: {
|
|
45
|
-
className?: string;
|
|
46
|
-
};
|
|
47
|
-
container?: {
|
|
48
|
-
className?: string;
|
|
49
|
-
};
|
|
50
|
-
header?: {
|
|
51
|
-
className?: string;
|
|
52
|
-
};
|
|
53
|
-
headingStyle?: {
|
|
54
|
-
className?: string;
|
|
55
|
-
};
|
|
56
|
-
subheadingStyle?: {
|
|
57
|
-
className?: string;
|
|
58
|
-
};
|
|
59
|
-
timelineContainer?: {
|
|
60
|
-
className?: string;
|
|
61
|
-
};
|
|
62
|
-
desktopTimeline?: {
|
|
63
|
-
className?: string;
|
|
64
|
-
};
|
|
65
|
-
connectingLine?: {
|
|
66
|
-
className?: string;
|
|
67
|
-
};
|
|
68
|
-
stepContainer?: {
|
|
69
|
-
className?: string;
|
|
70
|
-
};
|
|
71
|
-
stepCircle?: {
|
|
72
|
-
className?: string;
|
|
73
|
-
};
|
|
74
|
-
stepNumber?: {
|
|
75
|
-
className?: string;
|
|
76
|
-
};
|
|
77
|
-
stepIcon?: {
|
|
78
|
-
className?: string;
|
|
79
|
-
};
|
|
80
|
-
stepContent?: {
|
|
81
|
-
className?: string;
|
|
82
|
-
};
|
|
83
|
-
stepTitle?: {
|
|
84
|
-
className?: string;
|
|
85
|
-
};
|
|
86
|
-
stepDescription?: {
|
|
87
|
-
className?: string;
|
|
88
|
-
};
|
|
89
|
-
mobileTimeline?: {
|
|
90
|
-
className?: string;
|
|
91
|
-
};
|
|
92
|
-
mobileStep?: {
|
|
93
|
-
className?: string;
|
|
94
|
-
};
|
|
95
|
-
mobileVerticalLine?: {
|
|
96
|
-
className?: string;
|
|
97
|
-
};
|
|
98
|
-
mobileStepCircle?: {
|
|
99
|
-
className?: string;
|
|
100
|
-
};
|
|
101
|
-
mobileStepContent?: {
|
|
102
|
-
className?: string;
|
|
103
|
-
};
|
|
104
|
-
mobileStepIcon?: {
|
|
105
|
-
className?: string;
|
|
106
|
-
};
|
|
107
|
-
mobileStepTitle?: {
|
|
108
|
-
className?: string;
|
|
109
|
-
};
|
|
110
|
-
mobileStepDescription?: {
|
|
111
|
-
className?: string;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
/** ARIA label for the process timeline section */
|
|
115
|
-
ariaLabel?: string;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Responsive timeline showing a multi-step process for your workflow.
|
|
120
|
-
*
|
|
121
|
-
* @remarks
|
|
122
|
-
* - Renders horizontally on desktop and vertically on mobile.
|
|
123
|
-
* - Slot-style className overrides are merged after defaults via cn().
|
|
124
|
-
* - Uses a semantic <section> and supports aria-label.
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* <ProcessTimeline steps={[{ stepNumber: 1, title: 'Plan', description: '...' }]} />
|
|
128
|
-
*/
|
|
129
|
-
export function ProcessTimeline({
|
|
130
|
-
id,
|
|
131
|
-
className,
|
|
132
|
-
steps = [
|
|
133
|
-
{
|
|
134
|
-
stepNumber: 1,
|
|
135
|
-
title: "Discovery Call",
|
|
136
|
-
description: "Understanding your goals and requirements",
|
|
137
|
-
icon: "🔍",
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
stepNumber: 2,
|
|
141
|
-
title: "Strategy & Design",
|
|
142
|
-
description: "Custom mockups and project roadmap",
|
|
143
|
-
icon: "🎨",
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
stepNumber: 3,
|
|
147
|
-
title: "Development",
|
|
148
|
-
description: "Building your site with regular updates",
|
|
149
|
-
icon: "⚡",
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
stepNumber: 4,
|
|
153
|
-
title: "Launch & Support",
|
|
154
|
-
description: "Going live with ongoing maintenance",
|
|
155
|
-
icon: "🚀",
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
heading = "Our Process",
|
|
159
|
-
subheading,
|
|
160
|
-
section = {
|
|
161
|
-
className: "py-16 md:py-20 bg-muted",
|
|
162
|
-
},
|
|
163
|
-
container = {
|
|
164
|
-
className: "max-w-6xl mx-auto px-5 md:px-10",
|
|
165
|
-
},
|
|
166
|
-
header = {
|
|
167
|
-
className: "space-y-4 mb-12 md:mb-16 text-center",
|
|
168
|
-
},
|
|
169
|
-
headingStyle = {
|
|
170
|
-
className:
|
|
171
|
-
"text-4xl md:text-5xl font-bold font-poppins text-foreground leading-tight",
|
|
172
|
-
},
|
|
173
|
-
subheadingStyle = {
|
|
174
|
-
className:
|
|
175
|
-
"text-lg md:text-xl font-inter text-muted-foreground max-w-2xl mx-auto leading-relaxed",
|
|
176
|
-
},
|
|
177
|
-
timelineContainer = {
|
|
178
|
-
className: "w-full max-w-4xl mx-auto",
|
|
179
|
-
},
|
|
180
|
-
desktopTimeline = {
|
|
181
|
-
className: "hidden lg:flex justify-between items-start relative w-full",
|
|
182
|
-
},
|
|
183
|
-
connectingLine = {
|
|
184
|
-
className:
|
|
185
|
-
"absolute top-8 left-15 right-15 h-0.5 z-10 bg-[var(--process-connector)] dark:bg-[var(--process-connector)]",
|
|
186
|
-
},
|
|
187
|
-
stepContainer = {
|
|
188
|
-
className:
|
|
189
|
-
"flex flex-col items-center space-y-4 flex-1 max-w-48 relative z-20",
|
|
190
|
-
},
|
|
191
|
-
stepCircle = {
|
|
192
|
-
className:
|
|
193
|
-
"w-15 h-15 font-bold text-2xl rounded-full flex items-center justify-center shadow-lg relative z-30 bg-[var(--process-step-bg)] text-[var(--process-step-fg)] dark:bg-[var(--process-step-bg)] dark:text-[var(--process-step-fg)]",
|
|
194
|
-
},
|
|
195
|
-
stepNumber = {
|
|
196
|
-
className:
|
|
197
|
-
"font-bold text-2xl text-[var(--process-step-fg)] dark:text-[var(--process-step-fg)]",
|
|
198
|
-
},
|
|
199
|
-
stepIcon = {
|
|
200
|
-
className: "text-2xl md:text-3xl mb-2",
|
|
201
|
-
},
|
|
202
|
-
stepContent = {
|
|
203
|
-
className: "space-y-2 text-center",
|
|
204
|
-
},
|
|
205
|
-
stepTitle = {
|
|
206
|
-
className:
|
|
207
|
-
"text-lg md:text-xl font-semibold font-poppins text-foreground leading-tight",
|
|
208
|
-
},
|
|
209
|
-
stepDescription = {
|
|
210
|
-
className:
|
|
211
|
-
"text-sm md:text-base font-inter leading-relaxed text-[var(--description-fg)]",
|
|
212
|
-
},
|
|
213
|
-
mobileTimeline = {
|
|
214
|
-
className: "flex lg:hidden flex-col space-y-8 w-full",
|
|
215
|
-
},
|
|
216
|
-
mobileStep = {
|
|
217
|
-
className: "flex items-start relative",
|
|
218
|
-
},
|
|
219
|
-
mobileVerticalLine = {
|
|
220
|
-
className:
|
|
221
|
-
"absolute left-7 top-15 bottom-[-2rem] w-0.5 z-10 bg-[var(--process-connector)] dark:bg-[var(--process-connector)]",
|
|
222
|
-
},
|
|
223
|
-
mobileStepCircle = {
|
|
224
|
-
className:
|
|
225
|
-
"w-15 h-15 font-bold text-2xl rounded-full flex items-center justify-center shadow-lg flex-shrink-0 mr-6 z-20 bg-[var(--process-step-bg)] text-[var(--process-step-fg)] dark:bg-[var(--process-step-bg)] dark:text-[var(--process-step-fg)]",
|
|
226
|
-
},
|
|
227
|
-
mobileStepContent = {
|
|
228
|
-
className: "flex flex-col items-start space-y-3 flex-1 pt-2",
|
|
229
|
-
},
|
|
230
|
-
mobileStepIcon = {
|
|
231
|
-
className: "text-2xl md:text-3xl",
|
|
232
|
-
},
|
|
233
|
-
mobileStepTitle = {
|
|
234
|
-
className:
|
|
235
|
-
"text-lg md:text-xl font-semibold font-poppins text-foreground leading-tight",
|
|
236
|
-
},
|
|
237
|
-
mobileStepDescription = {
|
|
238
|
-
className:
|
|
239
|
-
"text-sm md:text-base font-inter leading-relaxed text-[var(--description-fg)]",
|
|
240
|
-
},
|
|
241
|
-
ariaLabel = "Process timeline section",
|
|
242
|
-
}: ProcessTimelineProps) {
|
|
243
|
-
return (
|
|
244
|
-
<section
|
|
245
|
-
id={id}
|
|
246
|
-
className={cn(section.className, className)}
|
|
247
|
-
aria-label={ariaLabel}
|
|
248
|
-
>
|
|
249
|
-
<div className={container.className}>
|
|
250
|
-
{/* Section Header */}
|
|
251
|
-
<div className={header.className}>
|
|
252
|
-
<h2 className={headingStyle.className}>{heading}</h2>
|
|
253
|
-
{subheading && (
|
|
254
|
-
<p className={subheadingStyle.className}>{subheading}</p>
|
|
255
|
-
)}
|
|
256
|
-
</div>
|
|
257
|
-
|
|
258
|
-
{/* Timeline Steps */}
|
|
259
|
-
<div className={timelineContainer.className}>
|
|
260
|
-
{/* Desktop: Horizontal Layout */}
|
|
261
|
-
<div className={desktopTimeline.className}>
|
|
262
|
-
{/* Connecting Line */}
|
|
263
|
-
<div className={connectingLine.className} />
|
|
264
|
-
|
|
265
|
-
{steps.map((step) => (
|
|
266
|
-
<div key={step.stepNumber} className={stepContainer.className}>
|
|
267
|
-
{/* Step Circle with Number */}
|
|
268
|
-
<div className={stepCircle.className}>
|
|
269
|
-
<span className={stepNumber.className}>
|
|
270
|
-
{step.stepNumber}
|
|
271
|
-
</span>
|
|
272
|
-
</div>
|
|
273
|
-
|
|
274
|
-
{/* Step Icon */}
|
|
275
|
-
{step.icon && (
|
|
276
|
-
<div className={stepIcon.className}>{step.icon}</div>
|
|
277
|
-
)}
|
|
278
|
-
|
|
279
|
-
{/* Step Content */}
|
|
280
|
-
<div className={stepContent.className}>
|
|
281
|
-
<h3 className={stepTitle.className}>{step.title}</h3>
|
|
282
|
-
<p className={stepDescription.className}>
|
|
283
|
-
{step.description}
|
|
284
|
-
</p>
|
|
285
|
-
</div>
|
|
286
|
-
</div>
|
|
287
|
-
))}
|
|
288
|
-
</div>
|
|
289
|
-
|
|
290
|
-
{/* Mobile: Vertical Layout */}
|
|
291
|
-
<div className={mobileTimeline.className}>
|
|
292
|
-
{steps.map((step, index) => (
|
|
293
|
-
<div key={step.stepNumber} className={mobileStep.className}>
|
|
294
|
-
{/* Vertical Line */}
|
|
295
|
-
{index < steps.length - 1 && (
|
|
296
|
-
<div className={mobileVerticalLine.className} />
|
|
297
|
-
)}
|
|
298
|
-
|
|
299
|
-
{/* Step Circle */}
|
|
300
|
-
<div className={mobileStepCircle.className}>
|
|
301
|
-
<span className={stepNumber.className}>
|
|
302
|
-
{step.stepNumber}
|
|
303
|
-
</span>
|
|
304
|
-
</div>
|
|
305
|
-
|
|
306
|
-
{/* Step Content */}
|
|
307
|
-
<div className={mobileStepContent.className}>
|
|
308
|
-
{/* Step Icon */}
|
|
309
|
-
{step.icon && (
|
|
310
|
-
<div className={mobileStepIcon.className}>{step.icon}</div>
|
|
311
|
-
)}
|
|
312
|
-
|
|
313
|
-
<h3 className={mobileStepTitle.className}>{step.title}</h3>
|
|
314
|
-
<p className={mobileStepDescription.className}>
|
|
315
|
-
{step.description}
|
|
316
|
-
</p>
|
|
317
|
-
</div>
|
|
318
|
-
</div>
|
|
319
|
-
))}
|
|
320
|
-
</div>
|
|
321
|
-
</div>
|
|
322
|
-
</div>
|
|
323
|
-
</section>
|
|
324
|
-
);
|
|
325
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Interface for individual process steps.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export interface ProcessStep {
|
|
11
|
+
/** Ordinal step number starting at 1 */
|
|
12
|
+
stepNumber: number;
|
|
13
|
+
/** Short title for the step */
|
|
14
|
+
title: string;
|
|
15
|
+
/** Description of what happens in this step */
|
|
16
|
+
description: string;
|
|
17
|
+
/** Optional icon or emoji to visually represent the step */
|
|
18
|
+
icon?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Props for configuring the ProcessTimeline component (slot-style + cn).
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* - Styling: exposes slot-style className overrides; consumer classes merge
|
|
26
|
+
* after defaults via cn().
|
|
27
|
+
* - Layout: renders a horizontal timeline on desktop and vertical on mobile.
|
|
28
|
+
* - Accessibility: semantic <section> with aria-label.
|
|
29
|
+
*/
|
|
30
|
+
export interface ProcessTimelineProps {
|
|
31
|
+
/** Optional id on root */
|
|
32
|
+
id?: string;
|
|
33
|
+
/** Root className merged into section slot */
|
|
34
|
+
className?: string;
|
|
35
|
+
|
|
36
|
+
/** Array of steps to render. @defaultValue a 4-step discovery-to-launch flow */
|
|
37
|
+
steps?: ProcessStep[];
|
|
38
|
+
/** Section heading text. @defaultValue "Our Process" */
|
|
39
|
+
heading?: string;
|
|
40
|
+
/** Optional subheading text */
|
|
41
|
+
subheading?: string;
|
|
42
|
+
|
|
43
|
+
/** Styling configuration objects */
|
|
44
|
+
section?: {
|
|
45
|
+
className?: string;
|
|
46
|
+
};
|
|
47
|
+
container?: {
|
|
48
|
+
className?: string;
|
|
49
|
+
};
|
|
50
|
+
header?: {
|
|
51
|
+
className?: string;
|
|
52
|
+
};
|
|
53
|
+
headingStyle?: {
|
|
54
|
+
className?: string;
|
|
55
|
+
};
|
|
56
|
+
subheadingStyle?: {
|
|
57
|
+
className?: string;
|
|
58
|
+
};
|
|
59
|
+
timelineContainer?: {
|
|
60
|
+
className?: string;
|
|
61
|
+
};
|
|
62
|
+
desktopTimeline?: {
|
|
63
|
+
className?: string;
|
|
64
|
+
};
|
|
65
|
+
connectingLine?: {
|
|
66
|
+
className?: string;
|
|
67
|
+
};
|
|
68
|
+
stepContainer?: {
|
|
69
|
+
className?: string;
|
|
70
|
+
};
|
|
71
|
+
stepCircle?: {
|
|
72
|
+
className?: string;
|
|
73
|
+
};
|
|
74
|
+
stepNumber?: {
|
|
75
|
+
className?: string;
|
|
76
|
+
};
|
|
77
|
+
stepIcon?: {
|
|
78
|
+
className?: string;
|
|
79
|
+
};
|
|
80
|
+
stepContent?: {
|
|
81
|
+
className?: string;
|
|
82
|
+
};
|
|
83
|
+
stepTitle?: {
|
|
84
|
+
className?: string;
|
|
85
|
+
};
|
|
86
|
+
stepDescription?: {
|
|
87
|
+
className?: string;
|
|
88
|
+
};
|
|
89
|
+
mobileTimeline?: {
|
|
90
|
+
className?: string;
|
|
91
|
+
};
|
|
92
|
+
mobileStep?: {
|
|
93
|
+
className?: string;
|
|
94
|
+
};
|
|
95
|
+
mobileVerticalLine?: {
|
|
96
|
+
className?: string;
|
|
97
|
+
};
|
|
98
|
+
mobileStepCircle?: {
|
|
99
|
+
className?: string;
|
|
100
|
+
};
|
|
101
|
+
mobileStepContent?: {
|
|
102
|
+
className?: string;
|
|
103
|
+
};
|
|
104
|
+
mobileStepIcon?: {
|
|
105
|
+
className?: string;
|
|
106
|
+
};
|
|
107
|
+
mobileStepTitle?: {
|
|
108
|
+
className?: string;
|
|
109
|
+
};
|
|
110
|
+
mobileStepDescription?: {
|
|
111
|
+
className?: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** ARIA label for the process timeline section */
|
|
115
|
+
ariaLabel?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Responsive timeline showing a multi-step process for your workflow.
|
|
120
|
+
*
|
|
121
|
+
* @remarks
|
|
122
|
+
* - Renders horizontally on desktop and vertically on mobile.
|
|
123
|
+
* - Slot-style className overrides are merged after defaults via cn().
|
|
124
|
+
* - Uses a semantic <section> and supports aria-label.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* <ProcessTimeline steps={[{ stepNumber: 1, title: 'Plan', description: '...' }]} />
|
|
128
|
+
*/
|
|
129
|
+
export function ProcessTimeline({
|
|
130
|
+
id,
|
|
131
|
+
className,
|
|
132
|
+
steps = [
|
|
133
|
+
{
|
|
134
|
+
stepNumber: 1,
|
|
135
|
+
title: "Discovery Call",
|
|
136
|
+
description: "Understanding your goals and requirements",
|
|
137
|
+
icon: "🔍",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
stepNumber: 2,
|
|
141
|
+
title: "Strategy & Design",
|
|
142
|
+
description: "Custom mockups and project roadmap",
|
|
143
|
+
icon: "🎨",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
stepNumber: 3,
|
|
147
|
+
title: "Development",
|
|
148
|
+
description: "Building your site with regular updates",
|
|
149
|
+
icon: "⚡",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
stepNumber: 4,
|
|
153
|
+
title: "Launch & Support",
|
|
154
|
+
description: "Going live with ongoing maintenance",
|
|
155
|
+
icon: "🚀",
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
heading = "Our Process",
|
|
159
|
+
subheading,
|
|
160
|
+
section = {
|
|
161
|
+
className: "py-16 md:py-20 bg-muted",
|
|
162
|
+
},
|
|
163
|
+
container = {
|
|
164
|
+
className: "max-w-6xl mx-auto px-5 md:px-10",
|
|
165
|
+
},
|
|
166
|
+
header = {
|
|
167
|
+
className: "space-y-4 mb-12 md:mb-16 text-center",
|
|
168
|
+
},
|
|
169
|
+
headingStyle = {
|
|
170
|
+
className:
|
|
171
|
+
"text-4xl md:text-5xl font-bold font-poppins text-foreground leading-tight",
|
|
172
|
+
},
|
|
173
|
+
subheadingStyle = {
|
|
174
|
+
className:
|
|
175
|
+
"text-lg md:text-xl font-inter text-muted-foreground max-w-2xl mx-auto leading-relaxed",
|
|
176
|
+
},
|
|
177
|
+
timelineContainer = {
|
|
178
|
+
className: "w-full max-w-4xl mx-auto",
|
|
179
|
+
},
|
|
180
|
+
desktopTimeline = {
|
|
181
|
+
className: "hidden lg:flex justify-between items-start relative w-full",
|
|
182
|
+
},
|
|
183
|
+
connectingLine = {
|
|
184
|
+
className:
|
|
185
|
+
"absolute top-8 left-15 right-15 h-0.5 z-10 bg-[var(--process-connector)] dark:bg-[var(--process-connector)]",
|
|
186
|
+
},
|
|
187
|
+
stepContainer = {
|
|
188
|
+
className:
|
|
189
|
+
"flex flex-col items-center space-y-4 flex-1 max-w-48 relative z-20",
|
|
190
|
+
},
|
|
191
|
+
stepCircle = {
|
|
192
|
+
className:
|
|
193
|
+
"w-15 h-15 font-bold text-2xl rounded-full flex items-center justify-center shadow-lg relative z-30 bg-[var(--process-step-bg)] text-[var(--process-step-fg)] dark:bg-[var(--process-step-bg)] dark:text-[var(--process-step-fg)]",
|
|
194
|
+
},
|
|
195
|
+
stepNumber = {
|
|
196
|
+
className:
|
|
197
|
+
"font-bold text-2xl text-[var(--process-step-fg)] dark:text-[var(--process-step-fg)]",
|
|
198
|
+
},
|
|
199
|
+
stepIcon = {
|
|
200
|
+
className: "text-2xl md:text-3xl mb-2",
|
|
201
|
+
},
|
|
202
|
+
stepContent = {
|
|
203
|
+
className: "space-y-2 text-center",
|
|
204
|
+
},
|
|
205
|
+
stepTitle = {
|
|
206
|
+
className:
|
|
207
|
+
"text-lg md:text-xl font-semibold font-poppins text-foreground leading-tight",
|
|
208
|
+
},
|
|
209
|
+
stepDescription = {
|
|
210
|
+
className:
|
|
211
|
+
"text-sm md:text-base font-inter leading-relaxed text-[var(--description-fg)]",
|
|
212
|
+
},
|
|
213
|
+
mobileTimeline = {
|
|
214
|
+
className: "flex lg:hidden flex-col space-y-8 w-full",
|
|
215
|
+
},
|
|
216
|
+
mobileStep = {
|
|
217
|
+
className: "flex items-start relative",
|
|
218
|
+
},
|
|
219
|
+
mobileVerticalLine = {
|
|
220
|
+
className:
|
|
221
|
+
"absolute left-7 top-15 bottom-[-2rem] w-0.5 z-10 bg-[var(--process-connector)] dark:bg-[var(--process-connector)]",
|
|
222
|
+
},
|
|
223
|
+
mobileStepCircle = {
|
|
224
|
+
className:
|
|
225
|
+
"w-15 h-15 font-bold text-2xl rounded-full flex items-center justify-center shadow-lg flex-shrink-0 mr-6 z-20 bg-[var(--process-step-bg)] text-[var(--process-step-fg)] dark:bg-[var(--process-step-bg)] dark:text-[var(--process-step-fg)]",
|
|
226
|
+
},
|
|
227
|
+
mobileStepContent = {
|
|
228
|
+
className: "flex flex-col items-start space-y-3 flex-1 pt-2",
|
|
229
|
+
},
|
|
230
|
+
mobileStepIcon = {
|
|
231
|
+
className: "text-2xl md:text-3xl",
|
|
232
|
+
},
|
|
233
|
+
mobileStepTitle = {
|
|
234
|
+
className:
|
|
235
|
+
"text-lg md:text-xl font-semibold font-poppins text-foreground leading-tight",
|
|
236
|
+
},
|
|
237
|
+
mobileStepDescription = {
|
|
238
|
+
className:
|
|
239
|
+
"text-sm md:text-base font-inter leading-relaxed text-[var(--description-fg)]",
|
|
240
|
+
},
|
|
241
|
+
ariaLabel = "Process timeline section",
|
|
242
|
+
}: ProcessTimelineProps) {
|
|
243
|
+
return (
|
|
244
|
+
<section
|
|
245
|
+
id={id}
|
|
246
|
+
className={cn(section.className, className)}
|
|
247
|
+
aria-label={ariaLabel}
|
|
248
|
+
>
|
|
249
|
+
<div className={container.className}>
|
|
250
|
+
{/* Section Header */}
|
|
251
|
+
<div className={header.className}>
|
|
252
|
+
<h2 className={headingStyle.className}>{heading}</h2>
|
|
253
|
+
{subheading && (
|
|
254
|
+
<p className={subheadingStyle.className}>{subheading}</p>
|
|
255
|
+
)}
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
{/* Timeline Steps */}
|
|
259
|
+
<div className={timelineContainer.className}>
|
|
260
|
+
{/* Desktop: Horizontal Layout */}
|
|
261
|
+
<div className={desktopTimeline.className}>
|
|
262
|
+
{/* Connecting Line */}
|
|
263
|
+
<div className={connectingLine.className} />
|
|
264
|
+
|
|
265
|
+
{steps.map((step) => (
|
|
266
|
+
<div key={step.stepNumber} className={stepContainer.className}>
|
|
267
|
+
{/* Step Circle with Number */}
|
|
268
|
+
<div className={stepCircle.className}>
|
|
269
|
+
<span className={stepNumber.className}>
|
|
270
|
+
{step.stepNumber}
|
|
271
|
+
</span>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
{/* Step Icon */}
|
|
275
|
+
{step.icon && (
|
|
276
|
+
<div className={stepIcon.className}>{step.icon}</div>
|
|
277
|
+
)}
|
|
278
|
+
|
|
279
|
+
{/* Step Content */}
|
|
280
|
+
<div className={stepContent.className}>
|
|
281
|
+
<h3 className={stepTitle.className}>{step.title}</h3>
|
|
282
|
+
<p className={stepDescription.className}>
|
|
283
|
+
{step.description}
|
|
284
|
+
</p>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
))}
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
{/* Mobile: Vertical Layout */}
|
|
291
|
+
<div className={mobileTimeline.className}>
|
|
292
|
+
{steps.map((step, index) => (
|
|
293
|
+
<div key={step.stepNumber} className={mobileStep.className}>
|
|
294
|
+
{/* Vertical Line */}
|
|
295
|
+
{index < steps.length - 1 && (
|
|
296
|
+
<div className={mobileVerticalLine.className} />
|
|
297
|
+
)}
|
|
298
|
+
|
|
299
|
+
{/* Step Circle */}
|
|
300
|
+
<div className={mobileStepCircle.className}>
|
|
301
|
+
<span className={stepNumber.className}>
|
|
302
|
+
{step.stepNumber}
|
|
303
|
+
</span>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
{/* Step Content */}
|
|
307
|
+
<div className={mobileStepContent.className}>
|
|
308
|
+
{/* Step Icon */}
|
|
309
|
+
{step.icon && (
|
|
310
|
+
<div className={mobileStepIcon.className}>{step.icon}</div>
|
|
311
|
+
)}
|
|
312
|
+
|
|
313
|
+
<h3 className={mobileStepTitle.className}>{step.title}</h3>
|
|
314
|
+
<p className={mobileStepDescription.className}>
|
|
315
|
+
{step.description}
|
|
316
|
+
</p>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
))}
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
</section>
|
|
324
|
+
);
|
|
325
|
+
}
|