@k8ordo/ui 1.0.0 → 2.0.0

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.
Files changed (85) hide show
  1. package/README.md +37 -12
  2. package/dist/components/ai/conversation/conversation.d.mts +8 -10
  3. package/dist/components/ai/conversation/conversation.mjs +1 -6
  4. package/dist/components/ai/conversation/index.d.mts +15 -1
  5. package/dist/components/ai/conversation/index.mjs +8 -1
  6. package/dist/components/ai/index.d.mts +5 -9
  7. package/dist/components/ai/index.mjs +4 -4
  8. package/dist/components/ai/message/index.d.mts +12 -1
  9. package/dist/components/ai/message/index.mjs +7 -1
  10. package/dist/components/ai/message/message.d.mts +3 -5
  11. package/dist/components/ai/message/message.mjs +1 -5
  12. package/dist/components/ai/prompt-input/index.d.mts +23 -1
  13. package/dist/components/ai/prompt-input/index.mjs +8 -1
  14. package/dist/components/ai/prompt-input/prompt-input.d.mts +4 -6
  15. package/dist/components/ai/prompt-input/prompt-input.mjs +1 -6
  16. package/dist/components/ai/suggestion/index.d.mts +13 -1
  17. package/dist/components/ai/suggestion/index.mjs +7 -1
  18. package/dist/components/ai/suggestion/suggestion.d.mts +3 -5
  19. package/dist/components/ai/suggestion/suggestion.mjs +1 -5
  20. package/dist/components/buttons/icon-button/icon-button.mjs +1 -1
  21. package/dist/components/form/checkbox/checkbox.d.mts +1 -0
  22. package/dist/components/form/checkbox/checkbox.mjs +3 -2
  23. package/dist/components/form/checkbox-group/index.d.mts +1 -0
  24. package/dist/components/form/file-field/file-field.d.mts +12 -15
  25. package/dist/components/form/file-field/file-field.mjs +1 -6
  26. package/dist/components/form/file-field/index.d.mts +17 -1
  27. package/dist/components/form/file-field/index.mjs +8 -1
  28. package/dist/components/form/radio/radio.d.mts +1 -0
  29. package/dist/components/form/radio/radio.mjs +3 -2
  30. package/dist/components/index.d.mts +15 -21
  31. package/dist/components/index.mjs +7 -7
  32. package/dist/components/navigation/anchor/anchor.mjs +1 -1
  33. package/dist/components/navigation/tabs/index.d.mts +19 -1
  34. package/dist/components/navigation/tabs/index.mjs +9 -1
  35. package/dist/components/navigation/tabs/tabs.d.mts +16 -18
  36. package/dist/components/navigation/tabs/tabs.mjs +1 -7
  37. package/dist/components/overlays/dialog/dialog.d.mts +12 -16
  38. package/dist/components/overlays/dialog/dialog.mjs +1 -6
  39. package/dist/components/overlays/dialog/index.d.mts +17 -1
  40. package/dist/components/overlays/dialog/index.mjs +8 -1
  41. package/dist/components/overlays/dropdown-menu/dropdown-menu.d.mts +20 -24
  42. package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +2 -11
  43. package/dist/components/overlays/dropdown-menu/index.d.mts +31 -1
  44. package/dist/components/overlays/dropdown-menu/index.mjs +12 -1
  45. package/dist/components/overlays/dropdown-menu/sub-menu.mjs +1 -1
  46. package/dist/components/overlays/list-box/index.d.mts +27 -1
  47. package/dist/components/overlays/list-box/index.mjs +9 -1
  48. package/dist/components/overlays/list-box/list-box.d.mts +20 -22
  49. package/dist/components/overlays/list-box/list-box.mjs +2 -8
  50. package/dist/components/overlays/popover/index.d.mts +24 -1
  51. package/dist/components/overlays/popover/index.mjs +8 -1
  52. package/dist/components/overlays/popover/popover.d.mts +18 -20
  53. package/dist/components/overlays/popover/popover.mjs +2 -7
  54. package/dist/components/overlays/tooltip/index.d.mts +21 -1
  55. package/dist/components/overlays/tooltip/index.mjs +8 -1
  56. package/dist/components/overlays/tooltip/tooltip.d.mts +18 -22
  57. package/dist/components/overlays/tooltip/tooltip.mjs +2 -7
  58. package/dist/hooks/index.d.mts +1 -4
  59. package/dist/hooks/index.mjs +2 -5
  60. package/dist/index.d.mts +13 -15
  61. package/dist/index.mjs +9 -12
  62. package/dist/integrations/_shared/renderers.mjs +7 -7
  63. package/dist/integrations/_shared/schemas.d.mts +1 -1
  64. package/dist/{hooks/focus-trap/index.d.mts → internal/focus-trap.d.mts} +1 -1
  65. package/dist/{hooks/focus-trap/index.mjs → internal/focus-trap.mjs} +1 -1
  66. package/dist/styles/index.css +0 -8
  67. package/docs/GUIDE.md +148 -133
  68. package/docs/llms.txt +11 -7
  69. package/docs/props.generated.json +18 -0
  70. package/docs/references/ai-chat.md +67 -67
  71. package/docs/references/color.md +108 -107
  72. package/docs/references/components.md +318 -310
  73. package/docs/references/generative-ui.md +51 -30
  74. package/docs/references/helpers.md +155 -52
  75. package/docs/references/hooks.md +61 -74
  76. package/docs/references/interaction-design.md +47 -47
  77. package/docs/references/spatial-design.md +83 -81
  78. package/docs/references/typography.md +68 -67
  79. package/package.json +32 -33
  80. package/dist/hooks/hash/index.d.mts +0 -4
  81. package/dist/hooks/hash/index.mjs +0 -25
  82. package/dist/hooks/local-storage/index.d.mts +0 -4
  83. package/dist/hooks/local-storage/index.mjs +0 -46
  84. package/dist/hooks/session-storage/index.d.mts +0 -4
  85. package/dist/hooks/session-storage/index.mjs +0 -46
@@ -1,35 +1,42 @@
1
- # 生成 UI(json-render / OpenUI)
1
+ # Generative UI (json-render / OpenUI)
2
2
 
3
- k8ordo UI は、LLM が k8ordo UI コンポーネントだけで UI を生成できる公式アダプタを同梱している。生成される UI はデザイントークンに固定され、ブランドから外れない。フレームワークは [json-render](https://json-render.dev) と [OpenUI](https://www.openui.com) の 2 つ。
3
+ `@k8ordo/ui` ships official adapters that let an LLM generate UI out of
4
+ `@k8ordo/ui` components only. The generated UI is pinned to the design tokens,
5
+ so it cannot drift off-brand. Two frameworks are supported:
6
+ [json-render](https://json-render.dev) and [OpenUI](https://www.openui.com).
4
7
 
5
- いずれも optional peer dependency なので、使うフレームワークだけインストールする。
8
+ Both are optional peer dependencies — install only the one you use.
6
9
 
7
10
  ```bash
8
11
  # json-render
9
12
  pnpm add @json-render/core @json-render/react zod
10
13
  # OpenUI
11
14
  pnpm add @openuidev/react-lang zod
12
- # OpenUI のサーバー安全な prompt エントリを使う場合は追加で:
15
+ # Add this too if you use OpenUI's server-safe prompt entry:
13
16
  pnpm add @openuidev/lang-core
14
17
  ```
15
18
 
16
19
  ## json-render
17
20
 
18
- catalog(スキーマ・プロンプト)と registry(描画)が分かれており、catalog は**サーバー安全**。
21
+ The catalog (schemas and prompt) is separate from the registry (rendering), and
22
+ the catalog is **server-safe**.
19
23
 
20
- ### 1. サーバーでプロンプトを生成する
24
+ ### 1. Generate the prompt on the server
21
25
 
22
26
  ```tsx
23
27
  import { catalog, uiRules } from '@k8ordo/ui/json-render';
24
28
 
25
- // customRules は LLM が破りやすい横断制約を注入する
26
- // (Table のセル数を columns に一致 / href の形式 / Tabs・Accordion の content はテキストのみ)。
29
+ // customRules injects the cross-cutting constraints an LLM most often breaks
30
+ // (cell count matching columns in Table, href format, text-only content in
31
+ // Tabs and Accordion).
27
32
  const systemPrompt = catalog.prompt({ customRules: [...uiRules] });
28
33
  ```
29
34
 
30
- ### 2. クライアントで描画する
35
+ ### 2. Render on the client
31
36
 
32
- `JsonRenderUI` が `JSONUIProvider` + `Renderer` + registry を内部結線済みなので、spec を渡すだけでよい。フォーム値を回収するときは `onStateChange` を渡す。
37
+ `JsonRenderUI` already wires up `JSONUIProvider` + `Renderer` + registry
38
+ internally, so passing the spec is enough. Pass `onStateChange` when you need to
39
+ collect form values.
33
40
 
34
41
  ```tsx
35
42
  'use client';
@@ -40,27 +47,33 @@ export function GenUi({ spec }: { spec: unknown }) {
40
47
  }
41
48
  ```
42
49
 
43
- 高度な構成(独自の `navigate` / `handlers` / `validationFunctions`)が必要なら、低レベルの `registry` を `@json-render/react` の `JSONUIProvider` / `Renderer` に直接渡す。
50
+ For an advanced setup (your own `navigate`, `handlers`, or
51
+ `validationFunctions`), pass the low-level `registry` straight to
52
+ `@json-render/react`'s `JSONUIProvider` / `Renderer`.
44
53
 
45
- ### 3. LLM 出力を検証して描画 or 修復する
54
+ ### 3. Validate LLM output, then render or repair it
46
55
 
47
- `validateGeneratedSpec` は機械修正 → 構造検証 → コンポーネントごとの props 検証を行い、失敗時はそのまま LLM に投げ返せる修復プロンプトを返す。`catalog.validate()` は現行の上流バージョンで正常 spec を誤って弾くため、こちらを使う。
56
+ `validateGeneratedSpec` applies mechanical fixes, validates the structure, then
57
+ validates props per component. On failure it returns a repair prompt you can
58
+ send straight back to the LLM. Use it instead of `catalog.validate()`, which
59
+ rejects valid specs in the current upstream version.
48
60
 
49
61
  ```tsx
50
62
  import { validateGeneratedSpec } from '@k8ordo/ui/json-render';
51
63
 
52
64
  const result = validateGeneratedSpec(JSON.parse(llmOutput));
53
65
  if (result.ok) {
54
- // result.fixes に自動修正の内容
66
+ // result.fixes lists what was auto-corrected
55
67
  return <JsonRenderUI spec={result.spec} />;
56
68
  }
57
- // 壊れていたら修復プロンプトで再生成させる
69
+ // If it is broken, regenerate with the repair prompt
58
70
  const retried = await llm(result.repairPrompt);
59
71
  ```
60
72
 
61
- ### 4. 型付き spec(任意)
73
+ ### 4. Typed specs (optional)
62
74
 
63
- `satisfies UISpec` で書くと、component 名・props の typo がコンパイルエラーになり、`as unknown as Spec` が不要になる。
75
+ Writing `satisfies UISpec` turns a typo in a component name or prop into a
76
+ compile error, and removes the need for `as unknown as Spec`.
64
77
 
65
78
  ```tsx
66
79
  import type { UISpec } from '@k8ordo/ui/json-render';
@@ -74,11 +87,13 @@ const spec = {
74
87
  } satisfies UISpec;
75
88
  ```
76
89
 
77
- `ComponentName` / `ComponentProps<K>` も export されており、特定コンポーネントの props 型を取り出せる。
90
+ `ComponentName` and `ComponentProps<K>` are exported as well, so you can pull
91
+ out the props type of a specific component.
78
92
 
79
93
  ## OpenUI
80
94
 
81
- 子要素を型付きサブコンポーネント(`z.array(Child.ref)`)で表すモデル。描画は `'use client'`。
95
+ A model where children are expressed as typed subcomponents
96
+ (`z.array(Child.ref)`). Rendering is `'use client'`.
82
97
 
83
98
  ```tsx
84
99
  'use client';
@@ -90,23 +105,29 @@ export function GenUi({ response }: { response: string }) {
90
105
  }
91
106
  ```
92
107
 
93
- システムプロンプトはサーバー安全な専用エントリで生成できる(json-render の `catalog.prompt()` と対称)。
108
+ The system prompt comes from a dedicated server-safe entry, mirroring
109
+ json-render's `catalog.prompt()`.
94
110
 
95
111
  ```tsx
96
112
  import { prompt } from '@k8ordo/ui/openui/prompt';
97
113
 
98
- const systemPrompt = prompt(); // React 非依存。RSC / API ルートから呼べる
114
+ const systemPrompt = prompt(); // No React dependency — callable from RSC or an API route
99
115
  ```
100
116
 
101
- OpenUI では `Stack` / `Grid` の直下に `Stack` / `Grid` / `Card` を置けない(自己参照スキーマ非対応)。入れ子レイアウトが必要なら `Card` の中に `Stack` / `Grid` を入れる。json-render は slots ベースで自由に入れ子にできる。
117
+ In OpenUI a `Stack` or `Grid` cannot sit directly inside another `Stack` or
118
+ `Grid` (self-referential schemas are unsupported). When you need nested layout,
119
+ put the `Stack` / `Grid` inside a `Card`. json-render is slot-based and nests
120
+ freely.
102
121
 
103
- ## エクスポート早見表
122
+ ## Exports at a glance
104
123
 
105
- | エクスポート | 区分 | 内容 |
124
+ | Export | Kind | Contents |
106
125
  | --------------------------------- | -------------- | ------------------------------------------------------------------ |
107
- | `@k8ordo/ui/json-render` | サーバー安全 | `catalog`, `validateGeneratedSpec`, `uiRules`, 型(`UISpec` など) |
108
- | `@k8ordo/ui/json-render/registry` | `'use client'` | `JsonRenderUI`(事前結線), `registry`(低レベル) |
109
- | `@k8ordo/ui/openui` | `'use client'` | `library`(描画) |
110
- | `@k8ordo/ui/openui/prompt` | サーバー安全 | `prompt()`(プロンプト生成) |
111
-
112
- > いずれも `@k8ordo/ui/styles.css`(Tailwind CSS 4 のプロジェクトは代わりに `@k8ordo/ui/tailwind.css`)の読み込みと `UIProvider` でのラップが前提。
126
+ | `@k8ordo/ui/json-render` | server-safe | `catalog`, `validateGeneratedSpec`, `uiRules`, types (`UISpec`, …) |
127
+ | `@k8ordo/ui/json-render/registry` | `'use client'` | `JsonRenderUI` (pre-wired), `registry` (low level) |
128
+ | `@k8ordo/ui/openui` | `'use client'` | `library` (rendering) |
129
+ | `@k8ordo/ui/openui/prompt` | server-safe | `prompt()` (prompt generation) |
130
+
131
+ > All of them assume you have loaded `@k8ordo/ui/styles.css` (or
132
+ > `@k8ordo/ui/tailwind.css` in a Tailwind CSS 4 project) and wrapped the tree in
133
+ > `UIProvider`.
@@ -1,120 +1,223 @@
1
- # ヘルパー・型
1
+ # Helpers and types
2
2
 
3
- k8ordo UI が提供するユーティリティ関数と型定義。
3
+ Utility functions and type definitions that `@k8ordo/ui` provides.
4
4
 
5
5
  ```tsx
6
- import { cn, between, commalize, uuidV4 } from '@k8ordo/ui';
7
- import type { Status, Direction, Option } from '@k8ordo/ui';
6
+ import {
7
+ chain,
8
+ cn,
9
+ createSafeContext,
10
+ mergeProps,
11
+ mergeRefs,
12
+ } from '@k8ordo/ui';
13
+ import type {
14
+ Status,
15
+ Direction,
16
+ Placement,
17
+ ModalSide,
18
+ DrawerSide,
19
+ Option,
20
+ } from '@k8ordo/ui';
8
21
  ```
9
22
 
10
- ## ヘルパー関数
23
+ The list below is the complete public helper API: `pnpm check:props` fails
24
+ when the headings under "Helper functions" and the exports of
25
+ `src/helpers/index.ts` disagree.
26
+
27
+ ## Helper functions
28
+
29
+ ### chain
30
+
31
+ Combines several callbacks into one that calls each in order with the same
32
+ arguments. `undefined` entries are skipped, so an optional user handler can be
33
+ passed straight in. The combined function returns nothing.
34
+
35
+ ```tsx
36
+ import { chain } from '@k8ordo/ui';
37
+
38
+ const onClick = chain(props.onClick, () => {
39
+ setOpen(false);
40
+ });
41
+
42
+ <button onClick={onClick} />;
43
+ ```
44
+
45
+ Signature:
46
+
47
+ ```ts
48
+ const chain: <T extends (...args: never[]) => unknown>(
49
+ ...callbacks: Array<T | undefined>
50
+ ) => (...args: Parameters<T>) => void;
51
+ ```
11
52
 
12
53
  ### cn
13
54
 
14
- Tailwind クラスのマージ(clsx + tailwind-merge)。
55
+ Merges Tailwind classes (clsx + tailwind-merge). Accepts strings, arrays,
56
+ objects, and falsy values, and resolves conflicting utilities with the last
57
+ one winning.
15
58
 
16
59
  ```tsx
17
60
  import { cn } from '@k8ordo/ui';
18
61
 
19
62
  cn('text-fg-base', isActive && 'bg-primary-bg', className);
20
- // 重複するクラスを自動的に解決
63
+ cn('flex', undefined, { hidden: false, grow: true }); // → 'flex grow'
21
64
  cn('px-4 py-2', 'px-6'); // → 'py-2 px-6'
22
65
  ```
23
66
 
24
- ### between
67
+ Signature:
68
+
69
+ ```ts
70
+ const cn: (...inputs: ClassValue[]) => string;
71
+ ```
72
+
73
+ ### createSafeContext
25
74
 
26
- 値を範囲内にクランプ。
75
+ Creates a context whose hook throws with the given message when there is no
76
+ provider above it, instead of handing back `null`. Returns the context (to
77
+ render as a provider) and the hook as a tuple.
27
78
 
28
79
  ```tsx
29
- import { between } from '@k8ordo/ui';
80
+ import { createSafeContext } from '@k8ordo/ui';
30
81
 
31
- between(150, 0, 100); // → 100
32
- between(-5, 0, 100); // → 0
33
- between(50, 0, 100); // → 50
34
- ```
82
+ const [TabsContext, useTabsContext] = createSafeContext<{
83
+ selectedId: string;
84
+ }>('Tabs.Tab must be used within <Tabs.Root>');
35
85
 
36
- ### commalize
86
+ const Root = ({ children }) => (
87
+ <TabsContext value={{ selectedId }}>{children}</TabsContext>
88
+ );
37
89
 
38
- 数値を3桁区切りでフォーマット。
90
+ const Tab = () => {
91
+ const { selectedId } = useTabsContext(); // throws outside <Root>
92
+ };
93
+ ```
39
94
 
40
- ```tsx
41
- import { commalize } from '@k8ordo/ui';
95
+ Signature:
42
96
 
43
- commalize(1000); // → '1,000'
44
- commalize(1234567); // → '1,234,567'
97
+ ```ts
98
+ const createSafeContext: <T>(
99
+ errorMessage: string,
100
+ ) => readonly [Context<T | null>, () => T];
45
101
  ```
46
102
 
47
- ### toPrecision
103
+ ### mergeProps
48
104
 
49
- 指定した小数点以下の精度に丸める。
105
+ Merges two props objects the way a `render*` prop expects: `className` goes
106
+ through `cn`, `style` is shallow-merged, event handlers (`onClick`,
107
+ `onKeyDown`, …) are chained with `chain` so both run, and any other key is
108
+ overwritten by `override` unless its value is `undefined`.
50
109
 
51
110
  ```tsx
52
- import { toPrecision } from '@k8ordo/ui';
111
+ import { mergeProps } from '@k8ordo/ui';
112
+
113
+ const merged = mergeProps(
114
+ { className: 'p-2 text-fg-base', onClick: track },
115
+ { className: 'text-fg-mute', onClick: open, id: 'menu' },
116
+ );
117
+ // merged.className → 'p-2 text-fg-mute'
118
+ // merged.onClick() → track(), then open()
119
+ ```
120
+
121
+ Signature:
53
122
 
54
- toPrecision(3.14159, 2); // → 3.14
123
+ ```ts
124
+ const mergeProps: <
125
+ A extends Record<string, unknown>,
126
+ B extends Record<string, unknown>,
127
+ >(
128
+ base: A,
129
+ override: B,
130
+ ) => Omit<A, keyof B> & B;
55
131
  ```
56
132
 
57
- ### cast
133
+ ### mergeRefs
58
134
 
59
- 型キャストユーティリティ。
135
+ Combines several refs into one callback ref, so a component can keep an
136
+ internal ref while forwarding the caller's. Object refs are assigned, function
137
+ refs are called, and `null` / `undefined` are skipped. The returned callback
138
+ returns a cleanup (React 19 ref cleanup) that resets object refs to `null` and
139
+ runs each function ref's own cleanup — or calls it with `null` when it did not
140
+ return one.
60
141
 
61
142
  ```tsx
62
- import { cast } from '@k8ordo/ui';
143
+ import { mergeRefs } from '@k8ordo/ui';
144
+
145
+ const Field = ({ ref, ...rest }: { ref?: Ref<HTMLInputElement> }) => {
146
+ const internalRef = useRef<HTMLInputElement>(null);
147
+ return <input ref={mergeRefs(internalRef, ref)} {...rest} />;
148
+ };
63
149
  ```
64
150
 
65
- ### isInternalRoute
151
+ Signature:
66
152
 
67
- 内部ルートかどうかの判定。
153
+ ```ts
154
+ const mergeRefs: <T>(
155
+ ...refs: ReadonlyArray<Ref<T> | undefined>
156
+ ) => RefCallback<T>;
157
+ ```
68
158
 
69
- ```tsx
70
- import { isInternalRoute } from '@k8ordo/ui';
159
+ ## Type definitions
71
160
 
72
- isInternalRoute('/about'); // → true
73
- isInternalRoute('https://ext.com'); // → false
161
+ ### Status
162
+
163
+ ```tsx
164
+ type Status = 'success' | 'info' | 'warning' | 'error';
74
165
  ```
75
166
 
76
- ### findAllColors
167
+ Used for the status of Alert, Badge, Toast, and similar components.
77
168
 
78
- デザイントークンからすべてのカラーを抽出。
169
+ ### Direction
79
170
 
80
171
  ```tsx
81
- import { findAllColors } from '@k8ordo/ui';
82
-
83
- const colors = findAllColors();
172
+ type Direction = 'up' | 'down' | 'right' | 'left';
84
173
  ```
85
174
 
86
- ### uuidV4
175
+ Used to point ChevronIcon and similar icons.
87
176
 
88
- UUID v4 の生成。
177
+ ### Placement
89
178
 
90
179
  ```tsx
91
- import { uuidV4 } from '@k8ordo/ui';
92
-
93
- const id = uuidV4(); // → 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
180
+ type Placement =
181
+ | 'top'
182
+ | 'top-start'
183
+ | 'top-end'
184
+ | 'bottom'
185
+ | 'bottom-start'
186
+ | 'bottom-end'
187
+ | 'left'
188
+ | 'left-start'
189
+ | 'left-end'
190
+ | 'right'
191
+ | 'right-start'
192
+ | 'right-end';
94
193
  ```
95
194
 
96
- ## 型定義
195
+ Placement relative to an anchor element, for Popover, Tooltip, DropdownMenu,
196
+ and ListBox (the `placement` prop).
97
197
 
98
- ### Status
198
+ ### ModalSide
99
199
 
100
200
  ```tsx
101
- type Status = 'success' | 'info' | 'warning' | 'error';
201
+ type ModalSide = 'center' | 'bottom' | 'left' | 'right';
102
202
  ```
103
203
 
104
- Alert, Badge, Toast 等のステータス表示に使用。
204
+ Which viewport edge a Modal sticks to (the `side` prop). It is a different
205
+ idea from `Placement`, which is relative to an anchor, so the prop name differs
206
+ too.
105
207
 
106
- ### Direction
208
+ ### DrawerSide
107
209
 
108
210
  ```tsx
109
- type Direction = 'up' | 'down' | 'right' | 'left';
211
+ type DrawerSide = Extract<ModalSide, 'left' | 'right'>;
110
212
  ```
111
213
 
112
- ChevronIcon 等の方向指定に使用。
214
+ The subset of `ModalSide` a Drawer accepts: a drawer always slides in from an
215
+ edge, so `center` is excluded.
113
216
 
114
217
  ### Option
115
218
 
116
219
  ```tsx
117
- type Option = { value: string; label: string };
220
+ type Option = Readonly<{ value: string; label: string }>;
118
221
  ```
119
222
 
120
- Select, Autocomplete 等の選択肢に使用。
223
+ Used for the choices in Radio, Select, Autocomplete, and similar components.