@godxjp/ui 19.2.0 → 19.3.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.
- package/dist/components/data-display/badge.d.ts +18 -2
- package/dist/components/data-display/badge.js +18 -4
- package/dist/props/components/data-display.prop.d.ts +7 -0
- package/dist/props/registry.d.ts +5 -1
- package/dist/props/registry.js +12 -1
- package/dist/styles/badge-layout.css +15 -0
- package/dist/tokens/components/badge.css +8 -0
- package/docs/data-display/badge.tsx +36 -0
- package/docs/data-display/carousel.tsx +8 -4
- package/docs/data-display/data-table/examples/grid-features.tsx +1 -1
- package/docs/data-display/permission-matrix.tsx +13 -9
- package/docs/data-display/popover.tsx +2 -1
- package/docs/data-display/scroll-area.tsx +107 -75
- package/docs/data-display/table.tsx +1 -1
- package/docs/data-entry/calendar.tsx +1 -1
- package/docs/data-entry/checkbox.tsx +1 -1
- package/docs/data-entry/country-picker-recipe.tsx +11 -6
- package/docs/data-entry/form-field/index.tsx +33 -29
- package/docs/data-entry/form-root.tsx +1 -1
- package/docs/data-entry/password-input.tsx +1 -5
- package/docs/data-entry/select.tsx +7 -7
- package/docs/data-entry/textarea.tsx +2 -2
- package/docs/feedback/sheet.tsx +112 -102
- package/docs/feedback/skeleton.tsx +2 -2
- package/docs/foundation/colors.tsx +8 -6
- package/docs/foundation/email-tokens.tsx +82 -65
- package/docs/foundation/radius-shadow.tsx +13 -11
- package/docs/layout/app-shell.tsx +2 -2
- package/docs/layout/aspect-ratio.tsx +30 -14
- package/docs/layout/flex.tsx +6 -2
- package/docs/layout/page-container.tsx +9 -1
- package/docs/layout/responsive-grid.tsx +10 -2
- package/docs/layout/sidebar.tsx +169 -146
- package/docs/layout/split-pane.tsx +44 -27
- package/docs/layout/topbar.tsx +17 -15
- package/docs/navigation/app-setting-picker.tsx +5 -4
- package/docs/navigation/breadcrumb.tsx +12 -5
- package/docs/navigation/context-menu.tsx +10 -4
- package/docs/navigation/navigation-menu.tsx +89 -96
- package/docs/navigation/steps.tsx +12 -10
- package/docs/navigation/tabs.tsx +26 -20
- package/docs/navigation/toolbar.tsx +15 -15
- package/docs/providers/format-date.tsx +2 -2
- package/docs/showcase/acme-portal.tsx +41 -27
- package/docs/showcase/acme-website.tsx +60 -54
- package/docs/showcase/case1-warehouse-dashboard.tsx +46 -30
- package/docs/showcase/case2-employee-me.tsx +23 -20
- package/docs/showcase/case3-approval-workflow.tsx +34 -32
- package/docs/showcase/case4-login.tsx +119 -113
- package/docs/showcase/case5-shift-calendar.tsx +3 -3
- package/docs/showcase/case6-agency-handy.tsx +340 -299
- package/docs/showcase/futurelastic-web.tsx +23 -21
- package/docs/showcase/org-switcher.tsx +2 -2
- package/docs/showcase/permission-matrix.tsx +7 -4
- package/docs/showcase/table-conditional-format.tsx +8 -8
- package/docs/showcase/table-crud-list.tsx +3 -3
- package/docs/showcase/table-density.tsx +49 -42
- package/docs/showcase/table-expandable-rows.tsx +24 -15
- package/docs/showcase/table-filter-chips.tsx +2 -7
- package/docs/showcase/table-footer-totals.tsx +7 -4
- package/docs/showcase/table-grouped-subtotals.tsx +25 -22
- package/docs/showcase/table-master-detail.tsx +15 -10
- package/docs/showcase/table-pagination.tsx +34 -27
- package/docs/showcase/table-states.tsx +8 -5
- package/docs/showcase/table-sticky-columns.tsx +8 -5
- package/package.json +2 -3
|
@@ -9,7 +9,7 @@ export type BadgeVariant = "default" | "secondary" | "outline" | "dashed";
|
|
|
9
9
|
*/
|
|
10
10
|
export type BadgeTone = ToneProp | "primary";
|
|
11
11
|
declare const badgeVariants: (props?: ({
|
|
12
|
-
variant?: "dashed" | "default" | "outline" | "secondary" | null | undefined;
|
|
12
|
+
variant?: "dashed" | "default" | "outline" | "secondary" | "tinted" | null | undefined;
|
|
13
13
|
shape?: "default" | "pill" | "sharp" | null | undefined;
|
|
14
14
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
15
|
export interface BadgeProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, Omit<VariantProps<typeof badgeVariants>, "variant" | "shape"> {
|
|
@@ -17,13 +17,29 @@ export interface BadgeProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "
|
|
|
17
17
|
/** Corner shape — `default` (badge radius) · `pill` (fully rounded) · `sharp` (square). */
|
|
18
18
|
shape?: ShapeProp | null;
|
|
19
19
|
tone?: BadgeTone | null;
|
|
20
|
+
/**
|
|
21
|
+
* The entity's OWN colour — a status colour, an issue type, a tag — as a CSS
|
|
22
|
+
* colour. A third axis beside `variant` (structure) and `tone` (meaning):
|
|
23
|
+
* this one carries DATA, a colour a person picked in a settings screen.
|
|
24
|
+
*
|
|
25
|
+
* The chip is washed rather than filled, and the reason is a contrast floor
|
|
26
|
+
* rather than taste: no foreground clears WCAG AA against every colour a
|
|
27
|
+
* picker can produce (near-black and white measure equal at luminance 0.2029,
|
|
28
|
+
* both 4.15:1). Washing the colour `--badge-tint-fill` into
|
|
29
|
+
* `--badge-tint-surface` and keeping the surface's own label makes the ratio
|
|
30
|
+
* a function of the tokens instead — 8.52:1 at the defaults, worst case
|
|
31
|
+
* across the sRGB cube on both themes.
|
|
32
|
+
*
|
|
33
|
+
* Wins over `tone` and over `variant`'s fill when both are given.
|
|
34
|
+
*/
|
|
35
|
+
color?: string;
|
|
20
36
|
icon?: React.ComponentType<{
|
|
21
37
|
className?: string;
|
|
22
38
|
}> | null;
|
|
23
39
|
status?: string;
|
|
24
40
|
children?: React.ReactNode;
|
|
25
41
|
}
|
|
26
|
-
export declare function Badge({ className, variant, shape, tone, icon, status, children, ...props }: BadgeProps): React.JSX.Element;
|
|
42
|
+
export declare function Badge({ className, variant, shape, tone, color, icon, status, style, children, ...props }: BadgeProps): React.JSX.Element;
|
|
27
43
|
/**
|
|
28
44
|
* Status-aware badge with the shared domain-status-to-tone mapping. `Badge` remains the
|
|
29
45
|
* general-purpose primitive.
|
|
@@ -57,7 +57,13 @@ const badgeVariants = cva(
|
|
|
57
57
|
default: "border-transparent bg-primary text-primary-foreground",
|
|
58
58
|
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
|
59
59
|
outline: "text-foreground",
|
|
60
|
-
dashed: "border-dashed text-foreground"
|
|
60
|
+
dashed: "border-dashed text-foreground",
|
|
61
|
+
/* `color` mode. Deliberately empty and deliberately NOT in the public
|
|
62
|
+
* `BadgeVariant` union: every fill, border and text utility has to stay
|
|
63
|
+
* off the element so badge-layout.css's `[data-tinted]` rule is
|
|
64
|
+
* reachable (a utility beats a components-layer rule whatever the
|
|
65
|
+
* specificity — gh#260). Selected by the `color` prop, never by hand. */
|
|
66
|
+
tinted: ""
|
|
61
67
|
},
|
|
62
68
|
// Corner shape — default inherits the badge radius token; pill/sharp override via the tokens.
|
|
63
69
|
shape: {
|
|
@@ -84,8 +90,10 @@ function Badge({
|
|
|
84
90
|
variant,
|
|
85
91
|
shape,
|
|
86
92
|
tone,
|
|
93
|
+
color,
|
|
87
94
|
icon,
|
|
88
95
|
status,
|
|
96
|
+
style,
|
|
89
97
|
children,
|
|
90
98
|
...props
|
|
91
99
|
}) {
|
|
@@ -94,17 +102,23 @@ function Badge({
|
|
|
94
102
|
const resolvedTone = tone ?? statusDef?.tone ?? "default";
|
|
95
103
|
const ResolvedIcon = icon === void 0 ? statusDef?.icon : icon;
|
|
96
104
|
const resolvedChildren = children ?? (status ? status in STATUS_MAP ? t(`status.${status}`) : status : void 0);
|
|
105
|
+
const tinted = color != null && color !== "";
|
|
97
106
|
return /* @__PURE__ */ jsxs(
|
|
98
107
|
"div",
|
|
99
108
|
{
|
|
100
109
|
"data-slot": "badge",
|
|
101
|
-
"data-tone": resolvedTone,
|
|
110
|
+
"data-tone": tinted ? void 0 : resolvedTone,
|
|
111
|
+
"data-tinted": tinted ? "" : void 0,
|
|
102
112
|
"data-shape": shape ?? "default",
|
|
103
113
|
className: cn(
|
|
104
|
-
badgeVariants({
|
|
105
|
-
|
|
114
|
+
badgeVariants({
|
|
115
|
+
variant: tinted ? "tinted" : variant ?? "default",
|
|
116
|
+
shape: shape ?? "default"
|
|
117
|
+
}),
|
|
118
|
+
tinted ? void 0 : badgeToneClass[resolvedTone],
|
|
106
119
|
className
|
|
107
120
|
),
|
|
121
|
+
style: tinted ? { ...style, ["--badge-color"]: color } : style,
|
|
108
122
|
...props,
|
|
109
123
|
children: [
|
|
110
124
|
ResolvedIcon ? /* @__PURE__ */ jsx(ResolvedIcon, { "data-slot": "badge-icon", "aria-hidden": "true" }) : null,
|
|
@@ -140,6 +140,13 @@ export type BadgeProp = {
|
|
|
140
140
|
variant?: "default" | "secondary" | "outline";
|
|
141
141
|
/** Status tones plus a brand `primary` tone (soft brand pill); solid brand = `variant="default"`. */
|
|
142
142
|
tone?: ToneProp | "primary";
|
|
143
|
+
/**
|
|
144
|
+
* The entity's OWN colour (a status, an issue type, a tag) as a CSS colour —
|
|
145
|
+
* DATA, not a semantic tone. Washed into `--badge-tint-surface` rather than
|
|
146
|
+
* filled, because no foreground clears WCAG AA against every colour a picker
|
|
147
|
+
* can produce. Wins over `tone` and over `variant`'s fill.
|
|
148
|
+
*/
|
|
149
|
+
color?: string;
|
|
143
150
|
status?: string;
|
|
144
151
|
icon?: React.ComponentType<{
|
|
145
152
|
className?: string;
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -1160,7 +1160,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1160
1160
|
readonly BadgeProp: {
|
|
1161
1161
|
readonly group: "data-display";
|
|
1162
1162
|
readonly file: "components/data-display.prop.ts";
|
|
1163
|
-
readonly vocabulary: readonly ["BadgeVariantProp", "ShapeProp", "ToneProp", "ChildrenProp", "ClassNameProp"
|
|
1163
|
+
readonly vocabulary: readonly ["BadgeVariantProp", "ShapeProp", "ToneProp", "ChildrenProp", "ClassNameProp", {
|
|
1164
|
+
readonly field: "color";
|
|
1165
|
+
readonly local: true;
|
|
1166
|
+
readonly reason: "The entity's OWN colour as a CSS colour string — DATA a person picked in a settings screen (a status, an issue type, a tag), a third axis beside `variant` (structure) and `tone` (meaning). No vocabulary type fits: ToneProp is the closed semantic set, and this value is open by definition. Washed into --badge-tint-surface rather than filled, because no foreground clears WCAG AA against every colour a picker can produce.";
|
|
1167
|
+
}];
|
|
1164
1168
|
};
|
|
1165
1169
|
readonly DataTableProp: {
|
|
1166
1170
|
readonly group: "data-display";
|
package/dist/props/registry.js
CHANGED
|
@@ -1345,7 +1345,18 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
1345
1345
|
BadgeProp: {
|
|
1346
1346
|
group: "data-display",
|
|
1347
1347
|
file: "components/data-display.prop.ts",
|
|
1348
|
-
vocabulary: [
|
|
1348
|
+
vocabulary: [
|
|
1349
|
+
"BadgeVariantProp",
|
|
1350
|
+
"ShapeProp",
|
|
1351
|
+
"ToneProp",
|
|
1352
|
+
"ChildrenProp",
|
|
1353
|
+
"ClassNameProp",
|
|
1354
|
+
{
|
|
1355
|
+
field: "color",
|
|
1356
|
+
local: true,
|
|
1357
|
+
reason: "The entity's OWN colour as a CSS colour string \u2014 DATA a person picked in a settings screen (a status, an issue type, a tag), a third axis beside `variant` (structure) and `tone` (meaning). No vocabulary type fits: ToneProp is the closed semantic set, and this value is open by definition. Washed into --badge-tint-surface rather than filled, because no foreground clears WCAG AA against every colour a picker can produce."
|
|
1358
|
+
}
|
|
1359
|
+
]
|
|
1349
1360
|
},
|
|
1350
1361
|
DataTableProp: {
|
|
1351
1362
|
group: "data-display",
|
|
@@ -25,6 +25,21 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
[data-slot="badge"][data-tinted] {
|
|
29
|
+
|
|
30
|
+
background-color: color-mix(
|
|
31
|
+
in srgb,
|
|
32
|
+
var(--badge-tint-surface),
|
|
33
|
+
var(--badge-color) var(--badge-tint-fill)
|
|
34
|
+
);
|
|
35
|
+
border-color: color-mix(
|
|
36
|
+
in srgb,
|
|
37
|
+
var(--badge-tint-surface),
|
|
38
|
+
var(--badge-color) var(--badge-tint-edge)
|
|
39
|
+
);
|
|
40
|
+
color: var(--badge-tint-foreground);
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
[data-slot="badge-icon"] {
|
|
29
44
|
width: var(--badge-icon-size);
|
|
30
45
|
height: var(--badge-icon-size);
|
|
@@ -10,4 +10,12 @@
|
|
|
10
10
|
--badge-line-height: calc(1 / 0.75);
|
|
11
11
|
|
|
12
12
|
--badge-icon-size: var(--icon-size-xs);
|
|
13
|
+
|
|
14
|
+
--badge-tint-fill: 18%;
|
|
15
|
+
--badge-tint-edge: 45%;
|
|
16
|
+
|
|
17
|
+
--badge-tint-surface: hsl(var(--card));
|
|
18
|
+
--badge-tint-foreground: hsl(var(--card-foreground));
|
|
19
|
+
|
|
20
|
+
--badge-color: var(--badge-tint-surface);
|
|
13
21
|
}
|
|
@@ -30,6 +30,21 @@ const shapes = [
|
|
|
30
30
|
{ shape: "sharp" as const, label: "角 Sharp" },
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Colours a person picked, not colours that mean something — a status and an
|
|
35
|
+
* issue type out of a project's own settings screen, plus the two ends of the
|
|
36
|
+
* range an administrator can still type. `#488a5a` is here because it is the
|
|
37
|
+
* worst case for a SOLID chip: near-black and white measure equal on it, both
|
|
38
|
+
* 4.15:1, under the 4.5 badge-sized text needs. Washed, it clears 8.52.
|
|
39
|
+
*/
|
|
40
|
+
const dataColours = [
|
|
41
|
+
{ color: "#4488c5", label: "処理中 In progress" },
|
|
42
|
+
{ color: "#ea9a10", label: "未対応 Open" },
|
|
43
|
+
{ color: "#488a5a", label: "完了 Done" },
|
|
44
|
+
{ color: "#000000", label: "黒 Black" },
|
|
45
|
+
{ color: "#ffffff", label: "白 White" },
|
|
46
|
+
];
|
|
47
|
+
|
|
33
48
|
const tones = [
|
|
34
49
|
{ tone: "default" as const, label: "既定 Default" },
|
|
35
50
|
{ tone: "primary" as const, label: "ブランド Brand" },
|
|
@@ -120,6 +135,27 @@ export default function Demo() {
|
|
|
120
135
|
</CardContent>
|
|
121
136
|
</Card>
|
|
122
137
|
|
|
138
|
+
<Card>
|
|
139
|
+
<CardHeader>
|
|
140
|
+
<CardTitle level={2}>The record’s own colour</CardTitle>
|
|
141
|
+
<CardDescription>
|
|
142
|
+
color carries DATA: a status an administrator coloured, an issue type, a tag. The chip
|
|
143
|
+
is washed into the surface rather than filled, because a solid chip has to choose a
|
|
144
|
+
foreground and no choice is readable for every colour a picker can produce. Retune the
|
|
145
|
+
wash with --badge-tint-fill / --badge-tint-edge.
|
|
146
|
+
</CardDescription>
|
|
147
|
+
</CardHeader>
|
|
148
|
+
<CardContent>
|
|
149
|
+
<Flex direction="row" wrap align="center" gap="sm">
|
|
150
|
+
{dataColours.map((c) => (
|
|
151
|
+
<Badge key={c.color} shape="pill" color={c.color}>
|
|
152
|
+
{c.label}
|
|
153
|
+
</Badge>
|
|
154
|
+
))}
|
|
155
|
+
</Flex>
|
|
156
|
+
</CardContent>
|
|
157
|
+
</Card>
|
|
158
|
+
|
|
123
159
|
<Card>
|
|
124
160
|
<CardHeader>
|
|
125
161
|
<CardTitle level={2}>Semantic tones</CardTitle>
|
|
@@ -39,7 +39,7 @@ const slides = [
|
|
|
39
39
|
function DotNavExample() {
|
|
40
40
|
return (
|
|
41
41
|
<Carousel
|
|
42
|
-
|
|
42
|
+
style={{ paddingInline: "var(--space-10)" }}
|
|
43
43
|
opts={{ loop: true }}
|
|
44
44
|
aria-label="ドットナビゲーション付きカルーセル"
|
|
45
45
|
>
|
|
@@ -71,7 +71,7 @@ export default function Demo() {
|
|
|
71
71
|
</CardDescription>
|
|
72
72
|
</CardHeader>
|
|
73
73
|
<CardContent>
|
|
74
|
-
<Carousel
|
|
74
|
+
<Carousel style={{ paddingInline: "var(--space-10)" }} aria-label="月次 KPI カルーセル">
|
|
75
75
|
<CarouselContent>
|
|
76
76
|
{months.map((m) => (
|
|
77
77
|
<CarouselItem key={m.label} className="basis-full sm:basis-1/2 lg:basis-1/3">
|
|
@@ -96,7 +96,7 @@ export default function Demo() {
|
|
|
96
96
|
</CardHeader>
|
|
97
97
|
<CardContent>
|
|
98
98
|
<Carousel
|
|
99
|
-
|
|
99
|
+
style={{ paddingInline: "var(--space-10)" }}
|
|
100
100
|
opts={{ loop: true, align: "start" }}
|
|
101
101
|
aria-label="ループギャラリーカルーセル"
|
|
102
102
|
>
|
|
@@ -137,7 +137,11 @@ export default function Demo() {
|
|
|
137
137
|
</CardDescription>
|
|
138
138
|
</CardHeader>
|
|
139
139
|
<CardContent>
|
|
140
|
-
<Carousel
|
|
140
|
+
<Carousel
|
|
141
|
+
style={{ paddingBlock: "var(--space-10)" }}
|
|
142
|
+
opts={{ axis: "y" }}
|
|
143
|
+
aria-label="縦方向カルーセル"
|
|
144
|
+
>
|
|
141
145
|
<CarouselContent className="h-48">
|
|
142
146
|
{slides.map((s) => (
|
|
143
147
|
<CarouselItem key={s.label}>
|
|
@@ -145,15 +145,19 @@ export default function Demo() {
|
|
|
145
145
|
<Label htmlFor="pm-doc-diff-only">差分のみ</Label>
|
|
146
146
|
</Flex>
|
|
147
147
|
</Flex>
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
148
|
+
<Card variant="outline" className="overflow-hidden">
|
|
149
|
+
<CardContent flush>
|
|
150
|
+
<div>
|
|
151
|
+
<PermissionMatrix
|
|
152
|
+
roles={ROLES}
|
|
153
|
+
permissions={PERMISSIONS}
|
|
154
|
+
grants={grants}
|
|
155
|
+
compare={[compareA, compareB]}
|
|
156
|
+
diffOnly={diffOnly}
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
</CardContent>
|
|
160
|
+
</Card>
|
|
157
161
|
</Flex>
|
|
158
162
|
</CardContent>
|
|
159
163
|
</Card>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import {
|
|
3
|
+
Badge,
|
|
3
4
|
Card,
|
|
4
5
|
CardContent,
|
|
5
6
|
CardDescription,
|
|
@@ -40,7 +41,7 @@ export default function Demo() {
|
|
|
40
41
|
<CardContent>
|
|
41
42
|
<Popover defaultOpen>
|
|
42
43
|
<PopoverAnchor asChild>
|
|
43
|
-
<
|
|
44
|
+
<Badge variant="outline">請求額 ¥482,000</Badge>
|
|
44
45
|
</PopoverAnchor>
|
|
45
46
|
<PopoverContent side="right" aria-label="請求額の補足">
|
|
46
47
|
<PopoverDescription>税額と支払条件の補足情報です。</PopoverDescription>
|
|
@@ -109,31 +109,38 @@ export default function Demo() {
|
|
|
109
109
|
</CardDescription>
|
|
110
110
|
</CardHeader>
|
|
111
111
|
<CardContent>
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
112
|
+
<Card variant="outline" className="h-64 w-full">
|
|
113
|
+
<CardContent flush>
|
|
114
|
+
<ScrollArea
|
|
115
|
+
anchor="bottom"
|
|
116
|
+
viewportRef={streamViewport}
|
|
117
|
+
onAnchoredChange={setAnchored}
|
|
118
|
+
type="always"
|
|
119
|
+
>
|
|
120
|
+
<CardContent>
|
|
121
|
+
<Flex direction="col">
|
|
122
|
+
{posts.map((post) => (
|
|
123
|
+
<Flex key={post.id} direction="col" gap="xs">
|
|
124
|
+
<Flex gap="sm" align="baseline">
|
|
125
|
+
<Text size="sm" weight="medium">
|
|
126
|
+
{post.author}
|
|
127
|
+
</Text>
|
|
128
|
+
<Text size="xs" tone="muted">
|
|
129
|
+
{timeFormatter.format(
|
|
130
|
+
new Date(STREAM_EPOCH + post.id * STREAM_STEP_MS),
|
|
131
|
+
)}
|
|
132
|
+
</Text>
|
|
133
|
+
</Flex>
|
|
134
|
+
<Text size="sm" tone="muted">
|
|
135
|
+
{post.body}
|
|
136
|
+
</Text>
|
|
137
|
+
</Flex>
|
|
138
|
+
))}
|
|
129
139
|
</Flex>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
))}
|
|
135
|
-
</Flex>
|
|
136
|
-
</ScrollArea>
|
|
140
|
+
</CardContent>
|
|
141
|
+
</ScrollArea>
|
|
142
|
+
</CardContent>
|
|
143
|
+
</Card>
|
|
137
144
|
</CardContent>
|
|
138
145
|
<CardFooter>
|
|
139
146
|
<Flex gap="sm" wrap>
|
|
@@ -164,20 +171,21 @@ export default function Demo() {
|
|
|
164
171
|
</CardDescription>
|
|
165
172
|
</CardHeader>
|
|
166
173
|
<CardContent>
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
174
|
+
<Card variant="outline" className="h-40 w-full">
|
|
175
|
+
<CardContent flush>
|
|
176
|
+
<ScrollArea anchor="bottom" anchorOffset={0} type="always">
|
|
177
|
+
<CardContent>
|
|
178
|
+
<Flex direction="col" gap="xs">
|
|
179
|
+
{entries.map((e) => (
|
|
180
|
+
<Text key={e} size="sm" className="tabular-nums">
|
|
181
|
+
{e}
|
|
182
|
+
</Text>
|
|
183
|
+
))}
|
|
184
|
+
</Flex>
|
|
185
|
+
</CardContent>
|
|
186
|
+
</ScrollArea>
|
|
187
|
+
</CardContent>
|
|
188
|
+
</Card>
|
|
181
189
|
</CardContent>
|
|
182
190
|
</Card>
|
|
183
191
|
|
|
@@ -189,15 +197,21 @@ export default function Demo() {
|
|
|
189
197
|
</CardDescription>
|
|
190
198
|
</CardHeader>
|
|
191
199
|
<CardContent>
|
|
192
|
-
<
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
200
|
+
<Card variant="outline" className="h-56 w-full">
|
|
201
|
+
<CardContent flush>
|
|
202
|
+
<ScrollArea>
|
|
203
|
+
<CardContent>
|
|
204
|
+
<Flex direction="col" gap="xs">
|
|
205
|
+
{entries.map((e) => (
|
|
206
|
+
<div key={e} className="text-sm tabular-nums">
|
|
207
|
+
{e}
|
|
208
|
+
</div>
|
|
209
|
+
))}
|
|
210
|
+
</Flex>
|
|
211
|
+
</CardContent>
|
|
212
|
+
</ScrollArea>
|
|
213
|
+
</CardContent>
|
|
214
|
+
</Card>
|
|
201
215
|
</CardContent>
|
|
202
216
|
</Card>
|
|
203
217
|
|
|
@@ -210,15 +224,21 @@ export default function Demo() {
|
|
|
210
224
|
</CardDescription>
|
|
211
225
|
</CardHeader>
|
|
212
226
|
<CardContent>
|
|
213
|
-
<
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
227
|
+
<Card variant="outline" className="h-56 w-full">
|
|
228
|
+
<CardContent flush>
|
|
229
|
+
<ScrollArea type="always">
|
|
230
|
+
<CardContent>
|
|
231
|
+
<Flex direction="col" gap="xs">
|
|
232
|
+
{entries.map((e) => (
|
|
233
|
+
<div key={e} className="text-sm tabular-nums">
|
|
234
|
+
{e}
|
|
235
|
+
</div>
|
|
236
|
+
))}
|
|
237
|
+
</Flex>
|
|
238
|
+
</CardContent>
|
|
239
|
+
</ScrollArea>
|
|
240
|
+
</CardContent>
|
|
241
|
+
</Card>
|
|
222
242
|
</CardContent>
|
|
223
243
|
</Card>
|
|
224
244
|
|
|
@@ -233,16 +253,22 @@ export default function Demo() {
|
|
|
233
253
|
</CardDescription>
|
|
234
254
|
</CardHeader>
|
|
235
255
|
<CardContent>
|
|
236
|
-
<
|
|
237
|
-
<
|
|
238
|
-
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
256
|
+
<Card variant="outline" className="w-full">
|
|
257
|
+
<CardContent flush>
|
|
258
|
+
<ScrollArea>
|
|
259
|
+
<CardContent>
|
|
260
|
+
<Flex gap="lg" className="w-max">
|
|
261
|
+
{columns.map((c) => (
|
|
262
|
+
<div key={c} className="text-sm whitespace-nowrap tabular-nums">
|
|
263
|
+
{c}
|
|
264
|
+
</div>
|
|
265
|
+
))}
|
|
266
|
+
</Flex>
|
|
267
|
+
</CardContent>
|
|
268
|
+
<ScrollBar orientation="horizontal" />
|
|
269
|
+
</ScrollArea>
|
|
270
|
+
</CardContent>
|
|
271
|
+
</Card>
|
|
246
272
|
</CardContent>
|
|
247
273
|
</Card>
|
|
248
274
|
|
|
@@ -254,15 +280,21 @@ export default function Demo() {
|
|
|
254
280
|
</CardDescription>
|
|
255
281
|
</CardHeader>
|
|
256
282
|
<CardContent>
|
|
257
|
-
<
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
283
|
+
<Card variant="outline" className="h-56 w-full">
|
|
284
|
+
<CardContent flush>
|
|
285
|
+
<ScrollArea type="always">
|
|
286
|
+
<CardContent>
|
|
287
|
+
<Flex direction="col" gap="xs">
|
|
288
|
+
{shortEntries.map((e) => (
|
|
289
|
+
<div key={e} className="text-sm tabular-nums">
|
|
290
|
+
{e}
|
|
291
|
+
</div>
|
|
292
|
+
))}
|
|
293
|
+
</Flex>
|
|
294
|
+
</CardContent>
|
|
295
|
+
</ScrollArea>
|
|
296
|
+
</CardContent>
|
|
297
|
+
</Card>
|
|
266
298
|
</CardContent>
|
|
267
299
|
</Card>
|
|
268
300
|
</Flex>
|
|
@@ -38,7 +38,7 @@ export default function Demo() {
|
|
|
38
38
|
</CardHeader>
|
|
39
39
|
<CardContent flush>
|
|
40
40
|
<Table>
|
|
41
|
-
<caption className="
|
|
41
|
+
<caption className="text-start" style={{ padding: "var(--space-2) var(--space-4)" }}>
|
|
42
42
|
<Text size="xs" tone="muted">
|
|
43
43
|
2026年5月 売上計上(税込)
|
|
44
44
|
</Text>
|
|
@@ -111,7 +111,7 @@ export default function Demo() {
|
|
|
111
111
|
onCheckedChange={(next) => setScopes(next === true ? ALL_SCOPES : [])}
|
|
112
112
|
/>
|
|
113
113
|
</Field>
|
|
114
|
-
<Flex direction="col" gap="sm"
|
|
114
|
+
<Flex direction="col" gap="sm" style={{ paddingInlineStart: "var(--space-6)" }}>
|
|
115
115
|
<Field id="scope-read" label="閲覧">
|
|
116
116
|
<Checkbox
|
|
117
117
|
id="scope-read"
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Badge,
|
|
5
|
+
Card,
|
|
6
|
+
CardContent,
|
|
7
|
+
CardDescription,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
} from "@godxjp/ui/data-display";
|
|
4
11
|
import { FormField, Select } from "@godxjp/ui/data-entry";
|
|
5
12
|
import { Text } from "@godxjp/ui/general";
|
|
6
13
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
@@ -63,12 +70,10 @@ async function loadCountries({ query }: SelectLoadParams): Promise<SelectLoadRes
|
|
|
63
70
|
// real product ships an SVG flag set and renders it here. Tokens only — no hex, no inline style.
|
|
64
71
|
function renderCountry(option: SelectOption) {
|
|
65
72
|
return (
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
{option.value}
|
|
69
|
-
</Text>
|
|
73
|
+
<Flex align="center" gap="sm">
|
|
74
|
+
<Badge variant="secondary">{option.value}</Badge>
|
|
70
75
|
<Text truncate>{option.label}</Text>
|
|
71
|
-
</
|
|
76
|
+
</Flex>
|
|
72
77
|
);
|
|
73
78
|
}
|
|
74
79
|
|