@nextworks/blocks-sections 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +44 -0
  2. package/dist/components/About.d.ts +93 -0
  3. package/dist/components/About.d.ts.map +1 -0
  4. package/dist/components/About.js +129 -0
  5. package/dist/components/About.jsx +153 -0
  6. package/dist/components/CTA.d.ts +118 -0
  7. package/dist/components/CTA.d.ts.map +1 -0
  8. package/dist/components/CTA.js +58 -0
  9. package/dist/components/CTA.jsx +88 -0
  10. package/dist/components/Contact.d.ts +111 -0
  11. package/dist/components/Contact.d.ts.map +1 -0
  12. package/dist/components/Contact.js +82 -0
  13. package/dist/components/Contact.jsx +107 -0
  14. package/dist/components/FAQ.d.ts +89 -0
  15. package/dist/components/FAQ.d.ts.map +1 -0
  16. package/dist/components/FAQ.js +78 -0
  17. package/dist/components/FAQ.jsx +98 -0
  18. package/dist/components/Features.d.ts +111 -0
  19. package/dist/components/Features.d.ts.map +1 -0
  20. package/dist/components/Features.js +109 -0
  21. package/dist/components/Features.jsx +122 -0
  22. package/dist/components/Footer.d.ts +120 -0
  23. package/dist/components/Footer.d.ts.map +1 -0
  24. package/dist/components/Footer.js +101 -0
  25. package/dist/components/Footer.jsx +138 -0
  26. package/dist/components/HeroMotion.d.ts +107 -0
  27. package/dist/components/HeroMotion.d.ts.map +1 -0
  28. package/dist/components/HeroMotion.js +55 -0
  29. package/dist/components/HeroMotion.jsx +95 -0
  30. package/dist/components/HeroOverlay.d.ts +116 -0
  31. package/dist/components/HeroOverlay.d.ts.map +1 -0
  32. package/dist/components/HeroOverlay.js +111 -0
  33. package/dist/components/HeroOverlay.jsx +141 -0
  34. package/dist/components/HeroSplit.d.ts +98 -0
  35. package/dist/components/HeroSplit.d.ts.map +1 -0
  36. package/dist/components/HeroSplit.js +100 -0
  37. package/dist/components/HeroSplit.jsx +134 -0
  38. package/dist/components/Navbar.d.ts +112 -0
  39. package/dist/components/Navbar.d.ts.map +1 -0
  40. package/dist/components/Navbar.js +80 -0
  41. package/dist/components/Navbar.jsx +127 -0
  42. package/dist/components/Newsletter.d.ts +59 -0
  43. package/dist/components/Newsletter.d.ts.map +1 -0
  44. package/dist/components/Newsletter.js +34 -0
  45. package/dist/components/Newsletter.jsx +54 -0
  46. package/dist/components/PortfolioSimple.d.ts +137 -0
  47. package/dist/components/PortfolioSimple.d.ts.map +1 -0
  48. package/dist/components/PortfolioSimple.js +180 -0
  49. package/dist/components/PortfolioSimple.jsx +259 -0
  50. package/dist/components/Pricing.d.ts +96 -0
  51. package/dist/components/Pricing.d.ts.map +1 -0
  52. package/dist/components/Pricing.js +91 -0
  53. package/dist/components/Pricing.jsx +103 -0
  54. package/dist/components/ProcessTimeline.d.ts +121 -0
  55. package/dist/components/ProcessTimeline.d.ts.map +1 -0
  56. package/dist/components/ProcessTimeline.js +88 -0
  57. package/dist/components/ProcessTimeline.jsx +151 -0
  58. package/dist/components/ServicesGrid.d.ts +64 -0
  59. package/dist/components/ServicesGrid.d.ts.map +1 -0
  60. package/dist/components/ServicesGrid.js +72 -0
  61. package/dist/components/ServicesGrid.jsx +97 -0
  62. package/dist/components/Team.d.ts +115 -0
  63. package/dist/components/Team.d.ts.map +1 -0
  64. package/dist/components/Team.js +107 -0
  65. package/dist/components/Team.jsx +135 -0
  66. package/dist/components/Testimonials.d.ts +81 -0
  67. package/dist/components/Testimonials.d.ts.map +1 -0
  68. package/dist/components/Testimonials.js +46 -0
  69. package/dist/components/Testimonials.jsx +58 -0
  70. package/dist/components/TrustBadges.d.ts +80 -0
  71. package/dist/components/TrustBadges.d.ts.map +1 -0
  72. package/dist/components/TrustBadges.js +46 -0
  73. package/dist/components/TrustBadges.jsx +64 -0
  74. package/dist/components/index.d.ts +21 -0
  75. package/dist/components/index.d.ts.map +1 -0
  76. package/dist/components/index.js +18 -0
  77. package/dist/index.d.ts +2 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +1 -0
  80. package/package.json +26 -0
@@ -0,0 +1,112 @@
1
+ import React from "react";
2
+ import { type ThemeToggleProps } from "@nextworks/blocks-core";
3
+ /**
4
+ * Props for the Navbar component.
5
+ *
6
+ * @remarks
7
+ * Slot-style className overrides are available for structural parts. The mobile
8
+ * menu locks body scroll when open and restores it on close/unmount.
9
+ *
10
+ * @public
11
+ */
12
+ export interface NavbarProps {
13
+ /** Optional id to attach to the root nav element */
14
+ id?: string;
15
+ /** The height of the navbar as a Tailwind class. Example: "h-16" or "h-[13vh]" */
16
+ navHeight?: string;
17
+ /**
18
+ * The text displayed as the brand/logo.
19
+ * @defaultValue "Brand Name"
20
+ */
21
+ brand?: string;
22
+ /** Optional custom brand node (e.g., logo). Rendered left of brand text */
23
+ brandNode?: React.ReactNode;
24
+ /** Navigation links array. Each item has a label and href */
25
+ menuItems?: {
26
+ label: string;
27
+ href: string;
28
+ }[];
29
+ /**
30
+ * Call to action button config or null to hide it.
31
+ * Example: { label: "Get Started", href: "#contact" }
32
+ */
33
+ ctaButton?: {
34
+ label: string;
35
+ href: string;
36
+ } | null;
37
+ /**
38
+ * Whether to display the color mode toggle.
39
+ * @defaultValue true
40
+ */
41
+ showColorModeToggle?: boolean;
42
+ /**
43
+ * Whether navbar should stick to top when scrolling.
44
+ * @defaultValue true
45
+ */
46
+ sticky?: boolean;
47
+ /** Optional top-level class to override the nav root */
48
+ className?: string;
49
+ /** Styling configuration objects */
50
+ nav?: {
51
+ className?: string;
52
+ };
53
+ brandText?: {
54
+ className?: string;
55
+ };
56
+ links?: {
57
+ className?: string;
58
+ };
59
+ ctaButtonStyle?: {
60
+ unstyled?: boolean;
61
+ style?: React.CSSProperties;
62
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
63
+ size?: "default" | "sm" | "lg" | "icon";
64
+ className?: string;
65
+ };
66
+ mobileMenu?: {
67
+ className?: string;
68
+ };
69
+ container?: {
70
+ className?: string;
71
+ };
72
+ brandWrapper?: {
73
+ className?: string;
74
+ };
75
+ desktopMenu?: {
76
+ className?: string;
77
+ };
78
+ toggleButton?: {
79
+ className?: string;
80
+ };
81
+ colorModeWrapper?: {
82
+ className?: string;
83
+ };
84
+ ctaButtonWrapper?: {
85
+ className?: string;
86
+ };
87
+ mobileMenuInner?: {
88
+ className?: string;
89
+ };
90
+ /** Additional class overrides for mobile menu link hover/background, etc. */
91
+ mobileLinks?: {
92
+ className?: string;
93
+ };
94
+ /** Props forwarded to ThemeToggle so templates can fully style it */
95
+ themeToggle?: ThemeToggleProps;
96
+ /** ARIA label for the navbar. */
97
+ ariaLabel?: string;
98
+ }
99
+ /**
100
+ * Responsive navbar with brand, menu links, color mode toggle, and optional CTA.
101
+ *
102
+ * @remarks
103
+ * - Sticky behavior is enabled by default (sticky top-0 z-50).
104
+ * - Mobile menu toggles with a button and traps body scroll while open.
105
+ * - Accessibility: Focus rings are applied to interactive elements; aria
106
+ * attributes are set on the toggle button for state.
107
+ *
108
+ * @example
109
+ * <Navbar brand="Acme" />
110
+ */
111
+ export declare function Navbar({ id, navHeight, brand, brandNode, menuItems, ctaButton, showColorModeToggle, sticky, className, nav, brandText, links, ctaButtonStyle, mobileMenu, container, brandWrapper, desktopMenu, toggleButton, colorModeWrapper, ctaButtonWrapper, mobileMenuInner, mobileLinks, themeToggle, ariaLabel, }: NavbarProps): React.JSX.Element;
112
+ //# sourceMappingURL=Navbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Navbar.d.ts","sourceRoot":"","sources":["../../src/components/Navbar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ // components/sections/Navbar.tsx
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import Link from "next/link";
6
+ import { Button } from "@nextworks/blocks-core";
7
+ import { ThemeToggle } from "@nextworks/blocks-core";
8
+ import { cn } from "@nextworks/blocks-core";
9
+ import { Menu, X } from "lucide-react";
10
+ const defaultMenuItems = [
11
+ { label: "Home", href: "#home" },
12
+ { label: "Features", href: "#features" },
13
+ { label: "Pricing", href: "#pricing" },
14
+ { label: "FAQ", href: "#faq" },
15
+ { label: "Contact", href: "#contact" },
16
+ ];
17
+ /**
18
+ * Responsive navbar with brand, menu links, color mode toggle, and optional CTA.
19
+ *
20
+ * @remarks
21
+ * - Sticky behavior is enabled by default (sticky top-0 z-50).
22
+ * - Mobile menu toggles with a button and traps body scroll while open.
23
+ * - Accessibility: Focus rings are applied to interactive elements; aria
24
+ * attributes are set on the toggle button for state.
25
+ *
26
+ * @example
27
+ * <Navbar brand="Acme" />
28
+ */
29
+ export function Navbar({ id, navHeight = "h-16", brand = "Brand Name", brandNode, menuItems = defaultMenuItems, ctaButton = { label: "Get Started", href: "#contact" }, showColorModeToggle = true, sticky = true, className, nav = {
30
+ className: "bg-background text-foreground border-b border-border",
31
+ }, brandText = {
32
+ className: "text-2xl font-bold text-primary",
33
+ }, links = {
34
+ className: "text-base font-normal text-foreground hover:text-gray-500 dark:hover-text-gray-400 transition-colors",
35
+ }, ctaButtonStyle = {
36
+ variant: "default",
37
+ size: "default",
38
+ className: "shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5",
39
+ }, mobileMenu = {
40
+ className: "border-t border-border",
41
+ },
42
+ /* new slot defaults */
43
+ container = { className: "" }, brandWrapper = { className: "" }, desktopMenu = {
44
+ className: "hidden items-center space-x-1 lg:flex lg:space-x-6",
45
+ }, toggleButton = {
46
+ className: "hover:bg-accent flex items-center justify-center rounded-md p-2 transition-colors",
47
+ }, colorModeWrapper = { className: "ml-2" }, ctaButtonWrapper = { className: "ml-2" }, mobileMenuInner = { className: "space-y-2 px-4 pt-2 pb-4" }, mobileLinks = { className: "hover:bg-accent" }, themeToggle = {}, ariaLabel = "Main navigation", }) {
48
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
49
+ const mobileMenuId = "navbar-mobile-menu";
50
+ // Measure header height for reliable max height on mobile menu
51
+ const headerRef = useRef(null);
52
+ const [headerHeightPx, setHeaderHeightPx] = useState(0);
53
+ useEffect(() => {
54
+ const update = () => { var _a, _b; return setHeaderHeightPx((_b = (_a = headerRef.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0); };
55
+ update();
56
+ window.addEventListener("resize", update);
57
+ return () => window.removeEventListener("resize", update);
58
+ }, []);
59
+ // Lock body scroll when mobile menu is open
60
+ useEffect(() => {
61
+ const originalOverflow = document.body.style.overflow;
62
+ if (isMobileMenuOpen) {
63
+ document.body.style.overflow = "hidden";
64
+ }
65
+ else {
66
+ document.body.style.overflow = originalOverflow || "";
67
+ }
68
+ return () => {
69
+ document.body.style.overflow = originalOverflow || "";
70
+ };
71
+ }, [isMobileMenuOpen]);
72
+ return (_jsxs("nav", { id: id, className: cn("w-full", sticky && "sticky top-0 z-50", nav.className, className), "aria-label": ariaLabel, children: [_jsxs("div", { ref: headerRef, className: cn("flex items-center justify-between px-4 py-2", navHeight, container.className), children: [_jsxs("div", { className: cn("mr-2 flex items-center gap-2 pl-2", brandWrapper.className), children: [brandNode, brand && _jsx("h1", { className: cn(brandText.className), children: brand })] }), _jsx("button", { "aria-label": "Toggle mobile menu", "aria-expanded": isMobileMenuOpen, "aria-controls": mobileMenuId, className: cn("lg:hidden", toggleButton.className),
73
+ // className={cn("lg:hidden", toggleButton.className)}
74
+ onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen), children: isMobileMenuOpen ? (_jsx(X, { className: "h-6 w-6" })) : (_jsx(Menu, { className: "h-6 w-6" })) }), _jsxs("div", { className: cn("hidden md:flex", desktopMenu.className), children: [menuItems.map((item) => (_jsx(Link, { href: item.href, className: cn("rounded-md px-2 py-2 transition-colors duration-200 lg:px-4", "focus:ring-ring focus:ring-2 focus:ring-offset-2 focus:outline-none", "focus-visible:ring-[var(--navbar-ring)]", links.className), children: item.label }, item.label))), showColorModeToggle && (_jsx("div", { className: cn(colorModeWrapper.className), children: _jsx(ThemeToggle, Object.assign({}, themeToggle)) })), 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 }) }))] })] }), isMobileMenuOpen && (_jsx("div", { id: mobileMenuId, className: cn("md:hidden",
75
+ // "lg:hidden",
76
+ "overflow-y-auto overscroll-y-contain", nav.className, mobileMenu.className), style: {
77
+ maxHeight: `calc(100dvh - ${headerHeightPx}px)`,
78
+ WebkitOverflowScrolling: "touch",
79
+ }, children: _jsxs("div", { className: cn(mobileMenuInner.className), children: [menuItems.map((item) => (_jsx(Link, { href: item.href, className: cn("block w-full rounded-md px-2 py-4 text-center transition-colors duration-200", mobileLinks.className, "focus:ring-ring focus:ring-2 focus:ring-offset-2 focus:outline-none", "focus-visible:ring-[var(--navbar-ring)]", links.className), onClick: () => setIsMobileMenuOpen(false), children: item.label }, item.label))), showColorModeToggle && (_jsx("div", { className: "flex w-full justify-center pt-4", children: _jsx(ThemeToggle, Object.assign({}, themeToggle)) })), ctaButton && (_jsx("div", { className: "flex w-full justify-center pt-6", children: _jsx(Button, { asChild: true, unstyled: ctaButtonStyle.unstyled, variant: ctaButtonStyle.variant, size: ctaButtonStyle.size, className: cn("w-full max-w-xs", ctaButtonStyle.className), style: ctaButtonStyle.style, children: _jsx(Link, { href: ctaButton.href, "aria-label": ctaButton.label, children: ctaButton.label }) }) }))] }) }))] }));
80
+ }
@@ -0,0 +1,127 @@
1
+ // components/sections/Navbar.tsx
2
+ "use client";
3
+ import React, { useEffect, useRef, useState } from "react";
4
+ import Link from "next/link";
5
+ import { Button } from "@nextworks/blocks-core";
6
+ import { ThemeToggle } from "@nextworks/blocks-core";
7
+ import { cn } from "@nextworks/blocks-core";
8
+ import { Menu, X } from "lucide-react";
9
+ const defaultMenuItems = [
10
+ { label: "Home", href: "#home" },
11
+ { label: "Features", href: "#features" },
12
+ { label: "Pricing", href: "#pricing" },
13
+ { label: "FAQ", href: "#faq" },
14
+ { label: "Contact", href: "#contact" },
15
+ ];
16
+ /**
17
+ * Responsive navbar with brand, menu links, color mode toggle, and optional CTA.
18
+ *
19
+ * @remarks
20
+ * - Sticky behavior is enabled by default (sticky top-0 z-50).
21
+ * - Mobile menu toggles with a button and traps body scroll while open.
22
+ * - Accessibility: Focus rings are applied to interactive elements; aria
23
+ * attributes are set on the toggle button for state.
24
+ *
25
+ * @example
26
+ * <Navbar brand="Acme" />
27
+ */
28
+ export function Navbar({ id, navHeight = "h-16", brand = "Brand Name", brandNode, menuItems = defaultMenuItems, ctaButton = { label: "Get Started", href: "#contact" }, showColorModeToggle = true, sticky = true, className, nav = {
29
+ className: "bg-background text-foreground border-b border-border",
30
+ }, brandText = {
31
+ className: "text-2xl font-bold text-primary",
32
+ }, links = {
33
+ className: "text-base font-normal text-foreground hover:text-gray-500 dark:hover-text-gray-400 transition-colors",
34
+ }, ctaButtonStyle = {
35
+ variant: "default",
36
+ size: "default",
37
+ className: "shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5",
38
+ }, mobileMenu = {
39
+ className: "border-t border-border",
40
+ },
41
+ /* new slot defaults */
42
+ container = { className: "" }, brandWrapper = { className: "" }, desktopMenu = {
43
+ className: "hidden items-center space-x-1 lg:flex lg:space-x-6",
44
+ }, toggleButton = {
45
+ className: "hover:bg-accent flex items-center justify-center rounded-md p-2 transition-colors",
46
+ }, colorModeWrapper = { className: "ml-2" }, ctaButtonWrapper = { className: "ml-2" }, mobileMenuInner = { className: "space-y-2 px-4 pt-2 pb-4" }, mobileLinks = { className: "hover:bg-accent" }, themeToggle = {}, ariaLabel = "Main navigation", }) {
47
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
48
+ const mobileMenuId = "navbar-mobile-menu";
49
+ // Measure header height for reliable max height on mobile menu
50
+ const headerRef = useRef(null);
51
+ const [headerHeightPx, setHeaderHeightPx] = useState(0);
52
+ useEffect(() => {
53
+ const update = () => { var _a, _b; return setHeaderHeightPx((_b = (_a = headerRef.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0); };
54
+ update();
55
+ window.addEventListener("resize", update);
56
+ return () => window.removeEventListener("resize", update);
57
+ }, []);
58
+ // Lock body scroll when mobile menu is open
59
+ useEffect(() => {
60
+ const originalOverflow = document.body.style.overflow;
61
+ if (isMobileMenuOpen) {
62
+ document.body.style.overflow = "hidden";
63
+ }
64
+ else {
65
+ document.body.style.overflow = originalOverflow || "";
66
+ }
67
+ return () => {
68
+ document.body.style.overflow = originalOverflow || "";
69
+ };
70
+ }, [isMobileMenuOpen]);
71
+ return (<nav id={id} className={cn("w-full", sticky && "sticky top-0 z-50", nav.className, className)} aria-label={ariaLabel}>
72
+ <div ref={headerRef} className={cn("flex items-center justify-between px-4 py-2", navHeight, container.className)}>
73
+ <div className={cn("mr-2 flex items-center gap-2 pl-2", brandWrapper.className)}>
74
+ {brandNode}
75
+ {brand && <h1 className={cn(brandText.className)}>{brand}</h1>}
76
+ </div>
77
+
78
+ <button aria-label="Toggle mobile menu" aria-expanded={isMobileMenuOpen} aria-controls={mobileMenuId} className={cn("lg:hidden", toggleButton.className)}
79
+ // className={cn("lg:hidden", toggleButton.className)}
80
+ onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}>
81
+ {isMobileMenuOpen ? (<X className="h-6 w-6"/>) : (<Menu className="h-6 w-6"/>)}
82
+ </button>
83
+
84
+ <div className={cn("hidden md:flex", desktopMenu.className)}>
85
+ {/* <div className={cn("hidden lg:flex", desktopMenu.className)}> */}
86
+ {menuItems.map((item) => (<Link key={item.label} href={item.href} className={cn("rounded-md px-2 py-2 transition-colors duration-200 lg:px-4", "focus:ring-ring focus:ring-2 focus:ring-offset-2 focus:outline-none", "focus-visible:ring-[var(--navbar-ring)]", links.className)}>
87
+ {item.label}
88
+ </Link>))}
89
+
90
+ {showColorModeToggle && (<div className={cn(colorModeWrapper.className)}>
91
+ <ThemeToggle {...themeToggle}/>
92
+ </div>)}
93
+
94
+ {ctaButton && (<Button asChild unstyled={ctaButtonStyle.unstyled} variant={ctaButtonStyle.variant} size={ctaButtonStyle.size} className={cn(ctaButtonWrapper.className, ctaButtonStyle.className)} style={ctaButtonStyle.style}>
95
+ <Link href={ctaButton.href} aria-label={ctaButton.label}>
96
+ {ctaButton.label}
97
+ </Link>
98
+ </Button>)}
99
+ </div>
100
+ </div>
101
+
102
+ {isMobileMenuOpen && (<div id={mobileMenuId} className={cn("md:hidden",
103
+ // "lg:hidden",
104
+ "overflow-y-auto overscroll-y-contain", nav.className, mobileMenu.className)} style={{
105
+ maxHeight: `calc(100dvh - ${headerHeightPx}px)`,
106
+ WebkitOverflowScrolling: "touch",
107
+ }}>
108
+ <div className={cn(mobileMenuInner.className)}>
109
+ {menuItems.map((item) => (<Link key={item.label} href={item.href} className={cn("block w-full rounded-md px-2 py-4 text-center transition-colors duration-200", mobileLinks.className, "focus:ring-ring focus:ring-2 focus:ring-offset-2 focus:outline-none", "focus-visible:ring-[var(--navbar-ring)]", links.className)} onClick={() => setIsMobileMenuOpen(false)}>
110
+ {item.label}
111
+ </Link>))}
112
+
113
+ {showColorModeToggle && (<div className="flex w-full justify-center pt-4">
114
+ <ThemeToggle {...themeToggle}/>
115
+ </div>)}
116
+
117
+ {ctaButton && (<div className="flex w-full justify-center pt-6">
118
+ <Button asChild unstyled={ctaButtonStyle.unstyled} variant={ctaButtonStyle.variant} size={ctaButtonStyle.size} className={cn("w-full max-w-xs", ctaButtonStyle.className)} style={ctaButtonStyle.style}>
119
+ <Link href={ctaButton.href} aria-label={ctaButton.label}>
120
+ {ctaButton.label}
121
+ </Link>
122
+ </Button>
123
+ </div>)}
124
+ </div>
125
+ </div>)}
126
+ </nav>);
127
+ }
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ /**
3
+ * Props for a compact newsletter/signup block.
4
+ *
5
+ * - Slot-style API (section, container, header, heading, subheading, form, formRow, input, button)
6
+ * - Merges consumer classes with sensible defaults via cn(...)
7
+ * - Uses CSS vars in defaults so token/theming overrides don't break
8
+ */
9
+ export interface NewsletterProps {
10
+ id?: string;
11
+ className?: string;
12
+ headingText?: string;
13
+ subheadingText?: string;
14
+ /** Called after successful submit (form event will be passed) */
15
+ onSubmit?: (e: React.FormEvent<HTMLFormElement>, email: string) => void;
16
+ /** Slot-style overrides */
17
+ section?: {
18
+ className?: string;
19
+ };
20
+ container?: {
21
+ className?: string;
22
+ };
23
+ header?: {
24
+ className?: string;
25
+ };
26
+ heading?: {
27
+ className?: string;
28
+ };
29
+ subheading?: {
30
+ className?: string;
31
+ };
32
+ form?: {
33
+ className?: string;
34
+ };
35
+ formRow?: {
36
+ className?: string;
37
+ };
38
+ input?: {
39
+ className?: string;
40
+ };
41
+ button?: {
42
+ className?: string;
43
+ variant?: any;
44
+ size?: any;
45
+ unstyled?: boolean;
46
+ };
47
+ enableMotion?: boolean;
48
+ ariaLabel?: string;
49
+ }
50
+ /**
51
+ * Compact newsletter/signup block.
52
+ *
53
+ * Usage:
54
+ * <Newsletter section={{ className: "bg-gradient-to-r ..." }} />
55
+ *
56
+ * Slots exposed: section, container, header, heading, subheading, form, formRow, input, button
57
+ */
58
+ export declare function Newsletter({ id, className, headingText, subheadingText, onSubmit, section, container, header, heading, subheading, form, formRow, input, button, enableMotion, ariaLabel, }: NewsletterProps): React.JSX.Element;
59
+ //# sourceMappingURL=Newsletter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Newsletter.d.ts","sourceRoot":"","sources":["../../src/components/Newsletter.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExE,2BAA2B;IAC3B,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,SAAS,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,KAAK,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IAEF,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,EAAE,EACF,SAAS,EACT,WAAgC,EAChC,cAAiE,EACjE,QAAQ,EACR,OAAO,EACP,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAmB,EACnB,SAAuC,GACxC,EAAE,eAAe,qBAgEjB"}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from "react";
4
+ import { cn } from "@nextworks/blocks-core";
5
+ import { Input, Button } from "@nextworks/blocks-core";
6
+ // Default classes used for slot merging. Consumers' slot.className will be merged after these.
7
+ const DEFAULT_SECTION = "py-12 bg-[var(--card-bg)] text-[var(--card-fg)]";
8
+ const DEFAULT_CONTAINER = "max-w-3xl mx-auto px-4";
9
+ const DEFAULT_HEADER = "text-center mb-6";
10
+ const DEFAULT_HEADING = "text-2xl font-bold font-poppins text-foreground text-[var(--heading-fg)]";
11
+ const DEFAULT_SUBHEADING = "text-sm font-inter text-muted-foreground max-w-xl mx-auto leading-relaxed text-[var(--subheading-fg)]";
12
+ const DEFAULT_FORM = "w-full";
13
+ const DEFAULT_FORM_ROW = "mt-6 flex flex-col sm:flex-row items-center gap-3 justify-center";
14
+ const DEFAULT_INPUT = "w-full sm:flex-1 p-3 rounded-md border border-[var(--input-border)] bg-[var(--input-bg)] text-[var(--input-fg)] placeholder:text-[var(--input-placeholder)]";
15
+ const DEFAULT_BUTTON = "w-full sm:w-auto px-5 py-3 rounded-md bg-primary hover:bg-primary/90 dark:bg-primary dark:hover:bg-primary text-primary-foreground font-medium shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5 border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]";
16
+ /**
17
+ * Compact newsletter/signup block.
18
+ *
19
+ * Usage:
20
+ * <Newsletter section={{ className: "bg-gradient-to-r ..." }} />
21
+ *
22
+ * Slots exposed: section, container, header, heading, subheading, form, formRow, input, button
23
+ */
24
+ export function Newsletter({ id, className, headingText = "Stay in the loop", subheadingText = "Subscribe for product news, tips, and updates.", onSubmit, section, container, header, heading, subheading, form, formRow, input, button, enableMotion = true, ariaLabel = "Newsletter signup section", }) {
25
+ const [email, setEmail] = React.useState("");
26
+ const handleSubmit = (e) => {
27
+ e.preventDefault();
28
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(e, email);
29
+ // Optimistic clear; consumer can override behavior via onSubmit
30
+ setEmail("");
31
+ };
32
+ return (_jsx("section", { id: id, className: cn(DEFAULT_SECTION, section === null || section === void 0 ? void 0 : section.className, className), "aria-label": ariaLabel, children: _jsxs("div", { className: cn(DEFAULT_CONTAINER, container === null || container === void 0 ? void 0 : container.className), children: [_jsxs("div", { className: cn(DEFAULT_HEADER, header === null || header === void 0 ? void 0 : header.className), children: [_jsx("h2", { className: cn(DEFAULT_HEADING, heading === null || heading === void 0 ? void 0 : heading.className), children: headingText }), _jsx("p", { className: cn(DEFAULT_SUBHEADING, subheading === null || subheading === void 0 ? void 0 : subheading.className), children: subheadingText })] }), _jsx("form", { className: cn(DEFAULT_FORM, form === null || form === void 0 ? void 0 : form.className), onSubmit: handleSubmit, "aria-label": "Newsletter signup form", children: _jsxs("div", { className: cn(DEFAULT_FORM_ROW, formRow === null || formRow === void 0 ? void 0 : formRow.className), children: [_jsx(Input, { id: "newsletter-email", name: "email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "Your email address", required: true, "aria-label": "Email address", className: cn(DEFAULT_INPUT, input === null || input === void 0 ? void 0 : input.className) }), _jsx(Button, { type: "submit", unstyled: button === null || button === void 0 ? void 0 : button.unstyled, variant: button === null || button === void 0 ? void 0 : button.variant, size: button === null || button === void 0 ? void 0 : button.size, className: cn(DEFAULT_BUTTON, button === null || button === void 0 ? void 0 : button.className, !enableMotion &&
33
+ "transition-none hover:!translate-y-0 hover:shadow-none"), children: "Subscribe" })] }) })] }) }));
34
+ }
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { cn } from "@nextworks/blocks-core";
4
+ import { Input, Button } from "@nextworks/blocks-core";
5
+ // Default classes used for slot merging. Consumers' slot.className will be merged after these.
6
+ const DEFAULT_SECTION = "py-12 bg-[var(--card-bg)] text-[var(--card-fg)]";
7
+ const DEFAULT_CONTAINER = "max-w-3xl mx-auto px-4";
8
+ const DEFAULT_HEADER = "text-center mb-6";
9
+ const DEFAULT_HEADING = "text-2xl font-bold font-poppins text-foreground text-[var(--heading-fg)]";
10
+ const DEFAULT_SUBHEADING = "text-sm font-inter text-muted-foreground max-w-xl mx-auto leading-relaxed text-[var(--subheading-fg)]";
11
+ const DEFAULT_FORM = "w-full";
12
+ const DEFAULT_FORM_ROW = "mt-6 flex flex-col sm:flex-row items-center gap-3 justify-center";
13
+ const DEFAULT_INPUT = "w-full sm:flex-1 p-3 rounded-md border border-[var(--input-border)] bg-[var(--input-bg)] text-[var(--input-fg)] placeholder:text-[var(--input-placeholder)]";
14
+ const DEFAULT_BUTTON = "w-full sm:w-auto px-5 py-3 rounded-md bg-primary hover:bg-primary/90 dark:bg-primary dark:hover:bg-primary text-primary-foreground font-medium shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5 border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]";
15
+ /**
16
+ * Compact newsletter/signup block.
17
+ *
18
+ * Usage:
19
+ * <Newsletter section={{ className: "bg-gradient-to-r ..." }} />
20
+ *
21
+ * Slots exposed: section, container, header, heading, subheading, form, formRow, input, button
22
+ */
23
+ export function Newsletter({ id, className, headingText = "Stay in the loop", subheadingText = "Subscribe for product news, tips, and updates.", onSubmit, section, container, header, heading, subheading, form, formRow, input, button, enableMotion = true, ariaLabel = "Newsletter signup section", }) {
24
+ const [email, setEmail] = React.useState("");
25
+ const handleSubmit = (e) => {
26
+ e.preventDefault();
27
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(e, email);
28
+ // Optimistic clear; consumer can override behavior via onSubmit
29
+ setEmail("");
30
+ };
31
+ return (<section id={id} className={cn(DEFAULT_SECTION, section === null || section === void 0 ? void 0 : section.className, className)} aria-label={ariaLabel}>
32
+ <div className={cn(DEFAULT_CONTAINER, container === null || container === void 0 ? void 0 : container.className)}>
33
+ <div className={cn(DEFAULT_HEADER, header === null || header === void 0 ? void 0 : header.className)}>
34
+ <h2 className={cn(DEFAULT_HEADING, heading === null || heading === void 0 ? void 0 : heading.className)}>
35
+ {headingText}
36
+ </h2>
37
+ <p className={cn(DEFAULT_SUBHEADING, subheading === null || subheading === void 0 ? void 0 : subheading.className)}>
38
+ {subheadingText}
39
+ </p>
40
+ </div>
41
+
42
+ <form className={cn(DEFAULT_FORM, form === null || form === void 0 ? void 0 : form.className)} onSubmit={handleSubmit} aria-label="Newsletter signup form">
43
+ <div className={cn(DEFAULT_FORM_ROW, formRow === null || formRow === void 0 ? void 0 : formRow.className)}>
44
+ <Input id="newsletter-email" name="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Your email address" required aria-label="Email address" className={cn(DEFAULT_INPUT, input === null || input === void 0 ? void 0 : input.className)}/>
45
+
46
+ <Button type="submit" unstyled={button === null || button === void 0 ? void 0 : button.unstyled} variant={button === null || button === void 0 ? void 0 : button.variant} size={button === null || button === void 0 ? void 0 : button.size} className={cn(DEFAULT_BUTTON, button === null || button === void 0 ? void 0 : button.className, !enableMotion &&
47
+ "transition-none hover:!translate-y-0 hover:shadow-none")}>
48
+ Subscribe
49
+ </Button>
50
+ </div>
51
+ </form>
52
+ </div>
53
+ </section>);
54
+ }
@@ -0,0 +1,137 @@
1
+ import React from "react";
2
+ export interface PortfolioProject {
3
+ id: number;
4
+ title: string;
5
+ category: string;
6
+ industry: string;
7
+ result: string;
8
+ description: string;
9
+ image?: string;
10
+ tags: string[];
11
+ color: string;
12
+ url?: string;
13
+ }
14
+ /**
15
+ * Props for the PortfolioSimple section component.
16
+ *
17
+ * @remarks
18
+ * - Styling: slot-style className overrides are merged after defaults via cn().
19
+ * - Motion: entrance animations respect enableMotion; prefers-reduced-motion is supported.
20
+ *
21
+ * @public
22
+ */
23
+ interface PortfolioSimpleProps {
24
+ /** Optional id on root section */
25
+ id?: string;
26
+ /** Root className merged into section slot */
27
+ className?: string;
28
+ projects?: PortfolioProject[];
29
+ /**
30
+ * List of filter labels. Filtering matches project.category exactly.
31
+ * The first item is selected by default; a value of "All Projects" disables filtering.
32
+ */
33
+ filters?: string[];
34
+ /** When false, disables entrance animations and hover transitions. */
35
+ enableMotion?: boolean;
36
+ sectionTitle?: string;
37
+ sectionSubtitle?: string;
38
+ ctaTitle?: string;
39
+ ctaDescription?: string;
40
+ /** Label for the first call-to-action button */
41
+ cta1Label?: string;
42
+ /** URL or anchor target for the first CTA button */
43
+ cta1Href?: string;
44
+ /** Label for the second call-to-action button */
45
+ cta2Label?: string;
46
+ /** URL or anchor target for the second CTA button */
47
+ cta2Href?: string;
48
+ /** Styling configuration objects */
49
+ section?: {
50
+ className?: string;
51
+ };
52
+ container?: {
53
+ className?: string;
54
+ };
55
+ header?: {
56
+ className?: string;
57
+ };
58
+ title?: {
59
+ className?: string;
60
+ };
61
+ subtitle?: {
62
+ className?: string;
63
+ };
64
+ filterContainer?: {
65
+ className?: string;
66
+ };
67
+ filterButton?: {
68
+ className?: string;
69
+ };
70
+ activeFilterButton?: {
71
+ className?: string;
72
+ };
73
+ grid?: {
74
+ className?: string;
75
+ };
76
+ projectCard?: {
77
+ className?: string;
78
+ };
79
+ imageContainer?: {
80
+ className?: string;
81
+ };
82
+ projectInfo?: {
83
+ className?: string;
84
+ };
85
+ projectTitle?: {
86
+ className?: string;
87
+ };
88
+ projectDescription?: {
89
+ className?: string;
90
+ };
91
+ tagsContainer?: {
92
+ className?: string;
93
+ };
94
+ tagStyle?: {
95
+ className?: string;
96
+ };
97
+ result?: {
98
+ className?: string;
99
+ };
100
+ ctaSection?: {
101
+ className?: string;
102
+ };
103
+ ctaTitleStyle?: {
104
+ className?: string;
105
+ };
106
+ ctaDescriptionStyle?: {
107
+ className?: string;
108
+ };
109
+ ctaButtons?: {
110
+ className?: string;
111
+ };
112
+ cta1Button?: {
113
+ className?: string;
114
+ };
115
+ cta2Button?: {
116
+ className?: string;
117
+ };
118
+ /** Called when a project image or card is clicked. */
119
+ onProjectClick?: (project: PortfolioProject) => void;
120
+ onPrimaryCtaClick?: () => void;
121
+ onSecondaryCtaClick?: () => void;
122
+ /** ARIA label for the portfolio section */
123
+ ariaLabel?: string;
124
+ }
125
+ /**
126
+ * Responsive portfolio/gallery grid with simple category filtering and CTA block.
127
+ *
128
+ * @remarks
129
+ * - Filtering uses exact category match; include "All Projects" to disable filtering.
130
+ * - Accessibility: Renders a semantic <section> with aria-label; ensure images have informative titles or alt text.
131
+ *
132
+ * @example
133
+ * <PortfolioSimple sectionTitle="Our Work" />
134
+ */
135
+ export declare function PortfolioSimple({ id, className, projects, filters, enableMotion, sectionTitle, sectionSubtitle, ctaTitle, ctaDescription, cta1Label, cta1Href, cta2Label, cta2Href, section, container, header, title, subtitle, filterContainer, filterButton, activeFilterButton, grid, projectCard, imageContainer, projectInfo, projectTitle, projectDescription, tagsContainer, tagStyle, result, ctaSection, ctaTitleStyle, ctaDescriptionStyle, ctaButtons, cta1Button, cta2Button, onProjectClick, onPrimaryCtaClick, onSecondaryCtaClick, ariaLabel, }: PortfolioSimpleProps): React.JSX.Element;
136
+ export {};
137
+ //# sourceMappingURL=PortfolioSimple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortfolioSimple.d.ts","sourceRoot":"","sources":["../../src/components/PortfolioSimple.tsx"],"names":[],"mappings":"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"}