@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
@@ -48,11 +48,14 @@ export type { TreeSelectProps } from "./tree-select.js";
48
48
  export { Transfer } from "./transfer.js";
49
49
  export type { TransferProps, TransferItemProp } from "./transfer.js";
50
50
  export { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "./command.js";
51
+ export { CommandPalette } from "./command-palette.js";
52
+ export type { CommandPaletteGroup, CommandPaletteItem, CommandPaletteLabels, CommandPaletteProps, } from "./command-palette.js";
51
53
  export { PasswordInput } from "./password-input.js";
52
54
  export type { PasswordInputProps } from "./password-input.js";
53
55
  export { PasswordStrength, usePasswordStrength } from "./password-strength.js";
54
56
  export type { PasswordRule, PasswordStrengthLabels, PasswordStrengthProps, PasswordStrengthReturn, } from "./password-strength.js";
55
57
  export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "./input-otp.js";
58
+ export type { InputOTPGroupAppearanceProp, InputOTPGroupProp, InputOTPGroupProps, } from "./input-otp.js";
56
59
  export { Rating } from "./rating.js";
57
60
  export type { RatingProps } from "./rating.js";
58
61
  export { TagInput } from "./tag-input.js";
@@ -44,6 +44,7 @@ import {
44
44
  CommandItem,
45
45
  CommandList
46
46
  } from "./command.js";
47
+ import { CommandPalette } from "./command-palette.js";
47
48
  import { PasswordInput } from "./password-input.js";
48
49
  import { PasswordStrength, usePasswordStrength } from "./password-strength.js";
49
50
  import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "./input-otp.js";
@@ -61,6 +62,7 @@ export {
61
62
  CommandInput,
62
63
  CommandItem,
63
64
  CommandList,
65
+ CommandPalette,
64
66
  DatePicker,
65
67
  DateRangePicker,
66
68
  Field,
@@ -1 +1,2 @@
1
1
  export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "../ui/input-otp.js";
2
+ export type { InputOTPGroupAppearanceProp, InputOTPGroupProp, InputOTPGroupProps, } from "../ui/input-otp.js";
@@ -13,6 +13,7 @@ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitiv
13
13
  declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
14
14
  showClose?: boolean;
15
15
  showCloseButton?: boolean;
16
+ overlayClassName?: string;
16
17
  } & React.RefAttributes<HTMLDivElement>>;
17
18
  interface DialogHeaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
18
19
  title?: React.ReactNode;
@@ -34,6 +35,19 @@ declare const DialogFooter: {
34
35
  };
35
36
  declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
36
37
  declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
38
+ type AlertDialogRootProps = React.ComponentProps<typeof AlertDialogPrimitive.Root> & {};
39
+ /**
40
+ * Compound alert-dialog Root — the `role="alertdialog"` mirror of {@link DialogRoot}.
41
+ *
42
+ * The flat {@link AlertDialog} preset owns the confirm / challenge / step-up recipe and cannot be
43
+ * re-composed; this Root is what a consumer reaches for when the confirmation needs bespoke
44
+ * content. It supplies the Radix AlertDialog context that `AlertDialogTitle`,
45
+ * `AlertDialogDescription`, `AlertDialogAction` and `AlertDialogCancel` read, so the compound
46
+ * parts are assemblable from the public API alone (no direct `@radix-ui/react-alert-dialog`
47
+ * import). Focus trap, focus restoration and the modal `role="alertdialog"` semantics stay
48
+ * Radix-owned.
49
+ */
50
+ declare function AlertDialogRoot(props: AlertDialogRootProps): React.JSX.Element;
37
51
  declare const AlertDialogTrigger: React.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
38
52
  declare const AlertDialogPortal: React.FC<AlertDialogPrimitive.AlertDialogPortalProps>;
39
53
  declare const AlertDialogOverlay: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -73,6 +87,7 @@ export declare const Dialog: typeof DialogRoot & {
73
87
  Content: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
74
88
  showClose?: boolean;
75
89
  showCloseButton?: boolean;
90
+ overlayClassName?: string;
76
91
  } & React.RefAttributes<HTMLDivElement>>;
77
92
  Header: {
78
93
  ({ className, title, subtitle, extra, tone, children, ...props }: DialogHeaderProps): React.JSX.Element;
@@ -92,4 +107,4 @@ export declare const Dialog: typeof DialogRoot & {
92
107
  Action: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
93
108
  Cancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
94
109
  };
95
- export { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogDescription, DialogClose, DialogAction, DialogCancel, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, AlertDialog, };
110
+ export { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogDescription, DialogClose, DialogAction, DialogCancel, AlertDialogRoot, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, AlertDialog, };
@@ -36,39 +36,48 @@ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__P
36
36
  }
37
37
  ));
38
38
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
39
- const DialogContent = React.forwardRef(({ className, children, showClose, showCloseButton: showCloseButtonProp, ...props }, ref) => {
40
- const { t } = useTranslation();
41
- const showCloseButton = showCloseButtonProp ?? showClose ?? true;
42
- return /* @__PURE__ */ jsxs(DialogPortal, { children: [
43
- /* @__PURE__ */ jsx(DialogOverlay, {}),
44
- /* @__PURE__ */ jsxs(
45
- DialogPrimitive.Content,
46
- {
47
- ref,
48
- "data-slot": "dialog-content",
49
- className: cn(
50
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 duration-200 outline-none",
51
- className
52
- ),
53
- ...props,
54
- children: [
55
- children,
56
- showCloseButton ? /* @__PURE__ */ jsxs(
57
- DialogPrimitive.Close,
58
- {
59
- "data-slot": "dialog-close",
60
- className: "ring-offset-background focus:ring-ring transition-opacity focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
61
- children: [
62
- /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" }),
63
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("feedback.alert.dismiss") })
64
- ]
65
- }
66
- ) : null
67
- ]
68
- }
69
- )
70
- ] });
71
- });
39
+ const DialogContent = React.forwardRef(
40
+ ({
41
+ className,
42
+ children,
43
+ showClose,
44
+ showCloseButton: showCloseButtonProp,
45
+ overlayClassName,
46
+ ...props
47
+ }, ref) => {
48
+ const { t } = useTranslation();
49
+ const showCloseButton = showCloseButtonProp ?? showClose ?? true;
50
+ return /* @__PURE__ */ jsxs(DialogPortal, { children: [
51
+ /* @__PURE__ */ jsx(DialogOverlay, { className: overlayClassName }),
52
+ /* @__PURE__ */ jsxs(
53
+ DialogPrimitive.Content,
54
+ {
55
+ ref,
56
+ "data-slot": "dialog-content",
57
+ className: cn(
58
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 duration-200 outline-none",
59
+ className
60
+ ),
61
+ ...props,
62
+ children: [
63
+ children,
64
+ showCloseButton ? /* @__PURE__ */ jsxs(
65
+ DialogPrimitive.Close,
66
+ {
67
+ "data-slot": "dialog-close",
68
+ className: "ring-offset-background focus:ring-ring transition-opacity focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
69
+ children: [
70
+ /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" }),
71
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("feedback.alert.dismiss") })
72
+ ]
73
+ }
74
+ ) : null
75
+ ]
76
+ }
77
+ )
78
+ ] });
79
+ }
80
+ );
72
81
  DialogContent.displayName = "DialogContent";
73
82
  const DialogHeader = ({
74
83
  className,
@@ -123,6 +132,9 @@ const DialogDescription = React.forwardRef(({ className, ...props }, ref) => {
123
132
  );
124
133
  });
125
134
  DialogDescription.displayName = "DialogDescription";
135
+ function AlertDialogRoot(props) {
136
+ return /* @__PURE__ */ jsx(AlertDialogPrimitive.Root, { "data-slot": "dialog", ...props });
137
+ }
126
138
  const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
127
139
  const AlertDialogPortal = AlertDialogPrimitive.Portal;
128
140
  const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
@@ -372,6 +384,7 @@ export {
372
384
  AlertDialogHeader,
373
385
  AlertDialogOverlay,
374
386
  AlertDialogPortal,
387
+ AlertDialogRoot,
375
388
  AlertDialogTitle,
376
389
  AlertDialogTrigger,
377
390
  Dialog,
@@ -1,6 +1,9 @@
1
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogBody, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DialogAction, DialogCancel, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, AlertDialog, } from "./dialog.js";
1
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogBody, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DialogAction, DialogCancel, AlertDialogRoot, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, AlertDialog, } from "./dialog.js";
2
2
  export type { AlertDialogProp, AlertDialogProps } from "./dialog.js";
3
- export { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, } from "./sheet.js";
3
+ export { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, useSheetResponsiveMode, } from "./sheet.js";
4
+ export type { SheetContentProps, SheetPresentation, SheetResponsiveProp } from "./sheet.js";
5
+ export { TwoFactorSetup } from "./two-factor-setup.js";
6
+ export type { TwoFactorSetupLabels, TwoFactorSetupProps } from "./two-factor-setup.js";
4
7
  export { Toaster } from "./sonner.js";
5
8
  export { toast } from "./use-toast.js";
6
9
  export { Skeleton, SkeletonRows, SkeletonTable, SkeletonDetail, SkeletonStat } from "./skeleton.js";
@@ -12,6 +12,7 @@ import {
12
12
  DialogTrigger,
13
13
  DialogAction,
14
14
  DialogCancel,
15
+ AlertDialogRoot,
15
16
  AlertDialogTrigger,
16
17
  AlertDialogPortal,
17
18
  AlertDialogOverlay,
@@ -35,8 +36,10 @@ import {
35
36
  SheetOverlay,
36
37
  SheetPortal,
37
38
  SheetTitle,
38
- SheetTrigger
39
+ SheetTrigger,
40
+ useSheetResponsiveMode
39
41
  } from "./sheet.js";
42
+ import { TwoFactorSetup } from "./two-factor-setup.js";
40
43
  import { Toaster } from "./sonner.js";
41
44
  import { toast } from "./use-toast.js";
42
45
  import { Skeleton, SkeletonRows, SkeletonTable, SkeletonDetail, SkeletonStat } from "./skeleton.js";
@@ -63,6 +66,7 @@ export {
63
66
  AlertDialogHeader,
64
67
  AlertDialogOverlay,
65
68
  AlertDialogPortal,
69
+ AlertDialogRoot,
66
70
  AlertDialogTitle,
67
71
  AlertDialogTrigger,
68
72
  AlertQueryError,
@@ -101,5 +105,7 @@ export {
101
105
  TooltipContent,
102
106
  TooltipProvider,
103
107
  TooltipTrigger,
104
- toast
108
+ TwoFactorSetup,
109
+ toast,
110
+ useSheetResponsiveMode
105
111
  };
@@ -1,23 +1,46 @@
1
1
  import * as React from "react";
2
2
  import * as DialogPrimitive from "@radix-ui/react-dialog";
3
3
  import { type VariantProps } from "class-variance-authority";
4
+ import type { SheetResponsiveProp } from "../../props/components/feedback.prop.js";
4
5
  import type { ToneProp, WidthProp } from "../../props/vocabulary/index.js";
6
+ export type { SheetResponsiveProp } from "../../props/components/feedback.prop.js";
7
+ /** Resolved presentation of a responsive sheet: the named side panel, or the mobile bottom sheet. */
8
+ export type SheetPresentation = "side" | "bottom";
9
+ /**
10
+ * The canonical responsive-overlay decision, shared by `SheetContent` and by any composite that
11
+ * swaps a desktop surface for a mobile sheet (see `OrgSwitcher`). Returns `"bottom"` when the
12
+ * viewport is at or below `--sheet-responsive-breakpoint-width`.
13
+ *
14
+ * Public so a consumer NEVER hand-rolls `useMediaQuery("(max-width: 390px)")` in app code — the
15
+ * breakpoint stays one themeable knob for the whole system.
16
+ */
17
+ export declare function useSheetResponsiveMode(responsive?: SheetResponsiveProp): SheetPresentation;
5
18
  export declare function Sheet(props: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
6
19
  export declare function SheetTrigger(props: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element;
7
20
  export declare function SheetClose(props: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element;
8
21
  export declare function SheetPortal(props: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
9
22
  export declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
10
23
  declare const sheetVariants: (props?: ({
11
- side?: "left" | "right" | "top" | "bottom" | null | undefined;
24
+ side?: "left" | "right" | "bottom" | "top" | null | undefined;
12
25
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
- interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
26
+ export interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
14
27
  showCloseButton?: boolean;
28
+ /** Optional semantic class for the owned backdrop (for a shell-specific overlay token). */
29
+ overlayClassName?: string;
15
30
  /**
16
31
  * Desired panel size for side left/right (Ant Drawer `width`). Caps at the viewport — a small
17
32
  * screen still gets a full-width panel (`min(width, 100%)`), it is NOT a hard fixed width. Omit
18
- * to keep the default `w-3/4 sm:max-w-md`.
33
+ * to keep the canonical drawer default from `--sheet-width-default`.
19
34
  */
20
35
  width?: WidthProp;
36
+ /**
37
+ * Responsive drawer / detail-panel contract. `"side"` (default) keeps today's behaviour: the
38
+ * physical `side` the consumer named, at every viewport. `"auto"` renders the desktop side panel
39
+ * above `--sheet-responsive-breakpoint-width` and the mobile bottom sheet at/below it (capped by
40
+ * `--sheet-bottom-max-height`), so ONE `<Sheet>` covers both without a page-local media query.
41
+ * `"bottom"` pins the bottom-sheet presentation.
42
+ */
43
+ responsive?: SheetResponsiveProp;
21
44
  }
22
45
  export declare const SheetContent: React.ForwardRefExoticComponent<SheetContentProps & React.RefAttributes<HTMLDivElement>>;
23
46
  export interface SheetHeaderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
@@ -35,4 +58,3 @@ export declare const SheetBody: ({ className, ...props }: React.HTMLAttributes<H
35
58
  export declare const SheetFooter: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
36
59
  export declare const SheetTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
37
60
  export declare const SheetDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
38
- export {};
@@ -4,10 +4,38 @@ import * as React from "react";
4
4
  import * as DialogPrimitive from "@radix-ui/react-dialog";
5
5
  import { cva } from "class-variance-authority";
6
6
  import { X } from "lucide-react";
7
+ import { useMediaQuery } from "../../lib/hooks.js";
7
8
  import { cn } from "../../lib/utils.js";
8
9
  import { overlayHeaderToneClass } from "./overlay-header-tone.js";
9
10
  import { useTranslation } from "../../i18n/use-translation.js";
10
11
  const toCssLength = (v) => typeof v === "number" ? `${v}px` : v;
12
+ const SHEET_BREAKPOINT_TOKEN = "--sheet-responsive-breakpoint-width";
13
+ const SHEET_BREAKPOINT_FALLBACK_QUERY = "(max-width: 768px)";
14
+ function cssLengthToPx(value, rootFontSize) {
15
+ const match = /^(-?\d*\.?\d+)(px|rem|em)?$/.exec(value.trim());
16
+ if (match == null) return void 0;
17
+ const amount = Number(match[1]);
18
+ if (!Number.isFinite(amount)) return void 0;
19
+ return match[2] === "rem" || match[2] === "em" ? amount * rootFontSize : amount;
20
+ }
21
+ function readSheetBreakpointQuery() {
22
+ if (typeof document === "undefined" || typeof window.getComputedStyle !== "function") {
23
+ return SHEET_BREAKPOINT_FALLBACK_QUERY;
24
+ }
25
+ const rootStyle = window.getComputedStyle(document.documentElement);
26
+ const rootFontSize = cssLengthToPx(rootStyle.fontSize || "16px", 16) ?? 16;
27
+ const px = cssLengthToPx(rootStyle.getPropertyValue(SHEET_BREAKPOINT_TOKEN), rootFontSize);
28
+ return px == null ? SHEET_BREAKPOINT_FALLBACK_QUERY : `(max-width: ${String(px)}px)`;
29
+ }
30
+ function useSheetResponsiveMode(responsive = "side") {
31
+ const [query, setQuery] = React.useState(SHEET_BREAKPOINT_FALLBACK_QUERY);
32
+ React.useEffect(() => {
33
+ setQuery(readSheetBreakpointQuery());
34
+ }, []);
35
+ const compact = useMediaQuery(query);
36
+ if (responsive === "side" || responsive === "bottom") return responsive;
37
+ return compact ? "bottom" : "side";
38
+ }
11
39
  function Sheet(props) {
12
40
  return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "sheet", ...props });
13
41
  }
@@ -44,9 +72,9 @@ const sheetVariants = cva(
44
72
  // the Radix/shadcn Sheet convention. The physical classes below are intended.
45
73
  side: {
46
74
  /* rtl-ignore: named physical side */
47
- right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-md",
75
+ right: "inset-y-0 right-0 h-full w-[min(var(--sheet-width-default),100%)] max-w-none border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
48
76
  /* rtl-ignore: named physical side */
49
- left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-md",
77
+ left: "inset-y-0 left-0 h-full w-[min(var(--sheet-width-default),100%)] max-w-none border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
50
78
  top: "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
51
79
  bottom: "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom"
52
80
  }
@@ -55,23 +83,41 @@ const sheetVariants = cva(
55
83
  }
56
84
  );
57
85
  const SheetContent = React.forwardRef(
58
- ({ side = "right", className, children, showCloseButton = true, width, style, ...props }, ref) => {
86
+ ({
87
+ side = "right",
88
+ className,
89
+ children,
90
+ showCloseButton = true,
91
+ overlayClassName,
92
+ width,
93
+ responsive = "side",
94
+ style,
95
+ ...props
96
+ }, ref) => {
59
97
  const { t } = useTranslation();
60
- const horizontal = side === "left" || side === "right";
98
+ const presentation = useSheetResponsiveMode(responsive);
99
+ const resolvedSide = presentation === "bottom" ? "bottom" : side;
100
+ const bottomSheet = responsive !== "side" && presentation === "bottom";
101
+ const horizontal = resolvedSide === "left" || resolvedSide === "right";
61
102
  const widthSet = width != null && horizontal;
62
103
  const mergedStyle = widthSet ? { ...style, ["--sheet-width"]: toCssLength(width) } : style;
63
104
  return /* @__PURE__ */ jsxs(SheetPortal, { children: [
64
- /* @__PURE__ */ jsx(SheetOverlay, {}),
105
+ /* @__PURE__ */ jsx(SheetOverlay, { className: overlayClassName }),
65
106
  /* @__PURE__ */ jsxs(
66
107
  DialogPrimitive.Content,
67
108
  {
68
109
  ref,
69
110
  "data-slot": "sheet-content",
111
+ "data-responsive": responsive,
112
+ "data-side": resolvedSide,
70
113
  style: mergedStyle,
71
114
  className: cn(
72
- sheetVariants({ side }),
115
+ sheetVariants({ side: resolvedSide }),
73
116
  // `width` caps at the viewport: full-width panel on a small screen, capped on a large one.
74
117
  widthSet && "w-[min(var(--sheet-width),100%)] max-w-none sm:max-w-none",
118
+ // Only the RESPONSIVE bottom presentation is capped — a plain `side="bottom"` sheet keeps
119
+ // its content-sized height so existing usage is untouched.
120
+ bottomSheet && "max-h-[var(--sheet-bottom-max-height)]",
75
121
  className
76
122
  ),
77
123
  ...props,
@@ -193,5 +239,6 @@ export {
193
239
  SheetOverlay,
194
240
  SheetPortal,
195
241
  SheetTitle,
196
- SheetTrigger
242
+ SheetTrigger,
243
+ useSheetResponsiveMode
197
244
  };
@@ -0,0 +1,31 @@
1
+ import * as React from "react";
2
+ export type TwoFactorSetupLabels = {
3
+ title: React.ReactNode;
4
+ description: React.ReactNode;
5
+ qrLabel: string;
6
+ manualKeyLabel: React.ReactNode;
7
+ codeLabel: string;
8
+ codePlaceholder?: string;
9
+ recoveryNotice: React.ReactNode;
10
+ cancel: React.ReactNode;
11
+ confirm: React.ReactNode;
12
+ acknowledge: React.ReactNode;
13
+ };
14
+ export type TwoFactorSetupProps = {
15
+ open: boolean;
16
+ onOpenChange: (open: boolean) => void;
17
+ qrValue?: string;
18
+ manualKey: string;
19
+ code: string;
20
+ onCodeChange: (code: string) => void;
21
+ onConfirm: () => void;
22
+ recoveryCodes?: string[];
23
+ onAcknowledge: () => void;
24
+ labels: TwoFactorSetupLabels;
25
+ pending?: boolean;
26
+ };
27
+ /**
28
+ * Canonical two-factor setup overlay. Network requests and state persistence remain application
29
+ * concerns; this component only owns the QR/manual-key/OTP/recovery presentation contract.
30
+ */
31
+ export declare function TwoFactorSetup({ open, onOpenChange, qrValue, manualKey, code, onCodeChange, onConfirm, recoveryCodes, onAcknowledge, labels, pending, }: TwoFactorSetupProps): React.JSX.Element;
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { CredentialReveal } from "../data-display/credential-reveal.js";
4
+ import { QrCode } from "../data-display/qr-code.js";
5
+ import { Input } from "../data-entry/input.js";
6
+ import { Button } from "../general/button.js";
7
+ import { Text } from "../general/typography.js";
8
+ import {
9
+ Dialog,
10
+ DialogBody,
11
+ DialogContent,
12
+ DialogDescription,
13
+ DialogFooter,
14
+ DialogHeader,
15
+ DialogTitle
16
+ } from "./dialog.js";
17
+ function TwoFactorSetup({
18
+ open,
19
+ onOpenChange,
20
+ qrValue,
21
+ manualKey,
22
+ code,
23
+ onCodeChange,
24
+ onConfirm,
25
+ recoveryCodes = [],
26
+ onAcknowledge,
27
+ labels,
28
+ pending = false
29
+ }) {
30
+ const showingRecovery = recoveryCodes.length > 0;
31
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
32
+ DialogContent,
33
+ {
34
+ className: "ui-two-factor-setup",
35
+ overlayClassName: "ui-two-factor-setup-overlay",
36
+ showCloseButton: !pending,
37
+ children: [
38
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
39
+ /* @__PURE__ */ jsx(DialogTitle, { children: labels.title }),
40
+ /* @__PURE__ */ jsx(DialogDescription, { children: labels.description })
41
+ ] }),
42
+ /* @__PURE__ */ jsx(DialogBody, { children: showingRecovery ? /* @__PURE__ */ jsxs(
43
+ "section",
44
+ {
45
+ className: "ui-two-factor-setup-recovery",
46
+ "aria-live": "polite",
47
+ "data-state": "recovery",
48
+ children: [
49
+ /* @__PURE__ */ jsx(Text, { as: "p", tone: "muted", children: labels.recoveryNotice }),
50
+ /* @__PURE__ */ jsx("ul", { className: "ui-two-factor-setup-recovery-codes", children: recoveryCodes.map((recoveryCode) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: recoveryCode }) }, recoveryCode)) })
51
+ ]
52
+ }
53
+ ) : /* @__PURE__ */ jsxs("div", { className: "ui-two-factor-setup-enrollment", "data-state": "enrollment", children: [
54
+ /* @__PURE__ */ jsx(Text, { as: "p", tone: "muted", children: labels.description }),
55
+ /* @__PURE__ */ jsxs("div", { className: "ui-two-factor-setup-grid", children: [
56
+ qrValue ? /* @__PURE__ */ jsx(QrCode, { value: qrValue, label: labels.qrLabel, size: "sm" }) : null,
57
+ /* @__PURE__ */ jsxs("div", { className: "ui-two-factor-setup-fields", children: [
58
+ /* @__PURE__ */ jsx(
59
+ CredentialReveal,
60
+ {
61
+ secret: manualKey,
62
+ label: labels.manualKeyLabel,
63
+ warning: null,
64
+ defaultRevealed: true,
65
+ size: "sm"
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsxs("label", { className: "ui-two-factor-setup-code", children: [
69
+ /* @__PURE__ */ jsx(Text, { as: "span", size: "sm", weight: "medium", children: labels.codeLabel }),
70
+ /* @__PURE__ */ jsx(
71
+ Input,
72
+ {
73
+ value: code,
74
+ onChange: (event) => onCodeChange(event.target.value.replace(/\D/g, "").slice(0, 6)),
75
+ inputMode: "numeric",
76
+ autoComplete: "one-time-code",
77
+ maxLength: 6,
78
+ placeholder: labels.codePlaceholder,
79
+ "aria-label": labels.codeLabel
80
+ }
81
+ )
82
+ ] })
83
+ ] })
84
+ ] }),
85
+ /* @__PURE__ */ jsx(Text, { as: "p", size: "sm", tone: "muted", className: "ui-two-factor-setup-notice", children: labels.recoveryNotice })
86
+ ] }) }),
87
+ /* @__PURE__ */ jsx(DialogFooter, { children: showingRecovery ? /* @__PURE__ */ jsx(Button, { onClick: onAcknowledge, children: labels.acknowledge }) : /* @__PURE__ */ jsxs(Fragment, { children: [
88
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: pending, children: labels.cancel }),
89
+ /* @__PURE__ */ jsx(Button, { onClick: onConfirm, disabled: pending || code.length !== 6, loading: pending, children: labels.confirm })
90
+ ] }) })
91
+ ]
92
+ }
93
+ ) });
94
+ }
95
+ export {
96
+ TwoFactorSetup
97
+ };
@@ -3,6 +3,6 @@ export type { ButtonProps } from "./button.js";
3
3
  export { Text, Heading } from "./typography.js";
4
4
  export type { TextProps, HeadingProps, TextProp, HeadingProp } from "./typography.js";
5
5
  export { Logo } from "./logo.js";
6
- export type { LogoProps, LogoSize } from "./logo.js";
6
+ export type { LogoMark, LogoProps, LogoSize, LogoTone } from "./logo.js";
7
7
  export { Reveal } from "./reveal.js";
8
8
  export type { RevealProp, RevealProps } from "./reveal.js";
@@ -1,27 +1,67 @@
1
1
  import * as React from "react";
2
2
  export type LogoSize = "xs" | "sm" | "md" | "lg";
3
+ export type LogoTone = "primary" | "success";
4
+ export type LogoMark = "glyph" | "godx";
3
5
  export interface LogoProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
4
6
  /**
5
7
  * The brand glyph — a short mark (a letter/initials, default `"g"`) or a custom node such as an
6
8
  * inline `<svg>`. Keep it to 1–2 glyphs; the box is square and centres its content.
7
9
  */
8
10
  glyph?: React.ReactNode;
9
- /** Box size tier (tokenised). Default `"md"` (1.75rem). */
11
+ /**
12
+ * Semantic mark artwork. `"godx"` renders the canonical GoDX identity mark as an inline vector;
13
+ * `"glyph"` preserves the configurable boxed-glyph treatment.
14
+ */
15
+ mark?: LogoMark;
16
+ /**
17
+ * Box size tier (tokenised), applied to EVERY mark. The boxed glyph reads `--logo-size-*`
18
+ * (default `md` = 1.75rem); `mark="godx"` reads its own `--logo-godx-size-*` scale (default `md`
19
+ * = 2rem — the identity artwork is a capsule in a square viewBox and needs slightly more box to
20
+ * read at the same optical weight). On a `wordmark` lockup the tier scales the mark and the
21
+ * wordmark together. A theme pins the identity box at every tier with `--logo-godx-size`.
22
+ */
10
23
  size?: LogoSize;
24
+ /**
25
+ * Semantic fill role. `"success"` provides the canonical green identity mark without changing
26
+ * the application's primary action colour. Default `"primary"` preserves existing behaviour.
27
+ */
28
+ tone?: LogoTone;
29
+ /**
30
+ * Readable product name rendered BESIDE the mark as one lockup. Pass the localized product name
31
+ * (a string, or a node when the name needs its own markup). When set, `Logo` renders
32
+ * `mark + wordmark` in a single inline-flex lockup: the mark becomes decorative and the wordmark
33
+ * carries the accessible name, so the pair is announced once. The wordmark reads
34
+ * `--logo-wordmark-*` tokens — its colour defaults to the identity role for the GoDX/`success`
35
+ * lockup and NEVER to `--primary`, so a re-themed action colour cannot recolour the brand.
36
+ * Omit for the bare mark (today's behaviour, unchanged).
37
+ *
38
+ * NOTE: the library ships no wordmark ARTWORK — the wordmark is set in the design-system
39
+ * typeface (`--logo-wordmark-font-family`, default `--font-family-display`). Pass an inline
40
+ * `<svg>` here when a real logotype asset exists.
41
+ */
42
+ wordmark?: React.ReactNode;
11
43
  /**
12
44
  * Accessible name for the mark. When set, the logo is exposed to assistive tech as an image with
13
45
  * this name; when omitted the mark is decorative (`aria-hidden`) — the correct default when a
14
- * readable wordmark sits beside it.
46
+ * readable wordmark sits beside it. With `wordmark` set, `label` overrides the lockup's
47
+ * accessible name (the wordmark text is otherwise the name).
15
48
  */
16
49
  label?: string;
17
50
  }
18
51
  /**
19
- * Logo — the product brand-mark box: a glyph on the primary fill. Use it INSTEAD of hand-rolling a
20
- * bare span with a fixed square size, a literal radius, and `bg-primary` + type utilities in shell
21
- * headers, auth screens, and topbars that repeats literal size/radius and puts type utilities on
22
- * a bare span (rules #45/#46). Size, radius, and per-tier font-size are tokens; the fill reads the
23
- * primary role, so a re-themed `--primary` re-tints the mark automatically. Pair with a wordmark for
24
- * the full lockup (leave `label` unset so the mark stays decorative and the wordmark carries the
25
- * accessible name).
52
+ * Logo — the product brand-mark box: a glyph on the primary fill, or (with `wordmark`) the full
53
+ * mark + wordmark LOCKUP. Use it INSTEAD of hand-rolling a bare span with a fixed square size, a
54
+ * literal radius, and `bg-primary` + type utilities in shell headers, auth screens, and topbars —
55
+ * that repeats literal size/radius and puts type utilities on a bare span (rules #45/#46). Size,
56
+ * radius, per-tier font-size, the wordmark's face/weight/tracking/colour and the mark↔wordmark gap
57
+ * are all tokens.
58
+ *
59
+ * COLOUR: the boxed glyph fill reads the primary role, so a re-themed `--primary` re-tints it.
60
+ * `mark="godx"` / `tone="success"` instead read the IDENTITY tokens (`--logo-godx-color`,
61
+ * `--logo-success-*`, `--logo-wordmark-color`), which never reference `--primary` — the canonical
62
+ * brand-green GoDX lockup therefore survives any action-colour re-theme with zero consumer CSS.
63
+ *
64
+ * A11Y: with a `wordmark`, the mark is decorative and the wordmark text carries the accessible
65
+ * name (announced once). Without one, set `label` when the mark stands alone.
26
66
  */
27
67
  export declare const Logo: React.ForwardRefExoticComponent<LogoProps & React.RefAttributes<HTMLSpanElement>>;