@godxjp/ui 27.8.0 → 27.10.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.
- package/dist/components/data-display/range-timeline.d.ts +19 -0
- package/dist/components/data-display/range-timeline.js +2 -0
- package/dist/components/data-display/tree.js +2 -0
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +19 -16
- package/dist/components/general/button.d.ts +1 -0
- package/dist/components/general/button.js +10 -2
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +8 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +12 -2
- package/dist/components/layout/topbar.d.ts +1 -1
- package/dist/components/layout/topbar.js +2 -0
- package/dist/components/ui/toggle-group.d.ts +4 -0
- package/dist/components/ui/toggle-group.js +10 -2
- package/dist/components/ui/toggle.d.ts +4 -2
- package/dist/components/ui/toggle.js +22 -3
- package/dist/contracts/measurement.json +1 -1
- package/dist/props/components/data-display.prop.d.ts +11 -0
- package/dist/props/components/data-entry.prop.d.ts +22 -3
- package/dist/props/components/general.prop.d.ts +12 -0
- package/dist/props/components/index.d.ts +1 -1
- package/dist/props/components/layout.prop.d.ts +60 -1
- package/dist/props/registry.d.ts +27 -6
- package/dist/props/registry.js +42 -3
- package/dist/styles/control.css +17 -7
- package/dist/styles/data-display-layout.css +25 -7
- package/dist/styles/data-entry-layout.css +13 -0
- package/dist/styles/layout.css +8 -0
- package/dist/styles/shell-layout.css +43 -1
- package/dist/styles/toggle.css +5 -0
- package/dist/tokens/components/control.css +5 -2
- package/dist/tokens/components/data-display.css +10 -1
- package/dist/tokens/components/shell.css +3 -0
- package/dist/tokens/components/toggle.css +7 -0
- package/dist/tokens/components/tree.css +2 -0
- package/docs/DESIGN-AUTHORITY.md +20 -0
- package/docs/FRAME-COVERAGE-REPORT.md +1 -1
- package/docs/data-display/timeline.tsx +77 -1
- package/docs/data-display/tree.tsx +94 -0
- package/docs/data-entry/calendar.tsx +3 -2
- package/docs/data-entry/toggle-count.tsx +51 -0
- package/docs/data-entry/toggle-group.tsx +40 -2
- package/docs/data-entry/toggle.tsx +54 -2
- package/docs/data-entry/upload.tsx +44 -0
- package/docs/general/button/index.tsx +18 -6
- package/docs/general/icon.tsx +3 -1
- package/docs/layout/app-shell-narrow-bar.tsx +205 -0
- package/docs/layout/app-shell.tsx +10 -0
- package/docs/layout/page-container.tsx +67 -1
- package/docs/layout/topbar.tsx +11 -1
- package/package.json +2 -2
- package/scripts/cli.mjs +3 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
1
3
|
import { useTranslation } from "@godxjp/ui/i18n";
|
|
2
4
|
import {
|
|
3
5
|
Card,
|
|
@@ -142,7 +144,10 @@ export default function Demo() {
|
|
|
142
144
|
<CardTitle level={2}>承認・消費税トラッカー</CardTitle>
|
|
143
145
|
<CardDescription>
|
|
144
146
|
variant="status" は status ごとにグリフを切り替えます(done → チェック、current →
|
|
145
|
-
塗りつぶしドット、pending →
|
|
147
|
+
塗りつぶしドット、pending → 連番)。進捗レールの色は1つだけ:
|
|
148
|
+
done・current・通過済みの線 はすべて --primary で塗られ、current
|
|
149
|
+
はリング(--timeline-dot-current-ring-width)と グリフで区別します。Steps の finish /
|
|
150
|
+
process と同じ約束です。
|
|
146
151
|
</CardDescription>
|
|
147
152
|
</CardHeader>
|
|
148
153
|
<CardContent>
|
|
@@ -163,6 +168,31 @@ export default function Demo() {
|
|
|
163
168
|
</CardContent>
|
|
164
169
|
</Card>
|
|
165
170
|
|
|
171
|
+
<Card>
|
|
172
|
+
<CardHeader>
|
|
173
|
+
<CardTitle level={2}>進捗レールの色をテーマで戻す</CardTitle>
|
|
174
|
+
<CardDescription>
|
|
175
|
+
done の緑と current の紫という 27.8 までの配色に戻したい場合は、塗りとインクを
|
|
176
|
+
対にしてテーマで指定します。塗りだけを戻すと、若竹の緑にほぼ白のグリフが乗って 2.18:1
|
|
177
|
+
になり AA を満たしません(gh#643)。同じ要領で --timeline-dot-current-background と
|
|
178
|
+
--timeline-line-completed-background も再着色できます。
|
|
179
|
+
</CardDescription>
|
|
180
|
+
</CardHeader>
|
|
181
|
+
{/* The knobs are declared on the CARD BODY, not on the Timeline: custom properties
|
|
182
|
+
inherit, so one scope retints every Timeline inside it — which is how a service
|
|
183
|
+
theme sets them (once, globally, or under `[data-tenant]`), not per call site. */}
|
|
184
|
+
<CardContent
|
|
185
|
+
style={
|
|
186
|
+
{
|
|
187
|
+
"--timeline-dot-done-background": "hsl(var(--success))",
|
|
188
|
+
"--timeline-dot-done-foreground": "hsl(var(--success-foreground))",
|
|
189
|
+
} as CSSProperties
|
|
190
|
+
}
|
|
191
|
+
>
|
|
192
|
+
<Timeline variant="status" items={approvalItems} />
|
|
193
|
+
</CardContent>
|
|
194
|
+
</Card>
|
|
195
|
+
|
|
166
196
|
<Card>
|
|
167
197
|
<CardHeader>
|
|
168
198
|
<CardTitle level={2}>RangeTimeline</CardTitle>
|
|
@@ -236,6 +266,52 @@ export default function Demo() {
|
|
|
236
266
|
</CardContent>
|
|
237
267
|
</Card>
|
|
238
268
|
|
|
269
|
+
<Card>
|
|
270
|
+
<CardHeader>
|
|
271
|
+
<CardTitle level={2}>密度(density)— 1日の列幅</CardTitle>
|
|
272
|
+
<CardDescription>
|
|
273
|
+
同じ31日分の軸を density で三段。compact は1日42px、default
|
|
274
|
+
は従来どおり56px、comfortable は70px です。動くのは列幅だけで、行の高さもバーの高さも
|
|
275
|
+
ラベル列の幅も変わりません。画面に入る日数を増やしたいときは compact
|
|
276
|
+
を選びます(app.css でトークンを書く必要はありません)。
|
|
277
|
+
</CardDescription>
|
|
278
|
+
</CardHeader>
|
|
279
|
+
<CardContent>
|
|
280
|
+
<Flex direction="col" gap="md">
|
|
281
|
+
{(["compact", "default", "comfortable"] as const).map((density) => (
|
|
282
|
+
<div key={density}>
|
|
283
|
+
<Text size="xs" tone="muted">
|
|
284
|
+
density="{density}"
|
|
285
|
+
</Text>
|
|
286
|
+
<RangeTimeline
|
|
287
|
+
label={t("rangeTimeline.schedule")}
|
|
288
|
+
density={density}
|
|
289
|
+
today={8}
|
|
290
|
+
bands={[{ label: monthLabel(8), units: 31 }]}
|
|
291
|
+
columns={Array.from({ length: 31 }, (_, index) => {
|
|
292
|
+
const weekday = new Date(Date.UTC(2026, 8, index + 1)).getUTCDay();
|
|
293
|
+
return {
|
|
294
|
+
label: new Intl.NumberFormat(locale).format(index + 1),
|
|
295
|
+
units: 1,
|
|
296
|
+
muted: weekday === 0 || weekday === 6,
|
|
297
|
+
};
|
|
298
|
+
})}
|
|
299
|
+
rows={[
|
|
300
|
+
{ id: "design", label: "要件定義", start: 0, end: 6 },
|
|
301
|
+
{ id: "build", label: "実装", start: 7, end: 22 },
|
|
302
|
+
{ id: "review", label: "レビュー", start: 20, end: 29 },
|
|
303
|
+
].map((row) => ({
|
|
304
|
+
...row,
|
|
305
|
+
startLabel: dayLabel(row.start + 1),
|
|
306
|
+
endLabel: dayLabel(row.end + 1),
|
|
307
|
+
}))}
|
|
308
|
+
/>
|
|
309
|
+
</div>
|
|
310
|
+
))}
|
|
311
|
+
</Flex>
|
|
312
|
+
</CardContent>
|
|
313
|
+
</Card>
|
|
314
|
+
|
|
239
315
|
<Card>
|
|
240
316
|
<CardHeader>
|
|
241
317
|
<CardTitle level={2}>月単位の軸(列ごとに units が異なる)</CardTitle>
|
|
@@ -100,6 +100,48 @@ const fileDetails: Record<string, { size: string; changed: string }> = {
|
|
|
100
100
|
"docs/tree.mdx": { size: "4.1 KB", changed: "2026-09-10" },
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
// ── the page index used as NAVIGATION inside a Card (`divided`, gh#732) ──────────────────────
|
|
104
|
+
const wikiPages: TreeNodeProp[] = [
|
|
105
|
+
{
|
|
106
|
+
value: "handbook",
|
|
107
|
+
label: "社内ハンドブック",
|
|
108
|
+
children: [
|
|
109
|
+
{ value: "handbook/onboarding", label: "入社手続き", isLeaf: true },
|
|
110
|
+
{ value: "handbook/expenses", label: "経費精算", isLeaf: true },
|
|
111
|
+
{
|
|
112
|
+
value: "handbook/security",
|
|
113
|
+
label: "情報セキュリティ",
|
|
114
|
+
children: [
|
|
115
|
+
{ value: "handbook/security/passwords", label: "パスワード規程", isLeaf: true },
|
|
116
|
+
{ value: "handbook/security/incidents", label: "インシデント報告", isLeaf: true },
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
value: "product",
|
|
123
|
+
label: "プロダクト仕様",
|
|
124
|
+
children: [
|
|
125
|
+
{ value: "product/release", label: "リリース手順", isLeaf: true },
|
|
126
|
+
{ value: "product/support", label: "サポート窓口", isLeaf: true },
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{ value: "minutes", label: "議事録", isLeaf: true },
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const wikiPageDetails: Record<string, { updated: string; author: string }> = {
|
|
133
|
+
handbook: { updated: "2026-09-01", author: "総務部" },
|
|
134
|
+
"handbook/onboarding": { updated: "2026-08-18", author: "人事部" },
|
|
135
|
+
"handbook/expenses": { updated: "2026-07-30", author: "経理部" },
|
|
136
|
+
"handbook/security": { updated: "2026-09-11", author: "情報システム部" },
|
|
137
|
+
"handbook/security/passwords": { updated: "2026-09-11", author: "情報システム部" },
|
|
138
|
+
"handbook/security/incidents": { updated: "2026-06-02", author: "情報システム部" },
|
|
139
|
+
product: { updated: "2026-09-14", author: "プロダクト部" },
|
|
140
|
+
"product/release": { updated: "2026-09-14", author: "プロダクト部" },
|
|
141
|
+
"product/support": { updated: "2026-05-20", author: "CS部" },
|
|
142
|
+
minutes: { updated: "2026-09-16", author: "総務部" },
|
|
143
|
+
};
|
|
144
|
+
|
|
103
145
|
// ── card 3 · async branches (fieldNames + loadData + titleRender) ────────────────────────────
|
|
104
146
|
type Department = { id: string; name: string; leaf?: boolean; units?: Department[] };
|
|
105
147
|
|
|
@@ -130,6 +172,8 @@ export default function Demo() {
|
|
|
130
172
|
const [granted, setGranted] = React.useState<string[]>(["billing.invoice.read"]);
|
|
131
173
|
// Card 2 — selection is controlled and drives the detail pane.
|
|
132
174
|
const [openFile, setOpenFile] = React.useState<string | undefined>("src/components/tree.tsx");
|
|
175
|
+
// The page index — the tree IS the navigation, so selection is what the reading pane follows.
|
|
176
|
+
const [openPage, setOpenPage] = React.useState<string | undefined>("handbook/security/passwords");
|
|
133
177
|
// Card 3 — async children land in state, exactly as a real fetch would.
|
|
134
178
|
const [departments, setDepartments] = React.useState<Department[]>(initialDepartments);
|
|
135
179
|
// Card 5 — independent (strict) checks, and a multi-select tree.
|
|
@@ -239,6 +283,56 @@ export default function Demo() {
|
|
|
239
283
|
</CardContent>
|
|
240
284
|
</Card>
|
|
241
285
|
|
|
286
|
+
<Card>
|
|
287
|
+
<CardHeader>
|
|
288
|
+
<CardTitle level={2}>ページ一覧をナビゲーションに使う(divided)</CardTitle>
|
|
289
|
+
<CardDescription>
|
|
290
|
+
ドキュメント/wiki のページ一覧のように、ツリーそのものが画面のナビゲーションになる
|
|
291
|
+
ときは divided で行間に罫を引きます。罫は各行の block-start に 1
|
|
292
|
+
本ずつ、外側の最初の行にだけ引かれません。 深さに関係なく行の幅いっぱいに走るので
|
|
293
|
+
(インデントは行の padding であって margin ではありません)、 子行が「表の中の表」に
|
|
294
|
+
見えることはありません。色は --tree-divider-color(既定 hsl(var(--border)))。 divided
|
|
295
|
+
は既定オフで、このページの他のカードがその既定の姿です。
|
|
296
|
+
</CardDescription>
|
|
297
|
+
</CardHeader>
|
|
298
|
+
<CardContent>
|
|
299
|
+
<Flex gap="lg" wrap>
|
|
300
|
+
<Card className="w-72">
|
|
301
|
+
<CardHeader>
|
|
302
|
+
<CardTitle level={3}>ページ一覧</CardTitle>
|
|
303
|
+
</CardHeader>
|
|
304
|
+
<CardContent flush>
|
|
305
|
+
<Tree
|
|
306
|
+
aria-label="ページ一覧"
|
|
307
|
+
divided
|
|
308
|
+
treeData={wikiPages}
|
|
309
|
+
defaultExpandAll
|
|
310
|
+
value={openPage}
|
|
311
|
+
onValueChange={(next) => setOpenPage(next as string | undefined)}
|
|
312
|
+
/>
|
|
313
|
+
</CardContent>
|
|
314
|
+
</Card>
|
|
315
|
+
<Flex direction="col" gap="sm">
|
|
316
|
+
{openPage && wikiPageDetails[openPage] ? (
|
|
317
|
+
<Descriptions
|
|
318
|
+
items={[
|
|
319
|
+
{ label: "パス", children: openPage },
|
|
320
|
+
{ label: "最終更新", children: wikiPageDetails[openPage].updated },
|
|
321
|
+
{ label: "更新者", children: wikiPageDetails[openPage].author },
|
|
322
|
+
]}
|
|
323
|
+
/>
|
|
324
|
+
) : (
|
|
325
|
+
<EmptyState
|
|
326
|
+
icon={FolderTree}
|
|
327
|
+
title="ページが選択されていません"
|
|
328
|
+
description="左の一覧からページを選んでください。"
|
|
329
|
+
/>
|
|
330
|
+
)}
|
|
331
|
+
</Flex>
|
|
332
|
+
</Flex>
|
|
333
|
+
</CardContent>
|
|
334
|
+
</Card>
|
|
335
|
+
|
|
242
336
|
<Card>
|
|
243
337
|
<CardHeader>
|
|
244
338
|
<CardTitle level={2}>組織ツリー(loadData · fieldNames · titleRender)</CardTitle>
|
|
@@ -77,8 +77,9 @@ export default function Demo() {
|
|
|
77
77
|
罫線 (bordered) · 既定で表示 / bordered={"{false}"} で解除
|
|
78
78
|
</CardTitle>
|
|
79
79
|
<CardDescription>
|
|
80
|
-
日と日の間に罫線を引くのが既定。線色は --calendar-grid-border-color (既定 --
|
|
81
|
-
|
|
80
|
+
日と日の間に罫線を引くのが既定。線色は --calendar-grid-border-color (既定 --border、
|
|
81
|
+
背景に対し約 1.15:1)。表の行やカードの枠と同じ段なので、罫線が枠より濃くなることは
|
|
82
|
+
ない。選択日・今日・範囲の始点/中間/終点・無効日・前後月の日が
|
|
82
83
|
罫線の中でも判別できる。罫線なしの浮いたボタン表示にしたい場合のみ bordered=
|
|
83
84
|
{"{false}"} を渡す。
|
|
84
85
|
</CardDescription>
|
|
@@ -72,6 +72,14 @@ const TICKETS: Ticket[] = [
|
|
|
72
72
|
},
|
|
73
73
|
];
|
|
74
74
|
|
|
75
|
+
const TAGS = [
|
|
76
|
+
{ value: "design", label: "設計", count: 12 },
|
|
77
|
+
{ value: "runbook", label: "運用手順", count: 148 },
|
|
78
|
+
{ value: "onboarding", label: "入社手続き", count: 7 },
|
|
79
|
+
{ value: "security", label: "セキュリティ", count: 31 },
|
|
80
|
+
{ value: "archive", label: "アーカイブ", count: 1240 },
|
|
81
|
+
];
|
|
82
|
+
|
|
75
83
|
const STATUS_LABEL: Record<Ticket["status"], string> = {
|
|
76
84
|
open: "未対応",
|
|
77
85
|
waiting: "保留中",
|
|
@@ -93,6 +101,8 @@ const COLUMNS = [
|
|
|
93
101
|
];
|
|
94
102
|
|
|
95
103
|
export default function Demo() {
|
|
104
|
+
// The tag panel of a Wiki/document screen — the chip this vocabulary exists for.
|
|
105
|
+
const [tags, setTags] = useState<string[]>(["design"]);
|
|
96
106
|
// Faceted filter chips — pressed = the facet is applied. Counts are the facet sizes.
|
|
97
107
|
const [facets, setFacets] = useState<string[]>(["open"]);
|
|
98
108
|
// A reaction row: the count is how many people reacted, the pressed state is whether YOU did.
|
|
@@ -112,6 +122,47 @@ export default function Demo() {
|
|
|
112
122
|
subtitle="カウント付きの押下チップ · faceted filter · リアクション"
|
|
113
123
|
>
|
|
114
124
|
<Flex direction="col" gap="lg">
|
|
125
|
+
<Card>
|
|
126
|
+
<CardHeader>
|
|
127
|
+
<CardTitle level={2}>タグで絞り込む · soft + pill のチップ</CardTitle>
|
|
128
|
+
<CardDescription>
|
|
129
|
+
Wiki / ドキュメントのタグパネル。variant="soft" が休止時の面(--secondary、
|
|
130
|
+
Badge variant="secondary" と同じ塗り)、shape="pill" が角、count
|
|
131
|
+
が件数、押下が選択。variant / size / shape はグループに一度だけ書けば context
|
|
132
|
+
で全アイテムに届く。default や outline
|
|
133
|
+
だとチップは押されるまで透明に見えるので、チップ列にはこの組み合わせを使う。
|
|
134
|
+
</CardDescription>
|
|
135
|
+
</CardHeader>
|
|
136
|
+
<CardContent>
|
|
137
|
+
<Flex direction="col" gap="md">
|
|
138
|
+
<ToggleGroup
|
|
139
|
+
type="multiple"
|
|
140
|
+
variant="soft"
|
|
141
|
+
shape="pill"
|
|
142
|
+
size="xs"
|
|
143
|
+
value={tags}
|
|
144
|
+
onValueChange={setTags}
|
|
145
|
+
aria-label="タグで絞り込み"
|
|
146
|
+
>
|
|
147
|
+
{TAGS.map((tag) => (
|
|
148
|
+
<ToggleGroupItem
|
|
149
|
+
key={tag.value}
|
|
150
|
+
value={tag.value}
|
|
151
|
+
count={tag.count}
|
|
152
|
+
countLabel="ページ"
|
|
153
|
+
>
|
|
154
|
+
{tag.label}
|
|
155
|
+
</ToggleGroupItem>
|
|
156
|
+
))}
|
|
157
|
+
</ToggleGroup>
|
|
158
|
+
<Text tone="muted" size="sm">
|
|
159
|
+
読み上げは「設計, 12 ページ」。数字はピル側が aria-hidden で、単位つきの一文が
|
|
160
|
+
sr-only で並ぶので、ラベルと数字がくっついて「設計12」になることはない。
|
|
161
|
+
</Text>
|
|
162
|
+
</Flex>
|
|
163
|
+
</CardContent>
|
|
164
|
+
</Card>
|
|
165
|
+
|
|
115
166
|
<Card>
|
|
116
167
|
<CardHeader>
|
|
117
168
|
<CardTitle level={2}>問い合わせ受信箱</CardTitle>
|
|
@@ -95,10 +95,11 @@ export default function Demo() {
|
|
|
95
95
|
|
|
96
96
|
<Card>
|
|
97
97
|
<CardHeader>
|
|
98
|
-
<CardTitle level={2}>variant · default / outline</CardTitle>
|
|
98
|
+
<CardTitle level={2}>variant · default / outline / soft</CardTitle>
|
|
99
99
|
<CardDescription>
|
|
100
100
|
variant は ToggleGroup にだけ指定すれば全アイテムへ伝播する(各 ToggleGroupItem
|
|
101
|
-
への繰り返し指定は不要)。default は選択時に背景が塗られ、outline は枠線で示す。
|
|
101
|
+
への繰り返し指定は不要)。default は選択時に背景が塗られ、outline は枠線で示す。soft
|
|
102
|
+
は休止時から --secondary で塗られるので、チップの列に使う。
|
|
102
103
|
</CardDescription>
|
|
103
104
|
</CardHeader>
|
|
104
105
|
<CardContent>
|
|
@@ -123,6 +124,43 @@ export default function Demo() {
|
|
|
123
124
|
<ToggleGroupItem value="xlsx">Excel</ToggleGroupItem>
|
|
124
125
|
</ToggleGroup>
|
|
125
126
|
</Flex>
|
|
127
|
+
<Flex direction="col" gap="sm">
|
|
128
|
+
<Text as="p" size="sm" tone="muted">
|
|
129
|
+
variant="soft"
|
|
130
|
+
</Text>
|
|
131
|
+
<ToggleGroup type="single" variant="soft" defaultValue="pdf">
|
|
132
|
+
<ToggleGroupItem value="pdf">PDF</ToggleGroupItem>
|
|
133
|
+
<ToggleGroupItem value="csv">CSV</ToggleGroupItem>
|
|
134
|
+
<ToggleGroupItem value="xlsx">Excel</ToggleGroupItem>
|
|
135
|
+
</ToggleGroup>
|
|
136
|
+
</Flex>
|
|
137
|
+
</Flex>
|
|
138
|
+
</CardContent>
|
|
139
|
+
</Card>
|
|
140
|
+
|
|
141
|
+
<Card>
|
|
142
|
+
<CardHeader>
|
|
143
|
+
<CardTitle level={2}>shape · default / pill / sharp</CardTitle>
|
|
144
|
+
<CardDescription>
|
|
145
|
+
shape も variant / size と同じく行の決定なので、ToggleGroup
|
|
146
|
+
に一度書けば全アイテムへ伝播する。値は Button / Badge と同じ三つで、読む radius
|
|
147
|
+
トークンも同じ。チップの列は soft + pill。
|
|
148
|
+
</CardDescription>
|
|
149
|
+
</CardHeader>
|
|
150
|
+
<CardContent>
|
|
151
|
+
<Flex direction="col" gap="md">
|
|
152
|
+
{(["default", "pill", "sharp"] as const).map((shape) => (
|
|
153
|
+
<Flex key={shape} direction="col" gap="sm">
|
|
154
|
+
<Text as="p" size="sm" tone="muted">
|
|
155
|
+
shape="{shape}"
|
|
156
|
+
</Text>
|
|
157
|
+
<ToggleGroup type="single" variant="soft" shape={shape} defaultValue="pdf">
|
|
158
|
+
<ToggleGroupItem value="pdf">PDF</ToggleGroupItem>
|
|
159
|
+
<ToggleGroupItem value="csv">CSV</ToggleGroupItem>
|
|
160
|
+
<ToggleGroupItem value="xlsx">Excel</ToggleGroupItem>
|
|
161
|
+
</ToggleGroup>
|
|
162
|
+
</Flex>
|
|
163
|
+
))}
|
|
126
164
|
</Flex>
|
|
127
165
|
</CardContent>
|
|
128
166
|
</Card>
|
|
@@ -46,11 +46,14 @@ export default function Demo() {
|
|
|
46
46
|
<CardHeader>
|
|
47
47
|
<CardTitle level={2}>Variants</CardTitle>
|
|
48
48
|
<CardDescription>
|
|
49
|
-
default
|
|
49
|
+
default(押下時だけ面が出る・休止時は透明な 1px 枠)· outline(--background
|
|
50
|
+
の上の細い枠)· soft(休止時から --secondary で塗られる)。
|
|
51
|
+
最初の二つはツールバー向けで、休止しているチップは「何もない」ように見える。
|
|
52
|
+
チップとして並べるときは soft。
|
|
50
53
|
</CardDescription>
|
|
51
54
|
</CardHeader>
|
|
52
55
|
<CardContent>
|
|
53
|
-
<Flex direction="row" gap="md">
|
|
56
|
+
<Flex direction="row" gap="md" wrap>
|
|
54
57
|
<Toggle
|
|
55
58
|
variant="default"
|
|
56
59
|
pressed={pinned}
|
|
@@ -67,6 +70,55 @@ export default function Demo() {
|
|
|
67
70
|
>
|
|
68
71
|
消費税対象のみ
|
|
69
72
|
</Toggle>
|
|
73
|
+
<Toggle variant="soft" aria-label="草案のみ">
|
|
74
|
+
草案のみ
|
|
75
|
+
</Toggle>
|
|
76
|
+
</Flex>
|
|
77
|
+
</CardContent>
|
|
78
|
+
</Card>
|
|
79
|
+
|
|
80
|
+
<Card>
|
|
81
|
+
<CardHeader>
|
|
82
|
+
<CardTitle level={2}>
|
|
83
|
+
soft + shape="pill" · チェック可能なタグチップ
|
|
84
|
+
</CardTitle>
|
|
85
|
+
<CardDescription>
|
|
86
|
+
antd の Tag.CheckableTag にあたる形。soft が休止時の面を、shape が角を担う。shape は
|
|
87
|
+
Button / Badge と同じ default / pill / sharp の三値で、同じ radius
|
|
88
|
+
トークンを読む。押下すると面が --primary に反転するので、状態は色だけに依存しない。
|
|
89
|
+
取り消せる(×つきの)タグは選択ではなく削除なので Badge の onRemove
|
|
90
|
+
側、つまり別のコンポーネントになる。
|
|
91
|
+
</CardDescription>
|
|
92
|
+
</CardHeader>
|
|
93
|
+
<CardContent>
|
|
94
|
+
<Flex direction="col" gap="md">
|
|
95
|
+
<Flex direction="row" gap="sm" wrap align="center">
|
|
96
|
+
<Toggle variant="soft" shape="pill" size="xs" defaultPressed>
|
|
97
|
+
設計
|
|
98
|
+
</Toggle>
|
|
99
|
+
<Toggle variant="soft" shape="pill" size="xs">
|
|
100
|
+
実装
|
|
101
|
+
</Toggle>
|
|
102
|
+
<Toggle variant="soft" shape="pill" size="xs">
|
|
103
|
+
検証
|
|
104
|
+
</Toggle>
|
|
105
|
+
</Flex>
|
|
106
|
+
<Flex direction="row" gap="sm" wrap align="center">
|
|
107
|
+
<Toggle variant="soft" shape="default">
|
|
108
|
+
default(--radius-md)
|
|
109
|
+
</Toggle>
|
|
110
|
+
<Toggle variant="soft" shape="pill">
|
|
111
|
+
pill
|
|
112
|
+
</Toggle>
|
|
113
|
+
<Toggle variant="soft" shape="sharp">
|
|
114
|
+
sharp
|
|
115
|
+
</Toggle>
|
|
116
|
+
</Flex>
|
|
117
|
+
<Text as="p" size="xs" tone="muted">
|
|
118
|
+
soft の面は Badge variant="secondary" / Button
|
|
119
|
+
variant="secondary" と同じ --secondary。ホバーは不透明な --secondary-hover
|
|
120
|
+
なので、ページの上でもカードの上でも同じ色になる。
|
|
121
|
+
</Text>
|
|
70
122
|
</Flex>
|
|
71
123
|
</CardContent>
|
|
72
124
|
</Card>
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "@godxjp/ui/data-entry";
|
|
10
10
|
import { Button, Text } from "@godxjp/ui/general";
|
|
11
11
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
12
|
+
import { FilePlus2, Plus } from "lucide-react";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Upload — drag-and-drop / button / avatar / picture file uploader (6 variants).
|
|
@@ -32,6 +33,7 @@ export default function Demo() {
|
|
|
32
33
|
const [submittedFiles, setSubmittedFiles] = useState<string[]>([]);
|
|
33
34
|
const [dropzoneItems, setDropzoneItems] = useState<UploadFileItem[]>([]);
|
|
34
35
|
const [buttonItems, setButtonItems] = useState<UploadFileItem[]>([]);
|
|
36
|
+
const [triggerIconItems, setTriggerIconItems] = useState<UploadFileItem[]>([]);
|
|
35
37
|
const [pictureCardItems, setPictureCardItems] = useState<UploadFileItem[]>([]);
|
|
36
38
|
const [pictureItem, setPictureItem] = useState<UploadFileItem[]>([]);
|
|
37
39
|
const [avatarItem, setAvatarItem] = useState<UploadFileItem[]>([]);
|
|
@@ -187,6 +189,48 @@ export default function Demo() {
|
|
|
187
189
|
</CardContent>
|
|
188
190
|
</Card>
|
|
189
191
|
|
|
192
|
+
<Card>
|
|
193
|
+
<CardHeader>
|
|
194
|
+
<CardTitle level={2}>triggerIcon · 「新規作成」がアップロードのとき</CardTitle>
|
|
195
|
+
<CardDescription>
|
|
196
|
+
variant="button"
|
|
197
|
+
のトリガーが描くグリフを差し替える。コンポーネントを渡す(triggerIcon={Plus}、
|
|
198
|
+
要素ではない)。triggerVariant
|
|
199
|
+
は強弱しか変えられないので、実体はアップロードでも「新規作成」として並ぶボタンは
|
|
200
|
+
これまで矢印を背負うしかなかった。クラスと余白と aria-hidden
|
|
201
|
+
はライブラリ側が持ったままなので、差し替えても大きさは --upload-row-icon-size
|
|
202
|
+
のまま、読み上げにも出ない。
|
|
203
|
+
</CardDescription>
|
|
204
|
+
</CardHeader>
|
|
205
|
+
<CardContent>
|
|
206
|
+
<Flex direction="row" gap="md" wrap align="center">
|
|
207
|
+
<Upload
|
|
208
|
+
variant="button"
|
|
209
|
+
triggerIcon={Plus}
|
|
210
|
+
triggerVariant="default"
|
|
211
|
+
value={triggerIconItems}
|
|
212
|
+
onValueChange={setTriggerIconItems}
|
|
213
|
+
accept=".pdf"
|
|
214
|
+
onUpload={demoUpload}
|
|
215
|
+
>
|
|
216
|
+
資料を追加
|
|
217
|
+
</Upload>
|
|
218
|
+
<Upload
|
|
219
|
+
variant="button"
|
|
220
|
+
triggerIcon={FilePlus2}
|
|
221
|
+
triggerSize="icon-sm"
|
|
222
|
+
triggerVariant="ghost"
|
|
223
|
+
value={[]}
|
|
224
|
+
onValueChange={() => {}}
|
|
225
|
+
aria-label="請求書を添付"
|
|
226
|
+
/>
|
|
227
|
+
<Upload variant="button" value={[]} onValueChange={() => {}}>
|
|
228
|
+
既定のグリフ
|
|
229
|
+
</Upload>
|
|
230
|
+
</Flex>
|
|
231
|
+
</CardContent>
|
|
232
|
+
</Card>
|
|
233
|
+
|
|
190
234
|
<Card>
|
|
191
235
|
<CardHeader>
|
|
192
236
|
<CardTitle level={2}>Picture Card</CardTitle>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "@godxjp/ui/data-display";
|
|
9
9
|
import { Button } from "@godxjp/ui/general";
|
|
10
10
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
11
|
-
import { Pencil, Plus, Trash2 } from "lucide-react";
|
|
11
|
+
import { Bell, Pencil, Plus, Trash2 } from "lucide-react";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Button — the core action primitive. Composed only from real @godxjp/ui
|
|
@@ -26,23 +26,35 @@ export default function Demo() {
|
|
|
26
26
|
<CardHeader>
|
|
27
27
|
<CardTitle level={2}>Count</CardTitle>
|
|
28
28
|
<CardDescription>
|
|
29
|
-
Trailing totals, overflow cap, and explicit zero visibility.
|
|
29
|
+
Trailing totals, overflow cap, and explicit zero visibility. countLabel
|
|
30
|
+
は数字が何を数えているかを読み上げに渡す(Toggle と同じ語彙)。ピルは aria-hidden
|
|
31
|
+
で、単位つきの一文が sr-only で並ぶので、名前は「保留中, 18 件」。countLabel
|
|
32
|
+
を渡さなくても「保留中, 18」までは分かれる。
|
|
30
33
|
</CardDescription>
|
|
31
34
|
</CardHeader>
|
|
32
35
|
<CardContent>
|
|
33
36
|
<Flex direction="row" wrap align="center" gap="md">
|
|
34
|
-
<Button variant="outline" count={18}>
|
|
37
|
+
<Button variant="outline" count={18} countLabel="件">
|
|
35
38
|
保留中
|
|
36
39
|
</Button>
|
|
37
|
-
<Button variant="outline" count={128} overflowCount={99}>
|
|
40
|
+
<Button variant="outline" count={128} overflowCount={99} countLabel="件">
|
|
38
41
|
受信トレイ
|
|
39
42
|
</Button>
|
|
40
|
-
<Button variant="ghost" count={0} showZero>
|
|
43
|
+
<Button variant="ghost" count={0} showZero countLabel="件">
|
|
41
44
|
完了
|
|
42
45
|
</Button>
|
|
43
|
-
<Button variant="ghost" count={0} showZero={false}>
|
|
46
|
+
<Button variant="ghost" count={0} showZero={false} countLabel="件">
|
|
44
47
|
非表示のゼロ
|
|
45
48
|
</Button>
|
|
49
|
+
<Button
|
|
50
|
+
variant="outline"
|
|
51
|
+
size="icon-sm"
|
|
52
|
+
aria-label="通知"
|
|
53
|
+
count={3}
|
|
54
|
+
countLabel="件の未読"
|
|
55
|
+
>
|
|
56
|
+
<Bell aria-hidden="true" />
|
|
57
|
+
</Button>
|
|
46
58
|
</Flex>
|
|
47
59
|
</CardContent>
|
|
48
60
|
</Card>
|
package/docs/general/icon.tsx
CHANGED
|
@@ -183,7 +183,9 @@ export default function Demo() {
|
|
|
183
183
|
|
|
184
184
|
<Flex direction="col" gap="xs">
|
|
185
185
|
<Heading level={3}>Button の中 · 明示した段が Button の既定に勝つ</Heading>
|
|
186
|
-
|
|
186
|
+
{/* 320px では 2 つのラベル付き Button が 1 行に収まらない。Button はラベル幅より
|
|
187
|
+
縮まないので、行を折り返させるのは並べた側の責任(`wrap`)。 */}
|
|
188
|
+
<Flex direction="row" gap="sm" align="center" wrap>
|
|
187
189
|
<Button size="sm">
|
|
188
190
|
<Icon as={Download} size="sm" />
|
|
189
191
|
書き出す
|