@godxjp/ui 30.9.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 (52) hide show
  1. package/README.md +2 -1
  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 +1 -1
  17. package/docs/CONSUMER-RULES.md +1 -1
  18. package/docs/data-display/permission-matrix.tsx +30 -28
  19. package/docs/data-entry/cascader.tsx +22 -20
  20. package/docs/data-entry/date-picker.tsx +47 -43
  21. package/docs/data-entry/form-field/examples/a11y-contract.tsx +80 -76
  22. package/docs/data-entry/form-field/examples/create-form.tsx +33 -31
  23. package/docs/data-entry/form-field/index.tsx +61 -57
  24. package/docs/data-entry/form.tsx +112 -106
  25. package/docs/data-entry/input.tsx +297 -270
  26. package/docs/data-entry/label.tsx +11 -9
  27. package/docs/data-entry/number-input.tsx +86 -78
  28. package/docs/data-entry/radio-group.tsx +33 -26
  29. package/docs/data-entry/rating.tsx +29 -25
  30. package/docs/data-entry/select-matrix.tsx +49 -47
  31. package/docs/data-entry/select.tsx +38 -35
  32. package/docs/data-entry/slider.tsx +45 -41
  33. package/docs/data-entry/textarea.tsx +44 -42
  34. package/docs/data-entry/time-picker.tsx +51 -47
  35. package/docs/feedback/sheet.tsx +84 -79
  36. package/docs/foundation/theme-editor.tsx +133 -124
  37. package/docs/general/button/examples/form-actions.tsx +17 -15
  38. package/docs/layout/auth-recovery/examples/password-recovery.tsx +31 -29
  39. package/docs/layout/auth-shell-registration.tsx +75 -72
  40. package/docs/layout/auth-shell-variants.tsx +55 -51
  41. package/docs/layout/space-compact.tsx +11 -8
  42. package/docs/{query → react-router}/prefetch-link.tsx +1 -1
  43. package/docs/showcase/caimono-price-comparison.tsx +59 -51
  44. package/docs/showcase/case3-approval-workflow.tsx +27 -25
  45. package/docs/showcase/case4-login.tsx +37 -34
  46. package/docs/showcase/permission-matrix.tsx +44 -42
  47. package/docs/showcase/theme-customization.tsx +108 -99
  48. package/package.json +6 -2
  49. package/scripts/consumer-rule.md +14 -0
  50. package/scripts/ui-audit.mjs +99 -2
  51. /package/dist/components/{query → react-router}/prefetch-link.d.ts +0 -0
  52. /package/dist/components/{query → react-router}/prefetch-link.js +0 -0
@@ -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 { FormField, Slider } from "@godxjp/ui/data-entry";
4
+ import { Form, FormField, Slider } from "@godxjp/ui/data-entry";
5
5
  import { Flex, PageContainer, ResponsiveGrid } from "@godxjp/ui/layout";
6
6
  import { Text } from "@godxjp/ui/general";
7
7
 
@@ -148,23 +148,25 @@ export default function Demo() {
148
148
  </CardDescription>
149
149
  </CardHeader>
150
150
  <CardContent>
151
- <ResponsiveGrid columns={{ base: 1, md: 2 }} gap="lg">
152
- <FormField id="bands" label={`区切り: ${bands.join(" / ")}`}>
153
- <Slider
154
- range={{ editable: true, minCount: 1, maxCount: 4, draggableTrack: false }}
155
- value={bands}
156
- onChange={setBands}
157
- step={5}
158
- />
159
- </FormField>
160
- <FormField id="scale" label="評価スケール (included={false})">
161
- <Slider
162
- defaultValue={50}
163
- included={false}
164
- marks={{ 0: "低", 50: "中", 100: "高" }}
165
- />
166
- </FormField>
167
- </ResponsiveGrid>
151
+ <Form>
152
+ <ResponsiveGrid columns={{ base: 1, md: 2 }} gap="lg">
153
+ <FormField id="bands" label={`区切り: ${bands.join(" / ")}`}>
154
+ <Slider
155
+ range={{ editable: true, minCount: 1, maxCount: 4, draggableTrack: false }}
156
+ value={bands}
157
+ onChange={setBands}
158
+ step={5}
159
+ />
160
+ </FormField>
161
+ <FormField id="scale" label="評価スケール (included={false})">
162
+ <Slider
163
+ defaultValue={50}
164
+ included={false}
165
+ marks={{ 0: "低", 50: "中", 100: "高" }}
166
+ />
167
+ </FormField>
168
+ </ResponsiveGrid>
169
+ </Form>
168
170
  </CardContent>
169
171
  </Card>
170
172
 
@@ -177,29 +179,31 @@ export default function Demo() {
177
179
  </CardDescription>
178
180
  </CardHeader>
179
181
  <CardContent>
180
- <ResponsiveGrid columns={{ base: 1, md: 3 }} gap="lg">
181
- <FormField id="volume-vertical" label={`音量 (縦): ${volume}`}>
182
- <Slider
183
- vertical
184
- value={volume}
185
- onChange={setVolume}
186
- marks={{ 0: "0", 50: "50", 100: "100" }}
187
- tooltip
188
- />
189
- </FormField>
190
- <FormField id="countdown" label="残り日数 (reverse)">
191
- <Slider
192
- reverse
193
- defaultValue={30}
194
- max={60}
195
- step={5}
196
- marks={{ 0: "0日", 30: "30日", 60: "60日" }}
197
- />
198
- </FormField>
199
- <FormField id="locked-rate" label="確定済み税率 (変更不可)">
200
- <Slider value={10} disabled min={0} max={20} step={1} />
201
- </FormField>
202
- </ResponsiveGrid>
182
+ <Form>
183
+ <ResponsiveGrid columns={{ base: 1, md: 3 }} gap="lg">
184
+ <FormField id="volume-vertical" label={`音量 (縦): ${volume}`}>
185
+ <Slider
186
+ vertical
187
+ value={volume}
188
+ onChange={setVolume}
189
+ marks={{ 0: "0", 50: "50", 100: "100" }}
190
+ tooltip
191
+ />
192
+ </FormField>
193
+ <FormField id="countdown" label="残り日数 (reverse)">
194
+ <Slider
195
+ reverse
196
+ defaultValue={30}
197
+ max={60}
198
+ step={5}
199
+ marks={{ 0: "0日", 30: "30日", 60: "60日" }}
200
+ />
201
+ </FormField>
202
+ <FormField id="locked-rate" label="確定済み税率 (変更不可)">
203
+ <Slider value={10} disabled min={0} max={20} step={1} />
204
+ </FormField>
205
+ </ResponsiveGrid>
206
+ </Form>
203
207
  </CardContent>
204
208
  </Card>
205
209
  </Flex>
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
 
3
3
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
4
- import { FormField, Textarea } from "@godxjp/ui/data-entry";
4
+ import { Form, FormField, Textarea } from "@godxjp/ui/data-entry";
5
5
  import { Button } from "@godxjp/ui/general";
6
6
  import { Flex, PageContainer } from "@godxjp/ui/layout";
7
7
 
@@ -145,50 +145,52 @@ export default function Demo() {
145
145
  </CardDescription>
146
146
  </CardHeader>
147
147
  <CardContent>
148
- <Flex direction="col" gap="md">
149
- <FormField
150
- id="autogrow-ceiling"
151
- label="上限あり (minRows=1 / maxRows=3)"
152
- helper="4行目からは箱が伸びずに内部スクロールへ切り替わります。"
153
- >
154
- <Textarea
148
+ <Form>
149
+ <Flex direction="col" gap="md">
150
+ <FormField
155
151
  id="autogrow-ceiling"
156
- autoGrow
157
- minRows={1}
158
- maxRows={3}
159
- defaultValue={"1行目\n2行目\n3行目\n4行目\n5行目\n6行目"}
160
- />
161
- </FormField>
162
-
163
- <FormField
164
- id="autogrow-floor"
165
- label="下限あり (minRows=3)"
166
- helper="空でも3行分の高さを保ちます。"
167
- >
168
- <Textarea
152
+ label="上限あり (minRows=1 / maxRows=3)"
153
+ helper="4行目からは箱が伸びずに内部スクロールへ切り替わります。"
154
+ >
155
+ <Textarea
156
+ id="autogrow-ceiling"
157
+ autoGrow
158
+ minRows={1}
159
+ maxRows={3}
160
+ defaultValue={"1行目\n2行目\n3行目\n4行目\n5行目\n6行目"}
161
+ />
162
+ </FormField>
163
+
164
+ <FormField
169
165
  id="autogrow-floor"
170
- autoGrow
171
- minRows={3}
172
- placeholder="社内メモ..."
173
- allowClear
174
- />
175
- </FormField>
176
-
177
- <FormField
178
- id="autogrow-unbounded"
179
- label="上限なし (maxRows=0)"
180
- helper="ページ側にスクロールを持つ画面でのみ使ってください。"
181
- >
182
- <Textarea
166
+ label="下限あり (minRows=3)"
167
+ helper="空でも3行分の高さを保ちます。"
168
+ >
169
+ <Textarea
170
+ id="autogrow-floor"
171
+ autoGrow
172
+ minRows={3}
173
+ placeholder="社内メモ..."
174
+ allowClear
175
+ />
176
+ </FormField>
177
+
178
+ <FormField
183
179
  id="autogrow-unbounded"
184
- autoGrow
185
- maxRows={0}
186
- defaultValue={
187
- "長文の下書きを最後まで見せたい画面向け。\n箱は内容に合わせて伸び続けます。"
188
- }
189
- />
190
- </FormField>
191
- </Flex>
180
+ label="上限なし (maxRows=0)"
181
+ helper="ページ側にスクロールを持つ画面でのみ使ってください。"
182
+ >
183
+ <Textarea
184
+ id="autogrow-unbounded"
185
+ autoGrow
186
+ maxRows={0}
187
+ defaultValue={
188
+ "長文の下書きを最後まで見せたい画面向け。\n箱は内容に合わせて伸び続けます。"
189
+ }
190
+ />
191
+ </FormField>
192
+ </Flex>
193
+ </Form>
192
194
  </CardContent>
193
195
  </Card>
194
196
 
@@ -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 { FormField, TimePicker, TimeRangePicker } from "@godxjp/ui/data-entry";
4
+ import { Form, FormField, TimePicker, TimeRangePicker } from "@godxjp/ui/data-entry";
5
5
  import { Flex, PageContainer } from "@godxjp/ui/layout";
6
6
 
7
7
  /**
@@ -51,28 +51,30 @@ export default function Demo() {
51
51
  </CardDescription>
52
52
  </CardHeader>
53
53
  <CardContent>
54
- <Flex direction="row" gap="md" wrap>
55
- <FormField id="shift-start" label="出勤時刻">
56
- <TimePicker
57
- id="shift-start"
58
- name="shift_start"
59
- value={shiftStart}
60
- onValueChange={setShiftStart}
61
- minuteStep={15}
62
- className="w-36"
63
- />
64
- </FormField>
65
- <FormField id="shift-end" label="退勤時刻">
66
- <TimePicker
67
- id="shift-end"
68
- name="shift_end"
69
- value={shiftEnd}
70
- onValueChange={setShiftEnd}
71
- minuteStep={15}
72
- className="w-36"
73
- />
74
- </FormField>
75
- </Flex>
54
+ <Form>
55
+ <Flex direction="row" gap="md" wrap>
56
+ <FormField id="shift-start" label="出勤時刻">
57
+ <TimePicker
58
+ id="shift-start"
59
+ name="shift_start"
60
+ value={shiftStart}
61
+ onValueChange={setShiftStart}
62
+ minuteStep={15}
63
+ className="w-36"
64
+ />
65
+ </FormField>
66
+ <FormField id="shift-end" label="退勤時刻">
67
+ <TimePicker
68
+ id="shift-end"
69
+ name="shift_end"
70
+ value={shiftEnd}
71
+ onValueChange={setShiftEnd}
72
+ minuteStep={15}
73
+ className="w-36"
74
+ />
75
+ </FormField>
76
+ </Flex>
77
+ </Form>
76
78
  </CardContent>
77
79
  </Card>
78
80
 
@@ -135,30 +137,32 @@ export default function Demo() {
135
137
  <CardTitle level={2}>入力状態</CardTitle>
136
138
  </CardHeader>
137
139
  <CardContent>
138
- <Flex direction="col" gap="md">
139
- <FormField id="readonly-time" label="選択のみ">
140
- <TimePicker
141
- id="readonly-time"
142
- inputReadOnly
143
- defaultValue="09:00"
144
- allowClear={false}
145
- size="sm"
146
- variant="filled"
147
- />
148
- </FormField>
149
- <FormField id="invalid-time" label="入力を保持">
150
- <TimePicker id="invalid-time" preserveInvalidOnBlur status="error" size="lg" />
151
- </FormField>
152
- <FormField id="quiet-time" label="任意時刻">
153
- <TimePicker
154
- id="quiet-time"
155
- variant="borderless"
156
- status="warning"
157
- placement="top-start"
158
- showNow={false}
159
- />
160
- </FormField>
161
- </Flex>
140
+ <Form>
141
+ <Flex direction="col" gap="md">
142
+ <FormField id="readonly-time" label="選択のみ">
143
+ <TimePicker
144
+ id="readonly-time"
145
+ inputReadOnly
146
+ defaultValue="09:00"
147
+ allowClear={false}
148
+ size="sm"
149
+ variant="filled"
150
+ />
151
+ </FormField>
152
+ <FormField id="invalid-time" label="入力を保持">
153
+ <TimePicker id="invalid-time" preserveInvalidOnBlur status="error" size="lg" />
154
+ </FormField>
155
+ <FormField id="quiet-time" label="任意時刻">
156
+ <TimePicker
157
+ id="quiet-time"
158
+ variant="borderless"
159
+ status="warning"
160
+ placement="top-start"
161
+ showNow={false}
162
+ />
163
+ </FormField>
164
+ </Flex>
165
+ </Form>
162
166
  </CardContent>
163
167
  </Card>
164
168
  <Card>
@@ -20,6 +20,7 @@ import {
20
20
  } from "@godxjp/ui/data-display";
21
21
  import { Button, Text } from "@godxjp/ui/general";
22
22
  import {
23
+ Form,
23
24
  FormField,
24
25
  Input,
25
26
  Select,
@@ -139,69 +140,71 @@ export default function Demo() {
139
140
  extra={<Badge tone="info">3 条件</Badge>}
140
141
  />
141
142
  <SheetBody>
142
- <Flex direction="col" gap="md">
143
- <FormField id="filter-account" label="勘定科目">
144
- <Select aria-label="勘定科目" value={account} onValueChange={setAccount}>
145
- <SelectTrigger id="filter-account">
146
- <SelectValue placeholder="すべての勘定科目" />
147
- </SelectTrigger>
148
- <SelectContent>
149
- <SelectItem value="all">すべての勘定科目</SelectItem>
150
- <SelectItem value="cash">現金</SelectItem>
151
- <SelectItem value="sales">売上高</SelectItem>
152
- <SelectItem value="expense">旅費交通費</SelectItem>
153
- </SelectContent>
154
- </Select>
155
- </FormField>
156
- <FormField id="filter-status" label="ステータス">
157
- <Select aria-label="ステータス" value={status} onValueChange={setStatus}>
158
- <SelectTrigger id="filter-status">
159
- <SelectValue placeholder="すべてのステータス" />
160
- </SelectTrigger>
161
- <SelectContent>
162
- <SelectItem value="all">すべてのステータス</SelectItem>
163
- <SelectItem value="draft">下書き</SelectItem>
164
- <SelectItem value="approved">承認済み</SelectItem>
165
- </SelectContent>
166
- </Select>
167
- </FormField>
168
- <FormField id="filter-source" label="ソース">
169
- <Select aria-label="ソース" value={source} onValueChange={setSource}>
170
- <SelectTrigger id="filter-source">
171
- <SelectValue placeholder="すべてのソース" />
172
- </SelectTrigger>
173
- <SelectContent>
174
- <SelectItem value="all">すべてのソース</SelectItem>
175
- <SelectItem value="manual">手入力</SelectItem>
176
- <SelectItem value="import">インポート</SelectItem>
177
- </SelectContent>
178
- </Select>
179
- </FormField>
180
- <FormField id="filter-amount-min" label="金額">
181
- <Flex direction="row" gap="sm" align="center">
182
- <Input
183
- id="filter-amount-min"
184
- className="min-w-0 flex-1"
185
- inputMode="numeric"
186
- placeholder="最小"
187
- value={minAmount}
188
- onChange={(e) => setMinAmount(e.target.value)}
189
- />
190
- <Text tone="muted" aria-hidden="true">
191
- –
192
- </Text>
193
- <Input
194
- id="filter-amount-max"
195
- aria-label="最大金額"
196
- className="min-w-0 flex-1"
197
- inputMode="numeric"
198
- placeholder="最大"
199
- value={maxAmount}
200
- onChange={(e) => setMaxAmount(e.target.value)}
201
- />
202
- </Flex>
203
- </FormField>
204
- </Flex>
143
+ <Form>
144
+ <Flex direction="col" gap="md">
145
+ <FormField id="filter-account" label="勘定科目">
146
+ <Select aria-label="勘定科目" value={account} onValueChange={setAccount}>
147
+ <SelectTrigger id="filter-account">
148
+ <SelectValue placeholder="すべての勘定科目" />
149
+ </SelectTrigger>
150
+ <SelectContent>
151
+ <SelectItem value="all">すべての勘定科目</SelectItem>
152
+ <SelectItem value="cash">現金</SelectItem>
153
+ <SelectItem value="sales">売上高</SelectItem>
154
+ <SelectItem value="expense">旅費交通費</SelectItem>
155
+ </SelectContent>
156
+ </Select>
157
+ </FormField>
158
+ <FormField id="filter-status" label="ステータス">
159
+ <Select aria-label="ステータス" value={status} onValueChange={setStatus}>
160
+ <SelectTrigger id="filter-status">
161
+ <SelectValue placeholder="すべてのステータス" />
162
+ </SelectTrigger>
163
+ <SelectContent>
164
+ <SelectItem value="all">すべてのステータス</SelectItem>
165
+ <SelectItem value="draft">下書き</SelectItem>
166
+ <SelectItem value="approved">承認済み</SelectItem>
167
+ </SelectContent>
168
+ </Select>
169
+ </FormField>
170
+ <FormField id="filter-source" label="ソース">
171
+ <Select aria-label="ソース" value={source} onValueChange={setSource}>
172
+ <SelectTrigger id="filter-source">
173
+ <SelectValue placeholder="すべてのソース" />
174
+ </SelectTrigger>
175
+ <SelectContent>
176
+ <SelectItem value="all">すべてのソース</SelectItem>
177
+ <SelectItem value="manual">手入力</SelectItem>
178
+ <SelectItem value="import">インポート</SelectItem>
179
+ </SelectContent>
180
+ </Select>
181
+ </FormField>
182
+ <FormField id="filter-amount-min" label="金額">
183
+ <Flex direction="row" gap="sm" align="center">
184
+ <Input
185
+ id="filter-amount-min"
186
+ className="min-w-0 flex-1"
187
+ inputMode="numeric"
188
+ placeholder="最小"
189
+ value={minAmount}
190
+ onChange={(e) => setMinAmount(e.target.value)}
191
+ />
192
+ <Text tone="muted" aria-hidden="true">
193
+ –
194
+ </Text>
195
+ <Input
196
+ id="filter-amount-max"
197
+ aria-label="最大金額"
198
+ className="min-w-0 flex-1"
199
+ inputMode="numeric"
200
+ placeholder="最大"
201
+ value={maxAmount}
202
+ onChange={(e) => setMaxAmount(e.target.value)}
203
+ />
204
+ </Flex>
205
+ </FormField>
206
+ </Flex>
207
+ </Form>
205
208
  </SheetBody>
206
209
  <SheetFooter>
207
210
  <Button
@@ -245,22 +248,24 @@ export default function Demo() {
245
248
  <SheetDescription>取引先の基本情報を編集します。</SheetDescription>
246
249
  </SheetHeader>
247
250
  <SheetBody>
248
- <Flex direction="col" gap="md">
249
- <FormField id="edit-company" label="会社名" required>
250
- <Input
251
- id="edit-company"
252
- value={companyName}
253
- onChange={(e) => setCompanyName(e.target.value)}
254
- />
255
- </FormField>
256
- <FormField id="edit-registration" label="登録番号" helper="T + 13桁">
257
- <Input
258
- id="edit-registration"
259
- value={registration}
260
- onChange={(e) => setRegistration(e.target.value)}
261
- />
262
- </FormField>
263
- </Flex>
251
+ <Form>
252
+ <Flex direction="col" gap="md">
253
+ <FormField id="edit-company" label="会社名" required>
254
+ <Input
255
+ id="edit-company"
256
+ value={companyName}
257
+ onChange={(e) => setCompanyName(e.target.value)}
258
+ />
259
+ </FormField>
260
+ <FormField id="edit-registration" label="登録番号" helper="T + 13桁">
261
+ <Input
262
+ id="edit-registration"
263
+ value={registration}
264
+ onChange={(e) => setRegistration(e.target.value)}
265
+ />
266
+ </FormField>
267
+ </Flex>
268
+ </Form>
264
269
  </SheetBody>
265
270
  <SheetFooter>
266
271
  <Button variant="outline" onClick={() => setEditOpen(false)}>