From 304282808b75ba413917aa99fb634d2f1fe1a93d Mon Sep 17 00:00:00 2001 From: Hirotaka Mizutani <52546+hirotaka@users.noreply.github.com> Date: Sat, 27 Jun 2026 23:33:22 +0900 Subject: [PATCH] feat(registry): Add blog post grid block --- app/components/demo/BlogPostGridDemo.vue | 61 +++++ .../blocks/blog-post-grid/BlogPostGrid.vue | 217 ++++++++++++++++++ app/registry/blocks/blog-post-grid/index.ts | 1 + .../docs/2.components/16.blog-post-grid.md | 111 +++++++++ scripts/registry-verify.ts | 4 + 5 files changed, 394 insertions(+) create mode 100644 app/components/demo/BlogPostGridDemo.vue create mode 100644 app/registry/blocks/blog-post-grid/BlogPostGrid.vue create mode 100644 app/registry/blocks/blog-post-grid/index.ts create mode 100644 content/docs/2.components/16.blog-post-grid.md diff --git a/app/components/demo/BlogPostGridDemo.vue b/app/components/demo/BlogPostGridDemo.vue new file mode 100644 index 0000000..91e365a --- /dev/null +++ b/app/components/demo/BlogPostGridDemo.vue @@ -0,0 +1,61 @@ + + + diff --git a/app/registry/blocks/blog-post-grid/BlogPostGrid.vue b/app/registry/blocks/blog-post-grid/BlogPostGrid.vue new file mode 100644 index 0000000..4892050 --- /dev/null +++ b/app/registry/blocks/blog-post-grid/BlogPostGrid.vue @@ -0,0 +1,217 @@ + + + diff --git a/app/registry/blocks/blog-post-grid/index.ts b/app/registry/blocks/blog-post-grid/index.ts new file mode 100644 index 0000000..1103ebc --- /dev/null +++ b/app/registry/blocks/blog-post-grid/index.ts @@ -0,0 +1 @@ +export { default as BlogPostGrid, type BlogPostGridAuthor, type BlogPostGridImage, type BlogPostGridPost, type BlogPostGridProps } from "./BlogPostGrid.vue"; diff --git a/content/docs/2.components/16.blog-post-grid.md b/content/docs/2.components/16.blog-post-grid.md new file mode 100644 index 0000000..14952d2 --- /dev/null +++ b/content/docs/2.components/16.blog-post-grid.md @@ -0,0 +1,111 @@ +--- +title: BlogPostGrid +description: Render responsive blog and content teaser grids from display-ready post data. +category: content +--- + +::component-preview +--- +name: BlogPostGridDemo +--- +:: + +## Installation + +```bash +npx shadcn-vue@latest add "https://ui.stackhacker.io/r/blog-post-grid.json" +``` + +## Usage + +```vue + + + +``` + +## App-Owned Post Data + +`BlogPostGrid` renders display-ready data. Your app owns fetching, sorting, slicing, localization, date formatting, route construction, image policy, and analytics. + +Pass formatted strings such as `Apr 23, 2026` through `dateLabel`. The component does not call `new Date()`, generate routes from slugs, import global post data, or install icon/button/avatar dependencies. + +Use `to` for internal Nuxt routes and `href` for external links. For `target="_blank"`, the component adds `rel="noopener noreferrer"` unless you provide a custom `rel` value. + +## Examples + +### Featured first post + +::component-preview +--- +name: BlogPostGridDemo +--- +:: + +## API Reference + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `title` | `string` | — | Optional section title. | +| `description` | `string` | — | Optional supporting section copy. | +| `posts` | `BlogPostGridPost[] \| null` | `[]` | Display-ready post data supplied by your app. | +| `featuredFirst` | `boolean` | `true` | Feature the first card on medium and larger screens. | +| `class` | `string` | — | Additional CSS classes for the section. | + +### Types + +```ts +interface BlogPostGridImage { + src: string + alt?: string +} + +interface BlogPostGridAuthor { + name: string + avatar?: BlogPostGridImage +} + +interface BlogPostGridPost { + id?: string + to?: string + href?: string + target?: HTMLAnchorElement['target'] + rel?: string + title: string + description?: string + dateLabel?: string + badge?: string + readTime?: string + image?: BlogPostGridImage + authors?: BlogPostGridAuthor[] +} +``` diff --git a/scripts/registry-verify.ts b/scripts/registry-verify.ts index 8a3a26d..37a49ca 100644 --- a/scripts/registry-verify.ts +++ b/scripts/registry-verify.ts @@ -143,6 +143,10 @@ const expectedItems: Record = { dependencies: [], registryDependencies: ["accordion", "tabs"], }, + "blog-post-grid": { + dependencies: [], + registryDependencies: [], + }, }; if (registryIndex) {