@godxjp/ui 30.3.1 → 30.4.1

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.
@@ -0,0 +1,199 @@
1
+ import { useState } from "react";
2
+ import { Flex, PageContainer, SpaceCompact } from "@godxjp/ui/layout";
3
+ import {
4
+ Card,
5
+ CardContent,
6
+ CardDescription,
7
+ CardHeader,
8
+ CardTitle,
9
+ Descriptions,
10
+ } from "@godxjp/ui/data-display";
11
+ import {
12
+ FormField,
13
+ Input,
14
+ NumberInput,
15
+ SearchInput,
16
+ Select,
17
+ Textarea,
18
+ } from "@godxjp/ui/data-entry";
19
+ import { Button, Text } from "@godxjp/ui/general";
20
+ import { useTranslation } from "@godxjp/ui/i18n";
21
+ import { Search, Send } from "lucide-react";
22
+
23
+ /**
24
+ * SpaceCompact · weld a row of controls into ONE box.
25
+ *
26
+ * Shows: the recurrence row the component was built for (毎[N][週▾]ごと), a search field welded to
27
+ * its button, a unit-suffixed amount, and the vertical axis with its documented limit.
28
+ *
29
+ * WHY THIS IS A COMPONENT AND NOT A RECIPE. Zeroing the inner corners and collapsing the shared
30
+ * border seam needs `[&>*:not(:first-child)]`-shaped selectors, which `ui-audit`'s
31
+ * `no-utility-layout` rule blocks at the call site. Everything else here is real primitives.
32
+ *
33
+ * ONE LABEL FOR THE PAIR. A `FormField` wrapping a `SpaceCompact` lands its label on the row, and a
34
+ * named row with no explicit `role` becomes `role="group"` — a `<div>` has no role to lose, so the
35
+ * name has somewhere to live. Each control inside keeps its own accessible name.
36
+ */
37
+
38
+ /** Currency CODES are ISO 4217 identifiers, not chrome — they are the same in every locale. */
39
+ const CURRENCIES = [
40
+ { value: "JPY", label: "JPY" },
41
+ { value: "USD", label: "USD" },
42
+ { value: "VND", label: "VND" },
43
+ ];
44
+
45
+ export default function SpaceCompactShowcase() {
46
+ const { t } = useTranslation();
47
+ const [every, setEvery] = useState(2);
48
+ const [unit, setUnit] = useState("week");
49
+ const [amount, setAmount] = useState(48000);
50
+ const [currency, setCurrency] = useState("JPY");
51
+ const [query, setQuery] = useState("");
52
+ const [note, setNote] = useState("");
53
+ const weekUnits = [
54
+ { value: "day", label: t("spaceCompactDocs.unit.day") },
55
+ { value: "week", label: t("spaceCompactDocs.unit.week") },
56
+ { value: "month", label: t("spaceCompactDocs.unit.month") },
57
+ ];
58
+
59
+ return (
60
+ <PageContainer title={t("spaceCompactDocs.title")} subtitle={t("spaceCompactDocs.subtitle")}>
61
+ <Flex direction="col" gap="lg">
62
+ <Card>
63
+ <CardHeader>
64
+ <CardTitle level={2}>{t("spaceCompactDocs.recur.title")}</CardTitle>
65
+ <CardDescription>{t("spaceCompactDocs.recur.body")}</CardDescription>
66
+ </CardHeader>
67
+ <CardContent>
68
+ <Flex direction="col" gap="md">
69
+ <FormField
70
+ label={t("spaceCompactDocs.recur.label")}
71
+ helper={t("spaceCompactDocs.recur.helper")}
72
+ >
73
+ <SpaceCompact>
74
+ <NumberInput
75
+ value={every}
76
+ onValueChange={(next) => setEvery(next ?? 1)}
77
+ min={1}
78
+ max={52}
79
+ aria-label={t("spaceCompactDocs.recur.every")}
80
+ />
81
+ <Select
82
+ value={unit}
83
+ onValueChange={(next: string | string[] | undefined) => setUnit(next as string)}
84
+ options={weekUnits}
85
+ aria-label={t("spaceCompactDocs.recur.unit")}
86
+ />
87
+ </SpaceCompact>
88
+ </FormField>
89
+
90
+ <Descriptions
91
+ items={[
92
+ {
93
+ label: t("spaceCompactDocs.recur.reads"),
94
+ children: `${every} ${weekUnits.find((u) => u.value === unit)?.label ?? ""}`,
95
+ },
96
+ {
97
+ label: t("spaceCompactDocs.recur.role"),
98
+ children: t("spaceCompactDocs.recur.roleValue"),
99
+ },
100
+ ]}
101
+ />
102
+ </Flex>
103
+ </CardContent>
104
+ </Card>
105
+
106
+ <Card>
107
+ <CardHeader>
108
+ <CardTitle level={2}>{t("spaceCompactDocs.search.title")}</CardTitle>
109
+ <CardDescription>{t("spaceCompactDocs.search.body")}</CardDescription>
110
+ </CardHeader>
111
+ <CardContent>
112
+ <SpaceCompact aria-label={t("spaceCompactDocs.search.row")}>
113
+ <SearchInput
114
+ value={query}
115
+ onValueChange={setQuery}
116
+ placeholder={t("spaceCompactDocs.search.placeholder")}
117
+ aria-label={t("spaceCompactDocs.search.term")}
118
+ />
119
+ <Button aria-label={t("spaceCompactDocs.search.run")}>
120
+ <Search aria-hidden="true" />
121
+ </Button>
122
+ </SpaceCompact>
123
+ </CardContent>
124
+ </Card>
125
+
126
+ <Card>
127
+ <CardHeader>
128
+ <CardTitle level={2}>{t("spaceCompactDocs.amount.title")}</CardTitle>
129
+ <CardDescription>{t("spaceCompactDocs.amount.body")}</CardDescription>
130
+ </CardHeader>
131
+ <CardContent>
132
+ <FormField label={t("spaceCompactDocs.amount.label")}>
133
+ <SpaceCompact fullWidth>
134
+ <NumberInput
135
+ value={amount}
136
+ onValueChange={(next) => setAmount(next ?? 0)}
137
+ min={0}
138
+ step={1000}
139
+ aria-label={t("spaceCompactDocs.amount.value")}
140
+ />
141
+ <Select
142
+ value={currency}
143
+ onValueChange={(next: string | string[] | undefined) =>
144
+ setCurrency(next as string)
145
+ }
146
+ options={CURRENCIES}
147
+ aria-label={t("spaceCompactDocs.amount.currency")}
148
+ />
149
+ </SpaceCompact>
150
+ </FormField>
151
+ </CardContent>
152
+ </Card>
153
+
154
+ <Card>
155
+ <CardHeader>
156
+ <CardTitle level={2}>{t("spaceCompactDocs.vertical.title")}</CardTitle>
157
+ <CardDescription>{t("spaceCompactDocs.vertical.body")}</CardDescription>
158
+ </CardHeader>
159
+ <CardContent>
160
+ <Flex direction="col" gap="sm">
161
+ <SpaceCompact orientation="vertical" aria-label={t("spaceCompactDocs.vertical.row")}>
162
+ <Textarea
163
+ value={note}
164
+ onValueChange={setNote}
165
+ placeholder={t("spaceCompactDocs.vertical.note")}
166
+ aria-label={t("spaceCompactDocs.vertical.note")}
167
+ />
168
+ <Button aria-label={t("spaceCompactDocs.vertical.send")}>
169
+ <Send aria-hidden="true" />
170
+ {t("spaceCompactDocs.vertical.send")}
171
+ </Button>
172
+ </SpaceCompact>
173
+ <Text tone="muted" size="sm">
174
+ {t("spaceCompactDocs.vertical.alias")}
175
+ </Text>
176
+ </Flex>
177
+ </CardContent>
178
+ </Card>
179
+
180
+ <Card>
181
+ <CardHeader>
182
+ <CardTitle level={2}>{t("spaceCompactDocs.dont.title")}</CardTitle>
183
+ <CardDescription>{t("spaceCompactDocs.dont.body")}</CardDescription>
184
+ </CardHeader>
185
+ <CardContent>
186
+ <Flex direction="row" gap="md" wrap>
187
+ <FormField label={t("spaceCompactDocs.dont.dept")}>
188
+ <Input placeholder="D-1024" aria-label={t("spaceCompactDocs.dont.dept")} />
189
+ </FormField>
190
+ <FormField label={t("spaceCompactDocs.dont.ext")}>
191
+ <Input placeholder="2831" aria-label={t("spaceCompactDocs.dont.ext")} />
192
+ </FormField>
193
+ </Flex>
194
+ </CardContent>
195
+ </Card>
196
+ </Flex>
197
+ </PageContainer>
198
+ );
199
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "30.3.1",
4
- "godxUiMcp": "30.3.1",
3
+ "version": "30.4.1",
4
+ "godxUiMcp": "30.4.1",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",