diff --git a/CLAUDE.md b/CLAUDE.md index ec1f0517..4f0ff45f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,7 +84,9 @@ src/ - **`meta.ts`**: タイトル、説明、TOC、リソース、フレームワーク別メタデータ(ソースファイル、API Props/Events/Slots)を `PatternMeta` 型で定義。全テキストは `Record` で i18n 対応 - **`DemoSection.*.astro`** (推奨): framework ごとに分割した薄い Astro。`DemoSection.{react,vue,svelte,web-component}.astro` が、それぞれ自分の framework の実装ファイルだけを静的 import する。ページ側 dispatcher が `framework` から該当ファイルを選んで呼ぶ +- **`{pattern}-demo-data.ts`** (任意): 4 framework で内容が完全に同一かつ概ね 8 行以上の純 data (配列/オブジェクトリテラル) を切り出した共通ファイル。framework 固有の prop 名 (Vue `ariaLabel` ↔ React/Astro `aria-label`) や関数 (`renderCell` など) は含めず、各 `DemoSection.{framework}.astro` 側で吸収する - **`DemoSection.astro`** (legacy): 4 framework の実装を 1 ファイルで静的 import する旧形式。dispatcher にフォールバックとして残してあり、まだ移行していない pattern で使われている。**注意**: legacy 形式は `@vitejs/plugin-react v6` + Vite 8 + Vue SFC ` diff --git a/src/patterns/tree-view/DemoSection.react.astro b/src/patterns/tree-view/DemoSection.react.astro new file mode 100644 index 00000000..eb7fa332 --- /dev/null +++ b/src/patterns/tree-view/DemoSection.react.astro @@ -0,0 +1,59 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import { TreeView as TreeViewReact } from './TreeView'; +import { TreeViewActivationDemo as TreeViewActivationDemoReact } from './TreeViewActivationDemo'; +import { fileSystemNodes, disabledNodes } from './tree-view-demo-data'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const singleSelectLabel = isJa ? '単一選択 + アクティベーション' : 'Single-Select with Activation'; +const multiSelectLabel = isJa ? '複数選択' : 'Multi-Select'; +const disabledLabel = isJa ? '無効化されたノード' : 'With Disabled Nodes'; +const fileExplorerAriaLabel = isJa ? 'ファイルエクスプローラー' : 'File Explorer'; +const multiSelectAriaLabel = isJa + ? '複数選択ファイルエクスプローラー' + : 'Multi-select File Explorer'; +const restrictedAriaLabel = isJa + ? 'アクセス制限付きファイルエクスプローラー' + : 'File Explorer with Restricted Access'; +--- + +
+
+
+

{singleSelectLabel}

+ +
+
+

{multiSelectLabel}

+ +
+
+

{disabledLabel}

+ +
+
+
diff --git a/src/patterns/tree-view/DemoSection.svelte.astro b/src/patterns/tree-view/DemoSection.svelte.astro new file mode 100644 index 00000000..5d9f8643 --- /dev/null +++ b/src/patterns/tree-view/DemoSection.svelte.astro @@ -0,0 +1,59 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeViewSvelte from './TreeView.svelte'; +import TreeViewActivationDemoSvelte from './TreeViewActivationDemo.svelte'; +import { fileSystemNodes, disabledNodes } from './tree-view-demo-data'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const singleSelectLabel = isJa ? '単一選択 + アクティベーション' : 'Single-Select with Activation'; +const multiSelectLabel = isJa ? '複数選択' : 'Multi-Select'; +const disabledLabel = isJa ? '無効化されたノード' : 'With Disabled Nodes'; +const fileExplorerAriaLabel = isJa ? 'ファイルエクスプローラー' : 'File Explorer'; +const multiSelectAriaLabel = isJa + ? '複数選択ファイルエクスプローラー' + : 'Multi-select File Explorer'; +const restrictedAriaLabel = isJa + ? 'アクセス制限付きファイルエクスプローラー' + : 'File Explorer with Restricted Access'; +--- + +
+
+
+

{singleSelectLabel}

+ +
+
+

{multiSelectLabel}

+ +
+
+

{disabledLabel}

+ +
+
+
diff --git a/src/patterns/tree-view/DemoSection.vue.astro b/src/patterns/tree-view/DemoSection.vue.astro new file mode 100644 index 00000000..a9bcf7d1 --- /dev/null +++ b/src/patterns/tree-view/DemoSection.vue.astro @@ -0,0 +1,59 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeViewVue from './TreeView.vue'; +import TreeViewActivationDemoVue from './TreeViewActivationDemo.vue'; +import { fileSystemNodes, disabledNodes } from './tree-view-demo-data'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const singleSelectLabel = isJa ? '単一選択 + アクティベーション' : 'Single-Select with Activation'; +const multiSelectLabel = isJa ? '複数選択' : 'Multi-Select'; +const disabledLabel = isJa ? '無効化されたノード' : 'With Disabled Nodes'; +const fileExplorerAriaLabel = isJa ? 'ファイルエクスプローラー' : 'File Explorer'; +const multiSelectAriaLabel = isJa + ? '複数選択ファイルエクスプローラー' + : 'Multi-select File Explorer'; +const restrictedAriaLabel = isJa + ? 'アクセス制限付きファイルエクスプローラー' + : 'File Explorer with Restricted Access'; +--- + +
+
+
+

{singleSelectLabel}

+ +
+
+

{multiSelectLabel}

+ +
+
+

{disabledLabel}

+ +
+
+
diff --git a/src/patterns/tree-view/DemoSection.web-component.astro b/src/patterns/tree-view/DemoSection.web-component.astro new file mode 100644 index 00000000..9f203a97 --- /dev/null +++ b/src/patterns/tree-view/DemoSection.web-component.astro @@ -0,0 +1,131 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeViewAstro from './TreeView.astro'; +import { fileSystemNodes, disabledNodes } from './tree-view-demo-data'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const singleSelectLabel = isJa ? '単一選択 + アクティベーション' : 'Single-Select with Activation'; +const multiSelectLabel = isJa ? '複数選択' : 'Multi-Select'; +const disabledLabel = isJa ? '無効化されたノード' : 'With Disabled Nodes'; +const fileExplorerAriaLabel = isJa ? 'ファイルエクスプローラー' : 'File Explorer'; +const multiSelectAriaLabel = isJa + ? '複数選択ファイルエクスプローラー' + : 'Multi-select File Explorer'; +const restrictedAriaLabel = isJa + ? 'アクセス制限付きファイルエクスプローラー' + : 'File Explorer with Restricted Access'; +const activatedPlaceholder = isJa + ? 'Enter、Space、またはクリックでノードを選択してください' + : 'Select a node with Enter, Space, or Click'; +const activatedPrefix = isJa ? 'アクティベート: ' : 'Activated: '; +--- + +
+
+
+

{singleSelectLabel}

+
+ +
+
+ {activatedPrefix} + + {activatedPlaceholder} + +
+ +
+
+
+
+

{multiSelectLabel}

+ +
+
+

{disabledLabel}

+ +
+
+
+ + diff --git a/src/patterns/tree-view/tree-view-demo-data.ts b/src/patterns/tree-view/tree-view-demo-data.ts new file mode 100644 index 00000000..4be6d6f2 --- /dev/null +++ b/src/patterns/tree-view/tree-view-demo-data.ts @@ -0,0 +1,49 @@ +/** + * Shared demo data for the Tree View pattern. + */ + +export const fileSystemNodes = [ + { + id: 'documents', + label: 'Documents', + children: [ + { id: 'report', label: 'report.pdf' }, + { id: 'notes', label: 'notes.txt' }, + { + id: 'projects', + label: 'Projects', + children: [ + { id: 'project-a', label: 'Project A' }, + { id: 'project-b', label: 'Project B' }, + ], + }, + ], + }, + { + id: 'images', + label: 'Images', + children: [ + { id: 'vacation', label: 'vacation.jpg' }, + { id: 'profile', label: 'profile.png' }, + ], + }, + { id: 'readme', label: 'readme.md' }, +]; + +export const disabledNodes = [ + { + id: 'folder1', + label: 'Accessible Folder', + children: [ + { id: 'file1', label: 'file1.txt' }, + { id: 'file2', label: 'file2.txt', disabled: true }, + ], + }, + { + id: 'folder2', + label: 'Restricted Folder', + disabled: true, + children: [{ id: 'secret', label: 'secret.txt' }], + }, + { id: 'public', label: 'public.txt' }, +]; diff --git a/src/patterns/treegrid/DemoSection.react.astro b/src/patterns/treegrid/DemoSection.react.astro new file mode 100644 index 00000000..7d6e3b7f --- /dev/null +++ b/src/patterns/treegrid/DemoSection.react.astro @@ -0,0 +1,25 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeGridDemoReact from './TreeGridDemo'; +import { TreeGridDemoJa as TreeGridDemoJaReact } from './TreeGridDemoJa'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const demoDescription = isJa + ? '矢印キーで移動。rowheaderでArrowRight/Leftで展開/折りたたみ。Spaceで行を選択。' + : 'Navigate with arrow keys. At rowheader, use ArrowRight/Left to expand/collapse. Press Space to select rows.'; +--- + +
+

+ {demoDescription} +

+ {isJa ? : } +
diff --git a/src/patterns/treegrid/DemoSection.svelte.astro b/src/patterns/treegrid/DemoSection.svelte.astro new file mode 100644 index 00000000..59f8c9c3 --- /dev/null +++ b/src/patterns/treegrid/DemoSection.svelte.astro @@ -0,0 +1,25 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeGridDemoSvelte from './TreeGridDemo.svelte'; +import TreeGridDemoJaSvelte from './TreeGridDemoJa.svelte'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const demoDescription = isJa + ? '矢印キーで移動。rowheaderでArrowRight/Leftで展開/折りたたみ。Spaceで行を選択。' + : 'Navigate with arrow keys. At rowheader, use ArrowRight/Left to expand/collapse. Press Space to select rows.'; +--- + +
+

+ {demoDescription} +

+ {isJa ? : } +
diff --git a/src/patterns/treegrid/DemoSection.vue.astro b/src/patterns/treegrid/DemoSection.vue.astro new file mode 100644 index 00000000..b874463f --- /dev/null +++ b/src/patterns/treegrid/DemoSection.vue.astro @@ -0,0 +1,25 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeGridDemoVue from './TreeGridDemo.vue'; +import TreeGridDemoJaVue from './TreeGridDemoJa.vue'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const demoDescription = isJa + ? '矢印キーで移動。rowheaderでArrowRight/Leftで展開/折りたたみ。Spaceで行を選択。' + : 'Navigate with arrow keys. At rowheader, use ArrowRight/Left to expand/collapse. Press Space to select rows.'; +--- + +
+

+ {demoDescription} +

+ {isJa ? : } +
diff --git a/src/patterns/treegrid/DemoSection.web-component.astro b/src/patterns/treegrid/DemoSection.web-component.astro new file mode 100644 index 00000000..e78a0071 --- /dev/null +++ b/src/patterns/treegrid/DemoSection.web-component.astro @@ -0,0 +1,36 @@ +--- +import type { Framework } from '@/lib/frameworks'; +import type { Locale } from '@/i18n/ui'; +import TreeGridAstro from './TreeGrid.astro'; +import { columnsEn, columnsJa, nodesEn, nodesJa } from './treegrid-demo-data'; + +interface Props { + framework?: Framework; + locale?: Locale; +} + +const { locale = 'en' } = Astro.props; +const isJa = locale === 'ja'; + +const demoDescription = isJa + ? '矢印キーで移動。rowheaderでArrowRight/Leftで展開/折りたたみ。Spaceで行を選択。' + : 'Navigate with arrow keys. At rowheader, use ArrowRight/Left to expand/collapse. Press Space to select rows.'; + +const columns = isJa ? columnsJa : columnsEn; +const nodes = isJa ? nodesJa : nodesEn; +const ariaLabel = isJa ? 'ファイルブラウザ' : 'File browser'; +--- + +
+

+ {demoDescription} +

+ +
diff --git a/src/patterns/treegrid/DemoSection.astro b/src/patterns/treegrid/treegrid-demo-data.ts similarity index 62% rename from src/patterns/treegrid/DemoSection.astro rename to src/patterns/treegrid/treegrid-demo-data.ts index 7db3ba27..da5c92d4 100644 --- a/src/patterns/treegrid/DemoSection.astro +++ b/src/patterns/treegrid/treegrid-demo-data.ts @@ -1,38 +1,19 @@ ---- /** - * TreeGrid Demo Section + * Shared demo data for the TreeGrid pattern (Astro Web Component variant). * - * Renders the treegrid demo for each framework variant. - * Uses locale-specific demo components for Japanese pages. + * The React / Vue / Svelte demos use locale-specific wrapper components + * (`TreeGridDemo` / `TreeGridDemoJa`); only the Astro Web Component variant + * consumes the raw data, but exposing both locales here keeps demo data + * colocated and avoids inlining ~130 lines into a single .astro file. */ -import type { Framework } from '@/lib/frameworks'; -import TreeGridDemoReact from './TreeGridDemo'; -import { TreeGridDemoJa as TreeGridDemoJaReact } from './TreeGridDemoJa'; -import TreeGridDemoVue from './TreeGridDemo.vue'; -import TreeGridDemoJaVue from './TreeGridDemoJa.vue'; -import TreeGridDemoSvelte from './TreeGridDemo.svelte'; -import TreeGridDemoJaSvelte from './TreeGridDemoJa.svelte'; -import TreeGridAstro from './TreeGrid.astro'; -interface Props { - framework: Framework; -} - -const { framework } = Astro.props; -const isJa = Astro.url.pathname.startsWith('/ja/'); - -const demoDescription = isJa - ? '矢印キーで移動。rowheaderでArrowRight/Leftで展開/折りたたみ。Spaceで行を選択。' - : 'Navigate with arrow keys. At rowheader, use ArrowRight/Left to expand/collapse. Press Space to select rows.'; - -// Astro demo data (English) -const columnsEn = [ +export const columnsEn = [ { id: 'name', header: 'Name', isRowHeader: true }, { id: 'size', header: 'Size' }, { id: 'date', header: 'Date Modified' }, ]; -const nodesEn = [ +export const nodesEn = [ { id: 'docs', cells: [ @@ -71,14 +52,13 @@ const nodesEn = [ }, ]; -// Astro demo data (Japanese) -const columnsJa = [ +export const columnsJa = [ { id: 'name', header: '名前', isRowHeader: true }, { id: 'size', header: 'サイズ' }, { id: 'date', header: '更新日' }, ]; -const nodesJa = [ +export const nodesJa = [ { id: 'docs', cells: [ @@ -160,32 +140,3 @@ const nodesJa = [ ], }, ]; - -const columns = isJa ? columnsJa : columnsEn; -const nodes = isJa ? nodesJa : nodesEn; -const ariaLabel = isJa ? 'ファイルブラウザ' : 'File browser'; ---- - -
-

- {demoDescription} -

- {framework === 'react' && !isJa && } - {framework === 'react' && isJa && } - {framework === 'vue' && !isJa && } - {framework === 'vue' && isJa && } - {framework === 'svelte' && !isJa && } - {framework === 'svelte' && isJa && } - { - framework === 'astro' && ( - - ) - } -