@booga/vblocks 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.2] - 2026-05-18
9
+
10
+ ### Fixed
11
+
12
+ - Category `<Badge>` in BlogGrid, BlogSplit, PortfolioGrid, PortfolioSplit, PostCentered, and PostSplit stretched to a full-width bar: each sat in a flex-column `DStack` whose default `align-items: stretch` widened it. Badges now carry `self-start`, rendering as content-width chips.
13
+ - BlogGrid default content: the middle post lacked a `category`, so its card rendered without the badge the sibling cards had. All default posts now carry a category for a consistent three-card grid.
14
+
8
15
  ## [0.3.1] - 2026-05-18
9
16
 
10
17
  ### Fixed
@@ -57,7 +57,7 @@ function BlogSplit({ content, theme }) {
57
57
  }
58
58
  ),
59
59
  /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, children: [
60
- featured.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: featured.category }),
60
+ featured.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: featured.category }),
61
61
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("text-xl font-semibold"), children: featured.title }),
62
62
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", children: featured.excerpt }),
63
63
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: featured.date, color: "muted", className: vui.cn("text-xs"), children: featured.date })
@@ -74,7 +74,7 @@ function BlogSplit({ content, theme }) {
74
74
  }
75
75
  ),
76
76
  /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 1, children: [
77
- post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: post.category }),
77
+ post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: post.category }),
78
78
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold leading-snug"), children: post.title }),
79
79
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: vui.cn("text-xs"), children: post.date })
80
80
  ] })
@@ -119,7 +119,7 @@ function BlogGrid({ content, theme }) {
119
119
  }
120
120
  ),
121
121
  /* @__PURE__ */ jsxRuntime.jsx(vui.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, pt: 2, children: [
122
- post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: post.category }),
122
+ post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: post.category }),
123
123
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold leading-snug"), children: post.title }),
124
124
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", className: vui.cn("text-sm"), children: post.excerpt }),
125
125
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: vui.cn("text-xs"), children: post.date })
@@ -133,7 +133,7 @@ var BlogGridDefaultContent = {
133
133
  heading: "From the blog",
134
134
  posts: [
135
135
  { title: "Designing for composability", excerpt: "Modular thinking at scale.", date: "2026-05-01", category: "Design", image: { src: "https://placehold.co/480x320", alt: "Design post" } },
136
- { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
136
+ { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
137
137
  { title: "Tree-shaking section blocks", excerpt: "Lean bundles, per-category entry points.", date: "2026-04-05", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Bundling post" } }
138
138
  ]
139
139
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/blog/BlogSplit/schema.ts","../../src/blog/BlogSplit/index.tsx","../../src/blog/BlogSplit/default.ts","../../src/blog/BlogGrid/schema.ts","../../src/blog/BlogGrid/index.tsx","../../src/blog/BlogGrid/default.ts"],"names":["dsl","Box","Stack","Grid","Inline","z","jsxs","cn","jsx","Badge","BlogPostSchema","Card","CardContent"],"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 { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogSplitContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogSplitContent = z.infer<typeof BlogSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogSplitContentSchema, type BlogSplitContent } from \"./schema\";\n\nexport function BlogSplit({ content, theme }: BlockProps<BlogSplitContent>) {\n BlogSplitContentSchema.parse(content);\n const { heading, posts } = content;\n const [featured, ...rest] = posts;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={2} gap={8} align=\"start\">\n {featured && (\n <DBox as=\"article\">\n <DStack gap={4}>\n <DBox\n as=\"img\"\n src={featured.image.src}\n alt={featured.image.alt}\n className={cn(\"w-full rounded-lg object-cover aspect-video\")}\n />\n <DStack gap={2}>\n {featured.category && <Badge variant=\"secondary\">{featured.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"text-xl font-semibold\")}>{featured.title}</DBox>\n <DBox as=\"p\" color=\"muted\">{featured.excerpt}</DBox>\n <DBox as=\"time\" dateTime={featured.date} color=\"muted\" className={cn(\"text-xs\")}>{featured.date}</DBox>\n </DStack>\n </DStack>\n </DBox>\n )}\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {rest.map((post, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"article\">\n <DGrid columns={2} gap={4} align=\"start\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-md object-cover aspect-video\")}\n />\n <DStack gap={1}>\n {post.category && <Badge variant=\"secondary\">{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </DGrid>\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogSplitContent } from \"./schema\";\n\nexport const BlogSplitDefaultContent: BlogSplitContent = {\n heading: \"Latest posts\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"How modular thinking unlocks maintainable systems at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/600x400\", alt: \"Design systems post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod schemas as the single source of truth for block content.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/400x280\", alt: \"Type safety post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Per-category entry points and how they keep bundles lean.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/400x280\", alt: \"Tree-shaking post\" } },\n ],\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogGridContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogGridContent = z.infer<typeof BlogGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, Card, CardContent, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogGridContentSchema, type BlogGridContent } from \"./schema\";\n\nexport function BlogGrid({ content, theme }: BlockProps<BlogGridContent>) {\n BlogGridContentSchema.parse(content);\n const { heading, posts } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={3} gap={6}>\n {posts.map((post, i) => (\n <Card key={i}>\n <DBox as=\"article\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-t-lg object-cover aspect-video\")}\n />\n <CardContent>\n <DStack gap={2} pt={2}>\n {post.category && <Badge variant=\"secondary\">{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{post.excerpt}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </CardContent>\n </DBox>\n </Card>\n ))}\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogGridContent } from \"./schema\";\n\nexport const BlogGridDefaultContent: BlogGridContent = {\n heading: \"From the blog\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"Modular thinking at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/480x320\", alt: \"Design post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod as single source of truth.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/480x320\", alt: \"Types post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Lean bundles, per-category entry points.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Bundling post\" } },\n ],\n};\n"]}
1
+ {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/blog/BlogSplit/schema.ts","../../src/blog/BlogSplit/index.tsx","../../src/blog/BlogSplit/default.ts","../../src/blog/BlogGrid/schema.ts","../../src/blog/BlogGrid/index.tsx","../../src/blog/BlogGrid/default.ts"],"names":["dsl","Box","Stack","Grid","Inline","z","jsxs","cn","jsx","Badge","BlogPostSchema","Card","CardContent"],"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 { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogSplitContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogSplitContent = z.infer<typeof BlogSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogSplitContentSchema, type BlogSplitContent } from \"./schema\";\n\nexport function BlogSplit({ content, theme }: BlockProps<BlogSplitContent>) {\n BlogSplitContentSchema.parse(content);\n const { heading, posts } = content;\n const [featured, ...rest] = posts;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={2} gap={8} align=\"start\">\n {featured && (\n <DBox as=\"article\">\n <DStack gap={4}>\n <DBox\n as=\"img\"\n src={featured.image.src}\n alt={featured.image.alt}\n className={cn(\"w-full rounded-lg object-cover aspect-video\")}\n />\n <DStack gap={2}>\n {featured.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{featured.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"text-xl font-semibold\")}>{featured.title}</DBox>\n <DBox as=\"p\" color=\"muted\">{featured.excerpt}</DBox>\n <DBox as=\"time\" dateTime={featured.date} color=\"muted\" className={cn(\"text-xs\")}>{featured.date}</DBox>\n </DStack>\n </DStack>\n </DBox>\n )}\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {rest.map((post, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"article\">\n <DGrid columns={2} gap={4} align=\"start\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-md object-cover aspect-video\")}\n />\n <DStack gap={1}>\n {post.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </DGrid>\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogSplitContent } from \"./schema\";\n\nexport const BlogSplitDefaultContent: BlogSplitContent = {\n heading: \"Latest posts\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"How modular thinking unlocks maintainable systems at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/600x400\", alt: \"Design systems post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod schemas as the single source of truth for block content.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/400x280\", alt: \"Type safety post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Per-category entry points and how they keep bundles lean.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/400x280\", alt: \"Tree-shaking post\" } },\n ],\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogGridContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogGridContent = z.infer<typeof BlogGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, Card, CardContent, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogGridContentSchema, type BlogGridContent } from \"./schema\";\n\nexport function BlogGrid({ content, theme }: BlockProps<BlogGridContent>) {\n BlogGridContentSchema.parse(content);\n const { heading, posts } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={3} gap={6}>\n {posts.map((post, i) => (\n <Card key={i}>\n <DBox as=\"article\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-t-lg object-cover aspect-video\")}\n />\n <CardContent>\n <DStack gap={2} pt={2}>\n {post.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{post.excerpt}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </CardContent>\n </DBox>\n </Card>\n ))}\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogGridContent } from \"./schema\";\n\nexport const BlogGridDefaultContent: BlogGridContent = {\n heading: \"From the blog\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"Modular thinking at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/480x320\", alt: \"Design post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod as single source of truth.\", date: \"2026-04-18\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Types post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Lean bundles, per-category entry points.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Bundling post\" } },\n ],\n};\n"]}
@@ -55,7 +55,7 @@ function BlogSplit({ content, theme }) {
55
55
  }
56
56
  ),
57
57
  /* @__PURE__ */ jsxs(DStack, { gap: 2, children: [
58
- featured.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: featured.category }),
58
+ featured.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: cn("self-start"), children: featured.category }),
59
59
  /* @__PURE__ */ jsx(DBox, { as: "h3", className: cn("text-xl font-semibold"), children: featured.title }),
60
60
  /* @__PURE__ */ jsx(DBox, { as: "p", color: "muted", children: featured.excerpt }),
61
61
  /* @__PURE__ */ jsx(DBox, { as: "time", dateTime: featured.date, color: "muted", className: cn("text-xs"), children: featured.date })
@@ -72,7 +72,7 @@ function BlogSplit({ content, theme }) {
72
72
  }
73
73
  ),
74
74
  /* @__PURE__ */ jsxs(DStack, { gap: 1, children: [
75
- post.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: post.category }),
75
+ post.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: cn("self-start"), children: post.category }),
76
76
  /* @__PURE__ */ jsx(DBox, { as: "h3", className: cn("font-semibold leading-snug"), children: post.title }),
77
77
  /* @__PURE__ */ jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: cn("text-xs"), children: post.date })
78
78
  ] })
@@ -117,7 +117,7 @@ function BlogGrid({ content, theme }) {
117
117
  }
118
118
  ),
119
119
  /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(DStack, { gap: 2, pt: 2, children: [
120
- post.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: post.category }),
120
+ post.category && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: cn("self-start"), children: post.category }),
121
121
  /* @__PURE__ */ jsx(DBox, { as: "h3", className: cn("font-semibold leading-snug"), children: post.title }),
122
122
  /* @__PURE__ */ jsx(DBox, { as: "p", color: "muted", className: cn("text-sm"), children: post.excerpt }),
123
123
  /* @__PURE__ */ jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: cn("text-xs"), children: post.date })
@@ -131,7 +131,7 @@ var BlogGridDefaultContent = {
131
131
  heading: "From the blog",
132
132
  posts: [
133
133
  { title: "Designing for composability", excerpt: "Modular thinking at scale.", date: "2026-05-01", category: "Design", image: { src: "https://placehold.co/480x320", alt: "Design post" } },
134
- { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
134
+ { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
135
135
  { title: "Tree-shaking section blocks", excerpt: "Lean bundles, per-category entry points.", date: "2026-04-05", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Bundling post" } }
136
136
  ]
137
137
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/blog/BlogSplit/schema.ts","../../src/blog/BlogSplit/index.tsx","../../src/blog/BlogSplit/default.ts","../../src/blog/BlogGrid/schema.ts","../../src/blog/BlogGrid/index.tsx","../../src/blog/BlogGrid/default.ts"],"names":["z","BlogPostSchema","jsx","jsxs","cn","Badge"],"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 { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogSplitContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogSplitContent = z.infer<typeof BlogSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogSplitContentSchema, type BlogSplitContent } from \"./schema\";\n\nexport function BlogSplit({ content, theme }: BlockProps<BlogSplitContent>) {\n BlogSplitContentSchema.parse(content);\n const { heading, posts } = content;\n const [featured, ...rest] = posts;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={2} gap={8} align=\"start\">\n {featured && (\n <DBox as=\"article\">\n <DStack gap={4}>\n <DBox\n as=\"img\"\n src={featured.image.src}\n alt={featured.image.alt}\n className={cn(\"w-full rounded-lg object-cover aspect-video\")}\n />\n <DStack gap={2}>\n {featured.category && <Badge variant=\"secondary\">{featured.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"text-xl font-semibold\")}>{featured.title}</DBox>\n <DBox as=\"p\" color=\"muted\">{featured.excerpt}</DBox>\n <DBox as=\"time\" dateTime={featured.date} color=\"muted\" className={cn(\"text-xs\")}>{featured.date}</DBox>\n </DStack>\n </DStack>\n </DBox>\n )}\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {rest.map((post, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"article\">\n <DGrid columns={2} gap={4} align=\"start\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-md object-cover aspect-video\")}\n />\n <DStack gap={1}>\n {post.category && <Badge variant=\"secondary\">{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </DGrid>\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogSplitContent } from \"./schema\";\n\nexport const BlogSplitDefaultContent: BlogSplitContent = {\n heading: \"Latest posts\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"How modular thinking unlocks maintainable systems at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/600x400\", alt: \"Design systems post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod schemas as the single source of truth for block content.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/400x280\", alt: \"Type safety post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Per-category entry points and how they keep bundles lean.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/400x280\", alt: \"Tree-shaking post\" } },\n ],\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogGridContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogGridContent = z.infer<typeof BlogGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, Card, CardContent, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogGridContentSchema, type BlogGridContent } from \"./schema\";\n\nexport function BlogGrid({ content, theme }: BlockProps<BlogGridContent>) {\n BlogGridContentSchema.parse(content);\n const { heading, posts } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={3} gap={6}>\n {posts.map((post, i) => (\n <Card key={i}>\n <DBox as=\"article\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-t-lg object-cover aspect-video\")}\n />\n <CardContent>\n <DStack gap={2} pt={2}>\n {post.category && <Badge variant=\"secondary\">{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{post.excerpt}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </CardContent>\n </DBox>\n </Card>\n ))}\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogGridContent } from \"./schema\";\n\nexport const BlogGridDefaultContent: BlogGridContent = {\n heading: \"From the blog\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"Modular thinking at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/480x320\", alt: \"Design post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod as single source of truth.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/480x320\", alt: \"Types post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Lean bundles, per-category entry points.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Bundling post\" } },\n ],\n};\n"]}
1
+ {"version":3,"sources":["../../src/primitives.ts","../../src/theme.ts","../../src/shared/schemas.ts","../../src/blog/BlogSplit/schema.ts","../../src/blog/BlogSplit/index.tsx","../../src/blog/BlogSplit/default.ts","../../src/blog/BlogGrid/schema.ts","../../src/blog/BlogGrid/index.tsx","../../src/blog/BlogGrid/default.ts"],"names":["z","BlogPostSchema","jsx","jsxs","cn","Badge"],"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 { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogSplitContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogSplitContent = z.infer<typeof BlogSplitContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogSplitContentSchema, type BlogSplitContent } from \"./schema\";\n\nexport function BlogSplit({ content, theme }: BlockProps<BlogSplitContent>) {\n BlogSplitContentSchema.parse(content);\n const { heading, posts } = content;\n const [featured, ...rest] = posts;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={2} gap={8} align=\"start\">\n {featured && (\n <DBox as=\"article\">\n <DStack gap={4}>\n <DBox\n as=\"img\"\n src={featured.image.src}\n alt={featured.image.alt}\n className={cn(\"w-full rounded-lg object-cover aspect-video\")}\n />\n <DStack gap={2}>\n {featured.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{featured.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"text-xl font-semibold\")}>{featured.title}</DBox>\n <DBox as=\"p\" color=\"muted\">{featured.excerpt}</DBox>\n <DBox as=\"time\" dateTime={featured.date} color=\"muted\" className={cn(\"text-xs\")}>{featured.date}</DBox>\n </DStack>\n </DStack>\n </DBox>\n )}\n <DBox as=\"ul\" m={0} p={0} gap={6} display=\"flex\" className={cn(\"list-none flex-col\")}>\n {rest.map((post, i) => (\n <DBox as=\"li\" key={i}>\n <DBox as=\"article\">\n <DGrid columns={2} gap={4} align=\"start\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-md object-cover aspect-video\")}\n />\n <DStack gap={1}>\n {post.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </DGrid>\n </DBox>\n </DBox>\n ))}\n </DBox>\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogSplitContent } from \"./schema\";\n\nexport const BlogSplitDefaultContent: BlogSplitContent = {\n heading: \"Latest posts\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"How modular thinking unlocks maintainable systems at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/600x400\", alt: \"Design systems post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod schemas as the single source of truth for block content.\", date: \"2026-04-18\", image: { src: \"https://placehold.co/400x280\", alt: \"Type safety post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Per-category entry points and how they keep bundles lean.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/400x280\", alt: \"Tree-shaking post\" } },\n ],\n};\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { z } from \"zod\";\nimport { ImageSchema } from \"../../shared/schemas\";\n\nconst BlogPostSchema = z.object({\n title: z.string(),\n excerpt: z.string(),\n date: z.string(),\n category: z.string().optional(),\n image: ImageSchema,\n}).strict();\n\nexport const BlogGridContentSchema = z.object({\n heading: z.string(),\n posts: z.array(BlogPostSchema).min(1),\n}).strict();\n\nexport type BlogGridContent = z.infer<typeof BlogGridContentSchema>;\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { Badge, Card, CardContent, cn } from \"@booga/vui\";\nimport { DBox, DGrid, DStack } from \"../../primitives\";\nimport { type BlockProps } from \"../../types\";\nimport { themeStyle } from \"../../theme\";\nimport { BlogGridContentSchema, type BlogGridContent } from \"./schema\";\n\nexport function BlogGrid({ content, theme }: BlockProps<BlogGridContent>) {\n BlogGridContentSchema.parse(content);\n const { heading, posts } = content;\n return (\n <DBox as=\"section\" aria-label={heading} style={themeStyle(theme)}>\n <DStack px={6} py={16} className={cn(\"max-w-6xl mx-auto gap-10\")}>\n <DBox as=\"h2\" className={cn(\"text-3xl font-bold tracking-tight\")}>{heading}</DBox>\n <DGrid columns={3} gap={6}>\n {posts.map((post, i) => (\n <Card key={i}>\n <DBox as=\"article\">\n <DBox\n as=\"img\"\n src={post.image.src}\n alt={post.image.alt}\n className={cn(\"w-full rounded-t-lg object-cover aspect-video\")}\n />\n <CardContent>\n <DStack gap={2} pt={2}>\n {post.category && <Badge variant=\"secondary\" className={cn(\"self-start\")}>{post.category}</Badge>}\n <DBox as=\"h3\" className={cn(\"font-semibold leading-snug\")}>{post.title}</DBox>\n <DBox as=\"p\" color=\"muted\" className={cn(\"text-sm\")}>{post.excerpt}</DBox>\n <DBox as=\"time\" dateTime={post.date} color=\"muted\" className={cn(\"text-xs\")}>{post.date}</DBox>\n </DStack>\n </CardContent>\n </DBox>\n </Card>\n ))}\n </DGrid>\n </DStack>\n </DBox>\n );\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 bvasilenko\nimport { type BlogGridContent } from \"./schema\";\n\nexport const BlogGridDefaultContent: BlogGridContent = {\n heading: \"From the blog\",\n posts: [\n { title: \"Designing for composability\", excerpt: \"Modular thinking at scale.\", date: \"2026-05-01\", category: \"Design\", image: { src: \"https://placehold.co/480x320\", alt: \"Design post\" } },\n { title: \"Type-safe content at runtime\", excerpt: \"Zod as single source of truth.\", date: \"2026-04-18\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Types post\" } },\n { title: \"Tree-shaking section blocks\", excerpt: \"Lean bundles, per-category entry points.\", date: \"2026-04-05\", category: \"Engineering\", image: { src: \"https://placehold.co/480x320\", alt: \"Bundling post\" } },\n ],\n};\n"]}
package/dist/index.cjs CHANGED
@@ -406,7 +406,7 @@ function PortfolioSplit({ content, theme }) {
406
406
  }
407
407
  ),
408
408
  /* @__PURE__ */ jsxRuntime.jsx(vui.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, pt: 2, children: [
409
- /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: item.category }),
409
+ /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: item.category }),
410
410
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold text-lg"), children: item.title })
411
411
  ] }) })
412
412
  ] }, i)) })
@@ -445,7 +445,7 @@ function PortfolioGrid({ content, theme }) {
445
445
  }
446
446
  ),
447
447
  /* @__PURE__ */ jsxRuntime.jsx(vui.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, pt: 2, children: [
448
- /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: item.category }),
448
+ /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: item.category }),
449
449
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold text-lg"), children: item.title })
450
450
  ] }) })
451
451
  ] }, i)) }) });
@@ -473,7 +473,7 @@ function PostSplit({ content, theme }) {
473
473
  const { title, author, date, category, body, image } = content;
474
474
  return /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "article", style: themeStyle(theme), children: /* @__PURE__ */ jsxRuntime.jsxs(DGrid, { columns: 2, px: 6, py: 16, gap: 16, align: "start", className: vui.cn("max-w-6xl mx-auto"), children: [
475
475
  /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 6, className: vui.cn("sticky top-16"), children: [
476
- category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: category }),
476
+ category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: category }),
477
477
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h1", className: vui.cn("text-3xl font-bold tracking-tight leading-snug"), children: title }),
478
478
  /* @__PURE__ */ jsxRuntime.jsx(vui.Separator, {}),
479
479
  /* @__PURE__ */ jsxRuntime.jsxs(DInline, { gap: 2, color: "muted", className: vui.cn("text-sm"), children: [
@@ -517,7 +517,7 @@ function PostCentered({ content, theme }) {
517
517
  PostCenteredContentSchema.parse(content);
518
518
  const { title, author, date, category, body } = content;
519
519
  return /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "article", style: themeStyle(theme), children: /* @__PURE__ */ jsxRuntime.jsxs(DStack, { px: 6, py: 16, gap: 6, className: vui.cn("max-w-2xl mx-auto"), children: [
520
- category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: category }),
520
+ category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: category }),
521
521
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h1", className: vui.cn("text-4xl font-bold tracking-tight leading-snug"), children: title }),
522
522
  /* @__PURE__ */ jsxRuntime.jsxs(DInline, { gap: 2, color: "muted", className: vui.cn("text-sm"), children: [
523
523
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "span", children: author }),
@@ -736,7 +736,7 @@ function BlogSplit({ content, theme }) {
736
736
  }
737
737
  ),
738
738
  /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, children: [
739
- featured.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: featured.category }),
739
+ featured.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: featured.category }),
740
740
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("text-xl font-semibold"), children: featured.title }),
741
741
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", children: featured.excerpt }),
742
742
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: featured.date, color: "muted", className: vui.cn("text-xs"), children: featured.date })
@@ -753,7 +753,7 @@ function BlogSplit({ content, theme }) {
753
753
  }
754
754
  ),
755
755
  /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 1, children: [
756
- post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: post.category }),
756
+ post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: post.category }),
757
757
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold leading-snug"), children: post.title }),
758
758
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: vui.cn("text-xs"), children: post.date })
759
759
  ] })
@@ -798,7 +798,7 @@ function BlogGrid({ content, theme }) {
798
798
  }
799
799
  ),
800
800
  /* @__PURE__ */ jsxRuntime.jsx(vui.CardContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(DStack, { gap: 2, pt: 2, children: [
801
- post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", children: post.category }),
801
+ post.category && /* @__PURE__ */ jsxRuntime.jsx(vui.Badge, { variant: "secondary", className: vui.cn("self-start"), children: post.category }),
802
802
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "h3", className: vui.cn("font-semibold leading-snug"), children: post.title }),
803
803
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "p", color: "muted", className: vui.cn("text-sm"), children: post.excerpt }),
804
804
  /* @__PURE__ */ jsxRuntime.jsx(DBox, { as: "time", dateTime: post.date, color: "muted", className: vui.cn("text-xs"), children: post.date })
@@ -812,7 +812,7 @@ var BlogGridDefaultContent = {
812
812
  heading: "From the blog",
813
813
  posts: [
814
814
  { title: "Designing for composability", excerpt: "Modular thinking at scale.", date: "2026-05-01", category: "Design", image: { src: "https://placehold.co/480x320", alt: "Design post" } },
815
- { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
815
+ { title: "Type-safe content at runtime", excerpt: "Zod as single source of truth.", date: "2026-04-18", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Types post" } },
816
816
  { title: "Tree-shaking section blocks", excerpt: "Lean bundles, per-category entry points.", date: "2026-04-05", category: "Engineering", image: { src: "https://placehold.co/480x320", alt: "Bundling post" } }
817
817
  ]
818
818
  };