@godxjp/ui 30.8.0 → 31.0.2

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 (56) hide show
  1. package/README.md +25 -2
  2. package/agent/START-HERE.md +1 -1
  3. package/agent/components/PrefetchLink.json +3 -3
  4. package/agent/components-index.json +1 -1
  5. package/agent/components.json +3 -3
  6. package/agent/index.json +2 -2
  7. package/agent/llms.txt +3 -3
  8. package/agent/patterns/settings-page-responsive.json +1 -1
  9. package/agent/patterns.json +1 -1
  10. package/dist/components/query/index.d.ts +0 -2
  11. package/dist/components/query/index.js +0 -2
  12. package/dist/components/react-router/index.d.ts +2 -0
  13. package/dist/components/react-router/index.js +4 -0
  14. package/dist/contracts/measurement.json +1 -1
  15. package/dist/styles/alert-layout.css +4 -2
  16. package/dist/styles/layers.json +1182 -0
  17. package/dist/styles/vendor-day-picker.css +2 -0
  18. package/dist/styles/vendor-sonner.css +2 -0
  19. package/docs/CONSUMER-RULES.md +1 -1
  20. package/docs/data-display/permission-matrix.tsx +30 -28
  21. package/docs/data-entry/cascader.tsx +22 -20
  22. package/docs/data-entry/date-picker.tsx +47 -43
  23. package/docs/data-entry/form-field/examples/a11y-contract.tsx +80 -76
  24. package/docs/data-entry/form-field/examples/create-form.tsx +33 -31
  25. package/docs/data-entry/form-field/index.tsx +61 -57
  26. package/docs/data-entry/form.tsx +112 -106
  27. package/docs/data-entry/input.tsx +297 -270
  28. package/docs/data-entry/label.tsx +11 -9
  29. package/docs/data-entry/number-input.tsx +86 -78
  30. package/docs/data-entry/radio-group.tsx +33 -26
  31. package/docs/data-entry/rating.tsx +29 -25
  32. package/docs/data-entry/select-matrix.tsx +49 -47
  33. package/docs/data-entry/select.tsx +38 -35
  34. package/docs/data-entry/slider.tsx +45 -41
  35. package/docs/data-entry/textarea.tsx +44 -42
  36. package/docs/data-entry/time-picker.tsx +51 -47
  37. package/docs/feedback/sheet.tsx +84 -79
  38. package/docs/foundation/theme-editor.tsx +133 -124
  39. package/docs/general/button/examples/form-actions.tsx +17 -15
  40. package/docs/layout/auth-recovery/examples/password-recovery.tsx +31 -29
  41. package/docs/layout/auth-shell-registration.tsx +75 -72
  42. package/docs/layout/auth-shell-variants.tsx +55 -51
  43. package/docs/layout/space-compact.tsx +11 -8
  44. package/docs/{query → react-router}/prefetch-link.tsx +1 -1
  45. package/docs/showcase/caimono-price-comparison.tsx +59 -51
  46. package/docs/showcase/case3-approval-workflow.tsx +27 -25
  47. package/docs/showcase/case4-login.tsx +37 -34
  48. package/docs/showcase/permission-matrix.tsx +44 -42
  49. package/docs/showcase/theme-customization.tsx +108 -99
  50. package/package.json +10 -3
  51. package/scripts/cli.mjs +15 -0
  52. package/scripts/consumer-rule.md +14 -0
  53. package/scripts/prune-css.mjs +221 -0
  54. package/scripts/ui-audit.mjs +99 -2
  55. /package/dist/components/{query → react-router}/prefetch-link.d.ts +0 -0
  56. /package/dist/components/{query → react-router}/prefetch-link.js +0 -0
@@ -0,0 +1,2 @@
1
+
2
+ @import "react-day-picker/style.css" layer(vendor);
@@ -0,0 +1,2 @@
1
+
2
+ @import "sonner/dist/styles.css" layer(vendor);
@@ -6,7 +6,7 @@ Read this once; the audit enforces it. Everything else in `docs/` is for contrib
6
6
  2. Every page is `<PageContainer title subtitle extra footer>`; its sections are spaced by the page. Group items inside a section with `<Flex direction="col" gap>` or `<ResponsiveGrid>`.
7
7
  3. No Tailwind layout on your own elements: no `flex`, `grid`, `gap-*`, `p-*`, `m-*`, `space-*`. Rows are `<Flex>` (default row), stacks are `<Flex direction="col">`, grids are `<ResponsiveGrid>`.
8
8
  4. No hand-rolled surfaces: no `rounded-* border bg-*` divs. A box is `Card`, a pill is `Badge`, a person is `Avatar`, a row is `ListRow`, a label/value pair is `Descriptions`, an empty area is `EmptyState`, a read-only sample of a colour the USER chose is `Swatch`. A LIST of those rows is `<Flex as="ul" marker="none" direction="col" gap="none">` with `<ListRow as="li">` children — `marker="none"` keeps the `<ul>`, the `<li>` semantics and the gap token while dropping the bullet and the indent. Never a raw `<ul>`/`<ol>` (it carries no gap token), never `<div role="list">` + `<div role="listitem">`, and never a wrapper around each row: the divider is `:not(:last-child)` among siblings, so a row alone in its own wrapper is always the last one and EVERY divider disappears silently. A bulleted prose list is the same `<Flex as="ul">` without `marker`.
9
- 5. Real controls only: `Button`, `Input`, `Select`, `Textarea`, `Checkbox`… never raw `<button>`/`<input>`; a labelled control lives in `<FormField label>`. A Select outside a form takes `width="auto"`. **A disabled control's reason is visible text, never a tooltip** — see below.
9
+ 5. Real controls only: `Button`, `Input`, `Select`, `Textarea`, `Checkbox`… never raw `<button>`/`<input>`; a labelled control lives in `<FormField label>`. A Select outside a form takes `width="auto"`. **A disabled control's reason is visible text, never a tooltip** — see below. **Fields live in a `<Form layout="horizontal" labelWidth controlWidth>`** — never a group of `FormField`s without one, never a hand-rolled `<Flex>` row of fields (a row that belongs together is `<SpaceCompact>` or `<Form columns>`); size each control for its content with `controlWidth` (GOV.UK text-input width: a port ~7rem, a short enum ~10rem); three or more fields is a page, not a Dialog. The audit rules are `formfield-needs-form`, `dialog-form-too-big` and `select-width-hint`. **A case the kit cannot express is an issue, not a hand-roll:** open it on godx-jp/godxjp-ui, use the nearest valid composition, and mark it `// TODO(godxjp-ui#<n>)` (gh#998).
10
10
  6. Text is `<Text>` / `<Heading>` with `tone`, `size`, `weight`, `truncate`, `mono` — not `className="text-muted-foreground font-semibold"`. A STANDALONE glyph is `<Icon as={Lock} size="sm" tone="muted" />` from `@godxjp/ui/general`: a bare lucide icon carries its own `width="24" height="24"` and only four places re-size it for you (`Button`, a `DropdownMenuItem`, a `TopbarItem`, a `ListRow` leading slot), so everywhere else — in a `Text`, a table cell, an `<a>` — it draws at 24px beside 14px type. `size-4` and `w-[16px]` are closed to you by rules 3 and 8, and `size={16}` hard-codes a number the theme owns; `Icon` puts the glyph on the `--icon-size-*` scale (`2xs…4xl`) instead, and is `aria-hidden` unless you give it a `label` (then it is `role="img"` with that name). The audit rule is `lucide-icon-needs-size`.
11
11
  7. Colours are semantic tokens (`tone="destructive"`, `bg-primary`), never palette names, hex, or `bg-black` / `text-white`.
12
12
  8. Sizes come from props (`size`, `width`, `columns`), never `w-[240px]` / `max-h-[420px]`.
@@ -17,7 +17,7 @@ import {
17
17
  CardTitle,
18
18
  PermissionMatrix,
19
19
  } from "@godxjp/ui/data-display";
20
- import { FormField, Label, Select, Switch } from "@godxjp/ui/data-entry";
20
+ import { Form, FormField, Label, Select, Switch } from "@godxjp/ui/data-entry";
21
21
  import { Flex, PageContainer } from "@godxjp/ui/layout";
22
22
  import { grantKey } from "@godxjp/ui/lib/permission-grid";
23
23
 
@@ -114,35 +114,37 @@ export default function Demo() {
114
114
  </CardHeader>
115
115
  <CardContent>
116
116
  <Flex direction="col" gap="md">
117
- <Flex direction="row" wrap align="end" gap="md">
118
- {/* Bare Select has NO accessible name (axe button-name) — the compare
117
+ <Form>
118
+ <Flex direction="row" wrap align="end" gap="md">
119
+ {/* Bare Select has NO accessible name (axe button-name) — the compare
119
120
  pickers are labelled through FormField, exactly as the showcase does. */}
120
- <FormField label="比較 A">
121
- <Select
122
- value={compareA}
123
- onValueChange={setCompareA}
124
- options={roleOptions}
125
- className="w-40"
126
- />
127
- </FormField>
128
- <FormField label="比較 B">
129
- <Select
130
- value={compareB}
131
- onValueChange={setCompareB}
132
- options={roleOptions}
133
- className="w-40"
134
- />
135
- </FormField>
136
- <Flex direction="row" align="center" gap="sm">
137
- <Switch
138
- id="pm-doc-diff-only"
139
- size="sm"
140
- checked={diffOnly}
141
- onCheckedChange={setDiffOnly}
142
- />
143
- <Label htmlFor="pm-doc-diff-only">差分のみ</Label>
121
+ <FormField label="比較 A">
122
+ <Select
123
+ value={compareA}
124
+ onValueChange={setCompareA}
125
+ options={roleOptions}
126
+ className="w-40"
127
+ />
128
+ </FormField>
129
+ <FormField label="比較 B">
130
+ <Select
131
+ value={compareB}
132
+ onValueChange={setCompareB}
133
+ options={roleOptions}
134
+ className="w-40"
135
+ />
136
+ </FormField>
137
+ <Flex direction="row" align="center" gap="sm">
138
+ <Switch
139
+ id="pm-doc-diff-only"
140
+ size="sm"
141
+ checked={diffOnly}
142
+ onCheckedChange={setDiffOnly}
143
+ />
144
+ <Label htmlFor="pm-doc-diff-only">差分のみ</Label>
145
+ </Flex>
144
146
  </Flex>
145
- </Flex>
147
+ </Form>
146
148
  <Card variant="outline" className="overflow-hidden">
147
149
  <CardContent flush>
148
150
  <div>
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
 
3
3
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
4
- import { Cascader, FormField } from "@godxjp/ui/data-entry";
4
+ import { Form, Cascader, FormField } from "@godxjp/ui/data-entry";
5
5
  import { Flex, PageContainer } from "@godxjp/ui/layout";
6
6
  import type { TreeOptionProp } from "@godxjp/ui/props";
7
7
 
@@ -351,25 +351,27 @@ export default function Demo() {
351
351
  </CardDescription>
352
352
  </CardHeader>
353
353
  <CardContent>
354
- <Flex direction="col" gap="md">
355
- <FormField id="disabled-empty" label="無効(未選択)">
356
- <Cascader
357
- id="disabled-empty"
358
- options={EXPENSE_CATEGORIES}
359
- disabled
360
- placeholder="カテゴリを選択..."
361
- />
362
- </FormField>
363
- <FormField id="disabled-selected" label="無効(選択済み)">
364
- <Cascader
365
- id="disabled-selected"
366
- options={EXPENSE_CATEGORIES}
367
- disabled
368
- defaultValue={["operating", "admin", "salary"]}
369
- placeholder="カテゴリを選択..."
370
- />
371
- </FormField>
372
- </Flex>
354
+ <Form>
355
+ <Flex direction="col" gap="md">
356
+ <FormField id="disabled-empty" label="無効(未選択)">
357
+ <Cascader
358
+ id="disabled-empty"
359
+ options={EXPENSE_CATEGORIES}
360
+ disabled
361
+ placeholder="カテゴリを選択..."
362
+ />
363
+ </FormField>
364
+ <FormField id="disabled-selected" label="無効(選択済み)">
365
+ <Cascader
366
+ id="disabled-selected"
367
+ options={EXPENSE_CATEGORIES}
368
+ disabled
369
+ defaultValue={["operating", "admin", "salary"]}
370
+ placeholder="カテゴリを選択..."
371
+ />
372
+ </FormField>
373
+ </Flex>
374
+ </Form>
373
375
  </CardContent>
374
376
  </Card>
375
377
  </Flex>
@@ -2,7 +2,7 @@ import { useState } from "react";
2
2
  import { ja } from "date-fns/locale";
3
3
 
4
4
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
5
- import { DatePicker, FormField } from "@godxjp/ui/data-entry";
5
+ import { Form, DatePicker, FormField } from "@godxjp/ui/data-entry";
6
6
  import { Flex, PageContainer } from "@godxjp/ui/layout";
7
7
  import type { DateRange } from "react-day-picker";
8
8
 
@@ -65,23 +65,25 @@ export default function Demo() {
65
65
  </CardDescription>
66
66
  </CardHeader>
67
67
  <CardContent>
68
- <Flex gap="lg" wrap>
69
- <FormField id="ruled-date" label="罫線あり (既定)">
70
- <DatePicker
71
- id="ruled-date"
72
- name="ruled_date"
73
- defaultValue={new Date(2026, 0, 15)}
74
- />
75
- </FormField>
76
- <FormField id="unruled-date" label="罫線なし (bordered={false})">
77
- <DatePicker
78
- id="unruled-date"
79
- name="unruled_date"
80
- defaultValue={new Date(2026, 0, 15)}
81
- bordered={false}
82
- />
83
- </FormField>
84
- </Flex>
68
+ <Form>
69
+ <Flex gap="lg" wrap>
70
+ <FormField id="ruled-date" label="罫線あり (既定)">
71
+ <DatePicker
72
+ id="ruled-date"
73
+ name="ruled_date"
74
+ defaultValue={new Date(2026, 0, 15)}
75
+ />
76
+ </FormField>
77
+ <FormField id="unruled-date" label="罫線なし (bordered={false})">
78
+ <DatePicker
79
+ id="unruled-date"
80
+ name="unruled_date"
81
+ defaultValue={new Date(2026, 0, 15)}
82
+ bordered={false}
83
+ />
84
+ </FormField>
85
+ </Flex>
86
+ </Form>
85
87
  </CardContent>
86
88
  </Card>
87
89
 
@@ -231,31 +233,33 @@ export default function Demo() {
231
233
  <CardTitle level={2}>表示形式と元号</CardTitle>
232
234
  </CardHeader>
233
235
  <CardContent>
234
- <Flex direction="col" gap="md">
235
- <FormField id="formatted-date" label="契約日">
236
- <DatePicker
237
- id="formatted-date"
238
- name="contract"
239
- defaultValue={new Date(2026, 8, 9)}
240
- format="yyyy年MM月dd日"
241
- />
242
- </FormField>
243
- <FormField id="era-date" label="和暦">
244
- <DatePicker
245
- id="era-date"
246
- name="era"
247
- defaultValue={new Date(2026, 8, 9)}
248
- format={{
249
- calendar: "japanese",
250
- era: "long",
251
- year: "numeric",
252
- month: "long",
253
- day: "numeric",
254
- }}
255
- inputReadOnly
256
- />
257
- </FormField>
258
- </Flex>
236
+ <Form>
237
+ <Flex direction="col" gap="md">
238
+ <FormField id="formatted-date" label="契約日">
239
+ <DatePicker
240
+ id="formatted-date"
241
+ name="contract"
242
+ defaultValue={new Date(2026, 8, 9)}
243
+ format="yyyy年MM月dd日"
244
+ />
245
+ </FormField>
246
+ <FormField id="era-date" label="和暦">
247
+ <DatePicker
248
+ id="era-date"
249
+ name="era"
250
+ defaultValue={new Date(2026, 8, 9)}
251
+ format={{
252
+ calendar: "japanese",
253
+ era: "long",
254
+ year: "numeric",
255
+ month: "long",
256
+ day: "numeric",
257
+ }}
258
+ inputReadOnly
259
+ />
260
+ </FormField>
261
+ </Flex>
262
+ </Form>
259
263
  </CardContent>
260
264
  </Card>
261
265
  <Card>
@@ -96,53 +96,55 @@ export default function Demo() {
96
96
  </CardDescription>
97
97
  </CardHeader>
98
98
  <CardContent>
99
- <Flex direction="col" gap="md">
100
- <FormField id="ac-account" label="勘定科目" required helper="仕訳で使用する科目">
101
- <Select
102
- id="ac-account"
103
- name="account"
104
- showSearch
105
- options={[
106
- { value: "sales", label: "売上高" },
107
- { value: "rent", label: "地代家賃" },
108
- { value: "misc", label: "雑費" },
109
- ]}
110
- onValueChange={() => {}}
111
- />
112
- </FormField>
113
- <FormField id="ac-currency" label="通貨" helper="ISO 4217">
114
- <Select
115
- id="ac-currency"
116
- name="currency"
117
- options={CURRENCIES}
118
- onValueChange={() => {}}
119
- />
120
- </FormField>
121
- <FormField id="ac-region" label="地域" helper="都道府県まで選択">
122
- <Cascader id="ac-region" options={REGIONS} onValueChange={() => {}} />
123
- </FormField>
124
- <FormField id="ac-category" label="カテゴリ" helper="ツリーから選択">
125
- <TreeSelect id="ac-category" treeData={CATEGORIES} onValueChange={() => {}} />
126
- </FormField>
127
- <FormField id="ac-date" label="取引日" helper="yyyy-MM-dd">
128
- <DatePicker id="ac-date" name="date" />
129
- </FormField>
130
- <FormField id="ac-month" label="対象月" helper="yyyy-MM">
131
- <DatePicker picker="month" id="ac-month" name="month" />
132
- </FormField>
133
- <FormField id="ac-time" label="締め時刻" helper="24時間表記">
134
- <TimePicker id="ac-time" name="time" />
135
- </FormField>
136
- <FormField id="ac-period" label="対象期間" helper="開始日と終了日">
137
- <DatePicker range id="ac-period" name="period" />
138
- </FormField>
139
- <FormField id="ac-color" label="タグ色" helper="16進カラー">
140
- <ColorPicker id="ac-color" onValueChange={() => {}} />
141
- </FormField>
142
- <FormField id="ac-search" label="取引先検索" helper="名称の一部で検索">
143
- <SearchInput id="ac-search" />
144
- </FormField>
145
- </Flex>
99
+ <Form>
100
+ <Flex direction="col" gap="md">
101
+ <FormField id="ac-account" label="勘定科目" required helper="仕訳で使用する科目">
102
+ <Select
103
+ id="ac-account"
104
+ name="account"
105
+ showSearch
106
+ options={[
107
+ { value: "sales", label: "売上高" },
108
+ { value: "rent", label: "地代家賃" },
109
+ { value: "misc", label: "雑費" },
110
+ ]}
111
+ onValueChange={() => {}}
112
+ />
113
+ </FormField>
114
+ <FormField id="ac-currency" label="通貨" helper="ISO 4217">
115
+ <Select
116
+ id="ac-currency"
117
+ name="currency"
118
+ options={CURRENCIES}
119
+ onValueChange={() => {}}
120
+ />
121
+ </FormField>
122
+ <FormField id="ac-region" label="地域" helper="都道府県まで選択">
123
+ <Cascader id="ac-region" options={REGIONS} onValueChange={() => {}} />
124
+ </FormField>
125
+ <FormField id="ac-category" label="カテゴリ" helper="ツリーから選択">
126
+ <TreeSelect id="ac-category" treeData={CATEGORIES} onValueChange={() => {}} />
127
+ </FormField>
128
+ <FormField id="ac-date" label="取引日" helper="yyyy-MM-dd">
129
+ <DatePicker id="ac-date" name="date" />
130
+ </FormField>
131
+ <FormField id="ac-month" label="対象月" helper="yyyy-MM">
132
+ <DatePicker picker="month" id="ac-month" name="month" />
133
+ </FormField>
134
+ <FormField id="ac-time" label="締め時刻" helper="24時間表記">
135
+ <TimePicker id="ac-time" name="time" />
136
+ </FormField>
137
+ <FormField id="ac-period" label="対象期間" helper="開始日と終了日">
138
+ <DatePicker range id="ac-period" name="period" />
139
+ </FormField>
140
+ <FormField id="ac-color" label="タグ色" helper="16進カラー">
141
+ <ColorPicker id="ac-color" onValueChange={() => {}} />
142
+ </FormField>
143
+ <FormField id="ac-search" label="取引先検索" helper="名称の一部で検索">
144
+ <SearchInput id="ac-search" />
145
+ </FormField>
146
+ </Flex>
147
+ </Form>
146
148
  </CardContent>
147
149
  </Card>
148
150
 
@@ -155,36 +157,38 @@ export default function Demo() {
155
157
  </CardDescription>
156
158
  </CardHeader>
157
159
  <CardContent>
158
- <Flex direction="col" gap="md">
159
- <FormField
160
- id="ac-method"
161
- label="支払方法"
162
- required
163
- error="支払方法を選択してください"
164
- >
165
- <RadioGroup
160
+ <Form>
161
+ <Flex direction="col" gap="md">
162
+ <FormField
166
163
  id="ac-method"
167
- options={[
168
- { value: "bank", label: "銀行振込" },
169
- { value: "card", label: "クレジットカード" },
170
- { value: "cash", label: "現金" },
171
- ]}
172
- onValueChange={() => {}}
173
- />
174
- </FormField>
175
- <FormField id="ac-tags" label="タグ" helper="複数選択できます">
176
- <CheckboxGroup
177
- id="ac-tags"
178
- orientation="horizontal"
179
- options={[
180
- { value: "urgent", label: "至急" },
181
- { value: "review", label: "要確認" },
182
- { value: "archived", label: "アーカイブ" },
183
- ]}
184
- onValueChange={() => {}}
185
- />
186
- </FormField>
187
- </Flex>
164
+ label="支払方法"
165
+ required
166
+ error="支払方法を選択してください"
167
+ >
168
+ <RadioGroup
169
+ id="ac-method"
170
+ options={[
171
+ { value: "bank", label: "銀行振込" },
172
+ { value: "card", label: "クレジットカード" },
173
+ { value: "cash", label: "現金" },
174
+ ]}
175
+ onValueChange={() => {}}
176
+ />
177
+ </FormField>
178
+ <FormField id="ac-tags" label="タグ" helper="複数選択できます">
179
+ <CheckboxGroup
180
+ id="ac-tags"
181
+ orientation="horizontal"
182
+ options={[
183
+ { value: "urgent", label: "至急" },
184
+ { value: "review", label: "要確認" },
185
+ { value: "archived", label: "アーカイブ" },
186
+ ]}
187
+ onValueChange={() => {}}
188
+ />
189
+ </FormField>
190
+ </Flex>
191
+ </Form>
188
192
  </CardContent>
189
193
  </Card>
190
194
 
@@ -1,6 +1,6 @@
1
1
  import { useState } from "react";
2
2
 
3
- import { Field, FormField, Input, Select, Switch, Textarea } from "@godxjp/ui/data-entry";
3
+ import { Form, Field, FormField, Input, Select, Switch, Textarea } from "@godxjp/ui/data-entry";
4
4
  import { Button } from "@godxjp/ui/general";
5
5
  import { Avatar, AvatarFallback } from "@godxjp/ui/data-display";
6
6
  import {
@@ -69,36 +69,38 @@ export default function Demo() {
69
69
  </Flex>
70
70
  }
71
71
  >
72
- <Flex direction="col" gap="md" className="max-w-2xl">
73
- <FormField id="cf-name" label="取引先名" required helper="最大50文字">
74
- <Input id="cf-name" placeholder="株式会社ベトヤ" />
75
- </FormField>
76
- <FormField id="cf-code" label="取引先コード" required helper="一意のコードを入力">
77
- <Input id="cf-code" placeholder="BTY-0012" />
78
- </FormField>
79
- <FormField id="cf-type" label="区分">
80
- <Select
81
- id="cf-type"
82
- name="type"
83
- value={type}
84
- onValueChange={setType}
85
- options={[
86
- { value: "corp", label: "法人" },
87
- { value: "indiv", label: "個人事業主" },
88
- ]}
89
- />
90
- </FormField>
91
- <FormField id="cf-memo" label="メモ" helper="任意">
92
- <Textarea id="cf-memo" placeholder="例: 4月分から取引開始" />
93
- </FormField>
94
- <Field
95
- id="cf-active"
96
- label="取引を有効にする"
97
- description="無効にすると新規取引を登録できません"
98
- >
99
- <Switch id="cf-active" defaultChecked />
100
- </Field>
101
- </Flex>
72
+ <Form>
73
+ <Flex direction="col" gap="md" className="max-w-2xl">
74
+ <FormField id="cf-name" label="取引先名" required helper="最大50文字">
75
+ <Input id="cf-name" placeholder="株式会社ベトヤ" />
76
+ </FormField>
77
+ <FormField id="cf-code" label="取引先コード" required helper="一意のコードを入力">
78
+ <Input id="cf-code" placeholder="BTY-0012" />
79
+ </FormField>
80
+ <FormField id="cf-type" label="区分">
81
+ <Select
82
+ id="cf-type"
83
+ name="type"
84
+ value={type}
85
+ onValueChange={setType}
86
+ options={[
87
+ { value: "corp", label: "法人" },
88
+ { value: "indiv", label: "個人事業主" },
89
+ ]}
90
+ />
91
+ </FormField>
92
+ <FormField id="cf-memo" label="メモ" helper="任意">
93
+ <Textarea id="cf-memo" placeholder="例: 4月分から取引開始" />
94
+ </FormField>
95
+ <Field
96
+ id="cf-active"
97
+ label="取引を有効にする"
98
+ description="無効にすると新規取引を登録できません"
99
+ >
100
+ <Switch id="cf-active" defaultChecked />
101
+ </Field>
102
+ </Flex>
103
+ </Form>
102
104
  </PageContainer>
103
105
  </AppShell>
104
106
  );