@godxjp/ui 18.2.0 → 18.4.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/README.md +2 -2
- package/dist/components/data-display/index.d.ts +3 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/qr-code.d.ts +8 -0
- package/dist/components/data-display/qr-code.js +34 -0
- package/dist/components/layout/app-shell.js +1 -1
- package/dist/props/components/data-display.prop.d.ts +11 -0
- package/dist/props/components/index.d.ts +1 -1
- package/dist/props/components/layout.prop.d.ts +1 -1
- package/dist/props/registry.d.ts +5 -0
- package/dist/props/registry.js +5 -0
- package/dist/styles/base.css +1 -1
- package/dist/styles/card-layout.css +1 -1
- package/dist/styles/data-display-layout.css +19 -0
- package/dist/styles/dialog-layout.css +4 -0
- package/dist/styles/fonts.css +14 -16
- package/dist/styles/layout.css +1 -1
- package/dist/styles/shell-layout.css +21 -26
- package/dist/tokens/components/card.css +4 -5
- package/dist/tokens/components/data-display.css +9 -0
- package/dist/tokens/components/shell.css +11 -1
- package/dist/tokens/foundation.css +2 -2
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ Components emit `data-slot` / `data-*`; the look lives in `styles/*-layout.css`.
|
|
|
70
70
|
| **Layout** | `@godxjp/ui/layout` | `Flex`, `PageContainer`, `ResponsiveGrid`, `AppShell`, `Sidebar`, `Separator`, `AspectRatio`, `Resizable` |
|
|
71
71
|
| **General** | `@godxjp/ui/general` | `Button` |
|
|
72
72
|
| **Data Entry** | `@godxjp/ui/data-entry` | `Input`, `Select`, `FormField`, `Field`, `DatePicker`, `TimePicker`, `Combobox`, `Switch`, `Toggle`, `Upload`, `Cascader`, `TreeSelect`, `ColorPicker`, `Slider`, `PasswordInput`, `PasswordStrength`, `InputOTP`, `Rating`, `TagInput` |
|
|
73
|
-
| **Data Display** | `@godxjp/ui/data-display` | `Table`, `DataTable`, `Card`, `StatCard`, `Badge`, `Avatar`, `Descriptions`, `Timeline`, `EmptyState`, `Progress`, `Accordion`, `HoverCard`, `Carousel`, `Popover`, `Collapsible`
|
|
73
|
+
| **Data Display** | `@godxjp/ui/data-display` | `Table`, `DataTable`, `Card`, `StatCard`, `Badge`, `Avatar`, `Descriptions`, `Timeline`, `EmptyState`, `Progress`, `QrCode`, `CredentialReveal`, `Accordion`, `HoverCard`, `Carousel`, `Popover`, `Collapsible` |
|
|
74
74
|
| **Feedback** | `@godxjp/ui/feedback` | `Dialog`, `AlertDialog`, `Sheet` (side), `Drawer` (bottom-sheet), `Toast`, `Skeleton`, `Alert`, `Tooltip` |
|
|
75
75
|
| **Query** | `@godxjp/ui/query` | `DataState`, `InfiniteQueryState`, `PrefetchLink` (adapter subpath — pulls TanStack Query) |
|
|
76
76
|
| **Navigation** | `@godxjp/ui/navigation` | `Tabs`, `Toolbar`, `DropdownMenu`, `ContextMenu`, `Menubar`, `NavigationMenu`, `Steps`, `Pagination`, `Breadcrumb`, `AppSettingPicker` |
|
|
@@ -121,7 +121,7 @@ separate `@godxjp/ui/data-grid` (`DataGrid`) subpath has been merged in and remo
|
|
|
121
121
|
## Consumer setup — theme is self-contained
|
|
122
122
|
|
|
123
123
|
The framework ships colors, the type scale, the wa-iro palette, and (opt-in)
|
|
124
|
-
bundled fonts (Noto Sans JP
|
|
124
|
+
bundled fonts (M PLUS 2 + Noto Sans JP fallback via `@fontsource`). A consumer's entire
|
|
125
125
|
styling surface is **one import + content sources** — no `:root` overrides, no
|
|
126
126
|
font `<link>`:
|
|
127
127
|
|
|
@@ -4,6 +4,9 @@ export { ListRow } from "./list-row.js";
|
|
|
4
4
|
export type { ListRowProps } from "./list-row.js";
|
|
5
5
|
export { CredentialReveal } from "./credential-reveal.js";
|
|
6
6
|
export type { CredentialRevealProp, CredentialRevealProps, CredentialRevealTone, } from "./credential-reveal.js";
|
|
7
|
+
export { QrCode } from "./qr-code.js";
|
|
8
|
+
export type { QrCodeProps } from "./qr-code.js";
|
|
9
|
+
export type { QrCodeProp } from "../../props/components/data-display.prop.js";
|
|
7
10
|
export { Avatar, AvatarImage, AvatarFallback } from "./avatar.js";
|
|
8
11
|
export { Card, CardBar, CardContent, CardCover, CardDescription, CardFooter, CardHeader, CardTitle, CardAction, StatCard, } from "./card.js";
|
|
9
12
|
export type { StatCardProps, CardBarProps } from "./card.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Badge } from "./badge.js";
|
|
2
2
|
import { ListRow } from "./list-row.js";
|
|
3
3
|
import { CredentialReveal } from "./credential-reveal.js";
|
|
4
|
+
import { QrCode } from "./qr-code.js";
|
|
4
5
|
import { Avatar, AvatarImage, AvatarFallback } from "./avatar.js";
|
|
5
6
|
import {
|
|
6
7
|
Card,
|
|
@@ -86,6 +87,7 @@ export {
|
|
|
86
87
|
PopoverTitle,
|
|
87
88
|
PopoverTrigger,
|
|
88
89
|
Progress,
|
|
90
|
+
QrCode,
|
|
89
91
|
ScrollArea,
|
|
90
92
|
ScrollBar,
|
|
91
93
|
StatCard,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { QrCodeProp } from "../../props/components/data-display.prop.js";
|
|
3
|
+
export type QrCodeProps = QrCodeProp & Omit<React.ComponentPropsWithoutRef<"svg">, keyof QrCodeProp | "children" | "role" | "style" | "type">;
|
|
4
|
+
/**
|
|
5
|
+
* Renders a QR code entirely in-process. The encoded value is never sent to a network service,
|
|
6
|
+
* written to an element attribute, or included in accessible text.
|
|
7
|
+
*/
|
|
8
|
+
export declare const QrCode: React.ForwardRefExoticComponent<QrCodeProp & Omit<Omit<React.SVGProps<SVGSVGElement>, "ref">, "style" | "children" | "role" | "type" | keyof QrCodeProp> & React.RefAttributes<SVGSVGElement>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { QRCodeSVG } from "qrcode.react";
|
|
4
|
+
import { cn } from "../../lib/utils.js";
|
|
5
|
+
const QR_INTRINSIC_SIZE = 256;
|
|
6
|
+
const QrCode = React.forwardRef(
|
|
7
|
+
({ value, label, size = "md", className, ...props }, ref) => {
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
QRCodeSVG,
|
|
10
|
+
{
|
|
11
|
+
ref,
|
|
12
|
+
...props,
|
|
13
|
+
value,
|
|
14
|
+
title: label,
|
|
15
|
+
size: QR_INTRINSIC_SIZE,
|
|
16
|
+
level: "M",
|
|
17
|
+
boostLevel: true,
|
|
18
|
+
marginSize: 4,
|
|
19
|
+
bgColor: "hsl(var(--qr-code-background))",
|
|
20
|
+
fgColor: "hsl(var(--qr-code-foreground))",
|
|
21
|
+
role: "img",
|
|
22
|
+
"aria-label": label,
|
|
23
|
+
focusable: "false",
|
|
24
|
+
"data-slot": "qr-code",
|
|
25
|
+
"data-size": size,
|
|
26
|
+
className: cn("ui-qr-code", className)
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
QrCode.displayName = "QrCode";
|
|
32
|
+
export {
|
|
33
|
+
QrCode
|
|
34
|
+
};
|
|
@@ -49,7 +49,7 @@ function AppShell({
|
|
|
49
49
|
type: "button",
|
|
50
50
|
variant: "ghost",
|
|
51
51
|
size: "sm",
|
|
52
|
-
className: "app-mobile-nav-trigger hidden max-
|
|
52
|
+
className: "app-mobile-nav-trigger hidden max-[900px]:inline-flex",
|
|
53
53
|
"aria-label": t("layout.appShell.openNav"),
|
|
54
54
|
"aria-haspopup": "dialog",
|
|
55
55
|
children: /* @__PURE__ */ jsx(Menu, { className: "size-5", "aria-hidden": "true" })
|
|
@@ -110,6 +110,17 @@ export type CredentialRevealProp = {
|
|
|
110
110
|
id?: IdProp;
|
|
111
111
|
"aria-label"?: string;
|
|
112
112
|
};
|
|
113
|
+
/** @see QrCode */
|
|
114
|
+
export type QrCodeProp = {
|
|
115
|
+
/** Sensitive or public value encoded locally into the QR modules. */
|
|
116
|
+
value: string;
|
|
117
|
+
/** Purpose-specific accessible name. The encoded value is never used as accessible text. */
|
|
118
|
+
label: string;
|
|
119
|
+
/** Natural display size. Default `md`. */
|
|
120
|
+
size?: SizeProp;
|
|
121
|
+
className?: ClassNameProp;
|
|
122
|
+
id?: IdProp;
|
|
123
|
+
};
|
|
113
124
|
/** @see DataTable */
|
|
114
125
|
export type DataTableProp<T> = {
|
|
115
126
|
data: T[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { AppShellProp, PageContainerProp, PageInsetProp, SidebarItemProp, SidebarProductProp, SidebarProp, SidebarSectionProp, TopbarProp, } from "./layout.prop.js";
|
|
2
2
|
export type { ButtonProp } from "./general.prop.js";
|
|
3
3
|
export type { InputProp, TextareaProp, FormFieldProp, SearchInputProp, CheckboxProp, CheckboxGroupProp, ChoiceOptionProp, RadioProp, RadioGroupProp, SwitchProp, SliderProp, CalendarProp, DatePickerProp, DateRangePickerProp, TimePickerProp, ColorPickerProp, UploadProp, UploadFileItemProp, UploadVariantProp, TreeOptionProp, TreeFieldNamesProp, CascaderProp, TreeSelectProp, ShowCheckedStrategyProp, TransferProp, TransferItemProp, } from "./data-entry.prop.js";
|
|
4
|
-
export type { EmptyStateProp, DescriptionsProp, DescriptionsItemProp, BadgeProp, DataTableProp, } from "./data-display.prop.js";
|
|
4
|
+
export type { EmptyStateProp, DescriptionsProp, DescriptionsItemProp, BadgeProp, DataTableProp, QrCodeProp, } from "./data-display.prop.js";
|
|
5
5
|
export type { ChartDatum, ChartSeriesProp, LineChartProp, BarChartProp, AreaChartProp, PieChartProp, } from "./charts.prop.js";
|
|
6
6
|
export type { AlertQueryErrorProp, AlertProp, AlertTitleProp, AlertContentProp, AlertDescriptionProp, AlertActionsProp, SkeletonRowsProp, } from "./feedback.prop.js";
|
|
7
7
|
export type { DataStateProp, InfiniteQueryStateProp, InfiniteQueryHelpers, PrefetchLinkProp, } from "./query.prop.js";
|
|
@@ -76,7 +76,7 @@ export type AppShellProp = {
|
|
|
76
76
|
footer?: ReactNode;
|
|
77
77
|
sidebarCollapsed?: boolean;
|
|
78
78
|
/**
|
|
79
|
-
* Navigation shown in the mobile drawer
|
|
79
|
+
* Navigation shown in the mobile drawer at the DXS 900px breakpoint, where the docked sidebar is
|
|
80
80
|
* hidden. AppShell OWNS the drawer: it renders a hamburger trigger in the topbar and a focus-
|
|
81
81
|
* trapped Sheet (Esc + overlay close, focus returns to the trigger) — hiding the sidebar without
|
|
82
82
|
* a reachable alternative is invalid (gh#165). Defaults to `sidebar`, so the same nav is
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -734,6 +734,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
734
734
|
readonly file: "components/data-display.prop.ts";
|
|
735
735
|
readonly vocabulary: readonly ["LabelProp", "SizeProp", "ToneProp", "OnValueChangeProp", "HandlerProp", "ClassNameProp", "IdProp"];
|
|
736
736
|
};
|
|
737
|
+
readonly QrCodeProp: {
|
|
738
|
+
readonly group: "data-display";
|
|
739
|
+
readonly file: "components/data-display.prop.ts";
|
|
740
|
+
readonly vocabulary: readonly ["ValueProp", "LabelProp", "SizeProp", "ClassNameProp", "IdProp"];
|
|
741
|
+
};
|
|
737
742
|
readonly ChartSeriesProp: {
|
|
738
743
|
readonly group: "data-display";
|
|
739
744
|
readonly file: "components/charts.prop.ts";
|
package/dist/props/registry.js
CHANGED
|
@@ -810,6 +810,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
810
810
|
"IdProp"
|
|
811
811
|
]
|
|
812
812
|
},
|
|
813
|
+
QrCodeProp: {
|
|
814
|
+
group: "data-display",
|
|
815
|
+
file: "components/data-display.prop.ts",
|
|
816
|
+
vocabulary: ["ValueProp", "LabelProp", "SizeProp", "ClassNameProp", "IdProp"]
|
|
817
|
+
},
|
|
813
818
|
ChartSeriesProp: {
|
|
814
819
|
group: "data-display",
|
|
815
820
|
file: "components/charts.prop.ts",
|
package/dist/styles/base.css
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* base sans. Consumers switch a locale's face by setting its slot, e.g.
|
|
28
28
|
* :root { --font-sans-ja: "Noto Sans JP", var(--font-sans-base); }
|
|
29
29
|
* without writing any [lang] selectors. The opt-in bundle styles/fonts fills
|
|
30
|
-
* these slots for its Noto Sans JP
|
|
30
|
+
* these slots for its M PLUS 2 + Noto Sans JP fallback. `--font-sans-base` is a
|
|
31
31
|
* separate token (not --font-family-sans) so the fallback can't self-reference. */
|
|
32
32
|
[lang="ja"] {
|
|
33
33
|
--font-family-sans: var(--font-sans-ja, var(--font-sans-base));
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
overflow: hidden;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/* ── Surface variants — fill only;
|
|
45
|
+
/* ── Surface variants — fill only; retain the shared DXS surface elevation ──── */
|
|
46
46
|
[data-slot="card"][data-variant="muted"] {
|
|
47
47
|
background: hsl(var(--secondary));
|
|
48
48
|
}
|
|
@@ -534,4 +534,23 @@
|
|
|
534
534
|
display: flex;
|
|
535
535
|
justify-content: flex-end;
|
|
536
536
|
}
|
|
537
|
+
|
|
538
|
+
/* QrCode — a quiet, scanner-safe SVG surface with an ISO/IEC-style four-module quiet zone
|
|
539
|
+
* supplied by the encoder. Sizing is natural rather than stretched across its container. */
|
|
540
|
+
.ui-qr-code {
|
|
541
|
+
display: block;
|
|
542
|
+
inline-size: var(--qr-code-size-md);
|
|
543
|
+
block-size: auto;
|
|
544
|
+
max-inline-size: 100%;
|
|
545
|
+
aspect-ratio: 1;
|
|
546
|
+
}
|
|
547
|
+
.ui-qr-code[data-size="xs"] {
|
|
548
|
+
inline-size: var(--qr-code-size-xs);
|
|
549
|
+
}
|
|
550
|
+
.ui-qr-code[data-size="sm"] {
|
|
551
|
+
inline-size: var(--qr-code-size-sm);
|
|
552
|
+
}
|
|
553
|
+
.ui-qr-code[data-size="lg"] {
|
|
554
|
+
inline-size: var(--qr-code-size-lg);
|
|
555
|
+
}
|
|
537
556
|
}
|
package/dist/styles/fonts.css
CHANGED
|
@@ -3,35 +3,33 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Self-contained so consumers need no font config. The browser only downloads
|
|
5
5
|
* the subset files matching the rendered text:
|
|
6
|
-
* ·
|
|
7
|
-
*
|
|
8
|
-
* ·
|
|
9
|
-
* incl. its `vietnamese` subset for full diacritics.
|
|
10
|
-
* See --font-family-sans + :lang(vi) in base.css.
|
|
6
|
+
* · M PLUS 2 — the DXS DEFAULT face for Japanese and Latin, including the
|
|
7
|
+
* Vietnamese glyph coverage used by the product locales.
|
|
8
|
+
* · Noto Sans JP — retained as the CJK fallback after M PLUS 2.
|
|
11
9
|
*
|
|
12
10
|
* The all-in-one `@godxjp/ui/styles` entry pulls this in automatically. If you
|
|
13
11
|
* manage fonts yourself (e.g. next/font), DON'T import this — import
|
|
14
12
|
* `@godxjp/ui/styles/base` + the layout layers you use and supply your own
|
|
15
13
|
* faces via the --font-family-* tokens.
|
|
16
14
|
* ───────────────────────────────────────────────────────────────────────── */
|
|
15
|
+
@import "@fontsource/m-plus-2/400.css";
|
|
16
|
+
@import "@fontsource/m-plus-2/500.css";
|
|
17
|
+
@import "@fontsource/m-plus-2/700.css";
|
|
17
18
|
@import "@fontsource/noto-sans-jp/400.css";
|
|
18
19
|
@import "@fontsource/noto-sans-jp/500.css";
|
|
19
20
|
@import "@fontsource/noto-sans-jp/700.css";
|
|
20
|
-
@import "@fontsource/montserrat/400.css";
|
|
21
|
-
@import "@fontsource/montserrat/500.css";
|
|
22
|
-
@import "@fontsource/montserrat/700.css";
|
|
23
21
|
|
|
24
22
|
/* Fill the font-token slots (see tokens/foundation.css + styles/base.css) with
|
|
25
23
|
* the bundled faces, so the all-in-one `@godxjp/ui/styles` entry stays
|
|
26
|
-
* zero-config:
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* their own faces simply DON'T import this file and set the slots themselves. */
|
|
24
|
+
* zero-config: M PLUS 2 is the DXS default face for every supported locale and
|
|
25
|
+
* Noto Sans JP remains its CJK fallback. Consumers on the per-layer setup who
|
|
26
|
+
* supply their own faces simply DON'T import this file and set the slots. */
|
|
30
27
|
:root {
|
|
31
28
|
--font-sans-base:
|
|
32
|
-
"
|
|
33
|
-
system
|
|
29
|
+
"M PLUS 2", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic Medium", YuGothic,
|
|
30
|
+
"Noto Sans JP", Meiryo, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui,
|
|
31
|
+
sans-serif;
|
|
34
32
|
--font-sans-vi:
|
|
35
|
-
"
|
|
36
|
-
|
|
33
|
+
"M PLUS 2", "Noto Sans JP", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui,
|
|
34
|
+
sans-serif;
|
|
37
35
|
}
|
package/dist/styles/layout.css
CHANGED
|
@@ -414,7 +414,7 @@
|
|
|
414
414
|
* touch targets remain readable while page chrome stops competing with primary actions. A
|
|
415
415
|
* single Flex action group must wrap even when the consumer omitted `wrap`, because clipping
|
|
416
416
|
* header actions makes functionality unreachable. */
|
|
417
|
-
@media (max-width:
|
|
417
|
+
@media (max-width: 720px) {
|
|
418
418
|
.ui-page-container {
|
|
419
419
|
--space-page-active-x: var(--space-page-compact-x);
|
|
420
420
|
--space-page-active-y: var(--space-page-compact-y);
|
|
@@ -11,11 +11,9 @@
|
|
|
11
11
|
"sidebar main"
|
|
12
12
|
"sidebar footer";
|
|
13
13
|
grid-template-columns: 16rem minmax(0, 1fr);
|
|
14
|
-
grid-template-rows:
|
|
14
|
+
grid-template-rows: var(--app-shell-bar-height) minmax(0, 1fr) auto;
|
|
15
15
|
height: 100vh;
|
|
16
|
-
background:
|
|
17
|
-
linear-gradient(180deg, hsl(var(--primary) / 0.035), transparent 14rem),
|
|
18
|
-
hsl(var(--background));
|
|
16
|
+
background: hsl(var(--background));
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
.app-root[data-collapsed="true"] {
|
|
@@ -46,10 +44,9 @@
|
|
|
46
44
|
gap: var(--space-3);
|
|
47
45
|
padding-inline: var(--space-4);
|
|
48
46
|
border-bottom: 1px solid hsl(var(--border));
|
|
49
|
-
background: hsl(var(--
|
|
47
|
+
background: hsl(var(--card));
|
|
50
48
|
/* Opt-in brand-chrome wash — invisible by default (--topbar-gradient: none). */
|
|
51
49
|
background-image: var(--topbar-gradient);
|
|
52
|
-
backdrop-filter: blur(12px);
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
.app-main {
|
|
@@ -69,6 +66,7 @@
|
|
|
69
66
|
* content can never extend the document scroll height (gh#104 — same shell-containment
|
|
70
67
|
* family as the gh#103 body-stretch void). */
|
|
71
68
|
contain: paint;
|
|
69
|
+
background-color: var(--app-shell-main-background);
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
.app-footer {
|
|
@@ -78,7 +76,8 @@
|
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
.app-main .ui-page-container {
|
|
81
|
-
|
|
79
|
+
width: 100%;
|
|
80
|
+
max-width: var(--app-shell-page-max-width);
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
/*
|
|
@@ -92,9 +91,7 @@
|
|
|
92
91
|
display: flex;
|
|
93
92
|
min-height: 100dvh;
|
|
94
93
|
flex-direction: column;
|
|
95
|
-
background:
|
|
96
|
-
linear-gradient(180deg, hsl(var(--primary) / 0.035), transparent 14rem),
|
|
97
|
-
hsl(var(--background));
|
|
94
|
+
background: hsl(var(--muted));
|
|
98
95
|
}
|
|
99
96
|
|
|
100
97
|
.ui-auth-shell-bar {
|
|
@@ -135,9 +132,7 @@
|
|
|
135
132
|
display: flex;
|
|
136
133
|
min-height: 100dvh;
|
|
137
134
|
flex-direction: column;
|
|
138
|
-
background:
|
|
139
|
-
linear-gradient(180deg, hsl(var(--primary) / 0.035), transparent 14rem),
|
|
140
|
-
hsl(var(--background));
|
|
135
|
+
background: hsl(var(--muted));
|
|
141
136
|
}
|
|
142
137
|
|
|
143
138
|
.ui-centered-shell-bar {
|
|
@@ -149,10 +144,9 @@
|
|
|
149
144
|
gap: var(--space-3);
|
|
150
145
|
padding-inline: var(--centered-shell-bar-padding-x);
|
|
151
146
|
border-bottom: 1px solid hsl(var(--border));
|
|
152
|
-
background: hsl(var(--
|
|
147
|
+
background: hsl(var(--card));
|
|
153
148
|
/* Opt-in brand-chrome wash — shares the topbar hook, invisible by default (none). */
|
|
154
149
|
background-image: var(--topbar-gradient);
|
|
155
|
-
backdrop-filter: blur(12px);
|
|
156
150
|
}
|
|
157
151
|
|
|
158
152
|
.ui-centered-shell-main {
|
|
@@ -235,7 +229,7 @@
|
|
|
235
229
|
font-size: var(--font-size-base);
|
|
236
230
|
}
|
|
237
231
|
|
|
238
|
-
@media (width
|
|
232
|
+
@media (width <= 56.25rem) {
|
|
239
233
|
.app-root,
|
|
240
234
|
.app-root[data-collapsed="true"] {
|
|
241
235
|
grid-template-areas:
|
|
@@ -265,7 +259,7 @@
|
|
|
265
259
|
.sb-product,
|
|
266
260
|
.sb-brand {
|
|
267
261
|
display: flex;
|
|
268
|
-
min-height:
|
|
262
|
+
min-height: var(--app-shell-bar-height);
|
|
269
263
|
align-items: center;
|
|
270
264
|
gap: var(--space-2);
|
|
271
265
|
padding-inline: var(--space-4);
|
|
@@ -294,8 +288,8 @@
|
|
|
294
288
|
|
|
295
289
|
.sb-logo-mark {
|
|
296
290
|
display: grid;
|
|
297
|
-
width:
|
|
298
|
-
height:
|
|
291
|
+
width: var(--sidebar-brand-mark-size);
|
|
292
|
+
height: var(--sidebar-brand-mark-size);
|
|
299
293
|
flex: 0 0 auto;
|
|
300
294
|
place-items: center;
|
|
301
295
|
border-radius: var(--radius);
|
|
@@ -344,14 +338,15 @@
|
|
|
344
338
|
.sb-nav-scroll {
|
|
345
339
|
flex: 1;
|
|
346
340
|
overflow-y: auto;
|
|
341
|
+
padding: var(--space-3) var(--space-2);
|
|
347
342
|
}
|
|
348
343
|
|
|
349
344
|
.sb-section {
|
|
350
|
-
padding:
|
|
345
|
+
padding: 0;
|
|
351
346
|
}
|
|
352
347
|
|
|
353
348
|
.sb-section + .sb-section {
|
|
354
|
-
|
|
349
|
+
margin-top: var(--space-4);
|
|
355
350
|
}
|
|
356
351
|
|
|
357
352
|
.sb-section-label {
|
|
@@ -373,18 +368,18 @@
|
|
|
373
368
|
.sb-nav-item {
|
|
374
369
|
display: flex;
|
|
375
370
|
width: 100%;
|
|
376
|
-
height: var(--
|
|
371
|
+
height: var(--sidebar-nav-item-height);
|
|
377
372
|
min-width: 0;
|
|
378
373
|
align-items: center;
|
|
379
|
-
gap:
|
|
380
|
-
padding-inline:
|
|
374
|
+
gap: 0.625rem;
|
|
375
|
+
padding-inline: 0.625rem;
|
|
381
376
|
border: 0;
|
|
382
377
|
border-radius: calc(var(--radius) - 1px);
|
|
383
378
|
background: transparent;
|
|
384
379
|
color: hsl(var(--muted-foreground));
|
|
385
380
|
cursor: pointer;
|
|
386
381
|
font-family: inherit;
|
|
387
|
-
font-size: var(--font-size
|
|
382
|
+
font-size: var(--sidebar-nav-item-font-size);
|
|
388
383
|
text-align: start;
|
|
389
384
|
}
|
|
390
385
|
|
|
@@ -737,7 +732,7 @@
|
|
|
737
732
|
|
|
738
733
|
.tb-search {
|
|
739
734
|
display: flex;
|
|
740
|
-
width: min(
|
|
735
|
+
width: min(var(--topbar-search-max-width), 40vw);
|
|
741
736
|
height: var(--control-height-sm);
|
|
742
737
|
align-items: center;
|
|
743
738
|
gap: var(--space-2);
|
|
@@ -41,11 +41,10 @@
|
|
|
41
41
|
* --card-header-background-alpha: 0 for a quiet borderless-band header.
|
|
42
42
|
* Default = 1px solid hsl(var(--card-border)) (resolved at the call site). */
|
|
43
43
|
--card-header-border-bottom: initial;
|
|
44
|
-
--card-radius: var(--radius);
|
|
45
|
-
/*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
--card-shadow: 0 0 0 0 transparent;
|
|
44
|
+
--card-radius: var(--radius-xl);
|
|
45
|
+
/* The DXS hi-fi baseline uses a quiet 10px data surface with one shadow-sm
|
|
46
|
+
* elevation layer. Consumers can still flatten or lift cards through this knob. */
|
|
47
|
+
--card-shadow: var(--shadow-sm);
|
|
49
48
|
/* Brand glow layer — invisible no-op at rest (rule #44). Paired AFTER --card-shadow in the
|
|
50
49
|
* surface box-shadow so a service can wash every card with the global glow, e.g.
|
|
51
50
|
* --card-glow: var(--shadow-glow), with no markup change. */
|
|
@@ -31,4 +31,13 @@
|
|
|
31
31
|
re-resolves under a scoped theme. Defaults = hsl(var(--primary) / 0.3) border · 0.05 fill. */
|
|
32
32
|
--tree-item-active-border: initial;
|
|
33
33
|
--tree-item-active-background: initial;
|
|
34
|
+
|
|
35
|
+
/* QR codes stay scanner-safe in light and dark application themes. Consumers may override these
|
|
36
|
+
component tokens only when the resulting pair retains strong contrast. */
|
|
37
|
+
--qr-code-foreground: 0 0% 0%;
|
|
38
|
+
--qr-code-background: 0 0% 100%;
|
|
39
|
+
--qr-code-size-xs: 6rem;
|
|
40
|
+
--qr-code-size-sm: 8rem;
|
|
41
|
+
--qr-code-size-md: 10rem;
|
|
42
|
+
--qr-code-size-lg: 12.5rem;
|
|
34
43
|
}
|
|
@@ -20,6 +20,16 @@
|
|
|
20
20
|
--sidebar-gradient: none;
|
|
21
21
|
--topbar-gradient: none;
|
|
22
22
|
|
|
23
|
+
/* DXS application-shell geometry. These defaults mirror the checked-in
|
|
24
|
+
* Admin/Console hi-fi source while remaining themeable by consumers. */
|
|
25
|
+
--app-shell-bar-height: 3rem;
|
|
26
|
+
--app-shell-page-max-width: 80rem;
|
|
27
|
+
--app-shell-main-background: hsl(var(--muted) / 0.4);
|
|
28
|
+
--sidebar-brand-mark-size: 1.375rem;
|
|
29
|
+
--sidebar-nav-item-height: 2rem;
|
|
30
|
+
--sidebar-nav-item-font-size: 0.8125rem;
|
|
31
|
+
--topbar-search-max-width: 26.25rem;
|
|
32
|
+
|
|
23
33
|
/* Sidebar active-item tint/marker — `initial` so the role defaults re-resolve at the call site
|
|
24
34
|
* under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override
|
|
25
35
|
* never reaches it). A service re-tunes the active sub-item accent without forking CSS.
|
|
@@ -47,7 +57,7 @@
|
|
|
47
57
|
* account, standalone settings). The bar mirrors AppShell's `.app-topbar` chrome (fixed height +
|
|
48
58
|
* inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A
|
|
49
59
|
* service retunes the bar inset, block padding and each width tier without forking CSS. */
|
|
50
|
-
--centered-shell-bar-height:
|
|
60
|
+
--centered-shell-bar-height: var(--app-shell-bar-height);
|
|
51
61
|
--centered-shell-bar-padding-x: var(--space-4);
|
|
52
62
|
--centered-shell-main-padding: var(--space-6);
|
|
53
63
|
--centered-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
|
|
@@ -161,8 +161,8 @@
|
|
|
161
161
|
* --font-sans-zh-hans (lang="zh" | "zh-Hans" | "zh-CN")
|
|
162
162
|
* --font-sans-zh-hant (lang="zh-Hant" | "zh-TW")
|
|
163
163
|
* e.g. `--font-sans-ja: "Noto Sans JP", var(--font-sans-base);`
|
|
164
|
-
* The opt-in bundle `@godxjp/ui/styles/fonts` fills these slots
|
|
165
|
-
* Noto Sans JP
|
|
164
|
+
* The opt-in bundle `@godxjp/ui/styles/fonts` fills these slots with the DXS
|
|
165
|
+
* M PLUS 2 face and Noto Sans JP fallback, so the all-in-one entry is zero-config. */
|
|
166
166
|
--font-sans-base:
|
|
167
167
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui,
|
|
168
168
|
sans-serif;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "18.
|
|
4
|
-
"godxUiMcp": "18.
|
|
3
|
+
"version": "18.4.0",
|
|
4
|
+
"godxUiMcp": "18.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.29.1",
|
|
7
7
|
"pnpm": {
|
|
@@ -374,7 +374,7 @@
|
|
|
374
374
|
},
|
|
375
375
|
"dependencies": {
|
|
376
376
|
"@date-fns/tz": "^1.5.0",
|
|
377
|
-
"@fontsource/
|
|
377
|
+
"@fontsource/m-plus-2": "^5.2.9",
|
|
378
378
|
"@fontsource/noto-sans-jp": "^5.2.9",
|
|
379
379
|
"@radix-ui/react-accordion": "^1.2.16",
|
|
380
380
|
"@radix-ui/react-alert-dialog": "^1.1.19",
|
|
@@ -410,6 +410,7 @@
|
|
|
410
410
|
"embla-carousel-react": "^8.6.0",
|
|
411
411
|
"input-otp": "^1.4.2",
|
|
412
412
|
"lucide-react": "^1.25.0",
|
|
413
|
+
"qrcode.react": "4.2.0",
|
|
413
414
|
"react-day-picker": "^10.0.1",
|
|
414
415
|
"react-resizable-panels": "^4.12.2",
|
|
415
416
|
"sonner": "^2.0.7",
|
|
@@ -427,6 +428,7 @@
|
|
|
427
428
|
"@testing-library/react": "^16.3.2",
|
|
428
429
|
"@testing-library/user-event": "^14.6.1",
|
|
429
430
|
"@types/node": "^22.19.19",
|
|
431
|
+
"@types/pngjs": "^6.0.5",
|
|
430
432
|
"@types/react": "^19.2.17",
|
|
431
433
|
"@types/react-dom": "^19.2.3",
|
|
432
434
|
"@vitejs/plugin-react": "^6.0.3",
|
|
@@ -437,7 +439,9 @@
|
|
|
437
439
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
438
440
|
"globals": "^15.15.0",
|
|
439
441
|
"jsdom": "^29.1.1",
|
|
442
|
+
"jsqr": "^1.4.0",
|
|
440
443
|
"playwright": "^1.61.1",
|
|
444
|
+
"pngjs": "^7.0.0",
|
|
441
445
|
"prettier": "^3.9.5",
|
|
442
446
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
|
443
447
|
"react": "^19.2.7",
|