@godxjp/ui 27.4.1 → 27.6.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.js +9 -6
- package/dist/components/data-entry/upload-file-kind.d.ts +25 -0
- package/dist/components/data-entry/upload-file-kind.js +88 -0
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +10 -6
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +2 -0
- package/dist/components/ui/segmented.d.ts +7 -2
- package/dist/components/ui/toggle.d.ts +2 -2
- package/dist/components/ui/toggle.js +4 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/props/components/data-display.prop.d.ts +14 -0
- package/dist/props/components/data-entry.prop.d.ts +28 -2
- package/dist/props/registry.d.ts +6 -1
- package/dist/props/registry.js +6 -1
- package/dist/styles/control.css +18 -6
- package/dist/styles/data-display-layout.css +40 -8
- package/dist/styles/data-entry-layout.css +22 -0
- package/dist/tokens/components/control.css +1 -0
- package/dist/tokens/components/data-display.css +26 -0
- package/dist/tokens/components/segmented.css +4 -0
- package/dist/tokens/components/upload.css +4 -0
- package/docs/CUSTOMER-THEMING.md +26 -0
- package/docs/data-display/avatar.tsx +128 -11
- package/docs/data-display/prose.tsx +64 -0
- package/docs/data-display/timeline.tsx +36 -0
- package/docs/data-entry/calendar.tsx +2 -3
- package/docs/data-entry/segmented.tsx +55 -5
- package/docs/data-entry/toggle-group.tsx +15 -3
- package/docs/data-entry/toggle.tsx +39 -1
- package/docs/data-entry/upload.tsx +38 -0
- package/package.json +2 -2
- package/scripts/_agent-setup.mjs +80 -1
- package/scripts/cli.mjs +5 -1
- package/scripts/init-agent-kit.mjs +3 -0
- package/scripts/postinstall.mjs +5 -0
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
--prose-code-font-size: calc(1em / var(--font-size-ratio));
|
|
31
31
|
--prose-code-space-inline: var(--space-1);
|
|
32
32
|
--prose-code-radius: var(--radius-sm);
|
|
33
|
+
|
|
34
|
+
--prose-link-color: initial;
|
|
35
|
+
|
|
36
|
+
--prose-link-decoration-line: underline;
|
|
33
37
|
--prose-image-radius: var(--radius-md);
|
|
34
38
|
--timeline-note-font-size: var(--font-size-xs);
|
|
35
39
|
|
|
@@ -37,6 +41,28 @@
|
|
|
37
41
|
|
|
38
42
|
--avatar-tint: transparent;
|
|
39
43
|
|
|
44
|
+
--avatar-size: var(--control-height);
|
|
45
|
+
|
|
46
|
+
--avatar-size-xs: var(--control-height-xs);
|
|
47
|
+
|
|
48
|
+
--avatar-size-sm: var(--control-height-sm);
|
|
49
|
+
|
|
50
|
+
--avatar-size-lg: var(--control-height-lg);
|
|
51
|
+
|
|
52
|
+
--avatar-font-size: var(--font-size-base);
|
|
53
|
+
|
|
54
|
+
--avatar-font-size-xs: var(--font-size-2xs);
|
|
55
|
+
|
|
56
|
+
--avatar-font-size-sm: var(--font-size-xs);
|
|
57
|
+
|
|
58
|
+
--avatar-font-size-lg: var(--font-size-lg);
|
|
59
|
+
|
|
60
|
+
--avatar-glyph-size-xs: calc(var(--icon-size-xs) * var(--scaling));
|
|
61
|
+
|
|
62
|
+
--avatar-glyph-size-sm: calc(var(--icon-size-sm) * var(--scaling));
|
|
63
|
+
|
|
64
|
+
--avatar-glyph-size-lg: calc(var(--icon-size-lg) * var(--scaling));
|
|
65
|
+
|
|
40
66
|
--avatar-square-radius: var(--radius-lg);
|
|
41
67
|
--avatar-square-size: var(--control-height);
|
|
42
68
|
--avatar-square-background: initial;
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
--segmented-item-padding-inline: calc(var(--control-padding-x) - 1px);
|
|
13
13
|
|
|
14
|
+
--segmented-xs-font-size: var(--font-size-xs);
|
|
15
|
+
|
|
16
|
+
--segmented-xs-item-padding-inline: calc(var(--control-padding-x-compact) - 1px);
|
|
17
|
+
|
|
14
18
|
--segmented-item-gap: calc(var(--space-3) / 2);
|
|
15
19
|
|
|
16
20
|
--segmented-item-color: var(--muted-foreground);
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
--upload-picture-radius: var(--radius-md);
|
|
31
31
|
--upload-picture-preview-max-height: 12rem;
|
|
32
32
|
--upload-picture-empty-height: 8rem;
|
|
33
|
+
|
|
34
|
+
--upload-picture-icon-size: var(--icon-size-2xl);
|
|
33
35
|
--upload-picture-empty-label-space-block-start: var(--space-2);
|
|
34
36
|
--upload-picture-empty-label-font-size: var(--font-size-sm);
|
|
35
37
|
--upload-picture-overlay-font-size: var(--font-size-sm);
|
|
@@ -41,6 +43,8 @@
|
|
|
41
43
|
--upload-picture-badge-font-size: var(--font-size-xs);
|
|
42
44
|
|
|
43
45
|
--upload-avatar-size: 6rem;
|
|
46
|
+
|
|
47
|
+
--upload-avatar-icon-size: var(--icon-size-xl);
|
|
44
48
|
--upload-avatar-border-width: var(--stroke-md);
|
|
45
49
|
--upload-avatar-change-space-block: var(--space-1);
|
|
46
50
|
|
package/docs/CUSTOMER-THEMING.md
CHANGED
|
@@ -213,6 +213,32 @@ Density (`<PageContainer density>`) scales component sizes, not the grid. - **Pi
|
|
|
213
213
|
|
|
214
214
|
---
|
|
215
215
|
|
|
216
|
+
## Selectors the package promises are YOURS
|
|
217
|
+
|
|
218
|
+
A `data-*` attribute the package never writes is a selector you can hold a stylesheet against — the one place where CSS of your own is the documented route rather than a workaround. Each of these is a promise held by a test, not an accident of the current markup:
|
|
219
|
+
|
|
220
|
+
| You write | The package promises | Why it exists |
|
|
221
|
+
| --- | --- | --- |
|
|
222
|
+
| `.ui-prose a[data-…]` | Prose writes `data-*` on its **own root only** — never on a descendant. Every `data-*` on an `a` inside it is yours, survives the render, and stays selectable (gh#717) | A renderer knows things about a link that the package cannot: in a wiki, a link whose target **does not exist yet** must read differently from one that resolves |
|
|
223
|
+
| `<TableRow data-expanded-row="">` | The striping counts records, not DOM rows — a row you mark is skipped in the count and wears its record's stripe | A detail row under a record is your composition, not a row of data |
|
|
224
|
+
| `[data-tenant]`, `[data-program]` | Every anchor token re-resolves at the scope (below) | One app, many brands |
|
|
225
|
+
|
|
226
|
+
**Style a marked link through the knob, not around it.** `--prose-link-color` is read as `hsl(var(--prose-link-color, var(--primary)))` **at the anchor**, so declaring the custom property inside your own higher-specificity selector is enough — you never have to restate the `color` declaration, and a later package change to how the ink is painted still reaches you:
|
|
227
|
+
|
|
228
|
+
```css
|
|
229
|
+
/* your app's stylesheet */
|
|
230
|
+
.ui-prose a[data-unresolved="true"] {
|
|
231
|
+
--prose-link-color: var(--text-error); /* the TEXT tier — 7.25:1 light, 5.51:1 dark on a card */
|
|
232
|
+
text-decoration-style: dashed;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Use `--text-error`, not `--destructive`: the fill tier is tuned for a white label on top of it and measures 2.95:1 as ink on the dark card (gh#610). The whole family is `--prose-link-color` (default `hsl(var(--primary))`, resolved at the anchor so a scoped re-tint reaches it) and `--prose-link-decoration-line` (default `underline`). Set the first on `[data-tenant]` to re-tint every wiki link at once.
|
|
237
|
+
|
|
238
|
+
There is **no prop** naming the attribute, deliberately: the attribute IS the API, the same way `data-expanded-row` and `data-axe-open` are. A prop would make the package own a name only your renderer knows, and would let exactly one state be marked.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
216
242
|
## Multi-tenant (one app, many brands)
|
|
217
243
|
|
|
218
244
|
Scope the overrides under a tenant attribute instead of `:root`. The colour utilities are declared with `@theme inline`, so a scoped `--primary` (and the other anchors) **re-resolve at the element** — `bg-primary`, `text-success`, every component surface, the focus ring, the brand glow, gradients and the modal scrim all retint inside the scope:
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
CardTitle,
|
|
10
10
|
ListRow,
|
|
11
11
|
} from "@godxjp/ui/data-display";
|
|
12
|
-
import { Text } from "@godxjp/ui/general";
|
|
12
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
13
13
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
14
14
|
import { Building2, KeyRound, ShieldCheck, Sparkles } from "lucide-react";
|
|
15
15
|
|
|
@@ -34,7 +34,9 @@ import portraitSlate from "../assets/portrait-slate.svg";
|
|
|
34
34
|
/**
|
|
35
35
|
* Avatar — identity image with a readable fallback (users, teams, entities).
|
|
36
36
|
* Always compose AvatarImage + AvatarFallback so broken/missing images degrade
|
|
37
|
-
* gracefully. Size
|
|
37
|
+
* gracefully. Size on the control ladder with `size` (xs/sm/md/lg, the same
|
|
38
|
+
* --control-height tier Button reads); className only for sizes off that ladder.
|
|
39
|
+
* Composed only from real @godxjp/ui components.
|
|
38
40
|
*/
|
|
39
41
|
export default function Demo() {
|
|
40
42
|
return (
|
|
@@ -322,25 +324,140 @@ export default function Demo() {
|
|
|
322
324
|
</CardContent>
|
|
323
325
|
</Card>
|
|
324
326
|
|
|
327
|
+
{/* size — the control ladder (gh#716) */}
|
|
325
328
|
<Card>
|
|
326
329
|
<CardHeader>
|
|
327
|
-
<CardTitle level={2}
|
|
330
|
+
<CardTitle level={2}>サイズ · size</CardTitle>
|
|
328
331
|
<CardDescription>
|
|
329
|
-
|
|
330
|
-
|
|
332
|
+
xs 24px / sm 28px / md 32px(既定) / lg 36px。すべて Button や Input と同じ
|
|
333
|
+
--control-height の段なので、同じ段の Button
|
|
334
|
+
と並べたときに高さがそろう。イニシャルの級数もグリフの箱も同じ段で動くため、小さい
|
|
335
|
+
マークは「小さい」であって「切れている」ではない。shape="square"
|
|
336
|
+
も同じ段に乗る。 ラダーの外側のサイズ(プロフィール用の 96px マークなど)は従来どおり
|
|
337
|
+
className。
|
|
338
|
+
</CardDescription>
|
|
339
|
+
</CardHeader>
|
|
340
|
+
<CardContent>
|
|
341
|
+
<Flex direction="col" gap="md">
|
|
342
|
+
<Flex direction="row" wrap align="center" gap="md">
|
|
343
|
+
<Avatar size="xs">
|
|
344
|
+
<AvatarFallback>XS</AvatarFallback>
|
|
345
|
+
</Avatar>
|
|
346
|
+
<Avatar size="sm">
|
|
347
|
+
<AvatarFallback>SM</AvatarFallback>
|
|
348
|
+
</Avatar>
|
|
349
|
+
<Avatar>
|
|
350
|
+
<AvatarFallback>MD</AvatarFallback>
|
|
351
|
+
</Avatar>
|
|
352
|
+
<Avatar size="lg">
|
|
353
|
+
<AvatarFallback>LG</AvatarFallback>
|
|
354
|
+
</Avatar>
|
|
355
|
+
</Flex>
|
|
356
|
+
{/* square rides the identical ladder */}
|
|
357
|
+
<Flex direction="row" wrap align="center" gap="md">
|
|
358
|
+
<Avatar size="xs" shape="square">
|
|
359
|
+
<AvatarFallback>山</AvatarFallback>
|
|
360
|
+
</Avatar>
|
|
361
|
+
<Avatar size="sm" shape="square">
|
|
362
|
+
<AvatarFallback>山</AvatarFallback>
|
|
363
|
+
</Avatar>
|
|
364
|
+
<Avatar shape="square">
|
|
365
|
+
<AvatarFallback>山</AvatarFallback>
|
|
366
|
+
</Avatar>
|
|
367
|
+
<Avatar size="lg" shape="square">
|
|
368
|
+
<AvatarFallback>山</AvatarFallback>
|
|
369
|
+
</Avatar>
|
|
370
|
+
</Flex>
|
|
371
|
+
{/* the glyph steps with the box, so a medallion is never clipped */}
|
|
372
|
+
<Flex direction="row" wrap align="center" gap="md">
|
|
373
|
+
<Avatar size="xs" shape="square" appearance="tinted">
|
|
374
|
+
<AvatarFallback>
|
|
375
|
+
<ShieldCheck aria-hidden="true" />
|
|
376
|
+
</AvatarFallback>
|
|
377
|
+
</Avatar>
|
|
378
|
+
<Avatar size="sm" shape="square" appearance="tinted">
|
|
379
|
+
<AvatarFallback>
|
|
380
|
+
<ShieldCheck aria-hidden="true" />
|
|
381
|
+
</AvatarFallback>
|
|
382
|
+
</Avatar>
|
|
383
|
+
<Avatar shape="square" appearance="tinted">
|
|
384
|
+
<AvatarFallback>
|
|
385
|
+
<ShieldCheck aria-hidden="true" />
|
|
386
|
+
</AvatarFallback>
|
|
387
|
+
</Avatar>
|
|
388
|
+
<Avatar size="lg" shape="square" appearance="tinted">
|
|
389
|
+
<AvatarFallback>
|
|
390
|
+
<ShieldCheck aria-hidden="true" />
|
|
391
|
+
</AvatarFallback>
|
|
392
|
+
</Avatar>
|
|
393
|
+
</Flex>
|
|
394
|
+
</Flex>
|
|
395
|
+
</CardContent>
|
|
396
|
+
</Card>
|
|
397
|
+
|
|
398
|
+
{/* The row that could not be built before #716 */}
|
|
399
|
+
<Card>
|
|
400
|
+
<CardHeader>
|
|
401
|
+
<CardTitle level={2}>行に入るマーク · size="sm" と icon-sm</CardTitle>
|
|
402
|
+
<CardDescription>
|
|
403
|
+
行の高さが先に決まっている場所(28px の icon-sm トリガ、24/28px
|
|
404
|
+
の密なテーブル行)では、マークの側が行に合わせる。#716 以前は箱が --control-height
|
|
405
|
+
に固定されていたため、28px のトリガに 32px
|
|
406
|
+
のマークが入って外へはみ出し、消費側に残された手は「行全体を 32px
|
|
407
|
+
に上げる」だけだった。 下の 1 段目は同じ段の Button と並べたもの、2 段目は icon-sm
|
|
408
|
+
トリガの中に入れたもの。
|
|
409
|
+
</CardDescription>
|
|
410
|
+
</CardHeader>
|
|
411
|
+
<CardContent>
|
|
412
|
+
<Flex direction="col" gap="md">
|
|
413
|
+
<Flex direction="row" wrap align="center" gap="sm">
|
|
414
|
+
<Avatar size="sm">
|
|
415
|
+
<AvatarImage src={portraitSlate} alt="" />
|
|
416
|
+
<AvatarFallback>田</AvatarFallback>
|
|
417
|
+
</Avatar>
|
|
418
|
+
<Button size="sm" variant="outline">
|
|
419
|
+
担当者を変更
|
|
420
|
+
</Button>
|
|
421
|
+
<Avatar size="xs">
|
|
422
|
+
<AvatarFallback>佐</AvatarFallback>
|
|
423
|
+
</Avatar>
|
|
424
|
+
<Button size="xs" variant="outline">
|
|
425
|
+
履歴
|
|
426
|
+
</Button>
|
|
427
|
+
</Flex>
|
|
428
|
+
<Flex direction="row" wrap align="center" gap="sm">
|
|
429
|
+
<Button size="icon-sm" variant="ghost" aria-label="担当者 田中 未来">
|
|
430
|
+
<Avatar size="sm">
|
|
431
|
+
<AvatarImage src={portraitMoss} alt="" />
|
|
432
|
+
<AvatarFallback>田</AvatarFallback>
|
|
433
|
+
</Avatar>
|
|
434
|
+
</Button>
|
|
435
|
+
<Button size="icon-xs" variant="ghost" aria-label="担当者 佐藤 玲">
|
|
436
|
+
<Avatar size="xs">
|
|
437
|
+
<AvatarFallback>佐</AvatarFallback>
|
|
438
|
+
</Avatar>
|
|
439
|
+
</Button>
|
|
440
|
+
<Text as="p" size="xs" tone="muted">
|
|
441
|
+
マークはトリガの内寸に収まる(28px の中に 28px、24px の中に 24px)。
|
|
442
|
+
</Text>
|
|
443
|
+
</Flex>
|
|
444
|
+
</Flex>
|
|
445
|
+
</CardContent>
|
|
446
|
+
</Card>
|
|
447
|
+
|
|
448
|
+
<Card>
|
|
449
|
+
<CardHeader>
|
|
450
|
+
<CardTitle level={2}>ラダーの外 · className</CardTitle>
|
|
451
|
+
<CardDescription>
|
|
452
|
+
コントロール行の段に無いサイズ(プロフィールヘッダの大きなマークなど)は、従来どおり
|
|
453
|
+
size-* ユーティリティで指定する。
|
|
331
454
|
</CardDescription>
|
|
332
455
|
</CardHeader>
|
|
333
456
|
<CardContent>
|
|
334
457
|
<Flex direction="row" wrap align="center" gap="md">
|
|
335
|
-
<Avatar className="size-8">
|
|
336
|
-
<AvatarFallback>S</AvatarFallback>
|
|
337
|
-
</Avatar>
|
|
338
458
|
<Avatar className="size-10">
|
|
339
459
|
<AvatarFallback>M</AvatarFallback>
|
|
340
460
|
</Avatar>
|
|
341
|
-
<Avatar>
|
|
342
|
-
<AvatarFallback>D</AvatarFallback>
|
|
343
|
-
</Avatar>
|
|
344
461
|
<Avatar className="size-12">
|
|
345
462
|
<AvatarFallback>L</AvatarFallback>
|
|
346
463
|
</Avatar>
|
|
@@ -13,6 +13,34 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
|
13
13
|
* semantic HTML inside it from the tokens; the HTML can come from react-markdown, a sanitised
|
|
14
14
|
* string or JSX. Composed only from real @godxjp/ui components.
|
|
15
15
|
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A CONSUMER'S OWN STYLESHEET — the file their app already has, not part of the package. It is
|
|
19
|
+
* inlined here so the third card below is the real thing rather than a description of it.
|
|
20
|
+
*
|
|
21
|
+
* Both halves of the gh#717 contract are exercised:
|
|
22
|
+
* · `--prose-link-*` — the service tunes every link in its wiki once, through the knob;
|
|
23
|
+
* · `a[data-unresolved]` — Prose writes `data-*` on its own ROOT only, so every `data-*` on a
|
|
24
|
+
* descendant `a` is the consumer's and stays selectable. That is a promise, held by
|
|
25
|
+
* src/components/data-display/__tests__/prose-link-717.test.tsx.
|
|
26
|
+
*
|
|
27
|
+
* Measured on the card surface (#fdfdfc light / #21201c dark):
|
|
28
|
+
* resolved --text-link #6400d4 → 8.29:1 light · #dcbcff → 9.85:1 dark
|
|
29
|
+
* unresolved --text-error #aa181f → 7.25:1 light · #eb7076 → 5.51:1 dark
|
|
30
|
+
* The TEXT tier, never `--destructive`: that is the FILL tier, tuned for a white label on top of
|
|
31
|
+
* it, and it measures 2.95:1 as ink on the dark card (gh#610).
|
|
32
|
+
*/
|
|
33
|
+
const WIKI_STYLESHEET = `
|
|
34
|
+
[data-wiki] {
|
|
35
|
+
--prose-link-color: var(--text-link);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-wiki] a[data-unresolved="true"] {
|
|
39
|
+
--prose-link-color: var(--text-error);
|
|
40
|
+
text-decoration-style: dashed;
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
16
44
|
export default function Demo() {
|
|
17
45
|
return (
|
|
18
46
|
<PageContainer title="Prose" subtitle="レンダリングされた本文のタイポグラフィ">
|
|
@@ -99,6 +127,42 @@ export default function Demo() {
|
|
|
99
127
|
</Prose>
|
|
100
128
|
</CardContent>
|
|
101
129
|
</Card>
|
|
130
|
+
|
|
131
|
+
<Card>
|
|
132
|
+
<CardHeader>
|
|
133
|
+
<CardTitle level={2}>Wiki body · リンクの状態 (--prose-link-*)</CardTitle>
|
|
134
|
+
<CardDescription>
|
|
135
|
+
リンクの色と下線は --prose-link-color / --prose-link-decoration-line で調整する。Prose
|
|
136
|
+
は自身のルート以外に data-* を書かないため、a[data-…]
|
|
137
|
+
は利用側が所有するセレクタとして保証される。ここではまだ存在しないページへのリンクを
|
|
138
|
+
--text-error +破線で示した。カード面でのコントラストは、解決済み 8.29:1 (ライト) /
|
|
139
|
+
9.85:1 (ダーク)、未解決 7.25:1 / 5.51:1。
|
|
140
|
+
</CardDescription>
|
|
141
|
+
</CardHeader>
|
|
142
|
+
<CardContent>
|
|
143
|
+
<style>{WIKI_STYLESHEET}</style>
|
|
144
|
+
<Prose size="md" data-wiki="">
|
|
145
|
+
<h2>出張費の精算</h2>
|
|
146
|
+
<p>
|
|
147
|
+
原則は <a href="#rules">精算規程</a> に従う。宿泊費の上限は地域区分で変わるため、
|
|
148
|
+
<a href="#lodging" data-unresolved="true">
|
|
149
|
+
宿泊費区分表
|
|
150
|
+
</a>{" "}
|
|
151
|
+
を参照すること(このページはまだ書かれていない)。
|
|
152
|
+
</p>
|
|
153
|
+
<ul>
|
|
154
|
+
<li>
|
|
155
|
+
<a href="#receipt">領収書の要件</a>
|
|
156
|
+
</li>
|
|
157
|
+
<li>
|
|
158
|
+
<a href="#foreign" data-unresolved="true">
|
|
159
|
+
海外出張の為替レート
|
|
160
|
+
</a>
|
|
161
|
+
</li>
|
|
162
|
+
</ul>
|
|
163
|
+
</Prose>
|
|
164
|
+
</CardContent>
|
|
165
|
+
</Card>
|
|
102
166
|
</Flex>
|
|
103
167
|
</PageContainer>
|
|
104
168
|
);
|
|
@@ -200,6 +200,42 @@ export default function Demo() {
|
|
|
200
200
|
</CardContent>
|
|
201
201
|
</Card>
|
|
202
202
|
|
|
203
|
+
<Card>
|
|
204
|
+
<CardHeader>
|
|
205
|
+
<CardTitle level={2}>月をまたぐ日単位の軸(bands)</CardTitle>
|
|
206
|
+
<CardDescription>
|
|
207
|
+
9月25日から10月7日まで。bands
|
|
208
|
+
の月の境界は、その月の1日の列の境界にぴったり重なります。
|
|
209
|
+
始まりが月の途中なので、最初の月の帯は6日分だけの幅です。
|
|
210
|
+
</CardDescription>
|
|
211
|
+
</CardHeader>
|
|
212
|
+
<CardContent>
|
|
213
|
+
<RangeTimeline
|
|
214
|
+
label={t("rangeTimeline.schedule")}
|
|
215
|
+
bands={[
|
|
216
|
+
{ label: monthLabel(8), units: 6 },
|
|
217
|
+
{ label: monthLabel(9), units: 7 },
|
|
218
|
+
]}
|
|
219
|
+
columns={Array.from({ length: 13 }, (_, index) => {
|
|
220
|
+
const date = new Date(Date.UTC(2026, 8, 25 + index));
|
|
221
|
+
return {
|
|
222
|
+
label: new Intl.NumberFormat(locale).format(date.getUTCDate()),
|
|
223
|
+
units: 1,
|
|
224
|
+
muted: date.getUTCDay() === 0 || date.getUTCDay() === 6,
|
|
225
|
+
};
|
|
226
|
+
})}
|
|
227
|
+
rows={[
|
|
228
|
+
{ id: "migration", label: "移行", start: 3, end: 8 },
|
|
229
|
+
{ id: "october", label: "10月の作業", start: 6, end: 12 },
|
|
230
|
+
].map((row) => ({
|
|
231
|
+
...row,
|
|
232
|
+
startLabel: dayLabel(25 + row.start),
|
|
233
|
+
endLabel: dayLabel(25 + row.end),
|
|
234
|
+
}))}
|
|
235
|
+
/>
|
|
236
|
+
</CardContent>
|
|
237
|
+
</Card>
|
|
238
|
+
|
|
203
239
|
<Card>
|
|
204
240
|
<CardHeader>
|
|
205
241
|
<CardTitle level={2}>月単位の軸(列ごとに units が異なる)</CardTitle>
|
|
@@ -77,9 +77,8 @@ export default function Demo() {
|
|
|
77
77
|
罫線 (bordered) · 既定で表示 / bordered={"{false}"} で解除
|
|
78
78
|
</CardTitle>
|
|
79
79
|
<CardDescription>
|
|
80
|
-
日と日の間に罫線を引くのが既定。線色は --calendar-grid-border-color (既定
|
|
81
|
-
|
|
82
|
-
以上)。選択日・今日・範囲の始点/中間/終点・無効日・前後月の日が
|
|
80
|
+
日と日の間に罫線を引くのが既定。線色は --calendar-grid-border-color (既定 --input の
|
|
81
|
+
50%、背景に対し約 1.7:1)。選択日・今日・範囲の始点/中間/終点・無効日・前後月の日が
|
|
83
82
|
罫線の中でも判別できる。罫線なしの浮いたボタン表示にしたい場合のみ bordered=
|
|
84
83
|
{"{false}"} を渡す。
|
|
85
84
|
</CardDescription>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
|
|
4
|
-
import { FormField, Segmented } from "@godxjp/ui/data-entry";
|
|
5
|
-
import { Text, VisuallyHidden } from "@godxjp/ui/general";
|
|
4
|
+
import { FormField, Segmented, ToggleGroup, ToggleGroupItem } from "@godxjp/ui/data-entry";
|
|
5
|
+
import { Button, Text, VisuallyHidden } from "@godxjp/ui/general";
|
|
6
6
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
7
7
|
import { CalendarDays, Columns3, LayoutList, Monitor, Moon, Sun } from "lucide-react";
|
|
8
8
|
|
|
@@ -110,14 +110,25 @@ export default function Demo() {
|
|
|
110
110
|
<CardHeader>
|
|
111
111
|
<CardTitle level={2}>size · vertical · block</CardTitle>
|
|
112
112
|
<CardDescription>
|
|
113
|
-
size は
|
|
114
|
-
MobileShell
|
|
115
|
-
vertical では 1 行ぶんが 1
|
|
113
|
+
size は 4 段(xs 24px / sm 28px / md 32px / lg 36px)。トラックの高さは
|
|
114
|
+
--control-height そのもので、MobileShell のようにその変数をスコープする領域では
|
|
115
|
+
自動的にタッチ段(44px)になります。vertical では 1 行ぶんが 1
|
|
116
|
+
コントロールの高さになります。横 1 行のときだけトラック
|
|
116
117
|
内側の余白を引くので、積んだときは引きません。block は幅いっぱいに広げます。
|
|
117
118
|
</CardDescription>
|
|
118
119
|
</CardHeader>
|
|
119
120
|
<CardContent>
|
|
120
121
|
<Flex direction="col" gap="md" align="start">
|
|
122
|
+
<Segmented
|
|
123
|
+
aria-label="サイズ xs"
|
|
124
|
+
size="xs"
|
|
125
|
+
defaultValue="a"
|
|
126
|
+
options={[
|
|
127
|
+
{ value: "a", label: "小" },
|
|
128
|
+
{ value: "b", label: "中" },
|
|
129
|
+
{ value: "c", label: "大" },
|
|
130
|
+
]}
|
|
131
|
+
/>
|
|
121
132
|
<Segmented
|
|
122
133
|
aria-label="サイズ sm"
|
|
123
134
|
size="sm"
|
|
@@ -162,6 +173,45 @@ export default function Demo() {
|
|
|
162
173
|
</CardContent>
|
|
163
174
|
</Card>
|
|
164
175
|
|
|
176
|
+
<Card>
|
|
177
|
+
<CardHeader>
|
|
178
|
+
<CardTitle level={2}>24px の密な行 · size="xs"</CardTitle>
|
|
179
|
+
<CardDescription>
|
|
180
|
+
行の高さが 24px に決まっている監査ログや明細ツールバーでは、xs
|
|
181
|
+
のトラックがそのまま収まる。同じ段の ToggleGroup size="xs" と Button
|
|
182
|
+
size="xs" と高さが一致するので、行が段差にならない。ここで xs
|
|
183
|
+
が無かったころは Button を並べて自作するしかなく、radiogroup
|
|
184
|
+
の読み上げも矢印キーも失われていた。
|
|
185
|
+
</CardDescription>
|
|
186
|
+
</CardHeader>
|
|
187
|
+
<CardContent>
|
|
188
|
+
<Flex direction="col" gap="sm">
|
|
189
|
+
<Flex direction="row" gap="sm" align="center">
|
|
190
|
+
<Segmented
|
|
191
|
+
aria-label="表示期間"
|
|
192
|
+
size="xs"
|
|
193
|
+
defaultValue="week"
|
|
194
|
+
options={[
|
|
195
|
+
{ value: "day", label: "日" },
|
|
196
|
+
{ value: "week", label: "週" },
|
|
197
|
+
{ value: "month", label: "月" },
|
|
198
|
+
]}
|
|
199
|
+
/>
|
|
200
|
+
<ToggleGroup type="single" size="xs" defaultValue="list" aria-label="表示形式">
|
|
201
|
+
<ToggleGroupItem value="list">一覧</ToggleGroupItem>
|
|
202
|
+
<ToggleGroupItem value="board">ボード</ToggleGroupItem>
|
|
203
|
+
</ToggleGroup>
|
|
204
|
+
<Button size="xs" variant="outline">
|
|
205
|
+
絞り込み
|
|
206
|
+
</Button>
|
|
207
|
+
</Flex>
|
|
208
|
+
<Text as="p" size="xs" tone="muted">
|
|
209
|
+
いずれも --control-height-xs(24px)。
|
|
210
|
+
</Text>
|
|
211
|
+
</Flex>
|
|
212
|
+
</CardContent>
|
|
213
|
+
</Card>
|
|
214
|
+
|
|
165
215
|
<Card>
|
|
166
216
|
<CardHeader>
|
|
167
217
|
<CardTitle level={2}>短い記号を出して、長い名前を読ませる</CardTitle>
|
|
@@ -129,14 +129,26 @@ export default function Demo() {
|
|
|
129
129
|
|
|
130
130
|
<Card>
|
|
131
131
|
<CardHeader>
|
|
132
|
-
<CardTitle level={2}>size · sm / md / lg</CardTitle>
|
|
132
|
+
<CardTitle level={2}>size · xs / sm / md / lg</CardTitle>
|
|
133
133
|
<CardDescription>
|
|
134
|
-
size も ToggleGroup にだけ指定すれば全アイテムへ伝播する。md
|
|
135
|
-
|
|
134
|
+
size も ToggleGroup にだけ指定すれば全アイテムへ伝播する。md が既定。xs 24px / sm 28px
|
|
135
|
+
/ md 32px / lg 36px はすべて --control-height
|
|
136
|
+
の同じ段なので、行の高さが先に決まっている場所ではその段を選ぶ。xs は 24px
|
|
137
|
+
の密な行にセグメントを載せるための段。
|
|
136
138
|
</CardDescription>
|
|
137
139
|
</CardHeader>
|
|
138
140
|
<CardContent>
|
|
139
141
|
<Flex direction="col" gap="md">
|
|
142
|
+
<Flex direction="col" gap="sm">
|
|
143
|
+
<Text as="p" size="sm" tone="muted">
|
|
144
|
+
size="xs" · 24px の密な行
|
|
145
|
+
</Text>
|
|
146
|
+
<ToggleGroup type="single" size="xs" defaultValue="day">
|
|
147
|
+
<ToggleGroupItem value="day">日次</ToggleGroupItem>
|
|
148
|
+
<ToggleGroupItem value="month">月次</ToggleGroupItem>
|
|
149
|
+
<ToggleGroupItem value="year">年次</ToggleGroupItem>
|
|
150
|
+
</ToggleGroup>
|
|
151
|
+
</Flex>
|
|
140
152
|
<Flex direction="col" gap="sm">
|
|
141
153
|
<Text as="p" size="sm" tone="muted">
|
|
142
154
|
size="sm"
|
|
@@ -2,6 +2,7 @@ import { useState } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
|
|
4
4
|
import { Toggle } from "@godxjp/ui/data-entry";
|
|
5
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
5
6
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -73,10 +74,18 @@ export default function Demo() {
|
|
|
73
74
|
<Card>
|
|
74
75
|
<CardHeader>
|
|
75
76
|
<CardTitle level={2}>Sizes</CardTitle>
|
|
76
|
-
<CardDescription>
|
|
77
|
+
<CardDescription>
|
|
78
|
+
xs 24px / sm 28px / md 32px / lg 36px · すべて --control-height
|
|
79
|
+
の同じ段。行の高さが先に決まっている場所では、その段を選ぶ。xs は 24px
|
|
80
|
+
の密な行にセグメント状のチップを載せるための段で、Button
|
|
81
|
+
を並べて自作する代わりになる。
|
|
82
|
+
</CardDescription>
|
|
77
83
|
</CardHeader>
|
|
78
84
|
<CardContent>
|
|
79
85
|
<Flex direction="row" gap="md" align="center">
|
|
86
|
+
<Toggle size="xs" aria-label="極小サイズ">
|
|
87
|
+
極小
|
|
88
|
+
</Toggle>
|
|
80
89
|
<Toggle size="sm" aria-label="小サイズ">
|
|
81
90
|
小
|
|
82
91
|
</Toggle>
|
|
@@ -90,6 +99,35 @@ export default function Demo() {
|
|
|
90
99
|
</CardContent>
|
|
91
100
|
</Card>
|
|
92
101
|
|
|
102
|
+
<Card>
|
|
103
|
+
<CardHeader>
|
|
104
|
+
<CardTitle level={2}>24px の密な行 · size="xs"</CardTitle>
|
|
105
|
+
<CardDescription>
|
|
106
|
+
行の高さが 24px に決まっている監査ログや明細ツールバーでは、xs
|
|
107
|
+
のチップがそのまま収まる。同じ段の Button size="xs"
|
|
108
|
+
と高さが一致するので、行が段差にならない。
|
|
109
|
+
</CardDescription>
|
|
110
|
+
</CardHeader>
|
|
111
|
+
<CardContent>
|
|
112
|
+
<Flex direction="col" gap="sm">
|
|
113
|
+
<Flex direction="row" gap="sm" align="center">
|
|
114
|
+
<Toggle size="xs" defaultPressed aria-label="未読のみ">
|
|
115
|
+
未読のみ
|
|
116
|
+
</Toggle>
|
|
117
|
+
<Toggle size="xs" aria-label="添付あり">
|
|
118
|
+
添付あり
|
|
119
|
+
</Toggle>
|
|
120
|
+
<Button size="xs" variant="outline">
|
|
121
|
+
絞り込み
|
|
122
|
+
</Button>
|
|
123
|
+
</Flex>
|
|
124
|
+
<Text as="p" size="xs" tone="muted">
|
|
125
|
+
いずれも --control-height-xs(24px)。
|
|
126
|
+
</Text>
|
|
127
|
+
</Flex>
|
|
128
|
+
</CardContent>
|
|
129
|
+
</Card>
|
|
130
|
+
|
|
93
131
|
<Card>
|
|
94
132
|
<CardHeader>
|
|
95
133
|
<CardTitle level={2}>Count</CardTitle>
|
|
@@ -36,6 +36,25 @@ export default function Demo() {
|
|
|
36
36
|
const [pictureItem, setPictureItem] = useState<UploadFileItem[]>([]);
|
|
37
37
|
const [avatarItem, setAvatarItem] = useState<UploadFileItem[]>([]);
|
|
38
38
|
const [avatarCropItem, setAvatarCropItem] = useState<UploadFileItem[]>([]);
|
|
39
|
+
/** A test-result drawer: one screenshot, one machine-readable result, one log, one archive. */
|
|
40
|
+
const mixedItems: UploadFileItem[] = [
|
|
41
|
+
{
|
|
42
|
+
uid: "mixed-screenshot",
|
|
43
|
+
name: "screenshot.png",
|
|
44
|
+
size: 184 * 1024,
|
|
45
|
+
mimeType: "image/png",
|
|
46
|
+
status: "done",
|
|
47
|
+
previewUrl:
|
|
48
|
+
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='72' height='72'><rect width='72' height='72' fill='%23c9c6bd'/><circle cx='26' cy='26' r='9' fill='%238a877d'/></svg>",
|
|
49
|
+
},
|
|
50
|
+
// Server media whose thumbnail has not been generated yet: still an image, still marked as one.
|
|
51
|
+
{ uid: "mixed-original", name: "photo-original.png", size: 4 * 1024 * 1024, status: "done" },
|
|
52
|
+
{ uid: "mixed-result", name: "result.json", size: 12 * 1024, status: "done" },
|
|
53
|
+
{ uid: "mixed-log", name: "run.txt", size: 3 * 1024, status: "done" },
|
|
54
|
+
{ uid: "mixed-bundle", name: "evidence.zip", size: 2 * 1024 * 1024, status: "done" },
|
|
55
|
+
{ uid: "mixed-spec", name: "spec.pdf", size: 640 * 1024, status: "done" },
|
|
56
|
+
{ uid: "mixed-dump", name: "device-dump", size: 96 * 1024, status: "done" },
|
|
57
|
+
];
|
|
39
58
|
const failedItems: UploadFileItem[] = [
|
|
40
59
|
{
|
|
41
60
|
uid: "failed-invoice",
|
|
@@ -105,6 +124,25 @@ export default function Demo() {
|
|
|
105
124
|
</CardContent>
|
|
106
125
|
</Card>
|
|
107
126
|
|
|
127
|
+
<Card>
|
|
128
|
+
<CardHeader>
|
|
129
|
+
<CardTitle level={2}>List type · 添付ファイル一覧</CardTitle>
|
|
130
|
+
<CardDescription>
|
|
131
|
+
listType は variant と独立した軸です。dropzone のまま listType="picture"
|
|
132
|
+
にすると、画像はサムネイル、それ以外はファイル種別のアイコンで並びます。
|
|
133
|
+
</CardDescription>
|
|
134
|
+
</CardHeader>
|
|
135
|
+
<CardContent>
|
|
136
|
+
<Upload
|
|
137
|
+
variant="dropzone"
|
|
138
|
+
listType="picture"
|
|
139
|
+
value={mixedItems}
|
|
140
|
+
onValueChange={() => {}}
|
|
141
|
+
onDownload={() => {}}
|
|
142
|
+
/>
|
|
143
|
+
</CardContent>
|
|
144
|
+
</Card>
|
|
145
|
+
|
|
108
146
|
<Card>
|
|
109
147
|
<CardHeader>
|
|
110
148
|
<CardTitle level={2}>Error and recovery</CardTitle>
|