Back to index

Release Changelog

Stack
Generates documents
Release Changelog

Seen as a design

Take it with you

Copy and paste, or save a file and hand it over. For a machine with no network, one “Everything” file is enough.

Everything

release-changelog-everything.md

Everything in this panel, including the contents behind each URL, in one Markdown file

Prompt

1.4 KB
Build an HTML document with "Release Changelog". This layout runs, so there is no composition to rebuild — what it needs is content.

## What this layout does
Release Changelog with explicit source values and reading conditions.

## What you have to supply
- Provide the source values, labels and decision conditions described by the schema.

## The shape of the input
- `title` — string — 結論を伝える見出し
- `subtitle` — string? — 出典・時点・母集団や仮定
- `version` — string — バージョン
- `releaseDate` — string — 公開予定日または公開日
- `changes` — array (kind, title, impact, action) — 変更区分・内容・影響・利用者の対応

schema.ts holds the machine-checkable validation. Ask rather than guess when an input is missing.

## When not to use it
- Do not compare values with incompatible units, populations, or assumptions.

## How to build it
Put the input in a JSON file and run:

```bash
node scripts/render.mjs release-changelog <input.json> --theme ink -o out.html
```

The output is one self-contained file and fetches nothing at render time.

## The source
- https://design-vault.pages.dev/designs/release-changelog/source/template.tsx
- https://design-vault.pages.dev/designs/release-changelog/source/schema.ts
- https://design-vault.pages.dev/designs/release-changelog/source/sample-data.json
- https://design-vault.pages.dev/designs/release-changelog/sample.html

Files

Template, input schema, sample data and metadata. This document was generated from those four. The generated document

template.tsx

6.6 KB

/designs/release-changelog/source/template.tsx

Show contents
import type { ReactNode } from "react";
import type { Props } from "./schema";
function Notes({children}:{children:ReactNode}) { return <details><summary>データ・判断条件を確認</summary>{children}</details>; }

const CSS = String.raw`
.asset{font-family:var(--font-sans);color:var(--color-primary);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:3rem 2rem;line-height:1.6;font-size:var(--text-body-sm)}
.asset *{box-sizing:border-box}.asset header{margin-bottom:2rem}.asset .eyebrow{font-family:var(--font-mono);font-size:var(--text-label);letter-spacing:.08em;color:var(--color-secondary);margin-bottom:.75rem}.asset h1{font-size:var(--text-h1);font-weight:700;line-height:1.35;letter-spacing:-.025em;max-width:32em}.asset h2{font-size:var(--text-h3);font-weight:600;margin-bottom:.75rem}.asset h3{font-size:var(--text-body-md);font-weight:600}.asset .subtitle,.asset .muted{color:var(--color-secondary)}.asset .subtitle{margin-top:.75rem}.asset .number{font-variant-numeric:tabular-nums;font-family:var(--font-mono)}.asset .hero-number{font-size:var(--text-display);line-height:1.2;font-weight:700;letter-spacing:-.04em}.asset .callout{border-left:.25rem solid var(--color-tertiary);padding:1rem 1.5rem;background:var(--color-surface-subtle);margin-bottom:1.5rem}.asset .grid2{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem}.asset .grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem}.asset .panel{padding:1.5rem;background:var(--color-surface-subtle);border-radius:var(--radius-md);min-width:0}.asset .rule{border-top:1px solid var(--color-outline);padding-top:1rem;margin-top:1rem}.asset .pill{display:inline-block;padding:.25rem .75rem;border:1px solid var(--color-outline);border-radius:var(--radius-full);font-size:var(--text-label)}.asset .focus{background:var(--color-tertiary-container);color:var(--color-on-tertiary-container)}.asset .dark{background:var(--color-primary);color:var(--color-on-primary)}.asset .dark .muted{color:var(--color-on-primary-container)}.asset .row{display:grid;grid-template-columns:12rem minmax(0,1fr) 6rem;gap:1rem;align-items:center;padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .row>*{min-width:0}.asset .track{height:1rem;position:relative;background:var(--color-neutral);border-radius:var(--radius-sm)}.asset .bar{height:100%;background:var(--color-tertiary);border-radius:var(--radius-sm)}.asset .track.tall{height:2rem}.asset .flex{display:flex;gap:1rem;align-items:center;justify-content:space-between;flex-wrap:wrap}.asset .stack>*+*{margin-top:1rem}.asset ul{list-style:disc;padding-left:1.25rem}.asset li+li{margin-top:.5rem}.asset .plot{display:block;width:100%;height:auto;overflow:visible}.asset .plot text{font-family:var(--font-sans);font-size:14px;fill:var(--color-secondary)}.asset .plot .ink{fill:var(--color-primary)}.asset .plot .axis{stroke:var(--color-outline);stroke-width:1}.asset .plot .accent{stroke:var(--color-tertiary);fill:none;stroke-width:3}.asset .legend{display:flex;gap:1.5rem;flex-wrap:wrap;font-size:var(--text-label);margin-bottom:1rem}.asset .legend b{display:inline-block;width:.75rem;height:.75rem;margin-right:.5rem}.asset .ledger{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}.asset .ledger caption{text-align:left;font-weight:600;margin:1rem 0}.asset .ledger th{font-weight:600;color:var(--color-secondary);text-align:left}.asset .ledger th,.asset .ledger td{padding:.75rem 1rem;border-bottom:1px solid var(--color-outline);vertical-align:top;overflow-wrap:anywhere}.asset .ledger th:first-child,.asset .ledger td:first-child{padding-left:0}.asset .ledger th:last-child,.asset .ledger td:last-child{padding-right:0}.asset .ledger tbody tr:hover{background:var(--color-surface-subtle)}.asset details{border-top:1px solid var(--color-outline);margin-top:1.5rem;padding-top:1rem}.asset summary{cursor:pointer;color:var(--color-secondary);padding:.5rem 0;min-height:2.75rem}.asset summary:focus-visible{outline:2px solid var(--color-tertiary);outline-offset:.25rem}.asset .small{font-size:var(--text-label)}.asset .mobile-only{display:none}.asset .horizontal-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem}.asset .board-column{border-top:.25rem solid var(--color-primary);padding-top:1rem;min-width:0}.asset .board-item{padding:1rem 0;border-bottom:1px solid var(--color-outline)}.asset .board-item p{margin-top:.5rem}.asset .statement{font-size:var(--text-h2);line-height:1.5;font-weight:600}.asset .meta-line{margin-top:.75rem;font-size:var(--text-label);color:var(--color-secondary)}.asset pre{white-space:pre-wrap;overflow-wrap:anywhere}.asset footer{margin-top:2rem;font-size:var(--text-label);color:var(--color-secondary)}
@media(max-width:640px){.asset{padding:1.5rem 1rem}.asset h1{font-size:var(--text-h2)}.asset header{margin-bottom:1.5rem}.asset .grid2,.asset .grid3,.asset .horizontal-list{grid-template-columns:1fr}.asset .row{grid-template-columns:minmax(0,1fr) 5rem;gap:.5rem}.asset .row>:first-child{grid-column:1/-1}.asset .desktop-only{display:none!important}.asset .mobile-only{display:block}.asset .panel{padding:1rem}.asset .ledger,.asset .ledger tbody,.asset .ledger tr,.asset .ledger td{display:block}.asset .ledger thead{display:none}.asset .ledger tr{padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .ledger td{display:grid;grid-template-columns:7rem minmax(0,1fr);gap:.75rem;border:0;padding:.25rem 0!important}.asset .ledger td:before{content:attr(data-label);color:var(--color-secondary);font-size:var(--text-label)}.asset .hero-number{font-size:var(--text-h1)}}
@media print{.asset{max-width:none;padding:1rem}.asset details>*{display:block}.asset summary{display:none}}
`;

export default function Template(d: Props) {
const names={added:"追加",changed:"変更",fixed:"修正",removed:"廃止"};
return <section className="asset asset-release-changelog"><style>{CSS}</style><header><p className="eyebrow">RELEASE CHANGELOG</p><h1>{d.title}</h1>{d.subtitle && <p className="subtitle">{d.subtitle}</p>}</header>
<div className="flex"><span className="hero-number">{d.version}</span><span className="pill">{d.releaseDate}</span></div><div className="stack" style={{marginTop:"1.5rem"}}>{d.changes.map((c,i)=><article className="grid2 rule" key={i}><div><span className="pill">{names[c.kind]}</span><h2>{c.title}</h2></div><div><p>{c.impact}</p><p className="meta-line">利用者の対応:{c.action}</p></div></article>)}</div><Notes><p>変更の完了状況と公開日を確認してから案内します。対応不要の場合も明記します。</p></Notes>
<footer>変更内容だけでなく、利用者への影響と必要な対応を示す。</footer></section>;
}

schema.ts

926 B

/designs/release-changelog/source/schema.ts

Show contents
import { z } from "zod";
const text = z.string().trim().min(1).max(160);
const short = z.string().trim().min(1).max(48);
const value = z.number().finite();
const positive = value.positive();
const date = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(s => Number.isFinite(Date.parse(s)) && new Date(s).toISOString().slice(0,10) === s, "実在する日付を YYYY-MM-DD で指定する");

export const schema = z.object({
  title: text.describe("結論を伝える見出し"),
  subtitle: text.optional().describe("出典・時点・母集団や仮定"),
  version:short.describe("バージョン"),releaseDate:date.describe("公開予定日または公開日"),
  changes:z.array(z.object({kind:z.enum(["added","changed","fixed","removed"]),title:short,impact:text,action:text}).strict()).min(2).max(8).describe("変更区分・内容・影響・利用者の対応"),
}).strict();
export type Props = z.infer<typeof schema>;

meta.yaml

1.4 KB

/designs/release-changelog/source/meta.yaml

Show contents
id: release-changelog
name:
  ja: 変更内容と利用者への影響
  en: Release Changelog
purpose:
  ja: 追加・変更・修正・廃止を区別し、利用者が行うことを添える。
  en: Release Changelog with explicit source values and reading conditions.
status: published
still: ./still.png
category: specification
catalogOrder: 680
jobs:
  - measure-change
useCases:
  - summary
layoutKinds:
  - stack
tags:
  - release-changelog
  - specification
  - offline
  - responsive
whenToUse:
  - ja: 追加・変更・修正・廃止を区別し、利用者が行うことを添える。
    en: Use to communicate release changelog.
avoidWhen:
  - ja: 同じ条件・単位で比較できないデータには使わない
    en: Do not compare values with incompatible units, populations, or assumptions.
requiredInputs:
  - ja: 変更内容だけでなく、利用者への影響と必要な対応を示す。
    en: Provide the source values, labels and decision conditions described by the schema.
relatedLayouts:
  - release-readiness
  - executive-summary-brief
dataSchema:
  title: string — 結論を伝える見出し
  subtitle: string? — 出典・時点・母集団や仮定
  version: string — バージョン
  releaseDate: string — 公開予定日または公開日
  changes: array (kind, title, impact, action) — 変更区分・内容・影響・利用者の対応
sources: []

sample-data.json

917 B

/designs/release-changelog/source/sample-data.json

Show contents
{
  "title": "受付機能v1.4の変更点と、利用前に確認すること",
  "subtitle": "架空サンプル|レイアウトの使用例",
  "version": "v1.4",
  "releaseDate": "2026-09-15",
  "changes": [
    {
      "kind": "added",
      "title": "入力例を追加",
      "impact": "必須項目の意味を確認しやすくなる",
      "action": "対応不要"
    },
    {
      "kind": "changed",
      "title": "通知の送信時点",
      "impact": "受付と確認開始を別通知に分割",
      "action": "受信ルールを確認"
    },
    {
      "kind": "fixed",
      "title": "再送信時の二重表示",
      "impact": "同じ申込が重複表示されなくなる",
      "action": "対応不要"
    },
    {
      "kind": "removed",
      "title": "旧CSV形式",
      "impact": "旧形式での出力を終了",
      "action": "新形式の項目を確認"
    }
  ]
}