@questpie/admin 3.5.3 → 3.5.5

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 (141) hide show
  1. package/README.md +8 -0
  2. package/dist/client/blocks/block-renderer.d.mts +2 -2
  3. package/dist/client/builder/index.d.mts +1 -1
  4. package/dist/client/builder/types/collection-types.d.mts +80 -5
  5. package/dist/client/builder/types/common.d.mts +5 -0
  6. package/dist/client/builder/types/field-types.d.mts +41 -1
  7. package/dist/client/builder/view/view.d.mts +3 -2
  8. package/dist/client/components/admin-link.d.mts +2 -2
  9. package/dist/client/components/fields/boolean-field.mjs +2 -1
  10. package/dist/client/components/fields/date-field.mjs +2 -1
  11. package/dist/client/components/fields/datetime-field.mjs +2 -1
  12. package/dist/client/components/fields/email-field.mjs +2 -1
  13. package/dist/client/components/fields/field-utils.d.mts +11 -0
  14. package/dist/client/components/fields/field-utils.mjs +3 -1
  15. package/dist/client/components/fields/field-wrapper.mjs +3 -3
  16. package/dist/client/components/fields/number-field.mjs +2 -1
  17. package/dist/client/components/fields/object-field.mjs +2 -1
  18. package/dist/client/components/fields/relation/displays/types.mjs +3 -3
  19. package/dist/client/components/fields/rich-text-editor/extensions.mjs +2 -1
  20. package/dist/client/components/fields/rich-text-editor/image-popover.mjs +6 -2
  21. package/dist/client/components/fields/rich-text-editor/image-upload.mjs +2 -1
  22. package/dist/client/components/fields/rich-text-editor/index.d.mts +3 -2
  23. package/dist/client/components/fields/rich-text-editor/index.mjs +4 -3
  24. package/dist/client/components/fields/select-field.mjs +2 -1
  25. package/dist/client/components/fields/text-field.mjs +2 -1
  26. package/dist/client/components/fields/textarea-field.mjs +2 -1
  27. package/dist/client/components/fields/time-field.mjs +2 -1
  28. package/dist/client/components/layout/field-layout-renderer.mjs +4 -4
  29. package/dist/client/components/media/media-grid.mjs +2 -1
  30. package/dist/client/components/primitives/asset-preview.mjs +4 -2
  31. package/dist/client/components/primitives/dropzone.d.mts +100 -0
  32. package/dist/client/components/primitives/field-select-control.mjs +2 -1
  33. package/dist/client/components/ui/button.d.mts +23 -0
  34. package/dist/client/components/ui/button.mjs +2 -2
  35. package/dist/client/components/ui/dropdown-menu.d.mts +49 -0
  36. package/dist/client/components/ui/dropdown-menu.mjs +22 -1
  37. package/dist/client/components/ui/popover.mjs +1 -1
  38. package/dist/client/components/ui/search-input.d.mts +56 -0
  39. package/dist/client/components/ui/select.mjs +2 -2
  40. package/dist/client/components/ui/sheet.d.mts +40 -0
  41. package/dist/client/components/ui/table.d.mts +49 -0
  42. package/dist/client/components/ui/table.mjs +15 -1
  43. package/dist/client/components/ui/tooltip.d.mts +21 -0
  44. package/dist/client/contexts/focus-context.d.mts +2 -2
  45. package/dist/client/hooks/use-admin-config.mjs +20 -1
  46. package/dist/client/hooks/use-autosave.mjs +91 -0
  47. package/dist/client/hooks/use-collection.mjs +65 -23
  48. package/dist/client/hooks/use-upload.d.mts +40 -0
  49. package/dist/client/hooks/use-upload.mjs +4 -2
  50. package/dist/client/i18n/hooks.d.mts +20 -0
  51. package/dist/client/lib/utils.d.mts +6 -0
  52. package/dist/client/preview/block-scope-context.d.mts +2 -2
  53. package/dist/client/preview/preview-banner.d.mts +2 -2
  54. package/dist/client/preview/preview-field.d.mts +4 -4
  55. package/dist/client/runtime/provider.mjs +22 -3
  56. package/dist/client/scope/picker.d.mts +2 -2
  57. package/dist/client/scope/provider.d.mts +2 -2
  58. package/dist/client/styles/base.css +22 -18
  59. package/dist/client/utils/asset-url.mjs +27 -0
  60. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  61. package/dist/client/views/auth/auth-layout.d.mts +3 -3
  62. package/dist/client/views/auth/forgot-password-form.d.mts +2 -2
  63. package/dist/client/views/auth/login-form.d.mts +2 -2
  64. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  65. package/dist/client/views/auth/setup-form.d.mts +2 -2
  66. package/dist/client/views/collection/auto-form-fields.mjs +4 -4
  67. package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +7 -0
  68. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +3 -2
  69. package/dist/client/views/collection/cells/shared/cell-helpers.mjs +3 -2
  70. package/dist/client/views/collection/cells/upload-cells.mjs +2 -1
  71. package/dist/client/views/collection/document-view.d.mts +30 -0
  72. package/dist/client/views/collection/document-view.mjs +377 -0
  73. package/dist/client/views/collection/field-context.mjs +3 -2
  74. package/dist/client/views/collection/field-renderer.mjs +2 -2
  75. package/dist/client/views/collection/form-view.mjs +14 -80
  76. package/dist/client/views/collection/list-view.mjs +19 -15
  77. package/dist/client/views/collection/table-view.mjs +1 -1
  78. package/dist/client/views/layout/admin-layout-provider.mjs +4 -3
  79. package/dist/client/views/layout/admin-layout.mjs +107 -20
  80. package/dist/client/views/layout/admin-router.mjs +19 -3
  81. package/dist/client/views/layout/admin-sidebar.mjs +50 -6
  82. package/dist/client/views/layout/admin-view-layout.d.mts +36 -0
  83. package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
  84. package/dist/client/views/pages/dashboard-page.d.mts +2 -2
  85. package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
  86. package/dist/client/views/pages/invite-page.d.mts +2 -2
  87. package/dist/client/views/pages/login-page.d.mts +2 -2
  88. package/dist/client/views/pages/reset-password-page.d.mts +2 -2
  89. package/dist/client/views/pages/setup-page.d.mts +2 -2
  90. package/dist/client.d.mts +17 -2
  91. package/dist/client.mjs +16 -1
  92. package/dist/components/rich-text/rich-text-renderer.d.mts +2 -2
  93. package/dist/factories.d.mts +2 -2
  94. package/dist/factories.mjs +2 -2
  95. package/dist/index.d.mts +17 -3
  96. package/dist/index.mjs +16 -1
  97. package/dist/server/augmentation/actions.d.mts +5 -0
  98. package/dist/server/augmentation/form-layout.d.mts +5 -0
  99. package/dist/server/augmentation/views.d.mts +4 -1
  100. package/dist/server/fields/blocks.mjs +4 -1
  101. package/dist/server/fields/reactive-runtime.mjs +3 -0
  102. package/dist/server/modules/admin/.generated/module.d.mts +1 -1
  103. package/dist/server/modules/admin/auth-helpers.mjs +7 -1
  104. package/dist/server/modules/admin/block/introspection.mjs +28 -4
  105. package/dist/server/modules/admin/block/prefetch.d.mts +11 -0
  106. package/dist/server/modules/admin/block/prefetch.mjs +108 -27
  107. package/dist/server/modules/admin/client/.generated/module.d.mts +68 -67
  108. package/dist/server/modules/admin/client/.generated/module.mjs +2 -0
  109. package/dist/server/modules/admin/client/views/collection-document.d.mts +6 -0
  110. package/dist/server/modules/admin/client/views/collection-document.mjs +10 -0
  111. package/dist/server/modules/admin/collections/account.d.mts +46 -46
  112. package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -57
  113. package/dist/server/modules/admin/collections/admin-preferences.d.mts +42 -42
  114. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -50
  115. package/dist/server/modules/admin/collections/apikey.d.mts +79 -71
  116. package/dist/server/modules/admin/collections/assets.d.mts +42 -42
  117. package/dist/server/modules/admin/collections/session.d.mts +45 -45
  118. package/dist/server/modules/admin/collections/user.d.mts +66 -66
  119. package/dist/server/modules/admin/collections/verification.d.mts +39 -39
  120. package/dist/server/modules/admin/dto/admin-config.dto.mjs +34 -4
  121. package/dist/server/modules/admin/factories.mjs +4 -34
  122. package/dist/server/modules/admin/routes/admin-config.d.mts +3 -2
  123. package/dist/server/modules/admin/routes/admin-config.mjs +18 -2
  124. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  125. package/dist/server/modules/admin/routes/execute-action.mjs +10 -4
  126. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  127. package/dist/server/modules/admin/routes/locales.mjs +1 -1
  128. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  129. package/dist/server/modules/admin/routes/preview.mjs +6 -5
  130. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  131. package/dist/server/modules/admin/routes/reactive.mjs +2 -2
  132. package/dist/server/modules/admin/routes/route-helpers.mjs +1 -1
  133. package/dist/server/modules/admin/routes/setup.d.mts +7 -7
  134. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  135. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  136. package/dist/server/modules/admin/routes/widget-data.mjs +1 -1
  137. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
  138. package/dist/server/plugin.mjs +8 -3
  139. package/dist/server/proxy-factories.d.mts +8 -1
  140. package/dist/server/proxy-factories.mjs +33 -1
  141. package/package.json +4 -4
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../../lib/utils.mjs";
2
2
  import { Button } from "../ui/button.mjs";
3
+ import { resolveAssetUrl } from "../../utils/asset-url.mjs";
3
4
  import { Skeleton } from "../ui/skeleton.mjs";
4
5
  import { Icon } from "@iconify/react";
5
6
  import * as React from "react";
@@ -76,13 +77,14 @@ function AssetPreview({ asset, pendingFile, onRemove, onEdit, loading = false, p
76
77
  const isImageType = isImage(mimeType);
77
78
  const fileIconName = getFileIconName(mimeType);
78
79
  const extension = getExtension(filename, mimeType);
80
+ const assetUrl = resolveAssetUrl(asset.url);
79
81
  const thumbnailUrl = React.useMemo(() => {
80
82
  if (pendingFile && isImageType) return URL.createObjectURL(pendingFile);
81
- if (asset.url && isImageType) return asset.url;
83
+ if (assetUrl && isImageType) return assetUrl;
82
84
  return null;
83
85
  }, [
84
86
  pendingFile,
85
- asset.url,
87
+ assetUrl,
86
88
  isImageType
87
89
  ]);
88
90
  React.useEffect(() => {
@@ -0,0 +1,100 @@
1
+ import * as React from "react";
2
+ import * as react_jsx_runtime11 from "react/jsx-runtime";
3
+
4
+ //#region src/client/components/primitives/dropzone.d.ts
5
+
6
+ interface DropzoneProps {
7
+ /**
8
+ * Called when files are dropped or selected
9
+ */
10
+ onDrop: (files: File[]) => void;
11
+ /**
12
+ * Accepted file types (MIME types or extensions)
13
+ * @example ["image/*", "application/pdf", ".doc"]
14
+ */
15
+ accept?: string[];
16
+ /**
17
+ * Maximum file size in bytes
18
+ */
19
+ maxSize?: number;
20
+ /**
21
+ * Whether multiple files can be selected
22
+ * @default false
23
+ */
24
+ multiple?: boolean;
25
+ /**
26
+ * Disable the dropzone
27
+ */
28
+ disabled?: boolean;
29
+ /**
30
+ * Show loading state (e.g., during upload)
31
+ */
32
+ loading?: boolean;
33
+ /**
34
+ * Current upload progress (0-100)
35
+ */
36
+ progress?: number;
37
+ /**
38
+ * Visual density of the dropzone.
39
+ * @default "panel"
40
+ */
41
+ variant?: "panel" | "compact";
42
+ /**
43
+ * Custom label text
44
+ * @default "Drop files here or click to browse"
45
+ */
46
+ label?: string;
47
+ /**
48
+ * Helper text shown below the label
49
+ */
50
+ hint?: string;
51
+ /**
52
+ * Error message to display
53
+ */
54
+ error?: string;
55
+ /**
56
+ * Additional className
57
+ */
58
+ className?: string;
59
+ /**
60
+ * Children to render inside the dropzone (custom content)
61
+ */
62
+ children?: React.ReactNode;
63
+ /**
64
+ * Secondary action rendered inside the dropzone.
65
+ */
66
+ action?: {
67
+ label: string;
68
+ icon?: string;
69
+ onClick: () => void;
70
+ disabled?: boolean;
71
+ };
72
+ /**
73
+ * Callback when validation fails
74
+ */
75
+ onValidationError?: (errors: ValidationError[]) => void;
76
+ }
77
+ interface ValidationError {
78
+ file: File;
79
+ type: "type" | "size";
80
+ message: string;
81
+ }
82
+ declare function Dropzone({
83
+ onDrop,
84
+ accept,
85
+ maxSize,
86
+ multiple,
87
+ disabled,
88
+ loading,
89
+ progress,
90
+ variant,
91
+ label,
92
+ hint,
93
+ error,
94
+ className,
95
+ children,
96
+ action,
97
+ onValidationError
98
+ }: DropzoneProps): react_jsx_runtime11.JSX.Element;
99
+ //#endregion
100
+ export { Dropzone };
@@ -6,9 +6,10 @@ import { InputGroup } from "../ui/input-group.mjs";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
 
8
8
  //#region src/client/components/primitives/field-select-control.tsx
9
- function FieldSelectTrigger({ className, hasValue, asInputGroupControl, ...props }) {
9
+ function FieldSelectTrigger({ className, hasValue, asInputGroupControl, static: staticPress = true, ...props }) {
10
10
  return /* @__PURE__ */ jsx(Button, {
11
11
  variant: "outline",
12
+ static: staticPress,
12
13
  "data-slot": asInputGroupControl ? "input-group-control" : void 0,
13
14
  className: cn("qa-field-select-control qa-select-single control-surface w-full justify-between px-3 py-2 font-normal", "hover:bg-surface-low focus-visible:border-border-strong focus-visible:ring-ring/20 aria-expanded:border-border-strong aria-expanded:ring-ring/20 focus-visible:ring-[3px] aria-expanded:ring-[3px]", !hasValue && "text-muted-foreground", asInputGroupControl && "h-full min-w-0 flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0", className),
14
15
  ...props
@@ -0,0 +1,23 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { Button } from "@base-ui/react/button";
3
+ import { VariantProps } from "class-variance-authority";
4
+ import * as class_variance_authority_types0 from "class-variance-authority/types";
5
+
6
+ //#region src/client/components/ui/button.d.ts
7
+ declare const buttonVariants: (props?: ({
8
+ variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
9
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
10
+ } & class_variance_authority_types0.ClassProp) | undefined) => string;
11
+ type ButtonProps = Button.Props & VariantProps<typeof buttonVariants> & {
12
+ static?: boolean;
13
+ };
14
+ declare function Button$1({
15
+ className,
16
+ type,
17
+ variant,
18
+ size,
19
+ static: staticPress,
20
+ ...props
21
+ }: ButtonProps): react_jsx_runtime0.JSX.Element;
22
+ //#endregion
23
+ export { Button$1 as Button };
@@ -6,7 +6,7 @@ import { Button } from "@base-ui/react/button";
6
6
  import { cva } from "class-variance-authority";
7
7
 
8
8
  //#region src/client/components/ui/button.tsx
9
- const buttonVariants = cva("qa-button font-chrome group/button text-foreground focus-visible:border-border-strong focus-visible:ring-ring/20 aria-invalid:border-border-strong aria-invalid:ring-ring/20 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--control-radius)] border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-[background-color,color,border-color,box-shadow,transform,opacity] duration-150 ease-out outline-none select-none focus-visible:ring-[3px] active:scale-[0.96] disabled:pointer-events-none disabled:opacity-50 disabled:active:scale-100 aria-invalid:ring-[3px] motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
9
+ const buttonVariants = cva("qa-button font-chrome group/button text-foreground focus-visible:border-border-strong focus-visible:ring-ring/20 aria-invalid:border-border-strong aria-invalid:ring-ring/20 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--control-radius)] border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-[background-color,color,border-color,box-shadow,transform,opacity] duration-150 ease-out outline-none select-none focus-visible:ring-[3px] active:translate-y-px disabled:pointer-events-none disabled:opacity-50 disabled:active:translate-y-0 aria-invalid:ring-[3px] motion-reduce:active:translate-y-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
10
10
  variants: {
11
11
  variant: {
12
12
  default: "bg-primary text-primary-foreground shadow-[var(--control-shadow)] hover:opacity-95",
@@ -39,7 +39,7 @@ function Button$1({ className, type = "button", variant = "default", size = "def
39
39
  className: cn(buttonVariants({
40
40
  variant,
41
41
  size
42
- }), staticPress && "active:scale-100", className),
42
+ }), staticPress && "active:translate-y-0", className),
43
43
  ...props
44
44
  });
45
45
  }
@@ -0,0 +1,49 @@
1
+ import * as React from "react";
2
+ import * as react_jsx_runtime18 from "react/jsx-runtime";
3
+ import { Menu } from "@base-ui/react/menu";
4
+
5
+ //#region src/client/components/ui/dropdown-menu.d.ts
6
+ declare function DropdownMenu({
7
+ ...props
8
+ }: Menu.Root.Props): react_jsx_runtime18.JSX.Element;
9
+ declare function DropdownMenuTrigger({
10
+ type,
11
+ ...props
12
+ }: Menu.Trigger.Props): react_jsx_runtime18.JSX.Element;
13
+ declare function DropdownMenuContent({
14
+ align,
15
+ alignOffset,
16
+ side,
17
+ sideOffset,
18
+ className,
19
+ ...props
20
+ }: Menu.Popup.Props & Pick<Menu.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): react_jsx_runtime18.JSX.Element;
21
+ declare function DropdownMenuGroup({
22
+ ...props
23
+ }: Menu.Group.Props): react_jsx_runtime18.JSX.Element;
24
+ declare function DropdownMenuLabel({
25
+ className,
26
+ inset,
27
+ ...props
28
+ }: React.ComponentProps<"div"> & {
29
+ inset?: boolean;
30
+ }): react_jsx_runtime18.JSX.Element;
31
+ declare function DropdownMenuItem({
32
+ className,
33
+ inset,
34
+ variant,
35
+ ...props
36
+ }: Menu.Item.Props & {
37
+ inset?: boolean;
38
+ variant?: "default" | "destructive";
39
+ }): react_jsx_runtime18.JSX.Element;
40
+ declare function DropdownMenuSeparator({
41
+ className,
42
+ ...props
43
+ }: Menu.Separator.Props): react_jsx_runtime18.JSX.Element;
44
+ declare function DropdownMenuShortcut({
45
+ className,
46
+ ...props
47
+ }: React.ComponentProps<"span">): react_jsx_runtime18.JSX.Element;
48
+ //#endregion
49
+ export { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger };
@@ -33,6 +33,20 @@ function DropdownMenuContent({ align = "start", alignOffset = 0, side = "bottom"
33
33
  })
34
34
  }) });
35
35
  }
36
+ function DropdownMenuGroup({ ...props }) {
37
+ return /* @__PURE__ */ jsx(Menu.Group, {
38
+ "data-slot": "dropdown-menu-group",
39
+ ...props
40
+ });
41
+ }
42
+ function DropdownMenuLabel({ className, inset, ...props }) {
43
+ return /* @__PURE__ */ jsx("div", {
44
+ "data-slot": "dropdown-menu-label",
45
+ "data-inset": inset,
46
+ className: cn("qa-dropdown-menu__label text-muted-foreground font-chrome chrome-meta px-2.5 py-1.5 text-xs font-medium data-[inset]:pl-8", className),
47
+ ...props
48
+ });
49
+ }
36
50
  function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
37
51
  return /* @__PURE__ */ jsx(Menu.Item, {
38
52
  "data-slot": "dropdown-menu-item",
@@ -78,6 +92,13 @@ function DropdownMenuSeparator({ className, ...props }) {
78
92
  ...props
79
93
  });
80
94
  }
95
+ function DropdownMenuShortcut({ className, ...props }) {
96
+ return /* @__PURE__ */ jsx("span", {
97
+ "data-slot": "dropdown-menu-shortcut",
98
+ className: cn("qa-dropdown-menu__shortcut text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground font-chrome chrome-meta ml-auto text-[0.625rem]", className),
99
+ ...props
100
+ });
101
+ }
81
102
 
82
103
  //#endregion
83
- export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
104
+ export { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
@@ -25,7 +25,7 @@ function PopoverContent({ className, align = "center", alignOffset = 0, side = "
25
25
  className: "isolate z-50",
26
26
  children: /* @__PURE__ */ jsx(Popover.Popup, {
27
27
  "data-slot": "popover-content",
28
- className: cn("qa-popover__content floating-surface motion-floating text-popover-foreground z-50 flex min-w-48 origin-(--transform-origin) flex-col gap-4 p-2.5 text-xs outline-hidden data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
28
+ className: cn("qa-popover__content floating-surface motion-floating text-popover-foreground z-50 flex min-w-48 origin-(--transform-origin) flex-col gap-4 overflow-hidden p-2.5 text-xs outline-hidden data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
29
29
  ...props
30
30
  })
31
31
  }) });
@@ -0,0 +1,56 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/client/components/ui/search-input.d.ts
4
+ interface SearchInputProps extends Omit<React.ComponentProps<"input">, "type"> {
5
+ /**
6
+ * Keyboard shortcut to display (e.g., "⌘K")
7
+ */
8
+ shortcut?: string;
9
+ /**
10
+ * Callback when clear button is clicked
11
+ */
12
+ onClear?: () => void;
13
+ /**
14
+ * Show loading spinner instead of search icon
15
+ */
16
+ isLoading?: boolean;
17
+ /**
18
+ * Additional className for the container
19
+ */
20
+ containerClassName?: string;
21
+ }
22
+ /**
23
+ * SearchInput - Consistent search input with icon, loading state, clear button, and keyboard shortcut
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * // Basic usage
28
+ * <SearchInput
29
+ * value={searchTerm}
30
+ * onChange={(e) => setSearchTerm(e.target.value)}
31
+ * onClear={() => setSearchTerm("")}
32
+ * placeholder="Search..."
33
+ * />
34
+ *
35
+ * // With keyboard shortcut
36
+ * <SearchInput
37
+ * shortcut="⌘K"
38
+ * onClick={openSearchDialog}
39
+ * readOnly
40
+ * />
41
+ *
42
+ * // Loading state
43
+ * <SearchInput isLoading={isSearching} ... />
44
+ * ```
45
+ */
46
+ declare function SearchInput({
47
+ shortcut,
48
+ onClear,
49
+ isLoading,
50
+ containerClassName,
51
+ className,
52
+ value,
53
+ ...props
54
+ }: SearchInputProps): React.ReactElement;
55
+ //#endregion
56
+ export { SearchInput };
@@ -10,7 +10,7 @@ const Select$1 = Select.Root;
10
10
  function SelectGroup({ className, ...props }) {
11
11
  return /* @__PURE__ */ jsx(Select.Group, {
12
12
  "data-slot": "select-group",
13
- className: cn("qa-select__group scroll-my-1 p-1", className),
13
+ className: cn("qa-select__group scroll-my-1 p-0", className),
14
14
  ...props
15
15
  });
16
16
  }
@@ -44,7 +44,7 @@ function SelectContent({ className, children, side = "bottom", sideOffset = 4, a
44
44
  className: "isolate z-50",
45
45
  children: /* @__PURE__ */ jsxs(Select.Popup, {
46
46
  "data-slot": "select-content",
47
- className: cn("qa-select__content floating-surface motion-floating text-popover-foreground relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
47
+ className: cn("qa-select__content floating-surface motion-floating text-popover-foreground relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto p-1 data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
48
48
  ...props,
49
49
  children: [
50
50
  /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
@@ -0,0 +1,40 @@
1
+ import * as React from "react";
2
+ import * as react_jsx_runtime12 from "react/jsx-runtime";
3
+ import { Dialog } from "@base-ui/react/dialog";
4
+
5
+ //#region src/client/components/ui/sheet.d.ts
6
+ declare function Sheet({
7
+ ...props
8
+ }: Dialog.Root.Props): react_jsx_runtime12.JSX.Element;
9
+ declare function SheetContent({
10
+ className,
11
+ children,
12
+ side,
13
+ showCloseButton,
14
+ animated,
15
+ showOverlay,
16
+ ...props
17
+ }: Dialog.Popup.Props & {
18
+ side?: "top" | "right" | "bottom" | "left";
19
+ showCloseButton?: boolean;
20
+ animated?: boolean;
21
+ showOverlay?: boolean;
22
+ }): react_jsx_runtime12.JSX.Element;
23
+ declare function SheetHeader({
24
+ className,
25
+ ...props
26
+ }: React.ComponentProps<"div">): react_jsx_runtime12.JSX.Element;
27
+ declare function SheetFooter({
28
+ className,
29
+ ...props
30
+ }: React.ComponentProps<"div">): react_jsx_runtime12.JSX.Element;
31
+ declare function SheetTitle({
32
+ className,
33
+ ...props
34
+ }: Dialog.Title.Props): react_jsx_runtime12.JSX.Element;
35
+ declare function SheetDescription({
36
+ className,
37
+ ...props
38
+ }: Dialog.Description.Props): react_jsx_runtime12.JSX.Element;
39
+ //#endregion
40
+ export { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle };
@@ -0,0 +1,49 @@
1
+ import * as React from "react";
2
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
3
+
4
+ //#region src/client/components/ui/table.d.ts
5
+ declare function Table({
6
+ className,
7
+ ...props
8
+ }: React.ComponentProps<"table">): react_jsx_runtime1.JSX.Element;
9
+ declare function TableHeader({
10
+ className,
11
+ ...props
12
+ }: React.ComponentProps<"thead">): react_jsx_runtime1.JSX.Element;
13
+ declare function TableBody({
14
+ className,
15
+ ...props
16
+ }: React.ComponentProps<"tbody">): react_jsx_runtime1.JSX.Element;
17
+ declare function TableFooter({
18
+ className,
19
+ ...props
20
+ }: React.ComponentProps<"tfoot">): react_jsx_runtime1.JSX.Element;
21
+ declare const TableRow: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>, "ref"> & React.RefAttributes<HTMLTableRowElement>>;
22
+ interface TableHeadProps extends React.ComponentProps<"th"> {
23
+ stickyLeft?: number;
24
+ showStickyBorder?: boolean;
25
+ }
26
+ declare function TableHead({
27
+ className,
28
+ stickyLeft,
29
+ showStickyBorder,
30
+ style,
31
+ ...props
32
+ }: TableHeadProps): react_jsx_runtime1.JSX.Element;
33
+ interface TableCellProps extends React.ComponentProps<"td"> {
34
+ stickyLeft?: number;
35
+ showStickyBorder?: boolean;
36
+ }
37
+ declare function TableCell({
38
+ className,
39
+ stickyLeft,
40
+ showStickyBorder,
41
+ style,
42
+ ...props
43
+ }: TableCellProps): react_jsx_runtime1.JSX.Element;
44
+ declare function TableCaption({
45
+ className,
46
+ ...props
47
+ }: React.ComponentProps<"caption">): react_jsx_runtime1.JSX.Element;
48
+ //#endregion
49
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
@@ -28,6 +28,13 @@ function TableBody({ className, ...props }) {
28
28
  ...props
29
29
  });
30
30
  }
31
+ function TableFooter({ className, ...props }) {
32
+ return /* @__PURE__ */ jsx("tfoot", {
33
+ "data-slot": "table-footer",
34
+ className: cn("qa-table__footer bg-background font-medium", className),
35
+ ...props
36
+ });
37
+ }
31
38
  const TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tr", {
32
39
  ref,
33
40
  "data-slot": "table-row",
@@ -61,6 +68,13 @@ function TableCell({ className, stickyLeft, showStickyBorder, style, ...props })
61
68
  ...props
62
69
  });
63
70
  }
71
+ function TableCaption({ className, ...props }) {
72
+ return /* @__PURE__ */ jsx("caption", {
73
+ "data-slot": "table-caption",
74
+ className: cn("qa-table__caption text-muted-foreground mt-4 text-xs", className),
75
+ ...props
76
+ });
77
+ }
64
78
 
65
79
  //#endregion
66
- export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow };
80
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
@@ -0,0 +1,21 @@
1
+ import * as react_jsx_runtime8 from "react/jsx-runtime";
2
+ import { Tooltip } from "@base-ui/react/tooltip";
3
+
4
+ //#region src/client/components/ui/tooltip.d.ts
5
+ declare function Tooltip$1({
6
+ ...props
7
+ }: Tooltip.Root.Props): react_jsx_runtime8.JSX.Element;
8
+ declare function TooltipTrigger({
9
+ ...props
10
+ }: Tooltip.Trigger.Props): react_jsx_runtime8.JSX.Element;
11
+ declare function TooltipContent({
12
+ className,
13
+ side,
14
+ sideOffset,
15
+ align,
16
+ alignOffset,
17
+ children,
18
+ ...props
19
+ }: Tooltip.Popup.Props & Pick<Tooltip.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): react_jsx_runtime8.JSX.Element;
20
+ //#endregion
21
+ export { Tooltip$1 as Tooltip, TooltipContent, TooltipTrigger };
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime16 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime50 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/client/contexts/focus-context.d.ts
5
5
 
@@ -59,7 +59,7 @@ type FocusProviderProps = {
59
59
  declare function FocusProvider({
60
60
  children,
61
61
  onFocusChange
62
- }: FocusProviderProps): react_jsx_runtime16.JSX.Element;
62
+ }: FocusProviderProps): react_jsx_runtime50.JSX.Element;
63
63
  /**
64
64
  * Use the focus context
65
65
  */
@@ -11,6 +11,11 @@ const adminConfigQueryKey = [
11
11
  "admin",
12
12
  "config"
13
13
  ];
14
+ const publicAdminConfigQueryKey = [
15
+ "questpie",
16
+ "admin",
17
+ "public-config"
18
+ ];
14
19
  /** Query options factory for admin config — can be used for prefetching in loaders */
15
20
  function getAdminConfigQueryOptions(client) {
16
21
  return {
@@ -23,6 +28,20 @@ function getAdminConfigQueryOptions(client) {
23
28
  gcTime: 1800 * 1e3
24
29
  };
25
30
  }
31
+ /** Query options for auth-page-safe public branding/bootstrap config. */
32
+ function getPublicAdminConfigQueryOptions(client) {
33
+ return {
34
+ queryKey: publicAdminConfigQueryKey,
35
+ queryFn: async () => {
36
+ if (!client || !client.routes) return {};
37
+ const routes = client.routes;
38
+ if (typeof routes.getPublicAdminConfig === "function") return routes.getPublicAdminConfig();
39
+ return {};
40
+ },
41
+ staleTime: 300 * 1e3,
42
+ gcTime: 1800 * 1e3
43
+ };
44
+ }
26
45
  /** Standard query hook - returns loading/error states */
27
46
  function useAdminConfig(queryOptions) {
28
47
  return useQuery({
@@ -36,4 +55,4 @@ function useSuspenseAdminConfig() {
36
55
  }
37
56
 
38
57
  //#endregion
39
- export { getAdminConfigQueryOptions, useAdminConfig, useSuspenseAdminConfig };
58
+ export { getAdminConfigQueryOptions, getPublicAdminConfigQueryOptions, useAdminConfig, useSuspenseAdminConfig };
@@ -0,0 +1,91 @@
1
+ import { useTranslation } from "../i18n/hooks.mjs";
2
+ import * as React from "react";
3
+ import { toast } from "sonner";
4
+
5
+ //#region src/client/hooks/use-autosave.ts
6
+ /**
7
+ * useAutosave — engine-agnostic debounced autosave for react-hook-form views.
8
+ *
9
+ * Extracted from the form view's `AutosaveManager`. The save pipeline
10
+ * (`runAutosave`) is unchanged — it guards on dirty/submitting, submits via the
11
+ * form, resets to the server result, and reports save state.
12
+ *
13
+ * The trigger is driven by `form.subscribe({ formState: { values: true } })`
14
+ * (the same value-subscription `PreviewPatchBridge` uses) rather than DOM
15
+ * `input`/`change` listeners. That makes it engine-agnostic: it catches native
16
+ * input edits AND programmatic `field.onChange` emissions (e.g. the TipTap
17
+ * rich-text field, whose contenteditable does not fire bubbling DOM events).
18
+ *
19
+ * Both the form view and the document view consume this hook so they share one
20
+ * autosave code path.
21
+ */
22
+ /**
23
+ * Wire debounced autosave onto a form. Returns the imperative `runAutosave`
24
+ * callback so callers can also flush manually if needed.
25
+ */
26
+ function useAutosave({ form, id, enabled, debounce, isDirtyRef, isSubmittingRef, updateMutation, onPreviewCommit, onPreviewRefresh, onSavingChange, onSaved }) {
27
+ const { t } = useTranslation();
28
+ const timerRef = React.useRef(null);
29
+ const runAutosave = React.useCallback(async () => {
30
+ if (!id || !isDirtyRef.current || isSubmittingRef.current) return;
31
+ try {
32
+ onSavingChange(true);
33
+ await form.handleSubmit(async (data) => {
34
+ const result = await updateMutation.mutateAsync({
35
+ id,
36
+ data
37
+ });
38
+ form.reset(result, { keepTouched: true });
39
+ onPreviewCommit?.(result);
40
+ onPreviewRefresh?.();
41
+ onSaved(/* @__PURE__ */ new Date());
42
+ onSavingChange(false);
43
+ }, () => {
44
+ onSavingChange(false);
45
+ })();
46
+ } catch (error) {
47
+ onSavingChange(false);
48
+ console.error("Autosave failed:", error);
49
+ toast.error(t("error.autosaveFailed"), { description: error instanceof Error ? error.message : void 0 });
50
+ }
51
+ }, [
52
+ form,
53
+ id,
54
+ isDirtyRef,
55
+ isSubmittingRef,
56
+ onSaved,
57
+ onSavingChange,
58
+ onPreviewCommit,
59
+ onPreviewRefresh,
60
+ t,
61
+ updateMutation
62
+ ]);
63
+ React.useEffect(() => {
64
+ if (timerRef.current) clearTimeout(timerRef.current);
65
+ if (!enabled || !id) return;
66
+ const scheduleAutosave = () => {
67
+ if (timerRef.current) clearTimeout(timerRef.current);
68
+ timerRef.current = setTimeout(() => {
69
+ runAutosave();
70
+ }, debounce);
71
+ };
72
+ const unsubscribe = form.subscribe({
73
+ formState: { values: true },
74
+ callback: scheduleAutosave
75
+ });
76
+ return () => {
77
+ unsubscribe();
78
+ if (timerRef.current) clearTimeout(timerRef.current);
79
+ };
80
+ }, [
81
+ debounce,
82
+ enabled,
83
+ form,
84
+ id,
85
+ runAutosave
86
+ ]);
87
+ return runAutosave;
88
+ }
89
+
90
+ //#endregion
91
+ export { useAutosave };