@burojs/ui-shadcn 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +22 -5
  2. package/dist/bulk-summary-CwSd6Yjb.cjs +108 -0
  3. package/dist/bulk-summary-CwSd6Yjb.cjs.map +1 -0
  4. package/dist/bulk-summary-GxMDP4bw.js +108 -0
  5. package/dist/bulk-summary-GxMDP4bw.js.map +1 -0
  6. package/dist/button-BxnnE28H.cjs +55 -0
  7. package/dist/button-BxnnE28H.cjs.map +1 -0
  8. package/dist/button-MWVeZaqj.js +44 -0
  9. package/dist/button-MWVeZaqj.js.map +1 -0
  10. package/dist/candidates-gate-Bb70LPAy.js +135 -0
  11. package/dist/candidates-gate-Bb70LPAy.js.map +1 -0
  12. package/dist/candidates-gate-D33jXLHO.cjs +153 -0
  13. package/dist/candidates-gate-D33jXLHO.cjs.map +1 -0
  14. package/dist/candidates-relation-picker-B116Bmqi.js +31 -0
  15. package/dist/candidates-relation-picker-B116Bmqi.js.map +1 -0
  16. package/dist/candidates-relation-picker-Cy0rTxvI.cjs +31 -0
  17. package/dist/candidates-relation-picker-Cy0rTxvI.cjs.map +1 -0
  18. package/dist/check-confirm-dialog--gPFnEeg.cjs +1547 -0
  19. package/dist/check-confirm-dialog--gPFnEeg.cjs.map +1 -0
  20. package/dist/check-confirm-dialog-bRT8lt0d.js +1245 -0
  21. package/dist/check-confirm-dialog-bRT8lt0d.js.map +1 -0
  22. package/dist/dialog-B_rt9S1c.js +63 -0
  23. package/dist/dialog-B_rt9S1c.js.map +1 -0
  24. package/dist/dialog-DRNUq9EA.cjs +112 -0
  25. package/dist/dialog-DRNUq9EA.cjs.map +1 -0
  26. package/dist/filter-builder-Bhn-dhZV.js +1621 -0
  27. package/dist/filter-builder-Bhn-dhZV.js.map +1 -0
  28. package/dist/filter-builder-nXqtM_h4.cjs +1789 -0
  29. package/dist/filter-builder-nXqtM_h4.cjs.map +1 -0
  30. package/dist/flow-runtime-D3avVH0I.cjs +255 -0
  31. package/dist/flow-runtime-D3avVH0I.cjs.map +1 -0
  32. package/dist/flow-runtime-s6lkRPKF.js +252 -0
  33. package/dist/flow-runtime-s6lkRPKF.js.map +1 -0
  34. package/dist/flow-screen-CCvgDI9G.js +704 -0
  35. package/dist/flow-screen-CCvgDI9G.js.map +1 -0
  36. package/dist/flow-screen-Ci_Sik4Y.cjs +708 -0
  37. package/dist/flow-screen-Ci_Sik4Y.cjs.map +1 -0
  38. package/dist/index.cjs +3420 -11986
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +1843 -2015
  41. package/dist/index.d.ts +1849 -2021
  42. package/dist/index.js +3090 -11675
  43. package/dist/index.js.map +1 -1
  44. package/dist/inline-flow-host-B6FI0ctQ.js +112 -0
  45. package/dist/inline-flow-host-B6FI0ctQ.js.map +1 -0
  46. package/dist/inline-flow-host-DV1et3c6.cjs +112 -0
  47. package/dist/inline-flow-host-DV1et3c6.cjs.map +1 -0
  48. package/dist/input-BI0czGyI.cjs +23 -0
  49. package/dist/input-BI0czGyI.cjs.map +1 -0
  50. package/dist/input-CUPStzZO.js +17 -0
  51. package/dist/input-CUPStzZO.js.map +1 -0
  52. package/dist/label-66W1qbke.js +29 -0
  53. package/dist/label-66W1qbke.js.map +1 -0
  54. package/dist/label-w6JYf2cF.cjs +36 -0
  55. package/dist/label-w6JYf2cF.cjs.map +1 -0
  56. package/dist/markdown/index.cjs +1 -1
  57. package/dist/markdown/index.d.cts +2 -3
  58. package/dist/markdown/index.d.ts +2 -3
  59. package/dist/markdown/index.js +1 -1
  60. package/dist/page-flow-route-hdnULWqd.cjs +277 -0
  61. package/dist/page-flow-route-hdnULWqd.cjs.map +1 -0
  62. package/dist/page-flow-route-i3ZfJ1sd.js +277 -0
  63. package/dist/page-flow-route-i3ZfJ1sd.js.map +1 -0
  64. package/dist/place-node-C5SmIAYU.cjs +8139 -0
  65. package/dist/place-node-C5SmIAYU.cjs.map +1 -0
  66. package/dist/place-node-NraNYKPx.js +7597 -0
  67. package/dist/place-node-NraNYKPx.js.map +1 -0
  68. package/dist/related-list-cards-BWZ9GfOG.js +42 -0
  69. package/dist/related-list-cards-BWZ9GfOG.js.map +1 -0
  70. package/dist/related-list-cards-CFq3meUn.cjs +42 -0
  71. package/dist/related-list-cards-CFq3meUn.cjs.map +1 -0
  72. package/dist/related-list-timeline-CCzl71aA.cjs +142 -0
  73. package/dist/related-list-timeline-CCzl71aA.cjs.map +1 -0
  74. package/dist/related-list-timeline-yrPsjA3F.js +142 -0
  75. package/dist/related-list-timeline-yrPsjA3F.js.map +1 -0
  76. package/dist/related-rows-ea43qhhy.cjs +208 -0
  77. package/dist/related-rows-ea43qhhy.cjs.map +1 -0
  78. package/dist/related-rows-o0_t-Yce.js +185 -0
  79. package/dist/related-rows-o0_t-Yce.js.map +1 -0
  80. package/dist/relation-create-IA40t1hi.cjs +364 -0
  81. package/dist/relation-create-IA40t1hi.cjs.map +1 -0
  82. package/dist/relation-create-h6F9B4C4.js +339 -0
  83. package/dist/relation-create-h6F9B4C4.js.map +1 -0
  84. package/dist/relation-many-picker-C8zFEjwd.cjs +467 -0
  85. package/dist/relation-many-picker-C8zFEjwd.cjs.map +1 -0
  86. package/dist/relation-many-picker-bvkjkv-k.js +466 -0
  87. package/dist/relation-many-picker-bvkjkv-k.js.map +1 -0
  88. package/dist/relation-picker-Z0ZJJ5uS.js +493 -0
  89. package/dist/relation-picker-Z0ZJJ5uS.js.map +1 -0
  90. package/dist/relation-picker-dialog-0IzkjmiA.cjs +304 -0
  91. package/dist/relation-picker-dialog-0IzkjmiA.cjs.map +1 -0
  92. package/dist/relation-picker-dialog-B6nIiJBf.js +303 -0
  93. package/dist/relation-picker-dialog-B6nIiJBf.js.map +1 -0
  94. package/dist/relation-picker-gag0qSR5.cjs +516 -0
  95. package/dist/relation-picker-gag0qSR5.cjs.map +1 -0
  96. package/dist/resource-page-router-3RUf9d1j.js +1588 -0
  97. package/dist/resource-page-router-3RUf9d1j.js.map +1 -0
  98. package/dist/resource-page-router-PXfMW9nh.cjs +1785 -0
  99. package/dist/resource-page-router-PXfMW9nh.cjs.map +1 -0
  100. package/dist/{rich-text-IDFvyvRE.js → rich-text-DFerywgz.js} +7 -4
  101. package/dist/{rich-text-IDFvyvRE.js.map → rich-text-DFerywgz.js.map} +1 -1
  102. package/dist/{rich-text-lndbYqzR.cjs → rich-text-vTyVjDoa.cjs} +25 -22
  103. package/dist/{rich-text-lndbYqzR.cjs.map → rich-text-vTyVjDoa.cjs.map} +1 -1
  104. package/dist/search-access-CPPmfuvy.js +654 -0
  105. package/dist/search-access-CPPmfuvy.js.map +1 -0
  106. package/dist/search-access-Dugvttlg.cjs +791 -0
  107. package/dist/search-access-Dugvttlg.cjs.map +1 -0
  108. package/dist/shell-BPlk8hEa.js +205 -0
  109. package/dist/shell-BPlk8hEa.js.map +1 -0
  110. package/dist/shell-DxhlsPwm.cjs +271 -0
  111. package/dist/shell-DxhlsPwm.cjs.map +1 -0
  112. package/dist/skeleton-U2noefj5.js +13 -0
  113. package/dist/skeleton-U2noefj5.js.map +1 -0
  114. package/dist/skeleton-_1gP7wan.cjs +18 -0
  115. package/dist/skeleton-_1gP7wan.cjs.map +1 -0
  116. package/dist/styles.css +241 -9
  117. package/dist/toaster-C02XbB9r.js +135 -0
  118. package/dist/toaster-C02XbB9r.js.map +1 -0
  119. package/dist/toaster-Cr51X7bz.cjs +195 -0
  120. package/dist/toaster-Cr51X7bz.cjs.map +1 -0
  121. package/dist/use-dialog-filter-state-C--oMAZG.js +87 -0
  122. package/dist/use-dialog-filter-state-C--oMAZG.js.map +1 -0
  123. package/dist/use-dialog-filter-state-Dhe8PcB5.cjs +92 -0
  124. package/dist/use-dialog-filter-state-Dhe8PcB5.cjs.map +1 -0
  125. package/dist/{use-theme-BwPWinB2.cjs → use-theme-DFlpXils.cjs} +12 -1
  126. package/dist/use-theme-DFlpXils.cjs.map +1 -0
  127. package/dist/{use-theme-IHmtrhEt.js → use-theme-dnE3Od3I.js} +7 -2
  128. package/dist/use-theme-dnE3Od3I.js.map +1 -0
  129. package/package.json +16 -14
  130. package/dist/use-theme-BwPWinB2.cjs.map +0 -1
  131. package/dist/use-theme-IHmtrhEt.js.map +0 -1
@@ -0,0 +1,654 @@
1
+ import { l as cn } from "./use-theme-dnE3Od3I.js";
2
+ import { o as useLinkComponent } from "./toaster-C02XbB9r.js";
3
+ import { i as DialogDescription, r as DialogContent, s as DialogTitle, t as Dialog } from "./dialog-B_rt9S1c.js";
4
+ import { hasRecordPage, relationAmbiguousError, relationOpenOf, resourceKey, resourceShowHref } from "@burojs/core";
5
+ import { PEEK_COMPONENT, QUICK_ANCHOR_ATTRIBUTE, filterFields, quickAnchorRef, useApp, useCurrentUIActivation, useEntryGate, useList, useListAccess, useOptionalT, useQuickOpener, useRelatedRecord, useUIPresentationRuntime } from "@burojs/react";
6
+ import { IconSearch } from "@tabler/icons-react";
7
+ import * as React from "react";
8
+ import { createContext, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ import { Command } from "cmdk";
11
+ //#region src/primitives/command.tsx
12
+ const Command$1 = React.forwardRef(({ className, ...props }, ref) => jsx(Command, {
13
+ ref,
14
+ className: cn("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", className),
15
+ ...props
16
+ }));
17
+ Command$1.displayName = Command.displayName;
18
+ const CommandInput = React.forwardRef(({ className, ...props }, ref) => jsxs("div", {
19
+ className: "flex items-center border-b px-3",
20
+ "cmdk-input-wrapper": "",
21
+ children: [jsx(IconSearch, {
22
+ className: "mr-2 h-4 w-4 shrink-0 opacity-50",
23
+ "aria-hidden": "true"
24
+ }), jsx(Command.Input, {
25
+ ref,
26
+ className: cn("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-input-disabled", className),
27
+ ...props
28
+ })]
29
+ }));
30
+ CommandInput.displayName = Command.Input.displayName;
31
+ const CommandList = React.forwardRef(({ className, ...props }, ref) => jsx(Command.List, {
32
+ ref,
33
+ className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
34
+ ...props
35
+ }));
36
+ CommandList.displayName = Command.List.displayName;
37
+ const CommandEmpty = React.forwardRef((props, ref) => jsx(Command.Empty, {
38
+ ref,
39
+ className: "py-6 text-center text-sm text-muted-foreground",
40
+ ...props
41
+ }));
42
+ CommandEmpty.displayName = Command.Empty.displayName;
43
+ const CommandGroup = React.forwardRef(({ className, ...props }, ref) => jsx(Command.Group, {
44
+ ref,
45
+ className: cn("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className),
46
+ ...props
47
+ }));
48
+ CommandGroup.displayName = Command.Group.displayName;
49
+ const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => jsx(Command.Separator, {
50
+ ref,
51
+ className: cn("-mx-1 h-px bg-border", className),
52
+ ...props
53
+ }));
54
+ CommandSeparator.displayName = Command.Separator.displayName;
55
+ const CommandItem = React.forwardRef(({ className, ...props }, ref) => jsx(Command.Item, {
56
+ ref,
57
+ className: cn("group relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50", className),
58
+ ...props
59
+ }));
60
+ CommandItem.displayName = Command.Item.displayName;
61
+ const CommandLoading = React.forwardRef(({ ...props }, ref) => jsx(Command.Loading, {
62
+ ref,
63
+ ...props
64
+ }));
65
+ CommandLoading.displayName = Command.Loading.displayName;
66
+ function CommandDialog({ open, onOpenChange, defaultOpen, modal, title = "Command Palette", description = "Search and run actions.", className, commandClassName, children, contentProps }) {
67
+ return jsx(Dialog, {
68
+ open,
69
+ onOpenChange,
70
+ defaultOpen,
71
+ modal,
72
+ children: jsxs(DialogContent, {
73
+ ...contentProps,
74
+ className: cn("overflow-hidden p-0 shadow-lg max-w-[480px] sm:max-w-[480px]", className),
75
+ overlayClassName: "backdrop-blur-sm",
76
+ children: [
77
+ jsx(DialogTitle, {
78
+ className: "sr-only",
79
+ children: title
80
+ }),
81
+ jsx(DialogDescription, {
82
+ className: "sr-only",
83
+ children: description
84
+ }),
85
+ jsx(Command$1, {
86
+ className: cn("[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", commandClassName),
87
+ children
88
+ })
89
+ ]
90
+ })
91
+ });
92
+ }
93
+ CommandDialog.displayName = "CommandDialog";
94
+ //#endregion
95
+ //#region src/fields/claimed-quick-link.tsx
96
+ function isPlainLeftClick(event) {
97
+ return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
98
+ }
99
+ function claimAnchor(wrapper) {
100
+ const anchor = wrapper?.querySelector("a") ?? null;
101
+ quickAnchorRef(anchor);
102
+ }
103
+ function ClaimedQuickLink({ href, testid, className, onOpen, children }) {
104
+ const RouterLink = useLinkComponent();
105
+ return jsx("span", {
106
+ ref: claimAnchor,
107
+ className: "contents",
108
+ children: jsx(RouterLink, {
109
+ href,
110
+ ...testid === void 0 ? {} : { "data-testid": testid },
111
+ [QUICK_ANCHOR_ATTRIBUTE]: "",
112
+ ...className === void 0 ? {} : { className },
113
+ onClick: (event) => {
114
+ event.stopPropagation();
115
+ if (!isPlainLeftClick(event) || event.currentTarget.target === "_blank") return;
116
+ event.preventDefault();
117
+ onOpen();
118
+ },
119
+ children
120
+ })
121
+ });
122
+ }
123
+ //#endregion
124
+ //#region src/resource/record-display-name.ts
125
+ function recordDisplayName(record, displayField) {
126
+ if (displayField && record[displayField] != null && record[displayField] !== "") return String(record[displayField]);
127
+ return String(record.id ?? "");
128
+ }
129
+ //#endregion
130
+ //#region src/resource/use-row-title.ts
131
+ function useRowTitle(target, displayField) {
132
+ const access = useListAccess(target);
133
+ const visible = displayField !== void 0 && access.status === "ready" && access.fieldVisible(displayField);
134
+ return useCallback((row) => recordDisplayName(row, visible ? displayField : void 0), [visible, displayField]);
135
+ }
136
+ //#endregion
137
+ //#region src/quick/peek-context.ts
138
+ const PeekHostContext = createContext(null);
139
+ const PeekContext = createContext(false);
140
+ const KEYBOARD_FOCUS_WINDOW_MS = 100;
141
+ const NAVIGATION_KEYS = new Set([
142
+ "Tab",
143
+ "ArrowUp",
144
+ "ArrowDown",
145
+ "ArrowLeft",
146
+ "ArrowRight"
147
+ ]);
148
+ let lastNavigationKeyAt = Number.NEGATIVE_INFINITY;
149
+ const listening = new WeakSet();
150
+ function listenForModality(doc) {
151
+ if (listening.has(doc)) return;
152
+ listening.add(doc);
153
+ doc.addEventListener("keydown", (event) => {
154
+ if (NAVIGATION_KEYS.has(event.key)) lastNavigationKeyAt = Date.now();
155
+ }, true);
156
+ const forget = () => {
157
+ lastNavigationKeyAt = Number.NEGATIVE_INFINITY;
158
+ };
159
+ doc.addEventListener("pointerdown", forget, true);
160
+ doc.addEventListener("mousedown", forget, true);
161
+ }
162
+ function keyboardModality() {
163
+ return Date.now() - lastNavigationKeyAt <= KEYBOARD_FOCUS_WINDOW_MS;
164
+ }
165
+ const focusedByCode = new WeakSet();
166
+ function focusWithoutPeek(element) {
167
+ focusedByCode.add(element);
168
+ element.focus();
169
+ focusedByCode.delete(element);
170
+ }
171
+ const anchorOpeners = new WeakMap();
172
+ function peekAnchorOpener(anchor) {
173
+ return anchor === null ? void 0 : anchorOpeners.get(anchor);
174
+ }
175
+ function anchorIn(wrapper) {
176
+ if (wrapper === null) return null;
177
+ const marked = wrapper.querySelector("[data-buro-quick]");
178
+ if (marked !== null) return marked;
179
+ const first = wrapper.firstElementChild;
180
+ return first instanceof HTMLElement ? first : null;
181
+ }
182
+ const noSubscription = () => () => void 0;
183
+ function PeekIntent({ target, children }) {
184
+ if (useContext(PeekContext)) return jsx(Fragment$1, { children });
185
+ return jsx(ActivePeekIntent, {
186
+ target,
187
+ children
188
+ });
189
+ }
190
+ function ActivePeekIntent({ target, children }) {
191
+ const gate = useEntryGate();
192
+ const runtime = useUIPresentationRuntime();
193
+ const activation = useCurrentUIActivation();
194
+ const [anchor, setAnchor] = useState(null);
195
+ const wrapper = useRef(null);
196
+ const timer = useRef(null);
197
+ const latest = useRef({
198
+ gate,
199
+ target,
200
+ activation
201
+ });
202
+ latest.current = {
203
+ gate,
204
+ target,
205
+ activation
206
+ };
207
+ const attach = useCallback((element) => {
208
+ wrapper.current = element;
209
+ if (element !== null && element.ownerDocument !== void 0) listenForModality(element.ownerDocument);
210
+ setAnchor(anchorIn(element));
211
+ }, []);
212
+ const expanded = useSyncExternalStore(anchor === null ? noSubscription : runtime.subscribe, () => anchor !== null && runtime.getSnapshot().some((d) => d.component === PEEK_COMPONENT && d.anchor?.element === anchor), () => false);
213
+ const peekable = gate(target.to, "peek").state === "open";
214
+ useEffect(() => {
215
+ if (anchor === null) return;
216
+ if (!peekable) {
217
+ anchor.removeAttribute("aria-haspopup");
218
+ anchor.removeAttribute("aria-expanded");
219
+ return;
220
+ }
221
+ anchor.setAttribute("aria-haspopup", "dialog");
222
+ anchor.setAttribute("aria-expanded", expanded ? "true" : "false");
223
+ }, [
224
+ anchor,
225
+ peekable,
226
+ expanded
227
+ ]);
228
+ const quickOpen = useQuickOpener();
229
+ const onOpen = useCallback((to, id) => void quickOpen(to, id), [quickOpen]);
230
+ useEffect(() => {
231
+ if (anchor === null) return;
232
+ anchorOpeners.set(anchor, onOpen);
233
+ return () => {
234
+ if (anchorOpeners.get(anchor) === onOpen) anchorOpeners.delete(anchor);
235
+ };
236
+ }, [anchor, onOpen]);
237
+ const cancel = useCallback(() => {
238
+ if (timer.current === null) return;
239
+ clearTimeout(timer.current);
240
+ timer.current = null;
241
+ }, []);
242
+ useEffect(() => cancel, [cancel]);
243
+ const fire = useCallback(() => {
244
+ timer.current = null;
245
+ const { gate: ask, target: what, activation: from } = latest.current;
246
+ const element = anchorIn(wrapper.current);
247
+ if (element === null || !element.isConnected) return;
248
+ const answer = ask(what.to, "peek");
249
+ if (answer.state !== "open") return;
250
+ const snapshot = runtime.getSnapshot();
251
+ if (snapshot.some((d) => d.component === PEEK_COMPONENT && d.anchor?.element === element)) return;
252
+ for (const descriptor of snapshot) if (descriptor.component === PEEK_COMPONENT) runtime.dismiss(descriptor.id);
253
+ const props = {
254
+ target: answer.target,
255
+ ...what.id === void 0 ? {} : { id: what.id },
256
+ ...what.by === void 0 ? {} : { by: what.by }
257
+ };
258
+ runtime.present({
259
+ component: PEEK_COMPONENT,
260
+ host: "popover",
261
+ anchor: { element },
262
+ props,
263
+ activation: from
264
+ });
265
+ }, [runtime]);
266
+ const schedule = useCallback(() => {
267
+ if (timer.current !== null) return;
268
+ timer.current = setTimeout(fire, 500);
269
+ }, [fire]);
270
+ return jsx("span", {
271
+ ref: attach,
272
+ className: "contents",
273
+ onPointerEnter: (event) => {
274
+ if (event.pointerType === "mouse" || event.pointerType === "pen") schedule();
275
+ },
276
+ onPointerLeave: cancel,
277
+ onFocus: (event) => {
278
+ if (focusedByCode.has(event.target)) return;
279
+ if (keyboardModality()) schedule();
280
+ },
281
+ onBlur: cancel,
282
+ onPointerDown: cancel,
283
+ onClickCapture: cancel,
284
+ children
285
+ });
286
+ }
287
+ //#endregion
288
+ //#region src/fields/relation-display.tsx
289
+ const relationLinkClassName = "rounded text-foreground underline decoration-muted-foreground/40 decoration-dotted underline-offset-4 transition-all hover:decoration-foreground hover:decoration-solid focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring";
290
+ function RelationDisplay({ value, field }) {
291
+ const app = useApp();
292
+ const meta = field?.meta;
293
+ const by = typeof meta?.by === "string" ? meta.by : void 0;
294
+ const lazy = meta?.resolve === "lazy";
295
+ let to;
296
+ try {
297
+ to = meta?.to === void 0 ? void 0 : resourceKey(meta.to);
298
+ } catch {
299
+ to = void 0;
300
+ }
301
+ const id = value;
302
+ const idStr = String(value ?? "");
303
+ const baseId = `relation-display:${to ?? "unknown"}:${idStr}`;
304
+ const open = relationOpenOf({ ui: field?.ui });
305
+ if (value == null || value === "") return jsx("span", {
306
+ "data-testid": `${baseId}:empty`,
307
+ className: "text-muted-foreground",
308
+ children: "—"
309
+ });
310
+ if (!to) {
311
+ if (process.env.NODE_ENV !== "production") console.warn(`[RelationDisplay] no meta.to declared on field — rendering raw value '${idStr}'`);
312
+ return jsx("span", {
313
+ "data-testid": `relation-display:unknown:${idStr}:no-target`,
314
+ children: idStr
315
+ });
316
+ }
317
+ if (lazy) return jsx(LazyRelationDisplay, {
318
+ to,
319
+ by,
320
+ idStr,
321
+ app,
322
+ open
323
+ });
324
+ return jsx(GatedRelationDisplay, {
325
+ to,
326
+ by,
327
+ id,
328
+ idStr,
329
+ app,
330
+ open
331
+ });
332
+ }
333
+ function RelationField({ to, value }) {
334
+ return jsx(RelationDisplay, {
335
+ value,
336
+ field: {
337
+ name: "",
338
+ meta: { to }
339
+ }
340
+ });
341
+ }
342
+ function peekTarget(to, by, key) {
343
+ return by === void 0 ? {
344
+ to,
345
+ id: key
346
+ } : {
347
+ to,
348
+ by: {
349
+ field: by,
350
+ key
351
+ }
352
+ };
353
+ }
354
+ function showPageDef(app, def) {
355
+ const delegate = def.routesTo?.show;
356
+ if (delegate === void 0) return def;
357
+ try {
358
+ return app.registry.get(resourceKey(delegate));
359
+ } catch {
360
+ return;
361
+ }
362
+ }
363
+ function linksToPage(app, def) {
364
+ const target = showPageDef(app, def);
365
+ return target !== void 0 && hasRecordPage(target, "show");
366
+ }
367
+ function QuickOpener({ href, testid, onOpen, children }) {
368
+ if (href === null) return jsx("button", {
369
+ type: "button",
370
+ "data-testid": testid,
371
+ [QUICK_ANCHOR_ATTRIBUTE]: "",
372
+ className: `${relationLinkClassName} text-left`,
373
+ onClick: (event) => {
374
+ event.preventDefault();
375
+ event.stopPropagation();
376
+ onOpen();
377
+ },
378
+ children
379
+ });
380
+ return jsx(ClaimedQuickLink, {
381
+ href,
382
+ testid,
383
+ className: relationLinkClassName,
384
+ onOpen,
385
+ children
386
+ });
387
+ }
388
+ function LazyRelationDisplay({ to, by, idStr, app, open: openMode }) {
389
+ const RouterLink = useLinkComponent();
390
+ const gate = useEntryGate();
391
+ const open = useQuickOpener();
392
+ const targetDef = app.registry.get(to);
393
+ const baseId = `relation-display:${to}:${idStr}`;
394
+ if (!targetDef || openMode === "none") return jsx("span", {
395
+ "data-testid": `${baseId}:lazy`,
396
+ children: idStr
397
+ });
398
+ const answer = gate(to, "show");
399
+ if (answer.state === "undecided") return jsx(PeekIntent, {
400
+ target: peekTarget(to, by, idStr),
401
+ children: jsx("span", {
402
+ "data-testid": `${baseId}:lazy`,
403
+ children: idStr
404
+ })
405
+ });
406
+ if (answer.state === "hidden" || answer.state === "disabled") return jsx("span", {
407
+ "data-testid": `${baseId}:lazy`,
408
+ children: idStr
409
+ });
410
+ const page = linksToPage(app, targetDef);
411
+ if (openMode === "page") {
412
+ if (by !== void 0 || !page) return jsx("span", {
413
+ "data-testid": `${baseId}:lazy`,
414
+ children: idStr
415
+ });
416
+ return jsx(RouterLink, {
417
+ href: resourceShowHref(app.registry, targetDef, to, idStr),
418
+ "data-testid": `${baseId}:lazy`,
419
+ className: relationLinkClassName,
420
+ onClick: (e) => e.stopPropagation(),
421
+ children: idStr
422
+ });
423
+ }
424
+ if (answer.state !== "open") {
425
+ if (by !== void 0 || !page) return jsx("span", {
426
+ "data-testid": `${baseId}:lazy`,
427
+ children: idStr
428
+ });
429
+ return jsx(RouterLink, {
430
+ href: resourceShowHref(app.registry, targetDef, to, idStr),
431
+ "data-testid": `${baseId}:lazy`,
432
+ className: relationLinkClassName,
433
+ onClick: (e) => e.stopPropagation(),
434
+ children: idStr
435
+ });
436
+ }
437
+ if (by !== void 0) return jsx(PeekIntent, {
438
+ target: peekTarget(to, by, idStr),
439
+ children: jsx(LazyByOpener, {
440
+ to,
441
+ by,
442
+ idStr,
443
+ target: answer.target
444
+ })
445
+ });
446
+ const openKey = () => void open(to, idStr);
447
+ return jsx(PeekIntent, {
448
+ target: peekTarget(to, void 0, idStr),
449
+ children: jsx(QuickOpener, {
450
+ href: page ? resourceShowHref(app.registry, targetDef, to, idStr) : null,
451
+ testid: `${baseId}:lazy`,
452
+ onOpen: openKey,
453
+ children: idStr
454
+ })
455
+ });
456
+ }
457
+ function LazyByOpener({ to, by, idStr, target }) {
458
+ const app = useApp();
459
+ const t = useOptionalT();
460
+ const open = useQuickOpener();
461
+ const [asked, setAsked] = useState(false);
462
+ const rows = useList(to, {
463
+ ...asked ? {
464
+ filter: {
465
+ field: by,
466
+ op: "eq",
467
+ value: idStr
468
+ },
469
+ pagination: {
470
+ kind: "offset",
471
+ page: 1,
472
+ pageSize: 2
473
+ }
474
+ } : {},
475
+ scope: "none",
476
+ enabled: asked,
477
+ retry: false
478
+ }).data?.data;
479
+ const baseId = `relation-display:${to}:${idStr}`;
480
+ const idField = (app.registry.get(target)?.data)?.idField;
481
+ const rowId = rows?.length === 1 ? rows[0]?.[typeof idField === "string" && idField.length > 0 ? idField : "id"] : void 0;
482
+ const requested = useRef(false);
483
+ useEffect(() => {
484
+ if (!asked || rows === void 0 || !requested.current) return;
485
+ if (rows.length > 1) {
486
+ requested.current = false;
487
+ if (process.env.NODE_ENV !== "production") console.error(`[burojs] ${relationAmbiguousError(to, by, idStr).message}`);
488
+ return;
489
+ }
490
+ requested.current = false;
491
+ if (rows.length === 1 && rowId !== void 0 && rowId !== null) open(to, String(rowId));
492
+ }, [
493
+ asked,
494
+ rows,
495
+ rowId,
496
+ open,
497
+ to,
498
+ by,
499
+ idStr
500
+ ]);
501
+ if (asked && rows !== void 0 && rows.length === 0) return jsx("span", {
502
+ "data-testid": `${baseId}:unavailable`,
503
+ className: "text-muted-foreground",
504
+ children: t("relation.unavailable", { defaultValue: "Not available" })
505
+ });
506
+ if (asked && rows !== void 0 && rows.length > 1) return jsx("span", {
507
+ "data-testid": `${baseId}:ambiguous`,
508
+ className: "text-muted-foreground",
509
+ children: idStr
510
+ });
511
+ return jsx("button", {
512
+ type: "button",
513
+ "data-testid": `${baseId}:lazy`,
514
+ [QUICK_ANCHOR_ATTRIBUTE]: "",
515
+ className: `${relationLinkClassName} text-left`,
516
+ onClick: (event) => {
517
+ event.preventDefault();
518
+ event.stopPropagation();
519
+ if (asked && rowId !== void 0 && rowId !== null) open(to, String(rowId));
520
+ else {
521
+ requested.current = true;
522
+ setAsked(true);
523
+ }
524
+ },
525
+ children: idStr
526
+ });
527
+ }
528
+ function GatedRelationDisplay(props) {
529
+ const gate = useEntryGate();
530
+ const target = props.to;
531
+ const { idStr } = props;
532
+ const answer = gate(target, "show");
533
+ if (answer.state === "undecided") return jsx(PeekIntent, {
534
+ target: peekTarget(target, props.by, idStr),
535
+ children: jsx("span", {
536
+ "data-testid": `relation-display:${target}:${idStr}:text`,
537
+ children: idStr
538
+ })
539
+ });
540
+ if (answer.state === "hidden" || answer.state === "disabled") return jsx("span", {
541
+ "data-testid": `relation-display:${target}:${idStr}:text`,
542
+ children: idStr
543
+ });
544
+ return jsx(RelationDisplayBody, {
545
+ ...props,
546
+ quickTarget: answer.state === "open" && props.open === "quick" ? answer.target : null
547
+ });
548
+ }
549
+ function RelationDisplayBody({ to, by, id, idStr, app, open: openMode, quickTarget }) {
550
+ const targetDef = app.registry.get(to);
551
+ const rowTitle = useRowTitle(to, targetDef?.displayField);
552
+ const baseId = `relation-display:${to}:${idStr}`;
553
+ const RouterLink = useLinkComponent();
554
+ const open = useQuickOpener();
555
+ const { record, isLoading, error, ambiguous } = useRelatedRecord(to, id, by === void 0 ? void 0 : { by });
556
+ if (!targetDef) {
557
+ if (process.env.NODE_ENV !== "production") console.warn(`[RelationDisplay] target resource '${to}' not registered — rendering raw value '${idStr}'`);
558
+ return jsx("span", {
559
+ "data-testid": `${baseId}:unregistered`,
560
+ className: "text-muted-foreground",
561
+ children: idStr
562
+ });
563
+ }
564
+ if (isLoading) return jsx("span", {
565
+ "data-testid": `relation-display-loading:${to}`,
566
+ className: "inline-block h-5 w-20 animate-pulse rounded bg-muted",
567
+ "aria-busy": "true"
568
+ });
569
+ if (ambiguous) return jsx("span", {
570
+ "data-testid": `${baseId}:ambiguous`,
571
+ className: "text-muted-foreground",
572
+ title: `${to}: more than one row has ${by ?? "id"} ${idStr}`,
573
+ children: idStr
574
+ });
575
+ if (error) return jsx("span", {
576
+ "data-testid": `${baseId}:error`,
577
+ className: "text-muted-foreground",
578
+ title: error.message,
579
+ children: idStr
580
+ });
581
+ if (!record) return jsx("span", {
582
+ "data-testid": `${baseId}:not-found`,
583
+ className: "text-muted-foreground",
584
+ title: `${to} #${idStr} not found`,
585
+ children: idStr
586
+ });
587
+ const displayName = rowTitle(record);
588
+ const idField = targetDef.data?.idField;
589
+ const rowId = record[typeof idField === "string" && idField.length > 0 ? idField : "id"];
590
+ if (rowId === null || rowId === void 0 || rowId === "") return jsx("span", {
591
+ "data-testid": `${baseId}:no-id`,
592
+ className: "text-muted-foreground",
593
+ children: displayName
594
+ });
595
+ const href = linksToPage(app, targetDef) ? resourceShowHref(app.registry, targetDef, to, String(rowId)) : null;
596
+ if (openMode === "none") return jsx("span", {
597
+ "data-testid": baseId,
598
+ children: displayName
599
+ });
600
+ if (quickTarget !== null) return jsx(RowOpener, {
601
+ to,
602
+ rowId: String(rowId),
603
+ href,
604
+ testid: baseId,
605
+ open,
606
+ children: displayName
607
+ });
608
+ if (href === null) return jsx("span", {
609
+ "data-testid": baseId,
610
+ children: displayName
611
+ });
612
+ return jsx(RouterLink, {
613
+ href,
614
+ "data-testid": baseId,
615
+ className: relationLinkClassName,
616
+ onClick: (e) => e.stopPropagation(),
617
+ children: displayName
618
+ });
619
+ }
620
+ function RowOpener({ to, rowId, href, testid, open, children }) {
621
+ const onOpen = useCallback(() => void open(to, rowId), [
622
+ open,
623
+ to,
624
+ rowId
625
+ ]);
626
+ return jsx(PeekIntent, {
627
+ target: peekTarget(to, void 0, rowId),
628
+ children: jsx(QuickOpener, {
629
+ href,
630
+ testid,
631
+ onOpen,
632
+ children
633
+ })
634
+ });
635
+ }
636
+ //#endregion
637
+ //#region src/fields/search-access.ts
638
+ function narrowSearchDecl(declared, visible) {
639
+ if (declared === void 0 || typeof declared === "function") return declared;
640
+ if (!Array.isArray(declared.fields)) return declared;
641
+ const fields = declared.fields.filter((ref) => visible(typeof ref === "string" ? ref : ref.field));
642
+ if (fields.length === declared.fields.length) return declared;
643
+ return fields.length === 0 ? void 0 : {
644
+ ...declared,
645
+ fields
646
+ };
647
+ }
648
+ function namesHiddenField(filter, visible) {
649
+ return filter !== void 0 && filterFields(filter).some((field) => !visible(field));
650
+ }
651
+ //#endregion
652
+ export { CommandSeparator as C, CommandLoading as S, CommandEmpty as _, linksToPage as a, CommandItem as b, peekAnchorOpener as c, useRowTitle as d, recordDisplayName as f, CommandDialog as g, Command$1 as h, RelationField as i, PeekContext as l, isPlainLeftClick as m, narrowSearchDecl as n, relationLinkClassName as o, ClaimedQuickLink as p, RelationDisplay as r, focusWithoutPeek as s, namesHiddenField as t, PeekHostContext as u, CommandGroup as v, CommandList as x, CommandInput as y };
653
+
654
+ //# sourceMappingURL=search-access-CPPmfuvy.js.map