@burojs/ui-shadcn 0.6.0 → 0.7.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 (152) hide show
  1. package/README.md +9 -0
  2. package/dist/bulk-summary-BWSAS7k2.js +143 -0
  3. package/dist/bulk-summary-BWSAS7k2.js.map +1 -0
  4. package/dist/bulk-summary-CrEij5vq.cjs +143 -0
  5. package/dist/bulk-summary-CrEij5vq.cjs.map +1 -0
  6. package/dist/{candidates-relation-picker-B116Bmqi.js → candidates-relation-picker-CS_JZ4Fd.js} +3 -3
  7. package/dist/{candidates-relation-picker-B116Bmqi.js.map → candidates-relation-picker-CS_JZ4Fd.js.map} +1 -1
  8. package/dist/{candidates-relation-picker-Cy0rTxvI.cjs → candidates-relation-picker-y5M6_oe4.cjs} +4 -4
  9. package/dist/{candidates-relation-picker-Cy0rTxvI.cjs.map → candidates-relation-picker-y5M6_oe4.cjs.map} +1 -1
  10. package/dist/{check-confirm-dialog-bRT8lt0d.js → check-confirm-dialog-2j0gOd7x.js} +384 -108
  11. package/dist/check-confirm-dialog-2j0gOd7x.js.map +1 -0
  12. package/dist/{check-confirm-dialog--gPFnEeg.cjs → check-confirm-dialog-C-NHgMST.cjs} +468 -107
  13. package/dist/check-confirm-dialog-C-NHgMST.cjs.map +1 -0
  14. package/dist/{dialog-B_rt9S1c.js → dialog-C123sVQ8.js} +4 -4
  15. package/dist/dialog-C123sVQ8.js.map +1 -0
  16. package/dist/{dialog-DRNUq9EA.cjs → dialog-vmMdfUWs.cjs} +3 -3
  17. package/dist/dialog-vmMdfUWs.cjs.map +1 -0
  18. package/dist/{filter-builder-nXqtM_h4.cjs → filter-builder-DFu0JP-1.cjs} +923 -120
  19. package/dist/filter-builder-DFu0JP-1.cjs.map +1 -0
  20. package/dist/{filter-builder-Bhn-dhZV.js → filter-builder-DaWHUZuV.js} +839 -108
  21. package/dist/filter-builder-DaWHUZuV.js.map +1 -0
  22. package/dist/{flow-runtime-D3avVH0I.cjs → flow-runtime-BpmrIUb6.cjs} +61 -29
  23. package/dist/flow-runtime-BpmrIUb6.cjs.map +1 -0
  24. package/dist/{flow-runtime-s6lkRPKF.js → flow-runtime-DyqTmK3H.js} +62 -30
  25. package/dist/flow-runtime-DyqTmK3H.js.map +1 -0
  26. package/dist/{flow-screen-Ci_Sik4Y.cjs → flow-screen-Bcz9NF2V.cjs} +128 -87
  27. package/dist/flow-screen-Bcz9NF2V.cjs.map +1 -0
  28. package/dist/{flow-screen-CCvgDI9G.js → flow-screen-DCdli6Ha.js} +128 -87
  29. package/dist/flow-screen-DCdli6Ha.js.map +1 -0
  30. package/dist/index.cjs +731 -906
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +455 -247
  33. package/dist/index.d.ts +455 -247
  34. package/dist/index.js +647 -828
  35. package/dist/index.js.map +1 -1
  36. package/dist/{inline-flow-host-DV1et3c6.cjs → inline-flow-host-3vw7LzzD.cjs} +5 -5
  37. package/dist/inline-flow-host-3vw7LzzD.cjs.map +1 -0
  38. package/dist/{inline-flow-host-B6FI0ctQ.js → inline-flow-host-C0rI9B7f.js} +5 -5
  39. package/dist/inline-flow-host-C0rI9B7f.js.map +1 -0
  40. package/dist/{candidates-gate-D33jXLHO.cjs → lazy-relation-picker-dialog-Bt8lrEIu.cjs} +10 -10
  41. package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs.map +1 -0
  42. package/dist/{candidates-gate-Bb70LPAy.js → lazy-relation-picker-dialog-CAScLPb2.js} +11 -11
  43. package/dist/lazy-relation-picker-dialog-CAScLPb2.js.map +1 -0
  44. package/dist/{page-flow-route-i3ZfJ1sd.js → page-flow-route-BHUEpn0I.js} +36 -23
  45. package/dist/page-flow-route-BHUEpn0I.js.map +1 -0
  46. package/dist/{page-flow-route-hdnULWqd.cjs → page-flow-route-DS8IVTVH.cjs} +41 -28
  47. package/dist/page-flow-route-DS8IVTVH.cjs.map +1 -0
  48. package/dist/{place-node-C5SmIAYU.cjs → place-node-CNb3w-c7.cjs} +1869 -947
  49. package/dist/place-node-CNb3w-c7.cjs.map +1 -0
  50. package/dist/{place-node-NraNYKPx.js → place-node-CfzQvh4Y.js} +1824 -926
  51. package/dist/place-node-CfzQvh4Y.js.map +1 -0
  52. package/dist/{related-list-cards-BWZ9GfOG.js → related-list-cards-BIqqY69Y.js} +9 -4
  53. package/dist/{related-list-cards-BWZ9GfOG.js.map → related-list-cards-BIqqY69Y.js.map} +1 -1
  54. package/dist/{related-list-cards-CFq3meUn.cjs → related-list-cards-CelMxl4q.cjs} +9 -4
  55. package/dist/{related-list-cards-CFq3meUn.cjs.map → related-list-cards-CelMxl4q.cjs.map} +1 -1
  56. package/dist/{related-list-timeline-yrPsjA3F.js → related-list-timeline-CRh7xwLD.js} +6 -7
  57. package/dist/related-list-timeline-CRh7xwLD.js.map +1 -0
  58. package/dist/{related-list-timeline-CCzl71aA.cjs → related-list-timeline-DsLdi8sv.cjs} +5 -6
  59. package/dist/related-list-timeline-DsLdi8sv.cjs.map +1 -0
  60. package/dist/{related-rows-o0_t-Yce.js → related-rows--uP2iKQC.js} +25 -14
  61. package/dist/related-rows--uP2iKQC.js.map +1 -0
  62. package/dist/{related-rows-ea43qhhy.cjs → related-rows-MPnLCmPF.cjs} +27 -16
  63. package/dist/related-rows-MPnLCmPF.cjs.map +1 -0
  64. package/dist/{search-access-CPPmfuvy.js → relation-create-C43cdPQt.js} +595 -13
  65. package/dist/relation-create-C43cdPQt.js.map +1 -0
  66. package/dist/{search-access-Dugvttlg.cjs → relation-create-DDEYcKfw.cjs} +633 -14
  67. package/dist/relation-create-DDEYcKfw.cjs.map +1 -0
  68. package/dist/{relation-many-picker-bvkjkv-k.js → relation-many-picker-BJhaEqxz.js} +203 -102
  69. package/dist/relation-many-picker-BJhaEqxz.js.map +1 -0
  70. package/dist/{relation-many-picker-C8zFEjwd.cjs → relation-many-picker-DzuGJpEl.cjs} +211 -110
  71. package/dist/relation-many-picker-DzuGJpEl.cjs.map +1 -0
  72. package/dist/{relation-picker-Z0ZJJ5uS.js → relation-picker-D-tBBZW_.js} +23 -59
  73. package/dist/relation-picker-D-tBBZW_.js.map +1 -0
  74. package/dist/{relation-picker-gag0qSR5.cjs → relation-picker-DaIMzf2H.cjs} +29 -71
  75. package/dist/relation-picker-DaIMzf2H.cjs.map +1 -0
  76. package/dist/{relation-picker-dialog-0IzkjmiA.cjs → relation-picker-dialog-9Vg5vvR1.cjs} +133 -35
  77. package/dist/relation-picker-dialog-9Vg5vvR1.cjs.map +1 -0
  78. package/dist/{relation-picker-dialog-B6nIiJBf.js → relation-picker-dialog-DoEY8EkH.js} +134 -36
  79. package/dist/relation-picker-dialog-DoEY8EkH.js.map +1 -0
  80. package/dist/relation-select-B8Fq4o-t.js +48 -0
  81. package/dist/relation-select-B8Fq4o-t.js.map +1 -0
  82. package/dist/relation-select-Cr3CfNLy.cjs +55 -0
  83. package/dist/relation-select-Cr3CfNLy.cjs.map +1 -0
  84. package/dist/{resource-page-router-PXfMW9nh.cjs → resource-page-router-C_kGW2o_.cjs} +543 -300
  85. package/dist/resource-page-router-C_kGW2o_.cjs.map +1 -0
  86. package/dist/{resource-page-router-3RUf9d1j.js → resource-page-router-Diw6S6TK.js} +498 -255
  87. package/dist/resource-page-router-Diw6S6TK.js.map +1 -0
  88. package/dist/{rich-text-vTyVjDoa.cjs → rich-text-C_7JCvRo.cjs} +2 -2
  89. package/dist/{rich-text-vTyVjDoa.cjs.map → rich-text-C_7JCvRo.cjs.map} +1 -1
  90. package/dist/{rich-text-DFerywgz.js → rich-text-RcPBf6hr.js} +2 -2
  91. package/dist/{rich-text-DFerywgz.js.map → rich-text-RcPBf6hr.js.map} +1 -1
  92. package/dist/success-notices-Dl3M1fZP.cjs +46 -0
  93. package/dist/success-notices-Dl3M1fZP.cjs.map +1 -0
  94. package/dist/success-notices-LDEgEkc4.js +41 -0
  95. package/dist/success-notices-LDEgEkc4.js.map +1 -0
  96. package/dist/{toaster-Cr51X7bz.cjs → toaster-BbByOytP.cjs} +60 -15
  97. package/dist/toaster-BbByOytP.cjs.map +1 -0
  98. package/dist/{toaster-C02XbB9r.js → toaster-Ct_YHGs6.js} +43 -16
  99. package/dist/toaster-Ct_YHGs6.js.map +1 -0
  100. package/dist/{use-dialog-filter-state-C--oMAZG.js → use-dialog-filter-state-B_MqzHaT.js} +5 -4
  101. package/dist/use-dialog-filter-state-B_MqzHaT.js.map +1 -0
  102. package/dist/{use-dialog-filter-state-Dhe8PcB5.cjs → use-dialog-filter-state-tNvqAAjh.cjs} +6 -5
  103. package/dist/use-dialog-filter-state-tNvqAAjh.cjs.map +1 -0
  104. package/package.json +11 -11
  105. package/dist/bulk-summary-CwSd6Yjb.cjs +0 -108
  106. package/dist/bulk-summary-CwSd6Yjb.cjs.map +0 -1
  107. package/dist/bulk-summary-GxMDP4bw.js +0 -108
  108. package/dist/bulk-summary-GxMDP4bw.js.map +0 -1
  109. package/dist/candidates-gate-Bb70LPAy.js.map +0 -1
  110. package/dist/candidates-gate-D33jXLHO.cjs.map +0 -1
  111. package/dist/check-confirm-dialog--gPFnEeg.cjs.map +0 -1
  112. package/dist/check-confirm-dialog-bRT8lt0d.js.map +0 -1
  113. package/dist/dialog-B_rt9S1c.js.map +0 -1
  114. package/dist/dialog-DRNUq9EA.cjs.map +0 -1
  115. package/dist/filter-builder-Bhn-dhZV.js.map +0 -1
  116. package/dist/filter-builder-nXqtM_h4.cjs.map +0 -1
  117. package/dist/flow-runtime-D3avVH0I.cjs.map +0 -1
  118. package/dist/flow-runtime-s6lkRPKF.js.map +0 -1
  119. package/dist/flow-screen-CCvgDI9G.js.map +0 -1
  120. package/dist/flow-screen-Ci_Sik4Y.cjs.map +0 -1
  121. package/dist/inline-flow-host-B6FI0ctQ.js.map +0 -1
  122. package/dist/inline-flow-host-DV1et3c6.cjs.map +0 -1
  123. package/dist/page-flow-route-hdnULWqd.cjs.map +0 -1
  124. package/dist/page-flow-route-i3ZfJ1sd.js.map +0 -1
  125. package/dist/place-node-C5SmIAYU.cjs.map +0 -1
  126. package/dist/place-node-NraNYKPx.js.map +0 -1
  127. package/dist/related-list-timeline-CCzl71aA.cjs.map +0 -1
  128. package/dist/related-list-timeline-yrPsjA3F.js.map +0 -1
  129. package/dist/related-rows-ea43qhhy.cjs.map +0 -1
  130. package/dist/related-rows-o0_t-Yce.js.map +0 -1
  131. package/dist/relation-create-IA40t1hi.cjs +0 -364
  132. package/dist/relation-create-IA40t1hi.cjs.map +0 -1
  133. package/dist/relation-create-h6F9B4C4.js +0 -339
  134. package/dist/relation-create-h6F9B4C4.js.map +0 -1
  135. package/dist/relation-many-picker-C8zFEjwd.cjs.map +0 -1
  136. package/dist/relation-many-picker-bvkjkv-k.js.map +0 -1
  137. package/dist/relation-picker-Z0ZJJ5uS.js.map +0 -1
  138. package/dist/relation-picker-dialog-0IzkjmiA.cjs.map +0 -1
  139. package/dist/relation-picker-dialog-B6nIiJBf.js.map +0 -1
  140. package/dist/relation-picker-gag0qSR5.cjs.map +0 -1
  141. package/dist/resource-page-router-3RUf9d1j.js.map +0 -1
  142. package/dist/resource-page-router-PXfMW9nh.cjs.map +0 -1
  143. package/dist/search-access-CPPmfuvy.js.map +0 -1
  144. package/dist/search-access-Dugvttlg.cjs.map +0 -1
  145. package/dist/shell-BPlk8hEa.js +0 -205
  146. package/dist/shell-BPlk8hEa.js.map +0 -1
  147. package/dist/shell-DxhlsPwm.cjs +0 -271
  148. package/dist/shell-DxhlsPwm.cjs.map +0 -1
  149. package/dist/toaster-C02XbB9r.js.map +0 -1
  150. package/dist/toaster-Cr51X7bz.cjs.map +0 -1
  151. package/dist/use-dialog-filter-state-C--oMAZG.js.map +0 -1
  152. package/dist/use-dialog-filter-state-Dhe8PcB5.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_use_theme = require("./use-theme-DFlpXils.cjs");
3
- const require_toaster = require("./toaster-Cr51X7bz.cjs");
4
- const require_check_confirm_dialog = require("./check-confirm-dialog--gPFnEeg.cjs");
3
+ const require_toaster = require("./toaster-BbByOytP.cjs");
4
+ const require_check_confirm_dialog = require("./check-confirm-dialog-C-NHgMST.cjs");
5
5
  const require_button = require("./button-BxnnE28H.cjs");
6
6
  const require_input = require("./input-BI0czGyI.cjs");
7
- const require_dialog = require("./dialog-DRNUq9EA.cjs");
8
- const require_search_access = require("./search-access-Dugvttlg.cjs");
9
- const require_shell = require("./shell-DxhlsPwm.cjs");
7
+ const require_dialog = require("./dialog-vmMdfUWs.cjs");
8
+ const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
10
9
  const require_skeleton = require("./skeleton-_1gP7wan.cjs");
11
- const require_place_node = require("./place-node-C5SmIAYU.cjs");
10
+ const require_place_node = require("./place-node-CNb3w-c7.cjs");
12
11
  const require_layout_theme_storage_key = require("./layout/theme-storage-key.cjs");
13
- const require_filter_builder = require("./filter-builder-nXqtM_h4.cjs");
14
- const require_resource_page_router = require("./resource-page-router-PXfMW9nh.cjs");
12
+ const require_filter_builder = require("./filter-builder-DFu0JP-1.cjs");
13
+ const require_resource_page_router = require("./resource-page-router-C_kGW2o_.cjs");
15
14
  const require_label = require("./label-w6JYf2cF.cjs");
16
- const require_relation_picker = require("./relation-picker-gag0qSR5.cjs");
17
- const require_candidates_gate = require("./candidates-gate-D33jXLHO.cjs");
18
- const require_use_dialog_filter_state = require("./use-dialog-filter-state-Dhe8PcB5.cjs");
15
+ const require_lazy_relation_picker_dialog = require("./lazy-relation-picker-dialog-Bt8lrEIu.cjs");
16
+ const require_relation_picker = require("./relation-picker-DaIMzf2H.cjs");
17
+ const require_use_dialog_filter_state = require("./use-dialog-filter-state-tNvqAAjh.cjs");
18
+ let _burojs_react_web = require("@burojs/react/web");
19
19
  let _burojs_core = require("@burojs/core");
20
20
  let _burojs_react = require("@burojs/react");
21
21
  let _tabler_icons_react = require("@tabler/icons-react");
@@ -35,6 +35,7 @@ let _radix_ui_react_avatar = require("@radix-ui/react-avatar");
35
35
  _radix_ui_react_avatar = require_use_theme.__toESM(_radix_ui_react_avatar, 1);
36
36
  let _radix_ui_react_collapsible = require("@radix-ui/react-collapsible");
37
37
  _radix_ui_react_collapsible = require_use_theme.__toESM(_radix_ui_react_collapsible, 1);
38
+ let _burojs_core_internal = require("@burojs/core/internal");
38
39
  let react_hook_form = require("react-hook-form");
39
40
  let _hookform_resolvers_zod = require("@hookform/resolvers/zod");
40
41
  let zod = require("zod");
@@ -496,7 +497,7 @@ function ScopeSummary({ scope, summary }) {
496
497
  const caps = (0, _burojs_react.useI18nCaps)();
497
498
  const t = (0, _burojs_react.useOptionalT)();
498
499
  const links = (scope !== void 0 ? (0, _burojs_core.resolveDoc)(caps, scope) : void 0)?.links ?? [];
499
- const newTabNote = t("docPanel.newTab", { defaultValue: "opens in a new tab" });
500
+ const newTabNote = t("docPanel.opensInNewTab", { defaultValue: "(opens in a new tab)" });
500
501
  if (summary === void 0 && links.length === 0) return null;
501
502
  return (0, react_jsx_runtime.jsxs)("div", {
502
503
  className: "mt-2 flex flex-col items-start gap-3",
@@ -632,9 +633,9 @@ function CommandPaletteDocsGroup({ locale, onSelect, heading }) {
632
633
  }];
633
634
  }), [groups, contextOf]);
634
635
  if (hits.length === 0) return null;
635
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
636
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
636
637
  heading: heading ?? t("docPanel.title", { defaultValue: "Help" }),
637
- children: hits.map((hit) => (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
638
+ children: hits.map((hit) => (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
638
639
  value: `doc ${hit.scopeLabel} ${hit.title}`,
639
640
  "data-testid": `command-doc:${hit.scope}${hit.topicId === void 0 ? "" : `:${hit.topicId}`}`,
640
641
  onSelect: () => {
@@ -777,10 +778,10 @@ const Sidebar = react.forwardRef(({ side = "left", variant = "sidebar", collapsi
777
778
  ...props,
778
779
  children
779
780
  });
780
- if (isMobile) return (0, react_jsx_runtime.jsx)(require_shell.Sheet, {
781
+ if (isMobile) return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Sheet, {
781
782
  open: openMobile,
782
783
  onOpenChange: setOpenMobile,
783
- children: (0, react_jsx_runtime.jsxs)(require_shell.SheetContent, {
784
+ children: (0, react_jsx_runtime.jsxs)(require_check_confirm_dialog.SheetContent, {
784
785
  "data-sidebar": "sidebar",
785
786
  "data-mobile": "true",
786
787
  className: "w-[var(--sidebar-width)] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
@@ -788,11 +789,11 @@ const Sidebar = react.forwardRef(({ side = "left", variant = "sidebar", collapsi
788
789
  side: side === "left" ? "left" : "right",
789
790
  ...props,
790
791
  children: [
791
- (0, react_jsx_runtime.jsx)(require_shell.SheetTitle, {
792
+ (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.SheetTitle, {
792
793
  className: "sr-only",
793
794
  children: t("nav.label", { defaultValue: "Navigation" })
794
795
  }),
795
- (0, react_jsx_runtime.jsx)(require_shell.SheetDescription, {
796
+ (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.SheetDescription, {
796
797
  className: "sr-only",
797
798
  children: t("nav.main", { defaultValue: "Main navigation" })
798
799
  }),
@@ -1118,7 +1119,7 @@ AlertDialogCancel.displayName = _radix_ui_react_alert_dialog.Cancel.displayName;
1118
1119
  function NavigationGuardDialog() {
1119
1120
  const prompt = (0, _burojs_react.useRegisterNavigationGuardDialog)();
1120
1121
  const text = (0, _burojs_react.useNavigationGuardText)();
1121
- const unsavedAction = (0, _burojs_react.useOptionalT)()("navigation.unsavedAction");
1122
+ const unsavedAction = (0, _burojs_react.useOptionalT)()("navigation.unsavedAction", { defaultValue: "An action on this screen has unsaved input" });
1122
1123
  const returnFocus = (0, react.useRef)(null);
1123
1124
  const wasOpen = (0, react.useRef)(false);
1124
1125
  const open = prompt !== null;
@@ -1141,7 +1142,7 @@ function NavigationGuardDialog() {
1141
1142
  event.preventDefault();
1142
1143
  element.focus();
1143
1144
  },
1144
- children: [(0, react_jsx_runtime.jsxs)(AlertDialogHeader, { children: [(0, react_jsx_runtime.jsx)(AlertDialogTitle, { children: text.title }), (0, react_jsx_runtime.jsxs)(AlertDialogDescription, { children: [text.body, prompt !== null && prompt.labels.length > 0 ? ` ${unsavedAction === "navigation.unsavedAction" ? "An action on this screen has unsaved input" : unsavedAction}: ${prompt.labels.join(", ")}.` : null] })] }), (0, react_jsx_runtime.jsxs)(AlertDialogFooter, { children: [(0, react_jsx_runtime.jsx)(AlertDialogCancel, {
1145
+ children: [(0, react_jsx_runtime.jsxs)(AlertDialogHeader, { children: [(0, react_jsx_runtime.jsx)(AlertDialogTitle, { children: text.title }), (0, react_jsx_runtime.jsxs)(AlertDialogDescription, { children: [text.body, prompt !== null && prompt.labels.length > 0 ? ` ${unsavedAction}: ${prompt.labels.join(", ")}.` : null] })] }), (0, react_jsx_runtime.jsxs)(AlertDialogFooter, { children: [(0, react_jsx_runtime.jsx)(AlertDialogCancel, {
1145
1146
  "data-testid": "nav-guard-stay",
1146
1147
  children: text.stay
1147
1148
  }), (0, react_jsx_runtime.jsx)(AlertDialogAction, {
@@ -1701,14 +1702,14 @@ const CollapsibleTrigger = _radix_ui_react_collapsible.CollapsibleTrigger;
1701
1702
  const CollapsibleContent = _radix_ui_react_collapsible.CollapsibleContent;
1702
1703
  //#endregion
1703
1704
  //#region src/shell/use-nav-icon.tsx
1704
- const warned = new Set();
1705
+ const warned$1 = new Set();
1705
1706
  function resolveNavIcon(name, components) {
1706
1707
  if (name === void 0 || name === "") return void 0;
1707
1708
  const slot = components(name);
1708
1709
  if (typeof slot === "function" || typeof slot === "object" && slot !== null) return (0, react_jsx_runtime.jsx)(slot, { className: "h-4 w-4" });
1709
1710
  if (require_check_confirm_dialog.hasIcon(name)) return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, { name });
1710
- if (process.env.NODE_ENV !== "production" && !warned.has(name)) {
1711
- warned.add(name);
1711
+ if (process.env.NODE_ENV !== "production" && !warned$1.has(name)) {
1712
+ warned$1.add(name);
1712
1713
  console.warn(`[buro] unknown nav icon "${name}"`);
1713
1714
  }
1714
1715
  }
@@ -1717,6 +1718,53 @@ function useNavIcon() {
1717
1718
  return (0, react.useCallback)((name) => resolveNavIcon(name, (key) => components[key]), [components]);
1718
1719
  }
1719
1720
  //#endregion
1721
+ //#region src/layout/build-nav-items.ts
1722
+ function buildNavItems(args) {
1723
+ const { registry, caps, groupName, match, isVisible, entryFilter, icons } = args;
1724
+ const chain = match?.groupChain ?? [];
1725
+ const qualifiedMatch = match;
1726
+ const activeLeaf = qualifiedMatch == null ? void 0 : qualifiedMatch.kind === "group-index" ? require_resource_page_router.canonicalNavKey({
1727
+ name: qualifiedMatch.target ?? qualifiedMatch.name,
1728
+ ref: qualifiedMatch.targetRef
1729
+ }) : require_resource_page_router.canonicalNavKey(qualifiedMatch);
1730
+ const isEligible = (node) => isVisible(node) && (entryFilter ? entryFilter(node) : true);
1731
+ const out = [];
1732
+ for (const child of registry.groups.childrenOf(groupName)) {
1733
+ if (!isEligible(child)) continue;
1734
+ const kind = (0, _burojs_core.nodeKind)(child);
1735
+ const childKey = require_resource_page_router.canonicalNavKey(child);
1736
+ const href = (0, _burojs_core.navHrefFor)(registry, childKey, { isVisible: isEligible });
1737
+ if (kind === "group") {
1738
+ const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${childKey}`, (0, _burojs_core.declaredText)("chrome", child, "label"));
1739
+ const active = chain.some((g) => require_resource_page_router.canonicalNavKey(g) === childKey);
1740
+ out.push({
1741
+ kind: "group",
1742
+ name: childKey,
1743
+ label,
1744
+ href,
1745
+ icon: icons?.group?.(childKey),
1746
+ active
1747
+ });
1748
+ } else if (kind === "custom-page") out.push({
1749
+ kind: "custom-page",
1750
+ name: childKey,
1751
+ label: (0, _burojs_core.resolveNavLabel)(caps, `pages.${childKey}`, (0, _burojs_core.declaredText)("chrome", child, "label")),
1752
+ href,
1753
+ icon: icons?.page?.(childKey),
1754
+ active: activeLeaf === childKey
1755
+ });
1756
+ else out.push({
1757
+ kind: "resource",
1758
+ name: childKey,
1759
+ label: (0, _burojs_core.resolveResourceNavLabel)(caps, childKey, child),
1760
+ href,
1761
+ icon: icons?.resource?.(childKey),
1762
+ active: activeLeaf === childKey
1763
+ });
1764
+ }
1765
+ return out;
1766
+ }
1767
+ //#endregion
1720
1768
  //#region src/layout/use-nav-tree.ts
1721
1769
  function isActiveHref(href, currentPath) {
1722
1770
  if (!currentPath) return false;
@@ -1730,8 +1778,7 @@ function useNavTree(opts = {}) {
1730
1778
  const passesEntryFilter = (entry) => entryFilter ? entryFilter(entry) : true;
1731
1779
  const app = (0, _burojs_react.useApp)();
1732
1780
  const caps = (0, _burojs_react.useI18nCaps)();
1733
- const visibilityCtx = (0, _burojs_react.useVisibilityCtx)();
1734
- const isResourceVisible = (r) => (0, _burojs_core.evaluateVisible)(r.visible, visibilityCtx);
1781
+ const isResourceVisible = require_resource_page_router.useResourceVisible();
1735
1782
  const resolveLayout = require_resource_page_router.useLayoutResolver();
1736
1783
  const match = require_resource_page_router.useMatch();
1737
1784
  const isVisible = require_resource_page_router.useNavVisible();
@@ -1741,6 +1788,7 @@ function useNavTree(opts = {}) {
1741
1788
  const allCustomPages = app.registry.customPages.list();
1742
1789
  const sections = app.registry.sections.list();
1743
1790
  const groups = app.registry.groups.rootNodes().filter((n) => (0, _burojs_core.nodeKind)(n) === "group");
1791
+ require_resource_page_router.useReportUnresolvedLayouts(app.registry.groups.list(), resolveLayout);
1744
1792
  const topLevelResources = allResources.filter((r) => (0, _burojs_core.hasListPage)(r)).filter(isResourceVisible).filter(passesEntryFilter).filter((r) => !r.section && !r.group).map((r, idx) => ({
1745
1793
  r,
1746
1794
  idx
@@ -1778,7 +1826,7 @@ function useNavTree(opts = {}) {
1778
1826
  };
1779
1827
  };
1780
1828
  const layoutOf = (group) => resolveLayout(group.layout) ? group.layout : group.collapsible ? "collapsible" : "flat";
1781
- const groupChildren = (groupKey) => require_resource_page_router.buildNavItems({
1829
+ const groupChildren = (groupKey) => buildNavItems({
1782
1830
  registry: app.registry,
1783
1831
  caps,
1784
1832
  groupName: groupKey,
@@ -1978,7 +2026,7 @@ function NavMain({ topLabel, iconForResource, iconForCustomPage, iconForSection,
1978
2026
  })
1979
2027
  }) }, entry.key);
1980
2028
  const [top, ...blocks] = tree;
1981
- return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)(SidebarGroup, { children: [topLabel !== null && (0, react_jsx_runtime.jsx)(SidebarGroupLabel, { children: topLabel ?? t("nav.resources") }), (0, react_jsx_runtime.jsx)(SidebarGroupContent, { children: (0, react_jsx_runtime.jsx)(SidebarMenu, { children: top?.entries.map(menuItem) }) })] }), blocks.map((block) => {
2029
+ return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [top !== void 0 && top.entries.length > 0 && (0, react_jsx_runtime.jsxs)(SidebarGroup, { children: [topLabel !== null && (0, react_jsx_runtime.jsx)(SidebarGroupLabel, { children: topLabel ?? t("nav.resources") }), (0, react_jsx_runtime.jsx)(SidebarGroupContent, { children: (0, react_jsx_runtime.jsx)(SidebarMenu, { children: top.entries.map(menuItem) }) })] }), blocks.map((block) => {
1982
2030
  const key = block.key ?? "";
1983
2031
  if (block.label === null) return (0, react_jsx_runtime.jsx)(SidebarGroup, { children: (0, react_jsx_runtime.jsx)(SidebarGroupContent, { children: (0, react_jsx_runtime.jsx)(SidebarMenu, { children: block.entries.map(menuItem) }) }) }, key);
1984
2032
  if (block.collapsible) return (0, react_jsx_runtime.jsx)(CollapsibleNavSection, {
@@ -2022,127 +2070,32 @@ function AppSidebar({ header, filters, nav, footer }) {
2022
2070
  });
2023
2071
  }
2024
2072
  //#endregion
2025
- //#region src/layout/layouts/secondary-sidebar-layout.tsx
2026
- function Row({ it }) {
2027
- const RouterLink = require_toaster.useLinkComponent();
2028
- return (0, react_jsx_runtime.jsx)("li", { children: (0, react_jsx_runtime.jsxs)(RouterLink, {
2029
- href: it.href,
2030
- "data-testid": `nav-secondary-item:${it.name}`,
2031
- "aria-current": it.active ? "page" : void 0,
2032
- className: require_use_theme.cn("flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium outline-hidden ring-offset-background transition-colors", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "bg-secondary text-secondary-foreground" : "text-muted-foreground hover:bg-secondary/50 hover:text-foreground"),
2033
- children: [it.icon != null && (0, react_jsx_runtime.jsx)("span", {
2034
- className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
2035
- "aria-hidden": "true",
2036
- children: it.icon
2037
- }), (0, react_jsx_runtime.jsx)("span", {
2038
- className: "truncate",
2039
- title: it.label,
2040
- children: it.label
2041
- })]
2042
- }) });
2043
- }
2044
- function SecondarySidebarLayout({ group, groupKey, items, children }) {
2045
- const RouterLink = require_toaster.useLinkComponent();
2046
- const caps = (0, _burojs_react.useI18nCaps)();
2047
- const id = groupKey ?? group.name;
2048
- const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2049
- return (0, react_jsx_runtime.jsxs)("div", {
2050
- className: "md:-m-6 md:flex md:min-h-[calc(100%+3rem)]",
2051
- "data-testid": `nav-secondary:${id}`,
2052
- children: [
2053
- (0, react_jsx_runtime.jsx)("aside", {
2054
- className: "hidden w-64 shrink-0 border-r bg-background text-foreground md:block",
2055
- children: (0, react_jsx_runtime.jsxs)("div", {
2056
- className: "space-y-4 p-4",
2057
- children: [(0, react_jsx_runtime.jsx)("p", {
2058
- className: "px-3 text-base font-semibold tracking-tight",
2059
- children: label
2060
- }), (0, react_jsx_runtime.jsx)("nav", {
2061
- "aria-label": label,
2062
- children: (0, react_jsx_runtime.jsx)("ul", {
2063
- className: "space-y-0.5",
2064
- children: items.map((it) => (0, react_jsx_runtime.jsx)(Row, { it }, it.name))
2065
- })
2066
- })]
2067
- })
2068
- }),
2069
- (0, react_jsx_runtime.jsx)("nav", {
2070
- "aria-label": label,
2071
- "data-testid": `nav-secondary-select:${id}`,
2072
- className: "-mx-1 mb-4 flex snap-x snap-proximity gap-1.5 overflow-x-auto scroll-smooth px-1 pb-1 [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] md:hidden [&::-webkit-scrollbar]:hidden",
2073
- children: items.map((it) => (0, react_jsx_runtime.jsx)(RouterLink, {
2074
- href: it.href,
2075
- "aria-current": it.active ? "page" : void 0,
2076
- className: require_use_theme.cn("snap-start whitespace-nowrap rounded-full border px-3 py-1.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "border-primary/40 bg-primary/10 font-medium text-foreground" : "border-border text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"),
2077
- children: it.label
2078
- }, it.name))
2079
- }),
2080
- (0, react_jsx_runtime.jsx)("div", {
2081
- className: "min-w-0 flex-1 md:overflow-x-hidden md:p-6",
2082
- children
2083
- })
2084
- ]
2085
- });
2086
- }
2087
- //#endregion
2088
- //#region src/layout/layouts/tabs-layout.tsx
2089
- function TabsLayout({ group, groupKey, items, children }) {
2090
- const RouterLink = require_toaster.useLinkComponent();
2091
- const caps = (0, _burojs_react.useI18nCaps)();
2092
- const id = groupKey ?? group.name;
2093
- const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${id}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2094
- return (0, react_jsx_runtime.jsxs)("div", {
2095
- className: "flex flex-col gap-4",
2096
- "data-testid": `nav-tabs:${id}`,
2097
- children: [(0, react_jsx_runtime.jsx)("nav", {
2098
- "aria-label": label,
2099
- className: "flex gap-1 overflow-x-auto scroll-smooth border-b border-border [-ms-overflow-style:none] [mask-image:linear-gradient(to_right,transparent,black_8px,black_calc(100%-8px),transparent)] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
2100
- children: items.map((it) => (0, react_jsx_runtime.jsxs)(RouterLink, {
2101
- href: it.href,
2102
- "aria-current": it.active ? "page" : void 0,
2103
- "data-testid": `nav-tab:${it.name}`,
2104
- className: require_use_theme.cn("group/tab relative flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-t-sm px-3 py-2.5 text-sm outline-hidden ring-offset-background transition-colors duration-150", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", it.active ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"),
2105
- children: [
2106
- it.icon != null && (0, react_jsx_runtime.jsx)("span", {
2107
- className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
2108
- "aria-hidden": "true",
2109
- children: it.icon
2110
- }),
2111
- it.label,
2112
- (0, react_jsx_runtime.jsx)("span", {
2113
- "aria-hidden": "true",
2114
- className: require_use_theme.cn("pointer-events-none absolute inset-x-2 -bottom-px h-0.5 origin-center scale-x-0 rounded-full bg-primary opacity-0 transition-all duration-300 ease-out", it.active ? "scale-x-100 opacity-100" : "group-hover/tab:scale-x-100 group-hover/tab:opacity-30")
2115
- })
2116
- ]
2117
- }, it.name))
2118
- }), (0, react_jsx_runtime.jsx)("div", {
2119
- className: "min-w-0",
2120
- children
2121
- })]
2122
- });
2123
- }
2124
- //#endregion
2125
- //#region src/layout/nav-area-layout.tsx
2073
+ //#region src/layout/nav-chrome.tsx
2126
2074
  const DETAIL_ACTIONS = new Set([
2127
2075
  "show",
2128
2076
  "edit",
2129
2077
  "create"
2130
2078
  ]);
2131
- function NavAreaLayout({ groupName, children, entryFilter, icons }) {
2079
+ function NavChrome({ children, entryFilter, icons }) {
2132
2080
  const app = (0, _burojs_react.useApp)();
2133
2081
  const caps = (0, _burojs_react.useI18nCaps)();
2134
2082
  const isVisible = require_resource_page_router.useNavVisible();
2135
2083
  const match = require_resource_page_router.useMatch();
2136
2084
  const resolveLayout = require_resource_page_router.useLayoutResolver();
2137
- const group = app.registry.groups.get(groupName);
2138
- if (!group) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
2139
- const groupKey = require_resource_page_router.canonicalNavKey(group);
2140
- const claimed = [groupKey, ...(0, _burojs_core.groupChain)(app.registry, group).map(require_resource_page_router.canonicalNavKey)];
2141
- const collapse = group.chromeOn === "list" && match?.kind === "resource" && DETAIL_ACTIONS.has(match.action);
2142
- const Layout = resolveLayout(group.layout);
2085
+ require_resource_page_router.useReportUnresolvedLayouts(match?.groupChain ?? [], resolveLayout);
2086
+ if (!match) return (0, react_jsx_runtime.jsx)(require_resource_page_router.NavChromeMountedProvider, {
2087
+ value: true,
2088
+ children
2089
+ });
2143
2090
  let content = children;
2144
- if (Layout && !collapse) {
2145
- const items = require_resource_page_router.buildNavItems({
2091
+ for (let i = match.groupChain.length - 1; i >= 0; i--) {
2092
+ const group = match.groupChain[i];
2093
+ if (!group) continue;
2094
+ const groupKey = require_resource_page_router.canonicalNavKey(group);
2095
+ if (group.chromeOn === "list" && match.kind === "resource" && DETAIL_ACTIONS.has(match.action)) continue;
2096
+ const Layout = resolveLayout(group.layout);
2097
+ if (!Layout) continue;
2098
+ const items = buildNavItems({
2146
2099
  registry: app.registry,
2147
2100
  caps,
2148
2101
  groupName: groupKey,
@@ -2155,11 +2108,11 @@ function NavAreaLayout({ groupName, children, entryFilter, icons }) {
2155
2108
  group,
2156
2109
  groupKey,
2157
2110
  items,
2158
- children
2111
+ children: content
2159
2112
  });
2160
2113
  }
2161
- return (0, react_jsx_runtime.jsx)(require_resource_page_router.NavChromeBoundaryProvider, {
2162
- claim: claimed,
2114
+ return (0, react_jsx_runtime.jsx)(require_resource_page_router.NavChromeMountedProvider, {
2115
+ value: true,
2163
2116
  children: content
2164
2117
  });
2165
2118
  }
@@ -2172,10 +2125,12 @@ function Chevron() {
2172
2125
  "aria-hidden": "true"
2173
2126
  });
2174
2127
  }
2175
- function Breadcrumbs(props) {
2128
+ function Breadcrumbs(input) {
2129
+ const props = input;
2176
2130
  const { leadingSegments, className, docScopes, "data-testid": testId } = props;
2177
2131
  const app = (0, _burojs_react.useApp)();
2178
- const def = props.resource === void 0 ? void 0 : app.registry.get(props.resource);
2132
+ const resource = props.resource === void 0 ? void 0 : (0, _burojs_core.routeResourceKey)(props.resource);
2133
+ const def = resource === void 0 ? void 0 : app.registry.get(resource);
2179
2134
  const tid = (0, _burojs_react.useTestIds)();
2180
2135
  const t = (0, _burojs_react.useOptionalT)();
2181
2136
  const RouterLink = require_toaster.useLinkComponent();
@@ -2230,7 +2185,12 @@ function Breadcrumbs(props) {
2230
2185
  "data-testid": testId,
2231
2186
  children: [
2232
2187
  leading(resourceKey),
2233
- resourceIsCurrent ? current(tid.navBreadcrumb(resourceKey), resourceLabel) : (0, react_jsx_runtime.jsx)(RouterLink, {
2188
+ resourceIsCurrent ? current(tid.navBreadcrumb(resourceKey), resourceLabel) : !(0, _burojs_core.hasListPage)(def) ? (0, react_jsx_runtime.jsx)("span", {
2189
+ "data-testid": tid.navBreadcrumb(resourceKey),
2190
+ className: "truncate",
2191
+ title: resourceLabel,
2192
+ children: resourceLabel
2193
+ }) : (0, react_jsx_runtime.jsx)(RouterLink, {
2234
2194
  href: listHref,
2235
2195
  "data-testid": tid.navBreadcrumb(resourceKey),
2236
2196
  className: require_use_theme.cn(LINK_CLASS, "truncate"),
@@ -2306,15 +2266,15 @@ function RecordBreadcrumbs() {
2306
2266
  }
2307
2267
  //#endregion
2308
2268
  //#region src/layout/default-nav-layouts.ts
2309
- const defaultNavLayouts = {
2310
- [require_resource_page_router.layoutSlot("secondary-sidebar")]: SecondarySidebarLayout,
2311
- [require_resource_page_router.layoutSlot("tabs")]: TabsLayout
2312
- };
2269
+ const defaultNavLayouts = { ...require_resource_page_router.BUILTIN_LAYOUTS };
2313
2270
  //#endregion
2314
2271
  //#region src/layout/context-picker.tsx
2315
- function ContextPicker({ sliceName, label, options, value, onChange, placeholder, disabled, className, hideLabel }) {
2272
+ const ALL = "\0all";
2273
+ function ContextPicker({ sliceName, label, options, value, onChange, placeholder, disabled, className, hideLabel, allOption }) {
2316
2274
  const tid = (0, _burojs_react.useTestIds)();
2317
2275
  const t = (0, _burojs_react.useOptionalT)();
2276
+ const chromeT = (0, _burojs_react.useChromeT)();
2277
+ const allLabel = typeof allOption === "string" ? allOption : chromeT("scope.all", { defaultValue: "All" });
2318
2278
  const displayLabel = label ?? (0, _burojs_core.humanizeKey)(sliceName);
2319
2279
  return (0, react_jsx_runtime.jsxs)("div", {
2320
2280
  className: require_use_theme.cn("space-y-1", className),
@@ -2323,23 +2283,114 @@ function ContextPicker({ sliceName, label, options, value, onChange, placeholder
2323
2283
  className: hideLabel ? "sr-only" : "text-xs font-medium text-muted-foreground uppercase tracking-wide",
2324
2284
  children: displayLabel
2325
2285
  }), (0, react_jsx_runtime.jsxs)(require_filter_builder.Select, {
2326
- value: value ?? "",
2327
- onValueChange: onChange,
2286
+ value: value ?? (allOption === void 0 ? "" : ALL),
2287
+ onValueChange: (next) => {
2288
+ if (allOption === void 0) onChange(next);
2289
+ else onChange(next === ALL ? null : next);
2290
+ },
2328
2291
  disabled,
2329
2292
  children: [(0, react_jsx_runtime.jsx)(require_filter_builder.SelectTrigger, {
2330
2293
  id: `context-picker:${sliceName}`,
2331
2294
  "data-testid": tid.contextPicker(sliceName),
2332
2295
  className: require_use_theme.cn("w-full", hideLabel ? "h-8 text-xs" : void 0),
2333
2296
  children: (0, react_jsx_runtime.jsx)(require_filter_builder.SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
2334
- }), (0, react_jsx_runtime.jsx)(require_filter_builder.SelectContent, { children: options.map((o) => (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
2297
+ }), (0, react_jsx_runtime.jsxs)(require_filter_builder.SelectContent, { children: [allOption === void 0 ? null : (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
2298
+ value: ALL,
2299
+ "data-testid": tid.contextPickerOption(sliceName, "all"),
2300
+ children: allLabel
2301
+ }), options.map((o) => (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
2335
2302
  value: o.value,
2336
2303
  "data-testid": tid.contextPickerOption(sliceName, o.value),
2337
2304
  children: o.label
2338
- }, o.value)) })]
2305
+ }, o.value))] })]
2339
2306
  })]
2340
2307
  });
2341
2308
  }
2342
2309
  //#endregion
2310
+ //#region src/layout/scope-dimension-picker.tsx
2311
+ function ScopeDimensionPicker(props) {
2312
+ const scope = (0, _burojs_react.useScope)();
2313
+ const definition = scope.definition?.dimensions[props.dimension];
2314
+ if (definition === void 0) throw new Error(`ScopeDimensionPicker: '${props.dimension}' is not a dimension of the app's defineScope(...)`);
2315
+ if (definition.select === "none") return null;
2316
+ const source = definition.values;
2317
+ if (source === void 0) throw new Error(`ScopeDimensionPicker: dimension '${props.dimension}' declares no values; add values: { resource } or a { value, label } list`);
2318
+ const allowed = scope.access[props.dimension]?.allowed;
2319
+ const permitted = Array.isArray(allowed) ? allowed : void 0;
2320
+ const common = {
2321
+ ...props,
2322
+ multiple: definition.select === "multiple",
2323
+ all: definition.all,
2324
+ selected: scope.selection[props.dimension] ?? null,
2325
+ select: (value) => scope.select(props.dimension, value)
2326
+ };
2327
+ if (Array.isArray(source)) {
2328
+ const options = source.filter((option) => permitted === void 0 || permitted.includes(option.value));
2329
+ return (0, react_jsx_runtime.jsx)(DimensionControl, {
2330
+ ...common,
2331
+ options
2332
+ });
2333
+ }
2334
+ const { resource, label } = source;
2335
+ return (0, react_jsx_runtime.jsx)(ResourceDimension, {
2336
+ ...common,
2337
+ resource,
2338
+ ...label ? { labelField: label } : {}
2339
+ });
2340
+ }
2341
+ function ResourceDimension({ resource, labelField, ...rest }) {
2342
+ const options = require_resource_page_router.useResourceDimensionOptions(rest.dimension, resource, labelField);
2343
+ return (0, react_jsx_runtime.jsx)(DimensionControl, {
2344
+ ...rest,
2345
+ options
2346
+ });
2347
+ }
2348
+ function DimensionControl({ dimension, label, hideLabel, className, multiple, all, selected, select, options }) {
2349
+ const tid = (0, _burojs_react.useTestIds)();
2350
+ const chromeT = (0, _burojs_react.useChromeT)();
2351
+ const byText = (0, react.useMemo)(() => new Map(options.map((option) => [String(option.value), option.value])), [options]);
2352
+ const textOptions = (0, react.useMemo)(() => options.map((option) => ({
2353
+ value: String(option.value),
2354
+ label: option.label
2355
+ })), [options]);
2356
+ const picked = (Array.isArray(selected) ? selected : selected === null ? [] : [selected]).map(String);
2357
+ const text = label ?? (0, _burojs_core.humanizeKey)(dimension);
2358
+ if (multiple) return (0, react_jsx_runtime.jsxs)("div", {
2359
+ className: require_use_theme.cn("space-y-1", className),
2360
+ children: [(0, react_jsx_runtime.jsx)("span", {
2361
+ className: hideLabel ? "sr-only" : "text-xs font-medium text-muted-foreground uppercase tracking-wide",
2362
+ children: text
2363
+ }), (0, react_jsx_runtime.jsx)(require_filter_builder.FacetedFilterPicker, {
2364
+ title: text,
2365
+ options: textOptions,
2366
+ selected: picked,
2367
+ ...all ? { emptyLabel: chromeT("scope.all", { defaultValue: "All" }) } : { clearable: false },
2368
+ onChange: (next) => {
2369
+ if (next.length === 0 && !all) return;
2370
+ select(next.length === 0 ? null : next.map((value) => byText.get(value) ?? value));
2371
+ },
2372
+ getTestId: (role, value) => role === "trigger" ? tid.contextPicker(dimension) : role === "option" ? tid.contextPickerOption(dimension, value ?? "") : role === "clear" ? tid.contextPickerOption(dimension, "all") : void 0
2373
+ })]
2374
+ });
2375
+ const common = {
2376
+ sliceName: dimension,
2377
+ ...label === void 0 ? {} : { label },
2378
+ options: textOptions,
2379
+ value: picked[0] ?? null,
2380
+ ...hideLabel === void 0 ? {} : { hideLabel },
2381
+ ...className === void 0 ? {} : { className }
2382
+ };
2383
+ const choose = (value) => select(value === null ? null : byText.get(value) ?? value);
2384
+ return all ? (0, react_jsx_runtime.jsx)(ContextPicker, {
2385
+ ...common,
2386
+ allOption: true,
2387
+ onChange: choose
2388
+ }) : (0, react_jsx_runtime.jsx)(ContextPicker, {
2389
+ ...common,
2390
+ onChange: choose
2391
+ });
2392
+ }
2393
+ //#endregion
2343
2394
  //#region src/layout/language-switch.tsx
2344
2395
  function LanguageSwitch({ onChange, className }) {
2345
2396
  const t = (0, _burojs_react.useOptionalT)();
@@ -2468,20 +2519,20 @@ function CommandPalette({ open, onOpenChange, children, placeholder, emptyState,
2468
2519
  }
2469
2520
  onOpenChange(next);
2470
2521
  }, [onOpenChange]);
2471
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandDialog, {
2522
+ return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandDialog, {
2472
2523
  open,
2473
2524
  onOpenChange: handleOpenChange,
2474
2525
  className,
2475
2526
  title: t("commandPalette.title", { defaultValue: "Command Palette" }),
2476
2527
  description: t("commandPalette.description", { defaultValue: "Search and run actions." }),
2477
2528
  children: [
2478
- (0, react_jsx_runtime.jsx)(require_search_access.CommandInput, {
2529
+ (0, react_jsx_runtime.jsx)(require_relation_create.CommandInput, {
2479
2530
  placeholder: resolvedPlaceholder,
2480
2531
  "data-testid": inputTestId
2481
2532
  }),
2482
- (0, react_jsx_runtime.jsxs)(require_search_access.CommandList, {
2533
+ (0, react_jsx_runtime.jsxs)(require_relation_create.CommandList, {
2483
2534
  "data-testid": dialogTestId,
2484
- children: [resolvedEmpty !== null && !hasAsyncResults && (0, react_jsx_runtime.jsx)(require_search_access.CommandEmpty, {
2535
+ children: [resolvedEmpty !== null && !hasAsyncResults && (0, react_jsx_runtime.jsx)(require_relation_create.CommandEmpty, {
2485
2536
  "data-testid": emptyTestId,
2486
2537
  children: resolvedEmpty
2487
2538
  }), (0, react_jsx_runtime.jsx)(CommandPaletteResultsContext.Provider, {
@@ -2528,7 +2579,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2528
2579
  const navigate = (0, _burojs_react.useRouteNavigate)();
2529
2580
  const isVisible = require_resource_page_router.useNavVisible();
2530
2581
  const resolveLayout = require_resource_page_router.useLayoutResolver();
2531
- const isResourceVisible = (r) => (0, _burojs_core.evaluateVisible)(r.visible, visibilityCtx);
2582
+ const isResourceVisible = require_resource_page_router.useResourceVisible();
2532
2583
  const pageAllowed = require_resource_page_router.usePageAllowed();
2533
2584
  const isPageVisible = (p) => (0, _burojs_core.evaluateVisible)(p.visible, visibilityCtx) && pageAllowed(p);
2534
2585
  const { topLevelResources, topLevelPages, sectionGroups } = (0, react.useMemo)(() => {
@@ -2559,13 +2610,13 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2559
2610
  const resourceLabel = (def) => (0, _burojs_core.resolveResourceLabel)(caps, require_resource_page_router.canonicalResourceKey(def), "plural", def);
2560
2611
  const pageLabel = (def) => (0, _burojs_core.resolveNavLabel)(caps, `pages.${require_resource_page_router.canonicalNavKey(def)}`, (0, _burojs_core.declaredText)("chrome", def, "label"));
2561
2612
  const groups = [];
2562
- if (topLevelResources.length > 0) groups.push((0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2613
+ if (topLevelResources.length > 0) groups.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2563
2614
  heading: t("commandPalette.resources", { defaultValue: "Resources" }),
2564
2615
  children: topLevelResources.map((def) => {
2565
2616
  const resource = require_resource_page_router.canonicalResourceKey(def);
2566
2617
  const label = resourceLabel(def);
2567
2618
  const href = (0, _burojs_core.hrefFor)(app.registry, resource, { isVisible });
2568
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2619
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2569
2620
  value: `resource:${resource}:${label}`,
2570
2621
  onSelect: () => goTo(href),
2571
2622
  "data-testid": getTestId?.("resource", resource),
@@ -2573,13 +2624,13 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2573
2624
  }, `resource:${resource}`);
2574
2625
  })
2575
2626
  }, "resources"));
2576
- if (topLevelPages.length > 0) groups.push((0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2627
+ if (topLevelPages.length > 0) groups.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2577
2628
  heading: t("commandPalette.pages", { defaultValue: "Pages" }),
2578
2629
  children: topLevelPages.map((page) => {
2579
2630
  const pageKey = require_resource_page_router.canonicalNavKey(page);
2580
2631
  const label = pageLabel(page);
2581
2632
  const href = page.path;
2582
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2633
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2583
2634
  value: `page:${pageKey}:${page.path}:${label}`,
2584
2635
  onSelect: () => goTo(href),
2585
2636
  "data-testid": getTestId?.("page", pageKey),
@@ -2590,9 +2641,9 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2590
2641
  for (const { section, children } of sectionGroups) {
2591
2642
  const sectionKey = require_resource_page_router.canonicalNavKey(section);
2592
2643
  const sectionLabel = (0, _burojs_core.resolveNavLabel)(caps, `sections.${sectionKey}`, (0, _burojs_core.declaredText)("chrome", section, "label"));
2593
- groups.push((0, react_jsx_runtime.jsxs)(require_search_access.CommandGroup, {
2644
+ groups.push((0, react_jsx_runtime.jsxs)(require_relation_create.CommandGroup, {
2594
2645
  heading: sectionLabel,
2595
- children: [(0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2646
+ children: [(0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2596
2647
  value: `section:${sectionKey}:${sectionLabel}`,
2597
2648
  disabled: true,
2598
2649
  className: "font-medium opacity-70",
@@ -2603,7 +2654,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2603
2654
  const pageKey = require_resource_page_router.canonicalNavKey(child);
2604
2655
  const href = child.path;
2605
2656
  const label = pageLabel(child);
2606
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2657
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2607
2658
  value: `section:${sectionKey}:page:${pageKey}:${child.path}:${label}`,
2608
2659
  onSelect: () => goTo(href),
2609
2660
  "data-testid": getTestId?.("page", `${sectionKey}:${pageKey}`),
@@ -2614,7 +2665,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2614
2665
  const resource = require_resource_page_router.canonicalResourceKey(child);
2615
2666
  const label = resourceLabel(child);
2616
2667
  const href = (0, _burojs_core.hrefFor)(app.registry, resource, { isVisible });
2617
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2668
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2618
2669
  value: `section:${sectionKey}:resource:${resource}:${label}`,
2619
2670
  onSelect: () => goTo(href),
2620
2671
  "data-testid": getTestId?.("resource", `${sectionKey}:${resource}`),
@@ -2630,7 +2681,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2630
2681
  const groupKey = require_resource_page_router.canonicalNavKey(group);
2631
2682
  const label = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2632
2683
  const href = (0, _burojs_core.navHrefFor)(app.registry, groupKey, { isVisible });
2633
- items.push((0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2684
+ items.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2634
2685
  value: `group:${idPath}:${label}`,
2635
2686
  onSelect: () => goTo(href),
2636
2687
  "data-testid": getTestId?.("group", idPath),
@@ -2651,7 +2702,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2651
2702
  const pageKey = require_resource_page_router.canonicalNavKey(page);
2652
2703
  const label = pageLabel(page);
2653
2704
  const href = page.path;
2654
- items.push((0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2705
+ items.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2655
2706
  value: `page:${idPath}:${pageKey}:${label}`,
2656
2707
  onSelect: () => goTo(href),
2657
2708
  "data-testid": getTestId?.("page", `${idPath}:${pageKey}`),
@@ -2666,7 +2717,7 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2666
2717
  const resourceId = require_resource_page_router.canonicalResourceKey(resource);
2667
2718
  const label = resourceLabel(resource);
2668
2719
  const href = (0, _burojs_core.hrefFor)(app.registry, resourceId, { isVisible });
2669
- items.push((0, react_jsx_runtime.jsx)(require_search_access.CommandItem, {
2720
+ items.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandItem, {
2670
2721
  value: `resource:${idPath}:${resourceId}:${label}`,
2671
2722
  onSelect: () => goTo(href),
2672
2723
  "data-testid": getTestId?.("resource", `${idPath}:${resourceId}`),
@@ -2683,13 +2734,13 @@ function CommandPaletteNavigationGroups({ onSelect, getTestId }) {
2683
2734
  const items = collectGroupItems(group, groupKey, 0);
2684
2735
  if (items.length === 0) continue;
2685
2736
  const heading = (0, _burojs_core.resolveNavLabel)(caps, `groups.${groupKey}`, (0, _burojs_core.declaredText)("chrome", group, "label"));
2686
- groups.push((0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2737
+ groups.push((0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2687
2738
  heading,
2688
2739
  children: items
2689
2740
  }, `group:${groupKey}`));
2690
2741
  }
2691
2742
  if (groups.length === 0) return null;
2692
- return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: groups.map((group, idx) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [idx > 0 && (0, react_jsx_runtime.jsx)(require_search_access.CommandSeparator, {}), group] }, `navgrp-${idx}`)) });
2743
+ return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: groups.map((group, idx) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [idx > 0 && (0, react_jsx_runtime.jsx)(require_relation_create.CommandSeparator, {}), group] }, `navgrp-${idx}`)) });
2693
2744
  }
2694
2745
  //#endregion
2695
2746
  //#region src/layout/quick-targets.ts
@@ -2702,10 +2753,10 @@ function opensInQuick(registry, resource, mode) {
2702
2753
  }
2703
2754
  //#endregion
2704
2755
  //#region src/layout/command-palette-recent-group.tsx
2705
- function entryHref(registry, entry, visibilityCtx) {
2756
+ function entryHref(registry, entry, isResourceVisible) {
2706
2757
  const def = registry.get(entry.canonicalRef);
2707
2758
  if (def === void 0) return void 0;
2708
- if (!(0, _burojs_core.evaluateVisible)(def.visible, visibilityCtx)) return void 0;
2759
+ if (!isResourceVisible(def)) return void 0;
2709
2760
  for (const action of ["show", "edit"]) if (require_place_node.recordRouteAvailable(registry, entry.canonicalRef, action)) return (0, _burojs_core.hrefFor)(registry, entry.canonicalRef, {
2710
2761
  action,
2711
2762
  id: entry.id
@@ -2719,27 +2770,39 @@ function CommandPaletteRecentGroup({ onSelect, getTestId, heading, refreshKey, w
2719
2770
  const navigate = (0, _burojs_react.useRouteNavigate)();
2720
2771
  const quick = (0, _burojs_react.useQuick)();
2721
2772
  const userId = (0, _burojs_react.useCurrentUserId)();
2722
- const visibilityCtx = (0, _burojs_react.useVisibilityCtx)();
2773
+ const isResourceVisible = require_resource_page_router.useResourceVisible();
2723
2774
  const resolvedHeading = heading ?? t("commandPalette.recent", { defaultValue: "Recent" });
2724
- const [hydrated, setHydrated] = (0, react.useState)(false);
2775
+ const store = (0, _burojs_react.usePlatformStorage)().local;
2776
+ const [stored, setStored] = (0, react.useState)([]);
2725
2777
  (0, react.useEffect)(() => {
2726
- setHydrated(true);
2727
- }, []);
2728
- const recents = (0, react.useMemo)(() => {
2729
- if (!hydrated || userId === null) return [];
2730
- return require_resource_page_router.readRecentRecords(userId).flatMap((entry) => {
2731
- const href = entryHref(app.registry, entry, visibilityCtx);
2732
- return href === void 0 ? [] : [{
2733
- entry,
2734
- href
2735
- }];
2736
- });
2778
+ if (userId === null) {
2779
+ setStored([]);
2780
+ return;
2781
+ }
2782
+ let current = true;
2783
+ const read = require_resource_page_router.readRecentRecords(store, userId);
2784
+ if (Array.isArray(read)) setStored(read);
2785
+ else read.then((entries) => {
2786
+ if (current) setStored(entries);
2787
+ }, () => void 0);
2788
+ return () => {
2789
+ current = false;
2790
+ };
2737
2791
  }, [
2738
- hydrated,
2792
+ store,
2739
2793
  userId,
2740
- refreshKey,
2794
+ refreshKey
2795
+ ]);
2796
+ const recents = (0, react.useMemo)(() => stored.flatMap((entry) => {
2797
+ const href = entryHref(app.registry, entry, isResourceVisible);
2798
+ return href === void 0 ? [] : [{
2799
+ entry,
2800
+ href
2801
+ }];
2802
+ }), [
2803
+ stored,
2741
2804
  app.registry,
2742
- visibilityCtx
2805
+ isResourceVisible
2743
2806
  ]);
2744
2807
  if (((0, cmdk.useCommandState)((state) => state.search) ?? "").length > 0) return null;
2745
2808
  if (recents.length === 0) return null;
@@ -2748,7 +2811,7 @@ function CommandPaletteRecentGroup({ onSelect, getTestId, heading, refreshKey, w
2748
2811
  if (href === null) quick.show(entry.canonicalRef, entry.id);
2749
2812
  else navigate(href);
2750
2813
  };
2751
- return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2814
+ return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2752
2815
  heading: resolvedHeading,
2753
2816
  children: recents.map(({ entry, href }) => (0, react_jsx_runtime.jsx)(RecentItem, {
2754
2817
  entry,
@@ -2756,7 +2819,7 @@ function CommandPaletteRecentGroup({ onSelect, getTestId, heading, refreshKey, w
2756
2819
  onGo: goTo,
2757
2820
  ...getTestId === void 0 ? {} : { getTestId }
2758
2821
  }, `recent:${entry.canonicalRef}:${entry.id}`))
2759
- }, "recent"), withSeparator && (0, react_jsx_runtime.jsx)(require_search_access.CommandSeparator, {})] });
2822
+ }, "recent"), withSeparator && (0, react_jsx_runtime.jsx)(require_relation_create.CommandSeparator, {})] });
2760
2823
  }
2761
2824
  function RecentItem({ entry, href, onGo, getTestId }) {
2762
2825
  const app = (0, _burojs_react.useApp)();
@@ -2769,7 +2832,7 @@ function RecentItem({ entry, href, onGo, getTestId }) {
2769
2832
  const candidates = def?.recordTitle === void 0 ? [...declared.filter((name) => require_resource_page_router.RECENT_LABEL_KEYS.includes(name)), ...def?.displayField === void 0 ? [] : [def.displayField]] : declared;
2770
2833
  const legacyTrusted = entry.label === entry.id || access.status === "ready" && candidates.every((name) => access.fieldVisible(name));
2771
2834
  const shown = entry.labelField === void 0 ? legacyTrusted ? entry.label : entry.id : access.status === "ready" && access.fieldVisible(entry.labelField) ? entry.label : entry.id;
2772
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
2835
+ return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
2773
2836
  value: `recent:${key}:${resourceLabel}:${shown}`,
2774
2837
  onSelect: () => onGo(href, entry),
2775
2838
  "data-testid": getTestId?.("recent", key),
@@ -2792,7 +2855,7 @@ function resolveDisplayField(def) {
2792
2855
  const isSearchable = (fieldName) => {
2793
2856
  const fieldDef = fields[fieldName];
2794
2857
  if (!fieldDef) return false;
2795
- const canonical = require_place_node.lowerLegacyField(fieldDef);
2858
+ const canonical = require_filter_builder.lowerLegacyField(fieldDef);
2796
2859
  return canonical.type === "string" && canonical.format !== "enum";
2797
2860
  };
2798
2861
  if (def.displayField && isSearchable(def.displayField)) return def.displayField;
@@ -2804,25 +2867,26 @@ function CommandPaletteRecordsGroup({ enabled = true, pageSize = 5, minQueryLeng
2804
2867
  const t = (0, _burojs_react.useOptionalT)();
2805
2868
  const navigate = (0, _burojs_react.useRouteNavigate)();
2806
2869
  const quick = (0, _burojs_react.useQuick)();
2870
+ const isResourceVisible = require_resource_page_router.useResourceVisible();
2807
2871
  const resolvedHeading = heading ?? t("commandPalette.records", { defaultValue: "Records" });
2808
2872
  const liveQuery = (0, cmdk.useCommandState)((state) => state.search) ?? "";
2809
2873
  const debouncedQuery = (0, _burojs_react.useDebouncedValue)(liveQuery, debounceMs);
2810
2874
  const searchableResources = (0, react.useMemo)(() => {
2811
- return app.registry.list().filter((r) => require_place_node.isShowAvailable(app.registry, require_resource_page_router.canonicalResourceKey(r)) || opensInQuick(app.registry, require_resource_page_router.canonicalResourceKey(r), "show")).map((def) => {
2875
+ return app.registry.list().filter((r) => require_place_node.isShowAvailable(app.registry, require_resource_page_router.canonicalResourceKey(r)) || opensInQuick(app.registry, require_resource_page_router.canonicalResourceKey(r), "show")).filter(isResourceVisible).map((def) => {
2812
2876
  const displayField = resolveDisplayField(def);
2813
2877
  return displayField ? {
2814
2878
  def,
2815
2879
  displayField
2816
2880
  } : null;
2817
2881
  }).filter((entry) => entry !== null);
2818
- }, [app.registry]);
2882
+ }, [app.registry, isResourceVisible]);
2819
2883
  if (!(enabled && debouncedQuery.length >= minQueryLength && searchableResources.length > 0)) return null;
2820
2884
  const goTo = (href, resource, id) => {
2821
2885
  onSelect?.();
2822
2886
  if (href === null) quick.show(resource, id);
2823
2887
  else navigate(href);
2824
2888
  };
2825
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
2889
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2826
2890
  heading: resolvedHeading,
2827
2891
  forceMount: true,
2828
2892
  children: searchableResources.map(({ def, displayField }) => (0, react_jsx_runtime.jsx)(PerResourceSearchHits, {
@@ -2864,14 +2928,16 @@ function PerResourceSearchHits({ def, displayField, query, pageSize, goTo, recor
2864
2928
  }, [report, rows.length]);
2865
2929
  if (rows.length === 0) return null;
2866
2930
  const resourceLabel = (0, _burojs_core.resolveResourceLabel)(caps, require_resource_page_router.canonicalResourceKey(def), "single", def);
2931
+ const declaredIdField = def.data?.idField;
2932
+ const idField = typeof declaredIdField === "string" && declaredIdField.length > 0 ? declaredIdField : "id";
2867
2933
  return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: rows.map((row) => {
2868
- const idVal = row.id ?? row.event_id ?? row.job_id;
2934
+ const idVal = row[idField] ?? row.id ?? row.event_id ?? row.job_id;
2869
2935
  const id = idVal == null ? "" : String(idVal);
2870
2936
  if (!id) return null;
2871
2937
  const display = titleVisible ? row[displayField] : void 0;
2872
2938
  const labelText = typeof display === "string" && display.length > 0 ? display : id;
2873
2939
  const href = recordHref ? recordHref(resource, id) : require_place_node.isShowAvailable(registry, resource) ? (0, _burojs_core.resourceShowHref)(registry, def, resource, id) : null;
2874
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
2940
+ return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
2875
2941
  value: `record:${resource}:${id}:${labelText}`,
2876
2942
  forceMount: true,
2877
2943
  onSelect: () => goTo(href, resource, id),
@@ -2973,7 +3039,7 @@ function CommandPaletteActionsGroup({ actions, onSelect, getTestId, heading }) {
2973
3039
  onSelect?.();
2974
3040
  }
2975
3041
  };
2976
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
3042
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
2977
3043
  heading: resolvedHeading,
2978
3044
  children: items.map((item) => {
2979
3045
  const value = [
@@ -2983,7 +3049,7 @@ function CommandPaletteActionsGroup({ actions, onSelect, getTestId, heading }) {
2983
3049
  item.label,
2984
3050
  item.keywords ?? ""
2985
3051
  ].filter((s) => s.length > 0).join(":");
2986
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
3052
+ return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
2987
3053
  value,
2988
3054
  className: require_use_theme.cn(item.disabled && "opacity-60"),
2989
3055
  onSelect: () => {
@@ -3010,7 +3076,7 @@ function CommandPaletteActionsGroup({ actions, onSelect, getTestId, heading }) {
3010
3076
  function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, heading, createHref, prefix }) {
3011
3077
  const caps = (0, _burojs_react.useI18nCaps)();
3012
3078
  const app = (0, _burojs_react.useApp)();
3013
- const visibilityCtx = (0, _burojs_react.useVisibilityCtx)();
3079
+ const isResourceVisible = require_resource_page_router.useResourceVisible();
3014
3080
  const gate = (0, _burojs_react.useAvailabilityGate)();
3015
3081
  const t = (0, _burojs_react.useOptionalT)();
3016
3082
  const navigate = (0, _burojs_react.useRouteNavigate)();
@@ -3018,11 +3084,11 @@ function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, headin
3018
3084
  const resolvedHeading = heading ?? t("commandPalette.create", { defaultValue: "Create" });
3019
3085
  const resolvedPrefix = prefix ?? t("commandPalette.createNew", { defaultValue: "Create new" });
3020
3086
  const visibleResources = (0, react.useMemo)(() => {
3021
- return app.registry.list().filter((r) => (0, _burojs_core.hasListPage)(r)).filter((r) => gate(require_resource_page_router.canonicalResourceKey(r), "create").state === "available").filter((r) => (0, _burojs_core.hasRecordPage)(r, "create") || opensInQuick(app.registry, require_resource_page_router.canonicalResourceKey(r), "create")).filter((r) => (0, _burojs_core.evaluateVisible)(r.visible, visibilityCtx)).filter((r) => resourceFilter ? resourceFilter(r) : true);
3087
+ return app.registry.list().filter((r) => (0, _burojs_core.hasListPage)(r)).filter((r) => gate(require_resource_page_router.canonicalResourceKey(r), "create").state === "available").filter((r) => (0, _burojs_core.hasRecordPage)(r, "create") || opensInQuick(app.registry, require_resource_page_router.canonicalResourceKey(r), "create")).filter(isResourceVisible).filter((r) => resourceFilter ? resourceFilter(r) : true);
3022
3088
  }, [
3023
3089
  app,
3024
3090
  gate,
3025
- visibilityCtx,
3091
+ isResourceVisible,
3026
3092
  resourceFilter
3027
3093
  ]);
3028
3094
  if (visibleResources.length === 0) return null;
@@ -3039,14 +3105,14 @@ function CommandPaletteCreateGroup({ resourceFilter, onSelect, getTestId, headin
3039
3105
  quick.create(require_resource_page_router.canonicalResourceKey(def));
3040
3106
  };
3041
3107
  const resourceLabel = (def) => (0, _burojs_core.resolveResourceLabel)(caps, require_resource_page_router.canonicalResourceKey(def), "single", def);
3042
- return (0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, {
3108
+ return (0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, {
3043
3109
  heading: resolvedHeading,
3044
3110
  children: visibleResources.map((def) => {
3045
3111
  const resource = require_resource_page_router.canonicalResourceKey(def);
3046
3112
  const label = resourceLabel(def);
3047
3113
  const href = createHref?.(def) ?? (0, _burojs_core.resourceCreateHref)(app.registry, def, resource);
3048
3114
  const value = `create:${resource}:${resolvedPrefix}:${label}`;
3049
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
3115
+ return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
3050
3116
  value,
3051
3117
  onSelect: () => createIn(def, href),
3052
3118
  "data-testid": getTestId?.("create", resource),
@@ -3104,7 +3170,7 @@ function AppActions() {
3104
3170
  variant: "outline",
3105
3171
  size: "sm",
3106
3172
  disabled: action.disabledReason !== void 0,
3107
- title: action.disabledReason,
3173
+ title: action.disabledReason === void 0 ? void 0 : require_check_confirm_dialog.reasonText(caps, action.disabledReason),
3108
3174
  "data-testid": `app-action:${action.name}`,
3109
3175
  children: action.disabledReason === void 0 ? (0, react_jsx_runtime.jsx)(RouterLink, {
3110
3176
  href,
@@ -3226,6 +3292,7 @@ function localizedSchema(t) {
3226
3292
  function LoginForm({ onSubmit, title, description, className }) {
3227
3293
  const tid = (0, _burojs_react.useTestIds)();
3228
3294
  const t = (0, _burojs_react.useOptionalT)();
3295
+ const caps = (0, _burojs_react.useI18nCaps)();
3229
3296
  const resolvedTitle = title ?? t("auth.signIn", { defaultValue: "Sign in" });
3230
3297
  const { register, handleSubmit, formState: { errors, isSubmitting } } = (0, react_hook_form.useForm)({
3231
3298
  resolver: (0, _hookform_resolvers_zod.zodResolver)(localizedSchema(t)),
@@ -3240,9 +3307,11 @@ function LoginForm({ onSubmit, title, description, className }) {
3240
3307
  try {
3241
3308
  await onSubmit(values);
3242
3309
  } catch (e) {
3243
- const raw = e instanceof Error ? e.message : String(e);
3310
+ const dataCode = e !== null && typeof e === "object" && !(e instanceof Error) ? e.code : void 0;
3311
+ const raw = e instanceof Error ? e.message : require_toaster.technicalText(e) ?? (dataCode === void 0 ? String(e) : "");
3244
3312
  const friendly = require_toaster.toFriendlyError(raw, "", require_toaster.friendlyStringsFrom(t));
3245
- setSubmitError(friendly.replaced ? `${friendly.title}. ${friendly.detail}` : credentialsMessage(raw, t));
3313
+ const credentials = credentialsMessage(raw, t);
3314
+ setSubmitError(friendly.replaced ? `${friendly.title}. ${friendly.detail}` : typeof dataCode === "string" && credentials === raw ? (0, _burojs_react.resolveErrorText)(e, caps) : credentials);
3246
3315
  }
3247
3316
  });
3248
3317
  return (0, react_jsx_runtime.jsxs)(Card, {
@@ -3367,9 +3436,108 @@ function AuthPage({ children, brand, footer, className }) {
3367
3436
  });
3368
3437
  }
3369
3438
  //#endregion
3439
+ //#region src/enum/enum-choice-group.tsx
3440
+ const NONE = "__none__";
3441
+ function isEmpty$1(value) {
3442
+ return value === null || value === void 0 || value === "";
3443
+ }
3444
+ function EnumChoiceGroup({ control, options, value, onChange, testid, name, id, required, disabled, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className }) {
3445
+ const t = (0, _burojs_react.useOptionalT)();
3446
+ const generatedName = react.useId();
3447
+ const groupName = name ?? generatedName;
3448
+ const empty = isEmpty$1(value);
3449
+ const noneLabel = t("field.none", { defaultValue: "None" });
3450
+ const pick = (next) => {
3451
+ if (!disabled) onChange(next);
3452
+ };
3453
+ const ariaProps = {
3454
+ "aria-invalid": ariaInvalid || void 0,
3455
+ "aria-describedby": ariaDescribedBy,
3456
+ ...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {}
3457
+ };
3458
+ if (control === "segmented") {
3459
+ const segment = (key, label, active, select) => (0, react_jsx_runtime.jsx)("button", {
3460
+ type: "button",
3461
+ "aria-pressed": active,
3462
+ "data-state": active ? "active" : "inactive",
3463
+ "data-testid": `${testid}:option:${key}`,
3464
+ disabled,
3465
+ onClick: select,
3466
+ className: require_use_theme.cn("inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all", "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs", "disabled:pointer-events-none disabled:opacity-50", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"),
3467
+ children: label
3468
+ }, key);
3469
+ return (0, react_jsx_runtime.jsxs)("div", {
3470
+ role: "group",
3471
+ id,
3472
+ "aria-labelledby": ariaLabelledBy,
3473
+ "data-testid": testid,
3474
+ className: require_use_theme.cn("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", className),
3475
+ ...ariaProps,
3476
+ children: [required ? null : segment(NONE, noneLabel, empty, () => pick(void 0)), options.map((option) => segment(option.value, (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [option.icon ? (0, react_jsx_runtime.jsx)("span", {
3477
+ "data-testid": `${testid}:option:${option.value}:icon`,
3478
+ className: "contents",
3479
+ children: (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
3480
+ name: option.icon,
3481
+ className: "size-3.5 shrink-0"
3482
+ })
3483
+ }) : null, option.label] }), value === option.value, () => pick(option.value)))]
3484
+ });
3485
+ }
3486
+ const cards = control === "cards";
3487
+ const choice = (key, option, label, checked, select) => {
3488
+ const inputId = `${id ?? groupName}:${key}`;
3489
+ return (0, react_jsx_runtime.jsxs)("label", {
3490
+ htmlFor: inputId,
3491
+ className: require_use_theme.cn("flex items-start gap-2.5", cards && "cursor-pointer rounded-lg border px-3 py-2.5 transition-colors hover:bg-accent/50 has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring", cards && (checked ? "border-primary" : "border-input"), disabled && "cursor-not-allowed opacity-60"),
3492
+ children: [(0, react_jsx_runtime.jsx)("input", {
3493
+ type: "radio",
3494
+ id: inputId,
3495
+ name: groupName,
3496
+ value: key,
3497
+ checked,
3498
+ onChange: select,
3499
+ disabled,
3500
+ ...ariaProps,
3501
+ "data-testid": `${testid}:option:${key}`,
3502
+ className: require_use_theme.cn("h-4 w-4 shrink-0 accent-primary", cards ? "mt-0.5" : "mt-1")
3503
+ }), (0, react_jsx_runtime.jsxs)("span", {
3504
+ className: "flex min-w-0 flex-col gap-0.5",
3505
+ children: [(0, react_jsx_runtime.jsxs)("span", {
3506
+ className: require_use_theme.cn("flex items-center gap-1.5", cards && "font-medium"),
3507
+ children: [option?.icon ? (0, react_jsx_runtime.jsx)("span", {
3508
+ "data-testid": `${testid}:option:${key}:icon`,
3509
+ className: "contents",
3510
+ children: (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
3511
+ name: option.icon,
3512
+ className: "size-4 shrink-0"
3513
+ })
3514
+ }) : null, (0, react_jsx_runtime.jsx)("span", { children: label })]
3515
+ }), option?.summary === void 0 || option.summary === "" ? null : (0, react_jsx_runtime.jsx)("span", {
3516
+ "data-testid": `${testid}:option:${key}:doc`,
3517
+ className: "text-sm text-muted-foreground",
3518
+ children: option.summary
3519
+ })]
3520
+ })]
3521
+ }, key);
3522
+ };
3523
+ return (0, react_jsx_runtime.jsxs)("div", {
3524
+ role: "radiogroup",
3525
+ id,
3526
+ "aria-labelledby": ariaLabelledBy,
3527
+ "data-testid": testid,
3528
+ "aria-required": required,
3529
+ className: require_use_theme.cn("flex flex-col", cards ? "gap-2" : "gap-1.5", className),
3530
+ children: [required ? null : choice(NONE, void 0, noneLabel, empty, () => pick(void 0)), options.map((option) => choice(option.value, option, option.label, value === option.value, () => pick(option.value)))]
3531
+ });
3532
+ }
3533
+ //#endregion
3370
3534
  //#region src/enum/enum-picker.tsx
3371
3535
  const ENUM_PICKER_CLEAR_SENTINEL = "__buro_clear__";
3372
- function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id, testid, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, className, clearable = false, clearLabel = "All" }) {
3536
+ function withSummary(summary) {
3537
+ return summary === void 0 ? {} : { summary };
3538
+ }
3539
+ function EnumPicker({ enumName: enumInput, value, onChange, control = "select", name, id, testid, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, className, clearable = false, clearLabel = "All" }) {
3540
+ const enumName = (0, _burojs_core_internal.enumBindingKey)(enumInput) ?? "";
3373
3541
  const app = (0, _burojs_react.useApp)();
3374
3542
  const t = (0, _burojs_react.useOptionalT)();
3375
3543
  const def = app.registry.enums.get(enumName);
@@ -3400,63 +3568,43 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
3400
3568
  children: (0, react_jsx_runtime.jsx)(require_filter_builder.SelectValue, { placeholder: t("field.loading", { defaultValue: "Loading…" }) })
3401
3569
  }), (0, react_jsx_runtime.jsx)(require_filter_builder.SelectContent, {})]
3402
3570
  });
3403
- if (error || !values) return (0, react_jsx_runtime.jsxs)("span", {
3404
- "data-testid": `${tid}:error`,
3571
+ if (error || !values) return (0, react_jsx_runtime.jsxs)(require_relation_create.LoadError, {
3572
+ surface: "picker",
3573
+ error,
3574
+ testId: `${tid}:error`,
3405
3575
  className: "text-muted-foreground",
3406
- title: error?.message,
3576
+ fallback: {
3577
+ key: "relation.failed",
3578
+ default: "Failed to load options."
3579
+ },
3407
3580
  children: [
3408
3581
  "(failed to load enum ‘",
3409
3582
  enumName,
3410
3583
  "’)"
3411
3584
  ]
3412
3585
  });
3413
- if (renderAs === "radio") return (0, react_jsx_runtime.jsx)("div", {
3414
- role: "radiogroup",
3415
- "data-testid": tid,
3416
- className: require_use_theme.cn("flex flex-col gap-2", className),
3417
- "aria-required": required,
3418
- children: values.map((entry) => {
3419
- const inputId = `${id ?? tid}:${entry.value}`;
3420
- return (0, react_jsx_runtime.jsxs)("label", {
3421
- htmlFor: inputId,
3422
- className: "flex items-center gap-2",
3423
- children: [(0, react_jsx_runtime.jsx)("input", {
3424
- type: "radio",
3425
- id: inputId,
3426
- name: name ?? tid,
3427
- value: entry.value,
3428
- checked: value === entry.value,
3429
- onChange: (e) => onChange(e.target.value),
3430
- disabled,
3431
- "aria-invalid": ariaInvalid || void 0,
3432
- "aria-describedby": ariaDescribedBy,
3433
- ...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
3434
- "data-testid": `${tid}:option:${entry.value}`,
3435
- className: "h-4 w-4"
3436
- }), (0, react_jsx_runtime.jsx)("span", { children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label) })]
3437
- }, entry.value);
3438
- })
3439
- });
3440
- if (renderAs === "segmented") return (0, react_jsx_runtime.jsx)("div", {
3441
- role: "group",
3442
- "data-testid": tid,
3443
- className: require_use_theme.cn("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground", className),
3444
- "aria-invalid": ariaInvalid || void 0,
3445
- "aria-describedby": ariaDescribedBy,
3446
- ...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
3447
- children: values.map((entry) => {
3448
- const isActive = value === entry.value;
3449
- return (0, react_jsx_runtime.jsx)("button", {
3450
- type: "button",
3451
- "aria-pressed": isActive,
3452
- "data-state": isActive ? "active" : "inactive",
3453
- "data-testid": `${tid}:option:${entry.value}`,
3454
- disabled,
3455
- onClick: () => onChange(entry.value),
3456
- className: require_use_theme.cn("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all", "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs", "disabled:pointer-events-none disabled:opacity-50", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"),
3457
- children: (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label)
3458
- }, entry.value);
3459
- })
3586
+ const labelOf = (entry) => (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label);
3587
+ const summaryOf = (entry) => (0, _burojs_core.resolveDoc)(caps, `enum/${ns}/${entry.value}`)?.summary || void 0;
3588
+ if (control !== "select") return (0, react_jsx_runtime.jsx)(EnumChoiceGroup, {
3589
+ control,
3590
+ options: values.map((entry) => ({
3591
+ value: entry.value,
3592
+ label: labelOf(entry),
3593
+ ...entry.icon === void 0 ? {} : { icon: entry.icon },
3594
+ ...withSummary(summaryOf(entry))
3595
+ })),
3596
+ value,
3597
+ onChange,
3598
+ testid: tid,
3599
+ name,
3600
+ id,
3601
+ required,
3602
+ disabled,
3603
+ ariaInvalid,
3604
+ ariaDescribedBy,
3605
+ ariaErrorMessage,
3606
+ ariaLabelledBy,
3607
+ className
3460
3608
  });
3461
3609
  const selectValue = value == null ? clearable ? ENUM_PICKER_CLEAR_SENTINEL : "" : value;
3462
3610
  const handleValueChange = (next) => {
@@ -3486,36 +3634,49 @@ function EnumPicker({ enumName, value, onChange, renderAs = "select", name, id,
3486
3634
  "data-testid": `${tid}:option:__clear__`,
3487
3635
  children: clearLabel
3488
3636
  }), values.map((entry) => {
3489
- const optionLabel = (0, _burojs_core.resolveEnumLabel)(caps, ns, entry.value, (0, _burojs_core.enumValueText)(def, entry.value) ?? entry.label);
3490
- const optionDoc = (0, _burojs_core.resolveDoc)(caps, `enum/${ns}/${entry.value}`)?.summary;
3637
+ const optionLabel = labelOf(entry);
3638
+ const optionDoc = summaryOf(entry);
3491
3639
  return (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
3492
3640
  value: entry.value,
3493
3641
  "data-testid": `${tid}:option:${entry.value}`,
3494
- children: optionDoc === void 0 ? optionLabel : (0, react_jsx_runtime.jsxs)("span", {
3495
- className: "flex flex-col gap-0.5",
3496
- children: [(0, react_jsx_runtime.jsx)("span", { children: optionLabel }), (0, react_jsx_runtime.jsx)("span", {
3497
- className: "text-xs leading-snug text-muted-foreground",
3498
- "data-testid": `${tid}:option:${entry.value}:doc`,
3499
- children: optionDoc
3500
- })]
3501
- })
3642
+ description: optionDoc === void 0 ? void 0 : (0, react_jsx_runtime.jsx)("span", {
3643
+ "data-testid": `${tid}:option:${entry.value}:doc`,
3644
+ children: optionDoc
3645
+ }),
3646
+ children: optionLabel
3502
3647
  }, entry.value);
3503
3648
  })] })]
3504
3649
  });
3505
3650
  }
3506
3651
  //#endregion
3652
+ //#region src/enum/resolve-enum-control.ts
3653
+ const warned = new Set();
3654
+ function resolveEnumControl(fieldControl, enumDef, where) {
3655
+ if ((0, _burojs_core.isEnumControl)(fieldControl)) return fieldControl;
3656
+ if (fieldControl !== void 0) {
3657
+ const shown = typeof fieldControl === "string" ? `'${fieldControl}'` : String(fieldControl);
3658
+ const key = `${where}\u0000${shown}`;
3659
+ if (!warned.has(key)) {
3660
+ warned.add(key);
3661
+ console.warn(`[buro/ui-shadcn] ${where}: unknown enum control ${shown}; expected one of ${_burojs_core.ENUM_CONTROLS.map((control) => `'${control}'`).join(", ")}. Using the enum's control, else 'select'.`);
3662
+ }
3663
+ }
3664
+ return enumDef?.control ?? "select";
3665
+ }
3666
+ //#endregion
3507
3667
  //#region src/forms/issue-severity.ts
3508
3668
  function isErrorIssue(issue) {
3509
3669
  return issue.severity === "error";
3510
3670
  }
3511
3671
  //#endregion
3512
3672
  //#region src/fields/boolean.tsx
3513
- function BooleanDisplay({ value }) {
3673
+ function BooleanDisplay({ value, text }) {
3514
3674
  const t = (0, _burojs_react.useOptionalT)();
3515
3675
  if (value == null) return (0, react_jsx_runtime.jsx)("span", {
3516
3676
  className: "text-muted-foreground",
3517
3677
  children: "—"
3518
3678
  });
3679
+ if (text !== void 0) return (0, react_jsx_runtime.jsx)("span", { children: text });
3519
3680
  return (0, react_jsx_runtime.jsx)("span", { children: value ? t("boolean.yes", { defaultValue: "Yes" }) : t("boolean.no", { defaultValue: "No" }) });
3520
3681
  }
3521
3682
  function BooleanInput({ name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
@@ -3534,17 +3695,32 @@ function BooleanInput({ name, id, value, onChange, testid, disabled, required, a
3534
3695
  }
3535
3696
  //#endregion
3536
3697
  //#region src/fields/date.tsx
3537
- function DateDisplay({ value }) {
3698
+ function DateDisplay({ value, text }) {
3699
+ return (0, react_jsx_runtime.jsx)(TemporalDisplay, {
3700
+ value,
3701
+ text,
3702
+ format: require_filter_builder.formatDate
3703
+ });
3704
+ }
3705
+ function DateTimeDisplay({ value, text }) {
3706
+ return (0, react_jsx_runtime.jsx)(TemporalDisplay, {
3707
+ value,
3708
+ text,
3709
+ format: require_filter_builder.formatDateTime
3710
+ });
3711
+ }
3712
+ function TemporalDisplay({ value, text, format }) {
3538
3713
  const locale = (0, _burojs_react.useOptionalLocale)();
3539
3714
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
3540
3715
  className: "text-muted-foreground",
3541
3716
  children: "—"
3542
3717
  });
3718
+ if (text !== void 0) return (0, react_jsx_runtime.jsx)("span", { children: text });
3543
3719
  const d = new Date(String(value));
3544
3720
  if (Number.isNaN(d.getTime())) return (0, react_jsx_runtime.jsx)("span", { children: String(value) });
3545
3721
  return (0, react_jsx_runtime.jsx)("span", {
3546
3722
  className: "whitespace-nowrap",
3547
- children: require_filter_builder.formatDate(d, locale)
3723
+ children: format(d, locale)
3548
3724
  });
3549
3725
  }
3550
3726
  function toIsoDate(v) {
@@ -3555,13 +3731,29 @@ function toIsoDate(v) {
3555
3731
  if (Number.isNaN(d.getTime())) return "";
3556
3732
  return d.toISOString().slice(0, 10);
3557
3733
  }
3558
- function DateInput({ name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
3734
+ function DateInput(props) {
3735
+ return (0, react_jsx_runtime.jsx)(TemporalInput, {
3736
+ ...props,
3737
+ type: "date",
3738
+ toText: toIsoDate,
3739
+ fromText: (text) => text || null
3740
+ });
3741
+ }
3742
+ function DateTimeInput(props) {
3743
+ return (0, react_jsx_runtime.jsx)(TemporalInput, {
3744
+ ...props,
3745
+ type: "datetime-local",
3746
+ toText: require_filter_builder.toLocalDateTimeText,
3747
+ fromText: (text) => require_filter_builder.fromLocalDateTimeText(text) ?? null
3748
+ });
3749
+ }
3750
+ function TemporalInput({ type, toText, fromText, name, id, value, onChange, testid, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage }) {
3559
3751
  return (0, react_jsx_runtime.jsx)(require_input.Input, {
3560
3752
  name,
3561
3753
  id,
3562
- type: "date",
3563
- value: toIsoDate(value),
3564
- onChange: (e) => onChange(e.target.value || null),
3754
+ type,
3755
+ value: toText(value),
3756
+ onChange: (e) => onChange(fromText(e.target.value)),
3565
3757
  "data-testid": testid,
3566
3758
  disabled,
3567
3759
  required,
@@ -3573,31 +3765,15 @@ function DateInput({ name, id, value, onChange, testid, disabled, required, aria
3573
3765
  }
3574
3766
  //#endregion
3575
3767
  //#region src/fields/enum.tsx
3576
- function optionLabel(caps, field, value, inline) {
3577
- const ns = (0, _burojs_core.enumNamespaceOf)(field);
3578
- if (ns) return (0, _burojs_core.resolveEnumLabel)(caps, ns, value, inline);
3579
- return field ? (0, _burojs_core.resolveFieldOptionLabel)(caps, field.name, value, inline) : inline;
3580
- }
3581
- function declaredOptionLabel(option, value, enumDef) {
3582
- return (enumDef === void 0 ? void 0 : (0, _burojs_core.enumValueText)(enumDef, value)) ?? (typeof option?.label === "string" ? option.label : value);
3583
- }
3584
- function useBoundEnum(field) {
3585
- const app = (0, _burojs_react.useOptionalApp)();
3586
- const namespace = (0, _burojs_core.enumNamespaceOf)(field);
3587
- return namespace === void 0 ? void 0 : app?.registry.enums.get(namespace);
3588
- }
3589
- function useOptionCaps(resource) {
3590
- return (0, _burojs_react.useI18nCaps)((0, react.useContext)(_burojs_react.ResourceContext).resource ?? resource);
3591
- }
3592
3768
  function EnumDisplay({ value, options, field, resource }) {
3593
- const caps = useOptionCaps(resource);
3594
- const enumDef = useBoundEnum(field);
3769
+ const caps = (0, _burojs_react.useOptionCaps)(resource);
3770
+ const enumDef = (0, _burojs_react.useBoundEnum)(field);
3595
3771
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
3596
3772
  className: "text-muted-foreground",
3597
3773
  children: "—"
3598
3774
  });
3599
3775
  const opt = options?.find((o) => o.value === String(value));
3600
- const label = optionLabel(caps, field, String(value), declaredOptionLabel(opt, String(value), enumDef));
3776
+ const label = (0, _burojs_react.resolveOptionLabel)(caps, field, String(value), opt, enumDef);
3601
3777
  return (0, react_jsx_runtime.jsxs)("span", {
3602
3778
  className: "inline-flex items-center gap-1",
3603
3779
  children: [opt?.icon ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
@@ -3606,10 +3782,36 @@ function EnumDisplay({ value, options, field, resource }) {
3606
3782
  }) : null, label]
3607
3783
  });
3608
3784
  }
3609
- function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, resource }) {
3785
+ function EnumInput({ name, id, value, onChange, testid, options, field, placeholder, disabled, required, ariaInvalid, ariaDescribedBy, ariaErrorMessage, ariaLabelledBy, resource }) {
3610
3786
  const t = (0, _burojs_react.useOptionalT)();
3611
- const caps = useOptionCaps(resource);
3612
- const enumDef = useBoundEnum(field);
3787
+ const caps = (0, _burojs_react.useOptionCaps)(resource);
3788
+ const enumDef = (0, _burojs_react.useBoundEnum)(field);
3789
+ const ns = (0, _burojs_core.enumNamespaceOf)(field);
3790
+ const control = resolveEnumControl(field?.ui?.control, enumDef, `field ${field?.name ?? name}`);
3791
+ const resolved = (options ?? []).map((o) => {
3792
+ const summary = ns === void 0 ? void 0 : (0, _burojs_core.resolveDoc)(caps, `enum/${ns}/${o.value}`)?.summary;
3793
+ return {
3794
+ value: o.value,
3795
+ label: (0, _burojs_react.resolveOptionLabel)(caps, field, o.value, o, enumDef),
3796
+ ...o.icon === void 0 ? {} : { icon: o.icon },
3797
+ ...summary === void 0 ? {} : { summary }
3798
+ };
3799
+ });
3800
+ if (control !== "select") return (0, react_jsx_runtime.jsx)(EnumChoiceGroup, {
3801
+ control,
3802
+ options: resolved,
3803
+ value,
3804
+ onChange,
3805
+ testid: testid ?? name,
3806
+ name,
3807
+ id,
3808
+ required,
3809
+ disabled,
3810
+ ariaInvalid,
3811
+ ariaDescribedBy,
3812
+ ariaErrorMessage,
3813
+ ariaLabelledBy
3814
+ });
3613
3815
  return (0, react_jsx_runtime.jsxs)(require_filter_builder.Select, {
3614
3816
  value: value ?? "",
3615
3817
  onValueChange: onChange,
@@ -3624,14 +3826,19 @@ function EnumInput({ name, id, value, onChange, testid, options, field, placehol
3624
3826
  "aria-describedby": ariaDescribedBy,
3625
3827
  ...ariaErrorMessage ? { "aria-errormessage": ariaErrorMessage } : {},
3626
3828
  children: (0, react_jsx_runtime.jsx)(require_filter_builder.SelectValue, { placeholder: placeholder ?? t("field.select", { defaultValue: "Select…" }) })
3627
- }), (0, react_jsx_runtime.jsx)(require_filter_builder.SelectContent, { children: options?.map((o) => (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
3829
+ }), (0, react_jsx_runtime.jsx)(require_filter_builder.SelectContent, { children: resolved.map((o) => (0, react_jsx_runtime.jsx)(require_filter_builder.SelectItem, {
3628
3830
  value: o.value,
3831
+ "data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}`,
3832
+ description: o.summary === void 0 ? void 0 : (0, react_jsx_runtime.jsx)("span", {
3833
+ "data-testid": testid === void 0 ? void 0 : `${testid}:option:${o.value}:doc`,
3834
+ children: o.summary
3835
+ }),
3629
3836
  children: (0, react_jsx_runtime.jsxs)("span", {
3630
3837
  className: "inline-flex items-center gap-1.5",
3631
3838
  children: [o.icon ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.Icon, {
3632
3839
  name: o.icon,
3633
3840
  className: "size-3.5 shrink-0 text-muted-foreground"
3634
- }) : null, optionLabel(caps, field, o.value, declaredOptionLabel(o, o.value, enumDef))]
3841
+ }) : null, o.label]
3635
3842
  })
3636
3843
  }, o.value)) })]
3637
3844
  });
@@ -4054,7 +4261,7 @@ function JsonInput({ name, id, value, onChange, testid, disabled, required, aria
4054
4261
  }
4055
4262
  //#endregion
4056
4263
  //#region src/fields/lazy-relation-many.tsx
4057
- const RelationManyPickerInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./relation-many-picker-C8zFEjwd.cjs")).then((module) => ({ default: module.RelationManyPickerInput })));
4264
+ const RelationManyPickerInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./relation-many-picker-DzuGJpEl.cjs")).then((module) => ({ default: module.RelationManyPickerInput })));
4058
4265
  function LazyRelationManyInput(props) {
4059
4266
  return (0, react_jsx_runtime.jsx)(react.Suspense, {
4060
4267
  fallback: (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
@@ -4067,8 +4274,8 @@ function LazyRelationManyInput(props) {
4067
4274
  }
4068
4275
  //#endregion
4069
4276
  //#region src/fields/lazy-rich-text.tsx
4070
- const RichTextDisplay = (0, react.lazy)(() => Promise.resolve().then(() => require("./rich-text-vTyVjDoa.cjs")).then((module) => ({ default: module.RichTextDisplay })));
4071
- const RichTextInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./rich-text-vTyVjDoa.cjs")).then((module) => ({ default: module.RichTextInput })));
4277
+ const RichTextDisplay = (0, react.lazy)(() => Promise.resolve().then(() => require("./rich-text-C_7JCvRo.cjs")).then((module) => ({ default: module.RichTextDisplay })));
4278
+ const RichTextInput = (0, react.lazy)(() => Promise.resolve().then(() => require("./rich-text-C_7JCvRo.cjs")).then((module) => ({ default: module.RichTextInput })));
4072
4279
  function RichTextDisplayLoading() {
4073
4280
  const t = (0, _burojs_react.useOptionalT)();
4074
4281
  return (0, react_jsx_runtime.jsx)("div", {
@@ -4125,12 +4332,13 @@ function isIdentifier(field) {
4125
4332
  const n = field?.name;
4126
4333
  return n === "id" || typeof n === "string" && n.endsWith("_id");
4127
4334
  }
4128
- function NumberDisplay({ value, field }) {
4335
+ function NumberDisplay({ value, field, text }) {
4129
4336
  const locale = (0, _burojs_react.useOptionalLocale)();
4130
4337
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
4131
4338
  className: "text-muted-foreground",
4132
4339
  children: "—"
4133
4340
  });
4341
+ if (text !== void 0) return (0, react_jsx_runtime.jsx)("span", { children: text });
4134
4342
  let raw = value;
4135
4343
  if (typeof raw === "string") raw = unquote(raw);
4136
4344
  const n = typeof raw === "number" ? raw : Number(raw);
@@ -4167,10 +4375,9 @@ function NumberInput({ name, id, value, onChange, testid, placeholder, disabled,
4167
4375
  //#endregion
4168
4376
  //#region src/fields/link-keys-display.tsx
4169
4377
  const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4170
- function qualify(name, owner) {
4378
+ function qualify(name) {
4171
4379
  try {
4172
- const namespace = (0, _burojs_core.normalizeEntityRef)(owner).namespace;
4173
- const ref = (0, _burojs_core.normalizeEntityRef)(name, { defaultNamespace: namespace });
4380
+ const ref = (0, _burojs_core.normalizeEntityRef)(name);
4174
4381
  return ref.namespace === "default" ? ref.id : `${ref.namespace}:${ref.id}`;
4175
4382
  } catch {
4176
4383
  return;
@@ -4195,7 +4402,7 @@ function LinkKeysDisplay(props) {
4195
4402
  const ownerDef = owner === "" ? void 0 : app.registry.get(owner);
4196
4403
  const declaration = ownerDef === void 0 ? void 0 : (0, _burojs_core.declaredField)(ownerDef, name);
4197
4404
  const link = isRecord$1(declaration) ? (0, _burojs_core.linkOf)(declaration) : void 0;
4198
- const junctionName = link === void 0 ? void 0 : qualify(link.junction, owner);
4405
+ const junctionName = link === void 0 ? void 0 : qualify(link.junction);
4199
4406
  const junctionDef = junctionName === void 0 ? void 0 : app.registry.get(junctionName);
4200
4407
  const junctionField = (key) => junctionDef === void 0 ? void 0 : (0, _burojs_core.declaredField)(junctionDef, key);
4201
4408
  const ownerField = link === void 0 ? idFieldOf(ownerDef) : byOf(junctionField(link.sourceKey)) ?? idFieldOf(ownerDef);
@@ -4203,11 +4410,11 @@ function LinkKeysDisplay(props) {
4203
4410
  const ownerKey = record?.[ownerField];
4204
4411
  const { keys, complete, isLoading, error } = (0, _burojs_react.useLinkKeys)(owner, name, ownerKey);
4205
4412
  const [missed, setMissed] = (0, react.useState)(() => new Set());
4206
- const onMiss = (0, react.useCallback)((key, miss) => {
4413
+ const onMiss = (0, react.useCallback)((key, isMiss) => {
4207
4414
  setMissed((current) => {
4208
- if (current.has(key) === miss) return current;
4415
+ if (current.has(key) === isMiss) return current;
4209
4416
  const next = new Set(current);
4210
- if (miss) next.add(key);
4417
+ if (isMiss) next.add(key);
4211
4418
  else next.delete(key);
4212
4419
  return next;
4213
4420
  });
@@ -4227,12 +4434,17 @@ function LinkKeysDisplay(props) {
4227
4434
  targetBy
4228
4435
  ]);
4229
4436
  const chipsId = tid.linkChips(owner, name);
4230
- if (error) return (0, react_jsx_runtime.jsx)("span", {
4231
- "data-testid": tid.linkError(owner, name),
4232
- role: "status",
4437
+ if (error) return (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
4438
+ surface: "relation",
4439
+ error,
4440
+ ...typeof target === "string" ? { resource: target } : {},
4441
+ testId: tid.linkError(owner, name),
4233
4442
  className: "text-destructive text-xs",
4234
- title: error.message,
4235
- children: t("fields.link.failed", { defaultValue: "Links could not be loaded" })
4443
+ attributes: { role: "status" },
4444
+ fallback: {
4445
+ key: "field.link.failed",
4446
+ default: "Links could not be loaded"
4447
+ }
4236
4448
  });
4237
4449
  if (keys === void 0) {
4238
4450
  if (!isLoading) return (0, react_jsx_runtime.jsx)("span", {
@@ -4252,7 +4464,7 @@ function LinkKeysDisplay(props) {
4252
4464
  children: (0, react_jsx_runtime.jsx)("span", {
4253
4465
  "data-testid": tid.linkIncomplete(owner, name),
4254
4466
  className: "text-muted-foreground",
4255
- children: t("fields.link.incomplete", {
4467
+ children: t("field.link.incomplete", {
4256
4468
  count: keys.length,
4257
4469
  defaultValue: "More than {{count}} links"
4258
4470
  })
@@ -4274,7 +4486,7 @@ function LinkKeysDisplay(props) {
4274
4486
  }, String(key))), hidden > 0 ? (0, react_jsx_runtime.jsx)("span", {
4275
4487
  "data-testid": tid.linkHidden(owner, name),
4276
4488
  className: `${chipClassName} text-muted-foreground`,
4277
- children: t("fields.link.hidden", {
4489
+ children: t("field.link.hidden", {
4278
4490
  count: hidden,
4279
4491
  defaultValue: "{{count}} not visible"
4280
4492
  })
@@ -4293,7 +4505,7 @@ function LinkChip({ value, field, onMiss }) {
4293
4505
  const answer = to === void 0 ? void 0 : gate(to, "show");
4294
4506
  if (!(to !== void 0 && answer !== void 0 && answer.state !== "undecided" && answer.state !== "hidden" && answer.state !== "disabled")) return (0, react_jsx_runtime.jsx)("span", {
4295
4507
  className: chipClassName,
4296
- children: (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4508
+ children: (0, react_jsx_runtime.jsx)(require_relation_create.RelationDisplay, {
4297
4509
  value,
4298
4510
  field
4299
4511
  })
@@ -4322,7 +4534,7 @@ function ReadChip({ to, value, field, onMiss }) {
4322
4534
  if (miss) return null;
4323
4535
  return (0, react_jsx_runtime.jsx)("span", {
4324
4536
  className: chipClassName,
4325
- children: (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4537
+ children: (0, react_jsx_runtime.jsx)(require_relation_create.RelationDisplay, {
4326
4538
  value,
4327
4539
  field
4328
4540
  })
@@ -4344,7 +4556,7 @@ function RelationManyDisplay(props) {
4344
4556
  return (0, react_jsx_runtime.jsx)("span", {
4345
4557
  className: "inline-flex flex-wrap gap-x-2",
4346
4558
  "data-testid": "relation-many-display",
4347
- children: keys.map((key, index) => (0, react_jsx_runtime.jsx)(require_search_access.RelationDisplay, {
4559
+ children: keys.map((key, index) => (0, react_jsx_runtime.jsx)(require_relation_create.RelationDisplay, {
4348
4560
  value: key,
4349
4561
  field
4350
4562
  }, `${String(key)}:${index}`))
@@ -4362,7 +4574,7 @@ const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
4362
4574
  path: []
4363
4575
  }] };
4364
4576
  const issues = [];
4365
- const { to, by, resolve, searchField, candidates } = value;
4577
+ const { to, by, resolve, searchField, candidates, scope } = value;
4366
4578
  if (to !== void 0 && !(typeof to === "string" && to.length > 0) && !(isRecord(to) && (typeof to.id === "string" || isRecord(to.ref)))) issues.push({
4367
4579
  message: "must be a resource name or reference",
4368
4580
  path: ["to"]
@@ -4383,16 +4595,21 @@ const relationMetaSchema = Object.freeze({ "~standard": Object.freeze({
4383
4595
  message: "must be an array of conditions",
4384
4596
  path: ["candidates"]
4385
4597
  });
4598
+ if (scope !== void 0 && scope !== "context" && scope !== "session" && scope !== "none") issues.push({
4599
+ message: "must be 'context', 'session' or 'none'",
4600
+ path: ["scope"]
4601
+ });
4386
4602
  return issues.length > 0 ? { issues } : { value };
4387
4603
  }
4388
4604
  }) });
4389
4605
  //#endregion
4390
4606
  //#region src/fields/text.tsx
4391
- function TextDisplay({ value }) {
4607
+ function TextDisplay({ value, text: formatted }) {
4392
4608
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
4393
4609
  className: "text-muted-foreground",
4394
4610
  children: "—"
4395
4611
  });
4612
+ if (formatted !== void 0) return (0, react_jsx_runtime.jsx)("span", { children: formatted });
4396
4613
  const { text, isStructured } = require_place_node.toDisplayText(value);
4397
4614
  return isStructured ? (0, react_jsx_runtime.jsx)("span", {
4398
4615
  className: "font-mono text-xs break-all",
@@ -4421,23 +4638,26 @@ function TextInput({ name, id, value, onChange, testid, placeholder, disabled, r
4421
4638
  }
4422
4639
  //#endregion
4423
4640
  //#region src/fields/textarea.tsx
4424
- function TextareaDisplay({ value }) {
4641
+ function TextareaDisplay({ value, text: formatted }) {
4425
4642
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
4426
4643
  className: "text-muted-foreground",
4427
4644
  children: "—"
4428
4645
  });
4429
- const { text, isStructured } = require_place_node.toDisplayText(value);
4646
+ const { text, isStructured } = formatted === void 0 ? require_place_node.toDisplayText(value) : {
4647
+ text: formatted,
4648
+ isStructured: false
4649
+ };
4430
4650
  return (0, react_jsx_runtime.jsx)("pre", {
4431
4651
  className: isStructured ? "whitespace-pre-wrap break-all font-mono text-xs" : "whitespace-pre-wrap font-sans text-sm",
4432
4652
  children: text
4433
4653
  });
4434
4654
  }
4435
- function CodeDisplay({ value, presentation, testid }) {
4655
+ function CodeDisplay({ value, text: formatted, presentation, testid }) {
4436
4656
  if (value == null || value === "") return (0, react_jsx_runtime.jsx)("span", {
4437
4657
  className: "text-muted-foreground",
4438
4658
  children: "—"
4439
4659
  });
4440
- const { text } = require_place_node.toDisplayText(value);
4660
+ const text = formatted ?? require_place_node.toDisplayText(value).text;
4441
4661
  return (0, react_jsx_runtime.jsx)("pre", {
4442
4662
  "data-testid": testid,
4443
4663
  className: presentation === "plain" ? "overflow-x-auto whitespace-pre font-mono text-xs leading-relaxed" : "overflow-x-auto whitespace-pre rounded-md border bg-muted/40 p-3 font-mono text-xs leading-relaxed",
@@ -4481,13 +4701,12 @@ function TextareaInput({ name, id, value, onChange, testid, placeholder, disable
4481
4701
  //#endregion
4482
4702
  //#region src/fields/default-renderers.ts
4483
4703
  function legacyField(props) {
4484
- const name = typeof props.path.at(-1) === "string" ? props.path.at(-1) : "field";
4704
+ const name = (0, _burojs_react.optionFieldName)(props.path);
4485
4705
  const texts = props.field.texts;
4486
4706
  return Object.freeze({
4487
4707
  name,
4488
4708
  meta: props.meta,
4489
4709
  ui: props.ui,
4490
- codec: props.field.codec,
4491
4710
  ...texts === void 0 ? {} : { texts }
4492
4711
  });
4493
4712
  }
@@ -4509,6 +4728,7 @@ function display(renderer) {
4509
4728
  return function ShadcnDisplay(props) {
4510
4729
  return (0, react.createElement)(renderer, {
4511
4730
  value: props.value,
4731
+ ...props.text === void 0 ? {} : { text: props.text },
4512
4732
  multiple: props.multiple,
4513
4733
  field: legacyField(props),
4514
4734
  options: legacyOptions(props.options, props.field),
@@ -4546,12 +4766,14 @@ function input(renderer) {
4546
4766
  ariaInvalid: props.issues.some(isErrorIssue),
4547
4767
  ariaDescribedBy: props.accessibility.description,
4548
4768
  ariaErrorMessage: props.accessibility.error,
4769
+ ariaLabelledBy: props.accessibility.label,
4549
4770
  field: legacyField(props),
4550
4771
  resource: props.resource.id,
4551
4772
  record: props.record,
4552
4773
  relationSeeds: props.relationSeeds,
4553
4774
  fixedFilters: props.fixedFilters,
4554
- metaSources: props.metaSources
4775
+ metaSources: props.metaSources,
4776
+ link: props.link
4555
4777
  });
4556
4778
  };
4557
4779
  }
@@ -4599,9 +4821,27 @@ function scalarOrCollection(renderer, layout) {
4599
4821
  });
4600
4822
  }
4601
4823
  function enumName(ui) {
4602
- const value = ui.enum;
4603
- if (typeof value === "string" && value.length > 0) return value;
4604
- if (value !== null && typeof value === "object" && typeof value.id === "string") return value.id;
4824
+ return (0, _burojs_core_internal.enumBindingKey)(ui.enum);
4825
+ }
4826
+ function RegistryEnumInput(props) {
4827
+ const app = (0, _burojs_react.useOptionalApp)();
4828
+ const control = resolveEnumControl(props.ui.control, app?.registry.enums.get(props.enumName), `field ${typeof props.path.at(-1) === "string" ? String(props.path.at(-1)) : props.enumName}`);
4829
+ return (0, react.createElement)(EnumPicker, {
4830
+ enumName: props.enumName,
4831
+ control,
4832
+ value: props.value == null ? void 0 : String(props.value),
4833
+ onChange: props.onChange ?? (() => void 0),
4834
+ name: props.accessibility.input,
4835
+ id: props.accessibility.input,
4836
+ testid: props.testIds.input,
4837
+ placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
4838
+ disabled: props.disabled,
4839
+ required: props.field.required === true,
4840
+ ariaInvalid: props.issues.some(isErrorIssue),
4841
+ ariaDescribedBy: props.accessibility.description,
4842
+ ariaErrorMessage: props.accessibility.error,
4843
+ ariaLabelledBy: props.accessibility.label
4844
+ });
4605
4845
  }
4606
4846
  function enumAware(renderer, layout) {
4607
4847
  const FallbackInput = input(renderer.Input);
@@ -4611,19 +4851,9 @@ function enumAware(renderer, layout) {
4611
4851
  return Object.freeze({
4612
4852
  Input: (props) => {
4613
4853
  const name = enumName(props.ui);
4614
- if (name !== void 0) return (0, react.createElement)(EnumPicker, {
4615
- enumName: name,
4616
- value: props.value == null ? void 0 : String(props.value),
4617
- onChange: props.onChange ?? (() => void 0),
4618
- name: props.accessibility.input,
4619
- id: props.accessibility.input,
4620
- testid: props.testIds.input,
4621
- placeholder: typeof props.ui.placeholder === "string" ? props.ui.placeholder : void 0,
4622
- disabled: props.disabled,
4623
- required: props.field.required === true,
4624
- ariaInvalid: props.issues.some(isErrorIssue),
4625
- ariaDescribedBy: props.accessibility.description,
4626
- ariaErrorMessage: props.accessibility.error
4854
+ if (name !== void 0) return (0, react.createElement)(RegistryEnumInput, {
4855
+ ...props,
4856
+ enumName: name
4627
4857
  });
4628
4858
  if (props.options.length > 0) return (0, react.createElement)(OptionedInput, props);
4629
4859
  return (0, react.createElement)(FallbackInput, props);
@@ -4658,6 +4888,10 @@ const date = {
4658
4888
  Display: DateDisplay,
4659
4889
  Input: DateInput
4660
4890
  };
4891
+ const dateTime = {
4892
+ Display: DateTimeDisplay,
4893
+ Input: DateTimeInput
4894
+ };
4661
4895
  const en = {
4662
4896
  Display: EnumDisplay,
4663
4897
  Input: EnumInput
@@ -4667,7 +4901,7 @@ const ta = {
4667
4901
  Input: TextareaInput
4668
4902
  };
4669
4903
  const rel = {
4670
- Display: require_search_access.RelationDisplay,
4904
+ Display: require_relation_create.RelationDisplay,
4671
4905
  Input: require_relation_picker.RelationPickerInput
4672
4906
  };
4673
4907
  const file = {
@@ -4693,9 +4927,9 @@ const shadcnFieldImplementations = Object.freeze({
4693
4927
  number: scalar(num),
4694
4928
  boolean: scalar(bool),
4695
4929
  date: scalar(date),
4696
- dateTime: scalar(date),
4697
- "date-time": scalar(date),
4698
- "default:date-time": scalar(date),
4930
+ dateTime: scalar(dateTime),
4931
+ "date-time": scalar(dateTime),
4932
+ "default:date-time": scalar(dateTime),
4699
4933
  enum: enumAware(en),
4700
4934
  json: scalar({
4701
4935
  Display: JsonDisplay,
@@ -4712,313 +4946,6 @@ const shadcnFieldImplementations = Object.freeze({
4712
4946
  file: scalarOrCollection(file, { size: "full" })
4713
4947
  });
4714
4948
  //#endregion
4715
- //#region src/fields/use-relation-picker.tsx
4716
- const noop = () => void 0;
4717
- function safeKey(input) {
4718
- if (input === void 0 || input === null) return void 0;
4719
- try {
4720
- return (0, _burojs_core.resourceKey)(input);
4721
- } catch {
4722
- return;
4723
- }
4724
- }
4725
- function sessionIdentity(runtime) {
4726
- const state = runtime.dataSession.getState();
4727
- const snapshot = state.status === "ready" ? state.snapshot : state.target;
4728
- let scopeKey;
4729
- try {
4730
- scopeKey = JSON.stringify(snapshot.scopeKey) ?? "";
4731
- } catch {
4732
- scopeKey = String(snapshot.scopeKey);
4733
- }
4734
- return {
4735
- sessionKey: snapshot.sessionKey,
4736
- scopeKey
4737
- };
4738
- }
4739
- function PickerHost(props) {
4740
- const { register } = props;
4741
- react.useEffect(() => register(), [register]);
4742
- return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.children });
4743
- }
4744
- function useRelationPicker(options) {
4745
- const app = (0, _burojs_react.useApp)();
4746
- const runtime = (0, _burojs_react.useDataRuntime)();
4747
- const frame = (0, _burojs_react.useOptionalRecordFrame)();
4748
- const frames = (0, _burojs_react.useRecordScopeFrames)();
4749
- const multiple = options.multiple === true;
4750
- const fieldName = options.field;
4751
- let to;
4752
- let declaredBy;
4753
- let declaredCandidates;
4754
- if (fieldName !== void 0) {
4755
- const meta = ((frame === null ? void 0 : app.registry.get(frame.resource)?.fields)?.[fieldName])?.meta;
4756
- to = safeKey(meta?.to);
4757
- declaredBy = typeof meta?.by === "string" ? meta.by : void 0;
4758
- declaredCandidates = Array.isArray(meta?.candidates) ? meta.candidates : void 0;
4759
- } else to = safeKey(options.to);
4760
- const target = to ?? "";
4761
- const by = options.valueField ?? declaredBy;
4762
- const scope = options.scope ?? "context";
4763
- const selection = require_candidates_gate.useCandidateSelection({
4764
- to,
4765
- candidates: options.candidates ?? declaredCandidates,
4766
- sources: frame?.controller.sources,
4767
- resource: frame?.resource ?? "",
4768
- fieldName: fieldName ?? target,
4769
- fixedFilters: options.fixedFilters
4770
- });
4771
- const held = selection.gate !== void 0;
4772
- const pendingRef = react.useRef(null);
4773
- const [active, setActive] = react.useState(null);
4774
- const activeRef = react.useRef(null);
4775
- activeRef.current = active;
4776
- const rowsRef = react.useRef(new Map());
4777
- const createdRowRef = react.useRef(void 0);
4778
- const alive = react.useRef(true);
4779
- const mounts = react.useRef(0);
4780
- const sequence = react.useRef(0);
4781
- const latest = react.useRef({
4782
- multiple,
4783
- select: options.select,
4784
- idField: "id",
4785
- valueField: "id",
4786
- available: false,
4787
- frames
4788
- });
4789
- const project = react.useCallback((row) => {
4790
- const select = latest.current.select;
4791
- if (select === void 0) return { ...row };
4792
- const out = {};
4793
- const key = row.id !== void 0 ? row.id : row[latest.current.idField];
4794
- if (key !== void 0) out.id = key;
4795
- const { valueField } = latest.current;
4796
- if (Object.hasOwn(row, valueField)) out[valueField] = row[valueField];
4797
- for (const name of select) if (Object.hasOwn(row, name)) out[name] = row[name];
4798
- return out;
4799
- }, []);
4800
- const settle = react.useCallback((result) => {
4801
- const pending = pendingRef.current;
4802
- if (pending === null) return;
4803
- pendingRef.current = null;
4804
- pending.detach();
4805
- if (alive.current) setActive(null);
4806
- pending.resolve(result);
4807
- }, []);
4808
- const toggle = react.useCallback((key, row) => {
4809
- setActive((current) => {
4810
- if (current === null) return current;
4811
- const has = current.selected.some((k) => String(k) === String(key));
4812
- if (has) rowsRef.current.delete(String(key));
4813
- else if (row !== void 0) rowsRef.current.set(String(key), row);
4814
- const selected = has ? current.selected.filter((k) => String(k) !== String(key)) : [...current.selected, key];
4815
- const next = {
4816
- ...current,
4817
- selected
4818
- };
4819
- activeRef.current = next;
4820
- return next;
4821
- });
4822
- }, []);
4823
- const onValue = react.useCallback((value) => {
4824
- const row = createdRowRef.current;
4825
- createdRowRef.current = void 0;
4826
- if (latest.current.multiple) {
4827
- const current = activeRef.current;
4828
- if (current !== null && !current.selected.some((k) => String(k) === String(value))) toggle(value, row);
4829
- return;
4830
- }
4831
- settle({
4832
- kind: "selected",
4833
- keys: [value],
4834
- rows: row === void 0 ? [] : [project(row)]
4835
- });
4836
- }, [
4837
- project,
4838
- settle,
4839
- toggle
4840
- ]);
4841
- const wiring = require_relation_picker.useRelationSelect({
4842
- to: target,
4843
- by,
4844
- fixedFilters: selection.fixedFilters,
4845
- scope,
4846
- ...fieldName === void 0 ? {} : { scopeField: fieldName },
4847
- held,
4848
- onValue
4849
- });
4850
- latest.current = {
4851
- multiple,
4852
- select: options.select,
4853
- idField: wiring.idField,
4854
- valueField: wiring.valueField,
4855
- available: to !== void 0 && wiring.targetDef !== void 0 && !held,
4856
- frames
4857
- };
4858
- const { create: shared } = wiring;
4859
- const create = react.useMemo(() => ({
4860
- ...shared,
4861
- start: (openCreate) => shared.start(() => {
4862
- const opened = openCreate();
4863
- opened.then((row) => {
4864
- createdRowRef.current = row === null ? void 0 : { ...row };
4865
- }, noop);
4866
- return opened;
4867
- })
4868
- }), [shared]);
4869
- react.useEffect(() => runtime.dataSession.subscribe(() => {
4870
- const pending = pendingRef.current;
4871
- if (pending === null) return;
4872
- const now = sessionIdentity(runtime);
4873
- if (now.sessionKey !== pending.sessionKey || now.scopeKey !== pending.scopeKey) settle({
4874
- kind: "cancelled",
4875
- reason: "session-changed"
4876
- });
4877
- }), [runtime, settle]);
4878
- react.useEffect(() => {
4879
- alive.current = true;
4880
- return () => {
4881
- alive.current = false;
4882
- settle({
4883
- kind: "cancelled",
4884
- reason: "unmounted"
4885
- });
4886
- };
4887
- }, [settle]);
4888
- react.useEffect(() => {
4889
- if (held) settle({
4890
- kind: "cancelled",
4891
- reason: "unavailable"
4892
- });
4893
- }, [held, settle]);
4894
- const register = react.useCallback(() => {
4895
- mounts.current += 1;
4896
- return () => {
4897
- mounts.current -= 1;
4898
- if (mounts.current === 0) settle({
4899
- kind: "cancelled",
4900
- reason: "unmounted"
4901
- });
4902
- };
4903
- }, [settle]);
4904
- const open = react.useCallback((opts = {}) => new Promise((resolve) => {
4905
- settle({
4906
- kind: "cancelled",
4907
- reason: "superseded"
4908
- });
4909
- if (mounts.current === 0) {
4910
- if (process.env.NODE_ENV !== "production") console.error("[burojs] useRelationPicker: open() was called but its element is not rendered — render `handle.element` once in your tree.");
4911
- resolve({
4912
- kind: "cancelled",
4913
- reason: "not-mounted"
4914
- });
4915
- return;
4916
- }
4917
- const { signal } = opts;
4918
- if (signal?.aborted === true) {
4919
- resolve({
4920
- kind: "cancelled",
4921
- reason: "aborted"
4922
- });
4923
- return;
4924
- }
4925
- if (!latest.current.available) {
4926
- resolve({
4927
- kind: "cancelled",
4928
- reason: "unavailable"
4929
- });
4930
- return;
4931
- }
4932
- sequence.current += 1;
4933
- const id = sequence.current;
4934
- const onAbort = () => {
4935
- if (pendingRef.current?.id === id) settle({
4936
- kind: "cancelled",
4937
- reason: "aborted"
4938
- });
4939
- };
4940
- signal?.addEventListener("abort", onAbort, { once: true });
4941
- pendingRef.current = {
4942
- id,
4943
- ...sessionIdentity(runtime),
4944
- resolve,
4945
- detach: () => signal?.removeEventListener("abort", onAbort)
4946
- };
4947
- rowsRef.current = new Map();
4948
- createdRowRef.current = void 0;
4949
- const next = {
4950
- id,
4951
- frames: latest.current.frames,
4952
- selected: opts.selected ?? []
4953
- };
4954
- activeRef.current = next;
4955
- setActive(next);
4956
- }), [runtime, settle]);
4957
- const onSelectRow = react.useCallback((row) => {
4958
- const field = wiring.valueField;
4959
- const value = field === "id" ? row.id : row[field];
4960
- if (typeof value !== "string" && typeof value !== "number") return;
4961
- settle({
4962
- kind: "selected",
4963
- keys: [value],
4964
- rows: [project(row)]
4965
- });
4966
- }, [
4967
- wiring.valueField,
4968
- settle,
4969
- project
4970
- ]);
4971
- const onDone = react.useCallback(() => {
4972
- const keys = activeRef.current?.selected ?? [];
4973
- const rows = keys.flatMap((key) => {
4974
- const row = rowsRef.current.get(String(key));
4975
- return row === void 0 ? [] : [project(row)];
4976
- });
4977
- settle({
4978
- kind: "selected",
4979
- keys,
4980
- rows
4981
- });
4982
- }, [settle, project]);
4983
- const onOpenChange = react.useCallback((next) => {
4984
- if (!next) settle({
4985
- kind: "cancelled",
4986
- reason: "dismissed"
4987
- });
4988
- }, [settle]);
4989
- return {
4990
- open,
4991
- element: (0, react_jsx_runtime.jsx)(PickerHost, {
4992
- register,
4993
- children: active === null || held ? null : (0, react_jsx_runtime.jsxs)(_burojs_react.RecordScopeChain, {
4994
- frames: active.frames,
4995
- children: [(0, react_jsx_runtime.jsx)(require_candidates_gate.LazyRelationPickerDialog, {
4996
- to: target,
4997
- open: true,
4998
- onOpenChange,
4999
- onSelect: noop,
5000
- onSelectRow,
5001
- valueField: wiring.valueField,
5002
- ...selection.fixedFilters === void 0 ? {} : { fixedFilters: selection.fixedFilters },
5003
- scope,
5004
- ...fieldName === void 0 ? {} : { scopeField: fieldName },
5005
- ...options.create === void 0 ? {} : {
5006
- create,
5007
- ...options.create.seeds === void 0 ? {} : { createSeeds: options.create.seeds }
5008
- },
5009
- fieldName: fieldName ?? target,
5010
- ...multiple ? {
5011
- multiple: true,
5012
- selected: active.selected,
5013
- onToggle: (value, row) => toggle(value, row),
5014
- onDone
5015
- } : {}
5016
- }), wiring.reader]
5017
- }, active.id)
5018
- })
5019
- };
5020
- }
5021
- //#endregion
5022
4949
  //#region src/forms/declarative-display.tsx
5023
4950
  function DeclarativeDisplay(props) {
5024
4951
  return (0, react_jsx_runtime.jsx)(_burojs_react.ScreenStateProvider, { children: (0, react_jsx_runtime.jsx)(DisplayBody, { ...props }) });
@@ -5044,7 +4971,8 @@ function DisplayBody(props) {
5044
4971
  }
5045
4972
  //#endregion
5046
4973
  //#region src/enum/enum-display.tsx
5047
- function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }) {
4974
+ function EnumDisplay$1({ enumName: enumInput, value, variant = "badge", testid, className }) {
4975
+ const enumName = (0, _burojs_core_internal.enumBindingKey)(enumInput) ?? "";
5048
4976
  const app = (0, _burojs_react.useApp)();
5049
4977
  const caps = (0, _burojs_react.useI18nCaps)();
5050
4978
  const def = app.registry.enums.get(enumName);
@@ -5092,159 +5020,6 @@ function EnumDisplay$1({ enumName, value, variant = "badge", testid, className }
5092
5020
  });
5093
5021
  }
5094
5022
  //#endregion
5095
- //#region src/data-table/data-table-faceted-filter.tsx
5096
- function DataTableFacetedFilter({ column, title, options = [], loadOptions, selectedLabelFor, searchPlaceholder, emptyText, getTestId, className }) {
5097
- const t = (0, _burojs_react.useOptionalT)();
5098
- const filterValue = column.getFilterValue();
5099
- const selected = (0, react.useMemo)(() => {
5100
- if (Array.isArray(filterValue)) return new Set(filterValue.map(String));
5101
- return new Set();
5102
- }, [filterValue]);
5103
- const [search, setSearch] = (0, react.useState)("");
5104
- const [asyncOptions, setAsyncOptions] = (0, react.useState)([]);
5105
- const [loading, setLoading] = (0, react.useState)(false);
5106
- const debounceRef = (0, react.useRef)(null);
5107
- const loadOptionsRef = (0, react.useRef)(loadOptions);
5108
- (0, react.useEffect)(() => {
5109
- loadOptionsRef.current = loadOptions;
5110
- });
5111
- (0, react.useEffect)(() => {
5112
- if (!loadOptionsRef.current) return;
5113
- setLoading(true);
5114
- if (debounceRef.current !== null) clearTimeout(debounceRef.current);
5115
- let cancelled = false;
5116
- debounceRef.current = setTimeout(() => {
5117
- const loader = loadOptionsRef.current;
5118
- if (!loader) return;
5119
- loader(search).then((results) => {
5120
- if (!cancelled) {
5121
- setAsyncOptions(results);
5122
- setLoading(false);
5123
- }
5124
- }).catch(() => {
5125
- if (!cancelled) setLoading(false);
5126
- });
5127
- }, 250);
5128
- return () => {
5129
- cancelled = true;
5130
- if (debounceRef.current !== null) clearTimeout(debounceRef.current);
5131
- };
5132
- }, [search]);
5133
- const effectiveOptions = loadOptions ? asyncOptions : options;
5134
- const labelFor = (value) => {
5135
- const opt = effectiveOptions.find((o) => o.value === value);
5136
- if (opt) return opt.label;
5137
- return selectedLabelFor?.(value) ?? value;
5138
- };
5139
- const toggle = (value) => {
5140
- const next = new Set(selected);
5141
- if (next.has(value)) next.delete(value);
5142
- else next.add(value);
5143
- column.setFilterValue(next.size === 0 ? void 0 : Array.from(next));
5144
- };
5145
- const selectedValues = Array.from(selected);
5146
- return (0, react_jsx_runtime.jsxs)(require_toaster.Popover, { children: [(0, react_jsx_runtime.jsx)(require_toaster.PopoverTrigger, {
5147
- asChild: true,
5148
- children: (0, react_jsx_runtime.jsxs)(require_button.Button, {
5149
- type: "button",
5150
- variant: "outline",
5151
- size: "sm",
5152
- "data-testid": getTestId?.("trigger"),
5153
- className: require_use_theme.cn("h-8 border-dashed", className),
5154
- children: [
5155
- (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCirclePlus, {
5156
- className: "mr-2 h-4 w-4",
5157
- "aria-hidden": "true"
5158
- }),
5159
- title,
5160
- selected.size > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
5161
- (0, react_jsx_runtime.jsx)("span", {
5162
- className: "mx-2 h-4 w-px bg-border",
5163
- "aria-hidden": "true"
5164
- }),
5165
- (0, react_jsx_runtime.jsx)(require_filter_builder.Badge, {
5166
- variant: "secondary",
5167
- className: "rounded-sm px-1 font-normal lg:hidden",
5168
- children: selected.size
5169
- }),
5170
- (0, react_jsx_runtime.jsx)("div", {
5171
- className: "hidden gap-1 lg:flex",
5172
- children: selected.size > 2 ? (0, react_jsx_runtime.jsx)(require_filter_builder.Badge, {
5173
- variant: "secondary",
5174
- className: "rounded-sm px-1 font-normal",
5175
- children: t("table.selectedCount", {
5176
- count: selected.size,
5177
- defaultValue: "{{count}} selected"
5178
- })
5179
- }) : selectedValues.map((value) => (0, react_jsx_runtime.jsx)(require_filter_builder.Badge, {
5180
- variant: "secondary",
5181
- className: "rounded-sm px-1 font-normal",
5182
- children: labelFor(value)
5183
- }, value))
5184
- })
5185
- ] })
5186
- ]
5187
- })
5188
- }), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
5189
- className: "w-[220px] p-0",
5190
- align: "start",
5191
- children: (0, react_jsx_runtime.jsxs)(require_search_access.Command, {
5192
- shouldFilter: !loadOptions,
5193
- children: [
5194
- (0, react_jsx_runtime.jsx)(require_search_access.CommandInput, {
5195
- placeholder: searchPlaceholder ?? title,
5196
- "data-testid": getTestId?.("search"),
5197
- ...loadOptions ? {
5198
- value: search,
5199
- onValueChange: setSearch
5200
- } : {}
5201
- }),
5202
- (0, react_jsx_runtime.jsxs)(require_search_access.CommandList, { children: [
5203
- loading && (0, react_jsx_runtime.jsx)("div", {
5204
- className: "py-6 text-center text-sm text-muted-foreground",
5205
- children: t("list.loadingShort", { defaultValue: "Loading…" })
5206
- }),
5207
- (0, react_jsx_runtime.jsx)(require_search_access.CommandEmpty, { children: emptyText ?? t("relation.noResults", { defaultValue: "No results." }) }),
5208
- (0, react_jsx_runtime.jsx)(require_search_access.CommandGroup, { children: effectiveOptions.map((opt) => {
5209
- const isSelected = selected.has(opt.value);
5210
- const Icon = opt.icon;
5211
- return (0, react_jsx_runtime.jsxs)(require_search_access.CommandItem, {
5212
- value: opt.label,
5213
- "data-testid": getTestId?.("option", opt.value),
5214
- role: "option",
5215
- "aria-selected": isSelected,
5216
- "aria-checked": isSelected,
5217
- onSelect: () => toggle(opt.value),
5218
- children: [
5219
- (0, react_jsx_runtime.jsx)("span", {
5220
- className: require_use_theme.cn("mr-2 flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border", isSelected ? "border-primary bg-primary text-primary-foreground" : "border-input opacity-50"),
5221
- "aria-hidden": "true",
5222
- children: isSelected && (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, { className: "h-3.5 w-3.5" })
5223
- }),
5224
- Icon && (0, react_jsx_runtime.jsx)(Icon, {
5225
- className: "mr-2 h-4 w-4 text-muted-foreground",
5226
- "aria-hidden": "true"
5227
- }),
5228
- (0, react_jsx_runtime.jsx)("span", {
5229
- className: "flex-1 text-left",
5230
- children: opt.label
5231
- })
5232
- ]
5233
- }, opt.value);
5234
- }) })
5235
- ] }),
5236
- selected.size > 0 && (0, react_jsx_runtime.jsx)("button", {
5237
- type: "button",
5238
- "data-testid": getTestId?.("clear"),
5239
- onClick: () => column.setFilterValue(void 0),
5240
- className: "flex w-full items-center justify-center border-t px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground",
5241
- children: t("filters.clearAll", { defaultValue: "Clear filters" })
5242
- })
5243
- ]
5244
- })
5245
- })] });
5246
- }
5247
- //#endregion
5248
5023
  //#region src/data-table/data-table-text-filter.tsx
5249
5024
  function DataTableTextFilter({ column, placeholder, testid, className }) {
5250
5025
  const external = column.getFilterValue() ?? "";
@@ -5280,7 +5055,7 @@ function DataTableTextFilter({ column, placeholder, testid, className }) {
5280
5055
  //#endregion
5281
5056
  //#region src/data-table/data-table-enum-filter.tsx
5282
5057
  function DataTableEnumFilter({ column, title, options, getTestId, className }) {
5283
- return (0, react_jsx_runtime.jsx)(DataTableFacetedFilter, {
5058
+ return (0, react_jsx_runtime.jsx)(require_filter_builder.DataTableFacetedFilter, {
5284
5059
  column,
5285
5060
  title,
5286
5061
  options,
@@ -5400,12 +5175,12 @@ const OPERATOR_LABELS = {
5400
5175
  hasAll: "has all of",
5401
5176
  hasNone: "has none of"
5402
5177
  };
5403
- function formatOperatorLabel(op, t) {
5404
- return t ? t(`filters.operators.${op}`, { defaultValue: OPERATOR_LABELS[op] }) : OPERATOR_LABELS[op];
5178
+ function formatOperatorLabel(op, chromeT) {
5179
+ return chromeT ? chromeT(`filters.operators.${op}`, { defaultValue: OPERATOR_LABELS[op] }) : OPERATOR_LABELS[op];
5405
5180
  }
5406
5181
  function useOperatorLabel() {
5407
- const t = (0, _burojs_react.useOptionalT)();
5408
- return (op) => formatOperatorLabel(op, t);
5182
+ const chromeT = (0, _burojs_react.useChromeT)();
5183
+ return (op) => formatOperatorLabel(op, chromeT);
5409
5184
  }
5410
5185
  function isEmpty(v) {
5411
5186
  return v === void 0 || v === null || v === "";
@@ -5499,7 +5274,7 @@ function DataTableOperatorFilter({ column, operators, defaultOperator, valueKind
5499
5274
  //#region src/data-table/data-table-row-actions.tsx
5500
5275
  function DataTableRowActions({ row, actions, getTestId, className }) {
5501
5276
  const [open, setOpen] = (0, react.useState)(false);
5502
- const t = (0, _burojs_react.useOptionalT)();
5277
+ const chromeT = (0, _burojs_react.useChromeT)();
5503
5278
  if (actions.length === 0) return null;
5504
5279
  return (0, react_jsx_runtime.jsxs)(require_toaster.Popover, {
5505
5280
  open,
@@ -5517,7 +5292,7 @@ function DataTableRowActions({ row, actions, getTestId, className }) {
5517
5292
  "aria-hidden": "true"
5518
5293
  }), (0, react_jsx_runtime.jsx)("span", {
5519
5294
  className: "sr-only",
5520
- children: t("actions.openMenu", { defaultValue: "Open row actions menu" })
5295
+ children: chromeT("actions.openMenu", { defaultValue: "Open row actions menu" })
5521
5296
  })]
5522
5297
  })
5523
5298
  }), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
@@ -5629,7 +5404,7 @@ function BlockScreen({ block, props, resource, record, label }) {
5629
5404
  snapshot
5630
5405
  ]);
5631
5406
  if (compiled === void 0) return (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, { className: "h-24 w-full" });
5632
- if ((0, _burojs_core.isScreenFailure)(compiled)) return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "error" });
5407
+ if ((0, _burojs_core.isScreenFailure)(compiled)) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "error" });
5633
5408
  return (0, react_jsx_runtime.jsx)(_burojs_react.RouteSourceContext.Provider, {
5634
5409
  value: null,
5635
5410
  children: (0, react_jsx_runtime.jsx)("div", {
@@ -5638,7 +5413,8 @@ function BlockScreen({ block, props, resource, record, label }) {
5638
5413
  children: (0, react_jsx_runtime.jsx)(require_resource_page_router.PlannedBody, {
5639
5414
  screen: compiled,
5640
5415
  name: "modal",
5641
- label: label ?? ""
5416
+ label: label ?? "",
5417
+ ...needsRow && row !== null ? { record: row } : {}
5642
5418
  })
5643
5419
  })
5644
5420
  });
@@ -5647,13 +5423,20 @@ function relation(field) {
5647
5423
  if (field === null || typeof field !== "object") return false;
5648
5424
  return (0, _burojs_core.isRelationField)(field);
5649
5425
  }
5426
+ const resolveOf = (bag) => bag !== null && typeof bag === "object" ? bag.resolve : void 0;
5427
+ function lazyToOne(field) {
5428
+ const entry = field;
5429
+ if (entry.kind === "relationMany" || entry.type === "array") return false;
5430
+ return (resolveOf(entry.meta) ?? resolveOf(entry.opts)) === "lazy";
5431
+ }
5650
5432
  function peekFields(def, columns, capabilityFor, fieldVisible = () => true) {
5651
5433
  const record = new Set((0, _burojs_core.dtoFields)(def, "record"));
5652
5434
  const out = [];
5653
5435
  for (const name of columns) {
5654
5436
  if (out.length === 5) break;
5655
5437
  if (name === def.displayField || out.includes(name) || !record.has(name)) continue;
5656
- if (!require_place_node.peekLeafAllowed(def, name, capabilityFor, fieldVisible) || relation(require_place_node.peekFieldDefinition(def, name))) continue;
5438
+ const field = require_place_node.peekFieldDefinition(def, name);
5439
+ if (!require_place_node.peekLeafAllowed(def, name, capabilityFor, fieldVisible) || relation(field) && !lazyToOne(field)) continue;
5657
5440
  out.push(name);
5658
5441
  }
5659
5442
  return Object.freeze(out);
@@ -5669,7 +5452,7 @@ function failure(error, retry) {
5669
5452
  };
5670
5453
  }
5671
5454
  function PeekScreen(props) {
5672
- return (0, react_jsx_runtime.jsx)(require_search_access.PeekContext.Provider, {
5455
+ return (0, react_jsx_runtime.jsx)(require_relation_create.PeekContext.Provider, {
5673
5456
  value: true,
5674
5457
  children: props.by !== void 0 ? (0, react_jsx_runtime.jsx)(PeekByKey, {
5675
5458
  target: props.target,
@@ -5736,7 +5519,7 @@ function PeekByKey({ target, by }) {
5736
5519
  } else if (query.error != null) read = failure(query.error, () => void query.refetch());
5737
5520
  else read = { state: "pending" };
5738
5521
  (0, react.useEffect)(() => {
5739
- if (read.state === "ambiguous" && process.env.NODE_ENV !== "production") console.error(`[burojs] ${(0, _burojs_core.relationAmbiguousError)(target, by.field, by.key).message}`);
5522
+ if (read.state === "ambiguous" && process.env.NODE_ENV !== "production") console.error(`[burojs] ${require_toaster.technicalText((0, _burojs_core.relationAmbiguousError)(target, by.field, by.key))}`);
5740
5523
  }, [
5741
5524
  read.state,
5742
5525
  target,
@@ -5752,6 +5535,7 @@ function PeekByKey({ target, by }) {
5752
5535
  function PeekBody({ target, peekKey, read }) {
5753
5536
  const tid = (0, _burojs_react.useTestIds)();
5754
5537
  const t = (0, _burojs_react.useOptionalT)();
5538
+ const chromeT = (0, _burojs_react.useChromeT)();
5755
5539
  const testid = tid.peek(target, peekKey);
5756
5540
  if (read.state === "pending") return (0, react_jsx_runtime.jsx)("div", {
5757
5541
  "data-testid": testid,
@@ -5779,7 +5563,7 @@ function PeekBody({ target, peekKey, read }) {
5779
5563
  variant: "outline",
5780
5564
  "data-testid": `${testid}:retry`,
5781
5565
  onClick: read.retry,
5782
- children: t("actions.retry", { defaultValue: "Retry" })
5566
+ children: chromeT("actions.retry", { defaultValue: "Retry" })
5783
5567
  })]
5784
5568
  });
5785
5569
  if (read.state === "unavailable") return (0, react_jsx_runtime.jsx)("p", {
@@ -5862,7 +5646,7 @@ function PeekRecord({ target, testid, row }) {
5862
5646
  capabilityFor,
5863
5647
  fieldVisible
5864
5648
  ]);
5865
- const host = (0, react.useContext)(require_search_access.PeekHostContext);
5649
+ const host = (0, react.useContext)(require_relation_create.PeekHostContext);
5866
5650
  const instance = (0, _burojs_react.useUIInstance)();
5867
5651
  const quickOpen = (0, _burojs_react.useQuickOpener)();
5868
5652
  const rowId = rowIdOf(def, row);
@@ -5870,9 +5654,9 @@ function PeekRecord({ target, testid, row }) {
5870
5654
  const open = (0, react.useCallback)(() => {
5871
5655
  if (!openable) return;
5872
5656
  const anchor = host?.anchor ?? null;
5873
- const anchorOpen = require_search_access.peekAnchorOpener(anchor);
5657
+ const anchorOpen = require_relation_create.peekAnchorOpener(anchor);
5874
5658
  instance.dismiss();
5875
- if (anchor?.isConnected) require_search_access.focusWithoutPeek(anchor);
5659
+ if (anchor?.isConnected) require_relation_create.focusWithoutPeek(anchor);
5876
5660
  if (anchorOpen !== void 0) anchorOpen(target, String(rowId));
5877
5661
  else quickOpen(target, String(rowId));
5878
5662
  }, [
@@ -5921,8 +5705,8 @@ function PeekRecord({ target, testid, row }) {
5921
5705
  });
5922
5706
  }
5923
5707
  function DeclaredPeekBody({ target, testid, record, frameRecord, def, capabilityFor, fieldVisible, view: View, builtin, open, openable, t }) {
5924
- const host = (0, react.useContext)(require_search_access.PeekHostContext);
5925
- const title = require_search_access.recordDisplayName(record, def?.displayField);
5708
+ const host = (0, react.useContext)(require_relation_create.PeekHostContext);
5709
+ const title = require_relation_create.recordDisplayName(record, def?.displayField);
5926
5710
  const setLabel = host?.setLabel;
5927
5711
  (0, react.useEffect)(() => setLabel?.(title), [setLabel, title]);
5928
5712
  const controller = (0, _burojs_react.useFormController)({
@@ -5993,7 +5777,7 @@ function DefaultPeekBody({ target, testid, row, open }) {
5993
5777
  namespace: "default",
5994
5778
  id: target
5995
5779
  };
5996
- const host = (0, react.useContext)(require_search_access.PeekHostContext);
5780
+ const host = (0, react.useContext)(require_relation_create.PeekHostContext);
5997
5781
  const caps = (0, _burojs_react.useI18nCaps)(target);
5998
5782
  const capabilityFor = (0, _burojs_react.useCapabilityResolver)(target, row, "show");
5999
5783
  const projection = useRecordProjection(target);
@@ -6001,13 +5785,13 @@ function DefaultPeekBody({ target, testid, row, open }) {
6001
5785
  const access = (0, _burojs_react.useFieldAccess)(target, "record", dtoRow);
6002
5786
  const projected = (0, _burojs_react.useProjectedRecord)(target, dtoRow);
6003
5787
  const record = projected.value ?? {};
6004
- const title = require_search_access.recordDisplayName(record, def?.displayField);
5788
+ const title = require_relation_create.recordDisplayName(record, def?.displayField);
6005
5789
  const setLabel = host?.setLabel;
6006
5790
  (0, react.useEffect)(() => setLabel?.(title), [setLabel, title]);
6007
5791
  const columns = (0, react.useMemo)(() => {
6008
5792
  if (def === void 0) return [];
6009
5793
  const listed = def.views?.list?.columns;
6010
- return peekFields(def, listed ?? Object.keys(def.fields), capabilityFor, (name) => access[name]?.view === "visible");
5794
+ return peekFields(def, listed?.map(_burojs_core.columnName) ?? Object.keys(def.fields), capabilityFor, (name) => access[name]?.view === "visible");
6011
5795
  }, [
6012
5796
  def,
6013
5797
  capabilityFor,
@@ -6047,13 +5831,21 @@ function DefaultPeekBody({ target, testid, row, open }) {
6047
5831
  children: (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", field, "label"))
6048
5832
  }), (0, react_jsx_runtime.jsx)("dd", {
6049
5833
  className: "min-w-0 break-words",
6050
- children: (0, react_jsx_runtime.jsx)(require_place_node.ResolvedFieldDisplay, {
6051
- resource: ref,
6052
- name,
6053
- field,
5834
+ children: (0, react_jsx_runtime.jsx)(require_place_node.FieldValueFrame, {
5835
+ field: {
5836
+ ...field,
5837
+ name
5838
+ },
6054
5839
  value,
6055
- record,
6056
- fallback: require_place_node.toDisplayText(value).text
5840
+ surface: "display",
5841
+ children: (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
5842
+ resource: ref,
5843
+ name,
5844
+ field,
5845
+ value,
5846
+ record,
5847
+ fallback: require_place_node.toDisplayText(value).text
5848
+ })
6057
5849
  })
6058
5850
  })]
6059
5851
  }, name);
@@ -6075,41 +5867,50 @@ function QuickBodyOf({ entry }) {
6075
5867
  entry,
6076
5868
  route: EMPTY_ROUTE
6077
5869
  });
6078
- if (entry.recordId === void 0 || entry.recordId === "") return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "not-found" });
6079
- return (0, react_jsx_runtime.jsx)(QuickRead, {
5870
+ if (entry.recordId === void 0 || entry.recordId === "") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
5871
+ return (0, react_jsx_runtime.jsx)(QuickReadRoute, {
6080
5872
  entry,
6081
5873
  recordId: entry.recordId
6082
5874
  });
6083
5875
  }
6084
- function QuickRead({ entry, recordId }) {
5876
+ function QuickReadRoute({ entry, recordId }) {
5877
+ const typed = (0, _burojs_react.useRouteRecordId)(entry.resource, recordId);
5878
+ if (typed === void 0) return (0, react_jsx_runtime.jsx)(require_relation_create.InvalidRouteId, { resource: entry.resource });
5879
+ return (0, react_jsx_runtime.jsx)(QuickRead, {
5880
+ entry,
5881
+ recordId,
5882
+ typedId: typed
5883
+ });
5884
+ }
5885
+ function QuickRead({ entry, recordId, typedId }) {
6085
5886
  const def = (0, _burojs_react.useApp)().registry.get(entry.resource);
6086
5887
  const projection = (0, react.useMemo)(() => def === void 0 ? void 0 : (0, _burojs_core.dtoFields)(def, "record"), [def]);
6087
5888
  const query = (0, _burojs_react.useOne)(entry.resource, {
6088
- id: recordId,
5889
+ id: typedId,
6089
5890
  retry: _burojs_react.retryRecordRead,
6090
5891
  ...projection === void 0 ? {} : { projection }
6091
5892
  });
6092
5893
  const result = query.data;
6093
5894
  if (result !== void 0) {
6094
5895
  const row = result.data;
6095
- if (row === null || typeof row !== "object") return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "not-found" });
5896
+ if (row === null || typeof row !== "object") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
6096
5897
  return (0, react_jsx_runtime.jsx)(QuickLoaded, {
6097
5898
  entry,
6098
5899
  recordId,
5900
+ typedId,
6099
5901
  row,
6100
5902
  isCurrentData: !query.isPlaceholderData
6101
5903
  });
6102
5904
  }
6103
- if (query.error != null) {
6104
- const state = require_resource_page_router.recordErrorState(query.error);
6105
- return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, {
6106
- state,
6107
- ...state === "error" ? { onRetry: () => void query.refetch() } : {}
6108
- });
6109
- }
6110
- return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "loading" });
5905
+ if (query.error != null) return (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
5906
+ surface: "record",
5907
+ resource: entry.resource,
5908
+ error: query.error,
5909
+ retry: () => void query.refetch()
5910
+ });
5911
+ return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
6111
5912
  }
6112
- function QuickLoaded({ entry, recordId, row, isCurrentData }) {
5913
+ function QuickLoaded({ entry, recordId, typedId, row, isCurrentData }) {
6113
5914
  const gate = (0, _burojs_react.useEntryGate)();
6114
5915
  const quick = (0, _burojs_react.useQuickEntry)();
6115
5916
  const answer = gate(entry.resource, entry.mode === "edit" ? "edit" : "show", row);
@@ -6125,20 +5926,20 @@ function QuickLoaded({ entry, recordId, row, isCurrentData }) {
6125
5926
  title
6126
5927
  ]);
6127
5928
  const route = (0, react.useMemo)(() => Object.freeze({ id: recordId }), [recordId]);
6128
- if (answer.state === "undecided") return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "loading" });
6129
- if (!open) return (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordState, { state: "not-found" });
5929
+ if (answer.state === "undecided") return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "loading" });
5930
+ if (!open) return (0, react_jsx_runtime.jsx)(require_relation_create.RecordState, { state: "not-found" });
6130
5931
  return (0, react_jsx_runtime.jsx)(QuickScreenOf, {
6131
5932
  entry,
6132
- route
5933
+ route,
5934
+ recordId: typedId
6133
5935
  });
6134
5936
  }
6135
5937
  function canonicalOrNull(name) {
6136
- if (typeof name !== "string") return null;
6137
5938
  try {
6138
- return require_check_confirm_dialog.canonicalResourceName(name);
6139
- } catch {
6140
- return null;
6141
- }
5939
+ if (typeof name === "string") return require_check_confirm_dialog.canonicalResourceName(name);
5940
+ if (name !== null && typeof name === "object") return (0, _burojs_core.routeResourceKey)(name);
5941
+ } catch {}
5942
+ return null;
6142
5943
  }
6143
5944
  function absorbedRedirect(to, entry) {
6144
5945
  if (typeof to !== "object" || to === null) return null;
@@ -6152,7 +5953,7 @@ function closeEntry(quick, dismiss) {
6152
5953
  if (quick.stack.entries.length > 1) quick.stack.pop();
6153
5954
  else dismiss(quick.presentationId);
6154
5955
  }
6155
- function QuickScreenOf({ entry, route }) {
5956
+ function QuickScreenOf({ entry, route, recordId }) {
6156
5957
  const quick = (0, _burojs_react.useQuickEntry)();
6157
5958
  const instance = (0, _burojs_react.useUIInstance)();
6158
5959
  const runtime = (0, _burojs_react.useUIPresentationRuntime)();
@@ -6204,7 +6005,7 @@ function QuickScreenOf({ entry, route }) {
6204
6005
  children: (0, react_jsx_runtime.jsx)(require_resource_page_router.RecordScreen, {
6205
6006
  resource: entry.resource,
6206
6007
  mode: entry.mode,
6207
- ...entry.recordId === void 0 ? {} : { recordId: entry.recordId },
6008
+ ...recordId === void 0 ? {} : { recordId },
6208
6009
  ...entry.defaults === void 0 ? {} : { defaults: entry.defaults },
6209
6010
  ...entry.input === void 0 ? {} : { input: entry.input },
6210
6011
  ...callbacks
@@ -6226,7 +6027,7 @@ function useEntryTitle(entry) {
6226
6027
  const caps = (0, _burojs_react.useI18nCaps)(entry.resource);
6227
6028
  const t = (0, _burojs_react.useOptionalT)();
6228
6029
  if (entry.mode !== "create") return entry.title ?? "";
6229
- return t("pageHeader.createTitle", { params: { label: (0, _burojs_core.resolveResourceLabel)(caps, entry.resource, "single", app.registry.get(entry.resource)) } });
6030
+ return require_place_node.resolveResourceTitle(caps, t, entry.resource, "createTitle", { label: (0, _burojs_core.resolveResourceLabel)(caps, entry.resource, "single", app.registry.get(entry.resource)) });
6230
6031
  }
6231
6032
  const HEADING_CLASS = "min-w-0 flex-1 break-words text-lg font-semibold tracking-tight focus-visible:outline-hidden";
6232
6033
  function QuickHeader({ entries }) {
@@ -6236,7 +6037,7 @@ function QuickHeader({ entries }) {
6236
6037
  const t = (0, _burojs_react.useOptionalT)();
6237
6038
  const tid = (0, _burojs_react.useTestIds)();
6238
6039
  const RouterLink = require_toaster.useLinkComponent();
6239
- const ownTitle = (0, react.useContext)(require_shell.OwnTitleContext);
6040
+ const ownTitle = (0, react.useContext)(require_check_confirm_dialog.OwnTitleContext);
6240
6041
  const top = entries[entries.length - 1];
6241
6042
  const previous = entries.length > 1 ? entries[entries.length - 2] : void 0;
6242
6043
  const title = useEntryTitle(top);
@@ -6372,7 +6173,7 @@ function wrapperEnabled(options) {
6372
6173
  //#region src/ui-presentations/dialog-host.tsx
6373
6174
  function DialogPresentationHost({ component: Component, props, options }) {
6374
6175
  const instance = (0, _burojs_react.useUIInstance)();
6375
- return (0, react_jsx_runtime.jsx)(require_shell.DialogPresentationShell, {
6176
+ return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DialogPresentationShell, {
6376
6177
  dismiss: instance.dismiss,
6377
6178
  wrapper: wrapperEnabled(options),
6378
6179
  ownTitle: options.ownTitle === true,
@@ -6453,7 +6254,7 @@ function PopoverPresentationHost({ component: Component, props, options, anchor
6453
6254
  onCloseAutoFocus: (event) => event.preventDefault(),
6454
6255
  onPointerEnter: hold,
6455
6256
  onPointerLeave: release,
6456
- children: (0, react_jsx_runtime.jsx)(require_search_access.PeekHostContext.Provider, {
6257
+ children: (0, react_jsx_runtime.jsx)(require_relation_create.PeekHostContext.Provider, {
6457
6258
  value: host,
6458
6259
  children: (0, react_jsx_runtime.jsx)(Component, { ...props })
6459
6260
  })
@@ -6465,7 +6266,7 @@ PopoverPresentationHost.optionsSchema = Object.freeze({ title: "string" });
6465
6266
  //#region src/ui-presentations/sheet-host.tsx
6466
6267
  function SheetPresentationHost({ component: Component, props, options }) {
6467
6268
  const instance = (0, _burojs_react.useUIInstance)();
6468
- return (0, react_jsx_runtime.jsx)(require_shell.SheetPresentationShell, {
6269
+ return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.SheetPresentationShell, {
6469
6270
  dismiss: instance.dismiss,
6470
6271
  wrapper: wrapperEnabled(options),
6471
6272
  ownTitle: options.ownTitle === true,
@@ -6483,11 +6284,25 @@ SheetPresentationHost.optionsSchema = Object.freeze({
6483
6284
  //#region src/ui-presentations/index.tsx
6484
6285
  function FlowScreen(props) {
6485
6286
  const loaded = require_check_confirm_dialog.useLoaded(require_check_confirm_dialog.loadFlowScreen);
6486
- if (loaded.error !== void 0) return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowLoadFailed, { onRetry: loaded.retry });
6487
- if (loaded.module === void 0) return null;
6287
+ if (loaded.error !== void 0) return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowLoadFailed, {
6288
+ label: props.label,
6289
+ onRetry: loaded.retry
6290
+ });
6291
+ if (loaded.module === void 0) return (0, react_jsx_runtime.jsxs)("div", {
6292
+ "data-buro-flow-step": "loading",
6293
+ "aria-busy": "true",
6294
+ className: "flex flex-col gap-4",
6295
+ children: [(0, react_jsx_runtime.jsx)(require_check_confirm_dialog.OwnTitleHeading, { label: props.label }), (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
6296
+ className: "h-5 w-5 animate-spin self-center",
6297
+ "aria-hidden": "true"
6298
+ })]
6299
+ });
6488
6300
  const Screen = loaded.module.FlowScreen;
6489
6301
  return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowBoundary, {
6490
- fallback: (_error, reset) => (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowLoadFailed, { onRetry: reset }),
6302
+ fallback: (_error, reset) => (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowLoadFailed, {
6303
+ label: props.label,
6304
+ onRetry: reset
6305
+ }),
6491
6306
  children: (0, react_jsx_runtime.jsx)(Screen, { ...props })
6492
6307
  });
6493
6308
  }
@@ -6762,9 +6577,13 @@ function DefaultCommandPalette({ open, onOpenChange, actions, children }) {
6762
6577
  }
6763
6578
  //#endregion
6764
6579
  //#region src/shell/app-shell.tsx
6765
- function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel, children }) {
6580
+ function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel, navChrome, children }) {
6766
6581
  const enabled = palette !== false;
6767
- const { open, setOpen } = (0, _burojs_react.useCommandPalette)({ disableShortcut: !enabled });
6582
+ const { open, setOpen, toggle } = (0, _burojs_react.useCommandPalette)();
6583
+ (0, _burojs_react_web.useGlobalShortcut)({
6584
+ key: "k",
6585
+ mod: true
6586
+ }, toggle, { enabled });
6768
6587
  const paletteState = (0, react.useMemo)(() => ({
6769
6588
  open,
6770
6589
  setOpen
@@ -6782,7 +6601,7 @@ function AppShell({ brand, user, loginPath, sidebar, header, palette, docPanel,
6782
6601
  sidebar: fill(sidebar, () => (0, react_jsx_runtime.jsx)(AppSidebar, {})),
6783
6602
  header: fill(header, () => (0, react_jsx_runtime.jsx)(AppHeader, {})),
6784
6603
  ...docPanel !== void 0 ? { docPanel } : {},
6785
- children
6604
+ children: navChrome === false ? children : (0, react_jsx_runtime.jsx)(NavChrome, { children })
6786
6605
  }), paletteNode]
6787
6606
  });
6788
6607
  }
@@ -6932,14 +6751,14 @@ exports.Collapsible = Collapsible;
6932
6751
  exports.CollapsibleContent = CollapsibleContent;
6933
6752
  exports.CollapsibleTrigger = CollapsibleTrigger;
6934
6753
  exports.ColumnsToggle = require_place_node.ColumnsToggle;
6935
- exports.Command = require_search_access.Command;
6936
- exports.CommandDialog = require_search_access.CommandDialog;
6937
- exports.CommandEmpty = require_search_access.CommandEmpty;
6938
- exports.CommandGroup = require_search_access.CommandGroup;
6939
- exports.CommandInput = require_search_access.CommandInput;
6940
- exports.CommandItem = require_search_access.CommandItem;
6941
- exports.CommandList = require_search_access.CommandList;
6942
- exports.CommandLoading = require_search_access.CommandLoading;
6754
+ exports.Command = require_relation_create.Command;
6755
+ exports.CommandDialog = require_relation_create.CommandDialog;
6756
+ exports.CommandEmpty = require_relation_create.CommandEmpty;
6757
+ exports.CommandGroup = require_relation_create.CommandGroup;
6758
+ exports.CommandInput = require_relation_create.CommandInput;
6759
+ exports.CommandItem = require_relation_create.CommandItem;
6760
+ exports.CommandList = require_relation_create.CommandList;
6761
+ exports.CommandLoading = require_relation_create.CommandLoading;
6943
6762
  exports.CommandPalette = CommandPalette;
6944
6763
  exports.CommandPaletteActionsGroup = CommandPaletteActionsGroup;
6945
6764
  exports.CommandPaletteCreateGroup = CommandPaletteCreateGroup;
@@ -6948,7 +6767,7 @@ exports.CommandPaletteNavigationGroups = CommandPaletteNavigationGroups;
6948
6767
  exports.CommandPaletteRecentGroup = CommandPaletteRecentGroup;
6949
6768
  exports.CommandPaletteRecordsGroup = CommandPaletteRecordsGroup;
6950
6769
  exports.CommandPaletteTrigger = CommandPaletteTrigger;
6951
- exports.CommandSeparator = require_search_access.CommandSeparator;
6770
+ exports.CommandSeparator = require_relation_create.CommandSeparator;
6952
6771
  exports.ContextPicker = ContextPicker;
6953
6772
  exports.CopyId = require_place_node.CopyId;
6954
6773
  exports.CreateButton = require_place_node.CreateButton;
@@ -6957,7 +6776,7 @@ exports.DEFAULT_LANGUAGE_STORAGE_KEY = _burojs_react.DEFAULT_LANGUAGE_STORAGE_KE
6957
6776
  exports.DataTable = require_place_node.DataTable;
6958
6777
  exports.DataTableDateRangeFilter = DataTableDateRangeFilter;
6959
6778
  exports.DataTableEnumFilter = DataTableEnumFilter;
6960
- exports.DataTableFacetedFilter = DataTableFacetedFilter;
6779
+ exports.DataTableFacetedFilter = require_filter_builder.DataTableFacetedFilter;
6961
6780
  exports.DataTableNumRangeFilter = DataTableNumRangeFilter;
6962
6781
  exports.DataTableOperatorFilter = DataTableOperatorFilter;
6963
6782
  exports.DataTableRowActions = DataTableRowActions;
@@ -6976,7 +6795,7 @@ exports.DialogDescription = require_dialog.DialogDescription;
6976
6795
  exports.DialogFooter = require_dialog.DialogFooter;
6977
6796
  exports.DialogHeader = require_dialog.DialogHeader;
6978
6797
  exports.DialogPresentationHost = DialogPresentationHost;
6979
- exports.DialogPresentationShell = require_shell.DialogPresentationShell;
6798
+ exports.DialogPresentationShell = require_check_confirm_dialog.DialogPresentationShell;
6980
6799
  exports.DialogTitle = require_dialog.DialogTitle;
6981
6800
  exports.DialogTrigger = require_dialog.DialogTrigger;
6982
6801
  exports.DisabledAction = require_check_confirm_dialog.DisabledAction;
@@ -7009,6 +6828,7 @@ exports.EnumPicker = EnumPicker;
7009
6828
  exports.EnumValueDisplay = EnumDisplay$1;
7010
6829
  exports.ExportButton = require_place_node.ExportButton;
7011
6830
  exports.ExportDialog = require_place_node.ExportDialog;
6831
+ exports.FacetedFilterPicker = require_filter_builder.FacetedFilterPicker;
7012
6832
  exports.Field = require_place_node.Field;
7013
6833
  exports.FieldDisplay = require_place_node.FieldDisplay;
7014
6834
  exports.FileDisplay = FileDisplay;
@@ -7050,10 +6870,8 @@ exports.ListLive = require_place_node.ListLive;
7050
6870
  exports.ListSavedViews = require_place_node.ListSavedViews;
7051
6871
  exports.ListSearchInput = require_place_node.ListSearchInput;
7052
6872
  exports.LoginForm = LoginForm;
7053
- exports.NavAreaLayout = NavAreaLayout;
7054
6873
  exports.NavAreaPage = require_resource_page_router.NavAreaPage;
7055
- exports.NavChrome = require_resource_page_router.NavChrome;
7056
- exports.NavChromeBoundaryProvider = require_resource_page_router.NavChromeBoundaryProvider;
6874
+ exports.NavChrome = NavChrome;
7057
6875
  exports.NavMain = NavMain;
7058
6876
  exports.NavigationGuardDialog = NavigationGuardDialog;
7059
6877
  exports.NumberDisplay = NumberDisplay;
@@ -7068,6 +6886,7 @@ exports.PopoverClose = require_toaster.PopoverClose;
7068
6886
  exports.PopoverContent = require_toaster.PopoverContent;
7069
6887
  exports.PopoverPresentationHost = PopoverPresentationHost;
7070
6888
  exports.PopoverTrigger = require_toaster.PopoverTrigger;
6889
+ exports.PresetFilterControls = require_filter_builder.PresetFilterControls;
7071
6890
  exports.Progress = Progress;
7072
6891
  exports.RecordActions = require_place_node.RecordActions;
7073
6892
  exports.RecordBreadcrumbs = RecordBreadcrumbs;
@@ -7075,18 +6894,19 @@ exports.RecordPage = require_resource_page_router.RecordPage;
7075
6894
  exports.RecordScreen = require_resource_page_router.RecordScreen;
7076
6895
  exports.RecordTitle = require_place_node.RecordTitle;
7077
6896
  exports.RefreshButton = RefreshButton;
7078
- exports.RelationDisplay = require_search_access.RelationDisplay;
7079
- exports.RelationField = require_search_access.RelationField;
6897
+ exports.RelationDisplay = require_relation_create.RelationDisplay;
6898
+ exports.RelationField = require_relation_create.RelationField;
7080
6899
  exports.RelationManyDisplay = RelationManyDisplay;
7081
6900
  exports.RelationPicker = require_relation_picker.RelationPicker;
7082
- exports.RelationPickerDialog = require_candidates_gate.LazyRelationPickerDialog;
6901
+ exports.RelationPickerDialog = require_lazy_relation_picker_dialog.LazyRelationPickerDialog;
7083
6902
  exports.RelationPickerInput = require_relation_picker.RelationPickerInput;
7084
6903
  exports.ResourceList = require_place_node.ResourceList;
7085
6904
  exports.ResourceListPage = require_resource_page_router.ResourceListPage;
7086
6905
  exports.ResourcePageRouter = require_resource_page_router.ResourcePageRouter;
7087
6906
  exports.SavedViewsDropdown = require_place_node.SavedViewsDropdown;
6907
+ exports.ScopeDimensionPicker = ScopeDimensionPicker;
7088
6908
  exports.ScopeSwitcher = ScopeSwitcher;
7089
- exports.SecondarySidebarLayout = SecondarySidebarLayout;
6909
+ exports.SecondarySidebarLayout = require_resource_page_router.SecondarySidebarLayout;
7090
6910
  exports.Select = require_filter_builder.Select;
7091
6911
  exports.SelectContent = require_filter_builder.SelectContent;
7092
6912
  exports.SelectGroup = require_filter_builder.SelectGroup;
@@ -7098,16 +6918,16 @@ exports.SelectSeparator = require_filter_builder.SelectSeparator;
7098
6918
  exports.SelectTrigger = require_filter_builder.SelectTrigger;
7099
6919
  exports.SelectValue = require_filter_builder.SelectValue;
7100
6920
  exports.Separator = Separator;
7101
- exports.Sheet = require_shell.Sheet;
7102
- exports.SheetClose = require_shell.SheetClose;
7103
- exports.SheetContent = require_shell.SheetContent;
7104
- exports.SheetDescription = require_shell.SheetDescription;
7105
- exports.SheetFooter = require_shell.SheetFooter;
7106
- exports.SheetHeader = require_shell.SheetHeader;
6921
+ exports.Sheet = require_check_confirm_dialog.Sheet;
6922
+ exports.SheetClose = require_check_confirm_dialog.SheetClose;
6923
+ exports.SheetContent = require_check_confirm_dialog.SheetContent;
6924
+ exports.SheetDescription = require_check_confirm_dialog.SheetDescription;
6925
+ exports.SheetFooter = require_check_confirm_dialog.SheetFooter;
6926
+ exports.SheetHeader = require_check_confirm_dialog.SheetHeader;
7107
6927
  exports.SheetPresentationHost = SheetPresentationHost;
7108
- exports.SheetPresentationShell = require_shell.SheetPresentationShell;
7109
- exports.SheetTitle = require_shell.SheetTitle;
7110
- exports.SheetTrigger = require_shell.SheetTrigger;
6928
+ exports.SheetPresentationShell = require_check_confirm_dialog.SheetPresentationShell;
6929
+ exports.SheetTitle = require_check_confirm_dialog.SheetTitle;
6930
+ exports.SheetTrigger = require_check_confirm_dialog.SheetTrigger;
7111
6931
  exports.ShellProvider = require_place_node.ShellProvider;
7112
6932
  exports.ShowPageHeader = require_place_node.ShowPageHeader;
7113
6933
  exports.Sidebar = Sidebar;
@@ -7146,7 +6966,7 @@ exports.TableHeader = require_filter_builder.TableHeader;
7146
6966
  exports.TableRow = require_filter_builder.TableRow;
7147
6967
  exports.Tabs = require_place_node.Tabs;
7148
6968
  exports.TabsContent = require_place_node.TabsContent;
7149
- exports.TabsLayout = TabsLayout;
6969
+ exports.TabsLayout = require_resource_page_router.TabsLayout;
7150
6970
  exports.TabsList = require_place_node.TabsList;
7151
6971
  exports.TabsTrigger = require_place_node.TabsTrigger;
7152
6972
  exports.TaskRunPanel = TaskRunPanel;
@@ -7164,7 +6984,7 @@ exports.TooltipProvider = require_check_confirm_dialog.TooltipProvider;
7164
6984
  exports.TooltipTrigger = require_check_confirm_dialog.TooltipTrigger;
7165
6985
  exports.UserMenu = UserMenu;
7166
6986
  exports.badgeVariants = require_filter_builder.badgeVariants;
7167
- exports.buildNavItems = require_resource_page_router.buildNavItems;
6987
+ exports.buildNavItems = buildNavItems;
7168
6988
  exports.buroSortingToTanStack = require_place_node.buroSortingToTanStack;
7169
6989
  exports.buttonVariants = require_button.buttonVariants;
7170
6990
  exports.cn = require_use_theme.cn;
@@ -7185,9 +7005,9 @@ Object.defineProperty(exports, "modeForSurface", {
7185
7005
  return _burojs_react.modeForSurface;
7186
7006
  }
7187
7007
  });
7188
- exports.recordDisplayName = require_search_access.recordDisplayName;
7008
+ exports.recordDisplayName = require_relation_create.recordDisplayName;
7189
7009
  exports.registerIcons = require_check_confirm_dialog.registerIcons;
7190
- exports.relationLinkClassName = require_search_access.relationLinkClassName;
7010
+ exports.relationLinkClassName = require_relation_create.relationLinkClassName;
7191
7011
  exports.resolveNavIcon = resolveNavIcon;
7192
7012
  exports.resolveUpdater = require_place_node.resolveUpdater;
7193
7013
  exports.saveLocale = require_filter_builder.saveLocale;
@@ -7203,7 +7023,7 @@ exports.useCurrentUser = useCurrentUser;
7203
7023
  exports.useDialogFilterState = require_use_dialog_filter_state.useDialogFilterState;
7204
7024
  exports.useDocumentTitle = require_place_node.useDocumentTitle;
7205
7025
  exports.useExportRunWatcher = require_place_node.useExportRunWatcher;
7206
- exports.useFormControl = require_resource_page_router.useFormControl;
7026
+ exports.useFormControl = require_place_node.useFormControl;
7207
7027
  exports.useFormField = useFormField;
7208
7028
  exports.useHref = require_resource_page_router.useHref;
7209
7029
  exports.useIsMobile = useIsMobile;
@@ -7214,18 +7034,23 @@ exports.useLayoutResolver = require_resource_page_router.useLayoutResolver;
7214
7034
  exports.useLinkComponent = require_toaster.useLinkComponent;
7215
7035
  exports.useListSlot = require_check_confirm_dialog.useListSlot;
7216
7036
  exports.useMatch = require_resource_page_router.useMatch;
7217
- exports.useNavChromeBoundary = require_resource_page_router.useNavChromeBoundary;
7218
7037
  exports.useNavIcon = useNavIcon;
7219
7038
  exports.useNavTree = useNavTree;
7220
7039
  exports.useNavVisible = require_resource_page_router.useNavVisible;
7221
7040
  exports.useOptionalSidebar = useOptionalSidebar;
7222
7041
  exports.usePaletteState = require_place_node.usePaletteState;
7223
7042
  exports.usePresentationCopy = usePresentationCopy;
7224
- exports.useRelationPicker = useRelationPicker;
7043
+ exports.useRelationPicker = require_place_node.useRelationPicker;
7225
7044
  exports.useShell = require_place_node.useShell;
7226
7045
  exports.useSidebar = useSidebar;
7227
7046
  exports.useTheme = require_use_theme.useTheme;
7228
7047
  exports.useThemePaletteActions = useThemePaletteActions;
7048
+ Object.defineProperty(exports, "webPlatform", {
7049
+ enumerable: true,
7050
+ get: function() {
7051
+ return _burojs_react_web.webPlatform;
7052
+ }
7053
+ });
7229
7054
  exports.wrapperEnabled = wrapperEnabled;
7230
7055
 
7231
7056
  //# sourceMappingURL=index.cjs.map