@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.
- package/README.md +25 -2
- package/agent/START-HERE.md +1 -1
- package/agent/components/PrefetchLink.json +3 -3
- package/agent/components-index.json +1 -1
- package/agent/components.json +3 -3
- package/agent/index.json +2 -2
- package/agent/llms.txt +3 -3
- package/agent/patterns/settings-page-responsive.json +1 -1
- package/agent/patterns.json +1 -1
- package/dist/components/query/index.d.ts +0 -2
- package/dist/components/query/index.js +0 -2
- package/dist/components/react-router/index.d.ts +2 -0
- package/dist/components/react-router/index.js +4 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/alert-layout.css +4 -2
- package/dist/styles/layers.json +1182 -0
- package/dist/styles/vendor-day-picker.css +2 -0
- package/dist/styles/vendor-sonner.css +2 -0
- package/docs/CONSUMER-RULES.md +1 -1
- package/docs/data-display/permission-matrix.tsx +30 -28
- package/docs/data-entry/cascader.tsx +22 -20
- package/docs/data-entry/date-picker.tsx +47 -43
- package/docs/data-entry/form-field/examples/a11y-contract.tsx +80 -76
- package/docs/data-entry/form-field/examples/create-form.tsx +33 -31
- package/docs/data-entry/form-field/index.tsx +61 -57
- package/docs/data-entry/form.tsx +112 -106
- package/docs/data-entry/input.tsx +297 -270
- package/docs/data-entry/label.tsx +11 -9
- package/docs/data-entry/number-input.tsx +86 -78
- package/docs/data-entry/radio-group.tsx +33 -26
- package/docs/data-entry/rating.tsx +29 -25
- package/docs/data-entry/select-matrix.tsx +49 -47
- package/docs/data-entry/select.tsx +38 -35
- package/docs/data-entry/slider.tsx +45 -41
- package/docs/data-entry/textarea.tsx +44 -42
- package/docs/data-entry/time-picker.tsx +51 -47
- package/docs/feedback/sheet.tsx +84 -79
- package/docs/foundation/theme-editor.tsx +133 -124
- package/docs/general/button/examples/form-actions.tsx +17 -15
- package/docs/layout/auth-recovery/examples/password-recovery.tsx +31 -29
- package/docs/layout/auth-shell-registration.tsx +75 -72
- package/docs/layout/auth-shell-variants.tsx +55 -51
- package/docs/layout/space-compact.tsx +11 -8
- package/docs/{query → react-router}/prefetch-link.tsx +1 -1
- package/docs/showcase/caimono-price-comparison.tsx +59 -51
- package/docs/showcase/case3-approval-workflow.tsx +27 -25
- package/docs/showcase/case4-login.tsx +37 -34
- package/docs/showcase/permission-matrix.tsx +44 -42
- package/docs/showcase/theme-customization.tsx +108 -99
- package/package.json +10 -3
- package/scripts/cli.mjs +15 -0
- package/scripts/consumer-rule.md +14 -0
- package/scripts/prune-css.mjs +221 -0
- package/scripts/ui-audit.mjs +99 -2
- /package/dist/components/{query → react-router}/prefetch-link.d.ts +0 -0
- /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, Input, PasswordInput, RadioGroup } from "@godxjp/ui/data-entry";
|
|
4
|
+
import { Form, FormField, Input, PasswordInput, RadioGroup } from "@godxjp/ui/data-entry";
|
|
5
5
|
import { Button, Logo, Text } from "@godxjp/ui/general";
|
|
6
6
|
import {
|
|
7
7
|
AuthDivider,
|
|
@@ -68,19 +68,21 @@ export default function Demo() {
|
|
|
68
68
|
<CardDescription>組織アカウントの資格情報を入力してください。</CardDescription>
|
|
69
69
|
</CardHeader>
|
|
70
70
|
<CardContent>
|
|
71
|
-
<
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
71
|
+
<Form>
|
|
72
|
+
<AuthStack>
|
|
73
|
+
<FormField id="auth-axis-email" label="メールアドレス" layout="vertical" required>
|
|
74
|
+
<Input id="auth-axis-email" type="email" placeholder="you@example.co.jp" />
|
|
75
|
+
</FormField>
|
|
76
|
+
<FormField id="auth-axis-password" label="パスワード" layout="vertical" required>
|
|
77
|
+
<PasswordInput id="auth-axis-password" />
|
|
78
|
+
</FormField>
|
|
79
|
+
<Button fullWidth>サインイン</Button>
|
|
80
|
+
<AuthDivider label="または" />
|
|
81
|
+
<Button variant="outline" fullWidth>
|
|
82
|
+
パスキーでサインイン
|
|
83
|
+
</Button>
|
|
84
|
+
</AuthStack>
|
|
85
|
+
</Form>
|
|
84
86
|
</CardContent>
|
|
85
87
|
</Card>
|
|
86
88
|
|
|
@@ -94,43 +96,45 @@ export default function Demo() {
|
|
|
94
96
|
</CardDescription>
|
|
95
97
|
</CardHeader>
|
|
96
98
|
<CardContent>
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
99
|
+
<Form>
|
|
100
|
+
<Flex direction="col" gap="md">
|
|
101
|
+
<FormField
|
|
102
|
+
id="auth-axis-variant"
|
|
103
|
+
label="variant · シェルの寸法"
|
|
104
|
+
layout="vertical"
|
|
105
|
+
helper="canonical は GoDX ID の正準寸法、default は素の中央寄せシェル。"
|
|
106
|
+
>
|
|
107
|
+
<RadioGroup
|
|
108
|
+
orientation="horizontal"
|
|
109
|
+
value={variant}
|
|
110
|
+
onValueChange={(next) => setVariant(next as AuthShellVariant)}
|
|
111
|
+
options={[
|
|
112
|
+
{ value: "default", label: "default(既定)" },
|
|
113
|
+
{ value: "canonical", label: "canonical(正準)" },
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
</FormField>
|
|
117
|
+
<FormField
|
|
118
|
+
id="auth-axis-density"
|
|
119
|
+
label="density · 操作要素の段"
|
|
120
|
+
layout="vertical"
|
|
121
|
+
helper="comfortable は 44px のタッチ下限、compact は情報密度を優先した段。"
|
|
122
|
+
>
|
|
123
|
+
<RadioGroup
|
|
124
|
+
orientation="horizontal"
|
|
125
|
+
value={density}
|
|
126
|
+
onValueChange={(next) => setDensity(next as AuthShellDensity)}
|
|
127
|
+
options={[
|
|
128
|
+
{ value: "comfortable", label: "comfortable(44px)" },
|
|
129
|
+
{ value: "compact", label: "compact" },
|
|
130
|
+
]}
|
|
131
|
+
/>
|
|
132
|
+
</FormField>
|
|
133
|
+
<Text size="sm" tone="muted">
|
|
134
|
+
現在の組み合わせ: variant="{variant}" · density="{density}"
|
|
135
|
+
</Text>
|
|
136
|
+
</Flex>
|
|
137
|
+
</Form>
|
|
134
138
|
</CardContent>
|
|
135
139
|
</Card>
|
|
136
140
|
</Flex>
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
Descriptions,
|
|
10
10
|
} from "@godxjp/ui/data-display";
|
|
11
11
|
import {
|
|
12
|
+
Form,
|
|
12
13
|
FormField,
|
|
13
14
|
Input,
|
|
14
15
|
NumberInput,
|
|
@@ -183,14 +184,16 @@ export default function SpaceCompactShowcase() {
|
|
|
183
184
|
<CardDescription>{t("spaceCompactDocs.dont.body")}</CardDescription>
|
|
184
185
|
</CardHeader>
|
|
185
186
|
<CardContent>
|
|
186
|
-
<
|
|
187
|
-
<
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
<Form>
|
|
188
|
+
<Flex direction="row" gap="md" wrap>
|
|
189
|
+
<FormField label={t("spaceCompactDocs.dont.dept")}>
|
|
190
|
+
<Input placeholder="D-1024" aria-label={t("spaceCompactDocs.dont.dept")} />
|
|
191
|
+
</FormField>
|
|
192
|
+
<FormField label={t("spaceCompactDocs.dont.ext")}>
|
|
193
|
+
<Input placeholder="2831" aria-label={t("spaceCompactDocs.dont.ext")} />
|
|
194
|
+
</FormField>
|
|
195
|
+
</Flex>
|
|
196
|
+
</Form>
|
|
194
197
|
</CardContent>
|
|
195
198
|
</Card>
|
|
196
199
|
</Flex>
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
TableRow,
|
|
19
19
|
} from "@godxjp/ui/data-display";
|
|
20
20
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
21
|
-
import { PrefetchLink } from "@godxjp/ui/
|
|
21
|
+
import { PrefetchLink } from "@godxjp/ui/react-router";
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* PrefetchLink · a React Router Link that fires queryClient.prefetchQuery on
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type ColumnDef,
|
|
18
18
|
} from "@godxjp/ui/data-display";
|
|
19
19
|
import {
|
|
20
|
+
Form,
|
|
20
21
|
Checkbox,
|
|
21
22
|
FormField,
|
|
22
23
|
NumberInput,
|
|
@@ -468,31 +469,33 @@ export default function CaimonoPriceComparison() {
|
|
|
468
469
|
<Card style={{ "--card-radius": "var(--radius-2xl)" } as React.CSSProperties}>
|
|
469
470
|
<CardContent solo>
|
|
470
471
|
<ResponsiveGrid columns={{ base: 1, md: 2 }} gap="xl">
|
|
471
|
-
<
|
|
472
|
-
<
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
<
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
value
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
<
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
value
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
472
|
+
<Form>
|
|
473
|
+
<Flex direction="col" gap="md">
|
|
474
|
+
<Badge tone="neutral">{t("caimono.synthetic")}</Badge>
|
|
475
|
+
<Heading level={1}>{t("caimono.product")}</Heading>
|
|
476
|
+
<Text tone="muted">{t("caimono.productMeta", { count: number(1) })}</Text>
|
|
477
|
+
<FormField label={t("caimono.variant")}>
|
|
478
|
+
<Select
|
|
479
|
+
value={variant}
|
|
480
|
+
onValueChange={setVariant}
|
|
481
|
+
options={["black", "cream"].map((value) => ({
|
|
482
|
+
value,
|
|
483
|
+
label: t(`caimono.${value}`),
|
|
484
|
+
}))}
|
|
485
|
+
/>
|
|
486
|
+
</FormField>
|
|
487
|
+
<FormField label={t("caimono.condition")}>
|
|
488
|
+
<Segmented
|
|
489
|
+
value={condition}
|
|
490
|
+
onValueChange={setCondition}
|
|
491
|
+
options={["new", "used"].map((value) => ({
|
|
492
|
+
value,
|
|
493
|
+
label: t(`caimono.${value}`),
|
|
494
|
+
}))}
|
|
495
|
+
/>
|
|
496
|
+
</FormField>
|
|
497
|
+
</Flex>
|
|
498
|
+
</Form>
|
|
496
499
|
<Flex direction="col" gap="md">
|
|
497
500
|
<Text tone="muted">{t("caimono.lowest")}</Text>
|
|
498
501
|
<Text size="4xl" weight="bold" tabular>
|
|
@@ -544,32 +547,37 @@ export default function CaimonoPriceComparison() {
|
|
|
544
547
|
<Text tone="muted" size="sm">
|
|
545
548
|
{t("caimono.snapshot", { date: date(snapshot) })}
|
|
546
549
|
</Text>
|
|
547
|
-
<
|
|
548
|
-
<
|
|
549
|
-
<
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
<
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
{
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
550
|
+
<Form>
|
|
551
|
+
<ResponsiveGrid columns={{ base: 1, md: 3 }} gap="md">
|
|
552
|
+
<FormField label={t("caimono.findShop")}>
|
|
553
|
+
<SearchInput
|
|
554
|
+
value={query}
|
|
555
|
+
onValueChange={setQuery}
|
|
556
|
+
placeholder={t("caimono.searchPlaceholder")}
|
|
557
|
+
/>
|
|
558
|
+
</FormField>
|
|
559
|
+
<FormField label={t("caimono.deliverTo")}>
|
|
560
|
+
<Select
|
|
561
|
+
value={destination}
|
|
562
|
+
onValueChange={(v: string) => setDestination(v === "Osaka" ? "Osaka" : "Tokyo")}
|
|
563
|
+
options={["Tokyo", "Osaka"].map((value) => ({
|
|
564
|
+
value,
|
|
565
|
+
label: t(`caimono.${value}`),
|
|
566
|
+
}))}
|
|
567
|
+
/>
|
|
568
|
+
</FormField>
|
|
569
|
+
<FormField label={t("caimono.sort")}>
|
|
570
|
+
<Select
|
|
571
|
+
value={sort}
|
|
572
|
+
onValueChange={setSort}
|
|
573
|
+
options={[
|
|
574
|
+
{ value: "total", label: t("caimono.totalSort") },
|
|
575
|
+
{ value: "delivery", label: t("caimono.deliverySort") },
|
|
576
|
+
]}
|
|
577
|
+
/>
|
|
578
|
+
</FormField>
|
|
579
|
+
</ResponsiveGrid>
|
|
580
|
+
</Form>
|
|
573
581
|
<Flex gap="md" wrap align="center">
|
|
574
582
|
<Checkbox checked={free} onCheckedChange={(v) => setFree(v === true)}>
|
|
575
583
|
{t("caimono.free")}
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
AvatarFallback,
|
|
44
44
|
} from "@godxjp/ui/data-display";
|
|
45
45
|
import { Alert, AlertDescription, SkeletonTable } from "@godxjp/ui/feedback";
|
|
46
|
-
import { DatePicker, FormField, Input, Select } from "@godxjp/ui/data-entry";
|
|
46
|
+
import { Form, DatePicker, FormField, Input, Select } from "@godxjp/ui/data-entry";
|
|
47
47
|
import { toIsoDate } from "@godxjp/ui/datetime";
|
|
48
48
|
import {
|
|
49
49
|
AppShell,
|
|
@@ -353,30 +353,32 @@ export default function Demo() {
|
|
|
353
353
|
<Card className="self-start">
|
|
354
354
|
<CardContent>
|
|
355
355
|
<Flex direction="col" gap="md">
|
|
356
|
-
<
|
|
357
|
-
<
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
<
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
356
|
+
<Form>
|
|
357
|
+
<ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
|
|
358
|
+
<FormField id="f-type" label="区分">
|
|
359
|
+
<Select
|
|
360
|
+
options={TYPE_OPTIONS}
|
|
361
|
+
value={type}
|
|
362
|
+
onValueChange={setType}
|
|
363
|
+
placeholder="すべて"
|
|
364
|
+
/>
|
|
365
|
+
</FormField>
|
|
366
|
+
<FormField id="f-status" label="状態">
|
|
367
|
+
<Select
|
|
368
|
+
options={STATUS_OPTIONS}
|
|
369
|
+
value={status}
|
|
370
|
+
onValueChange={setStatus}
|
|
371
|
+
placeholder="すべて"
|
|
372
|
+
/>
|
|
373
|
+
</FormField>
|
|
374
|
+
<FormField id="f-from" label="期間 (開始)">
|
|
375
|
+
<DatePicker value={from} onValueChange={setFrom} placeholder="YYYY-MM-DD" />
|
|
376
|
+
</FormField>
|
|
377
|
+
<FormField id="f-to" label="期間 (終了)">
|
|
378
|
+
<DatePicker value={to} onValueChange={setTo} placeholder="YYYY-MM-DD" />
|
|
379
|
+
</FormField>
|
|
380
|
+
</ResponsiveGrid>
|
|
381
|
+
</Form>
|
|
380
382
|
{hasActiveFilters && (
|
|
381
383
|
<Flex direction="row" justify="end">
|
|
382
384
|
<Button variant="ghost" size="sm" onClick={clearFilters}>
|
|
@@ -29,6 +29,7 @@ import { Languages, Monitor, Moon, Sun } from "lucide-react";
|
|
|
29
29
|
|
|
30
30
|
import { Button, Heading, Text } from "@godxjp/ui/general";
|
|
31
31
|
import {
|
|
32
|
+
Form,
|
|
32
33
|
FormField,
|
|
33
34
|
Input,
|
|
34
35
|
PasswordInput,
|
|
@@ -243,42 +244,44 @@ export default function LoginShowcase() {
|
|
|
243
244
|
e.preventDefault();
|
|
244
245
|
}}
|
|
245
246
|
>
|
|
246
|
-
<
|
|
247
|
-
<
|
|
248
|
-
<
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
247
|
+
<Form>
|
|
248
|
+
<Flex direction="col" gap="md">
|
|
249
|
+
<FormField id="login-email" label="メールアドレス" required>
|
|
250
|
+
<Input
|
|
251
|
+
type="email"
|
|
252
|
+
name="email"
|
|
253
|
+
autoComplete="email"
|
|
254
|
+
inputMode="email"
|
|
255
|
+
placeholder="name@example.com"
|
|
256
|
+
defaultValue="m.tanaka@famgia.com"
|
|
257
|
+
/>
|
|
258
|
+
</FormField>
|
|
257
259
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
260
|
+
{/* Password — labelAddon hosts the right-aligned "忘れた場合" link. */}
|
|
261
|
+
<FormField
|
|
262
|
+
id="login-password"
|
|
263
|
+
label="パスワード"
|
|
264
|
+
required
|
|
265
|
+
labelAddon={
|
|
266
|
+
<Button type="button" variant="link" size="sm" className="ms-auto text-xs">
|
|
267
|
+
お忘れの場合
|
|
268
|
+
</Button>
|
|
269
|
+
}
|
|
270
|
+
>
|
|
271
|
+
<PasswordInput
|
|
272
|
+
name="password"
|
|
273
|
+
autoComplete="current-password"
|
|
274
|
+
placeholder="パスワードを入力"
|
|
275
|
+
defaultValue="example-pass"
|
|
276
|
+
/>
|
|
277
|
+
</FormField>
|
|
276
278
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
{/* The single --primary action of the view. */}
|
|
280
|
+
<Button type="submit" className="w-full justify-center">
|
|
281
|
+
ログイン
|
|
282
|
+
</Button>
|
|
283
|
+
</Flex>
|
|
284
|
+
</Form>
|
|
282
285
|
</form>
|
|
283
286
|
|
|
284
287
|
<Text as="p" size="2xs" tone="muted" align="center" className="leading-relaxed">
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
TableHeader,
|
|
46
46
|
TableRow,
|
|
47
47
|
} from "@godxjp/ui/data-display";
|
|
48
|
-
import { FormField, Label, Select, Switch } from "@godxjp/ui/data-entry";
|
|
48
|
+
import { Form, FormField, Label, Select, Switch } from "@godxjp/ui/data-entry";
|
|
49
49
|
import { Text } from "@godxjp/ui/general";
|
|
50
50
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
51
51
|
import { cn } from "@godxjp/ui/lib/utils";
|
|
@@ -170,50 +170,52 @@ export default function Demo() {
|
|
|
170
170
|
</Text>
|
|
171
171
|
</CardHeader>
|
|
172
172
|
<CardContent>
|
|
173
|
-
<
|
|
174
|
-
<
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
同一ロールを比較中
|
|
204
|
-
</Text>
|
|
205
|
-
) : (
|
|
206
|
-
<>
|
|
207
|
-
<Badge tone={diffN > 0 ? "warning" : "success"} variant="outline">
|
|
208
|
-
差分 {diffN} 件
|
|
209
|
-
</Badge>
|
|
173
|
+
<Form>
|
|
174
|
+
<Flex direction="row" wrap align="end" gap="md">
|
|
175
|
+
<FormField label="比較 A">
|
|
176
|
+
<Select
|
|
177
|
+
value={compareA}
|
|
178
|
+
onValueChange={setCompareA}
|
|
179
|
+
options={roleOptions}
|
|
180
|
+
className="w-40"
|
|
181
|
+
/>
|
|
182
|
+
</FormField>
|
|
183
|
+
<FormField label="比較 B">
|
|
184
|
+
<Select
|
|
185
|
+
value={compareB}
|
|
186
|
+
onValueChange={setCompareB}
|
|
187
|
+
options={roleOptions}
|
|
188
|
+
className="w-40"
|
|
189
|
+
/>
|
|
190
|
+
</FormField>
|
|
191
|
+
<Flex direction="row" align="center" gap="sm">
|
|
192
|
+
<Switch
|
|
193
|
+
id="pm-diff-only"
|
|
194
|
+
size="sm"
|
|
195
|
+
checked={diffOnly}
|
|
196
|
+
onCheckedChange={setDiffOnly}
|
|
197
|
+
disabled={sameRole}
|
|
198
|
+
/>
|
|
199
|
+
<Label htmlFor="pm-diff-only">差分のみ</Label>
|
|
200
|
+
</Flex>
|
|
201
|
+
<Flex direction="row" align="center" gap="xs" aria-live="polite">
|
|
202
|
+
{sameRole ? (
|
|
210
203
|
<Text size="xs" tone="muted">
|
|
211
|
-
|
|
204
|
+
同一ロールを比較中
|
|
212
205
|
</Text>
|
|
213
|
-
|
|
214
|
-
|
|
206
|
+
) : (
|
|
207
|
+
<>
|
|
208
|
+
<Badge tone={diffN > 0 ? "warning" : "success"} variant="outline">
|
|
209
|
+
差分 {diffN} 件
|
|
210
|
+
</Badge>
|
|
211
|
+
<Text size="xs" tone="muted">
|
|
212
|
+
{roleName(compareA)} vs {roleName(compareB)}
|
|
213
|
+
</Text>
|
|
214
|
+
</>
|
|
215
|
+
)}
|
|
216
|
+
</Flex>
|
|
215
217
|
</Flex>
|
|
216
|
-
</
|
|
218
|
+
</Form>
|
|
217
219
|
</CardContent>
|
|
218
220
|
</Card>
|
|
219
221
|
|