@nextworks/blocks-sections 0.1.0-alpha.8 → 0.2.0-alpha.2
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 +16 -11
- package/dist/components/Features.d.ts +4 -2
- package/dist/components/Features.d.ts.map +1 -1
- package/dist/components/Features.jsx +2 -2
- package/dist/components/HeroMotion.d.ts +4 -2
- package/dist/components/HeroMotion.d.ts.map +1 -1
- 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 +113 -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 +109 -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 +8 -6
- 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/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
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import Image from "next/image";
|
|
4
|
-
import Link from "next/link";
|
|
5
|
-
import { Button } from "@nextworks/blocks-core";
|
|
6
|
-
import { cn } from "@nextworks/blocks-core";
|
|
7
|
-
/**
|
|
8
|
-
* Full-bleed image hero with color overlay, heading/subheading, and up to two CTAs.
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* - Styling: slot-style overrides for container, imageContainer, overlay, content, textContainer.
|
|
12
|
-
* - Motion: enableMotion applies hover-lift transitions to CTA buttons only.
|
|
13
|
-
* - Accessibility: uses semantic <section> with aria-label; background image is
|
|
14
|
-
* decorative with overlay and text content provided separately.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* <HeroOverlay
|
|
18
|
-
* image={{ src: "/hero.png", alt: "" }}
|
|
19
|
-
* heading="Welcome"
|
|
20
|
-
* subheading="Build faster with our blocks"
|
|
21
|
-
* cta1={{ label: "Get Started", href: "#getstarted" }}
|
|
22
|
-
* />
|
|
23
|
-
*/
|
|
24
|
-
export function HeroOverlay({ id, className,
|
|
25
|
-
// Deprecated flat image defaults (still supported)
|
|
26
|
-
imageSrc = "/hero.png", imageAlt = "Hero background image", imageObjectFit = "cover", imageObjectPosition = "center",
|
|
27
|
-
// New structured image (optional)
|
|
28
|
-
image,
|
|
29
|
-
// Keep string defaults; object form supported
|
|
30
|
-
heading = "Lorem ipsum dolor sit amet, consectetur", subheading = "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", overlayRGBA = "rgba(255, 255, 255, 0.8)", overlayDarkRGBA = "rgba(0, 0, 0, 0.8)",
|
|
31
|
-
// Deprecated CTA label/href (still supported)
|
|
32
|
-
ctaBtn1Label = "Get Started", ctaBtn1Href = "#getstarted", ctaBtn2Label, ctaBtn2Href,
|
|
33
|
-
// Layout containers
|
|
34
|
-
container = { className: "relative h-[440px] md:h-[500px] w-full" },
|
|
35
|
-
// container = { className: "relative h-[500px] md:h-[600px] w-full" },
|
|
36
|
-
section, imageContainer = { className: "absolute inset-0" }, overlay = { className: "absolute inset-0 z-10 pointer-events-none" }, content = {
|
|
37
|
-
className: "relative z-20 h-full w-full flex flex-col justify-start items-center pt-14 pb-8 px-8",
|
|
38
|
-
}, textContainer = { className: "max-w-4xl space-y-6 text-center" },
|
|
39
|
-
// Typography defaults (deprecated props still merged)
|
|
40
|
-
headingStyle = { className: "" }, subheadingStyle = { className: "" },
|
|
41
|
-
// CTA containers and variants
|
|
42
|
-
ctaContainer = {
|
|
43
|
-
className: "flex flex-col sm:flex-row gap-4 mt-6 justify-center items-center",
|
|
44
|
-
}, cta1, cta2, ariaLabel = "Hero section", enableMotion = true, }) {
|
|
45
|
-
var _a, _b, _c, _d, _e, _f;
|
|
46
|
-
// Merge new structured image with deprecated flat props
|
|
47
|
-
const effImage = {
|
|
48
|
-
src: (_a = image === null || image === void 0 ? void 0 : image.src) !== null && _a !== void 0 ? _a : imageSrc,
|
|
49
|
-
alt: (_b = image === null || image === void 0 ? void 0 : image.alt) !== null && _b !== void 0 ? _b : imageAlt,
|
|
50
|
-
objectFit: (_c = image === null || image === void 0 ? void 0 : image.objectFit) !== null && _c !== void 0 ? _c : imageObjectFit,
|
|
51
|
-
objectPosition: (_d = image === null || image === void 0 ? void 0 : image.objectPosition) !== null && _d !== void 0 ? _d : imageObjectPosition,
|
|
52
|
-
className: image === null || image === void 0 ? void 0 : image.className,
|
|
53
|
-
};
|
|
54
|
-
// Defaults and normalization like HeroSplit
|
|
55
|
-
const defaultHeading = {
|
|
56
|
-
text: "Lorem ipsum dolor sit amet, consectetur",
|
|
57
|
-
className: "text-4xl md:text-5xl font-bold text-center leading-tight text-foreground",
|
|
58
|
-
};
|
|
59
|
-
const defaultSubheading = {
|
|
60
|
-
text: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
|
|
61
|
-
className: "text-xl md:text-2xl text-center text-foreground leading-relaxed",
|
|
62
|
-
};
|
|
63
|
-
const normalizedHeading = typeof heading === "string"
|
|
64
|
-
? {
|
|
65
|
-
text: heading,
|
|
66
|
-
className: cn(defaultHeading.className, headingStyle === null || headingStyle === void 0 ? void 0 : headingStyle.className),
|
|
67
|
-
}
|
|
68
|
-
: {
|
|
69
|
-
text: (_e = heading === null || heading === void 0 ? void 0 : heading.text) !== null && _e !== void 0 ? _e : defaultHeading.text,
|
|
70
|
-
className: cn(defaultHeading.className, headingStyle === null || headingStyle === void 0 ? void 0 : headingStyle.className, heading === null || heading === void 0 ? void 0 : heading.className),
|
|
71
|
-
};
|
|
72
|
-
const normalizedSubheading = typeof subheading === "string"
|
|
73
|
-
? {
|
|
74
|
-
text: subheading,
|
|
75
|
-
className: cn(defaultSubheading.className, subheadingStyle === null || subheadingStyle === void 0 ? void 0 : subheadingStyle.className),
|
|
76
|
-
}
|
|
77
|
-
: {
|
|
78
|
-
text: (_f = subheading === null || subheading === void 0 ? void 0 : subheading.text) !== null && _f !== void 0 ? _f : defaultSubheading.text,
|
|
79
|
-
className: cn(defaultSubheading.className, subheadingStyle === null || subheadingStyle === void 0 ? void 0 : subheadingStyle.className, subheading === null || subheading === void 0 ? void 0 : subheading.className),
|
|
80
|
-
};
|
|
81
|
-
// Motion class for CTA buttons
|
|
82
|
-
const buttonLift = enableMotion
|
|
83
|
-
? "transition-all duration-200 hover:-translate-y-0.5"
|
|
84
|
-
: "transition-none hover:!translate-y-0";
|
|
85
|
-
// CTA defaults and normalization (merge, don't replace).
|
|
86
|
-
const defaultCta1 = {
|
|
87
|
-
label: ctaBtn1Label,
|
|
88
|
-
href: ctaBtn1Href,
|
|
89
|
-
variant: "default",
|
|
90
|
-
size: "lg",
|
|
91
|
-
className: "",
|
|
92
|
-
};
|
|
93
|
-
const defaultCta2 = {
|
|
94
|
-
label: ctaBtn2Label,
|
|
95
|
-
href: ctaBtn2Href,
|
|
96
|
-
variant: "outline",
|
|
97
|
-
size: "lg",
|
|
98
|
-
className: "",
|
|
99
|
-
};
|
|
100
|
-
const mergedCta1 = Object.assign(Object.assign(Object.assign({}, defaultCta1), (cta1 !== null && cta1 !== void 0 ? cta1 : {})), { className: cn(defaultCta1.className, cta1 === null || cta1 === void 0 ? void 0 : cta1.className, buttonLift) });
|
|
101
|
-
const mergedCta2 = cta2 || ctaBtn2Label || ctaBtn2Href
|
|
102
|
-
? Object.assign(Object.assign(Object.assign({}, defaultCta2), (cta2 !== null && cta2 !== void 0 ? cta2 : {})), { className: cn(defaultCta2.className, cta2 === null || cta2 === void 0 ? void 0 : cta2.className, buttonLift) }) : undefined;
|
|
103
|
-
// buttonLift defined above
|
|
104
|
-
// Merge alias section.className with container.className
|
|
105
|
-
const finalContainerClass = cn(container.className, section === null || section === void 0 ? void 0 : section.className);
|
|
106
|
-
const showCta2 = !!(mergedCta2 === null || mergedCta2 === void 0 ? void 0 : mergedCta2.label);
|
|
107
|
-
return (_jsxs("section", { id: id, className: cn(finalContainerClass, className), "aria-label": ariaLabel, children: [_jsx("div", { className: imageContainer.className, children: _jsx(Image, { src: effImage.src, alt: effImage.alt, fill: true, sizes: "100vw", quality: 75, priority: true, className: effImage.className, style: {
|
|
108
|
-
objectFit: effImage.objectFit,
|
|
109
|
-
objectPosition: effImage.objectPosition,
|
|
110
|
-
} }) }), _jsx("div", { className: overlay.className, style: { backgroundColor: overlayRGBA }, "aria-hidden": true }), _jsx("div", { className: cn(overlay.className, "hidden dark:block"), style: { backgroundColor: overlayDarkRGBA }, "aria-hidden": true }), _jsx("div", { className: content.className, children: _jsxs("div", { className: textContainer.className, children: [_jsx("h1", { className: normalizedHeading.className, children: normalizedHeading.text }), _jsx("p", { className: normalizedSubheading.className, children: normalizedSubheading.text }), _jsxs("div", { className: ctaContainer.className, children: [mergedCta1.label && (_jsx(Button, { asChild: true, variant: mergedCta1.variant, size: mergedCta1.size, className: mergedCta1.className, unstyled: mergedCta1.unstyled, style: mergedCta1.style, children: _jsx(Link, { href: mergedCta1.href || "#", "aria-label": mergedCta1.label, children: mergedCta1.label }) })), showCta2 && (_jsx(Button, { asChild: true, variant: mergedCta2.variant, size: mergedCta2.size, className: mergedCta2.className, unstyled: mergedCta2.unstyled, style: mergedCta2.style, children: _jsx(Link, { href: mergedCta2.href || "#", "aria-label": mergedCta2.label, children: mergedCta2.label }) }))] })] }) })] }));
|
|
111
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import Image from "next/image";
|
|
4
|
-
import Link from "next/link";
|
|
5
|
-
import { Button } from "@nextworks/blocks-core";
|
|
6
|
-
import { cn } from "@nextworks/blocks-core";
|
|
7
|
-
/**
|
|
8
|
-
* Split hero with text on one side and an image on the other.
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* - Text props accept string or object forms to easily override classes.
|
|
12
|
-
* - Full-bleed layout absolutely positions the image on larger screens.
|
|
13
|
-
* - Motion only affects the subtle hover lift on CTA buttons.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* <HeroSplit heading="Build faster" subheading="Launch confidently" />
|
|
17
|
-
*/
|
|
18
|
-
export function HeroSplit({ id, className, heading, subheading, section, cta1, cta2, image = {
|
|
19
|
-
src: "/placeholders/gallery/hero-pexels-broken-9945014.avif",
|
|
20
|
-
alt: "Hero image",
|
|
21
|
-
className: "object-contain",
|
|
22
|
-
}, imageContainer, textContainer = { className: "flex-1 p-5" }, buttonsContainer = { className: "flex flex-col md:flex-row gap-4 mt-6" }, textAlign = "center", fallback, ariaLabel = "Hero section", enableMotion = true, imageLayout = "full-bleed", }) {
|
|
23
|
-
var _a, _b;
|
|
24
|
-
const lgTextAlignClasses = {
|
|
25
|
-
left: "lg:text-left",
|
|
26
|
-
right: "lg:text-right",
|
|
27
|
-
center: "lg:text-center",
|
|
28
|
-
};
|
|
29
|
-
const lgItemsAlignClasses = {
|
|
30
|
-
left: "lg:items-start",
|
|
31
|
-
right: "lg:items-end",
|
|
32
|
-
center: "lg:items-center",
|
|
33
|
-
};
|
|
34
|
-
const lgJustifyAlignClasses = {
|
|
35
|
-
left: "lg:justify-start",
|
|
36
|
-
right: "lg:justify-end",
|
|
37
|
-
center: "lg:justify-center",
|
|
38
|
-
};
|
|
39
|
-
const buttonLift = enableMotion
|
|
40
|
-
? "transition-all duration-200 hover:-translate-y-0.5"
|
|
41
|
-
: "transition-none hover:!translate-y-0";
|
|
42
|
-
// Defaults for text props (normalized below)
|
|
43
|
-
const defaultHeading = {
|
|
44
|
-
text: "Lorem ipsum dolor sit amet",
|
|
45
|
-
className: "text-3xl md:text-4xl font-bold leading-tight text-foreground",
|
|
46
|
-
};
|
|
47
|
-
const defaultSubheading = {
|
|
48
|
-
text: "Consectetur adipiscing elit, sed do eiusmod tempor.",
|
|
49
|
-
className: "text-lg md:text-xl text-foreground mt-4 mb-6",
|
|
50
|
-
};
|
|
51
|
-
const normalizedHeading = typeof heading === "string"
|
|
52
|
-
? { text: heading, className: defaultHeading.className }
|
|
53
|
-
: {
|
|
54
|
-
text: (_a = heading === null || heading === void 0 ? void 0 : heading.text) !== null && _a !== void 0 ? _a : defaultHeading.text,
|
|
55
|
-
className: cn(defaultHeading.className, heading === null || heading === void 0 ? void 0 : heading.className),
|
|
56
|
-
};
|
|
57
|
-
const normalizedSubheading = typeof subheading === "string"
|
|
58
|
-
? { text: subheading, className: defaultSubheading.className }
|
|
59
|
-
: {
|
|
60
|
-
text: (_b = subheading === null || subheading === void 0 ? void 0 : subheading.text) !== null && _b !== void 0 ? _b : defaultSubheading.text,
|
|
61
|
-
className: cn(defaultSubheading.className, subheading === null || subheading === void 0 ? void 0 : subheading.className),
|
|
62
|
-
};
|
|
63
|
-
// CTA defaults and normalization (merge, don't replace)
|
|
64
|
-
const defaultCta1 = {
|
|
65
|
-
label: "Get Started",
|
|
66
|
-
href: "#contact",
|
|
67
|
-
variant: "default",
|
|
68
|
-
size: "default",
|
|
69
|
-
className: "shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5",
|
|
70
|
-
};
|
|
71
|
-
const mergedCta1 = Object.assign(Object.assign(Object.assign({}, defaultCta1), (cta1 !== null && cta1 !== void 0 ? cta1 : {})), { className: cn(defaultCta1.className, cta1 === null || cta1 === void 0 ? void 0 : cta1.className, buttonLift) });
|
|
72
|
-
const defaultCta2 = {
|
|
73
|
-
label: "Learn More",
|
|
74
|
-
href: "#",
|
|
75
|
-
variant: "outline",
|
|
76
|
-
size: "default",
|
|
77
|
-
className: "",
|
|
78
|
-
};
|
|
79
|
-
const mergedCta2 = cta2
|
|
80
|
-
? Object.assign(Object.assign(Object.assign({}, defaultCta2), cta2), { className: cn(defaultCta2.className, cta2.className, buttonLift) }) : undefined;
|
|
81
|
-
const defaultSectionPadded = cn("px-8 pt-8 pb-8 md:min-h-[60vh] lg:min-h-[70vh]");
|
|
82
|
-
const defaultSectionFull = cn("relative overflow-hidden pt-0 pb-0 md:min-h-[60vh] lg:min-h-[70vh]");
|
|
83
|
-
const defaultImageContainerPadded = cn("relative mb-4 h-48 min-h-[12rem] w-full md:mb-0 md:h-72 md:w-1/2");
|
|
84
|
-
// For full-bleed: absolute positioning on large screens to break out completely
|
|
85
|
-
const defaultImageContainerFull = cn("relative h-48 w-full md:absolute md:inset-y-0 md:right-0 md:h-full md:w-1/2");
|
|
86
|
-
const baseSectionClass = imageLayout === "full-bleed" ? defaultSectionFull : defaultSectionPadded;
|
|
87
|
-
const finalSectionClass = cn(baseSectionClass, section === null || section === void 0 ? void 0 : section.className);
|
|
88
|
-
const baseImageContainerClass = imageLayout === "full-bleed"
|
|
89
|
-
? defaultImageContainerFull
|
|
90
|
-
: defaultImageContainerPadded;
|
|
91
|
-
const finalImageContainerClass = cn(baseImageContainerClass, imageContainer === null || imageContainer === void 0 ? void 0 : imageContainer.className);
|
|
92
|
-
// -- This overrides the image.className that is passed from importing components ... devs should be able to decide on cover/contain from the importing component.
|
|
93
|
-
const finalImageClass = cn(image === null || image === void 0 ? void 0 : image.className, imageLayout === "full-bleed"
|
|
94
|
-
? "object-cover object-center md:object-right"
|
|
95
|
-
: "object-contain object-center");
|
|
96
|
-
return (_jsx("section", { id: id, className: cn(finalSectionClass, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn("flex flex-col items-stretch", imageLayout === "full-bleed"
|
|
97
|
-
? "md:block"
|
|
98
|
-
: "md:flex-row md:items-start"), children: [_jsx("div", { className: cn("w-full", imageLayout === "full-bleed" &&
|
|
99
|
-
"relative z-10 md:w-1/2 md:px-8 md:py-12", textContainer.className), children: _jsxs("div", { className: cn("flex flex-col items-center", lgItemsAlignClasses[textAlign]), children: [_jsx("h1", { className: cn("text-center", lgTextAlignClasses[textAlign], normalizedHeading.className), children: normalizedHeading.text }), _jsx("p", { className: cn("text-center", lgTextAlignClasses[textAlign], normalizedSubheading.className), children: normalizedSubheading.text }), _jsxs("div", { className: cn("flex flex-col items-center justify-center gap-4 sm:flex-row", lgJustifyAlignClasses[textAlign], lgItemsAlignClasses[textAlign], buttonsContainer.className), children: [mergedCta1.label && (_jsx(Button, { asChild: true, variant: mergedCta1.variant, size: mergedCta1.size, className: mergedCta1.className, unstyled: mergedCta1.unstyled, style: mergedCta1.style, children: _jsx(Link, { href: mergedCta1.href || "#", "aria-label": mergedCta1.label, children: mergedCta1.label }) })), (mergedCta2 === null || mergedCta2 === void 0 ? void 0 : mergedCta2.label) && (_jsx(Button, { asChild: true, variant: mergedCta2.variant, size: mergedCta2.size, className: mergedCta2.className, unstyled: mergedCta2.unstyled, style: mergedCta2.style, children: _jsx(Link, { href: mergedCta2.href || "#", "aria-label": mergedCta2.label, children: mergedCta2.label }) }))] })] }) }), _jsx("div", { className: cn(finalImageContainerClass), children: (image === null || image === void 0 ? void 0 : image.src) ? (_jsx(Image, { priority: true, fetchPriority: "high", src: image.src, alt: image.alt || "Hero image", className: finalImageClass, fill: true, sizes: "(min-width: 768px) 50vw, 100vw", quality: 75 })) : (_jsx("div", { className: "absolute inset-0", children: fallback || null })) })] }) }));
|
|
100
|
-
}
|