npm package: @mezzanine-stack/astro-renderer
Description: Mezzanine Platform の Astro 描画層 headless component 群。 `@mezzanine-stack/content-schema` の `MezzFolderCollection` / `MezzField` を props として受け取り、コンテンツを描画する。
Latest version: 0.1.0

# @mezzanine-stack/astro-renderer

Mezzanine Platform の Astro 描画層 headless component 群。
`@mezzanine-stack/content-schema` の `MezzFolderCollection` / `MezzField` を props として受け取り、コンテンツを描画する。

## 設計方針

- **props 駆動**: app 固有ファイル (`config-generated.js`, `template-utils.js` など) への相対 import を持たない。
- **schema 正本**: フィールド定義は `@mezzanine-stack/content-schema` の DSL 型 (`MezzField`) が正本。カスタム fieldType 文字列は使わない。
- **headless**: 標準的な HTML 要素と CSS クラスを出力するが、スタイルの責務はホスト app の CSS に委ねる。

## 公開 API

| コンポーネント | 用途 |
|---|---|
| `CollectionList.astro` | folder collection の一覧をページネーション付きで表示 |
| `InfiniteCollectionList.astro` | IntersectionObserver による無限スクロール一覧 |
| `CollectionTemplate.astro` | コレクションエントリの詳細表示（フィールド順序制御 + slot） |
| `FieldRenderer.astro` | `MezzField` 型ごとの描画分岐 |
| `WorkCard.astro` | `works` コレクション専用カード |
| `Hero.astro` | サイトトップ用 hero セクション |

## CollectionList.astro

```astro
---
import CollectionList from "@mezzanine-stack/astro-renderer/CollectionList.astro";
---

<!-- 単一コレクション -->
<CollectionList
  name="blog"
  dateFieldMap={{ blog: "pubDate" }}
  maxItems={5}
/>

<!-- 複数コレクションを一括表示 -->
<CollectionList
  collectionNames={["works", "blog", "gallery"]}
  dateFieldMap={{ works: "date", blog: "pubDate", gallery: "date" }}
  maxItems={3}
/>
```

### Props

| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
| `name` | `string` | — | 単一コレクション名。`collectionNames` と排他 |
| `collectionNames` | `string[]` | `[]` | 複数コレクション名。`name` が優先される |
| `dateFieldMap` | `Record<string, string>` | `{}` | コレクション名 → 日付フィールド名のマップ |
| `maxItems` | `number` | — | コレクションあたりの最大表示件数 |
| `sortOrder` | `'asc' \| 'desc'` | `'desc'` | 日付ソート順 |
| `page` | `number` | `1` | ページ番号 (1 始まり) |
| `perPage` | `number` | — | 1 ページあたりの件数（設定するとページネーション有効） |
| `showMoreLink` | `boolean` | `true` | maxItems 超過時の「もっと見る」リンク表示 |

## InfiniteCollectionList.astro

```astro
<InfiniteCollectionList name="blog" dateField="pubDate" batchSize={10} />
```

### Props

| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
| `name` | `string` | — | コレクション名 (必須) |
| `dateField` | `string` | `'date'` | 日付フィールド名 |
| `batchSize` | `number` | `10` | 一度に追加読み込みする件数 |
| `sortOrder` | `'asc' \| 'desc'` | `'desc'` | 日付ソート順 |

## CollectionTemplate.astro

```astro
---
import { getCollection } from "astro:content";
import { blogCollection } from "@mezzanine-stack/content-schema";
import CollectionTemplate from "@mezzanine-stack/astro-renderer/CollectionTemplate.astro";

const entry = ...; // getCollection から取得した entry
const { Content } = await entry.render();
---

<CollectionTemplate content={entry} collection={blogCollection} collectionName="blog">
  <Content />
</CollectionTemplate>
```

### Props

| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
| `content` | `CollectionEntry` | — | Astro content collection entry (必須) |
| `collection` | `MezzFolderCollection` | — | スキーマ定義。フィールド表示順序に使用 |
| `collectionName` | `string` | — | 一覧ページへの戻りリンクに使用 |

## FieldRenderer.astro

```astro
---
import type { MezzField } from "@mezzanine-stack/content-schema";
import FieldRenderer from "@mezzanine-stack/astro-renderer/FieldRenderer.astro";

const field: MezzField = { type: "date", name: "pubDate", label: "公開日" };
const value = new Date("2026-01-01");
---

<FieldRenderer field={field} value={value} />
```

### Props

| Prop | 型 | 説明 |
|---|---|---|
| `field` | `MezzField` | `@mezzanine-stack/content-schema` の DSL フィールド定義 |
| `value` | `unknown` | フィールドの値 |

## WorkCard.astro

```astro
---
import { getCollection } from "astro:content";
import WorkCard from "@mezzanine-stack/astro-renderer/WorkCard.astro";

const works = await getCollection("works");
---

{works.map((work) => <WorkCard work={work} />)}
```

`works` コレクションのフィールド名: `title`, `date`, `thumbnail`, `tags`

## 注意事項

- このパッケージは `apps/site-starter-astro` 側の collection metadata glue (`src/lib/content/collection-derived.ts`) と組み合わせて使う前提で設計されている。
- `@mezzanine-stack/ui/Section.astro` と `@mezzanine-stack/ui/Pagination.astro` を内部で使用しているため、ホスト app に `@mezzanine-stack/ui` が必要。