@opensite/ui 0.1.2 → 0.1.4
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/components.cjs +1511 -3
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +13 -0
- package/dist/components.d.ts +13 -0
- package/dist/components.js +1499 -4
- package/dist/components.js.map +1 -1
- package/dist/footer-animated-social.cjs +272 -0
- package/dist/footer-animated-social.cjs.map +1 -0
- package/dist/footer-animated-social.d.cts +41 -0
- package/dist/footer-animated-social.d.ts +41 -0
- package/dist/footer-animated-social.js +250 -0
- package/dist/footer-animated-social.js.map +1 -0
- package/dist/footer-background-card.cjs +149 -0
- package/dist/footer-background-card.cjs.map +1 -0
- package/dist/footer-background-card.d.cts +74 -0
- package/dist/footer-background-card.d.ts +74 -0
- package/dist/footer-background-card.js +147 -0
- package/dist/footer-background-card.js.map +1 -0
- package/dist/footer-brand-description.cjs +244 -0
- package/dist/footer-brand-description.cjs.map +1 -0
- package/dist/footer-brand-description.d.cts +65 -0
- package/dist/footer-brand-description.d.ts +65 -0
- package/dist/footer-brand-description.js +222 -0
- package/dist/footer-brand-description.js.map +1 -0
- package/dist/footer-contact-card.cjs +238 -0
- package/dist/footer-contact-card.cjs.map +1 -0
- package/dist/footer-contact-card.d.cts +65 -0
- package/dist/footer-contact-card.d.ts +65 -0
- package/dist/footer-contact-card.js +216 -0
- package/dist/footer-contact-card.js.map +1 -0
- package/dist/footer-cta-banner.cjs +282 -0
- package/dist/footer-cta-banner.cjs.map +1 -0
- package/dist/footer-cta-banner.d.cts +77 -0
- package/dist/footer-cta-banner.d.ts +77 -0
- package/dist/footer-cta-banner.js +260 -0
- package/dist/footer-cta-banner.js.map +1 -0
- package/dist/footer-cta-social.cjs +221 -0
- package/dist/footer-cta-social.cjs.map +1 -0
- package/dist/footer-cta-social.d.cts +45 -0
- package/dist/footer-cta-social.d.ts +45 -0
- package/dist/footer-cta-social.js +199 -0
- package/dist/footer-cta-social.js.map +1 -0
- package/dist/footer-links-grid.cjs +119 -0
- package/dist/footer-links-grid.cjs.map +1 -0
- package/dist/footer-links-grid.d.cts +54 -0
- package/dist/footer-links-grid.d.ts +54 -0
- package/dist/footer-links-grid.js +117 -0
- package/dist/footer-links-grid.js.map +1 -0
- package/dist/footer-nav-social.cjs +273 -0
- package/dist/footer-nav-social.cjs.map +1 -0
- package/dist/footer-nav-social.d.cts +72 -0
- package/dist/footer-nav-social.d.ts +72 -0
- package/dist/footer-nav-social.js +251 -0
- package/dist/footer-nav-social.js.map +1 -0
- package/dist/footer-newsletter-grid.cjs +271 -0
- package/dist/footer-newsletter-grid.cjs.map +1 -0
- package/dist/footer-newsletter-grid.d.cts +74 -0
- package/dist/footer-newsletter-grid.d.ts +74 -0
- package/dist/footer-newsletter-grid.js +249 -0
- package/dist/footer-newsletter-grid.js.map +1 -0
- package/dist/footer-newsletter-minimal.cjs +271 -0
- package/dist/footer-newsletter-minimal.cjs.map +1 -0
- package/dist/footer-newsletter-minimal.d.cts +57 -0
- package/dist/footer-newsletter-minimal.d.ts +57 -0
- package/dist/footer-newsletter-minimal.js +249 -0
- package/dist/footer-newsletter-minimal.js.map +1 -0
- package/dist/footer-simple-centered.cjs +101 -0
- package/dist/footer-simple-centered.cjs.map +1 -0
- package/dist/footer-simple-centered.d.cts +52 -0
- package/dist/footer-simple-centered.d.ts +52 -0
- package/dist/footer-simple-centered.js +99 -0
- package/dist/footer-simple-centered.js.map +1 -0
- package/dist/footer-social-apps.cjs +247 -0
- package/dist/footer-social-apps.cjs.map +1 -0
- package/dist/footer-social-apps.d.cts +75 -0
- package/dist/footer-social-apps.d.ts +75 -0
- package/dist/footer-social-apps.js +225 -0
- package/dist/footer-social-apps.js.map +1 -0
- package/dist/footer-social-newsletter.cjs +267 -0
- package/dist/footer-social-newsletter.cjs.map +1 -0
- package/dist/footer-social-newsletter.d.cts +68 -0
- package/dist/footer-social-newsletter.d.ts +68 -0
- package/dist/footer-social-newsletter.js +245 -0
- package/dist/footer-social-newsletter.js.map +1 -0
- package/dist/index.cjs +1511 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1499 -4
- package/dist/index.js.map +1 -1
- package/dist/pressable.cjs +10 -3
- package/dist/pressable.cjs.map +1 -1
- package/dist/pressable.js +10 -3
- package/dist/pressable.js.map +1 -1
- package/dist/registry.cjs +1971 -1
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +1971 -1
- package/dist/registry.js.map +1 -1
- package/dist/team-media-showcase.cjs +182 -0
- package/dist/team-media-showcase.cjs.map +1 -0
- package/dist/team-media-showcase.d.cts +145 -0
- package/dist/team-media-showcase.d.ts +145 -0
- package/dist/team-media-showcase.js +160 -0
- package/dist/team-media-showcase.js.map +1 -0
- package/package.json +71 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var img = require('@page-speed/img');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
// lib/utils.ts
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var defaultMenuItems = [
|
|
14
|
+
{
|
|
15
|
+
title: "Product",
|
|
16
|
+
links: [
|
|
17
|
+
{ text: "Overview", url: "#" },
|
|
18
|
+
{ text: "Pricing", url: "#" },
|
|
19
|
+
{ text: "Marketplace", url: "#" },
|
|
20
|
+
{ text: "Features", url: "#" },
|
|
21
|
+
{ text: "Integrations", url: "#" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: "Company",
|
|
26
|
+
links: [
|
|
27
|
+
{ text: "About", url: "#" },
|
|
28
|
+
{ text: "Team", url: "#" },
|
|
29
|
+
{ text: "Blog", url: "#" },
|
|
30
|
+
{ text: "Careers", url: "#" },
|
|
31
|
+
{ text: "Contact", url: "#" }
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
title: "Resources",
|
|
36
|
+
links: [
|
|
37
|
+
{ text: "Help", url: "#" },
|
|
38
|
+
{ text: "Sales", url: "#" },
|
|
39
|
+
{ text: "Advertise", url: "#" }
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: "Social",
|
|
44
|
+
links: [
|
|
45
|
+
{ text: "Twitter", url: "#" },
|
|
46
|
+
{ text: "Instagram", url: "#" },
|
|
47
|
+
{ text: "LinkedIn", url: "#" }
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
var defaultBottomLinks = [
|
|
52
|
+
{ text: "Terms and Conditions", url: "#" },
|
|
53
|
+
{ text: "Privacy Policy", url: "#" }
|
|
54
|
+
];
|
|
55
|
+
function FooterLinksGrid({
|
|
56
|
+
logo = {
|
|
57
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
58
|
+
alt: "Opensite AI",
|
|
59
|
+
title: "Opensite AI",
|
|
60
|
+
url: "https://opensite.ai"
|
|
61
|
+
},
|
|
62
|
+
className,
|
|
63
|
+
tagline = "Components made easy.",
|
|
64
|
+
menuItems = defaultMenuItems,
|
|
65
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
66
|
+
bottomLinks = defaultBottomLinks,
|
|
67
|
+
optixFlowConfig
|
|
68
|
+
}) {
|
|
69
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: cn("py-32", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container", children: /* @__PURE__ */ jsxRuntime.jsxs("footer", { children: [
|
|
70
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-8 lg:grid-cols-6", children: [
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2 mb-8 lg:mb-0", children: [
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 lg:justify-start", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: logo.url, className: "flex items-center gap-2", children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
img.Img,
|
|
75
|
+
{
|
|
76
|
+
src: logo.src,
|
|
77
|
+
alt: logo.alt,
|
|
78
|
+
className: "h-10 dark:invert",
|
|
79
|
+
optixFlowConfig
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl font-semibold", children: logo.title })
|
|
83
|
+
] }) }),
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 font-bold", children: tagline })
|
|
85
|
+
] }),
|
|
86
|
+
menuItems.map((section, sectionIdx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 font-bold", children: section.title }),
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-4 text-muted-foreground", children: section.links.map((link, linkIdx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
+
"li",
|
|
90
|
+
{
|
|
91
|
+
className: "font-medium hover:text-primary",
|
|
92
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.url, children: link.text })
|
|
93
|
+
},
|
|
94
|
+
linkIdx
|
|
95
|
+
)) })
|
|
96
|
+
] }, sectionIdx))
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-24 flex flex-col justify-between gap-4 border-t pt-8 text-sm font-medium text-muted-foreground md:flex-row md:items-center", children: [
|
|
99
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:gap-4", children: [
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: copyright }),
|
|
101
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
"a",
|
|
103
|
+
{
|
|
104
|
+
href: "https://opensite.ai",
|
|
105
|
+
className: "hover:text-primary",
|
|
106
|
+
target: "_blank",
|
|
107
|
+
rel: "noopener noreferrer",
|
|
108
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex gap-4", children: bottomLinks.map((link, linkIdx) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "underline hover:text-primary", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.url, children: link.text }) }, linkIdx)) })
|
|
113
|
+
] })
|
|
114
|
+
] }) }) });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
exports.FooterLinksGrid = FooterLinksGrid;
|
|
118
|
+
//# sourceMappingURL=footer-links-grid.cjs.map
|
|
119
|
+
//# sourceMappingURL=footer-links-grid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/blocks/footers/footer-links-grid.tsx"],"names":["twMerge","clsx","jsx","jsxs","Img"],"mappings":";;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;AC6CA,IAAM,gBAAA,GAA8C;AAAA,EAClD;AAAA,IACE,KAAA,EAAO,SAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,UAAA,EAAY,GAAA,EAAK,GAAA,EAAI;AAAA,MAC7B,EAAE,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAA,EAAI;AAAA,MAC5B,EAAE,IAAA,EAAM,aAAA,EAAe,GAAA,EAAK,GAAA,EAAI;AAAA,MAChC,EAAE,IAAA,EAAM,UAAA,EAAY,GAAA,EAAK,GAAA,EAAI;AAAA,MAC7B,EAAE,IAAA,EAAM,cAAA,EAAgB,GAAA,EAAK,GAAA;AAAI;AACnC,GACF;AAAA,EACA;AAAA,IACE,KAAA,EAAO,SAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,OAAA,EAAS,GAAA,EAAK,GAAA,EAAI;AAAA,MAC1B,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,GAAA,EAAI;AAAA,MACzB,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,GAAA,EAAI;AAAA,MACzB,EAAE,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAA,EAAI;AAAA,MAC5B,EAAE,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAA;AAAI;AAC9B,GACF;AAAA,EACA;AAAA,IACE,KAAA,EAAO,WAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,GAAA,EAAI;AAAA,MACzB,EAAE,IAAA,EAAM,OAAA,EAAS,GAAA,EAAK,GAAA,EAAI;AAAA,MAC1B,EAAE,IAAA,EAAM,WAAA,EAAa,GAAA,EAAK,GAAA;AAAI;AAChC,GACF;AAAA,EACA;AAAA,IACE,KAAA,EAAO,QAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAA,EAAI;AAAA,MAC5B,EAAE,IAAA,EAAM,WAAA,EAAa,GAAA,EAAK,GAAA,EAAI;AAAA,MAC9B,EAAE,IAAA,EAAM,UAAA,EAAY,GAAA,EAAK,GAAA;AAAI;AAC/B;AAEJ,CAAA;AAEA,IAAM,kBAAA,GAAqB;AAAA,EACzB,EAAE,IAAA,EAAM,sBAAA,EAAwB,GAAA,EAAK,GAAA,EAAI;AAAA,EACzC,EAAE,IAAA,EAAM,gBAAA,EAAkB,GAAA,EAAK,GAAA;AACjC,CAAA;AASO,SAAS,eAAA,CAAgB;AAAA,EAC9B,IAAA,GAAO;AAAA,IACL,GAAA,EAAK,2FAAA;AAAA,IACL,GAAA,EAAK,aAAA;AAAA,IACL,KAAA,EAAO,aAAA;AAAA,IACP,GAAA,EAAK;AAAA,GACP;AAAA,EACA,SAAA;AAAA,EACA,OAAA,GAAU,uBAAA;AAAA,EACV,SAAA,GAAY,gBAAA;AAAA,EACZ,YAAY,CAAA,KAAA,EAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,aAAa,CAAA,kCAAA,CAAA;AAAA,EACzC,WAAA,GAAc,kBAAA;AAAA,EACd;AACF,CAAA,EAA4C;AAC1C,EAAA,uBACEC,cAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAW,EAAA,CAAG,OAAA,EAAS,SAAS,CAAA,EACvC,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,kBAAAC,eAAA,CAAC,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uCAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,cAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,kBAAAC,eAAA,CAAC,OAAE,IAAA,EAAM,IAAA,CAAK,GAAA,EAAK,SAAA,EAAU,yBAAA,EAC3B,QAAA,EAAA;AAAA,0BAAAD,cAAA;AAAA,YAACE,OAAA;AAAA,YAAA;AAAA,cACC,KAAK,IAAA,CAAK,GAAA;AAAA,cACV,KAAK,IAAA,CAAK,GAAA;AAAA,cACV,SAAA,EAAU,kBAAA;AAAA,cACV;AAAA;AAAA,WACF;AAAA,0BACAF,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAyB,eAAK,KAAA,EAAM;AAAA,SAAA,EACtD,CAAA,EACF,CAAA;AAAA,wBACAA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,OAAA,EAAQ;AAAA,OAAA,EACzC,CAAA;AAAA,MACC,UAAU,GAAA,CAAI,CAAC,OAAA,EAAS,UAAA,qCACtB,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,OAAA,CAAQ,KAAA,EAAM,CAAA;AAAA,wBAC9CA,cAAA,CAAC,QAAG,SAAA,EAAU,iCAAA,EACX,kBAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,OAAA,qBACxBA,cAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAU,gCAAA;AAAA,YAEV,yCAAC,GAAA,EAAA,EAAE,IAAA,EAAM,IAAA,CAAK,GAAA,EAAM,eAAK,IAAA,EAAK;AAAA,WAAA;AAAA,UAHzB;AAAA,SAKR,CAAA,EACH;AAAA,OAAA,EAAA,EAXQ,UAYV,CACD;AAAA,KAAA,EACH,CAAA;AAAA,oBACAC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+HAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0DAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,cAAA,CAAC,OAAG,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,wBACdA,cAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,qBAAA;AAAA,YACL,SAAA,EAAU,oBAAA;AAAA,YACV,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,qBAAA;AAAA,YACL,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF,CAAA;AAAA,sBACAA,cAAA,CAAC,QAAG,SAAA,EAAU,YAAA,EACX,sBAAY,GAAA,CAAI,CAAC,IAAA,EAAM,OAAA,qBACtBA,cAAA,CAAC,IAAA,EAAA,EAAiB,WAAU,8BAAA,EAC1B,QAAA,kBAAAA,cAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,IAAA,CAAK,GAAA,EAAM,eAAK,IAAA,EAAK,CAAA,EAAA,EADvB,OAET,CACD,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EACF,GACF,CAAA,EACF,CAAA;AAEJ","file":"footer-links-grid.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\n\n/**\n * Menu item structure for footer navigation sections\n */\nexport interface FooterLinksGridMenuItem {\n /** Section title */\n title: string;\n /** Links within the section */\n links: {\n text: string;\n url: string;\n }[];\n}\n\n/**\n * Props for the FooterLinksGrid component\n */\nexport interface FooterLinksGridProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Tagline displayed below the logo */\n tagline?: string;\n /** Navigation menu sections */\n menuItems?: FooterLinksGridMenuItem[];\n /** Copyright text - use {year} placeholder for dynamic year */\n copyright?: string;\n /** Bottom links (terms, privacy, etc.) */\n bottomLinks?: {\n text: string;\n url: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultMenuItems: FooterLinksGridMenuItem[] = [\n {\n title: \"Product\",\n links: [\n { text: \"Overview\", url: \"#\" },\n { text: \"Pricing\", url: \"#\" },\n { text: \"Marketplace\", url: \"#\" },\n { text: \"Features\", url: \"#\" },\n { text: \"Integrations\", url: \"#\" },\n ],\n },\n {\n title: \"Company\",\n links: [\n { text: \"About\", url: \"#\" },\n { text: \"Team\", url: \"#\" },\n { text: \"Blog\", url: \"#\" },\n { text: \"Careers\", url: \"#\" },\n { text: \"Contact\", url: \"#\" },\n ],\n },\n {\n title: \"Resources\",\n links: [\n { text: \"Help\", url: \"#\" },\n { text: \"Sales\", url: \"#\" },\n { text: \"Advertise\", url: \"#\" },\n ],\n },\n {\n title: \"Social\",\n links: [\n { text: \"Twitter\", url: \"#\" },\n { text: \"Instagram\", url: \"#\" },\n { text: \"LinkedIn\", url: \"#\" },\n ],\n },\n];\n\nconst defaultBottomLinks = [\n { text: \"Terms and Conditions\", url: \"#\" },\n { text: \"Privacy Policy\", url: \"#\" },\n];\n\n/**\n * FooterLinksGrid - A multi-column footer with logo, navigation links, and legal information.\n *\n * Features a responsive grid layout with customizable navigation sections,\n * company branding, and bottom legal links. Ideal for corporate websites,\n * SaaS products, and marketing sites that need organized footer navigation.\n */\nexport function FooterLinksGrid({\n logo = {\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n url: \"https://opensite.ai\",\n },\n className,\n tagline = \"Components made easy.\",\n menuItems = defaultMenuItems,\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n bottomLinks = defaultBottomLinks,\n optixFlowConfig,\n}: FooterLinksGridProps): React.JSX.Element {\n return (\n <section className={cn(\"py-32\", className)}>\n <div className=\"container\">\n <footer>\n <div className=\"grid grid-cols-2 gap-8 lg:grid-cols-6\">\n <div className=\"col-span-2 mb-8 lg:mb-0\">\n <div className=\"flex items-center gap-2 lg:justify-start\">\n <a href={logo.url} className=\"flex items-center gap-2\">\n <Img\n src={logo.src}\n alt={logo.alt}\n className=\"h-10 dark:invert\"\n optixFlowConfig={optixFlowConfig}\n />\n <span className=\"text-xl font-semibold\">{logo.title}</span>\n </a>\n </div>\n <p className=\"mt-4 font-bold\">{tagline}</p>\n </div>\n {menuItems.map((section, sectionIdx) => (\n <div key={sectionIdx}>\n <h3 className=\"mb-4 font-bold\">{section.title}</h3>\n <ul className=\"space-y-4 text-muted-foreground\">\n {section.links.map((link, linkIdx) => (\n <li\n key={linkIdx}\n className=\"font-medium hover:text-primary\"\n >\n <a href={link.url}>{link.text}</a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n <div className=\"mt-24 flex flex-col justify-between gap-4 border-t pt-8 text-sm font-medium text-muted-foreground md:flex-row md:items-center\">\n <div className=\"flex flex-col gap-2 md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <ul className=\"flex gap-4\">\n {bottomLinks.map((link, linkIdx) => (\n <li key={linkIdx} className=\"underline hover:text-primary\">\n <a href={link.url}>{link.text}</a>\n </li>\n ))}\n </ul>\n </div>\n </footer>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Menu item structure for footer navigation sections
|
|
5
|
+
*/
|
|
6
|
+
interface FooterLinksGridMenuItem {
|
|
7
|
+
/** Section title */
|
|
8
|
+
title: string;
|
|
9
|
+
/** Links within the section */
|
|
10
|
+
links: {
|
|
11
|
+
text: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Props for the FooterLinksGrid component
|
|
17
|
+
*/
|
|
18
|
+
interface FooterLinksGridProps {
|
|
19
|
+
/** Logo configuration */
|
|
20
|
+
logo?: {
|
|
21
|
+
url: string;
|
|
22
|
+
src: string;
|
|
23
|
+
alt: string;
|
|
24
|
+
title: string;
|
|
25
|
+
};
|
|
26
|
+
/** Additional CSS classes */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** Tagline displayed below the logo */
|
|
29
|
+
tagline?: string;
|
|
30
|
+
/** Navigation menu sections */
|
|
31
|
+
menuItems?: FooterLinksGridMenuItem[];
|
|
32
|
+
/** Copyright text - use {year} placeholder for dynamic year */
|
|
33
|
+
copyright?: string;
|
|
34
|
+
/** Bottom links (terms, privacy, etc.) */
|
|
35
|
+
bottomLinks?: {
|
|
36
|
+
text: string;
|
|
37
|
+
url: string;
|
|
38
|
+
}[];
|
|
39
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
40
|
+
optixFlowConfig?: {
|
|
41
|
+
apiKey: string;
|
|
42
|
+
compression?: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* FooterLinksGrid - A multi-column footer with logo, navigation links, and legal information.
|
|
47
|
+
*
|
|
48
|
+
* Features a responsive grid layout with customizable navigation sections,
|
|
49
|
+
* company branding, and bottom legal links. Ideal for corporate websites,
|
|
50
|
+
* SaaS products, and marketing sites that need organized footer navigation.
|
|
51
|
+
*/
|
|
52
|
+
declare function FooterLinksGrid({ logo, className, tagline, menuItems, copyright, bottomLinks, optixFlowConfig, }: FooterLinksGridProps): React.JSX.Element;
|
|
53
|
+
|
|
54
|
+
export { FooterLinksGrid, type FooterLinksGridMenuItem, type FooterLinksGridProps };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Menu item structure for footer navigation sections
|
|
5
|
+
*/
|
|
6
|
+
interface FooterLinksGridMenuItem {
|
|
7
|
+
/** Section title */
|
|
8
|
+
title: string;
|
|
9
|
+
/** Links within the section */
|
|
10
|
+
links: {
|
|
11
|
+
text: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Props for the FooterLinksGrid component
|
|
17
|
+
*/
|
|
18
|
+
interface FooterLinksGridProps {
|
|
19
|
+
/** Logo configuration */
|
|
20
|
+
logo?: {
|
|
21
|
+
url: string;
|
|
22
|
+
src: string;
|
|
23
|
+
alt: string;
|
|
24
|
+
title: string;
|
|
25
|
+
};
|
|
26
|
+
/** Additional CSS classes */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** Tagline displayed below the logo */
|
|
29
|
+
tagline?: string;
|
|
30
|
+
/** Navigation menu sections */
|
|
31
|
+
menuItems?: FooterLinksGridMenuItem[];
|
|
32
|
+
/** Copyright text - use {year} placeholder for dynamic year */
|
|
33
|
+
copyright?: string;
|
|
34
|
+
/** Bottom links (terms, privacy, etc.) */
|
|
35
|
+
bottomLinks?: {
|
|
36
|
+
text: string;
|
|
37
|
+
url: string;
|
|
38
|
+
}[];
|
|
39
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
40
|
+
optixFlowConfig?: {
|
|
41
|
+
apiKey: string;
|
|
42
|
+
compression?: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* FooterLinksGrid - A multi-column footer with logo, navigation links, and legal information.
|
|
47
|
+
*
|
|
48
|
+
* Features a responsive grid layout with customizable navigation sections,
|
|
49
|
+
* company branding, and bottom legal links. Ideal for corporate websites,
|
|
50
|
+
* SaaS products, and marketing sites that need organized footer navigation.
|
|
51
|
+
*/
|
|
52
|
+
declare function FooterLinksGrid({ logo, className, tagline, menuItems, copyright, bottomLinks, optixFlowConfig, }: FooterLinksGridProps): React.JSX.Element;
|
|
53
|
+
|
|
54
|
+
export { FooterLinksGrid, type FooterLinksGridMenuItem, type FooterLinksGridProps };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { Img } from '@page-speed/img';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// lib/utils.ts
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var defaultMenuItems = [
|
|
12
|
+
{
|
|
13
|
+
title: "Product",
|
|
14
|
+
links: [
|
|
15
|
+
{ text: "Overview", url: "#" },
|
|
16
|
+
{ text: "Pricing", url: "#" },
|
|
17
|
+
{ text: "Marketplace", url: "#" },
|
|
18
|
+
{ text: "Features", url: "#" },
|
|
19
|
+
{ text: "Integrations", url: "#" }
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
title: "Company",
|
|
24
|
+
links: [
|
|
25
|
+
{ text: "About", url: "#" },
|
|
26
|
+
{ text: "Team", url: "#" },
|
|
27
|
+
{ text: "Blog", url: "#" },
|
|
28
|
+
{ text: "Careers", url: "#" },
|
|
29
|
+
{ text: "Contact", url: "#" }
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: "Resources",
|
|
34
|
+
links: [
|
|
35
|
+
{ text: "Help", url: "#" },
|
|
36
|
+
{ text: "Sales", url: "#" },
|
|
37
|
+
{ text: "Advertise", url: "#" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: "Social",
|
|
42
|
+
links: [
|
|
43
|
+
{ text: "Twitter", url: "#" },
|
|
44
|
+
{ text: "Instagram", url: "#" },
|
|
45
|
+
{ text: "LinkedIn", url: "#" }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
var defaultBottomLinks = [
|
|
50
|
+
{ text: "Terms and Conditions", url: "#" },
|
|
51
|
+
{ text: "Privacy Policy", url: "#" }
|
|
52
|
+
];
|
|
53
|
+
function FooterLinksGrid({
|
|
54
|
+
logo = {
|
|
55
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
56
|
+
alt: "Opensite AI",
|
|
57
|
+
title: "Opensite AI",
|
|
58
|
+
url: "https://opensite.ai"
|
|
59
|
+
},
|
|
60
|
+
className,
|
|
61
|
+
tagline = "Components made easy.",
|
|
62
|
+
menuItems = defaultMenuItems,
|
|
63
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
64
|
+
bottomLinks = defaultBottomLinks,
|
|
65
|
+
optixFlowConfig
|
|
66
|
+
}) {
|
|
67
|
+
return /* @__PURE__ */ jsx("section", { className: cn("py-32", className), children: /* @__PURE__ */ jsx("div", { className: "container", children: /* @__PURE__ */ jsxs("footer", { children: [
|
|
68
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-8 lg:grid-cols-6", children: [
|
|
69
|
+
/* @__PURE__ */ jsxs("div", { className: "col-span-2 mb-8 lg:mb-0", children: [
|
|
70
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 lg:justify-start", children: /* @__PURE__ */ jsxs("a", { href: logo.url, className: "flex items-center gap-2", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
Img,
|
|
73
|
+
{
|
|
74
|
+
src: logo.src,
|
|
75
|
+
alt: logo.alt,
|
|
76
|
+
className: "h-10 dark:invert",
|
|
77
|
+
optixFlowConfig
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-semibold", children: logo.title })
|
|
81
|
+
] }) }),
|
|
82
|
+
/* @__PURE__ */ jsx("p", { className: "mt-4 font-bold", children: tagline })
|
|
83
|
+
] }),
|
|
84
|
+
menuItems.map((section, sectionIdx) => /* @__PURE__ */ jsxs("div", { children: [
|
|
85
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-4 font-bold", children: section.title }),
|
|
86
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-4 text-muted-foreground", children: section.links.map((link, linkIdx) => /* @__PURE__ */ jsx(
|
|
87
|
+
"li",
|
|
88
|
+
{
|
|
89
|
+
className: "font-medium hover:text-primary",
|
|
90
|
+
children: /* @__PURE__ */ jsx("a", { href: link.url, children: link.text })
|
|
91
|
+
},
|
|
92
|
+
linkIdx
|
|
93
|
+
)) })
|
|
94
|
+
] }, sectionIdx))
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-24 flex flex-col justify-between gap-4 border-t pt-8 text-sm font-medium text-muted-foreground md:flex-row md:items-center", children: [
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:gap-4", children: [
|
|
98
|
+
/* @__PURE__ */ jsx("p", { children: copyright }),
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
"a",
|
|
101
|
+
{
|
|
102
|
+
href: "https://opensite.ai",
|
|
103
|
+
className: "hover:text-primary",
|
|
104
|
+
target: "_blank",
|
|
105
|
+
rel: "noopener noreferrer",
|
|
106
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ jsx("ul", { className: "flex gap-4", children: bottomLinks.map((link, linkIdx) => /* @__PURE__ */ jsx("li", { className: "underline hover:text-primary", children: /* @__PURE__ */ jsx("a", { href: link.url, children: link.text }) }, linkIdx)) })
|
|
111
|
+
] })
|
|
112
|
+
] }) }) });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { FooterLinksGrid };
|
|
116
|
+
//# sourceMappingURL=footer-links-grid.js.map
|
|
117
|
+
//# sourceMappingURL=footer-links-grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/blocks/footers/footer-links-grid.tsx"],"names":[],"mappings":"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","file":"footer-links-grid.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\n\n/**\n * Menu item structure for footer navigation sections\n */\nexport interface FooterLinksGridMenuItem {\n /** Section title */\n title: string;\n /** Links within the section */\n links: {\n text: string;\n url: string;\n }[];\n}\n\n/**\n * Props for the FooterLinksGrid component\n */\nexport interface FooterLinksGridProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Tagline displayed below the logo */\n tagline?: string;\n /** Navigation menu sections */\n menuItems?: FooterLinksGridMenuItem[];\n /** Copyright text - use {year} placeholder for dynamic year */\n copyright?: string;\n /** Bottom links (terms, privacy, etc.) */\n bottomLinks?: {\n text: string;\n url: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultMenuItems: FooterLinksGridMenuItem[] = [\n {\n title: \"Product\",\n links: [\n { text: \"Overview\", url: \"#\" },\n { text: \"Pricing\", url: \"#\" },\n { text: \"Marketplace\", url: \"#\" },\n { text: \"Features\", url: \"#\" },\n { text: \"Integrations\", url: \"#\" },\n ],\n },\n {\n title: \"Company\",\n links: [\n { text: \"About\", url: \"#\" },\n { text: \"Team\", url: \"#\" },\n { text: \"Blog\", url: \"#\" },\n { text: \"Careers\", url: \"#\" },\n { text: \"Contact\", url: \"#\" },\n ],\n },\n {\n title: \"Resources\",\n links: [\n { text: \"Help\", url: \"#\" },\n { text: \"Sales\", url: \"#\" },\n { text: \"Advertise\", url: \"#\" },\n ],\n },\n {\n title: \"Social\",\n links: [\n { text: \"Twitter\", url: \"#\" },\n { text: \"Instagram\", url: \"#\" },\n { text: \"LinkedIn\", url: \"#\" },\n ],\n },\n];\n\nconst defaultBottomLinks = [\n { text: \"Terms and Conditions\", url: \"#\" },\n { text: \"Privacy Policy\", url: \"#\" },\n];\n\n/**\n * FooterLinksGrid - A multi-column footer with logo, navigation links, and legal information.\n *\n * Features a responsive grid layout with customizable navigation sections,\n * company branding, and bottom legal links. Ideal for corporate websites,\n * SaaS products, and marketing sites that need organized footer navigation.\n */\nexport function FooterLinksGrid({\n logo = {\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n url: \"https://opensite.ai\",\n },\n className,\n tagline = \"Components made easy.\",\n menuItems = defaultMenuItems,\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n bottomLinks = defaultBottomLinks,\n optixFlowConfig,\n}: FooterLinksGridProps): React.JSX.Element {\n return (\n <section className={cn(\"py-32\", className)}>\n <div className=\"container\">\n <footer>\n <div className=\"grid grid-cols-2 gap-8 lg:grid-cols-6\">\n <div className=\"col-span-2 mb-8 lg:mb-0\">\n <div className=\"flex items-center gap-2 lg:justify-start\">\n <a href={logo.url} className=\"flex items-center gap-2\">\n <Img\n src={logo.src}\n alt={logo.alt}\n className=\"h-10 dark:invert\"\n optixFlowConfig={optixFlowConfig}\n />\n <span className=\"text-xl font-semibold\">{logo.title}</span>\n </a>\n </div>\n <p className=\"mt-4 font-bold\">{tagline}</p>\n </div>\n {menuItems.map((section, sectionIdx) => (\n <div key={sectionIdx}>\n <h3 className=\"mb-4 font-bold\">{section.title}</h3>\n <ul className=\"space-y-4 text-muted-foreground\">\n {section.links.map((link, linkIdx) => (\n <li\n key={linkIdx}\n className=\"font-medium hover:text-primary\"\n >\n <a href={link.url}>{link.text}</a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n <div className=\"mt-24 flex flex-col justify-between gap-4 border-t pt-8 text-sm font-medium text-muted-foreground md:flex-row md:items-center\">\n <div className=\"flex flex-col gap-2 md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <ul className=\"flex gap-4\">\n {bottomLinks.map((link, linkIdx) => (\n <li key={linkIdx} className=\"underline hover:text-primary\">\n <a href={link.url}>{link.text}</a>\n </li>\n ))}\n </ul>\n </div>\n </footer>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var img = require('@page-speed/img');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
function _interopNamespace(e) {
|
|
11
|
+
if (e && e.__esModule) return e;
|
|
12
|
+
var n = Object.create(null);
|
|
13
|
+
if (e) {
|
|
14
|
+
Object.keys(e).forEach(function (k) {
|
|
15
|
+
if (k !== 'default') {
|
|
16
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return e[k]; }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
n.default = e;
|
|
25
|
+
return Object.freeze(n);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
29
|
+
|
|
30
|
+
// lib/utils.ts
|
|
31
|
+
function cn(...inputs) {
|
|
32
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
33
|
+
}
|
|
34
|
+
var svgCache = /* @__PURE__ */ new Map();
|
|
35
|
+
function DynamicIcon({
|
|
36
|
+
name,
|
|
37
|
+
size = 28,
|
|
38
|
+
color,
|
|
39
|
+
className,
|
|
40
|
+
alt
|
|
41
|
+
}) {
|
|
42
|
+
const [svgContent, setSvgContent] = React__namespace.useState(null);
|
|
43
|
+
const [isLoading, setIsLoading] = React__namespace.useState(true);
|
|
44
|
+
const [error, setError] = React__namespace.useState(null);
|
|
45
|
+
const { url, iconName } = React__namespace.useMemo(() => {
|
|
46
|
+
const separator = name.includes("/") ? "/" : ":";
|
|
47
|
+
const [prefix, iconName2] = name.split(separator);
|
|
48
|
+
const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
|
|
49
|
+
return {
|
|
50
|
+
url: baseUrl,
|
|
51
|
+
iconName: iconName2
|
|
52
|
+
};
|
|
53
|
+
}, [name, size]);
|
|
54
|
+
React__namespace.useEffect(() => {
|
|
55
|
+
let isMounted = true;
|
|
56
|
+
const fetchSvg = async () => {
|
|
57
|
+
const cached = svgCache.get(url);
|
|
58
|
+
if (cached) {
|
|
59
|
+
if (isMounted) {
|
|
60
|
+
setSvgContent(cached);
|
|
61
|
+
setIsLoading(false);
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
setIsLoading(true);
|
|
67
|
+
setError(null);
|
|
68
|
+
const response = await fetch(url);
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
throw new Error(`Failed to fetch icon: ${response.status}`);
|
|
71
|
+
}
|
|
72
|
+
let svg = await response.text();
|
|
73
|
+
svg = processSvgForCurrentColor(svg);
|
|
74
|
+
svgCache.set(url, svg);
|
|
75
|
+
if (isMounted) {
|
|
76
|
+
setSvgContent(svg);
|
|
77
|
+
setIsLoading(false);
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (isMounted) {
|
|
81
|
+
setError(err instanceof Error ? err.message : "Failed to load icon");
|
|
82
|
+
setIsLoading(false);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
fetchSvg();
|
|
87
|
+
return () => {
|
|
88
|
+
isMounted = false;
|
|
89
|
+
};
|
|
90
|
+
}, [url]);
|
|
91
|
+
if (isLoading) {
|
|
92
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
+
"span",
|
|
94
|
+
{
|
|
95
|
+
className: cn("inline-block", className),
|
|
96
|
+
style: { width: size, height: size },
|
|
97
|
+
"aria-hidden": "true"
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
if (error || !svgContent) {
|
|
102
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
103
|
+
"span",
|
|
104
|
+
{
|
|
105
|
+
className: cn("inline-block", className),
|
|
106
|
+
style: { width: size, height: size },
|
|
107
|
+
role: "img",
|
|
108
|
+
"aria-label": alt || iconName
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
113
|
+
"span",
|
|
114
|
+
{
|
|
115
|
+
className: cn("inline-flex items-center justify-center", className),
|
|
116
|
+
style: {
|
|
117
|
+
width: size,
|
|
118
|
+
height: size,
|
|
119
|
+
color: color || "inherit"
|
|
120
|
+
},
|
|
121
|
+
role: "img",
|
|
122
|
+
"aria-label": alt || iconName,
|
|
123
|
+
dangerouslySetInnerHTML: { __html: svgContent }
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
function processSvgForCurrentColor(svg) {
|
|
128
|
+
let processed = svg;
|
|
129
|
+
processed = processed.replace(
|
|
130
|
+
/stroke=["'](#000000|#000|black)["']/gi,
|
|
131
|
+
'stroke="currentColor"'
|
|
132
|
+
);
|
|
133
|
+
processed = processed.replace(
|
|
134
|
+
/fill=["'](#000000|#000|black)["']/gi,
|
|
135
|
+
'fill="currentColor"'
|
|
136
|
+
);
|
|
137
|
+
return processed;
|
|
138
|
+
}
|
|
139
|
+
var defaultSections = [
|
|
140
|
+
{
|
|
141
|
+
title: "Product",
|
|
142
|
+
links: [
|
|
143
|
+
{ name: "Overview", href: "#" },
|
|
144
|
+
{ name: "Pricing", href: "#" },
|
|
145
|
+
{ name: "Marketplace", href: "#" },
|
|
146
|
+
{ name: "Features", href: "#" }
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
title: "Company",
|
|
151
|
+
links: [
|
|
152
|
+
{ name: "About", href: "#" },
|
|
153
|
+
{ name: "Team", href: "#" },
|
|
154
|
+
{ name: "Blog", href: "#" },
|
|
155
|
+
{ name: "Careers", href: "#" }
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
title: "Resources",
|
|
160
|
+
links: [
|
|
161
|
+
{ name: "Help", href: "#" },
|
|
162
|
+
{ name: "Sales", href: "#" },
|
|
163
|
+
{ name: "Advertise", href: "#" }
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
];
|
|
167
|
+
var defaultSocialLinks = [
|
|
168
|
+
{ icon: "simple-icons/instagram", href: "#", label: "Instagram" },
|
|
169
|
+
{ icon: "simple-icons/facebook", href: "#", label: "Facebook" },
|
|
170
|
+
{ icon: "simple-icons/x", href: "#", label: "X (Twitter)" },
|
|
171
|
+
{ icon: "simple-icons/linkedin", href: "#", label: "LinkedIn" }
|
|
172
|
+
];
|
|
173
|
+
var defaultLegalLinks = [
|
|
174
|
+
{ name: "Terms and Conditions", href: "#" },
|
|
175
|
+
{ name: "Privacy Policy", href: "#" }
|
|
176
|
+
];
|
|
177
|
+
function FooterNavSocial({
|
|
178
|
+
logo = {
|
|
179
|
+
url: "https://opensite.ai",
|
|
180
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
181
|
+
alt: "Opensite AI",
|
|
182
|
+
title: "Opensite AI"
|
|
183
|
+
},
|
|
184
|
+
className,
|
|
185
|
+
sections = defaultSections,
|
|
186
|
+
socialLinks = defaultSocialLinks,
|
|
187
|
+
newsletterHeading = "Stay Updated",
|
|
188
|
+
newsletterDescription = "Subscribe to our newsletter for the latest updates and news.",
|
|
189
|
+
newsletterPlaceholder = "Enter your email",
|
|
190
|
+
newsletterButtonText = "Subscribe",
|
|
191
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
192
|
+
legalLinks = defaultLegalLinks,
|
|
193
|
+
optixFlowConfig
|
|
194
|
+
}) {
|
|
195
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: cn("py-32", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container", children: /* @__PURE__ */ jsxRuntime.jsxs("footer", { children: [
|
|
196
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-10 lg:grid-cols-2", children: [
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
198
|
+
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: logo.url, className: "mb-8 flex items-center gap-2", children: [
|
|
199
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
200
|
+
img.Img,
|
|
201
|
+
{
|
|
202
|
+
src: logo.src,
|
|
203
|
+
alt: logo.alt,
|
|
204
|
+
className: "h-10",
|
|
205
|
+
optixFlowConfig
|
|
206
|
+
}
|
|
207
|
+
),
|
|
208
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl font-semibold", children: logo.title })
|
|
209
|
+
] }),
|
|
210
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-8 sm:grid-cols-3", children: sections.map((section, sectionIdx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
211
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 font-semibold", children: section.title }),
|
|
212
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-3 text-sm text-muted-foreground", children: section.links.map((link, linkIdx) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.href, className: "hover:text-primary", children: link.name }) }, linkIdx)) })
|
|
213
|
+
] }, sectionIdx)) })
|
|
214
|
+
] }),
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between", children: [
|
|
216
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8", children: [
|
|
217
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 text-lg font-semibold", children: newsletterHeading }),
|
|
218
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: newsletterDescription }),
|
|
219
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-w-md gap-2", children: [
|
|
220
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
221
|
+
"input",
|
|
222
|
+
{
|
|
223
|
+
type: "email",
|
|
224
|
+
placeholder: newsletterPlaceholder,
|
|
225
|
+
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
226
|
+
}
|
|
227
|
+
),
|
|
228
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
229
|
+
"button",
|
|
230
|
+
{
|
|
231
|
+
type: "submit",
|
|
232
|
+
className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
|
|
233
|
+
children: newsletterButtonText
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
] })
|
|
237
|
+
] }),
|
|
238
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
239
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 font-medium", children: "Follow Us" }),
|
|
240
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex items-center gap-4", children: socialLinks.map((social, idx) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
241
|
+
"a",
|
|
242
|
+
{
|
|
243
|
+
href: social.href,
|
|
244
|
+
"aria-label": social.label,
|
|
245
|
+
className: "text-muted-foreground transition-colors hover:text-primary",
|
|
246
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: social.icon, size: 20 })
|
|
247
|
+
}
|
|
248
|
+
) }, idx)) })
|
|
249
|
+
] })
|
|
250
|
+
] })
|
|
251
|
+
] }),
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-16 flex flex-col justify-between gap-4 border-t pt-8 text-sm text-muted-foreground md:flex-row md:items-center", children: [
|
|
253
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:gap-4", children: [
|
|
254
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: copyright }),
|
|
255
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
256
|
+
"a",
|
|
257
|
+
{
|
|
258
|
+
href: "https://opensite.ai",
|
|
259
|
+
className: "hover:text-primary",
|
|
260
|
+
target: "_blank",
|
|
261
|
+
rel: "noopener noreferrer",
|
|
262
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
] }),
|
|
266
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex gap-4", children: legalLinks.map((link, idx) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.href, className: "hover:text-primary", children: link.name }) }, idx)) })
|
|
267
|
+
] })
|
|
268
|
+
] }) }) });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
exports.FooterNavSocial = FooterNavSocial;
|
|
272
|
+
//# sourceMappingURL=footer-nav-social.cjs.map
|
|
273
|
+
//# sourceMappingURL=footer-nav-social.cjs.map
|