@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,153 @@
1
+ const require_use_theme = require("./use-theme-DFlpXils.cjs");
2
+ let _burojs_core = require("@burojs/core");
3
+ let _burojs_react = require("@burojs/react");
4
+ let react = require("react");
5
+ react = require_use_theme.__toESM(react, 1);
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ //#region src/fields/lazy-relation-picker-dialog.tsx
8
+ const Dialog = (0, react.lazy)(() => Promise.resolve().then(() => require("./relation-picker-dialog-0IzkjmiA.cjs")).then((module) => ({ default: module.RelationPickerDialog })));
9
+ function LazyRelationPickerDialog(props) {
10
+ return (0, react_jsx_runtime.jsx)(react.Suspense, {
11
+ fallback: null,
12
+ children: (0, react_jsx_runtime.jsx)(Dialog, { ...props })
13
+ });
14
+ }
15
+ //#endregion
16
+ //#region src/fields/candidates-match.ts
17
+ function rowMatches(row, filters) {
18
+ let unknown = false;
19
+ for (const filter of filters) {
20
+ const group = filter;
21
+ if (Array.isArray(group.and) || Array.isArray(group.or)) {
22
+ const answers = (Array.isArray(group.and) ? group.and : group.or).map((part) => rowMatches(row, [part]));
23
+ const all = Array.isArray(group.and);
24
+ const decided = answers.filter((answer) => answer !== void 0);
25
+ if (all ? decided.includes(false) : decided.length > 0 && !decided.includes(true)) return false;
26
+ if (decided.length < answers.length && !(all ? false : decided.includes(true))) unknown = true;
27
+ continue;
28
+ }
29
+ const { field, op, value } = filter;
30
+ if (typeof field !== "string" || typeof op !== "string") continue;
31
+ if (!Object.hasOwn(row, field)) {
32
+ unknown = true;
33
+ continue;
34
+ }
35
+ const held = holds(row[field], op, value);
36
+ if (held === false) return false;
37
+ if (held === void 0) unknown = true;
38
+ }
39
+ return unknown ? void 0 : true;
40
+ }
41
+ function holds(actual, op, expected) {
42
+ const list = Array.isArray(expected) ? expected : void 0;
43
+ const text = (value) => String(value ?? "").toLowerCase();
44
+ switch (op) {
45
+ case "eq": return Object.is(actual, expected) || String(actual) === String(expected);
46
+ case "neq": return !(Object.is(actual, expected) || String(actual) === String(expected));
47
+ case "in": return list === void 0 ? void 0 : list.some((entry) => String(entry) === String(actual));
48
+ case "notIn": return list === void 0 ? void 0 : !list.some((entry) => String(entry) === String(actual));
49
+ case "gt": return compare(actual, expected, (a, b) => a > b);
50
+ case "gte": return compare(actual, expected, (a, b) => a >= b);
51
+ case "lt": return compare(actual, expected, (a, b) => a < b);
52
+ case "lte": return compare(actual, expected, (a, b) => a <= b);
53
+ case "contains": return text(actual).includes(text(expected));
54
+ case "startsWith": return text(actual).startsWith(text(expected));
55
+ case "endsWith": return text(actual).endsWith(text(expected));
56
+ case "isNull": return actual === null || actual === void 0;
57
+ case "isNotNull": return actual !== null && actual !== void 0;
58
+ default: return;
59
+ }
60
+ }
61
+ function compare(actual, expected, test) {
62
+ return typeof actual === "number" && typeof expected === "number" || typeof actual === "string" && typeof expected === "string" ? test(actual, expected) : void 0;
63
+ }
64
+ //#endregion
65
+ //#region src/fields/candidates-gate.ts
66
+ const NO_SOURCES = Object.freeze({});
67
+ const NO_FILTERS = Object.freeze([]);
68
+ function useCandidatesGate(input) {
69
+ const { to, candidates, sources, resource, fieldName } = input;
70
+ const t = (0, _burojs_react.useOptionalT)();
71
+ const app = (0, _burojs_react.useApp)();
72
+ const tid = (0, _burojs_react.useTestIds)();
73
+ const ownerCaps = (0, _burojs_react.useI18nCaps)(resource);
74
+ const targetCaps = (0, _burojs_react.useI18nCaps)(to ?? resource);
75
+ const access = (0, _burojs_react.useCandidatesAccess)(to ?? "", candidates);
76
+ const resolution = react.useMemo(() => (0, _burojs_core.resolveCandidates)(candidates, sources ?? NO_SOURCES), [candidates, sources]);
77
+ if (candidates === void 0 || candidates.length === 0) return { filters: NO_FILTERS };
78
+ const testId = tid.relationCandidatesHint(resource, fieldName);
79
+ if (access.status === "pending") return {
80
+ filters: NO_FILTERS,
81
+ gate: { kind: "pending" }
82
+ };
83
+ if (access.status === "forbidden") {
84
+ const declared = (0, _burojs_core.declaredText)("field", (app.registry.get(to ?? "")?.fields)?.[access.field], "label");
85
+ const label = (0, _burojs_core.resolveFieldLabel)(targetCaps, access.field, declared);
86
+ return {
87
+ filters: NO_FILTERS,
88
+ gate: {
89
+ kind: "forbidden",
90
+ testId,
91
+ message: t("relationPicker.cannotSearchBy", {
92
+ params: { label },
93
+ defaultValue: `You cannot search by ${label}`
94
+ })
95
+ }
96
+ };
97
+ }
98
+ if (resolution.status === "pending") return {
99
+ filters: NO_FILTERS,
100
+ gate: { kind: "pending" }
101
+ };
102
+ if (resolution.status === "empty") {
103
+ const { source, path } = resolution.hint;
104
+ const head = path[0];
105
+ const declared = (source === "values" || source === "record") && head !== void 0 ? (0, _burojs_core.declaredText)("field", (app.registry.get(resource)?.fields)?.[head], "label") : void 0;
106
+ const label = (0, _burojs_core.resolveFieldLabel)(ownerCaps, head ?? source, declared);
107
+ return {
108
+ filters: NO_FILTERS,
109
+ gate: {
110
+ kind: "empty",
111
+ testId,
112
+ message: t("relationPicker.chooseFirst", {
113
+ params: { label },
114
+ defaultValue: `Choose ${label} first`
115
+ })
116
+ }
117
+ };
118
+ }
119
+ return { filters: resolution.filters };
120
+ }
121
+ function useCandidateSelection(input) {
122
+ const { fixedFilters } = input;
123
+ const gate = useCandidatesGate(input);
124
+ const filters = gate.filters;
125
+ const combined = react.useMemo(() => filters.length === 0 ? fixedFilters : [...filters, ...fixedFilters ?? []], [filters, fixedFilters]);
126
+ const rowFits = react.useMemo(() => filters.length === 0 ? void 0 : (row) => rowMatches(row, filters), [filters]);
127
+ return {
128
+ fixedFilters: combined,
129
+ ...gate.gate === void 0 ? {} : { gate: gate.gate },
130
+ ...rowFits === void 0 ? {} : { rowFits }
131
+ };
132
+ }
133
+ //#endregion
134
+ Object.defineProperty(exports, "LazyRelationPickerDialog", {
135
+ enumerable: true,
136
+ get: function() {
137
+ return LazyRelationPickerDialog;
138
+ }
139
+ });
140
+ Object.defineProperty(exports, "useCandidateSelection", {
141
+ enumerable: true,
142
+ get: function() {
143
+ return useCandidateSelection;
144
+ }
145
+ });
146
+ Object.defineProperty(exports, "useCandidatesGate", {
147
+ enumerable: true,
148
+ get: function() {
149
+ return useCandidatesGate;
150
+ }
151
+ });
152
+
153
+ //# sourceMappingURL=candidates-gate-D33jXLHO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates-gate-D33jXLHO.cjs","names":["lazy","Suspense","useOptionalT","useApp","useTestIds","useI18nCaps","useCandidatesAccess","React","resolveCandidates","declaredText","resolveFieldLabel"],"sources":["../src/fields/lazy-relation-picker-dialog.tsx","../src/fields/candidates-match.ts","../src/fields/candidates-gate.ts"],"sourcesContent":["import { type ComponentProps, type ReactElement, Suspense, lazy } from 'react';\nimport type { RelationPickerDialog } from './relation-picker-dialog.js';\n\nconst Dialog = lazy(() =>\n import('./relation-picker-dialog.js').then((module) => ({\n default: module.RelationPickerDialog,\n })),\n);\n\n/** The \"Advanced search\" dialog, loaded on the first open: nothing is drawn until it arrives. */\nexport function LazyRelationPickerDialog(\n props: ComponentProps<typeof RelationPickerDialog>,\n): ReactElement {\n return (\n <Suspense fallback={null}>\n <Dialog {...props} />\n </Suspense>\n );\n}\n","import type { FixedFilterInput } from '@burojs/core';\n\ntype Entry = { readonly field?: unknown; readonly op?: unknown; readonly value?: unknown };\n\n/**\n * Whether `row` meets every candidate filter (P7 3.4): `true`, `false`, or `undefined` when the\n * row does not carry a field a filter names (a narrower projection), so nothing can be said.\n * Only the flat `{ field, op, value }` entries candidates resolve to are evaluated; this is what\n * \"does not match the current filter\" is decided on, never what is sent.\n */\nexport function rowMatches(\n row: Readonly<Record<string, unknown>>,\n filters: readonly FixedFilterInput[],\n): boolean | undefined {\n let unknown = false;\n for (const filter of filters) {\n const group = filter as { readonly and?: unknown; readonly or?: unknown };\n if (Array.isArray(group.and) || Array.isArray(group.or)) {\n const parts = (\n Array.isArray(group.and) ? group.and : group.or\n ) as readonly FixedFilterInput[];\n const answers = parts.map((part) => rowMatches(row, [part]));\n const all = Array.isArray(group.and);\n const decided = answers.filter((answer) => answer !== undefined);\n if (all ? decided.includes(false) : decided.length > 0 && !decided.includes(true))\n return false;\n if (decided.length < answers.length && !(all ? false : decided.includes(true)))\n unknown = true;\n continue;\n }\n const { field, op, value } = filter as Entry;\n if (typeof field !== 'string' || typeof op !== 'string') continue;\n if (!Object.hasOwn(row, field)) {\n unknown = true;\n continue;\n }\n const held = holds(row[field], op, value);\n if (held === false) return false;\n if (held === undefined) unknown = true;\n }\n return unknown ? undefined : true;\n}\n\nfunction holds(actual: unknown, op: string, expected: unknown): boolean | undefined {\n const list = Array.isArray(expected) ? (expected as readonly unknown[]) : undefined;\n const text = (value: unknown) => String(value ?? '').toLowerCase();\n switch (op) {\n case 'eq':\n return Object.is(actual, expected) || String(actual) === String(expected);\n case 'neq':\n return !(Object.is(actual, expected) || String(actual) === String(expected));\n case 'in':\n return list === undefined\n ? undefined\n : list.some((entry) => String(entry) === String(actual));\n case 'notIn':\n return list === undefined\n ? undefined\n : !list.some((entry) => String(entry) === String(actual));\n case 'gt':\n return compare(actual, expected, (a, b) => a > b);\n case 'gte':\n return compare(actual, expected, (a, b) => a >= b);\n case 'lt':\n return compare(actual, expected, (a, b) => a < b);\n case 'lte':\n return compare(actual, expected, (a, b) => a <= b);\n case 'contains':\n return text(actual).includes(text(expected));\n case 'startsWith':\n return text(actual).startsWith(text(expected));\n case 'endsWith':\n return text(actual).endsWith(text(expected));\n case 'isNull':\n return actual === null || actual === undefined;\n case 'isNotNull':\n return actual !== null && actual !== undefined;\n default:\n return undefined;\n }\n}\n\nfunction compare(\n actual: unknown,\n expected: unknown,\n test: (a: number | string, b: number | string) => boolean,\n): boolean | undefined {\n const both =\n (typeof actual === 'number' && typeof expected === 'number') ||\n (typeof actual === 'string' && typeof expected === 'string');\n return both ? test(actual as number | string, expected as number | string) : undefined;\n}\n","import {\n type FixedFilterInput,\n type RelationCandidate,\n type ScreenSources,\n resolveCandidates,\n resolveFieldLabel,\n declaredText,\n} from '@burojs/core';\nimport { useApp, useCandidatesAccess, useI18nCaps, useOptionalT, useTestIds } from '@burojs/react';\nimport * as React from 'react';\nimport { rowMatches } from './candidates-match.js';\n\n/** A select that must not read its target now (P7 3.4): why, and what it tells the user. */\nexport type CandidatesGate =\n | { readonly kind: 'pending' }\n | { readonly kind: 'empty'; readonly message: string; readonly testId: string }\n | { readonly kind: 'forbidden'; readonly message: string; readonly testId: string };\n\nconst NO_SOURCES: ScreenSources = Object.freeze({});\nconst NO_FILTERS: readonly FixedFilterInput[] = Object.freeze([]);\n\n/**\n * A relation field's `candidates` as the select applies them (P7 3.4): the filters to send and,\n * when they say the target must not be read yet, the gate that tells the user why. The refs are\n * read from the owner's projected sources, so a field P5 hides reads `null` (the select asks for\n * it first, and sends nothing); a candidate on a target field the user may not view forbids the\n * read; an undecided source or permission map keeps the select disabled.\n */\nexport function useCandidatesGate(input: {\n readonly to: string | undefined;\n readonly candidates: readonly RelationCandidate[] | undefined;\n readonly sources: ScreenSources | undefined;\n readonly resource: string;\n readonly fieldName: string;\n}): { readonly filters: readonly FixedFilterInput[]; readonly gate?: CandidatesGate } {\n const { to, candidates, sources, resource, fieldName } = input;\n const t = useOptionalT();\n const app = useApp();\n const tid = useTestIds();\n const ownerCaps = useI18nCaps(resource);\n const targetCaps = useI18nCaps(to ?? resource);\n const access = useCandidatesAccess(to ?? '', candidates);\n const resolution = React.useMemo(\n () => resolveCandidates(candidates, sources ?? NO_SOURCES),\n [candidates, sources],\n );\n if (candidates === undefined || candidates.length === 0) return { filters: NO_FILTERS };\n const testId = tid.relationCandidatesHint(resource, fieldName);\n if (access.status === 'pending') return { filters: NO_FILTERS, gate: { kind: 'pending' } };\n if (access.status === 'forbidden') {\n const declared = declaredText(\n 'field',\n (app.registry.get(to ?? '')?.fields as Record<string, unknown> | undefined)?.[access.field],\n 'label',\n );\n const label = resolveFieldLabel(targetCaps, access.field, declared);\n return {\n filters: NO_FILTERS,\n gate: {\n kind: 'forbidden',\n testId,\n message: t('relationPicker.cannotSearchBy', {\n params: { label },\n defaultValue: `You cannot search by ${label}`,\n }),\n },\n };\n }\n if (resolution.status === 'pending') return { filters: NO_FILTERS, gate: { kind: 'pending' } };\n if (resolution.status === 'empty') {\n const { source, path } = resolution.hint;\n const head = path[0];\n // The field a `values` / `record` ref reads is labelled as the owner labels it; any other\n // source (`scope`, `user`) names the key it reads, humanised.\n const own = source === 'values' || source === 'record';\n const declared =\n own && head !== undefined\n ? declaredText(\n 'field',\n (app.registry.get(resource)?.fields as Record<string, unknown> | undefined)?.[head],\n 'label',\n )\n : undefined;\n const label = resolveFieldLabel(ownerCaps, head ?? source, declared);\n return {\n filters: NO_FILTERS,\n gate: {\n kind: 'empty',\n testId,\n message: t('relationPicker.chooseFirst', {\n params: { label },\n defaultValue: `Choose ${label} first`,\n }),\n },\n };\n }\n return { filters: resolution.filters };\n}\n\n/**\n * A select's declared candidates as the shared select wiring applies them (`CandidatesRelationPicker`\n * and `useRelationPicker`): the gate, the resolved candidate filters prepended to the caller's\n * `fixedFilters`, and whether a loaded row fits them (`undefined` when no candidate filter applies).\n */\nexport function useCandidateSelection(input: {\n readonly to: string | undefined;\n readonly candidates: readonly RelationCandidate[] | undefined;\n readonly sources: ScreenSources | undefined;\n readonly resource: string;\n readonly fieldName: string;\n readonly fixedFilters: readonly FixedFilterInput[] | undefined;\n}): {\n readonly fixedFilters: readonly FixedFilterInput[] | undefined;\n readonly gate?: CandidatesGate;\n readonly rowFits?: (row: Record<string, unknown>) => boolean | undefined;\n} {\n const { fixedFilters } = input;\n const gate = useCandidatesGate(input);\n const filters = gate.filters;\n const combined = React.useMemo(\n () => (filters.length === 0 ? fixedFilters : [...filters, ...(fixedFilters ?? [])]),\n [filters, fixedFilters],\n );\n const rowFits = React.useMemo(\n () =>\n filters.length === 0 ? undefined : (row: Record<string, unknown>) => rowMatches(row, filters),\n [filters],\n );\n return {\n fixedFilters: combined,\n ...(gate.gate === undefined ? {} : { gate: gate.gate }),\n ...(rowFits === undefined ? {} : { rowFits }),\n };\n}\n"],"mappings":";;;;;;;AAGA,MAAM,UAAA,GAASA,MAAAA,KAAAA,OAAAA,QAAAA,QAAAA,CAAAA,CAAAA,WAAAA,QACb,uCAAA,CAAA,CAAA,CAAsC,MAAM,YAAY,EACtD,SAAS,OAAO,qBAClB,EAAE,CACJ;AAGA,SAAgB,yBACd,OACc;CACd,QACE,GAAA,kBAAA,IAAA,CAACC,MAAAA,UAAD;EAAU,UAAU;EAClB,WAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAQ,GAAI,MAAQ,CAAA;CACZ,CAAA;AAEd;;;ACRA,SAAgB,WACd,KACA,SACqB;CACrB,IAAI,UAAU;CACd,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ;EACd,IAAI,MAAM,QAAQ,MAAM,GAAG,KAAK,MAAM,QAAQ,MAAM,EAAE,GAAG;GAIvD,MAAM,WAFJ,MAAM,QAAQ,MAAM,GAAG,IAAI,MAAM,MAAM,MAAM,GAAA,CAEzB,KAAK,SAAS,WAAW,KAAK,CAAC,IAAI,CAAC,CAAC;GAC3D,MAAM,MAAM,MAAM,QAAQ,MAAM,GAAG;GACnC,MAAM,UAAU,QAAQ,QAAQ,WAAW,WAAW,KAAA,CAAS;GAC/D,IAAI,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,SAAS,KAAK,CAAC,QAAQ,SAAS,IAAI,GAC9E,OAAO;GACT,IAAI,QAAQ,SAAS,QAAQ,UAAU,EAAE,MAAM,QAAQ,QAAQ,SAAS,IAAI,IAC1E,UAAU;GACZ;EACF;EACA,MAAM,EAAE,OAAO,IAAI,UAAU;EAC7B,IAAI,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU;EACzD,IAAI,CAAC,OAAO,OAAO,KAAK,KAAK,GAAG;GAC9B,UAAU;GACV;EACF;EACA,MAAM,OAAO,MAAM,IAAI,QAAQ,IAAI,KAAK;EACxC,IAAI,SAAS,OAAO,OAAO;EAC3B,IAAI,SAAS,KAAA,GAAW,UAAU;CACpC;CACA,OAAO,UAAU,KAAA,IAAY;AAC/B;AAEA,SAAS,MAAM,QAAiB,IAAY,UAAwC;CAClF,MAAM,OAAO,MAAM,QAAQ,QAAQ,IAAK,WAAkC,KAAA;CAC1E,MAAM,QAAQ,UAAmB,OAAO,SAAS,EAAE,CAAC,CAAC,YAAY;CACjE,QAAQ,IAAR;EACE,KAAK,MACH,OAAO,OAAO,GAAG,QAAQ,QAAQ,KAAK,OAAO,MAAM,MAAM,OAAO,QAAQ;EAC1E,KAAK,OACH,OAAO,EAAE,OAAO,GAAG,QAAQ,QAAQ,KAAK,OAAO,MAAM,MAAM,OAAO,QAAQ;EAC5E,KAAK,MACH,OAAO,SAAS,KAAA,IACZ,KAAA,IACA,KAAK,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC;EAC3D,KAAK,SACH,OAAO,SAAS,KAAA,IACZ,KAAA,IACA,CAAC,KAAK,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC;EAC5D,KAAK,MACH,OAAO,QAAQ,QAAQ,WAAW,GAAG,MAAM,IAAI,CAAC;EAClD,KAAK,OACH,OAAO,QAAQ,QAAQ,WAAW,GAAG,MAAM,KAAK,CAAC;EACnD,KAAK,MACH,OAAO,QAAQ,QAAQ,WAAW,GAAG,MAAM,IAAI,CAAC;EAClD,KAAK,OACH,OAAO,QAAQ,QAAQ,WAAW,GAAG,MAAM,KAAK,CAAC;EACnD,KAAK,YACH,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC;EAC7C,KAAK,cACH,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC;EAC/C,KAAK,YACH,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC;EAC7C,KAAK,UACH,OAAO,WAAW,QAAQ,WAAW,KAAA;EACvC,KAAK,aACH,OAAO,WAAW,QAAQ,WAAW,KAAA;EACvC,SACE;CACJ;AACF;AAEA,SAAS,QACP,QACA,UACA,MACqB;CAIrB,OAFG,OAAO,WAAW,YAAY,OAAO,aAAa,YAClD,OAAO,WAAW,YAAY,OAAO,aAAa,WACvC,KAAK,QAA2B,QAA2B,IAAI,KAAA;AAC/E;;;ACzEA,MAAM,aAA4B,OAAO,OAAO,CAAC,CAAC;AAClD,MAAM,aAA0C,OAAO,OAAO,CAAC,CAAC;AAShE,SAAgB,kBAAkB,OAMoD;CACpF,MAAM,EAAE,IAAI,YAAY,SAAS,UAAU,cAAc;CACzD,MAAM,KAAA,GAAIC,cAAAA,aAAAA,CAAa;CACvB,MAAM,OAAA,GAAMC,cAAAA,OAAAA,CAAO;CACnB,MAAM,OAAA,GAAMC,cAAAA,WAAAA,CAAW;CACvB,MAAM,aAAA,GAAYC,cAAAA,YAAAA,CAAY,QAAQ;CACtC,MAAM,cAAA,GAAaA,cAAAA,YAAAA,CAAY,MAAM,QAAQ;CAC7C,MAAM,UAAA,GAASC,cAAAA,oBAAAA,CAAoB,MAAM,IAAI,UAAU;CACvD,MAAM,aAAaC,MAAM,eAAA,GACjBC,aAAAA,kBAAAA,CAAkB,YAAY,WAAW,UAAU,GACzD,CAAC,YAAY,OAAO,CACtB;CACA,IAAI,eAAe,KAAA,KAAa,WAAW,WAAW,GAAG,OAAO,EAAE,SAAS,WAAW;CACtF,MAAM,SAAS,IAAI,uBAAuB,UAAU,SAAS;CAC7D,IAAI,OAAO,WAAW,WAAW,OAAO;EAAE,SAAS;EAAY,MAAM,EAAE,MAAM,UAAU;CAAE;CACzF,IAAI,OAAO,WAAW,aAAa;EACjC,MAAM,YAAA,GAAWC,aAAAA,aAAAA,CACf,UACC,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC,EAAE,OAAA,GAAiD,OAAO,QACrF,OACF;EACA,MAAM,SAAA,GAAQC,aAAAA,kBAAAA,CAAkB,YAAY,OAAO,OAAO,QAAQ;EAClE,OAAO;GACL,SAAS;GACT,MAAM;IACJ,MAAM;IACN;IACA,SAAS,EAAE,iCAAiC;KAC1C,QAAQ,EAAE,MAAM;KAChB,cAAc,wBAAwB;IACxC,CAAC;GACH;EACF;CACF;CACA,IAAI,WAAW,WAAW,WAAW,OAAO;EAAE,SAAS;EAAY,MAAM,EAAE,MAAM,UAAU;CAAE;CAC7F,IAAI,WAAW,WAAW,SAAS;EACjC,MAAM,EAAE,QAAQ,SAAS,WAAW;EACpC,MAAM,OAAO,KAAK;EAIlB,MAAM,YADM,WAAW,YAAY,WAAW,aAErC,SAAS,KAAA,KAAA,GACZD,aAAAA,aAAAA,CACE,UACC,IAAI,SAAS,IAAI,QAAQ,CAAC,EAAE,OAAA,GAAiD,OAC9E,OACF,IACA,KAAA;EACN,MAAM,SAAA,GAAQC,aAAAA,kBAAAA,CAAkB,WAAW,QAAQ,QAAQ,QAAQ;EACnE,OAAO;GACL,SAAS;GACT,MAAM;IACJ,MAAM;IACN;IACA,SAAS,EAAE,8BAA8B;KACvC,QAAQ,EAAE,MAAM;KAChB,cAAc,UAAU,MAAM;IAChC,CAAC;GACH;EACF;CACF;CACA,OAAO,EAAE,SAAS,WAAW,QAAQ;AACvC;AAOA,SAAgB,sBAAsB,OAWpC;CACA,MAAM,EAAE,iBAAiB;CACzB,MAAM,OAAO,kBAAkB,KAAK;CACpC,MAAM,UAAU,KAAK;CACrB,MAAM,WAAWH,MAAM,cACd,QAAQ,WAAW,IAAI,eAAe,CAAC,GAAG,SAAS,GAAI,gBAAgB,CAAC,CAAE,GACjF,CAAC,SAAS,YAAY,CACxB;CACA,MAAM,UAAUA,MAAM,cAElB,QAAQ,WAAW,IAAI,KAAA,KAAa,QAAiC,WAAW,KAAK,OAAO,GAC9F,CAAC,OAAO,CACV;CACA,OAAO;EACL,cAAc;EACd,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;EACrD,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;CAC7C;AACF"}
@@ -0,0 +1,31 @@
1
+ import { t as FieldRelationPicker } from "./relation-picker-Z0ZJJ5uS.js";
2
+ import { t as useCandidateSelection } from "./candidates-gate-Bb70LPAy.js";
3
+ import { resourceKey } from "@burojs/core";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/fields/candidates-relation-picker.tsx
6
+ function CandidatesRelationPicker(props) {
7
+ const { name, field, metaSources, resource, fixedFilters } = props;
8
+ const meta = field?.meta;
9
+ const to = resourceKey(meta.to);
10
+ const selection = useCandidateSelection({
11
+ to,
12
+ candidates: meta.candidates,
13
+ sources: metaSources,
14
+ resource: resource ?? "",
15
+ fieldName: field?.name ?? name,
16
+ fixedFilters
17
+ });
18
+ return jsx(FieldRelationPicker, {
19
+ props,
20
+ to,
21
+ extra: {
22
+ fixedFilters: selection.fixedFilters,
23
+ ...selection.gate === void 0 ? {} : { candidatesGate: selection.gate },
24
+ ...selection.rowFits === void 0 ? {} : { rowFits: selection.rowFits }
25
+ }
26
+ });
27
+ }
28
+ //#endregion
29
+ export { CandidatesRelationPicker };
30
+
31
+ //# sourceMappingURL=candidates-relation-picker-B116Bmqi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates-relation-picker-B116Bmqi.js","names":[],"sources":["../src/fields/candidates-relation-picker.tsx"],"sourcesContent":["import { type RelationCandidate, type ResourceRefInput, resourceKey } from '@burojs/core';\nimport type * as React from 'react';\nimport { useCandidateSelection } from './candidates-gate.js';\nimport { FieldRelationPicker } from './relation-picker.js';\nimport type { FieldInputProps } from './registry.js';\n\n/** The select of a field that declares `candidates`: the gate and the filters it resolves. */\nexport function CandidatesRelationPicker(props: FieldInputProps): React.ReactElement {\n const { name, field, metaSources, resource, fixedFilters } = props;\n const meta = field?.meta as { to?: ResourceRefInput; candidates?: unknown };\n const to = resourceKey(meta.to as ResourceRefInput);\n const selection = useCandidateSelection({\n to,\n candidates: meta.candidates as readonly RelationCandidate[],\n sources: metaSources,\n resource: resource ?? '',\n fieldName: field?.name ?? name,\n fixedFilters,\n });\n return (\n <FieldRelationPicker\n props={props}\n to={to}\n extra={{\n fixedFilters: selection.fixedFilters,\n ...(selection.gate === undefined ? {} : { candidatesGate: selection.gate }),\n ...(selection.rowFits === undefined ? {} : { rowFits: selection.rowFits }),\n }}\n />\n );\n}\n"],"mappings":";;;;;AAOA,SAAgB,yBAAyB,OAA4C;CACnF,MAAM,EAAE,MAAM,OAAO,aAAa,UAAU,iBAAiB;CAC7D,MAAM,OAAO,OAAO;CACpB,MAAM,KAAK,YAAY,KAAK,EAAsB;CAClD,MAAM,YAAY,sBAAsB;EACtC;EACA,YAAY,KAAK;EACjB,SAAS;EACT,UAAU,YAAY;EACtB,WAAW,OAAO,QAAQ;EAC1B;CACF,CAAC;CACD,OACE,IAAC,qBAAD;EACS;EACH;EACJ,OAAO;GACL,cAAc,UAAU;GACxB,GAAI,UAAU,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,UAAU,KAAK;GACzE,GAAI,UAAU,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,UAAU,QAAQ;EAC1E;CACD,CAAA;AAEL"}
@@ -0,0 +1,31 @@
1
+ const require_relation_picker = require("./relation-picker-gag0qSR5.cjs");
2
+ const require_candidates_gate = require("./candidates-gate-D33jXLHO.cjs");
3
+ let _burojs_core = require("@burojs/core");
4
+ let react_jsx_runtime = require("react/jsx-runtime");
5
+ //#region src/fields/candidates-relation-picker.tsx
6
+ function CandidatesRelationPicker(props) {
7
+ const { name, field, metaSources, resource, fixedFilters } = props;
8
+ const meta = field?.meta;
9
+ const to = (0, _burojs_core.resourceKey)(meta.to);
10
+ const selection = require_candidates_gate.useCandidateSelection({
11
+ to,
12
+ candidates: meta.candidates,
13
+ sources: metaSources,
14
+ resource: resource ?? "",
15
+ fieldName: field?.name ?? name,
16
+ fixedFilters
17
+ });
18
+ return (0, react_jsx_runtime.jsx)(require_relation_picker.FieldRelationPicker, {
19
+ props,
20
+ to,
21
+ extra: {
22
+ fixedFilters: selection.fixedFilters,
23
+ ...selection.gate === void 0 ? {} : { candidatesGate: selection.gate },
24
+ ...selection.rowFits === void 0 ? {} : { rowFits: selection.rowFits }
25
+ }
26
+ });
27
+ }
28
+ //#endregion
29
+ exports.CandidatesRelationPicker = CandidatesRelationPicker;
30
+
31
+ //# sourceMappingURL=candidates-relation-picker-Cy0rTxvI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates-relation-picker-Cy0rTxvI.cjs","names":["resourceKey","useCandidateSelection","FieldRelationPicker"],"sources":["../src/fields/candidates-relation-picker.tsx"],"sourcesContent":["import { type RelationCandidate, type ResourceRefInput, resourceKey } from '@burojs/core';\nimport type * as React from 'react';\nimport { useCandidateSelection } from './candidates-gate.js';\nimport { FieldRelationPicker } from './relation-picker.js';\nimport type { FieldInputProps } from './registry.js';\n\n/** The select of a field that declares `candidates`: the gate and the filters it resolves. */\nexport function CandidatesRelationPicker(props: FieldInputProps): React.ReactElement {\n const { name, field, metaSources, resource, fixedFilters } = props;\n const meta = field?.meta as { to?: ResourceRefInput; candidates?: unknown };\n const to = resourceKey(meta.to as ResourceRefInput);\n const selection = useCandidateSelection({\n to,\n candidates: meta.candidates as readonly RelationCandidate[],\n sources: metaSources,\n resource: resource ?? '',\n fieldName: field?.name ?? name,\n fixedFilters,\n });\n return (\n <FieldRelationPicker\n props={props}\n to={to}\n extra={{\n fixedFilters: selection.fixedFilters,\n ...(selection.gate === undefined ? {} : { candidatesGate: selection.gate }),\n ...(selection.rowFits === undefined ? {} : { rowFits: selection.rowFits }),\n }}\n />\n );\n}\n"],"mappings":";;;;;AAOA,SAAgB,yBAAyB,OAA4C;CACnF,MAAM,EAAE,MAAM,OAAO,aAAa,UAAU,iBAAiB;CAC7D,MAAM,OAAO,OAAO;CACpB,MAAM,MAAA,GAAKA,aAAAA,YAAAA,CAAY,KAAK,EAAsB;CAClD,MAAM,YAAYC,wBAAAA,sBAAsB;EACtC;EACA,YAAY,KAAK;EACjB,SAAS;EACT,UAAU,YAAY;EACtB,WAAW,OAAO,QAAQ;EAC1B;CACF,CAAC;CACD,QACE,GAAA,kBAAA,IAAA,CAACC,wBAAAA,qBAAD;EACS;EACH;EACJ,OAAO;GACL,cAAc,UAAU;GACxB,GAAI,UAAU,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,UAAU,KAAK;GACzE,GAAI,UAAU,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,UAAU,QAAQ;EAC1E;CACD,CAAA;AAEL"}