@godxjp/ui 23.1.0 → 23.2.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/card.d.ts +45 -2
- package/dist/components/data-display/card.js +4 -2
- package/dist/components/data-display/feature-list.d.ts +26 -0
- package/dist/components/data-display/feature-list.js +29 -0
- package/dist/components/data-display/index.d.ts +6 -0
- package/dist/components/data-display/index.js +6 -0
- package/dist/components/data-display/swatch.d.ts +24 -0
- package/dist/components/data-display/swatch.js +19 -0
- package/dist/components/data-display/thumbnail.d.ts +37 -0
- package/dist/components/data-display/thumbnail.js +20 -0
- package/dist/components/feedback/index.d.ts +2 -2
- package/dist/components/feedback/index.js +19 -1
- package/dist/components/feedback/skeleton.d.ts +33 -3
- package/dist/components/feedback/skeleton.js +154 -3
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +17 -5
- package/dist/components/layout/sidebar.js +9 -2
- package/dist/components/navigation/tabs-scroll.d.ts +27 -0
- package/dist/components/navigation/tabs-scroll.js +36 -1
- package/dist/components/navigation/tabs.d.ts +2 -2
- package/dist/components/navigation/tabs.js +44 -12
- package/dist/i18n/messages/en.json +5 -0
- package/dist/i18n/messages/ja.json +5 -0
- package/dist/i18n/messages/vi.json +5 -0
- package/dist/props/components/data-display.prop.d.ts +93 -0
- package/dist/props/components/feedback.prop.d.ts +85 -1
- package/dist/props/components/layout.prop.d.ts +72 -1
- package/dist/props/components/navigation.prop.d.ts +72 -1
- package/dist/props/registry.d.ts +118 -0
- package/dist/props/registry.js +134 -0
- package/dist/styles/alert-layout.css +139 -0
- package/dist/styles/card-layout.css +48 -0
- package/dist/styles/data-display-layout.css +88 -0
- package/dist/styles/navigation-layout.css +76 -3
- package/dist/styles/shell-layout.css +18 -0
- package/dist/tokens/components/card.css +2 -0
- package/dist/tokens/components/data-display.css +23 -0
- package/dist/tokens/components/feedback.css +18 -0
- package/dist/tokens/components/navigation.css +2 -0
- package/dist/tokens/foundation.css +18 -16
- package/docs/CONSUMER-RULES.md +1 -1
- package/docs/DESIGN-AUTHORITY.md +2 -1
- package/docs/FRAME-COVERAGE-REPORT.md +29 -3
- package/docs/assets/shot-landscape.svg +12 -0
- package/docs/assets/shot-portrait.svg +10 -0
- package/docs/data-display/card/index.tsx +40 -0
- package/docs/data-display/feature-list.tsx +159 -0
- package/docs/data-display/swatch.tsx +107 -0
- package/docs/data-display/thumbnail.tsx +128 -0
- package/docs/feedback/skeleton.tsx +57 -0
- package/docs/layout/flex.tsx +29 -0
- package/docs/layout/sidebar.tsx +66 -10
- package/docs/navigation/tabs.tsx +59 -0
- package/package.json +4 -7
- package/scripts/consumer-rule.md +16 -0
- package/scripts/ui-audit.mjs +3 -4
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Card,
|
|
3
|
+
CardContent,
|
|
4
|
+
CardDescription,
|
|
5
|
+
CardFooter,
|
|
6
|
+
CardHeader,
|
|
7
|
+
CardTitle,
|
|
8
|
+
FeatureList,
|
|
9
|
+
} from "@godxjp/ui/data-display";
|
|
10
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
11
|
+
import { Flex, PageContainer, ResponsiveGrid } from "@godxjp/ui/layout";
|
|
12
|
+
|
|
13
|
+
const STARTER = [
|
|
14
|
+
{ state: "included", label: "ユーザー 10 名まで" },
|
|
15
|
+
{ state: "included", label: "監査ログ", description: "直近 30 日分を保持します。" },
|
|
16
|
+
{
|
|
17
|
+
state: "limited",
|
|
18
|
+
label: "API 呼び出し",
|
|
19
|
+
description: "月 10,000 回を超えると 429 を返します。",
|
|
20
|
+
},
|
|
21
|
+
{ state: "excluded", label: "SAML / OIDC シングルサインオン" },
|
|
22
|
+
{ state: "excluded", label: "監査ログのエクスポート" },
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
const ENTERPRISE = [
|
|
26
|
+
{ state: "included", label: "ユーザー数 無制限" },
|
|
27
|
+
{ state: "included", label: "監査ログ", description: "保持期間は契約単位で設定します。" },
|
|
28
|
+
{ state: "included", label: "API 呼び出し", description: "レート上限は個別に調整します。" },
|
|
29
|
+
{
|
|
30
|
+
state: "included",
|
|
31
|
+
label: "SAML / OIDC シングルサインオン",
|
|
32
|
+
description: "SAML 2.0 と OIDC の両方に対応。",
|
|
33
|
+
},
|
|
34
|
+
{ state: "included", label: "監査ログのエクスポート" },
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* FeatureList — 先頭の状態グリフ(含む/含まない/制限あり)を持つ「文」のリスト。
|
|
39
|
+
*
|
|
40
|
+
* ListRow は 1 行のエンティティ行(区切り線・末尾アクション)、Timeline は順序のあるイベント
|
|
41
|
+
* レール、Descriptions は用語/値のグリッド。どれも「折り返す説明文つきの状態リスト」ではない。
|
|
42
|
+
* Composed only from real @godxjp/ui components.
|
|
43
|
+
*/
|
|
44
|
+
export default function Demo() {
|
|
45
|
+
return (
|
|
46
|
+
<PageContainer
|
|
47
|
+
title="FeatureList"
|
|
48
|
+
subtitle="状態グリフつきの文のリスト · グリフは最初の行に揃う"
|
|
49
|
+
>
|
|
50
|
+
<Flex direction="col" gap="lg">
|
|
51
|
+
<Card>
|
|
52
|
+
<CardHeader>
|
|
53
|
+
<CardTitle level={2}>三つの状態</CardTitle>
|
|
54
|
+
<CardDescription>
|
|
55
|
+
included(✓)· limited(−)· excluded(✗)。色は意味を運ぶ唯一の手段ではありません ——
|
|
56
|
+
形が違い、読み上げ用の語も添えられます(WCAG 1.4.1)。excluded を赤で塗らないのは、
|
|
57
|
+
「含まれない」は失敗ではなく事実だからです。
|
|
58
|
+
</CardDescription>
|
|
59
|
+
</CardHeader>
|
|
60
|
+
<CardContent>
|
|
61
|
+
<FeatureList items={[...STARTER]} />
|
|
62
|
+
</CardContent>
|
|
63
|
+
</Card>
|
|
64
|
+
|
|
65
|
+
<Card>
|
|
66
|
+
<CardHeader>
|
|
67
|
+
<CardTitle level={2}>折り返しても、グリフは最初の行に揃う</CardTitle>
|
|
68
|
+
<CardDescription>
|
|
69
|
+
グリフの枠は 1 行分(1lh)の高さで、その中央にグリフが置かれます。だから 3 行に
|
|
70
|
+
折り返すラベルでも、揃う先は箱の上端ではなく最初の行です。呼び出し側に数値は
|
|
71
|
+
ありません。
|
|
72
|
+
</CardDescription>
|
|
73
|
+
</CardHeader>
|
|
74
|
+
<CardContent>
|
|
75
|
+
<FeatureList
|
|
76
|
+
items={[
|
|
77
|
+
{
|
|
78
|
+
state: "included",
|
|
79
|
+
label:
|
|
80
|
+
"組織をまたぐ権限の委譲(部門管理者が自部門の範囲内でだけロールを付け替えられる設定を含みます)",
|
|
81
|
+
description:
|
|
82
|
+
"委譲の範囲は組織ツリーのノード単位で決まり、親を超える付与はできません。監査ログには委譲元と委譲先の両方が記録されます。",
|
|
83
|
+
},
|
|
84
|
+
{ state: "limited", label: "短いラベル" },
|
|
85
|
+
]}
|
|
86
|
+
/>
|
|
87
|
+
</CardContent>
|
|
88
|
+
</Card>
|
|
89
|
+
|
|
90
|
+
<ResponsiveGrid columns={{ base: 1, md: 2 }}>
|
|
91
|
+
<Card>
|
|
92
|
+
<CardHeader>
|
|
93
|
+
<CardTitle level={2}>Starter</CardTitle>
|
|
94
|
+
<CardDescription>小さなチームのための最小構成。</CardDescription>
|
|
95
|
+
</CardHeader>
|
|
96
|
+
<CardContent>
|
|
97
|
+
<FeatureList items={[...STARTER]} />
|
|
98
|
+
</CardContent>
|
|
99
|
+
<CardFooter>
|
|
100
|
+
<Button variant="outline">Starter を選ぶ</Button>
|
|
101
|
+
</CardFooter>
|
|
102
|
+
</Card>
|
|
103
|
+
|
|
104
|
+
<Card>
|
|
105
|
+
<CardHeader>
|
|
106
|
+
<CardTitle level={2}>Enterprise</CardTitle>
|
|
107
|
+
<CardDescription>監査と SSO を必要とする組織向け。</CardDescription>
|
|
108
|
+
</CardHeader>
|
|
109
|
+
<CardContent>
|
|
110
|
+
<FeatureList items={[...ENTERPRISE]} />
|
|
111
|
+
</CardContent>
|
|
112
|
+
<CardFooter>
|
|
113
|
+
<Button>Enterprise を選ぶ</Button>
|
|
114
|
+
</CardFooter>
|
|
115
|
+
</Card>
|
|
116
|
+
</ResponsiveGrid>
|
|
117
|
+
|
|
118
|
+
<Card>
|
|
119
|
+
<CardHeader>
|
|
120
|
+
<CardTitle level={2}>数量はラベルに組み立てる</CardTitle>
|
|
121
|
+
<CardDescription>
|
|
122
|
+
「· 10,000 req/mo」のような数量に専用の prop はありません。Text を label に入れる
|
|
123
|
+
書き方がすでに合法で audit も通るため、prop を足すと docs/WHAT-BELONGS-HERE.md の問い
|
|
124
|
+
1(consumer に手がないか)に落ちます。
|
|
125
|
+
</CardDescription>
|
|
126
|
+
</CardHeader>
|
|
127
|
+
<CardContent>
|
|
128
|
+
<FeatureList
|
|
129
|
+
items={[
|
|
130
|
+
{
|
|
131
|
+
state: "limited",
|
|
132
|
+
label: (
|
|
133
|
+
<>
|
|
134
|
+
API 呼び出し{" "}
|
|
135
|
+
<Text tone="muted" tabular>
|
|
136
|
+
10,000 req/mo
|
|
137
|
+
</Text>
|
|
138
|
+
</>
|
|
139
|
+
),
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
state: "included",
|
|
143
|
+
label: (
|
|
144
|
+
<>
|
|
145
|
+
ストレージ{" "}
|
|
146
|
+
<Text tone="muted" tabular>
|
|
147
|
+
250 GB
|
|
148
|
+
</Text>
|
|
149
|
+
</>
|
|
150
|
+
),
|
|
151
|
+
},
|
|
152
|
+
]}
|
|
153
|
+
/>
|
|
154
|
+
</CardContent>
|
|
155
|
+
</Card>
|
|
156
|
+
</Flex>
|
|
157
|
+
</PageContainer>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Card,
|
|
3
|
+
CardContent,
|
|
4
|
+
CardDescription,
|
|
5
|
+
CardHeader,
|
|
6
|
+
CardTitle,
|
|
7
|
+
ListRow,
|
|
8
|
+
Swatch,
|
|
9
|
+
} from "@godxjp/ui/data-display";
|
|
10
|
+
import { Text } from "@godxjp/ui/general";
|
|
11
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
12
|
+
|
|
13
|
+
const BRAND = {
|
|
14
|
+
name: "株式会社山田製作所",
|
|
15
|
+
primary: "#0071bd",
|
|
16
|
+
secondary: "#c0392f",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const CATEGORIES = [
|
|
20
|
+
{ name: "定例会議", color: "#7c3aed" },
|
|
21
|
+
{ name: "出張", color: "#0f9d58" },
|
|
22
|
+
{ name: "締切", color: "#c0392f" },
|
|
23
|
+
{ name: "予備", color: "#ffffff" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Swatch — a read-only sample of ONE colour a person chose.
|
|
28
|
+
* Composed only from real @godxjp/ui components.
|
|
29
|
+
*/
|
|
30
|
+
export default function Demo() {
|
|
31
|
+
return (
|
|
32
|
+
<PageContainer title="Swatch" subtitle="利用者が選んだ色を、そのまま見せる読み取り専用の見本">
|
|
33
|
+
<Flex direction="col" gap="lg">
|
|
34
|
+
<Card>
|
|
35
|
+
<CardHeader>
|
|
36
|
+
<CardTitle level={2}>ブランドカラー</CardTitle>
|
|
37
|
+
<CardDescription>
|
|
38
|
+
組織が登録した色は tone ではなく値です。見本に名前を渡すと、見える文字を増やさずに
|
|
39
|
+
読み上げられます。
|
|
40
|
+
</CardDescription>
|
|
41
|
+
</CardHeader>
|
|
42
|
+
<CardContent>
|
|
43
|
+
<Flex direction="col" gap="sm">
|
|
44
|
+
<Flex align="center" gap="sm">
|
|
45
|
+
<Swatch color={BRAND.primary} aria-label={`プライマリカラー: ${BRAND.primary}`} />
|
|
46
|
+
<Text weight="medium">{BRAND.name}</Text>
|
|
47
|
+
<Text tone="muted" mono size="xs">
|
|
48
|
+
{BRAND.primary}
|
|
49
|
+
</Text>
|
|
50
|
+
</Flex>
|
|
51
|
+
<Flex align="center" gap="sm">
|
|
52
|
+
<Swatch
|
|
53
|
+
color={BRAND.secondary}
|
|
54
|
+
aria-label={`セカンダリカラー: ${BRAND.secondary}`}
|
|
55
|
+
/>
|
|
56
|
+
<Text weight="medium">{BRAND.name}</Text>
|
|
57
|
+
<Text tone="muted" mono size="xs">
|
|
58
|
+
{BRAND.secondary}
|
|
59
|
+
</Text>
|
|
60
|
+
</Flex>
|
|
61
|
+
</Flex>
|
|
62
|
+
</CardContent>
|
|
63
|
+
</Card>
|
|
64
|
+
|
|
65
|
+
<Card>
|
|
66
|
+
<CardHeader>
|
|
67
|
+
<CardTitle level={2}>一覧の先頭マークとして</CardTitle>
|
|
68
|
+
<CardDescription>
|
|
69
|
+
行のラベルが色の意味を言っているので、見本は aria-hidden
|
|
70
|
+
のままにします。同じことを二度読み上げないためです。最後の「予備」は白で、
|
|
71
|
+
白いカードの上でも見本の輪郭が残ることを示します。
|
|
72
|
+
</CardDescription>
|
|
73
|
+
</CardHeader>
|
|
74
|
+
<CardContent>
|
|
75
|
+
<Flex direction="col" gap="none">
|
|
76
|
+
{CATEGORIES.map((category) => (
|
|
77
|
+
<ListRow
|
|
78
|
+
key={category.name}
|
|
79
|
+
leading={<Swatch color={category.color} />}
|
|
80
|
+
title={category.name}
|
|
81
|
+
description={category.color}
|
|
82
|
+
/>
|
|
83
|
+
))}
|
|
84
|
+
</Flex>
|
|
85
|
+
</CardContent>
|
|
86
|
+
</Card>
|
|
87
|
+
|
|
88
|
+
<Card>
|
|
89
|
+
<CardHeader>
|
|
90
|
+
<CardTitle level={2}>色の形式は問いません</CardTitle>
|
|
91
|
+
<CardDescription>
|
|
92
|
+
hex でも rgb() でも oklch() でも、CSS の色として有効ならそのまま塗ります。
|
|
93
|
+
値はスタイルシートには入らず、要素の上にだけ乗ります。
|
|
94
|
+
</CardDescription>
|
|
95
|
+
</CardHeader>
|
|
96
|
+
<CardContent>
|
|
97
|
+
<Flex align="center" gap="md" wrap>
|
|
98
|
+
<Swatch color="#7c3aed" aria-label="hex: #7c3aed" />
|
|
99
|
+
<Swatch color="rgb(15 157 88)" aria-label="rgb: rgb(15 157 88)" />
|
|
100
|
+
<Swatch color="oklch(0.72 0.15 45)" aria-label="oklch: oklch(0.72 0.15 45)" />
|
|
101
|
+
</Flex>
|
|
102
|
+
</CardContent>
|
|
103
|
+
</Card>
|
|
104
|
+
</Flex>
|
|
105
|
+
</PageContainer>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Card,
|
|
3
|
+
CardContent,
|
|
4
|
+
CardDescription,
|
|
5
|
+
CardHeader,
|
|
6
|
+
CardTitle,
|
|
7
|
+
Thumbnail,
|
|
8
|
+
} from "@godxjp/ui/data-display";
|
|
9
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
10
|
+
|
|
11
|
+
import coverTerrain from "../assets/cover-terrain.svg";
|
|
12
|
+
import portraitIris from "../assets/portrait-iris.svg";
|
|
13
|
+
import shotLandscape from "../assets/shot-landscape.svg";
|
|
14
|
+
import shotPortrait from "../assets/shot-portrait.svg";
|
|
15
|
+
|
|
16
|
+
/* Committed SVG files under docs/assets, imported so the bundler rewrites each URL against
|
|
17
|
+
* PREVIEW_BASE. A docs page must never fetch a third-party image: on CI the request never
|
|
18
|
+
* settles, `networkidle` never fires, and the page load times out. */
|
|
19
|
+
|
|
20
|
+
/** Four DIFFERENT intrinsic ratios — the case AspectRatio cannot express with one number. */
|
|
21
|
+
const SHOTS = [
|
|
22
|
+
{ src: shotPortrait, width: 360, height: 640, alt: "モバイル版の一覧画面" },
|
|
23
|
+
{ src: shotLandscape, width: 960, height: 540, alt: "デスクトップ版のダッシュボード" },
|
|
24
|
+
{ src: coverTerrain, width: 480, height: 270, alt: "ストア掲載用のカバー画像" },
|
|
25
|
+
{ src: portraitIris, width: 96, height: 96, alt: "アプリアイコン" },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Thumbnail — 高さは固定、幅は画像そのものの比率。囲みは画像に直接かかる hairline。
|
|
30
|
+
*
|
|
31
|
+
* AspectRatio は比率を固定して幅 100% に広げるので、比率の違う数枚を並べるとレターボックスか
|
|
32
|
+
* 切り抜きになる。Avatar は人・組織の識別マーク、Card は囲みと画像のあいだに padding を入れる、
|
|
33
|
+
* CardCover は Card の中のスロット。Composed only from real @godxjp/ui components.
|
|
34
|
+
*/
|
|
35
|
+
export default function Demo() {
|
|
36
|
+
return (
|
|
37
|
+
<PageContainer title="Thumbnail" subtitle="高さ固定・幅は実寸比 · 画像に直接かかる hairline">
|
|
38
|
+
<Flex direction="col" gap="lg">
|
|
39
|
+
<Card>
|
|
40
|
+
<CardHeader>
|
|
41
|
+
<CardTitle level={2}>比率の違う画像を 1 行に並べる</CardTitle>
|
|
42
|
+
<CardDescription>
|
|
43
|
+
縦長・横長・ワイド・正方形が同じ行に並んでも、高さはそろい、幅はそれぞれの比率の
|
|
44
|
+
まま。切り抜きもレターボックスも起きません。狭い画面では折り返します。
|
|
45
|
+
</CardDescription>
|
|
46
|
+
</CardHeader>
|
|
47
|
+
<CardContent>
|
|
48
|
+
<Flex gap="sm" wrap align="start">
|
|
49
|
+
{SHOTS.map((shot) => (
|
|
50
|
+
<Thumbnail key={shot.alt} size="lg" {...shot} />
|
|
51
|
+
))}
|
|
52
|
+
</Flex>
|
|
53
|
+
</CardContent>
|
|
54
|
+
</Card>
|
|
55
|
+
|
|
56
|
+
<Card>
|
|
57
|
+
<CardHeader>
|
|
58
|
+
<CardTitle level={2}>size · sm · md(既定)· lg</CardTitle>
|
|
59
|
+
<CardDescription>
|
|
60
|
+
sm 64px は添付ファイルの行に、md 96px はギャラリー行に、lg 160px は画像そのものが
|
|
61
|
+
本文である審査画面に。px 指定はありません。
|
|
62
|
+
</CardDescription>
|
|
63
|
+
</CardHeader>
|
|
64
|
+
<CardContent>
|
|
65
|
+
<Flex direction="col" gap="md">
|
|
66
|
+
<Flex gap="sm" wrap align="start">
|
|
67
|
+
<Thumbnail size="sm" {...SHOTS[0]} />
|
|
68
|
+
<Thumbnail size="sm" {...SHOTS[1]} />
|
|
69
|
+
</Flex>
|
|
70
|
+
<Flex gap="sm" wrap align="start">
|
|
71
|
+
<Thumbnail {...SHOTS[0]} />
|
|
72
|
+
<Thumbnail {...SHOTS[1]} />
|
|
73
|
+
</Flex>
|
|
74
|
+
<Flex gap="sm" wrap align="start">
|
|
75
|
+
<Thumbnail size="lg" {...SHOTS[0]} />
|
|
76
|
+
<Thumbnail size="lg" {...SHOTS[1]} />
|
|
77
|
+
</Flex>
|
|
78
|
+
</Flex>
|
|
79
|
+
</CardContent>
|
|
80
|
+
</Card>
|
|
81
|
+
|
|
82
|
+
<Card>
|
|
83
|
+
<CardHeader>
|
|
84
|
+
<CardTitle level={2}>読み込み前に幅を確保する</CardTitle>
|
|
85
|
+
<CardDescription>
|
|
86
|
+
幅が実寸比のままということは、画像が届くまで幅が決まらないということでもあります。
|
|
87
|
+
元ファイルの width / height をそのまま渡すと、ブラウザが比率を先に知るので、
|
|
88
|
+
高さが固定されている分だけ最初の描画から最終的な幅になります。
|
|
89
|
+
</CardDescription>
|
|
90
|
+
</CardHeader>
|
|
91
|
+
<CardContent>
|
|
92
|
+
<Flex gap="sm" wrap align="start">
|
|
93
|
+
<Thumbnail
|
|
94
|
+
src={shotPortrait}
|
|
95
|
+
width={360}
|
|
96
|
+
height={640}
|
|
97
|
+
alt="幅を先に確保した縦長の画面"
|
|
98
|
+
/>
|
|
99
|
+
<Thumbnail
|
|
100
|
+
src={shotLandscape}
|
|
101
|
+
width={960}
|
|
102
|
+
height={540}
|
|
103
|
+
alt="幅を先に確保した横長の画面"
|
|
104
|
+
loading="lazy"
|
|
105
|
+
/>
|
|
106
|
+
</Flex>
|
|
107
|
+
</CardContent>
|
|
108
|
+
</Card>
|
|
109
|
+
|
|
110
|
+
<Card>
|
|
111
|
+
<CardHeader>
|
|
112
|
+
<CardTitle level={2}>alt は省略できない</CardTitle>
|
|
113
|
+
<CardDescription>
|
|
114
|
+
型の上で必須です。ページが既に述べていることしか写っていない画像には alt=""
|
|
115
|
+
を渡します —— 空文字は著者が下す「決定」で、属性そのものを書き忘れるのとは違います
|
|
116
|
+
(WCAG 1.1.1)。
|
|
117
|
+
</CardDescription>
|
|
118
|
+
</CardHeader>
|
|
119
|
+
<CardContent>
|
|
120
|
+
<Flex gap="sm" wrap align="start">
|
|
121
|
+
<Thumbnail src={coverTerrain} width={480} height={270} alt="" />
|
|
122
|
+
</Flex>
|
|
123
|
+
</CardContent>
|
|
124
|
+
</Card>
|
|
125
|
+
</Flex>
|
|
126
|
+
</PageContainer>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Skeleton,
|
|
3
|
+
SkeletonArticle,
|
|
4
|
+
SkeletonAvatar,
|
|
5
|
+
SkeletonButton,
|
|
3
6
|
SkeletonDetail,
|
|
7
|
+
SkeletonImage,
|
|
8
|
+
SkeletonInput,
|
|
9
|
+
SkeletonNode,
|
|
4
10
|
SkeletonRows,
|
|
5
11
|
SkeletonStat,
|
|
6
12
|
SkeletonTable,
|
|
@@ -14,6 +20,8 @@ import { Flex, PageContainer, ResponsiveGrid } from "@godxjp/ui/layout";
|
|
|
14
20
|
* SkeletonTable · pre-mount DataTable placeholder (rows, columns props).
|
|
15
21
|
* SkeletonStat · StatCard/KPI tile placeholder (no props; use in ResponsiveGrid).
|
|
16
22
|
* SkeletonDetail · single-record detail placeholder (title + metadata rows, no props).
|
|
23
|
+
* SkeletonArticle · avatar + heading + paragraph (Ant Design's own Skeleton shape).
|
|
24
|
+
* SkeletonAvatar/Button/Input/Node/Image · the shaped presets, also on the Skeleton namespace.
|
|
17
25
|
* Never use a spinner overlay on skeletonable content.
|
|
18
26
|
*/
|
|
19
27
|
export default function Demo() {
|
|
@@ -48,6 +56,55 @@ export default function Demo() {
|
|
|
48
56
|
</CardContent>
|
|
49
57
|
</Card>
|
|
50
58
|
|
|
59
|
+
<Card>
|
|
60
|
+
<CardHeader>
|
|
61
|
+
<CardTitle level={2}>SkeletonArticle · avatar + heading + paragraph</CardTitle>
|
|
62
|
+
<CardDescription>
|
|
63
|
+
Ant Design's own Skeleton shape. Defaults follow it exactly: no avatar, a 38% heading
|
|
64
|
+
and three body lines; with an avatar the heading drops to 50% and the body to two
|
|
65
|
+
lines. `active` swaps the resting pulse for the travelling sheen · `round` pills every
|
|
66
|
+
line · `loading={false}` renders children instead.
|
|
67
|
+
</CardDescription>
|
|
68
|
+
</CardHeader>
|
|
69
|
+
<CardContent>
|
|
70
|
+
<Flex direction="col" gap="lg">
|
|
71
|
+
<SkeletonArticle />
|
|
72
|
+
<SkeletonArticle avatar />
|
|
73
|
+
<SkeletonArticle avatar active round paragraph={{ rows: 4, width: ["90%", "80%"] }} />
|
|
74
|
+
<SkeletonArticle avatar paragraph={false} title={{ width: "14rem" }} />
|
|
75
|
+
</Flex>
|
|
76
|
+
</CardContent>
|
|
77
|
+
</Card>
|
|
78
|
+
|
|
79
|
+
<Card>
|
|
80
|
+
<CardHeader>
|
|
81
|
+
<CardTitle level={2}>Shaped presets · the boxes the controls occupy</CardTitle>
|
|
82
|
+
<CardDescription>
|
|
83
|
+
Each preset carries the box of the control it stands in for, from the --control-height
|
|
84
|
+
tier · SkeletonButton is two heights wide, SkeletonInput five. Reachable as named
|
|
85
|
+
exports or through the Skeleton namespace (Skeleton.Button…).
|
|
86
|
+
</CardDescription>
|
|
87
|
+
</CardHeader>
|
|
88
|
+
<CardContent>
|
|
89
|
+
<Flex direction="col" gap="md">
|
|
90
|
+
<Flex direction="row" gap="sm" align="center" wrap>
|
|
91
|
+
<SkeletonAvatar size="sm" />
|
|
92
|
+
<SkeletonAvatar />
|
|
93
|
+
<SkeletonAvatar size="lg" shape="square" />
|
|
94
|
+
<SkeletonButton size="sm" />
|
|
95
|
+
<SkeletonButton />
|
|
96
|
+
<SkeletonButton size="lg" shape="pill" active />
|
|
97
|
+
<SkeletonInput size="sm" />
|
|
98
|
+
</Flex>
|
|
99
|
+
<SkeletonInput block />
|
|
100
|
+
<Flex direction="row" gap="sm" align="center" wrap>
|
|
101
|
+
<SkeletonNode />
|
|
102
|
+
<SkeletonImage active />
|
|
103
|
+
</Flex>
|
|
104
|
+
</Flex>
|
|
105
|
+
</CardContent>
|
|
106
|
+
</Card>
|
|
107
|
+
|
|
51
108
|
<Card>
|
|
52
109
|
<CardHeader>
|
|
53
110
|
<CardTitle>SkeletonRows · generic repeated rows</CardTitle>
|
package/docs/layout/flex.tsx
CHANGED
|
@@ -280,6 +280,35 @@ export default function Demo() {
|
|
|
280
280
|
</Flex>
|
|
281
281
|
</CardContent>
|
|
282
282
|
</Card>
|
|
283
|
+
<Card>
|
|
284
|
+
<CardHeader>
|
|
285
|
+
<CardTitle level={2}>刻みにない幅で折りたたむ</CardTitle>
|
|
286
|
+
<CardDescription>
|
|
287
|
+
hideBelow の 4 段(40/48/64/80rem)に無い幅は hideBelowRaw / hideFromRaw
|
|
288
|
+
で指定します。900px ちょうどでは「広い側」だけが残り、両方消える隙間はありません。
|
|
289
|
+
</CardDescription>
|
|
290
|
+
</CardHeader>
|
|
291
|
+
<CardContent>
|
|
292
|
+
<Flex align="center" gap="sm">
|
|
293
|
+
<Flex id="raw-wide-nav" hideBelowRaw={900} align="center" gap="sm">
|
|
294
|
+
<Button variant="ghost" size="sm">
|
|
295
|
+
機能
|
|
296
|
+
</Button>
|
|
297
|
+
<Button variant="ghost" size="sm">
|
|
298
|
+
料金
|
|
299
|
+
</Button>
|
|
300
|
+
<Button variant="ghost" size="sm">
|
|
301
|
+
導入事例
|
|
302
|
+
</Button>
|
|
303
|
+
</Flex>
|
|
304
|
+
<Flex id="raw-narrow-nav" hideFromRaw={900} align="center" gap="sm">
|
|
305
|
+
<Button variant="outline" size="sm">
|
|
306
|
+
メニュー
|
|
307
|
+
</Button>
|
|
308
|
+
</Flex>
|
|
309
|
+
</Flex>
|
|
310
|
+
</CardContent>
|
|
311
|
+
</Card>
|
|
283
312
|
<Card>
|
|
284
313
|
<CardHeader>
|
|
285
314
|
<CardTitle level={2}>軽い強調と行アクション</CardTitle>
|
package/docs/layout/sidebar.tsx
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
PanelLeftClose,
|
|
40
40
|
PanelLeftOpen,
|
|
41
41
|
Search,
|
|
42
|
+
ChevronsUpDown,
|
|
42
43
|
} from "lucide-react";
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -229,18 +230,31 @@ export default function Demo() {
|
|
|
229
230
|
color: "hsl(var(--primary))",
|
|
230
231
|
}}
|
|
231
232
|
onProductClick={() => undefined}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
233
|
+
/*
|
|
234
|
+
* footer · brand と同じ「関数を渡すと EFFECTIVE な collapsed が来る」形。自前の collapsed
|
|
235
|
+
* を読むと、AppShell が同じ Sidebar をドロワーにも渡す(ドロワーは展開表示に戻す)ため
|
|
236
|
+
* 全幅のドロワーの中でアイコンだけの足元になります。
|
|
237
|
+
*/
|
|
238
|
+
footer={(railCollapsed) =>
|
|
239
|
+
railCollapsed ? (
|
|
240
|
+
<Flex justify="center">
|
|
241
|
+
<Avatar className="size-7 shrink-0">
|
|
242
|
+
<AvatarFallback>山</AvatarFallback>
|
|
243
|
+
</Avatar>
|
|
244
|
+
</Flex>
|
|
245
|
+
) : (
|
|
246
|
+
<Flex direction="col" gap="xs">
|
|
247
|
+
<Text as="div" weight="medium">
|
|
248
|
+
山田 太郎
|
|
241
249
|
</Text>
|
|
250
|
+
<Flex align="center" gap="xs">
|
|
251
|
+
<span className="bg-success size-1.5 rounded-full" />
|
|
252
|
+
<Text size="xs" tone="muted">
|
|
253
|
+
オンライン
|
|
254
|
+
</Text>
|
|
255
|
+
</Flex>
|
|
242
256
|
</Flex>
|
|
243
|
-
|
|
257
|
+
)
|
|
244
258
|
}
|
|
245
259
|
/>
|
|
246
260
|
);
|
|
@@ -574,6 +588,46 @@ export default function Demo() {
|
|
|
574
588
|
</CardContent>
|
|
575
589
|
</Card>
|
|
576
590
|
|
|
591
|
+
{/* trailingIcon · 行の末尾に置く 16px の「開くよ」グリフ。badge(件数ピル)とは別枠。 */}
|
|
592
|
+
<Card>
|
|
593
|
+
<CardHeader>
|
|
594
|
+
<CardTitle level={2}>trailingIcon プロップ(末尾のグリフ)</CardTitle>
|
|
595
|
+
<CardDescription>
|
|
596
|
+
ワークスペース切替のような「押すと何か開く」行の末尾に置く 16px
|
|
597
|
+
のグリフです。件数ピルの badge とは別の枠で、背景も角丸も描きません · badge に ⌃⌄
|
|
598
|
+
を入れると .sb-badge の灰色ピル(実測 36×24、中の SVG は 24×24)に
|
|
599
|
+
なってしまうため、サイズを DS 側で固定した専用の枠にしています。 icon
|
|
600
|
+
と同じくコンポーネントを渡す形なので、SVG の寸法は 16px に固定されます。
|
|
601
|
+
折りたたみレールでは badge と同じように隠れます。
|
|
602
|
+
</CardDescription>
|
|
603
|
+
</CardHeader>
|
|
604
|
+
<CardContent>
|
|
605
|
+
<Card className="h-64 w-64 overflow-hidden">
|
|
606
|
+
<CardContent flush>
|
|
607
|
+
<Flex direction="col">
|
|
608
|
+
<Sidebar
|
|
609
|
+
ariaLabel="切替行つきのナビゲーション"
|
|
610
|
+
activeId={brandActiveId}
|
|
611
|
+
onSelect={setBrandActiveId}
|
|
612
|
+
sections={BRAND_SECTIONS}
|
|
613
|
+
aria-label="trailingIcon 例のナビゲーション"
|
|
614
|
+
footer={
|
|
615
|
+
<SidebarItem
|
|
616
|
+
item={{
|
|
617
|
+
id: "workspace",
|
|
618
|
+
label: "アクメ株式会社",
|
|
619
|
+
icon: Building2,
|
|
620
|
+
trailingIcon: ChevronsUpDown,
|
|
621
|
+
}}
|
|
622
|
+
/>
|
|
623
|
+
}
|
|
624
|
+
/>
|
|
625
|
+
</Flex>
|
|
626
|
+
</CardContent>
|
|
627
|
+
</Card>
|
|
628
|
+
</CardContent>
|
|
629
|
+
</Card>
|
|
630
|
+
|
|
577
631
|
{/* Feature notes */}
|
|
578
632
|
<Card>
|
|
579
633
|
<CardHeader>
|
|
@@ -590,6 +644,8 @@ export default function Demo() {
|
|
|
590
644
|
"badgeTone で未読(neutral)と自分宛て(destructive)を色だけで区別",
|
|
591
645
|
"disabled=true で項目を非活性化(クリック不可)",
|
|
592
646
|
"footer prop でスクロール外にユーザー情報を固定",
|
|
647
|
+
"footer は brand と同じく関数も受け取る · 実効の collapsed が渡る",
|
|
648
|
+
"trailingIcon で行の末尾に 16px のグリフ(切替の ⌃⌄ など)を置ける",
|
|
593
649
|
"linkComponent · ルーター Link は「要素だけ」渡す。行の中身はライブラリが組み立てる",
|
|
594
650
|
"linkComponent は葉・サブメニュー・折りたたみレール・フライアウトの全てに適用される",
|
|
595
651
|
"グループのトリガーは aria-expanded を持つ開閉ボタンのままなので linkComponent は適用されない",
|