@nextworks/blocks-sections 0.1.0-alpha.11 → 0.1.0-alpha.14
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-types/components/About.d.ts +93 -0
- package/dist-types/components/About.d.ts.map +1 -0
- package/dist-types/components/CTA.d.ts +118 -0
- package/dist-types/components/CTA.d.ts.map +1 -0
- package/dist-types/components/Contact.d.ts +111 -0
- package/dist-types/components/Contact.d.ts.map +1 -0
- package/dist-types/components/FAQ.d.ts +89 -0
- package/dist-types/components/FAQ.d.ts.map +1 -0
- package/dist-types/components/Features.d.ts +111 -0
- package/dist-types/components/Features.d.ts.map +1 -0
- package/dist-types/components/Footer.d.ts +120 -0
- package/dist-types/components/Footer.d.ts.map +1 -0
- package/dist-types/components/HeroMotion.d.ts +107 -0
- package/dist-types/components/HeroMotion.d.ts.map +1 -0
- package/dist-types/components/HeroOverlay.d.ts +116 -0
- package/dist-types/components/HeroOverlay.d.ts.map +1 -0
- package/dist-types/components/HeroSplit.d.ts +98 -0
- package/dist-types/components/HeroSplit.d.ts.map +1 -0
- package/dist-types/components/Navbar.d.ts +112 -0
- package/dist-types/components/Navbar.d.ts.map +1 -0
- package/dist-types/components/Newsletter.d.ts +59 -0
- package/dist-types/components/Newsletter.d.ts.map +1 -0
- package/dist-types/components/PortfolioSimple.d.ts +137 -0
- package/dist-types/components/PortfolioSimple.d.ts.map +1 -0
- package/dist-types/components/Pricing.d.ts +96 -0
- package/dist-types/components/Pricing.d.ts.map +1 -0
- package/dist-types/components/ProcessTimeline.d.ts +121 -0
- package/dist-types/components/ProcessTimeline.d.ts.map +1 -0
- package/dist-types/components/ServicesGrid.d.ts +64 -0
- package/dist-types/components/ServicesGrid.d.ts.map +1 -0
- package/dist-types/components/Team.d.ts +115 -0
- package/dist-types/components/Team.d.ts.map +1 -0
- package/dist-types/components/Testimonials.d.ts +81 -0
- package/dist-types/components/Testimonials.d.ts.map +1 -0
- package/dist-types/components/TrustBadges.d.ts +80 -0
- package/dist-types/components/TrustBadges.d.ts.map +1 -0
- package/dist-types/components/index.d.ts +21 -0
- package/dist-types/components/index.d.ts.map +1 -0
- package/dist-types/index.d.ts +2 -0
- package/dist-types/index.d.ts.map +1 -0
- package/package.json +6 -4
- package/dist/components/About.js +0 -129
- package/dist/components/CTA.js +0 -58
- package/dist/components/Contact.js +0 -82
- package/dist/components/FAQ.js +0 -78
- package/dist/components/Features.js +0 -109
- package/dist/components/Footer.js +0 -101
- package/dist/components/HeroMotion.js +0 -55
- package/dist/components/HeroOverlay.js +0 -111
- package/dist/components/HeroSplit.js +0 -100
- package/dist/components/Navbar.js +0 -80
- package/dist/components/Newsletter.js +0 -34
- package/dist/components/PortfolioSimple.js +0 -180
- package/dist/components/Pricing.js +0 -91
- package/dist/components/ProcessTimeline.js +0 -88
- package/dist/components/ServicesGrid.js +0 -72
- package/dist/components/Team.js +0 -107
- package/dist/components/Testimonials.js +0 -46
- package/dist/components/TrustBadges.js +0 -46
package/dist/components/About.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { cn } from "@nextworks/blocks-core";
|
|
5
|
-
/**
|
|
6
|
-
* Default statistics displayed if no aboutStats are provided.
|
|
7
|
-
*/
|
|
8
|
-
const defaultStatsData = [
|
|
9
|
-
{ value: "50", label: "Successful Projects", suffix: "+" },
|
|
10
|
-
{ value: "5", label: "Years Experience", suffix: "+" },
|
|
11
|
-
{ value: "100", label: "Happy Clients", suffix: "%" },
|
|
12
|
-
{ value: "24", label: "Support Hours", suffix: "/7" },
|
|
13
|
-
];
|
|
14
|
-
/**
|
|
15
|
-
* About section with a heading, optional subheading/content, and an optional
|
|
16
|
-
* stats block.
|
|
17
|
-
*
|
|
18
|
-
* @remarks
|
|
19
|
-
* - Styling: exposes slot-style className overrides. Consumer classes are
|
|
20
|
-
* merged after defaults via cn().
|
|
21
|
-
* - Layout: control text alignment with aboutTextAlign.
|
|
22
|
-
* - Accessibility: rendered as a semantic <section> with aria-label.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* <About
|
|
26
|
-
* aboutHeadingText="Your Success Is Our Mission"
|
|
27
|
-
* aboutContentText="We build digital products that convert."
|
|
28
|
-
* aboutStats={[{ value: "50", label: "Successful Projects", suffix: "+" }]}
|
|
29
|
-
* />
|
|
30
|
-
*/
|
|
31
|
-
/**
|
|
32
|
-
* About section with a heading, optional subheading/content, and an optional
|
|
33
|
-
* stats block.
|
|
34
|
-
*
|
|
35
|
-
* @remarks
|
|
36
|
-
* - Styling: exposes slot-style className overrides. Consumer classes are
|
|
37
|
-
* merged after defaults via cn().
|
|
38
|
-
* - Layout: control text alignment with aboutTextAlign.
|
|
39
|
-
* - Accessibility: rendered as a semantic <section> with aria-label.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* <About
|
|
43
|
-
* aboutHeadingText="Your Success Is Our Mission"
|
|
44
|
-
* aboutContentText="We build digital products that convert."
|
|
45
|
-
* aboutStats={[{ value: "50", label: "Successful Projects", suffix: "+" }]}
|
|
46
|
-
* />
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* Animated count-up for integers using requestAnimationFrame.
|
|
50
|
-
* Eases out and runs once when shouldStart becomes true.
|
|
51
|
-
*/
|
|
52
|
-
function AnimatedCount({ end, shouldStart, duration = 1500, }) {
|
|
53
|
-
const [value, setValue] = React.useState(0);
|
|
54
|
-
const [done, setDone] = React.useState(false);
|
|
55
|
-
const prefersReduced = React.useMemo(() => {
|
|
56
|
-
if (typeof window === "undefined")
|
|
57
|
-
return false;
|
|
58
|
-
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
59
|
-
}, []);
|
|
60
|
-
React.useEffect(() => {
|
|
61
|
-
if (prefersReduced)
|
|
62
|
-
return; // show end value immediately below
|
|
63
|
-
if (!shouldStart || done)
|
|
64
|
-
return;
|
|
65
|
-
let raf;
|
|
66
|
-
const startTs = performance.now();
|
|
67
|
-
const tick = (now) => {
|
|
68
|
-
const progress = Math.min((now - startTs) / duration, 1);
|
|
69
|
-
const eased = 1 - Math.pow(1 - progress, 3);
|
|
70
|
-
const next = Math.round(eased * end);
|
|
71
|
-
setValue(next);
|
|
72
|
-
if (progress < 1) {
|
|
73
|
-
raf = requestAnimationFrame(tick);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
setDone(true);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
raf = requestAnimationFrame(tick);
|
|
80
|
-
return () => cancelAnimationFrame(raf);
|
|
81
|
-
}, [shouldStart, end, duration, done, prefersReduced]);
|
|
82
|
-
if (prefersReduced)
|
|
83
|
-
return _jsx(_Fragment, { children: end });
|
|
84
|
-
return _jsx(_Fragment, { children: value });
|
|
85
|
-
}
|
|
86
|
-
export function About({ aboutHeadingText = "Your Success Is Our Mission", aboutSubheadingText, aboutContentText = "With 50+ successful projects and 5 years of experience, we specialize in creating digital solutions that drive real business growth.", aboutStats = defaultStatsData, className, section = { className: "py-20 bg-muted text-foreground" }, container = { className: "max-w-7xl mx-auto px-6" }, inner = { className: "flex flex-col gap-12" }, contentContainer = { className: "max-w-4xl mx-auto" }, contentStack = { className: "flex flex-col gap-6" }, subheading = {
|
|
87
|
-
className: "text-sm font-semibold font-poppins text-primary uppercase tracking-wider",
|
|
88
|
-
}, heading = {
|
|
89
|
-
className: "text-3xl font-bold font-poppins text-foreground leading-tight",
|
|
90
|
-
}, content = {
|
|
91
|
-
className: "text-lg font-inter text-foreground leading-relaxed opacity-90 max-w-3xl",
|
|
92
|
-
}, statsSection = {
|
|
93
|
-
className: "bg-card p-8 rounded-xl shadow-lg mx-auto max-w-5xl w-full border border-border",
|
|
94
|
-
}, statsGrid = {
|
|
95
|
-
className: "grid grid-cols-2 md:grid-cols-4 gap-8 justify-items-center",
|
|
96
|
-
}, statItem = { className: "flex flex-col items-center gap-2" }, statNumber = {
|
|
97
|
-
className: "text-4xl font-bold font-poppins text-foreground leading-none",
|
|
98
|
-
}, statLabel = {
|
|
99
|
-
className: "text-sm font-medium font-inter text-foreground text-center opacity-80",
|
|
100
|
-
}, aboutTextAlign = "center", showStats = true, animateStats = false, ariaLabel = "About section", }) {
|
|
101
|
-
const textAlignClasses = {
|
|
102
|
-
left: "text-left",
|
|
103
|
-
right: "text-right",
|
|
104
|
-
center: "text-center",
|
|
105
|
-
};
|
|
106
|
-
const statsSectionRef = React.useRef(null);
|
|
107
|
-
const [shouldStartCount, setShouldStartCount] = React.useState(false);
|
|
108
|
-
React.useEffect(() => {
|
|
109
|
-
if (!animateStats)
|
|
110
|
-
return;
|
|
111
|
-
if (!statsSectionRef.current)
|
|
112
|
-
return;
|
|
113
|
-
const observer = new IntersectionObserver((entries) => {
|
|
114
|
-
for (const entry of entries) {
|
|
115
|
-
if (entry.isIntersecting) {
|
|
116
|
-
setShouldStartCount(true);
|
|
117
|
-
observer.disconnect();
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}, { threshold: 0.3 });
|
|
122
|
-
observer.observe(statsSectionRef.current);
|
|
123
|
-
return () => observer.disconnect();
|
|
124
|
-
}, [animateStats]);
|
|
125
|
-
return (_jsx("section", { className: cn(section.className, className), "aria-label": ariaLabel, children: _jsx("div", { className: cn(container.className), children: _jsxs("div", { className: cn(inner.className), children: [_jsx("div", { className: cn(contentContainer.className, textAlignClasses[aboutTextAlign]), children: _jsxs("div", { className: cn(contentStack.className), children: [aboutSubheadingText && (_jsx("div", { className: cn(subheading.className), children: aboutSubheadingText })), _jsx("h2", { className: cn(heading.className), children: aboutHeadingText }), _jsx("p", { className: cn(content.className), children: aboutContentText })] }) }), showStats && (aboutStats === null || aboutStats === void 0 ? void 0 : aboutStats.length) ? (_jsx("div", { ref: statsSectionRef, className: cn(statsSection.className), children: _jsx("div", { className: cn(statsGrid.className), children: aboutStats.map((s, i) => {
|
|
126
|
-
var _a;
|
|
127
|
-
return (_jsxs("div", { className: cn(statItem.className), children: [_jsxs("div", { className: cn(statNumber.className), children: [animateStats && Number.isFinite(Number(s.value)) ? (_jsx(AnimatedCount, { end: Number(s.value), shouldStart: shouldStartCount })) : (s.value), s.suffix] }), _jsx("div", { className: cn(statLabel.className), children: s.label })] }, `${(_a = s.label) !== null && _a !== void 0 ? _a : "stat"}-${i}`));
|
|
128
|
-
}) }) })) : null] }) }) }));
|
|
129
|
-
}
|
package/dist/components/CTA.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import Link from "next/link";
|
|
4
|
-
import { Button } from "@nextworks/blocks-core";
|
|
5
|
-
import { cn } from "@nextworks/blocks-core";
|
|
6
|
-
/**
|
|
7
|
-
* Call-to-Action section with a heading, optional subheading/description,
|
|
8
|
-
* and up to two actions (primary and secondary).
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* - Styling: exposes slot-style className overrides (section, container,
|
|
12
|
-
* contentWrapper, headingText, subheadingText, descriptionText, actionsWrapper,
|
|
13
|
-
* ctaButtonStyle, secondaryButtonStyle). Consumer classes are merged after
|
|
14
|
-
* defaults via cn().
|
|
15
|
-
* - Accessibility: rendered as a semantic <section> with aria-label. The role
|
|
16
|
-
* defaults to "region" but can be customized with the role prop.
|
|
17
|
-
* - Motion: subtle hover lift effects on buttons are included by default.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* <CTA
|
|
21
|
-
* headingText={{ text: "Join The Launch Today!" }}
|
|
22
|
-
* descriptionText={{ text: "Start your free trial in minutes." }}
|
|
23
|
-
* ctaButton={{ label: "Sign Up", href: "#contact" }}
|
|
24
|
-
* secondaryButton={{ label: "Learn More", href: "#features" }}
|
|
25
|
-
* />
|
|
26
|
-
*/
|
|
27
|
-
export function CTA({ id = "cta", className, section = {
|
|
28
|
-
className: "bg-background text-foreground",
|
|
29
|
-
}, container = {
|
|
30
|
-
className: "mx-auto flex min-h-[42vh] w-full max-w-6xl flex-col items-center justify-center overflow-hidden px-4 pb-7",
|
|
31
|
-
}, contentWrapper = {
|
|
32
|
-
className: "flex w-full flex-col items-center text-center",
|
|
33
|
-
}, headingText = {
|
|
34
|
-
text: "Join The Launch Today!",
|
|
35
|
-
className: "text-3xl font-bold leading-[1.1] text-primary sm:text-4xl md:text-5xl text-[var(--heading-fg)]",
|
|
36
|
-
}, subheadingText = {
|
|
37
|
-
text: "",
|
|
38
|
-
className: "mt-2 text-lg font-medium text-muted-foreground sm:text-xl text-[var(--subheading-fg)]",
|
|
39
|
-
}, descriptionText = {
|
|
40
|
-
text: "",
|
|
41
|
-
className: "mt-3 max-w-2xl text-base text-foreground/80 sm:text-lg text-[var(--description-fg)]",
|
|
42
|
-
}, actionsWrapper = {
|
|
43
|
-
className: "mt-6 flex flex-col items-center gap-3 sm:flex-row",
|
|
44
|
-
}, ctaButton = { label: "Sign Up Now", href: "#contact" }, ctaButtonStyle = {
|
|
45
|
-
variant: "default",
|
|
46
|
-
size: "default",
|
|
47
|
-
className: "shadow-lg transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]",
|
|
48
|
-
}, ctaButtonWrapper = { className: "" }, secondaryButton = null, secondaryButtonStyle = {
|
|
49
|
-
variant: "outline",
|
|
50
|
-
size: "default",
|
|
51
|
-
className: "transition-transform duration-200 hover:-translate-y-0.5 border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]",
|
|
52
|
-
}, secondaryButtonWrapper = { className: "" }, spacing = { topMargin: "mt-0 sm:mt-12" },
|
|
53
|
-
// spacing = { topMargin: "mt-[17vh]" },
|
|
54
|
-
ariaLabel = "Call to action section", role = "region", }) {
|
|
55
|
-
// default class for actions wrapper (keeps a gap and responsive row layout)
|
|
56
|
-
const actionsWrapperDefault = "mt-6 flex flex-col items-center gap-3 sm:flex-row";
|
|
57
|
-
return (_jsx("section", { id: id, role: role, "aria-label": ariaLabel, className: cn("w-full", section.className, className), children: _jsx("div", { className: cn(container.className), children: _jsxs("div", { className: cn(contentWrapper.className), children: [(headingText === null || headingText === void 0 ? void 0 : headingText.text) ? (_jsx("h2", { className: cn("text-center", spacing === null || spacing === void 0 ? void 0 : spacing.topMargin, headingText.className), children: headingText.text })) : null, (subheadingText === null || subheadingText === void 0 ? void 0 : subheadingText.text) ? (_jsx("p", { className: cn(subheadingText.className), children: subheadingText.text })) : null, (descriptionText === null || descriptionText === void 0 ? void 0 : descriptionText.text) ? (_jsx("p", { className: cn(descriptionText.className), children: descriptionText.text })) : null, _jsxs("div", { className: cn(actionsWrapperDefault, actionsWrapper.className), children: [ctaButton && (_jsx(Button, { asChild: true, unstyled: ctaButtonStyle.unstyled, variant: ctaButtonStyle.variant, size: ctaButtonStyle.size, className: cn(ctaButtonWrapper.className, ctaButtonStyle.className), style: ctaButtonStyle.style, children: _jsx(Link, { href: ctaButton.href, "aria-label": ctaButton.label, children: ctaButton.label }) })), secondaryButton && (_jsx(Button, { asChild: true, unstyled: secondaryButtonStyle.unstyled, variant: secondaryButtonStyle.variant, size: secondaryButtonStyle.size, className: cn(secondaryButtonWrapper.className, secondaryButtonStyle.className), style: secondaryButtonStyle.style, children: _jsx(Link, { href: secondaryButton.href, "aria-label": secondaryButton.label, children: secondaryButton.label }) }))] })] }) }) }));
|
|
58
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { cn } from "@nextworks/blocks-core";
|
|
4
|
-
import { Button, Input, Textarea, Label } from "@nextworks/blocks-core";
|
|
5
|
-
const defaultFormData = [
|
|
6
|
-
{
|
|
7
|
-
id: "name",
|
|
8
|
-
label: "Your Full Name",
|
|
9
|
-
placeholder: "John Doe",
|
|
10
|
-
required: true,
|
|
11
|
-
type: "text",
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
id: "email",
|
|
15
|
-
label: "Email Address",
|
|
16
|
-
placeholder: "you@example.com",
|
|
17
|
-
required: true,
|
|
18
|
-
type: "email",
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
id: "phone",
|
|
22
|
-
label: "Phone Number",
|
|
23
|
-
placeholder: "Enter your phone number",
|
|
24
|
-
required: false,
|
|
25
|
-
type: "tel",
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
id: "company",
|
|
29
|
-
label: "Company",
|
|
30
|
-
placeholder: "Enter your company name",
|
|
31
|
-
required: false,
|
|
32
|
-
type: "text",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: "message",
|
|
36
|
-
label: "Message",
|
|
37
|
-
placeholder: "Tell us about your project...",
|
|
38
|
-
required: true,
|
|
39
|
-
type: "textarea",
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
/**
|
|
43
|
-
* Contact section with a configurable form and submit action.
|
|
44
|
-
*
|
|
45
|
-
* @remarks
|
|
46
|
-
* - Styling: slot-style className overrides are merged via cn().
|
|
47
|
-
* - Behavior: onSubmit is invoked with the form event after calling
|
|
48
|
-
* preventDefault().
|
|
49
|
-
* - Motion: enableMotion toggles the button hover lift/transition.
|
|
50
|
-
* - Accessibility: Uses a semantic <section> with aria-label.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* <Contact onSubmit={(e) => { // send to your API }} />
|
|
54
|
-
*/
|
|
55
|
-
export function Contact({ fields = defaultFormData, contactHeaderText = "Ready to Grow Your Business?", contactSubHeaderText = "Schedule a free consultation with our experts.", id = "contact", className, section = { className: "py-16 px-4 bg-primary" }, container = { className: "mx-auto max-w-4xl" }, headerWrapper = { className: "mb-8 text-center" }, headerText = {
|
|
56
|
-
className: "text-2xl font-bold font-poppins text-primary-foreground",
|
|
57
|
-
}, subheaderText = {
|
|
58
|
-
className: "mt-2 text-lg font-inter text-primary-foreground px-4 md:px-14",
|
|
59
|
-
}, form = {
|
|
60
|
-
className: "bg-card p-8 rounded-lg shadow-md border border-border bg-[var(--card-bg)] text-[var(--card-fg)] border-[var(--card-border)] shadow-[var(--card-shadow)]",
|
|
61
|
-
}, fieldsWrapper = { className: "space-y-4" }, field = { className: "space-y-2" }, label = {
|
|
62
|
-
className: "text-card-foreground text-sm font-medium font-poppins block text-[var(--label-fg)]",
|
|
63
|
-
}, input = {
|
|
64
|
-
className: "w-full p-3 border border-input rounded-md bg-background text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent font-inter border-[var(--input-border)] bg-[var(--input-bg)] text-[var(--input-fg)] placeholder:text-[var(--input-placeholder)] focus-visible:ring-[var(--input-focus-ring)] focus-visible:ring-offset-[var(--input-ring-offset)]",
|
|
65
|
-
}, textarea = {
|
|
66
|
-
className: "w-full p-3 border border-input rounded-md bg-background text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent resize-vertical min-h-[120px] font-inter border-[var(--input-border)] bg-[var(--input-bg)] text-[var(--input-fg)] placeholder:text-[var(--input-placeholder)] focus-visible:ring-[var(--input-focus-ring)] focus-visible:ring-offset-[var(--input-ring-offset)]",
|
|
67
|
-
}, submitButtonWrapper = { className: "pt-2" }, submitButtonStyle = {
|
|
68
|
-
variant: "default",
|
|
69
|
-
size: "lg",
|
|
70
|
-
className: "w-full shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5 border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]",
|
|
71
|
-
}, submitButtonText = "Schedule Free Consultation", onSubmit, ariaLabel = "Contact section", enableMotion = true, }) {
|
|
72
|
-
const handleSubmit = (e) => {
|
|
73
|
-
e.preventDefault();
|
|
74
|
-
onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(e);
|
|
75
|
-
};
|
|
76
|
-
return (_jsx("section", { id: id, className: cn("w-full", section.className, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn(container.className), children: [_jsxs("div", { className: cn(headerWrapper.className), children: [contactHeaderText && (_jsx("h2", { className: cn(headerText.className), children: contactHeaderText })), contactSubHeaderText && (_jsx("p", { className: cn(subheaderText.className), children: contactSubHeaderText }))] }), _jsx("form", { onSubmit: handleSubmit, className: cn(form.className), children: _jsxs("div", { className: cn(fieldsWrapper.className), children: [fields.map((f) => {
|
|
77
|
-
var _a;
|
|
78
|
-
const isTextarea = f.type === "textarea";
|
|
79
|
-
return (_jsxs("div", { className: cn(field.className), children: [_jsxs(Label, { htmlFor: f.id, className: cn(label.className), children: [f.label, f.required && (_jsx("span", { className: "text-destructive ml-1", children: "*" }))] }), isTextarea ? (_jsx(Textarea, { id: f.id, name: f.id, placeholder: f.placeholder, required: f.required, rows: 4, className: cn(textarea.className) })) : (_jsx(Input, { type: (_a = f.type) !== null && _a !== void 0 ? _a : "text", id: f.id, name: f.id, placeholder: f.placeholder, required: f.required, className: cn(input.className) }))] }, f.id));
|
|
80
|
-
}), _jsx("div", { className: cn(submitButtonWrapper.className), children: _jsx(Button, { type: "submit", unstyled: submitButtonStyle.unstyled, variant: submitButtonStyle.variant, size: submitButtonStyle.size, className: cn(submitButtonStyle.className, !enableMotion &&
|
|
81
|
-
"transition-none hover:!translate-y-0 hover:shadow-none"), style: submitButtonStyle.style, children: submitButtonText }) })] }) })] }) }));
|
|
82
|
-
}
|
package/dist/components/FAQ.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo, useState } from "react";
|
|
4
|
-
import { cn } from "@nextworks/blocks-core";
|
|
5
|
-
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
6
|
-
// const defaultFaqData: FAQS[] = [
|
|
7
|
-
// {
|
|
8
|
-
// question: "What does IntelliOpAI do?",
|
|
9
|
-
// answer: "Automates ops with real-time insights.",
|
|
10
|
-
// },
|
|
11
|
-
// {
|
|
12
|
-
// question: "Do I need coding skills?",
|
|
13
|
-
// answer: "No, it's designed for ease of use.",
|
|
14
|
-
// },
|
|
15
|
-
// ];
|
|
16
|
-
const defaultFaqData = [
|
|
17
|
-
{
|
|
18
|
-
question: "What does IntelliOpAI do?",
|
|
19
|
-
answer: "Automates ops with real-time insights.",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
question: "How secure is my data?",
|
|
23
|
-
answer: "We use industry-standard encryption and strict access controls.",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
question: "Can I integrate with other tools?",
|
|
27
|
-
answer: "Yes — supports APIs and popular integrations like Slack, GitHub, and Jira.",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
question: "How do I get support?",
|
|
31
|
-
answer: "Contact our support team via in-app chat or the help center for assistance.",
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
/**
|
|
35
|
-
* Expandable FAQ section with accessible toggles and optional icons.
|
|
36
|
-
*
|
|
37
|
-
* @remarks
|
|
38
|
-
* - Supports multiple or single open item behavior via allowMultipleOpen.
|
|
39
|
-
* - Uses button with aria-expanded and a region with aria-labelledby.
|
|
40
|
-
* - Motion can be disabled via enableMotion for reduced animation.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* <FAQ faqData={[{ question: 'What is X?', answer: 'Y' }]} />
|
|
44
|
-
*/
|
|
45
|
-
export function FAQ({ faqSectionHeaderText = "Frequently Asked Questions", faqData = defaultFaqData, sectionId = "faq", className, allowMultipleOpen = true, defaultOpenIndices = [], openIcon, closedIcon, ariaLabel = "Frequently asked questions section", section = { className: "py-10 px-5 bg-muted text-foreground" }, container = { className: "mx-auto max-w-7xl" }, heading = {
|
|
46
|
-
className: "mb-6 text-center text-2xl font-bold text-foreground",
|
|
47
|
-
}, grid = { className: "grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6" }, item = { className: "mb-4" }, questionButton = {
|
|
48
|
-
className: "shadow-md hover:shadow-lg border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)] bg-[var(--faq-btn-bg,var(--btn-bg))] text-[var(--faq-btn-fg,var(--btn-fg))] hover:bg-[var(--faq-btn-hover-bg,var(--btn-hover-bg))] hover:text-[var(--faq-btn-hover-fg,var(--btn-hover-fg))]",
|
|
49
|
-
}, questionText = { className: "" }, chevronIcon = { className: "transition-transform duration-200" }, answer = {
|
|
50
|
-
className: "bg-[var(--faq-answer-bg,var(--card-bg))] text-[var(--faq-answer-fg,var(--card-fg))] border-[var(--card-border)]",
|
|
51
|
-
}, answerText = { className: "leading-relaxed" }, enableMotion = true, }) {
|
|
52
|
-
const [openSet, setOpenSet] = useState(() => new Set(defaultOpenIndices));
|
|
53
|
-
const idPrefix = useMemo(() => sectionId || "faq", [sectionId]);
|
|
54
|
-
const onToggle = (idx) => {
|
|
55
|
-
setOpenSet((prev) => {
|
|
56
|
-
const next = new Set(prev);
|
|
57
|
-
if (next.has(idx))
|
|
58
|
-
next.delete(idx);
|
|
59
|
-
else {
|
|
60
|
-
if (!allowMultipleOpen)
|
|
61
|
-
next.clear();
|
|
62
|
-
next.add(idx);
|
|
63
|
-
}
|
|
64
|
-
return next;
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
|
-
return (_jsx("section", { id: sectionId, className: cn(section.className, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn(container.className), children: [faqSectionHeaderText && (_jsx("h2", { className: cn(heading.className), children: faqSectionHeaderText })), _jsx("div", { className: cn(grid.className), children: faqData.map((faq, index) => {
|
|
68
|
-
const transitionCls = enableMotion
|
|
69
|
-
? "transition-all duration-300 ease-in-out"
|
|
70
|
-
: "transition-none";
|
|
71
|
-
const isOpen = openSet.has(index);
|
|
72
|
-
return (_jsxs("div", { className: cn("w-full", item.className), children: [_jsxs("button", { id: `${idPrefix}-trigger-${index}`, "aria-controls": `${idPrefix}-panel-${index}`, "aria-expanded": isOpen, onClick: () => onToggle(index), className: cn("flex w-full items-center justify-between rounded-md p-4 text-left focus:outline-none",
|
|
73
|
-
// preset-first ring/border
|
|
74
|
-
"border-[var(--btn-border)] focus-visible:ring-2 focus-visible:ring-[var(--btn-ring)] focus-visible:ring-offset-2", questionButton.className), children: [_jsx("span", { className: cn("flex-1 font-medium select-none", questionText.className), children: faq.question }), _jsx("span", { className: cn("ml-3 flex-shrink-0", chevronIcon.className), children: isOpen
|
|
75
|
-
? (openIcon !== null && openIcon !== void 0 ? openIcon : _jsx(ChevronUp, { className: "h-5 w-5" }))
|
|
76
|
-
: (closedIcon !== null && closedIcon !== void 0 ? closedIcon : _jsx(ChevronDown, { className: "h-5 w-5" })) })] }), _jsx("div", { id: `${idPrefix}-panel-${index}`, role: "region", "aria-labelledby": `${idPrefix}-trigger-${index}`, className: cn("border-border overflow-hidden rounded-md border", isOpen ? "max-h-96 opacity-100" : "max-h-0 opacity-0", transitionCls, answer.className), children: _jsx("div", { className: cn("p-4", answerText.className), children: faq.answer }) })] }, `${idPrefix}-item-${index}`));
|
|
77
|
-
}) })] }) }));
|
|
78
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { motion } from "motion/react";
|
|
4
|
-
import { cn } from "@nextworks/blocks-core";
|
|
5
|
-
import { FeatureCard } from "@nextworks/blocks-core";
|
|
6
|
-
const defaultFeaturesData = [
|
|
7
|
-
{
|
|
8
|
-
imageSrc: "/feature_1.png",
|
|
9
|
-
imageAlt: "Advanced Analytics Dashboard",
|
|
10
|
-
headingText: "Advanced Analytics",
|
|
11
|
-
subheadingText: "Get deep insights into your business performance with our comprehensive analytics dashboard that tracks key metrics and provides actionable recommendations.",
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
imageSrc: "/feature_2.png",
|
|
15
|
-
imageAlt: "Real-time Collaboration Tools",
|
|
16
|
-
headingText: "Real-time Collaboration",
|
|
17
|
-
subheadingText: "Work seamlessly with your team using our real-time collaboration tools that keep everyone in sync and boost productivity across all projects.",
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
imageSrc: "/feature_3.png",
|
|
21
|
-
imageAlt: "Secure Data Management",
|
|
22
|
-
headingText: "Secure Data Management",
|
|
23
|
-
subheadingText: "Protect your sensitive information with enterprise-grade security features including encryption, access controls, and compliance monitoring.",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
imageSrc: "/feature_4.png",
|
|
27
|
-
imageAlt: "Mobile-First Design",
|
|
28
|
-
headingText: "Mobile-First Design",
|
|
29
|
-
subheadingText: "Access your data and manage your workflow from anywhere with our responsive, mobile-optimized interface that works perfectly on all devices.",
|
|
30
|
-
},
|
|
31
|
-
];
|
|
32
|
-
/**
|
|
33
|
-
* Responsive Features section that renders a heading, optional subheading,
|
|
34
|
-
* and a grid of FeatureCard items with configurable entrance animations.
|
|
35
|
-
*
|
|
36
|
-
* @remarks
|
|
37
|
-
* - Styling: slot-style className overrides are merged after defaults via cn().
|
|
38
|
-
* - Motion: Controlled by enableMotion and motionConfig; animations are reduced
|
|
39
|
-
* or disabled when users prefer reduced motion.
|
|
40
|
-
* - Accessibility: Uses a semantic <section> with an aria-label.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* <Features
|
|
44
|
-
* sectionHeading="Key Features"
|
|
45
|
-
* featuresData={[{ imageSrc: "/a.png", imageAlt: "", headingText: "Fast", subheadingText: "Blazing" }]}
|
|
46
|
-
* />
|
|
47
|
-
*/
|
|
48
|
-
export function Features({ id = "features", sectionHeading = "Key Features", sectionSubheading = "Discover what makes our platform unique and powerful", featuresData = defaultFeaturesData, className, section = { className: "py-16 md:py-20 lg:py-24 bg-background" }, container = { className: "max-w-7xl mx-auto px-4 md:px-6 lg:px-8" }, header = { className: "text-center mb-12 md:mb-16" }, heading = {
|
|
49
|
-
className: "text-3xl md:text-4xl lg:text-5xl font-bold text-foreground mb-4",
|
|
50
|
-
}, subheading = {
|
|
51
|
-
className: "text-lg md:text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed",
|
|
52
|
-
}, grid = {
|
|
53
|
-
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-4 gap-6 md:gap-8",
|
|
54
|
-
}, cardWrapper = {
|
|
55
|
-
className: "motion-reduce:transform-none motion-reduce:transition-none",
|
|
56
|
-
}, card = {
|
|
57
|
-
className: "h-full bg-card border border-border rounded-lg shadow-md transition-all duration-200 hover:-translate-y-1 hover:shadow-lg overflow-hidden motion-reduce:transition-none motion-reduce:transform-none",
|
|
58
|
-
}, image = {
|
|
59
|
-
className: "w-full h-48 md:h-56 object-cover transition-none hover:!scale-100 group-hover:!scale-100 [transform:none]",
|
|
60
|
-
}, cardHeading = {
|
|
61
|
-
className: "text-xl md:text-2xl font-semibold text-card-foreground mb-3 leading-tight",
|
|
62
|
-
}, cardSubheading = {
|
|
63
|
-
className: "text-sm md:text-base text-muted-foreground leading-relaxed",
|
|
64
|
-
}, enableMotion = true, motionConfig = {
|
|
65
|
-
initial: { opacity: 0, y: 12 },
|
|
66
|
-
whileInView: { opacity: 1, y: 0 },
|
|
67
|
-
viewport: { once: true, amount: 0.2 },
|
|
68
|
-
transition: {
|
|
69
|
-
type: "tween",
|
|
70
|
-
stiffness: 0,
|
|
71
|
-
damping: 50,
|
|
72
|
-
mass: 1,
|
|
73
|
-
delay: 0.15,
|
|
74
|
-
},
|
|
75
|
-
}, ariaLabel = "Features section", }) {
|
|
76
|
-
return (_jsx("section", { id: id, className: cn(section.className, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn(container.className), children: [_jsxs("div", { className: cn(header.className), children: [_jsx("h2", { className: cn(heading.className), children: sectionHeading }), sectionSubheading && (_jsx("p", { className: cn(subheading.className), children: sectionSubheading }))] }), _jsx("div", { className: cn(grid.className), children: featuresData.map((feature, index) => {
|
|
77
|
-
var _a, _b, _c;
|
|
78
|
-
const mConfig = enableMotion
|
|
79
|
-
? motionConfig
|
|
80
|
-
: {
|
|
81
|
-
initial: { opacity: 1, y: 0 },
|
|
82
|
-
whileInView: { opacity: 1, y: 0 },
|
|
83
|
-
viewport: { once: true, amount: 0 },
|
|
84
|
-
transition: {
|
|
85
|
-
type: "tween",
|
|
86
|
-
duration: 0,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
// Ensure we always spread a defined object into transition
|
|
90
|
-
const baseTransition = ((_a = mConfig.transition) !== null && _a !== void 0 ? _a : {
|
|
91
|
-
type: "tween",
|
|
92
|
-
duration: 0,
|
|
93
|
-
});
|
|
94
|
-
const noMotionCard = "transition-none hover:!translate-y-0 hover:shadow-none motion-reduce:transition-none motion-reduce:transform-none";
|
|
95
|
-
const noMotionImage = "transition-none hover:!scale-100 transform-none motion-reduce:transform-none group-hover:!scale-100";
|
|
96
|
-
return (_jsx(motion.div, { initial: mConfig.initial, whileInView: mConfig.whileInView, viewport: mConfig.viewport, transition: Object.assign(Object.assign({}, baseTransition), {
|
|
97
|
-
// Stagger based on index while preserving provided delay if any
|
|
98
|
-
delay: ((_c = (_b = mConfig.transition) === null || _b === void 0 ? void 0 : _b.delay) !== null && _c !== void 0 ? _c : 0.15) +
|
|
99
|
-
index * (enableMotion ? 0.06 : 0) }), className: cn(cardWrapper.className), children: _jsx(FeatureCard, { cardImageSrc: feature.imageSrc, cardImageAlt: feature.imageAlt, cardHeadingText: feature.headingText, cardSubheadingText: feature.subheadingText, card: {
|
|
100
|
-
className: cn(card.className, !enableMotion && noMotionCard),
|
|
101
|
-
}, image: {
|
|
102
|
-
className: cn(image.className, !enableMotion && noMotionImage),
|
|
103
|
-
},
|
|
104
|
-
// image={{
|
|
105
|
-
// className: cn(image.className),
|
|
106
|
-
// }}
|
|
107
|
-
heading: { className: cn(cardHeading.className) }, subheading: { className: cn(cardSubheading.className) }, className: cn("h-full") }) }, index));
|
|
108
|
-
}) })] }) }));
|
|
109
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import Link from "next/link";
|
|
4
|
-
import { cn } from "@nextworks/blocks-core";
|
|
5
|
-
import { Facebook, Twitter, Instagram, Linkedin } from "lucide-react";
|
|
6
|
-
/**
|
|
7
|
-
* Default navigation link groups with common footer sections
|
|
8
|
-
*/
|
|
9
|
-
const defaultNavLinks = [
|
|
10
|
-
{
|
|
11
|
-
heading: "Product",
|
|
12
|
-
links: [
|
|
13
|
-
{ name: "Features", href: "#features" },
|
|
14
|
-
{ name: "Pricing", href: "#pricing" },
|
|
15
|
-
{ name: "Documentation", href: "#documentation" },
|
|
16
|
-
{ name: "FAQ", href: "#faq" },
|
|
17
|
-
],
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
heading: "Company",
|
|
21
|
-
links: [
|
|
22
|
-
{ name: "About", href: "#about" },
|
|
23
|
-
{ name: "Careers", href: "#careers" },
|
|
24
|
-
{ name: "Blog", href: "#blog" },
|
|
25
|
-
{ name: "Contact", href: "#contact" },
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
heading: "Resources",
|
|
30
|
-
links: [
|
|
31
|
-
{ name: "Help Center", href: "#help" },
|
|
32
|
-
{ name: "Terms of Service", href: "#terms" },
|
|
33
|
-
{ name: "Privacy Policy", href: "#privacy" },
|
|
34
|
-
{ name: "Status", href: "#status" },
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
/**
|
|
39
|
-
* Default social media links shown in the footer
|
|
40
|
-
*/
|
|
41
|
-
const defaultSocialLinks = [
|
|
42
|
-
{
|
|
43
|
-
name: "Facebook",
|
|
44
|
-
icon: Facebook,
|
|
45
|
-
url: "https://facebook.com",
|
|
46
|
-
external: true,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: "Twitter",
|
|
50
|
-
icon: Twitter,
|
|
51
|
-
url: "https://twitter.com",
|
|
52
|
-
external: true,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "Instagram",
|
|
56
|
-
icon: Instagram,
|
|
57
|
-
url: "https://instagram.com",
|
|
58
|
-
external: true,
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: "LinkedIn",
|
|
62
|
-
icon: Linkedin,
|
|
63
|
-
url: "https://linkedin.com",
|
|
64
|
-
external: true,
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
/**
|
|
68
|
-
* Site footer with brand, grouped navigation links, social icons, and copyright.
|
|
69
|
-
*
|
|
70
|
-
* @remarks
|
|
71
|
-
* - Styling: slot-style className overrides are merged after defaults via cn().
|
|
72
|
-
* - Accessibility: renders a semantic <footer> with aria-label and clear link
|
|
73
|
-
* names; external links open in a new tab with rel security attributes.
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* <Footer footerBrandName="Acme" />
|
|
77
|
-
*/
|
|
78
|
-
export function Footer({ id, footerBrandName = "Brand Name", brandNode, brandHref, footerNavLinks = defaultNavLinks, footerSocialLinks = defaultSocialLinks, className, section = {
|
|
79
|
-
className: "w-full bg-muted text-foreground bg-[var(--footer-bg)] text-[var(--footer-fg)]",
|
|
80
|
-
}, container = { className: "max-w-7xl mx-auto px-6" }, brand = { className: "text-lg font-bold font-poppins text-foreground" }, brandWrapper = {
|
|
81
|
-
className: "flex flex-col items-center lg:items-start lg:pr-8",
|
|
82
|
-
}, navSection = {
|
|
83
|
-
className: "flex flex-col lg:flex-row items-start justify-center gap-8 lg:gap-12 pt-6.5 pb-8",
|
|
84
|
-
}, navGroup = {
|
|
85
|
-
className: "flex flex-col items-center lg:items-start text-center lg:text-left pt-1.5",
|
|
86
|
-
}, navHeading = {
|
|
87
|
-
className: "font-bold font-poppins text-foreground mb-3 text-sm uppercase tracking-wider text-[var(--footer-heading-fg)]",
|
|
88
|
-
}, navLink = {
|
|
89
|
-
className: "text-muted-foreground hover:text-primary transition-colors duration-200 text-sm mb-2 block font-inter text-[var(--footer-link-fg)] hover:text-[var(--footer-link-hover-fg)]",
|
|
90
|
-
}, linksList = { className: "space-y-2" }, socialSection = { className: "flex items-center justify-center gap-4 py-4" }, socialLink = {
|
|
91
|
-
className: "text-muted-foreground hover:text-primary transition-colors duration-200 p-2 rounded-md hover:bg-accent text-[var(--footer-link-fg)] hover:text-[var(--footer-link-hover-fg)] hover:bg-[var(--footer-link-hover-bg)]",
|
|
92
|
-
}, socialIcon = { className: "h-5 w-5" }, copyright = {
|
|
93
|
-
className: "text-center text-xs text-muted-foreground py-4 border-t border-border font-inter text-[var(--footer-muted-fg)] border-[var(--footer-border)]",
|
|
94
|
-
}, copyrightYear, copyrightOverride, ariaLabel = "Footer section", }) {
|
|
95
|
-
const year = copyrightYear !== null && copyrightYear !== void 0 ? copyrightYear : new Date().getFullYear();
|
|
96
|
-
return (_jsx("footer", { id: id, className: cn("w-full", section.className, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn(container.className), children: [_jsxs("div", { className: cn(navSection.className), children: [_jsxs("div", { className: cn(brandWrapper.className), children: [brandNode, footerBrandName &&
|
|
97
|
-
(brandHref ? (_jsx(Link, { href: brandHref, className: cn(brand.className), "aria-label": footerBrandName, children: footerBrandName })) : (_jsx("h3", { className: cn(brand.className), children: footerBrandName })))] }), footerNavLinks.map((group) => (_jsxs("div", { className: cn(navGroup.className), children: [_jsx("h3", { className: cn(navHeading.className), children: group.heading }), _jsx("div", { className: cn(linksList.className), children: group.links.map((link) => (_jsx(Link, { href: link.href, target: link.external ? "_blank" : undefined, rel: link.external ? "noopener noreferrer" : undefined, className: cn(navLink.className), children: link.name }, link.name))) })] }, group.heading)))] }), _jsx("div", { className: cn(socialSection.className), children: footerSocialLinks.map((social) => {
|
|
98
|
-
const IconComponent = social.icon;
|
|
99
|
-
return (_jsx(Link, { href: social.url, target: social.external ? "_blank" : undefined, rel: social.external ? "noopener noreferrer" : undefined, "aria-label": social.label || social.name, className: cn(socialLink.className), children: _jsx(IconComponent, { className: cn(socialIcon.className) }) }, social.name));
|
|
100
|
-
}) }), _jsx("div", { className: cn(copyright.className), children: copyrightOverride !== null && copyrightOverride !== void 0 ? copyrightOverride : (_jsxs(_Fragment, { children: ["\u00A9 ", year, " ", footerBrandName, ". All rights reserved."] })) })] }) }));
|
|
101
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import Link from "next/link";
|
|
4
|
-
import { motion } from "motion/react";
|
|
5
|
-
import { Button } from "@nextworks/blocks-core";
|
|
6
|
-
import { cn } from "@nextworks/blocks-core";
|
|
7
|
-
const defaultChildTransition = {
|
|
8
|
-
type: "tween",
|
|
9
|
-
duration: 0.5,
|
|
10
|
-
ease: [0.22, 1, 0.36, 1], // smooth easeOut
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Motion-first hero with heading/highlight, optional description and CTAs.
|
|
14
|
-
*
|
|
15
|
-
* @remarks
|
|
16
|
-
* - Styling: slot-style className overrides are merged after defaults via cn().
|
|
17
|
-
* - Motion: enableMotion toggles entrance transitions; motionOptions controls
|
|
18
|
-
* delays and viewport.
|
|
19
|
-
* - Accessibility: semantic <section> with aria-label.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* <HeroMotion
|
|
23
|
-
* heading="Supercharge growth with"
|
|
24
|
-
* highlight="AI-powered insights"
|
|
25
|
-
* primaryCta={{ label: 'Get Started', href: '#contact' }}
|
|
26
|
-
* />
|
|
27
|
-
*/
|
|
28
|
-
export function HeroMotion({ id, ariaLabel = "Hero section", className, heading = "Supercharge growth with", headingNode, highlight = "AI-powered insights", description = (_jsx(_Fragment, { children: "Real-time trends, accurate user signals, and smarter, data-driven decisions." })), primaryCta = { label: "Get Started" }, secondaryCta = { label: "See Demo" }, section = { className: "bg-background relative overflow-hidden" }, container = { className: "mx-auto max-w-7xl px-6 py-24 sm:py-28 lg:py-32" }, content = { className: "mx-auto max-w-3xl text-center" }, headingText = {
|
|
29
|
-
className: "transform-gpu will-change-transform text-foreground text-4xl font-semibold tracking-tight text-balance sm:text-5xl md:text-6xl",
|
|
30
|
-
}, highlightText = {
|
|
31
|
-
className: "from-primary via-primary/80 to-primary/60 bg-gradient-to-r bg-clip-text text-transparent",
|
|
32
|
-
}, descriptionText = {
|
|
33
|
-
className: "transform-gpu will-change-transform text-muted-foreground mt-5 text-base text-pretty sm:text-lg",
|
|
34
|
-
}, actions = { className: "mt-8 flex items-center justify-center gap-3" }, primaryButtonStyle = { size: "lg", variant: "default", className: "" }, secondaryButtonStyle = { size: "lg", variant: "outline", className: "" }, enableMotion = true, motionOptions = {
|
|
35
|
-
viewport: { once: true, amount: 0.25 },
|
|
36
|
-
headingDelay: 0.5,
|
|
37
|
-
descriptionDelay: 0.58,
|
|
38
|
-
actionsDelay: 0.66,
|
|
39
|
-
transition: defaultChildTransition,
|
|
40
|
-
}, backgroundNode, }) {
|
|
41
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
42
|
-
const viewport = enableMotion
|
|
43
|
-
? {
|
|
44
|
-
once: (_b = (_a = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.viewport) === null || _a === void 0 ? void 0 : _a.once) !== null && _b !== void 0 ? _b : true,
|
|
45
|
-
amount: (_d = (_c = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.viewport) === null || _c === void 0 ? void 0 : _c.amount) !== null && _d !== void 0 ? _d : 0.25,
|
|
46
|
-
}
|
|
47
|
-
: { once: true, amount: 0 };
|
|
48
|
-
const transition = Object.assign(Object.assign({}, defaultChildTransition), ((_e = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.transition) !== null && _e !== void 0 ? _e : {}));
|
|
49
|
-
return (_jsxs("section", { id: id, "aria-label": ariaLabel, className: cn(section.className, className), children: [backgroundNode, _jsx("div", { className: cn(container.className), children: _jsxs(motion.div, { className: cn(content.className), children: [_jsx(motion.h1, { initial: enableMotion ? { opacity: 0, y: 12 } : { opacity: 1, y: 0 }, whileInView: { opacity: 1, y: 0 }, viewport: viewport, transition: enableMotion
|
|
50
|
-
? Object.assign(Object.assign({}, transition), { delay: (_f = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.headingDelay) !== null && _f !== void 0 ? _f : 0.5 }) : { type: "tween", duration: 0 }, className: cn(headingText.className), children: headingNode ? (headingNode) : (_jsxs(_Fragment, { children: [heading, highlight ? (_jsxs("span", { className: cn(highlightText.className), children: [" ", highlight] })) : null] })) }), description ? (_jsx(motion.p, { initial: enableMotion ? { opacity: 0, y: 10 } : { opacity: 1, y: 0 }, whileInView: { opacity: 1, y: 0 }, viewport: viewport, transition: enableMotion
|
|
51
|
-
? Object.assign(Object.assign({}, transition), { delay: (_g = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.descriptionDelay) !== null && _g !== void 0 ? _g : 0.58 }) : { type: "tween", duration: 0 }, className: cn(descriptionText.className), children: description })) : null, (primaryCta || secondaryCta) && (_jsxs(motion.div, { initial: enableMotion ? { opacity: 0, y: 10 } : { opacity: 1, y: 0 }, whileInView: { opacity: 1, y: 0 }, viewport: viewport, transition: enableMotion
|
|
52
|
-
? Object.assign(Object.assign({}, transition), { delay: (_h = motionOptions === null || motionOptions === void 0 ? void 0 : motionOptions.actionsDelay) !== null && _h !== void 0 ? _h : 0.66 }) : { type: "tween", duration: 0 }, className: cn(actions.className), children: [primaryCta &&
|
|
53
|
-
(primaryCta.href ? (_jsx(Button, { asChild: true, unstyled: primaryButtonStyle.unstyled, variant: primaryButtonStyle.variant, size: primaryButtonStyle.size, className: cn(primaryButtonStyle.className), style: primaryButtonStyle.style, children: _jsx(Link, { href: primaryCta.href, "aria-label": primaryCta.label, children: primaryCta.label }) })) : (_jsx(Button, { variant: primaryButtonStyle.variant, size: primaryButtonStyle.size, className: cn(primaryButtonStyle.className), unstyled: primaryButtonStyle.unstyled, style: primaryButtonStyle.style, "aria-label": primaryCta.label, children: primaryCta.label }))), secondaryCta &&
|
|
54
|
-
(secondaryCta.href ? (_jsx(Button, { asChild: true, unstyled: secondaryButtonStyle.unstyled, variant: secondaryButtonStyle.variant, size: secondaryButtonStyle.size, className: cn(secondaryButtonStyle.className), style: secondaryButtonStyle.style, children: _jsx(Link, { href: secondaryCta.href, "aria-label": secondaryCta.label, children: secondaryCta.label }) })) : (_jsx(Button, { variant: secondaryButtonStyle.variant, size: secondaryButtonStyle.size, className: cn(secondaryButtonStyle.className), unstyled: secondaryButtonStyle.unstyled, style: secondaryButtonStyle.style, "aria-label": secondaryCta.label, children: secondaryCta.label })))] }))] }) })] }));
|
|
55
|
-
}
|