@godxjp/ui 18.4.0 → 18.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.
Files changed (159) hide show
  1. package/README.md +16 -1
  2. package/dist/app/theme-axes.d.ts +11 -3
  3. package/dist/app/theme-axes.js +2 -1
  4. package/dist/components/charts/chart-frame.d.ts +17 -3
  5. package/dist/components/charts/chart-frame.js +7 -1
  6. package/dist/components/charts/chart-summary.d.ts +21 -0
  7. package/dist/components/charts/chart-summary.js +32 -5
  8. package/dist/components/charts/compact-bar-trend.d.ts +30 -0
  9. package/dist/components/charts/compact-bar-trend.js +74 -0
  10. package/dist/components/charts/index.d.ts +6 -0
  11. package/dist/components/charts/index.js +2 -0
  12. package/dist/components/data-display/badge.d.ts +8 -0
  13. package/dist/components/data-display/badge.js +7 -1
  14. package/dist/components/data-display/data-table.d.ts +40 -4
  15. package/dist/components/data-display/data-table.js +69 -2
  16. package/dist/components/data-display/empty-state.js +1 -1
  17. package/dist/components/data-display/index.d.ts +4 -2
  18. package/dist/components/data-display/index.js +10 -1
  19. package/dist/components/data-display/list-row.d.ts +41 -4
  20. package/dist/components/data-display/list-row.js +23 -3
  21. package/dist/components/data-display/qr-code.d.ts +1 -1
  22. package/dist/components/data-display/service-launcher-card.d.ts +40 -0
  23. package/dist/components/data-display/service-launcher-card.js +97 -0
  24. package/dist/components/data-display/table.d.ts +47 -2
  25. package/dist/components/data-display/table.js +29 -4
  26. package/dist/components/data-entry/command-palette.d.ts +37 -0
  27. package/dist/components/data-entry/command-palette.js +125 -0
  28. package/dist/components/data-entry/command.d.ts +10 -10
  29. package/dist/components/data-entry/index.d.ts +3 -0
  30. package/dist/components/data-entry/index.js +2 -0
  31. package/dist/components/data-entry/input-otp.d.ts +1 -0
  32. package/dist/components/feedback/dialog.d.ts +16 -1
  33. package/dist/components/feedback/dialog.js +46 -33
  34. package/dist/components/feedback/index.d.ts +5 -2
  35. package/dist/components/feedback/index.js +8 -2
  36. package/dist/components/feedback/sheet.d.ts +26 -4
  37. package/dist/components/feedback/sheet.js +54 -7
  38. package/dist/components/feedback/two-factor-setup.d.ts +31 -0
  39. package/dist/components/feedback/two-factor-setup.js +97 -0
  40. package/dist/components/general/index.d.ts +1 -1
  41. package/dist/components/general/logo.d.ts +49 -9
  42. package/dist/components/general/logo.js +67 -14
  43. package/dist/components/layout/app-shell.d.ts +1 -1
  44. package/dist/components/layout/app-shell.js +55 -30
  45. package/dist/components/layout/auth-account-summary.d.ts +5 -0
  46. package/dist/components/layout/auth-account-summary.js +31 -0
  47. package/dist/components/layout/auth-divider.d.ts +7 -0
  48. package/dist/components/layout/auth-divider.js +21 -0
  49. package/dist/components/layout/auth-footer.d.ts +5 -0
  50. package/dist/components/layout/auth-footer.js +24 -0
  51. package/dist/components/layout/auth-identity.d.ts +5 -0
  52. package/dist/components/layout/auth-identity.js +17 -0
  53. package/dist/components/layout/auth-shell.d.ts +9 -1
  54. package/dist/components/layout/auth-shell.js +25 -6
  55. package/dist/components/layout/auth-stack.d.ts +4 -0
  56. package/dist/components/layout/auth-stack.js +8 -0
  57. package/dist/components/layout/centered-shell.d.ts +5 -2
  58. package/dist/components/layout/centered-shell.js +29 -19
  59. package/dist/components/layout/error-surface.d.ts +35 -0
  60. package/dist/components/layout/error-surface.js +155 -0
  61. package/dist/components/layout/flex.d.ts +1 -1
  62. package/dist/components/layout/flex.js +4 -0
  63. package/dist/components/layout/index.d.ts +23 -3
  64. package/dist/components/layout/index.js +21 -2
  65. package/dist/components/layout/legal-document-shell.d.ts +34 -0
  66. package/dist/components/layout/legal-document-shell.js +186 -0
  67. package/dist/components/layout/master-detail.d.ts +24 -0
  68. package/dist/components/layout/master-detail.js +48 -0
  69. package/dist/components/layout/org-switcher.d.ts +9 -0
  70. package/dist/components/layout/org-switcher.js +218 -0
  71. package/dist/components/layout/page-container.d.ts +1 -1
  72. package/dist/components/layout/page-container.js +7 -2
  73. package/dist/components/layout/sidebar-link.d.ts +43 -0
  74. package/dist/components/layout/sidebar-link.js +13 -0
  75. package/dist/components/layout/sidebar.d.ts +42 -5
  76. package/dist/components/layout/sidebar.js +170 -85
  77. package/dist/components/navigation/app-setting-picker.js +17 -6
  78. package/dist/components/navigation/filter-bar.d.ts +12 -3
  79. package/dist/components/navigation/filter-bar.js +8 -2
  80. package/dist/components/navigation/index.d.ts +2 -2
  81. package/dist/components/navigation/index.js +3 -1
  82. package/dist/components/navigation/steps.js +38 -19
  83. package/dist/components/navigation/tabs-scroll.d.ts +70 -0
  84. package/dist/components/navigation/tabs-scroll.js +76 -0
  85. package/dist/components/navigation/tabs.js +47 -23
  86. package/dist/components/ui/avatar.d.ts +2 -1
  87. package/dist/components/ui/avatar.js +2 -1
  88. package/dist/components/ui/input-otp.d.ts +4 -1
  89. package/dist/components/ui/input-otp.js +2 -1
  90. package/dist/components/ui/toggle-group.d.ts +7 -4
  91. package/dist/components/ui/toggle-group.js +32 -21
  92. package/dist/email/brand-mark.d.ts +108 -0
  93. package/dist/email/brand-mark.js +88 -0
  94. package/dist/email/color.d.ts +53 -0
  95. package/dist/email/color.js +37 -0
  96. package/dist/email/geometry.d.ts +120 -0
  97. package/dist/email/geometry.js +90 -0
  98. package/dist/email/index.d.ts +83 -0
  99. package/dist/email/index.js +82 -0
  100. package/dist/email/inline-style.d.ts +27 -0
  101. package/dist/email/inline-style.js +26 -0
  102. package/dist/email/tokens.generated.d.ts +167 -0
  103. package/dist/email/tokens.generated.js +162 -0
  104. package/dist/email/urgency.d.ts +22 -0
  105. package/dist/email/urgency.js +14 -0
  106. package/dist/i18n/messages/en.json +36 -3
  107. package/dist/i18n/messages/ja.json +36 -3
  108. package/dist/i18n/messages/vi.json +36 -3
  109. package/dist/inertia/index.d.ts +50 -0
  110. package/dist/inertia/index.js +5 -0
  111. package/dist/props/components/app.prop.d.ts +11 -1
  112. package/dist/props/components/charts.prop.d.ts +40 -1
  113. package/dist/props/components/data-display.prop.d.ts +75 -1
  114. package/dist/props/components/data-entry.prop.d.ts +6 -0
  115. package/dist/props/components/feedback.prop.d.ts +10 -0
  116. package/dist/props/components/index.d.ts +3 -3
  117. package/dist/props/components/layout.prop.d.ts +560 -10
  118. package/dist/props/components/layout.prop.js +1 -0
  119. package/dist/props/components/navigation.prop.d.ts +24 -2
  120. package/dist/props/registry.d.ts +433 -8
  121. package/dist/props/registry.js +527 -9
  122. package/dist/props/vocabulary/data.prop.d.ts +27 -0
  123. package/dist/props/vocabulary/index.d.ts +3 -3
  124. package/dist/props/vocabulary/interaction.prop.d.ts +10 -1
  125. package/dist/props/vocabulary/layout.prop.d.ts +49 -0
  126. package/dist/styles/base.css +8 -2
  127. package/dist/styles/card-layout.css +161 -7
  128. package/dist/styles/chart-layout.css +97 -0
  129. package/dist/styles/control.css +76 -2
  130. package/dist/styles/data-display-layout.css +78 -6
  131. package/dist/styles/dialog-layout.css +105 -4
  132. package/dist/styles/fonts.css +15 -4
  133. package/dist/styles/index.css +11 -3
  134. package/dist/styles/layout.css +466 -1
  135. package/dist/styles/logo-layout.css +95 -0
  136. package/dist/styles/navigation-layout.css +152 -0
  137. package/dist/styles/shell-layout.css +790 -40
  138. package/dist/styles/table-layout.css +164 -1
  139. package/dist/theme/dxs.canonical.css +77 -0
  140. package/dist/tokens/axes.css +40 -0
  141. package/dist/tokens/base.css +6 -0
  142. package/dist/tokens/components/card.css +48 -0
  143. package/dist/tokens/components/chart.css +47 -0
  144. package/dist/tokens/components/control.css +16 -0
  145. package/dist/tokens/components/data-display.css +13 -0
  146. package/dist/tokens/components/email.css +93 -0
  147. package/dist/tokens/components/error-surface.css +36 -0
  148. package/dist/tokens/components/feedback.css +17 -0
  149. package/dist/tokens/components/legal-document.css +67 -0
  150. package/dist/tokens/components/list-row.css +43 -2
  151. package/dist/tokens/components/logo.css +74 -0
  152. package/dist/tokens/components/navigation.css +28 -0
  153. package/dist/tokens/components/sheet.css +19 -0
  154. package/dist/tokens/components/shell.css +210 -0
  155. package/dist/tokens/components/sidebar.css +33 -0
  156. package/dist/tokens/components/table.css +45 -0
  157. package/dist/tokens/foundation.css +31 -2
  158. package/dist/tokens/semantic/layout.css +69 -2
  159. package/package.json +22 -5
@@ -1,21 +1,74 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { cn } from "../../lib/utils.js";
4
- const Logo = React.forwardRef(
5
- ({ glyph = "g", size = "md", label, className, ...props }, ref) => /* @__PURE__ */ jsx(
6
- "span",
4
+ function MarkArtwork({ mark, glyph }) {
5
+ if (mark !== "godx") return /* @__PURE__ */ jsx(Fragment, { children: glyph });
6
+ return /* @__PURE__ */ jsx(
7
+ "svg",
7
8
  {
8
- ref,
9
- "data-slot": "logo",
10
- "data-size": size,
11
- className: cn("ui-logo", className),
12
- role: label ? "img" : void 0,
13
- "aria-label": label,
14
- "aria-hidden": label ? void 0 : true,
15
- ...props,
16
- children: glyph
9
+ "data-slot": "logo-artwork",
10
+ viewBox: "0 0 32 32",
11
+ width: "32",
12
+ height: "32",
13
+ focusable: "false",
14
+ "aria-hidden": "true",
15
+ children: /* @__PURE__ */ jsx(
16
+ "path",
17
+ {
18
+ fill: "currentColor",
19
+ fillRule: "evenodd",
20
+ d: "M8 7h16a7 7 0 0 1 7 7v4a7 7 0 0 1-7 7H8a7 7 0 0 1-7-7v-4a7 7 0 0 1 7-7Zm0 6a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1H8Z"
21
+ }
22
+ )
23
+ }
24
+ );
25
+ }
26
+ const Logo = React.forwardRef(
27
+ ({
28
+ glyph = "g",
29
+ mark = "glyph",
30
+ size = "md",
31
+ tone = "primary",
32
+ wordmark,
33
+ label,
34
+ className,
35
+ ...props
36
+ }, ref) => {
37
+ const hasWordmark = wordmark !== void 0 && wordmark !== null && wordmark !== false;
38
+ const identity = { "data-mark": mark, "data-size": size, "data-tone": tone };
39
+ if (hasWordmark) {
40
+ return /* @__PURE__ */ jsxs(
41
+ "span",
42
+ {
43
+ ref,
44
+ "data-slot": "logo-lockup",
45
+ ...identity,
46
+ className: cn("ui-logo-lockup", className),
47
+ role: label ? "img" : void 0,
48
+ "aria-label": label,
49
+ ...props,
50
+ children: [
51
+ /* @__PURE__ */ jsx("span", { "data-slot": "logo", ...identity, className: "ui-logo", "aria-hidden": "true", children: /* @__PURE__ */ jsx(MarkArtwork, { mark, glyph }) }),
52
+ /* @__PURE__ */ jsx("span", { "data-slot": "logo-wordmark", "data-logotype": true, className: "ui-logo-wordmark", children: wordmark })
53
+ ]
54
+ }
55
+ );
17
56
  }
18
- )
57
+ return /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ ref,
61
+ "data-slot": "logo",
62
+ ...identity,
63
+ className: cn("ui-logo", className),
64
+ role: label ? "img" : void 0,
65
+ "aria-label": label,
66
+ "aria-hidden": label ? void 0 : true,
67
+ ...props,
68
+ children: /* @__PURE__ */ jsx(MarkArtwork, { mark, glyph })
69
+ }
70
+ );
71
+ }
19
72
  );
20
73
  Logo.displayName = "Logo";
21
74
  export {
@@ -1,4 +1,4 @@
1
1
  import * as React from "react";
2
2
  import type { AppShellProp } from "../../props/components/layout.prop.js";
3
3
  export type { AppShellProp, AppShellProp as AppShellProps, } from "../../props/components/layout.prop.js";
4
- export declare function AppShell({ sidebar, topbar, topbarLeft, topbarRight, logo, breadcrumb, footer, children, sidebarCollapsed, mobileNav, mobileNavLabel, mobileNavOpen, onMobileNavOpenChange, }: AppShellProp): React.JSX.Element;
4
+ export declare function AppShell({ sidebar, topbar, topbarLeft, topbarRight, logo, breadcrumb, footer, children, sidebarCollapsed, responsiveNavigation, mobileNav, mobileNavLabel, mobileNavOpen, onMobileNavOpenChange, }: AppShellProp): React.JSX.Element;
@@ -15,6 +15,7 @@ function AppShell({
15
15
  footer,
16
16
  children,
17
17
  sidebarCollapsed = false,
18
+ responsiveNavigation = "drawer",
18
19
  mobileNav,
19
20
  mobileNavLabel,
20
21
  mobileNavOpen,
@@ -22,7 +23,7 @@ function AppShell({
22
23
  }) {
23
24
  const { t } = useTranslation();
24
25
  const drawerNav = mobileNav !== void 0 ? mobileNav : sidebar;
25
- const hasDrawer = drawerNav != null;
26
+ const hasDrawer = responsiveNavigation === "drawer" && drawerNav != null;
26
27
  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
27
28
  const drawerOpen = mobileNavOpen ?? uncontrolledOpen;
28
29
  const setDrawerOpen = onMobileNavOpenChange ?? setUncontrolledOpen;
@@ -39,35 +40,59 @@ function AppShell({
39
40
  /* @__PURE__ */ jsx("div", { className: "app-topbar-spacer" }),
40
41
  topbarRight !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-right", children: topbarRight })
41
42
  ] });
42
- return /* @__PURE__ */ jsxs("div", { className: "app-root", "data-collapsed": sidebarCollapsed ? "true" : void 0, children: [
43
- /* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar }),
44
- /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
45
- hasDrawer && /* @__PURE__ */ jsxs(Sheet, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
46
- /* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
47
- Button,
48
- {
49
- type: "button",
50
- variant: "ghost",
51
- size: "sm",
52
- className: "app-mobile-nav-trigger hidden max-[900px]:inline-flex",
53
- "aria-label": t("layout.appShell.openNav"),
54
- "aria-haspopup": "dialog",
55
- children: /* @__PURE__ */ jsx(Menu, { className: "size-5", "aria-hidden": "true" })
56
- }
57
- ) }),
58
- /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "app-mobile-nav-drawer", children: [
59
- /* @__PURE__ */ jsx(SheetHeader, { title: mobileNavLabel ?? t("layout.appShell.navLabel") }),
60
- /* @__PURE__ */ jsx(SheetBody, { className: "app-mobile-nav-body", onClick: handleDrawerClick, children: drawerNav })
61
- ] })
62
- ] }),
63
- resolvedTopbar
64
- ] }),
65
- /* @__PURE__ */ jsxs("main", { className: "app-main", "aria-label": t("layout.appShell.mainLabel"), children: [
66
- breadcrumb !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-breadcrumb", children: breadcrumb }),
67
- children
68
- ] }),
69
- footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "app-footer", "aria-label": t("layout.appShell.footerLabel"), children: footer })
70
- ] });
43
+ return /* @__PURE__ */ jsxs(
44
+ "div",
45
+ {
46
+ className: "app-root",
47
+ "data-collapsed": sidebarCollapsed ? "true" : void 0,
48
+ "data-responsive-navigation": responsiveNavigation,
49
+ children: [
50
+ /* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar }),
51
+ /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
52
+ hasDrawer && /* @__PURE__ */ jsxs(Sheet, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
53
+ /* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
54
+ Button,
55
+ {
56
+ type: "button",
57
+ variant: "ghost",
58
+ size: "sm",
59
+ className: "app-mobile-nav-trigger hidden max-[900px]:inline-flex",
60
+ "aria-label": t("layout.appShell.openNav"),
61
+ "aria-haspopup": "dialog",
62
+ children: /* @__PURE__ */ jsx(Menu, { className: "size-5", "aria-hidden": "true" })
63
+ }
64
+ ) }),
65
+ /* @__PURE__ */ jsxs(
66
+ SheetContent,
67
+ {
68
+ side: "left",
69
+ width: "var(--app-shell-mobile-nav-width)",
70
+ className: "app-mobile-nav-drawer",
71
+ overlayClassName: "app-mobile-nav-overlay",
72
+ children: [
73
+ /* @__PURE__ */ jsx(SheetHeader, { title: mobileNavLabel ?? t("layout.appShell.navLabel") }),
74
+ /* @__PURE__ */ jsx(
75
+ SheetBody,
76
+ {
77
+ className: "app-mobile-nav-body px-[var(--app-shell-mobile-nav-inset)]",
78
+ onClick: handleDrawerClick,
79
+ children: drawerNav
80
+ }
81
+ )
82
+ ]
83
+ }
84
+ )
85
+ ] }),
86
+ resolvedTopbar
87
+ ] }),
88
+ /* @__PURE__ */ jsxs("main", { className: "app-main", "aria-label": t("layout.appShell.mainLabel"), tabIndex: 0, children: [
89
+ breadcrumb !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-breadcrumb", children: breadcrumb }),
90
+ children
91
+ ] }),
92
+ footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "app-footer", "aria-label": t("layout.appShell.footerLabel"), children: footer })
93
+ ]
94
+ }
95
+ );
71
96
  }
72
97
  export {
73
98
  AppShell
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ import type { AuthAccountSummaryProp } from "../../props/components/layout.prop.js";
3
+ export type { AuthAccountSummaryProp, AuthAccountSummaryProp as AuthAccountSummaryProps, } from "../../props/components/layout.prop.js";
4
+ /** Compact, token-owned signed-in identity row for hosted auth and device authorization. */
5
+ export declare const AuthAccountSummary: React.ForwardRefExoticComponent<AuthAccountSummaryProp & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { UserRound } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ import { Avatar, AvatarFallback, AvatarImage } from "../data-display/avatar.js";
7
+ import { Button } from "../general/button.js";
8
+ const AuthAccountSummary = React.forwardRef(
9
+ ({ email, avatarSrc, avatarFallback, actionLabel, onAction, disabled, className }, ref) => /* @__PURE__ */ jsxs(
10
+ "div",
11
+ {
12
+ ref,
13
+ "data-slot": "auth-account-summary",
14
+ className: cn("ui-auth-account-summary", className),
15
+ children: [
16
+ /* @__PURE__ */ jsxs("div", { "data-slot": "auth-account-identity", className: "ui-auth-account-identity", children: [
17
+ /* @__PURE__ */ jsxs(Avatar, { className: "ui-auth-account-avatar", "aria-hidden": "true", children: [
18
+ avatarSrc ? /* @__PURE__ */ jsx(AvatarImage, { src: avatarSrc, alt: "" }) : null,
19
+ /* @__PURE__ */ jsx(AvatarFallback, { children: avatarFallback ?? /* @__PURE__ */ jsx(UserRound, { className: "ui-auth-account-fallback-icon", "aria-hidden": "true" }) })
20
+ ] }),
21
+ /* @__PURE__ */ jsx("span", { className: "ui-auth-account-email", dir: "auto", title: email, children: email })
22
+ ] }),
23
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", disabled, onClick: onAction, children: actionLabel })
24
+ ]
25
+ }
26
+ )
27
+ );
28
+ AuthAccountSummary.displayName = "AuthAccountSummary";
29
+ export {
30
+ AuthAccountSummary
31
+ };
@@ -0,0 +1,7 @@
1
+ import type { AuthDividerProp } from "../../props/components/layout.prop.js";
2
+ export type { AuthDividerProp, AuthDividerProp as AuthDividerProps, } from "../../props/components/layout.prop.js";
3
+ /**
4
+ * AuthDivider — a centred, localized conjunction between two equal separator rules. The grid
5
+ * composition keeps the label optically and geometrically centred regardless of translation.
6
+ */
7
+ export declare function AuthDivider({ label, className }: AuthDividerProp): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/utils.js";
3
+ function AuthDivider({ label, className }) {
4
+ return /* @__PURE__ */ jsxs(
5
+ "div",
6
+ {
7
+ "data-slot": "auth-divider",
8
+ className: cn("ui-auth-divider", className),
9
+ role: "separator",
10
+ "aria-label": label,
11
+ children: [
12
+ /* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" }),
13
+ /* @__PURE__ */ jsx("span", { className: "ui-auth-divider-label", "aria-hidden": "true", children: label }),
14
+ /* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" })
15
+ ]
16
+ }
17
+ );
18
+ }
19
+ export {
20
+ AuthDivider
21
+ };
@@ -0,0 +1,5 @@
1
+ import type { AuthFooterProp } from "../../props/components/layout.prop.js";
2
+ export type { AuthFooterProp } from "../../props/components/layout.prop.js";
3
+ export type { AuthFooterProp as AuthFooterProps } from "../../props/components/layout.prop.js";
4
+ /** Canonical mono legal line shared by hosted identity screens. */
5
+ export declare function AuthFooter({ product, terms, privacy, locale, className }: AuthFooterProp): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/utils.js";
3
+ const SLOTS = ["product", "terms", "privacy", "locale"];
4
+ function AuthFooter({ product, terms, privacy, locale, className }) {
5
+ const bySlot = { product, terms, privacy, locale };
6
+ const items = SLOTS.filter(
7
+ (slot) => bySlot[slot] !== null && bySlot[slot] !== void 0 && bySlot[slot] !== false
8
+ );
9
+ return /* @__PURE__ */ jsx("div", { "data-slot": "auth-legal-footer", className: cn("ui-auth-legal-footer", className), children: items.map((slot, index) => /* @__PURE__ */ jsxs(
10
+ "span",
11
+ {
12
+ "data-slot": `auth-legal-footer-${slot}`,
13
+ className: "ui-auth-legal-footer-item",
14
+ children: [
15
+ index > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ui-auth-legal-footer-separator", children: "\xB7" }) : null,
16
+ bySlot[slot]
17
+ ]
18
+ },
19
+ slot
20
+ )) });
21
+ }
22
+ export {
23
+ AuthFooter
24
+ };
@@ -0,0 +1,5 @@
1
+ import type { AuthIdentityProp } from "../../props/components/layout.prop.js";
2
+ export type { AuthIdentityProp } from "../../props/components/layout.prop.js";
3
+ export type { AuthIdentityProp as AuthIdentityProps } from "../../props/components/layout.prop.js";
4
+ /** Canonical hosted-identity mark, heading and optional real requesting-client context. */
5
+ export declare function AuthIdentity({ title, requester, className }: AuthIdentityProp): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Clock } from "lucide-react";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { Heading, Logo, Text } from "../general/index.js";
5
+ function AuthIdentity({ title, requester, className }) {
6
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "auth-identity", className: cn("ui-auth-identity", className), children: [
7
+ /* @__PURE__ */ jsx(Logo, { mark: "godx", tone: "success" }),
8
+ /* @__PURE__ */ jsx(Heading, { level: 1, children: title }),
9
+ requester !== void 0 && requester !== null ? /* @__PURE__ */ jsxs("div", { "data-slot": "auth-requester", className: "ui-auth-requester", children: [
10
+ /* @__PURE__ */ jsx("span", { "data-slot": "auth-requester-icon", className: "ui-auth-requester-icon", children: /* @__PURE__ */ jsx(Clock, { "aria-hidden": "true" }) }),
11
+ /* @__PURE__ */ jsx(Text, { as: "span", size: "xs", tone: "muted", children: requester })
12
+ ] }) : null
13
+ ] });
14
+ }
15
+ export {
16
+ AuthIdentity
17
+ };
@@ -7,5 +7,13 @@ export type { AuthShellProp, AuthShellProp as AuthShellProps, } from "../../prop
7
7
  * touch floor) and the auth heading is bumped up, so forms read at the right size — replacing a
8
8
  * consumer's `.auth-shell-*` / `.ui-auth-scope` classes. Motion is delegated to `Reveal` (wrap the
9
9
  * card) so `prefers-reduced-motion` is honoured in one place.
10
+ *
11
+ * `preset` names the flow MEASURE (card max-width + desktop/mobile page gutters) so a consumer
12
+ * never overrides page geometry by hand: `"login"` = SCR-001's stable identity/card/footer anchor
13
+ * for standalone and real requester states; `"device-authorization"` = 380px card with a 5px
14
+ * inline gutter at 390px; `"context-selection"` = 25rem card, edge-to-edge on mobile;
15
+ * `"account-recovery"` = the 432px SCR-008 panel measure shared by password recovery and the
16
+ * sign-in MFA challenge, with a 15px inline gutter at 390px. It is orthogonal to `variant` —
17
+ * combine `variant="canonical"` with any preset.
10
18
  */
11
- export declare function AuthShell({ brand, footer, children, className }: AuthShellProp): import("react").JSX.Element;
19
+ export declare function AuthShell({ brand, footer, children, variant, preset, density, className, }: AuthShellProp): import("react").JSX.Element;
@@ -2,13 +2,32 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useTranslation } from "../../i18n/use-translation.js";
4
4
  import { cn } from "../../lib/utils.js";
5
- function AuthShell({ brand, footer, children, className }) {
5
+ function AuthShell({
6
+ brand,
7
+ footer,
8
+ children,
9
+ variant = "default",
10
+ preset = "default",
11
+ density,
12
+ className
13
+ }) {
6
14
  const { t } = useTranslation();
7
- return /* @__PURE__ */ jsxs("div", { "data-slot": "auth-shell", className: cn("ui-auth-shell", className), children: [
8
- brand !== void 0 && /* @__PURE__ */ jsx("header", { className: "ui-auth-shell-bar", "aria-label": t("layout.authShell.brandLabel"), children: brand }),
9
- /* @__PURE__ */ jsx("main", { className: "ui-auth-shell-main", "aria-label": t("layout.authShell.mainLabel"), children: /* @__PURE__ */ jsx("div", { className: "ui-auth-shell-card", children }) }),
10
- footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "ui-auth-shell-footer", "aria-label": t("layout.authShell.footerLabel"), children: footer })
11
- ] });
15
+ const resolvedDensity = density ?? (variant === "canonical" ? "compact" : "comfortable");
16
+ return /* @__PURE__ */ jsxs(
17
+ "div",
18
+ {
19
+ "data-slot": "auth-shell",
20
+ "data-variant": variant,
21
+ "data-preset": preset === "default" ? void 0 : preset,
22
+ "data-density": resolvedDensity,
23
+ className: cn("ui-auth-shell", className),
24
+ children: [
25
+ brand !== void 0 && /* @__PURE__ */ jsx("header", { className: "ui-auth-shell-bar", "aria-label": t("layout.authShell.brandLabel"), children: brand }),
26
+ /* @__PURE__ */ jsx("main", { className: "ui-auth-shell-main", "aria-label": t("layout.authShell.mainLabel"), children: /* @__PURE__ */ jsx("div", { className: "ui-auth-shell-card", children }) }),
27
+ footer !== void 0 && /* @__PURE__ */ jsx("footer", { className: "ui-auth-shell-footer", "aria-label": t("layout.authShell.footerLabel"), children: footer })
28
+ ]
29
+ }
30
+ );
12
31
  }
13
32
  export {
14
33
  AuthShell
@@ -0,0 +1,4 @@
1
+ import type { HTMLAttributes } from "react";
2
+ export type AuthStackProps = HTMLAttributes<HTMLDivElement>;
3
+ /** Canonical 12px vertical rhythm for the direct sections inside an auth card. */
4
+ export declare function AuthStack({ className, ...props }: AuthStackProps): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/utils.js";
3
+ function AuthStack({ className, ...props }) {
4
+ return /* @__PURE__ */ jsx("div", { "data-slot": "auth-stack", className: cn("ui-auth-stack", className), ...props });
5
+ }
6
+ export {
7
+ AuthStack
8
+ };
@@ -14,9 +14,12 @@ export type { CenteredShellProp, CenteredShellProp as CenteredShellProps, } from
14
14
  * `.app-topbar` (padding-inline · border · backdrop) WITHOUT a sidebar, a scrollable `main` whose
15
15
  * content is a **centred column** of a configurable medium width (`width` = sm|md|lg, all wider than
16
16
  * the 24rem auth card) **top-aligned** so sections flow and scroll (not vertically centred), and an
17
- * optional footer (contentinfo). A hosted account page thus needs ZERO custom CSS and never
17
+ * optional footer (contentinfo) or, with `align="center"`, the column centred in the viewport for
18
+ * a SYSTEM-level standalone surface (a 500/503 error page, a maintenance notice), so that full-page
19
+ * geometry stays package-owned instead of a consumer re-implementing `min-h-dvh` + flex centring.
20
+ * A hosted account page thus needs ZERO custom CSS and never
18
21
  * hand-rolls a bar (the bare `Topbar` primitive ships no padding — the `.ui-topbar` zero-inset
19
22
  * footgun). Layout-only: delegate motion to `Reveal` (wrap a section) so `prefers-reduced-motion`
20
23
  * is honoured in one place.
21
24
  */
22
- export declare function CenteredShell({ topbar, footer, children, width, className, }: CenteredShellProp): import("react").JSX.Element;
25
+ export declare function CenteredShell({ topbar, footer, children, width, align, preset, className, }: CenteredShellProp): import("react").JSX.Element;
@@ -7,28 +7,38 @@ function CenteredShell({
7
7
  footer,
8
8
  children,
9
9
  width = "md",
10
+ align = "start",
11
+ preset = "default",
10
12
  className
11
13
  }) {
12
14
  const { t } = useTranslation();
13
- return /* @__PURE__ */ jsxs("div", { "data-slot": "centered-shell", className: cn("ui-centered-shell", className), children: [
14
- topbar !== void 0 && /* @__PURE__ */ jsx(
15
- "header",
16
- {
17
- className: "ui-centered-shell-bar ui-scale-fixed",
18
- "aria-label": t("layout.centeredShell.headerLabel"),
19
- children: topbar
20
- }
21
- ),
22
- /* @__PURE__ */ jsx("main", { className: "ui-centered-shell-main", "aria-label": t("layout.centeredShell.mainLabel"), children: /* @__PURE__ */ jsx("div", { className: "ui-centered-shell-column", "data-width": width, children }) }),
23
- footer !== void 0 && /* @__PURE__ */ jsx(
24
- "footer",
25
- {
26
- className: "ui-centered-shell-footer",
27
- "aria-label": t("layout.centeredShell.footerLabel"),
28
- children: footer
29
- }
30
- )
31
- ] });
15
+ return /* @__PURE__ */ jsxs(
16
+ "div",
17
+ {
18
+ "data-slot": "centered-shell",
19
+ "data-preset": preset === "default" ? void 0 : preset,
20
+ className: cn("ui-centered-shell", className),
21
+ children: [
22
+ topbar !== void 0 && /* @__PURE__ */ jsx(
23
+ "header",
24
+ {
25
+ className: "ui-centered-shell-bar ui-scale-fixed",
26
+ "aria-label": t("layout.centeredShell.headerLabel"),
27
+ children: topbar
28
+ }
29
+ ),
30
+ /* @__PURE__ */ jsx("main", { className: "ui-centered-shell-main", "aria-label": t("layout.centeredShell.mainLabel"), children: /* @__PURE__ */ jsx("div", { className: "ui-centered-shell-column", "data-width": width, "data-align": align, children }) }),
31
+ footer !== void 0 && /* @__PURE__ */ jsx(
32
+ "footer",
33
+ {
34
+ className: "ui-centered-shell-footer",
35
+ "aria-label": t("layout.centeredShell.footerLabel"),
36
+ children: footer
37
+ }
38
+ )
39
+ ]
40
+ }
41
+ );
32
42
  }
33
43
  export {
34
44
  CenteredShell
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import type { ErrorSurfaceProp } from "../../props/components/layout.prop.js";
3
+ export type { ErrorSurfaceMaintenanceProp, ErrorSurfaceProp, ErrorSurfaceProp as ErrorSurfaceProps, } from "../../props/components/layout.prop.js";
4
+ export type { ErrorSurfaceModeProp, ErrorSurfaceStatusProp } from "../../props/vocabulary/index.js";
5
+ /**
6
+ * ErrorSurface — the package-owned semantic exception surface for **403 · 404 · 500 · 503**
7
+ * (gh#221, gh#251).
8
+ *
9
+ * It exists because the alternative — every app composing `EmptyState` + `Flex` + `Text` inside a
10
+ * hand-picked shell — is unimportable: a consumer cannot `import` a docs page, so the four
11
+ * exception screens drifted per application (a generic `Card` in an `AuthShell`, a local
12
+ * `.canonical-auth-card`, a bespoke `min-h-dvh` class). What the surface owns is the CONTRACT the
13
+ * composition kept losing:
14
+ *
15
+ * - **`mode` is the shell contract.** `application` (403/404) renders the surface as the BODY you
16
+ * place inside the `AppShell` the route already provides, so the sidebar, topbar and breadcrumb
17
+ * are PRESERVED — it never reconstructs navigation chrome, because nav data and the user menu are
18
+ * consumer-owned and a component cannot manufacture them. `system` (500/503) owns the page and
19
+ * renders `CenteredShell align="center"`, so the viewport-centred geometry at 1440 / 1024 / 390
20
+ * is package-owned and the consumer writes no `min-h-dvh`, no flex-centring class, no media query.
21
+ * - **Exactly one recovery action**, structurally (see `singleAction`).
22
+ * - **Semantic metadata slots** instead of free-form paragraphs: `requestId` (mono/tabular so a
23
+ * support id is read out accurately), `permission` and `organization` (which of the two a 403 is
24
+ * actually about), and `maintenance` (ISO-8601 + IANA formatted through `Intl.DateTimeFormat`,
25
+ * with an optional labelled `Progress` meter). Each is a `<dt>`/`<dd>` pair, so the label↔value
26
+ * relationship survives for a screen reader instead of being a colon in a sentence.
27
+ * - **Valid heading order by default** — `h2` under a `PageContainer` `h1` in `application` mode,
28
+ * `h1` on a `system` page — and the status code announced as "HTTP status 403", not "403".
29
+ *
30
+ * PRODUCT COPY stays consumer-owned: `title` / `description` / `action` come from the app's own
31
+ * `t()`. The surface localizes only its OWN metadata labels. It holds no state, runs no effect and
32
+ * opens no portal, so it renders fully server-side — an exception page must be readable before
33
+ * hydration.
34
+ */
35
+ export declare const ErrorSurface: React.ForwardRefExoticComponent<ErrorSurfaceProp & React.RefAttributes<HTMLDivElement>>;