@booga/vblocks 0.1.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 (84) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +83 -0
  4. package/dist/blog/index.cjs +148 -0
  5. package/dist/blog/index.cjs.map +1 -0
  6. package/dist/blog/index.d.cts +140 -0
  7. package/dist/blog/index.d.ts +140 -0
  8. package/dist/blog/index.js +141 -0
  9. package/dist/blog/index.js.map +1 -0
  10. package/dist/business/index.cjs +121 -0
  11. package/dist/business/index.cjs.map +1 -0
  12. package/dist/business/index.d.cts +102 -0
  13. package/dist/business/index.d.ts +102 -0
  14. package/dist/business/index.js +114 -0
  15. package/dist/business/index.js.map +1 -0
  16. package/dist/cta/index.cjs +99 -0
  17. package/dist/cta/index.cjs.map +1 -0
  18. package/dist/cta/index.d.cts +110 -0
  19. package/dist/cta/index.d.ts +110 -0
  20. package/dist/cta/index.js +92 -0
  21. package/dist/cta/index.js.map +1 -0
  22. package/dist/faq/index.cjs +93 -0
  23. package/dist/faq/index.cjs.map +1 -0
  24. package/dist/faq/index.d.cts +71 -0
  25. package/dist/faq/index.d.ts +71 -0
  26. package/dist/faq/index.js +86 -0
  27. package/dist/faq/index.js.map +1 -0
  28. package/dist/features/index.cjs +104 -0
  29. package/dist/features/index.cjs.map +1 -0
  30. package/dist/features/index.d.cts +81 -0
  31. package/dist/features/index.d.ts +81 -0
  32. package/dist/features/index.js +97 -0
  33. package/dist/features/index.js.map +1 -0
  34. package/dist/footer/index.cjs +117 -0
  35. package/dist/footer/index.cjs.map +1 -0
  36. package/dist/footer/index.d.cts +107 -0
  37. package/dist/footer/index.d.ts +107 -0
  38. package/dist/footer/index.js +110 -0
  39. package/dist/footer/index.js.map +1 -0
  40. package/dist/gallery/index.cjs +106 -0
  41. package/dist/gallery/index.cjs.map +1 -0
  42. package/dist/gallery/index.d.cts +78 -0
  43. package/dist/gallery/index.d.ts +78 -0
  44. package/dist/gallery/index.js +99 -0
  45. package/dist/gallery/index.js.map +1 -0
  46. package/dist/hero/index.cjs +108 -0
  47. package/dist/hero/index.cjs.map +1 -0
  48. package/dist/hero/index.d.cts +134 -0
  49. package/dist/hero/index.d.ts +134 -0
  50. package/dist/hero/index.js +101 -0
  51. package/dist/hero/index.js.map +1 -0
  52. package/dist/index.cjs +1079 -0
  53. package/dist/index.cjs.map +1 -0
  54. package/dist/index.d.cts +22 -0
  55. package/dist/index.d.ts +22 -0
  56. package/dist/index.js +1005 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/portfolio/index.cjs +122 -0
  59. package/dist/portfolio/index.cjs.map +1 -0
  60. package/dist/portfolio/index.d.cts +120 -0
  61. package/dist/portfolio/index.d.ts +120 -0
  62. package/dist/portfolio/index.js +115 -0
  63. package/dist/portfolio/index.js.map +1 -0
  64. package/dist/post/index.cjs +116 -0
  65. package/dist/post/index.cjs.map +1 -0
  66. package/dist/post/index.d.cts +74 -0
  67. package/dist/post/index.d.ts +74 -0
  68. package/dist/post/index.js +109 -0
  69. package/dist/post/index.js.map +1 -0
  70. package/dist/team/index.cjs +120 -0
  71. package/dist/team/index.cjs.map +1 -0
  72. package/dist/team/index.d.cts +128 -0
  73. package/dist/team/index.d.ts +128 -0
  74. package/dist/team/index.js +113 -0
  75. package/dist/team/index.js.map +1 -0
  76. package/dist/testimonial/index.cjs +130 -0
  77. package/dist/testimonial/index.cjs.map +1 -0
  78. package/dist/testimonial/index.d.cts +113 -0
  79. package/dist/testimonial/index.d.ts +113 -0
  80. package/dist/testimonial/index.js +123 -0
  81. package/dist/testimonial/index.js.map +1 -0
  82. package/dist/types-n6w6cZmP.d.cts +16 -0
  83. package/dist/types-n6w6cZmP.d.ts +16 -0
  84. package/package.json +126 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/features/FeaturesSplit/schema.ts","../../src/features/FeaturesSplit/index.tsx","../../src/features/FeaturesSplit/default.ts","../../src/features/FeaturesGrid/schema.ts","../../src/features/FeaturesGrid/index.tsx","../../src/features/FeaturesGrid/default.ts"],"names":["FeatureItemSchema","z","jsx","jsxs","cn"],"mappings":"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","file":"index.js","sourcesContent":["// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type ElementType } from \"react\";\nimport { dsl } from \"@booga/vdsl\";\nimport { Box, Stack, Grid, Inline } from \"@booga/vui\";\n\n// PolymorphicComponent is not structurally assignable to ElementType; dsl() uses\n// createElement() at runtime which accepts any callable, so the bridge is safe.\nexport const DBox = dsl(Box as unknown as ElementType);\nexport const DStack = dsl(Stack as unknown as ElementType);\nexport const DGrid = dsl(Grid as unknown as ElementType);\nexport const DInline = dsl(Inline as unknown as ElementType);\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type CSSProperties } from \"react\";\nimport { type ThemeOverride } from \"./types\";\n\nexport function themeStyle(theme: ThemeOverride | undefined): CSSProperties | undefined {\n if (!theme) return undefined;\n return Object.fromEntries(\n Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])\n ) as CSSProperties;\n}\n\nexport function clampedGridCols(n: number): 1 | 2 | 3 | 4 | 5 | 6 {\n return Math.max(1, Math.min(6, Math.round(n))) as 1 | 2 | 3 | 4 | 5 | 6;\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\n\nconst FeatureItemSchema = z.object({\n title: z.string(),\n description: z.string(),\n icon: z.string().optional(),\n}).strict();\n\nexport const FeaturesSplitContentSchema = z.object({\n heading: z.string(),\n description: z.string().optional(),\n features: z.array(FeatureItemSchema).min(1),\n}).strict();\n\nexport type FeaturesSplitContent = z.infer<typeof FeaturesSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { cn } from \"@booga/vui\";\nimport { DBox, DGrid, DInline, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { FeaturesSplitContentSchema, type FeaturesSplitContent } from \"./schema\";\n\nexport function FeaturesSplit({ content, theme }: BlockProps<FeaturesSplitContent>) {\n FeaturesSplitContentSchema.parse(content);\n const { heading, description, features } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DGrid columns={2} px={6} py={16} gap={16} align=\"start\" className={cn(\"max-w-6xl mx-auto\")}>\n <DStack gap={4} className={cn(\"sticky top-16\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n {description && (\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-lg\")}>{description}</DBox>\n )}\n </DStack>\n <DBox as=\"ul\" m={0} p={0} gap={8} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {features.map((feature, i) => (\n <DBox as=\"li\" key={i}>\n <DInline gap={4} align=\"start\">\n {feature.icon && (\n <DBox as=\"span\" className={cn(\"text-xl flex-shrink-0 mt-0.5\")} aria-hidden=\"true\">\n {feature.icon}\n </DBox>\n )}\n <DStack gap={1}>\n <DBox as=\"h3\" className={cn(\"font-semibold\")}>{feature.title}</DBox>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{feature.description}</DBox>\n </DStack>\n </DInline>\n </DBox>\n ))}\n </DBox>\n </DGrid>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FeaturesSplitContent } from \"./schema\";\n\nexport const FeaturesSplitDefaultContent: FeaturesSplitContent = {\n heading: \"Everything you need\",\n description: \"A complete toolkit for building composable, schema-validated interfaces.\",\n features: [\n { title: \"Schema validation\", description: \"Every block validates content at runtime. Bad data fails fast, before it reaches the DOM.\", icon: \"✓\" },\n { title: \"Tree-shaking\", description: \"Per-category entry points keep bundles lean. Import only what the page uses.\", icon: \"⚡\" },\n { title: \"Accessibility first\", description: \"Semantic HTML, ARIA landmarks, and proper heading hierarchy — no patching required.\", icon: \"♿\" },\n { title: \"Theme overrides\", description: \"Remap CSS custom properties per block without touching global styles.\", icon: \"🎨\" },\n ],\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\n\nconst FeatureItemSchema = z.object({\n title: z.string(),\n description: z.string(),\n icon: z.string().optional(),\n}).strict();\n\nexport const FeaturesGridContentSchema = z.object({\n heading: z.string(),\n features: z.array(FeatureItemSchema).min(1),\n}).strict();\n\nexport type FeaturesGridContent = z.infer<typeof FeaturesGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Card, CardContent, CardHeader, CardTitle, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { FeaturesGridContentSchema, type FeaturesGridContent } from \"./schema\";\n\nexport function FeaturesGrid({ content, theme }: BlockProps<FeaturesGridContent>) {\n FeaturesGridContentSchema.parse(content);\n const { heading, features } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-5xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight text-center\")}>{heading}</DBox>\n <DGrid columns={3} gap={6}>\n {features.map((feature, i) => (\n <Card key={i}>\n <CardHeader>\n <DStack gap={2}>\n {feature.icon && (\n <DBox as=\"span\" className={cn(\"text-xl\")} aria-hidden=\"true\">{feature.icon}</DBox>\n )}\n <CardTitle as=\"h3\">{feature.title}</CardTitle>\n </DStack>\n </CardHeader>\n <CardContent>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{feature.description}</DBox>\n </CardContent>\n </Card>\n ))}\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FeaturesGridContent } from \"./schema\";\n\nexport const FeaturesGridDefaultContent: FeaturesGridContent = {\n heading: \"Built-in capabilities\",\n features: [\n { title: \"Schema validation\", description: \"Content validated at runtime via Zod.\", icon: \"✓\" },\n { title: \"Tree-shaking\", description: \"Per-category entry points, lean bundles.\", icon: \"⚡\" },\n { title: \"Accessibility\", description: \"Semantic HTML and ARIA by default.\", icon: \"♿\" },\n { title: \"Theme overrides\", description: \"CSS custom properties per block.\", icon: \"🎨\" },\n { title: \"TypeScript\", description: \"All schemas export their inferred types.\", icon: \"🔷\" },\n { title: \"Zero config\", description: \"Drop in. Pass content. Done.\", icon: \"▶️\" },\n ],\n};\n"]}
@@ -0,0 +1,117 @@
1
+ 'use strict';
2
+
3
+ var vui = require('@booga/vui');
4
+ var vdsl = require('@booga/vdsl');
5
+ var zod = require('zod');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/footer/FooterSplit/index.tsx
9
+ var DBox = vdsl.dsl(vui.Box);
10
+ var DStack = vdsl.dsl(vui.Stack);
11
+ var DGrid = vdsl.dsl(vui.Grid);
12
+ vdsl.dsl(vui.Inline);
13
+
14
+ // src/theme.ts
15
+ function themeStyle(theme) {
16
+ if (!theme) return void 0;
17
+ return Object.fromEntries(
18
+ Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])
19
+ );
20
+ }
21
+ function clampedGridCols(n) {
22
+ return Math.max(1, Math.min(6, Math.round(n)));
23
+ }
24
+ var CtaSchema = zod.z.object({
25
+ label: zod.z.string(),
26
+ href: zod.z.string()
27
+ }).strict();
28
+ zod.z.object({
29
+ src: zod.z.string(),
30
+ alt: zod.z.string()
31
+ }).strict();
32
+
33
+ // src/footer/FooterSplit/schema.ts
34
+ var BrandSchema = zod.z.object({
35
+ name: zod.z.string(),
36
+ tagline: zod.z.string().optional()
37
+ }).strict();
38
+ var FooterSplitContentSchema = zod.z.object({
39
+ brand: BrandSchema,
40
+ links: zod.z.array(CtaSchema).min(1),
41
+ copyright: zod.z.string()
42
+ }).strict();
43
+ function FooterSplit({ content, theme }) {
44
+ FooterSplitContentSchema.parse(content);
45
+ const { brand, links, copyright } = content;
46
+ return /* @__PURE__ */ jsxRuntime.jsxs(DBox, { as: "footer", style: themeStyle(theme), children: [
47
+ /* @__PURE__ */ jsxRuntime.jsxs(DGrid, { columns: 2, px: 6, py: 12, gap: 8, align: "start", className: vui.cn("max-w-6xl mx-auto"), children: [
48
+ /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, children: [
49
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", className: vui.cn("font-bold text-lg"), children: brand.name }),
50
+ brand.tagline && /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", className: vui.cn("text-sm"), children: brand.tagline })
51
+ ] }),
52
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "nav", "aria-label": "Footer navigation", children: /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "ul", m: 0, p: 0, gap: 6, display: "flex", className: vui.cn("list-none flex-wrap"), children: links.map((link, i) => /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "li", children: /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "a", href: link.href, className: vui.cn("text-sm hover:underline"), children: link.label }) }, i)) }) })
53
+ ] }),
54
+ /* @__PURE__ */ jsxRuntime.jsx(vui.Separator, {}),
55
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { px: 6, py: 4, className: vui.cn("max-w-6xl mx-auto"), children: /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", className: vui.cn("text-xs text-center"), children: copyright }) })
56
+ ] });
57
+ }
58
+
59
+ // src/footer/FooterSplit/default.ts
60
+ var FooterSplitDefaultContent = {
61
+ brand: { name: "Acme", tagline: "Build things that matter." },
62
+ links: [
63
+ { label: "Privacy", href: "#" },
64
+ { label: "Terms", href: "#" },
65
+ { label: "Contact", href: "#" }
66
+ ],
67
+ copyright: "\xA9 2026 Acme. All rights reserved."
68
+ };
69
+ var FooterColumnSchema = zod.z.object({
70
+ heading: zod.z.string(),
71
+ links: zod.z.array(CtaSchema).min(1)
72
+ }).strict();
73
+ var FooterGridContentSchema = zod.z.object({
74
+ columns: zod.z.array(FooterColumnSchema).min(1).max(6),
75
+ copyright: zod.z.string()
76
+ }).strict();
77
+ function FooterGrid({ content, theme }) {
78
+ FooterGridContentSchema.parse(content);
79
+ const { columns, copyright } = content;
80
+ return /* @__PURE__ */ jsxRuntime.jsxs(DBox, { as: "footer", style: themeStyle(theme), children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(
82
+ DGrid,
83
+ {
84
+ columns: clampedGridCols(columns.length),
85
+ px: 6,
86
+ py: 12,
87
+ gap: 8,
88
+ className: vui.cn("max-w-6xl mx-auto"),
89
+ children: columns.map((col, i) => /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 4, children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold text-sm uppercase tracking-widest"), children: col.heading }),
91
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "ul", m: 0, p: 0, gap: 2, display: "flex", className: vui.cn("list-none flex-col"), children: col.links.map((link, j) => /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "li", children: /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "a", href: link.href, color: "muted", className: vui.cn("text-sm hover:underline"), children: link.label }) }, j)) })
92
+ ] }, i))
93
+ }
94
+ ),
95
+ /* @__PURE__ */ jsxRuntime.jsx(vui.Separator, {}),
96
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { px: 6, py: 4, className: vui.cn("max-w-6xl mx-auto"), children: /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", className: vui.cn("text-xs text-center"), children: copyright }) })
97
+ ] });
98
+ }
99
+
100
+ // src/footer/FooterGrid/default.ts
101
+ var FooterGridDefaultContent = {
102
+ columns: [
103
+ { heading: "Product", links: [{ label: "Features", href: "#" }, { label: "Pricing", href: "#" }] },
104
+ { heading: "Company", links: [{ label: "About", href: "#" }, { label: "Blog", href: "#" }] },
105
+ { heading: "Legal", links: [{ label: "Privacy", href: "#" }, { label: "Terms", href: "#" }] }
106
+ ],
107
+ copyright: "\xA9 2026 Acme. All rights reserved."
108
+ };
109
+
110
+ exports.FooterGrid = FooterGrid;
111
+ exports.FooterGridContentSchema = FooterGridContentSchema;
112
+ exports.FooterGridDefaultContent = FooterGridDefaultContent;
113
+ exports.FooterSplit = FooterSplit;
114
+ exports.FooterSplitContentSchema = FooterSplitContentSchema;
115
+ exports.FooterSplitDefaultContent = FooterSplitDefaultContent;
116
+ //# sourceMappingURL=index.cjs.map
117
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/footer/FooterSplit/schema.ts","../../src/footer/FooterSplit/index.tsx","../../src/footer/FooterSplit/default.ts","../../src/footer/FooterGrid/schema.ts","../../src/footer/FooterGrid/index.tsx","../../src/footer/FooterGrid/default.ts"],"names":["dsl","Box","Stack","Grid","Inline","z","jsxs","cn","jsx","Separator"],"mappings":"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","file":"index.cjs","sourcesContent":["// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type ElementType } from \"react\";\nimport { dsl } from \"@booga/vdsl\";\nimport { Box, Stack, Grid, Inline } from \"@booga/vui\";\n\n// PolymorphicComponent is not structurally assignable to ElementType; dsl() uses\n// createElement() at runtime which accepts any callable, so the bridge is safe.\nexport const DBox = dsl(Box as unknown as ElementType);\nexport const DStack = dsl(Stack as unknown as ElementType);\nexport const DGrid = dsl(Grid as unknown as ElementType);\nexport const DInline = dsl(Inline as unknown as ElementType);\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type CSSProperties } from \"react\";\nimport { type ThemeOverride } from \"./types\";\n\nexport function themeStyle(theme: ThemeOverride | undefined): CSSProperties | undefined {\n if (!theme) return undefined;\n return Object.fromEntries(\n Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])\n ) as CSSProperties;\n}\n\nexport function clampedGridCols(n: number): 1 | 2 | 3 | 4 | 5 | 6 {\n return Math.max(1, Math.min(6, Math.round(n))) as 1 | 2 | 3 | 4 | 5 | 6;\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\n\nexport const CtaSchema = z.object({\n label: z.string(),\n href: z.string(),\n}).strict();\n\nexport const ImageSchema = z.object({\n src: z.string(),\n alt: z.string(),\n}).strict();\n\nexport const AvatarSchema = ImageSchema;\n\nexport type Cta = z.infer<typeof CtaSchema>;\nexport type Image = z.infer<typeof ImageSchema>;\nexport type AvatarSrc = Image;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { CtaSchema } from \"../../shared/schemas\";\n\nconst BrandSchema = z.object({\n name: z.string(),\n tagline: z.string().optional(),\n}).strict();\n\nexport const FooterSplitContentSchema = z.object({\n brand: BrandSchema,\n links: z.array(CtaSchema).min(1),\n copyright: z.string(),\n}).strict();\n\nexport type FooterSplitContent = z.infer<typeof FooterSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Separator, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { FooterSplitContentSchema, type FooterSplitContent } from \"./schema\";\n\nexport function FooterSplit({ content, theme }: BlockProps<FooterSplitContent>) {\n FooterSplitContentSchema.parse(content);\n const { brand, links, copyright } = content;\n return (\n <DBox as=\"footer\" style={themeStyle(theme)}>\n <DGrid columns={2} px={6} py={12} gap={8} align=\"start\" className={cn(\"max-w-6xl mx-auto\")}>\n <DStack gap={2}>\n <DBox as=\"p\" className={cn(\"font-bold text-lg\")}>{brand.name}</DBox>\n {brand.tagline && (\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{brand.tagline}</DBox>\n )}\n </DStack>\n <DBox as=\"nav\" aria-label=\"Footer navigation\">\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-wrap\")}>\n {links.map((link, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"a\" href={link.href} className={cn(\"text-sm hover:underline\")}>\n {link.label}\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DBox>\n </DGrid>\n <Separator />\n <DBox px={6} py={4} className={cn(\"max-w-6xl mx-auto\")}>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-xs text-center\")}>{copyright}</DBox>\n </DBox>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FooterSplitContent } from \"./schema\";\n\nexport const FooterSplitDefaultContent: FooterSplitContent = {\n brand: { name: \"Acme\", tagline: \"Build things that matter.\" },\n links: [\n { label: \"Privacy\", href: \"#\" },\n { label: \"Terms\", href: \"#\" },\n { label: \"Contact\", href: \"#\" },\n ],\n copyright: \"© 2026 Acme. All rights reserved.\",\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { CtaSchema } from \"../../shared/schemas\";\n\nconst FooterColumnSchema = z.object({\n heading: z.string(),\n links: z.array(CtaSchema).min(1),\n}).strict();\n\nexport const FooterGridContentSchema = z.object({\n columns: z.array(FooterColumnSchema).min(1).max(6),\n copyright: z.string(),\n}).strict();\n\nexport type FooterGridContent = z.infer<typeof FooterGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Separator, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle, clampedGridCols } from \"../../theme\";\nimport { FooterGridContentSchema, type FooterGridContent } from \"./schema\";\n\nexport function FooterGrid({ content, theme }: BlockProps<FooterGridContent>) {\n FooterGridContentSchema.parse(content);\n const { columns, copyright } = content;\n return (\n <DBox as=\"footer\" style={themeStyle(theme)}>\n <DGrid\n columns={clampedGridCols(columns.length)}\n px={6} py={12} gap={8}\n className={cn(\"max-w-6xl mx-auto\")}\n >\n {columns.map((col, i) => (\n <DStack key={i} gap={4}>\n <DBox as=\"h3\" className={cn(\"font-semibold text-sm uppercase tracking-widest\")}>\n {col.heading}\n </DBox>\n <DBox as=\"ul\" m={0} p={0} gap={2} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {col.links.map((link, j) => (\n <DBox as=\"li\" key={j}>\n <DBox as=\"a\" href={link.href} color=\"muted\" className={cn(\"text-sm hover:underline\")}>\n {link.label}\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DStack>\n ))}\n </DGrid>\n <Separator />\n <DBox px={6} py={4} className={cn(\"max-w-6xl mx-auto\")}>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-xs text-center\")}>{copyright}</DBox>\n </DBox>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FooterGridContent } from \"./schema\";\n\nexport const FooterGridDefaultContent: FooterGridContent = {\n columns: [\n { heading: \"Product\", links: [{ label: \"Features\", href: \"#\" }, { label: \"Pricing\", href: \"#\" }] },\n { heading: \"Company\", links: [{ label: \"About\", href: \"#\" }, { label: \"Blog\", href: \"#\" }] },\n { heading: \"Legal\", links: [{ label: \"Privacy\", href: \"#\" }, { label: \"Terms\", href: \"#\" }] },\n ],\n copyright: \"© 2026 Acme. All rights reserved.\",\n};\n"]}
@@ -0,0 +1,107 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { a as BlockProps } from '../types-n6w6cZmP.cjs';
3
+ import { z } from 'zod';
4
+ import 'react';
5
+
6
+ declare const FooterSplitContentSchema: z.ZodObject<{
7
+ brand: z.ZodObject<{
8
+ name: z.ZodString;
9
+ tagline: z.ZodOptional<z.ZodString>;
10
+ }, "strict", z.ZodTypeAny, {
11
+ name: string;
12
+ tagline?: string | undefined;
13
+ }, {
14
+ name: string;
15
+ tagline?: string | undefined;
16
+ }>;
17
+ links: z.ZodArray<z.ZodObject<{
18
+ label: z.ZodString;
19
+ href: z.ZodString;
20
+ }, "strict", z.ZodTypeAny, {
21
+ label: string;
22
+ href: string;
23
+ }, {
24
+ label: string;
25
+ href: string;
26
+ }>, "many">;
27
+ copyright: z.ZodString;
28
+ }, "strict", z.ZodTypeAny, {
29
+ brand: {
30
+ name: string;
31
+ tagline?: string | undefined;
32
+ };
33
+ links: {
34
+ label: string;
35
+ href: string;
36
+ }[];
37
+ copyright: string;
38
+ }, {
39
+ brand: {
40
+ name: string;
41
+ tagline?: string | undefined;
42
+ };
43
+ links: {
44
+ label: string;
45
+ href: string;
46
+ }[];
47
+ copyright: string;
48
+ }>;
49
+ type FooterSplitContent = z.infer<typeof FooterSplitContentSchema>;
50
+
51
+ declare function FooterSplit({ content, theme }: BlockProps<FooterSplitContent>): react_jsx_runtime.JSX.Element;
52
+
53
+ declare const FooterSplitDefaultContent: FooterSplitContent;
54
+
55
+ declare const FooterGridContentSchema: z.ZodObject<{
56
+ columns: z.ZodArray<z.ZodObject<{
57
+ heading: z.ZodString;
58
+ links: z.ZodArray<z.ZodObject<{
59
+ label: z.ZodString;
60
+ href: z.ZodString;
61
+ }, "strict", z.ZodTypeAny, {
62
+ label: string;
63
+ href: string;
64
+ }, {
65
+ label: string;
66
+ href: string;
67
+ }>, "many">;
68
+ }, "strict", z.ZodTypeAny, {
69
+ heading: string;
70
+ links: {
71
+ label: string;
72
+ href: string;
73
+ }[];
74
+ }, {
75
+ heading: string;
76
+ links: {
77
+ label: string;
78
+ href: string;
79
+ }[];
80
+ }>, "many">;
81
+ copyright: z.ZodString;
82
+ }, "strict", z.ZodTypeAny, {
83
+ columns: {
84
+ heading: string;
85
+ links: {
86
+ label: string;
87
+ href: string;
88
+ }[];
89
+ }[];
90
+ copyright: string;
91
+ }, {
92
+ columns: {
93
+ heading: string;
94
+ links: {
95
+ label: string;
96
+ href: string;
97
+ }[];
98
+ }[];
99
+ copyright: string;
100
+ }>;
101
+ type FooterGridContent = z.infer<typeof FooterGridContentSchema>;
102
+
103
+ declare function FooterGrid({ content, theme }: BlockProps<FooterGridContent>): react_jsx_runtime.JSX.Element;
104
+
105
+ declare const FooterGridDefaultContent: FooterGridContent;
106
+
107
+ export { FooterGrid, type FooterGridContent, FooterGridContentSchema, FooterGridDefaultContent, FooterSplit, type FooterSplitContent, FooterSplitContentSchema, FooterSplitDefaultContent };
@@ -0,0 +1,107 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { a as BlockProps } from '../types-n6w6cZmP.js';
3
+ import { z } from 'zod';
4
+ import 'react';
5
+
6
+ declare const FooterSplitContentSchema: z.ZodObject<{
7
+ brand: z.ZodObject<{
8
+ name: z.ZodString;
9
+ tagline: z.ZodOptional<z.ZodString>;
10
+ }, "strict", z.ZodTypeAny, {
11
+ name: string;
12
+ tagline?: string | undefined;
13
+ }, {
14
+ name: string;
15
+ tagline?: string | undefined;
16
+ }>;
17
+ links: z.ZodArray<z.ZodObject<{
18
+ label: z.ZodString;
19
+ href: z.ZodString;
20
+ }, "strict", z.ZodTypeAny, {
21
+ label: string;
22
+ href: string;
23
+ }, {
24
+ label: string;
25
+ href: string;
26
+ }>, "many">;
27
+ copyright: z.ZodString;
28
+ }, "strict", z.ZodTypeAny, {
29
+ brand: {
30
+ name: string;
31
+ tagline?: string | undefined;
32
+ };
33
+ links: {
34
+ label: string;
35
+ href: string;
36
+ }[];
37
+ copyright: string;
38
+ }, {
39
+ brand: {
40
+ name: string;
41
+ tagline?: string | undefined;
42
+ };
43
+ links: {
44
+ label: string;
45
+ href: string;
46
+ }[];
47
+ copyright: string;
48
+ }>;
49
+ type FooterSplitContent = z.infer<typeof FooterSplitContentSchema>;
50
+
51
+ declare function FooterSplit({ content, theme }: BlockProps<FooterSplitContent>): react_jsx_runtime.JSX.Element;
52
+
53
+ declare const FooterSplitDefaultContent: FooterSplitContent;
54
+
55
+ declare const FooterGridContentSchema: z.ZodObject<{
56
+ columns: z.ZodArray<z.ZodObject<{
57
+ heading: z.ZodString;
58
+ links: z.ZodArray<z.ZodObject<{
59
+ label: z.ZodString;
60
+ href: z.ZodString;
61
+ }, "strict", z.ZodTypeAny, {
62
+ label: string;
63
+ href: string;
64
+ }, {
65
+ label: string;
66
+ href: string;
67
+ }>, "many">;
68
+ }, "strict", z.ZodTypeAny, {
69
+ heading: string;
70
+ links: {
71
+ label: string;
72
+ href: string;
73
+ }[];
74
+ }, {
75
+ heading: string;
76
+ links: {
77
+ label: string;
78
+ href: string;
79
+ }[];
80
+ }>, "many">;
81
+ copyright: z.ZodString;
82
+ }, "strict", z.ZodTypeAny, {
83
+ columns: {
84
+ heading: string;
85
+ links: {
86
+ label: string;
87
+ href: string;
88
+ }[];
89
+ }[];
90
+ copyright: string;
91
+ }, {
92
+ columns: {
93
+ heading: string;
94
+ links: {
95
+ label: string;
96
+ href: string;
97
+ }[];
98
+ }[];
99
+ copyright: string;
100
+ }>;
101
+ type FooterGridContent = z.infer<typeof FooterGridContentSchema>;
102
+
103
+ declare function FooterGrid({ content, theme }: BlockProps<FooterGridContent>): react_jsx_runtime.JSX.Element;
104
+
105
+ declare const FooterGridDefaultContent: FooterGridContent;
106
+
107
+ export { FooterGrid, type FooterGridContent, FooterGridContentSchema, FooterGridDefaultContent, FooterSplit, type FooterSplitContent, FooterSplitContentSchema, FooterSplitDefaultContent };
@@ -0,0 +1,110 @@
1
+ import { Box, Stack, Grid, Inline, cn, Separator } from '@booga/vui';
2
+ import { dsl } from '@booga/vdsl';
3
+ import { z } from 'zod';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/footer/FooterSplit/index.tsx
7
+ var DBox = dsl(Box);
8
+ var DStack = dsl(Stack);
9
+ var DGrid = dsl(Grid);
10
+ dsl(Inline);
11
+
12
+ // src/theme.ts
13
+ function themeStyle(theme) {
14
+ if (!theme) return void 0;
15
+ return Object.fromEntries(
16
+ Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])
17
+ );
18
+ }
19
+ function clampedGridCols(n) {
20
+ return Math.max(1, Math.min(6, Math.round(n)));
21
+ }
22
+ var CtaSchema = z.object({
23
+ label: z.string(),
24
+ href: z.string()
25
+ }).strict();
26
+ z.object({
27
+ src: z.string(),
28
+ alt: z.string()
29
+ }).strict();
30
+
31
+ // src/footer/FooterSplit/schema.ts
32
+ var BrandSchema = z.object({
33
+ name: z.string(),
34
+ tagline: z.string().optional()
35
+ }).strict();
36
+ var FooterSplitContentSchema = z.object({
37
+ brand: BrandSchema,
38
+ links: z.array(CtaSchema).min(1),
39
+ copyright: z.string()
40
+ }).strict();
41
+ function FooterSplit({ content, theme }) {
42
+ FooterSplitContentSchema.parse(content);
43
+ const { brand, links, copyright } = content;
44
+ return /* @__PURE__ */ jsxs(DBox, { as: "footer", style: themeStyle(theme), children: [
45
+ /* @__PURE__ */ jsxs(DGrid, { columns: 2, px: 6, py: 12, gap: 8, align: "start", className: cn("max-w-6xl mx-auto"), children: [
46
+ /* @__PURE__ */ jsxs(DStack, { gap: 2, children: [
47
+ /* @__PURE__ */ jsx(DBox, { as: "p", className: cn("font-bold text-lg"), children: brand.name }),
48
+ brand.tagline && /* @__PURE__ */ jsx(DBox, { as: "p", color: "muted", className: cn("text-sm"), children: brand.tagline })
49
+ ] }),
50
+ /* @__PURE__ */ jsx(DBox, { as: "nav", "aria-label": "Footer navigation", children: /* @__PURE__ */ jsx(DBox, { as: "ul", m: 0, p: 0, gap: 6, display: "flex", className: cn("list-none flex-wrap"), children: links.map((link, i) => /* @__PURE__ */ jsx(DBox, { as: "li", children: /* @__PURE__ */ jsx(DBox, { as: "a", href: link.href, className: cn("text-sm hover:underline"), children: link.label }) }, i)) }) })
51
+ ] }),
52
+ /* @__PURE__ */ jsx(Separator, {}),
53
+ /* @__PURE__ */ jsx(DBox, { px: 6, py: 4, className: cn("max-w-6xl mx-auto"), children: /* @__PURE__ */ jsx(DBox, { as: "p", color: "muted", className: cn("text-xs text-center"), children: copyright }) })
54
+ ] });
55
+ }
56
+
57
+ // src/footer/FooterSplit/default.ts
58
+ var FooterSplitDefaultContent = {
59
+ brand: { name: "Acme", tagline: "Build things that matter." },
60
+ links: [
61
+ { label: "Privacy", href: "#" },
62
+ { label: "Terms", href: "#" },
63
+ { label: "Contact", href: "#" }
64
+ ],
65
+ copyright: "\xA9 2026 Acme. All rights reserved."
66
+ };
67
+ var FooterColumnSchema = z.object({
68
+ heading: z.string(),
69
+ links: z.array(CtaSchema).min(1)
70
+ }).strict();
71
+ var FooterGridContentSchema = z.object({
72
+ columns: z.array(FooterColumnSchema).min(1).max(6),
73
+ copyright: z.string()
74
+ }).strict();
75
+ function FooterGrid({ content, theme }) {
76
+ FooterGridContentSchema.parse(content);
77
+ const { columns, copyright } = content;
78
+ return /* @__PURE__ */ jsxs(DBox, { as: "footer", style: themeStyle(theme), children: [
79
+ /* @__PURE__ */ jsx(
80
+ DGrid,
81
+ {
82
+ columns: clampedGridCols(columns.length),
83
+ px: 6,
84
+ py: 12,
85
+ gap: 8,
86
+ className: cn("max-w-6xl mx-auto"),
87
+ children: columns.map((col, i) => /* @__PURE__ */ jsxs(DStack, { gap: 4, children: [
88
+ /* @__PURE__ */ jsx(DBox, { as: "h3", className: cn("font-semibold text-sm uppercase tracking-widest"), children: col.heading }),
89
+ /* @__PURE__ */ jsx(DBox, { as: "ul", m: 0, p: 0, gap: 2, display: "flex", className: cn("list-none flex-col"), children: col.links.map((link, j) => /* @__PURE__ */ jsx(DBox, { as: "li", children: /* @__PURE__ */ jsx(DBox, { as: "a", href: link.href, color: "muted", className: cn("text-sm hover:underline"), children: link.label }) }, j)) })
90
+ ] }, i))
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(Separator, {}),
94
+ /* @__PURE__ */ jsx(DBox, { px: 6, py: 4, className: cn("max-w-6xl mx-auto"), children: /* @__PURE__ */ jsx(DBox, { as: "p", color: "muted", className: cn("text-xs text-center"), children: copyright }) })
95
+ ] });
96
+ }
97
+
98
+ // src/footer/FooterGrid/default.ts
99
+ var FooterGridDefaultContent = {
100
+ columns: [
101
+ { heading: "Product", links: [{ label: "Features", href: "#" }, { label: "Pricing", href: "#" }] },
102
+ { heading: "Company", links: [{ label: "About", href: "#" }, { label: "Blog", href: "#" }] },
103
+ { heading: "Legal", links: [{ label: "Privacy", href: "#" }, { label: "Terms", href: "#" }] }
104
+ ],
105
+ copyright: "\xA9 2026 Acme. All rights reserved."
106
+ };
107
+
108
+ export { FooterGrid, FooterGridContentSchema, FooterGridDefaultContent, FooterSplit, FooterSplitContentSchema, FooterSplitDefaultContent };
109
+ //# sourceMappingURL=index.js.map
110
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/footer/FooterSplit/schema.ts","../../src/footer/FooterSplit/index.tsx","../../src/footer/FooterSplit/default.ts","../../src/footer/FooterGrid/schema.ts","../../src/footer/FooterGrid/index.tsx","../../src/footer/FooterGrid/default.ts"],"names":["z","jsxs","jsx","cn","Separator"],"mappings":"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","file":"index.js","sourcesContent":["// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type ElementType } from \"react\";\nimport { dsl } from \"@booga/vdsl\";\nimport { Box, Stack, Grid, Inline } from \"@booga/vui\";\n\n// PolymorphicComponent is not structurally assignable to ElementType; dsl() uses\n// createElement() at runtime which accepts any callable, so the bridge is safe.\nexport const DBox = dsl(Box as unknown as ElementType);\nexport const DStack = dsl(Stack as unknown as ElementType);\nexport const DGrid = dsl(Grid as unknown as ElementType);\nexport const DInline = dsl(Inline as unknown as ElementType);\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type CSSProperties } from \"react\";\nimport { type ThemeOverride } from \"./types\";\n\nexport function themeStyle(theme: ThemeOverride | undefined): CSSProperties | undefined {\n if (!theme) return undefined;\n return Object.fromEntries(\n Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])\n ) as CSSProperties;\n}\n\nexport function clampedGridCols(n: number): 1 | 2 | 3 | 4 | 5 | 6 {\n return Math.max(1, Math.min(6, Math.round(n))) as 1 | 2 | 3 | 4 | 5 | 6;\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\n\nexport const CtaSchema = z.object({\n label: z.string(),\n href: z.string(),\n}).strict();\n\nexport const ImageSchema = z.object({\n src: z.string(),\n alt: z.string(),\n}).strict();\n\nexport const AvatarSchema = ImageSchema;\n\nexport type Cta = z.infer<typeof CtaSchema>;\nexport type Image = z.infer<typeof ImageSchema>;\nexport type AvatarSrc = Image;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { CtaSchema } from \"../../shared/schemas\";\n\nconst BrandSchema = z.object({\n name: z.string(),\n tagline: z.string().optional(),\n}).strict();\n\nexport const FooterSplitContentSchema = z.object({\n brand: BrandSchema,\n links: z.array(CtaSchema).min(1),\n copyright: z.string(),\n}).strict();\n\nexport type FooterSplitContent = z.infer<typeof FooterSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Separator, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { FooterSplitContentSchema, type FooterSplitContent } from \"./schema\";\n\nexport function FooterSplit({ content, theme }: BlockProps<FooterSplitContent>) {\n FooterSplitContentSchema.parse(content);\n const { brand, links, copyright } = content;\n return (\n <DBox as=\"footer\" style={themeStyle(theme)}>\n <DGrid columns={2} px={6} py={12} gap={8} align=\"start\" className={cn(\"max-w-6xl mx-auto\")}>\n <DStack gap={2}>\n <DBox as=\"p\" className={cn(\"font-bold text-lg\")}>{brand.name}</DBox>\n {brand.tagline && (\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{brand.tagline}</DBox>\n )}\n </DStack>\n <DBox as=\"nav\" aria-label=\"Footer navigation\">\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-wrap\")}>\n {links.map((link, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"a\" href={link.href} className={cn(\"text-sm hover:underline\")}>\n {link.label}\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DBox>\n </DGrid>\n <Separator />\n <DBox px={6} py={4} className={cn(\"max-w-6xl mx-auto\")}>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-xs text-center\")}>{copyright}</DBox>\n </DBox>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FooterSplitContent } from \"./schema\";\n\nexport const FooterSplitDefaultContent: FooterSplitContent = {\n brand: { name: \"Acme\", tagline: \"Build things that matter.\" },\n links: [\n { label: \"Privacy\", href: \"#\" },\n { label: \"Terms\", href: \"#\" },\n { label: \"Contact\", href: \"#\" },\n ],\n copyright: \"© 2026 Acme. All rights reserved.\",\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { CtaSchema } from \"../../shared/schemas\";\n\nconst FooterColumnSchema = z.object({\n heading: z.string(),\n links: z.array(CtaSchema).min(1),\n}).strict();\n\nexport const FooterGridContentSchema = z.object({\n columns: z.array(FooterColumnSchema).min(1).max(6),\n copyright: z.string(),\n}).strict();\n\nexport type FooterGridContent = z.infer<typeof FooterGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Separator, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle, clampedGridCols } from \"../../theme\";\nimport { FooterGridContentSchema, type FooterGridContent } from \"./schema\";\n\nexport function FooterGrid({ content, theme }: BlockProps<FooterGridContent>) {\n FooterGridContentSchema.parse(content);\n const { columns, copyright } = content;\n return (\n <DBox as=\"footer\" style={themeStyle(theme)}>\n <DGrid\n columns={clampedGridCols(columns.length)}\n px={6} py={12} gap={8}\n className={cn(\"max-w-6xl mx-auto\")}\n >\n {columns.map((col, i) => (\n <DStack key={i} gap={4}>\n <DBox as=\"h3\" className={cn(\"font-semibold text-sm uppercase tracking-widest\")}>\n {col.heading}\n </DBox>\n <DBox as=\"ul\" m={0} p={0} gap={2} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {col.links.map((link, j) => (\n <DBox as=\"li\" key={j}>\n <DBox as=\"a\" href={link.href} color=\"muted\" className={cn(\"text-sm hover:underline\")}>\n {link.label}\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DStack>\n ))}\n </DGrid>\n <Separator />\n <DBox px={6} py={4} className={cn(\"max-w-6xl mx-auto\")}>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-xs text-center\")}>{copyright}</DBox>\n </DBox>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type FooterGridContent } from \"./schema\";\n\nexport const FooterGridDefaultContent: FooterGridContent = {\n columns: [\n { heading: \"Product\", links: [{ label: \"Features\", href: \"#\" }, { label: \"Pricing\", href: \"#\" }] },\n { heading: \"Company\", links: [{ label: \"About\", href: \"#\" }, { label: \"Blog\", href: \"#\" }] },\n { heading: \"Legal\", links: [{ label: \"Privacy\", href: \"#\" }, { label: \"Terms\", href: \"#\" }] },\n ],\n copyright: \"© 2026 Acme. All rights reserved.\",\n};\n"]}
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ var vui = require('@booga/vui');
4
+ var vdsl = require('@booga/vdsl');
5
+ var zod = require('zod');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/gallery/GallerySplit/index.tsx
9
+ var DBox = vdsl.dsl(vui.Box);
10
+ var DStack = vdsl.dsl(vui.Stack);
11
+ var DGrid = vdsl.dsl(vui.Grid);
12
+ vdsl.dsl(vui.Inline);
13
+
14
+ // src/theme.ts
15
+ function themeStyle(theme) {
16
+ if (!theme) return void 0;
17
+ return Object.fromEntries(
18
+ Object.entries(theme).map(([k, v]) => [`--v-${k}`, v])
19
+ );
20
+ }
21
+ var GalleryItemSchema = zod.z.object({
22
+ src: zod.z.string(),
23
+ alt: zod.z.string(),
24
+ caption: zod.z.string().optional()
25
+ }).strict();
26
+ var GallerySplitContentSchema = zod.z.object({
27
+ heading: zod.z.string(),
28
+ description: zod.z.string().optional(),
29
+ items: zod.z.array(GalleryItemSchema).min(1)
30
+ }).strict();
31
+ function GallerySplit({ content, theme }) {
32
+ GallerySplitContentSchema.parse(content);
33
+ const { heading, description, items } = content;
34
+ return /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "section", "aria-label": heading, style: themeStyle(theme), children: /* @__PURE__ */ jsxRuntime.jsxs(DGrid, { columns: 2, px: 6, py: 16, gap: 12, align: "start", className: vui.cn("max-w-6xl mx-auto"), children: [
35
+ /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 4, className: vui.cn("sticky top-16"), children: [
36
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h2", className: vui.cn("text-3xl font-bold tracking-tight"), children: heading }),
37
+ description && /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", children: description })
38
+ ] }),
39
+ /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "ul", m: 0, p: 0, gap: 4, display: "grid", className: vui.cn("list-none grid-cols-2"), children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "li", children: /* @__PURE__ */ jsxRuntime.jsxs(DBox, { as: "figure", m: 0, children: [
40
+ /* @__PURE__ */ jsxRuntime.jsx(
41
+ DBox,
42
+ {
43
+ as: "img",
44
+ src: item.src,
45
+ alt: item.alt,
46
+ className: vui.cn("w-full rounded-lg object-cover aspect-square")
47
+ }
48
+ ),
49
+ item.caption && /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "figcaption", color: "muted", mt: 1, className: vui.cn("text-xs"), children: item.caption })
50
+ ] }) }, i)) })
51
+ ] }) });
52
+ }
53
+
54
+ // src/gallery/GallerySplit/default.ts
55
+ var GallerySplitDefaultContent = {
56
+ heading: "Our work",
57
+ description: "A selection of recent projects.",
58
+ items: [
59
+ { src: "https://placehold.co/400x300", alt: "Project one" },
60
+ { src: "https://placehold.co/400x300", alt: "Project two" },
61
+ { src: "https://placehold.co/400x300", alt: "Project three", caption: "Featured project" }
62
+ ]
63
+ };
64
+ var GalleryItemSchema2 = zod.z.object({
65
+ src: zod.z.string(),
66
+ alt: zod.z.string(),
67
+ caption: zod.z.string().optional()
68
+ }).strict();
69
+ var GalleryGridContentSchema = zod.z.object({
70
+ items: zod.z.array(GalleryItemSchema2).min(1)
71
+ }).strict();
72
+ function GalleryGrid({ content, theme }) {
73
+ GalleryGridContentSchema.parse(content);
74
+ const { items } = content;
75
+ return /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "section", "aria-label": "Gallery", style: themeStyle(theme), children: /* @__PURE__ */ jsxRuntime.jsx(DGrid, { columns: 3, px: 6, py: 12, gap: 4, className: vui.cn("max-w-6xl mx-auto"), children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(DBox, { as: "figure", m: 0, children: [
76
+ /* @__PURE__ */ jsxRuntime.jsx(
77
+ DBox,
78
+ {
79
+ as: "img",
80
+ src: item.src,
81
+ alt: item.alt,
82
+ className: vui.cn("w-full rounded-lg object-cover aspect-square")
83
+ }
84
+ ),
85
+ item.caption && /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "figcaption", color: "muted", mt: 1, className: vui.cn("text-xs"), children: item.caption })
86
+ ] }, i)) }) });
87
+ }
88
+
89
+ // src/gallery/GalleryGrid/default.ts
90
+ var GalleryGridDefaultContent = {
91
+ items: [
92
+ { src: "https://placehold.co/400x400", alt: "Gallery image one" },
93
+ { src: "https://placehold.co/400x400", alt: "Gallery image two" },
94
+ { src: "https://placehold.co/400x400", alt: "Gallery image three" },
95
+ { src: "https://placehold.co/400x400", alt: "Gallery image four", caption: "Featured" }
96
+ ]
97
+ };
98
+
99
+ exports.GalleryGrid = GalleryGrid;
100
+ exports.GalleryGridContentSchema = GalleryGridContentSchema;
101
+ exports.GalleryGridDefaultContent = GalleryGridDefaultContent;
102
+ exports.GallerySplit = GallerySplit;
103
+ exports.GallerySplitContentSchema = GallerySplitContentSchema;
104
+ exports.GallerySplitDefaultContent = GallerySplitDefaultContent;
105
+ //# sourceMappingURL=index.cjs.map
106
+ //# sourceMappingURL=index.cjs.map