@arbidocs/blocks 0.5.16 → 0.5.18

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 (205) hide show
  1. package/dist/{ConnectedCallDock-PNF46ZCD.js → ConnectedCallDock-2NBGBWY5.js} +6 -6
  2. package/dist/{ConnectedCallDock-PNF46ZCD.js.map → ConnectedCallDock-2NBGBWY5.js.map} +1 -1
  3. package/dist/{ConnectedCallDock-AN7H7EA5.cjs → ConnectedCallDock-W5WIPP3F.cjs} +15 -15
  4. package/dist/{ConnectedCallDock-AN7H7EA5.cjs.map → ConnectedCallDock-W5WIPP3F.cjs.map} +1 -1
  5. package/dist/{ConnectedCallRoom-BCBK3JOH.js → ConnectedCallRoom-5AZH33AJ.js} +6 -6
  6. package/dist/{ConnectedCallRoom-BCBK3JOH.js.map → ConnectedCallRoom-5AZH33AJ.js.map} +1 -1
  7. package/dist/{ConnectedCallRoom-CISDTK4R.cjs → ConnectedCallRoom-XR25N6PN.cjs} +7 -7
  8. package/dist/{ConnectedCallRoom-CISDTK4R.cjs.map → ConnectedCallRoom-XR25N6PN.cjs.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-FCAICKSW.js → ConnectedNativeDocxComparison-FZNRXKCH.js} +12 -11
  10. package/dist/{ConnectedNativeDocxComparison-FCAICKSW.js.map → ConnectedNativeDocxComparison-FZNRXKCH.js.map} +1 -1
  11. package/dist/{ConnectedNativeDocxComparison-M2YD5ZIU.cjs → ConnectedNativeDocxComparison-KEDY65GN.cjs} +13 -12
  12. package/dist/{ConnectedNativeDocxComparison-M2YD5ZIU.cjs.map → ConnectedNativeDocxComparison-KEDY65GN.cjs.map} +1 -1
  13. package/dist/{ConnectedNativeDocxEditor-WCVJ7UTP.js → ConnectedNativeDocxEditor-E3ZGVJZJ.js} +11 -10
  14. package/dist/{ConnectedNativeDocxEditor-WCVJ7UTP.js.map → ConnectedNativeDocxEditor-E3ZGVJZJ.js.map} +1 -1
  15. package/dist/{ConnectedNativeDocxEditor-USWYSQTI.cjs → ConnectedNativeDocxEditor-WDIX32SH.cjs} +13 -12
  16. package/dist/{ConnectedNativeDocxEditor-USWYSQTI.cjs.map → ConnectedNativeDocxEditor-WDIX32SH.cjs.map} +1 -1
  17. package/dist/{ConnectedStreamedWordArtifact-4VXP44AG.cjs → ConnectedStreamedWordArtifact-AALQYJ5H.cjs} +13 -12
  18. package/dist/ConnectedStreamedWordArtifact-AALQYJ5H.cjs.map +1 -0
  19. package/dist/{ConnectedStreamedWordArtifact-EWTERIGT.js → ConnectedStreamedWordArtifact-HTUZ2KK2.js} +12 -11
  20. package/dist/ConnectedStreamedWordArtifact-HTUZ2KK2.js.map +1 -0
  21. package/dist/{WorkspaceTableView-V236NDPK.js → WorkspaceTableView-4VMLQOQ5.js} +4 -4
  22. package/dist/{WorkspaceTableView-V236NDPK.js.map → WorkspaceTableView-4VMLQOQ5.js.map} +1 -1
  23. package/dist/{WorkspaceTableView-P4PCXHZ6.cjs → WorkspaceTableView-S2ZHZ64L.cjs} +5 -5
  24. package/dist/{WorkspaceTableView-P4PCXHZ6.cjs.map → WorkspaceTableView-S2ZHZ64L.cjs.map} +1 -1
  25. package/dist/agents/index.cjs +330 -329
  26. package/dist/agents/index.js +8 -7
  27. package/dist/calls/index.cjs +142 -142
  28. package/dist/calls/index.js +10 -10
  29. package/dist/{chunk-5QJDDEYV.js → chunk-2AWDMU6T.js} +3 -3
  30. package/dist/{chunk-5QJDDEYV.js.map → chunk-2AWDMU6T.js.map} +1 -1
  31. package/dist/{chunk-ATNQD3AE.js → chunk-2EYAJAKT.js} +3 -3
  32. package/dist/{chunk-ATNQD3AE.js.map → chunk-2EYAJAKT.js.map} +1 -1
  33. package/dist/{chunk-PBM6BFFH.cjs → chunk-3L5MXUBZ.cjs} +4 -4
  34. package/dist/{chunk-PBM6BFFH.cjs.map → chunk-3L5MXUBZ.cjs.map} +1 -1
  35. package/dist/{chunk-4IMTH6Z4.js → chunk-5RHNGSVP.js} +3 -3
  36. package/dist/{chunk-4IMTH6Z4.js.map → chunk-5RHNGSVP.js.map} +1 -1
  37. package/dist/{chunk-TRHAIU6U.js → chunk-5S424MAG.js} +4 -4
  38. package/dist/{chunk-TRHAIU6U.js.map → chunk-5S424MAG.js.map} +1 -1
  39. package/dist/{chunk-TDIC7IXS.cjs → chunk-63VQD4R7.cjs} +7 -7
  40. package/dist/{chunk-TDIC7IXS.cjs.map → chunk-63VQD4R7.cjs.map} +1 -1
  41. package/dist/{chunk-LFBT3XTK.cjs → chunk-6MHGFCIW.cjs} +14 -14
  42. package/dist/{chunk-LFBT3XTK.cjs.map → chunk-6MHGFCIW.cjs.map} +1 -1
  43. package/dist/{chunk-N5YEF3LC.js → chunk-7F5Z4K5W.js} +18 -20
  44. package/dist/chunk-7F5Z4K5W.js.map +1 -0
  45. package/dist/{chunk-5DRKMFRL.cjs → chunk-APZFUKR4.cjs} +55 -55
  46. package/dist/{chunk-5DRKMFRL.cjs.map → chunk-APZFUKR4.cjs.map} +1 -1
  47. package/dist/{chunk-ZJX7RUQ3.js → chunk-B5BJH76B.js} +4 -4
  48. package/dist/{chunk-ZJX7RUQ3.js.map → chunk-B5BJH76B.js.map} +1 -1
  49. package/dist/{chunk-4AAM6UQG.js → chunk-BIZDGRNM.js} +3 -3
  50. package/dist/{chunk-4AAM6UQG.js.map → chunk-BIZDGRNM.js.map} +1 -1
  51. package/dist/{chunk-5NFQCGGO.cjs → chunk-BLESTVHK.cjs} +5 -5
  52. package/dist/{chunk-5NFQCGGO.cjs.map → chunk-BLESTVHK.cjs.map} +1 -1
  53. package/dist/{chunk-5TALCIRH.js → chunk-CH4FHZSR.js} +4 -91
  54. package/dist/chunk-CH4FHZSR.js.map +1 -0
  55. package/dist/{chunk-UCVCYHAC.js → chunk-CTCF4I22.js} +3 -3
  56. package/dist/{chunk-UCVCYHAC.js.map → chunk-CTCF4I22.js.map} +1 -1
  57. package/dist/{chunk-AAWF27UG.js → chunk-D3OGQ5ZW.js} +3 -3
  58. package/dist/{chunk-AAWF27UG.js.map → chunk-D3OGQ5ZW.js.map} +1 -1
  59. package/dist/{chunk-DJ4BTWMA.cjs → chunk-DAL6B556.cjs} +4 -4
  60. package/dist/{chunk-DJ4BTWMA.cjs.map → chunk-DAL6B556.cjs.map} +1 -1
  61. package/dist/{chunk-RAPIHS52.js → chunk-E3H7Q3ZO.js} +3 -3
  62. package/dist/{chunk-RAPIHS52.js.map → chunk-E3H7Q3ZO.js.map} +1 -1
  63. package/dist/{chunk-XUWZMZP5.cjs → chunk-F4UYC2M2.cjs} +5 -5
  64. package/dist/{chunk-XUWZMZP5.cjs.map → chunk-F4UYC2M2.cjs.map} +1 -1
  65. package/dist/{chunk-WINJF2AK.js → chunk-F6UJUUFK.js} +3 -3
  66. package/dist/{chunk-WINJF2AK.js.map → chunk-F6UJUUFK.js.map} +1 -1
  67. package/dist/{chunk-I5KTRLKB.cjs → chunk-G6GUMZOZ.cjs} +10 -10
  68. package/dist/{chunk-I5KTRLKB.cjs.map → chunk-G6GUMZOZ.cjs.map} +1 -1
  69. package/dist/{chunk-RG4SLXZG.js → chunk-G7PAZQHJ.js} +3 -3
  70. package/dist/{chunk-RG4SLXZG.js.map → chunk-G7PAZQHJ.js.map} +1 -1
  71. package/dist/{chunk-CJFJNR2V.js → chunk-GTO65EQQ.js} +3 -3
  72. package/dist/{chunk-CJFJNR2V.js.map → chunk-GTO65EQQ.js.map} +1 -1
  73. package/dist/{chunk-IFE4MZXD.js → chunk-H7L43DIE.js} +3 -3
  74. package/dist/{chunk-IFE4MZXD.js.map → chunk-H7L43DIE.js.map} +1 -1
  75. package/dist/{chunk-VPUGVNGV.cjs → chunk-HVEDOBLY.cjs} +4 -4
  76. package/dist/{chunk-VPUGVNGV.cjs.map → chunk-HVEDOBLY.cjs.map} +1 -1
  77. package/dist/{chunk-LHLBMP24.js → chunk-HVXNEOOU.js} +6 -6
  78. package/dist/{chunk-LHLBMP24.js.map → chunk-HVXNEOOU.js.map} +1 -1
  79. package/dist/{chunk-PSWTOD7E.js → chunk-HXYYH4OB.js} +3 -3
  80. package/dist/{chunk-PSWTOD7E.js.map → chunk-HXYYH4OB.js.map} +1 -1
  81. package/dist/{chunk-4MADJGGF.cjs → chunk-JYYJGYUP.cjs} +4 -4
  82. package/dist/{chunk-4MADJGGF.cjs.map → chunk-JYYJGYUP.cjs.map} +1 -1
  83. package/dist/{chunk-AUDT4L2H.cjs → chunk-KNQQFJNE.cjs} +4 -4
  84. package/dist/{chunk-AUDT4L2H.cjs.map → chunk-KNQQFJNE.cjs.map} +1 -1
  85. package/dist/{chunk-TSD3GFOH.js → chunk-L5UHXBJK.js} +3 -3
  86. package/dist/{chunk-TSD3GFOH.js.map → chunk-L5UHXBJK.js.map} +1 -1
  87. package/dist/{chunk-ITOQYYTG.cjs → chunk-LFVD3CS5.cjs} +5 -5
  88. package/dist/{chunk-ITOQYYTG.cjs.map → chunk-LFVD3CS5.cjs.map} +1 -1
  89. package/dist/{chunk-C2CWWEHO.cjs → chunk-LKK52DEY.cjs} +18 -20
  90. package/dist/chunk-LKK52DEY.cjs.map +1 -0
  91. package/dist/{chunk-52BZME74.cjs → chunk-LNLAD7XW.cjs} +4 -4
  92. package/dist/{chunk-52BZME74.cjs.map → chunk-LNLAD7XW.cjs.map} +1 -1
  93. package/dist/{chunk-SWBD76UN.cjs → chunk-M36FYCOE.cjs} +9 -9
  94. package/dist/{chunk-SWBD76UN.cjs.map → chunk-M36FYCOE.cjs.map} +1 -1
  95. package/dist/{chunk-RPWNNTJJ.js → chunk-M3AADQ4Y.js} +7 -7
  96. package/dist/{chunk-RPWNNTJJ.js.map → chunk-M3AADQ4Y.js.map} +1 -1
  97. package/dist/{chunk-NEODSOVW.js → chunk-MYJJ3RPH.js} +3 -3
  98. package/dist/{chunk-NEODSOVW.js.map → chunk-MYJJ3RPH.js.map} +1 -1
  99. package/dist/{chunk-3NTC4UZV.js → chunk-NUHWRBSL.js} +3 -3
  100. package/dist/{chunk-3NTC4UZV.js.map → chunk-NUHWRBSL.js.map} +1 -1
  101. package/dist/{chunk-VP7VAE2M.cjs → chunk-P4NS4LV7.cjs} +6 -6
  102. package/dist/{chunk-VP7VAE2M.cjs.map → chunk-P4NS4LV7.cjs.map} +1 -1
  103. package/dist/{chunk-MRG4OUL3.js → chunk-PJYE6AJS.js} +6 -6
  104. package/dist/{chunk-MRG4OUL3.js.map → chunk-PJYE6AJS.js.map} +1 -1
  105. package/dist/{chunk-JWNCZ6UP.cjs → chunk-QVMQMPBZ.cjs} +4 -4
  106. package/dist/{chunk-JWNCZ6UP.cjs.map → chunk-QVMQMPBZ.cjs.map} +1 -1
  107. package/dist/{chunk-3GT6GPTM.cjs → chunk-RZ3EBN7G.cjs} +26 -26
  108. package/dist/{chunk-3GT6GPTM.cjs.map → chunk-RZ3EBN7G.cjs.map} +1 -1
  109. package/dist/{chunk-CPLRUC7D.cjs → chunk-SHRNXL2Q.cjs} +76 -76
  110. package/dist/{chunk-CPLRUC7D.cjs.map → chunk-SHRNXL2Q.cjs.map} +1 -1
  111. package/dist/chunk-SI222Z3A.cjs +185 -0
  112. package/dist/chunk-SI222Z3A.cjs.map +1 -0
  113. package/dist/{chunk-DCQGJNZQ.js → chunk-SX2RX5DT.js} +3 -3
  114. package/dist/{chunk-DCQGJNZQ.js.map → chunk-SX2RX5DT.js.map} +1 -1
  115. package/dist/{chunk-3EVLRDXP.cjs → chunk-SZGUU2TS.cjs} +7 -7
  116. package/dist/{chunk-3EVLRDXP.cjs.map → chunk-SZGUU2TS.cjs.map} +1 -1
  117. package/dist/{chunk-A6MGGHHN.cjs → chunk-T55BHIB7.cjs} +4 -4
  118. package/dist/{chunk-A6MGGHHN.cjs.map → chunk-T55BHIB7.cjs.map} +1 -1
  119. package/dist/{chunk-35AUFGD7.js → chunk-T5ZFFHC6.js} +4 -4
  120. package/dist/{chunk-35AUFGD7.js.map → chunk-T5ZFFHC6.js.map} +1 -1
  121. package/dist/{chunk-ML27HIMM.cjs → chunk-TCT2VS72.cjs} +6 -6
  122. package/dist/{chunk-ML27HIMM.cjs.map → chunk-TCT2VS72.cjs.map} +1 -1
  123. package/dist/{chunk-OKYALUAN.js → chunk-TXLMCQOH.js} +4 -4
  124. package/dist/{chunk-OKYALUAN.js.map → chunk-TXLMCQOH.js.map} +1 -1
  125. package/dist/chunk-U4HWVCRN.js +180 -0
  126. package/dist/chunk-U4HWVCRN.js.map +1 -0
  127. package/dist/{chunk-IUPZMPXP.cjs → chunk-UR6DWL4L.cjs} +20 -20
  128. package/dist/{chunk-IUPZMPXP.cjs.map → chunk-UR6DWL4L.cjs.map} +1 -1
  129. package/dist/{chunk-AE3M3RTH.js → chunk-VNWWK44S.js} +6 -6
  130. package/dist/{chunk-AE3M3RTH.js.map → chunk-VNWWK44S.js.map} +1 -1
  131. package/dist/{chunk-HJQLVCIK.cjs → chunk-WUG24K7P.cjs} +4 -4
  132. package/dist/{chunk-HJQLVCIK.cjs.map → chunk-WUG24K7P.cjs.map} +1 -1
  133. package/dist/{chunk-U7ZBIU4S.cjs → chunk-XZ2IUJQV.cjs} +4 -4
  134. package/dist/{chunk-U7ZBIU4S.cjs.map → chunk-XZ2IUJQV.cjs.map} +1 -1
  135. package/dist/{chunk-5RIPA5DV.js → chunk-YFLARXLW.js} +5 -5
  136. package/dist/{chunk-5RIPA5DV.js.map → chunk-YFLARXLW.js.map} +1 -1
  137. package/dist/{chunk-OTV7TUKD.cjs → chunk-Z3IB6UMJ.cjs} +29 -29
  138. package/dist/{chunk-OTV7TUKD.cjs.map → chunk-Z3IB6UMJ.cjs.map} +1 -1
  139. package/dist/{chunk-BZF6E46W.cjs → chunk-ZLSMS6OK.cjs} +5 -92
  140. package/dist/chunk-ZLSMS6OK.cjs.map +1 -0
  141. package/dist/citations/index.cjs +12 -10
  142. package/dist/citations/index.js +4 -2
  143. package/dist/collaboration/index.cjs +68 -68
  144. package/dist/collaboration/index.js +2 -2
  145. package/dist/connect/docx.cjs +15 -14
  146. package/dist/connect/docx.js +11 -10
  147. package/dist/connect/index.cjs +774 -775
  148. package/dist/connect/index.cjs.map +1 -1
  149. package/dist/connect/index.js +34 -35
  150. package/dist/connect/index.js.map +1 -1
  151. package/dist/connect/viewer.cjs +95 -95
  152. package/dist/connect/viewer.js +18 -18
  153. package/dist/connection/billing/{ReferralReward.d.ts → ConnectedReferralReward.d.ts} +7 -7
  154. package/dist/connection/billing/referral-reward.d.ts +1 -1
  155. package/dist/databases/index.cjs +2 -2
  156. package/dist/databases/index.js +1 -1
  157. package/dist/document-tools/index.cjs +16 -16
  158. package/dist/document-tools/index.js +2 -2
  159. package/dist/facts/index.cjs +6 -5
  160. package/dist/facts/index.cjs.map +1 -1
  161. package/dist/facts/index.js +4 -3
  162. package/dist/facts/index.js.map +1 -1
  163. package/dist/files/index.cjs +226 -225
  164. package/dist/files/index.js +5 -4
  165. package/dist/home/index.cjs +31 -30
  166. package/dist/home/index.cjs.map +1 -1
  167. package/dist/home/index.js +6 -5
  168. package/dist/home/index.js.map +1 -1
  169. package/dist/index.cjs +521 -520
  170. package/dist/index.cjs.map +1 -1
  171. package/dist/index.js +16 -15
  172. package/dist/index.js.map +1 -1
  173. package/dist/provider/dialogs.d.ts +43 -0
  174. package/dist/retrieval/index.cjs +5 -4
  175. package/dist/retrieval/index.js +3 -2
  176. package/dist/settings/index.cjs +3 -3
  177. package/dist/settings/index.d.ts +1 -1
  178. package/dist/settings/index.js +1 -1
  179. package/dist/shell/index.cjs +47 -46
  180. package/dist/shell/index.js +4 -3
  181. package/dist/studio/index.cjs +14 -13
  182. package/dist/studio/index.cjs.map +1 -1
  183. package/dist/studio/index.js +6 -5
  184. package/dist/studio/index.js.map +1 -1
  185. package/dist/workflow-canvas/index.cjs +28 -27
  186. package/dist/workflow-canvas/index.cjs.map +1 -1
  187. package/dist/workflow-canvas/index.js +10 -9
  188. package/dist/workflow-canvas/index.js.map +1 -1
  189. package/dist/workspaces/index.cjs +22 -20
  190. package/dist/workspaces/index.cjs.map +1 -1
  191. package/dist/workspaces/index.js +6 -4
  192. package/dist/workspaces/index.js.map +1 -1
  193. package/node_modules/@arbidocs/coedit/package.json +1 -1
  194. package/package.json +5 -5
  195. package/dist/ConnectedStreamedWordArtifact-4VXP44AG.cjs.map +0 -1
  196. package/dist/ConnectedStreamedWordArtifact-EWTERIGT.js.map +0 -1
  197. package/dist/chunk-5TALCIRH.js.map +0 -1
  198. package/dist/chunk-BZF6E46W.cjs.map +0 -1
  199. package/dist/chunk-C2CWWEHO.cjs.map +0 -1
  200. package/dist/chunk-ECERC6TI.js +0 -77
  201. package/dist/chunk-ECERC6TI.js.map +0 -1
  202. package/dist/chunk-N5YEF3LC.js.map +0 -1
  203. package/dist/chunk-ZAVEMQ37.cjs +0 -80
  204. package/dist/chunk-ZAVEMQ37.cjs.map +0 -1
  205. package/dist/settings/ConfirmDialog.d.ts +0 -31
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk5NFQCGGO_cjs = require('./chunk-5NFQCGGO.cjs');
5
- var chunkA6MGGHHN_cjs = require('./chunk-A6MGGHHN.cjs');
4
+ var chunkBLESTVHK_cjs = require('./chunk-BLESTVHK.cjs');
5
+ var chunkT55BHIB7_cjs = require('./chunk-T55BHIB7.cjs');
6
6
  var chunkMB3S2ETI_cjs = require('./chunk-MB3S2ETI.cjs');
7
- var chunkBZF6E46W_cjs = require('./chunk-BZF6E46W.cjs');
7
+ var chunkZLSMS6OK_cjs = require('./chunk-ZLSMS6OK.cjs');
8
8
  var chunkZ2XZ2D4N_cjs = require('./chunk-Z2XZ2D4N.cjs');
9
9
  var chunkCQ2YSHIF_cjs = require('./chunk-CQ2YSHIF.cjs');
10
10
  var React = require('react');
@@ -138,7 +138,7 @@ function WorkspaceDocumentReference({
138
138
  children,
139
139
  className = "inline-flex rounded-full border px-2 py-0.5 text-xs hover:bg-muted"
140
140
  }) {
141
- const { openDocument } = chunkBZF6E46W_cjs.useBlocksEnvironment();
141
+ const { openDocument } = chunkZLSMS6OK_cjs.useBlocksEnvironment();
142
142
  return /* @__PURE__ */ jsxRuntime.jsx(
143
143
  "button",
144
144
  {
@@ -165,19 +165,19 @@ function MentionLink({ kind, id, text }) {
165
165
  );
166
166
  }
167
167
  function ExternalLink({ href, children }) {
168
- return /* @__PURE__ */ jsxRuntime.jsx(chunk5NFQCGGO_cjs.QuietLink, { href, kind: "external", children });
168
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkBLESTVHK_cjs.QuietLink, { href, kind: "external", children });
169
169
  }
170
170
  function InternalDocLink({
171
171
  docId,
172
172
  href,
173
173
  children
174
174
  }) {
175
- const { openDocument } = chunkBZF6E46W_cjs.useBlocksEnvironment();
175
+ const { openDocument } = chunkZLSMS6OK_cjs.useBlocksEnvironment();
176
176
  const workspaceId = useDocumentWorkspace();
177
177
  if (workspaceId) {
178
178
  return /* @__PURE__ */ jsxRuntime.jsx(WorkspaceDocumentReference, { workspaceId, docId, children });
179
179
  }
180
- return /* @__PURE__ */ jsxRuntime.jsx(chunk5NFQCGGO_cjs.QuietLink, { href, kind: "document", onOpen: () => openDocument(docId), children });
180
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkBLESTVHK_cjs.QuietLink, { href, kind: "document", onOpen: () => openDocument(docId), children });
181
181
  }
182
182
  function DocumentChip({ docId }) {
183
183
  const render = react.useArbiHost().chat?.renderDocumentChip;
@@ -187,7 +187,7 @@ function DocumentChip({ docId }) {
187
187
  }
188
188
  function DefaultDocumentChip({ docId }) {
189
189
  const { data: doc } = react.useDocument(docId);
190
- const { openDocument } = chunkBZF6E46W_cjs.useBlocksEnvironment();
190
+ const { openDocument } = chunkZLSMS6OK_cjs.useBlocksEnvironment();
191
191
  if (!doc)
192
192
  return /* @__PURE__ */ jsxRuntime.jsx(
193
193
  ui.EntityPill,
@@ -220,13 +220,13 @@ var conversationMarkdownComponents = {
220
220
  children,
221
221
  ...props
222
222
  }) {
223
- const deploymentDomain = chunkBZF6E46W_cjs.useBlocksEnvironment().runtimeConfig.deploymentDomain;
223
+ const deploymentDomain = chunkZLSMS6OK_cjs.useBlocksEnvironment().runtimeConfig.deploymentDomain;
224
224
  const mention = shell.mentionFromHref(href);
225
225
  if (mention) {
226
226
  return /* @__PURE__ */ jsxRuntime.jsx(MentionLink, { kind: mention.kind, id: mention.id, text: childrenText(children) });
227
227
  }
228
228
  if (href?.startsWith("#") && !href.startsWith("#cite-")) {
229
- return /* @__PURE__ */ jsxRuntime.jsx(chunk5NFQCGGO_cjs.QuietLink, { href, kind: "anchor", children });
229
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkBLESTVHK_cjs.QuietLink, { href, kind: "anchor", children });
230
230
  }
231
231
  if (!href || href.startsWith("#") || href.startsWith("cite:")) {
232
232
  return /* @__PURE__ */ jsxRuntime.jsx(ui.MarkdownLink, { href, ...props, children });
@@ -277,8 +277,8 @@ function OwnDocumentTools({ children }) {
277
277
  const arbi = react.useArbi();
278
278
  const queryClient = reactQuery.useQueryClient();
279
279
  const host = chunkMB3S2ETI_cjs.useHost().documentTools;
280
- const { user, ensureWorkspaceOpen } = chunkA6MGGHHN_cjs.useConnectedWorkspace();
281
- const { notify: environmentNotify, openDocument: openInHost } = chunkBZF6E46W_cjs.useBlocksEnvironment();
280
+ const { user, ensureWorkspaceOpen } = chunkT55BHIB7_cjs.useConnectedWorkspace();
281
+ const { notify: environmentNotify, openDocument: openInHost } = chunkZLSMS6OK_cjs.useBlocksEnvironment();
282
282
  const useEmailDocument = host?.useEmailDocument ?? NO_EMAIL;
283
283
  const emailDocument = useEmailDocument();
284
284
  const client = host?.client ?? (arbi.isLoggedIn ? arbi.getClient().fetch : null);
@@ -372,5 +372,5 @@ exports.useViewerDraftDocument = useViewerDraftDocument;
372
372
  exports.useViewerIsDetached = useViewerIsDetached;
373
373
  exports.useViewerPassageCitation = useViewerPassageCitation;
374
374
  exports.useViewerStreamingDocument = useViewerStreamingDocument;
375
- //# sourceMappingURL=chunk-LFBT3XTK.cjs.map
376
- //# sourceMappingURL=chunk-LFBT3XTK.cjs.map
375
+ //# sourceMappingURL=chunk-6MHGFCIW.cjs.map
376
+ //# sourceMappingURL=chunk-6MHGFCIW.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chat/mermaid-normalize.ts","../src/connection/conversation/MermaidDiagram.tsx","../src/connection/conversation/DocumentWorkspaceContext.tsx","../src/connection/conversation/ConnectedMarkdown.tsx","../src/connection/viewer/ConnectedDocumentToolsProvider.tsx","../src/connection/viewer/support.ts"],"names":["useState","useId","useEffect","jsxs","jsx","createContext","useContext","useBlocksEnvironment","React","useArbiSession","MentionChip","QuietLink","useArbiHost","Fragment","useDocument","EntityPill","FileText","DocumentEntity","Mail","mentionFromHref","MarkdownLink","workspaceDocIdFromHref","MarkdownStreamingContext","MarkdownCode","rehypeDocEntityPills","useMemo","KitMarkdownRenderer","useOptionalDocumentTools","useArbi","useQueryClient","useHost","useConnectedWorkspace","useCallback","refreshDocuments","arbiQueryKeys","documentBytesKey","clientUpload","DocumentToolsProvider"],"mappings":"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","file":"chunk-LFBT3XTK.cjs","sourcesContent":["/**\n * Defensive normalizer for single-line `graph` / `flowchart` Mermaid source.\n *\n * Some LLMs emit the entire diagram on one line. Mermaid's parser splits\n * statements on newlines, so a single-line graph fails outright. This helper\n * inserts newlines on safe statement boundaries so the diagram has a chance\n * of parsing. Only attempts normalization when:\n * 1. The source has no embedded newlines (i.e. is genuinely single-line), and\n * 2. The first directive is `graph` or `flowchart`.\n *\n * Other diagram types (sequenceDiagram, classDiagram, gantt, …) have very\n * different syntaxes — applying these heuristics to them would corrupt valid\n * input, so they're left untouched.\n *\n * Boundaries we split on:\n * - After the diagram-type header (`graph TD`, `flowchart LR`, …).\n * - Before each `style` / `classDef` / `class` / `linkStyle` / `click`\n * / `subgraph` keyword.\n * - Before/after `end` (closes a subgraph block).\n * - After a `]` (label close) that's followed by another node identifier\n * starting a new edge or node declaration.\n */\nexport function normalizeMermaidGraph(source: string): string {\n // Already multi-line — assume it's well-formed; don't touch it.\n if (/\\n/.test(source)) return source\n\n const headerMatch = source.match(/^\\s*(graph|flowchart)\\s+\\w+\\s+/)\n if (!headerMatch) return source\n\n const header = headerMatch[0].trimEnd()\n let body = source.slice(headerMatch[0].length)\n\n // Insert newline before keywords that always start a new statement.\n body = body.replace(/\\s+(style|classDef|class|linkStyle|click|subgraph)\\s/g, '\\n$1 ')\n\n // `end` closes a subgraph: put it on its own line, with a break after it\n // too so any trailing statements don't stay attached.\n body = body.replace(/\\s+end\\b\\s*/g, '\\nend\\n')\n\n // After a label close (`]`), if the next token looks like a Mermaid node id\n // followed by another `[` or `-->`, that's a new statement starting.\n body = body.replace(/\\]\\s+(?=[A-Za-z_][\\w-]*\\s*(?:\\[|-->))/g, ']\\n')\n\n // Collapse any accidental runs of blank lines we may have produced.\n body = body.replace(/\\n{2,}/g, '\\n')\n\n return `${header}\\n${body.trimStart()}`\n}\n","/**\n * MermaidDiagram Component\n *\n * Renders a Mermaid diagram from source code.\n * Used inside MarkdownRenderer to handle ```mermaid code blocks.\n * Lazy-loads the mermaid library to avoid bloating the initial bundle.\n */\n\nimport { useState, useEffect, useId } from 'react'\nimport { normalizeMermaidGraph } from '../../chat/mermaid-normalize'\n\ninterface MermaidDiagramProps {\n /** Mermaid diagram source code */\n chart: string\n}\n\n// Lazy-load and initialize mermaid once\nlet mermaidInstance: typeof import('mermaid').default | null = null\nlet mermaidLoadPromise: Promise<typeof import('mermaid').default> | null = null\n\nasync function getMermaid() {\n if (mermaidInstance) return mermaidInstance\n if (!mermaidLoadPromise) {\n mermaidLoadPromise = import('mermaid').then((mod) => {\n const m = mod.default\n m.initialize({\n startOnLoad: false,\n theme: 'default',\n securityLevel: 'strict',\n flowchart: { useMaxWidth: true, curve: 'basis' },\n })\n mermaidInstance = m\n return m\n })\n }\n return mermaidLoadPromise\n}\n\nexport function MermaidDiagram({ chart }: MermaidDiagramProps) {\n const [svg, setSvg] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const uniqueId = useId().replace(/:/g, '-')\n\n useEffect(() => {\n let cancelled = false\n\n async function render() {\n const mermaid = await getMermaid()\n const diagramId = `mermaid${uniqueId}`\n\n // Validate with parse() before render(). In Mermaid v11 a render() with\n // bad source can return a \"Syntax error in text\" bomb SVG instead of\n // throwing — and it appends DOM side-effects of its own — so a try/catch\n // around render() doesn't reliably catch failures and the bomb leaks\n // into the page (especially under React StrictMode where effects run\n // twice). parse() throws cleanly with no DOM side-effects.\n //\n // Defensive rescue: some LLMs emit single-line `graph`/`flowchart`\n // source. If the original parse fails, try a normalized variant. The\n // normalizer is a no-op on already-multi-line source and on non-graph\n // diagram types, so this only helps the bad-source case and never\n // corrupts valid input.\n let validSource: string | null = null\n let firstErr: unknown\n try {\n await mermaid.parse(chart)\n validSource = chart\n } catch (err) {\n firstErr = err\n const normalized = normalizeMermaidGraph(chart)\n if (normalized !== chart) {\n try {\n await mermaid.parse(normalized)\n validSource = normalized\n } catch (retryErr) {\n console.warn('Mermaid normalized parse also failed', retryErr)\n }\n }\n }\n\n if (cancelled) return\n\n if (!validSource) {\n console.warn('Mermaid parse failed, showing source', firstErr)\n setError('Failed to render diagram')\n setSvg(null)\n return\n }\n\n try {\n const { svg: renderedSvg } = await mermaid.render(diagramId, validSource)\n if (!cancelled) {\n setSvg(renderedSvg)\n setError(null)\n }\n } catch (renderErr) {\n if (!cancelled) {\n console.warn('Mermaid render failed despite parse success', renderErr)\n setError('Failed to render diagram')\n setSvg(null)\n }\n }\n }\n\n render()\n return () => {\n cancelled = true\n }\n }, [chart, uniqueId])\n\n if (error) {\n // Fall back to showing the raw source in a code block\n return (\n <div className=\"code-block\" data-testid=\"mermaid-error\">\n <div className=\"text-sm text-muted-foreground mb-1\">{error}</div>\n <code className=\"language-mermaid\">{chart}</code>\n </div>\n )\n }\n\n if (!svg) {\n return (\n <div\n className=\"flex items-center justify-center py-8 text-muted-foreground text-sm\"\n data-testid=\"mermaid-loading\"\n >\n Rendering diagram...\n </div>\n )\n }\n\n return (\n <div\n className=\"mermaid-diagram my-4 overflow-x-auto rounded-md border border-border bg-background p-4\"\n data-testid=\"mermaid-diagram\"\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n )\n}\n","/**\n * The workspace a conversation's document references belong to, when it is not the open one: an\n * agent's direct-message thread runs in the agent's workspace, so the documents it names are there.\n * A reference then opens that workspace first (`openDocument(id, { workspaceId })`).\n */\n\nimport { createContext, useContext, type ReactNode } from 'react'\nimport { useBlocksEnvironment } from '../../provider/environment'\n\n/** The workspace of the documents referenced inside it (null: the open workspace). */\nexport const DocumentWorkspaceContext = createContext<string | null>(null)\nexport const useDocumentWorkspace = () => useContext(DocumentWorkspaceContext)\n\n/** A reference to a document of another workspace: opening it opens that workspace first. */\nexport function WorkspaceDocumentReference({\n workspaceId,\n docId,\n children,\n className = 'inline-flex rounded-full border px-2 py-0.5 text-xs hover:bg-muted',\n}: {\n workspaceId: string\n docId: string\n children?: ReactNode\n className?: string\n}) {\n const { openDocument } = useBlocksEnvironment()\n return (\n <button\n type=\"button\"\n className={className}\n onClick={() => openDocument(docId, { workspaceId })}\n >\n {children ?? docId}\n </button>\n )\n}\n","/**\n * The conversation's markdown: the kit's `MarkdownRenderer` (`@arbidocs/react`: sanitised HTML,\n * slugs, lazy KaTeX, streaming blocks, tables, code) with what a conversation adds: @mention chips,\n * workspace documents opening in the viewer, quiet external links, document and email pills (the\n * host's chips, `ArbiChatHost.renderDocumentChip` / `renderMailChip`) and Mermaid diagrams.\n */\nimport { useArbiHost, useArbiSession, useDocument } from '@arbidocs/react'\nimport { mentionFromHref, type MentionKind } from '@arbidocs/react/shell'\nimport {\n EntityPill,\n MarkdownCode,\n MarkdownLink,\n MarkdownRenderer as KitMarkdownRenderer,\n MarkdownStreamingContext,\n type MarkdownRendererProps as KitMarkdownRendererProps,\n DocumentEntity,\n} from '@arbidocs/react/ui'\nimport React, { useContext, useMemo } from 'react'\nimport { FileText, Mail } from 'lucide-react'\n\n/** The markdown element overrides, as the kit's renderer takes them. */\ntype Components = NonNullable<KitMarkdownRendererProps['components']>\nimport { MentionChip } from '../../chat/MentionMenu'\nimport { QuietLink } from '../../citations/QuietMarks'\nimport { rehypeDocEntityPills } from '../../chat/rehype-doc-entity-pills'\nimport { workspaceDocIdFromHref } from '../../chat/doc-links'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { MermaidDiagram } from './MermaidDiagram'\nimport { useDocumentWorkspace, WorkspaceDocumentReference } from './DocumentWorkspaceContext'\n\n/** Plain text of a link's children (the `@Label` of a mention link). */\nfunction childrenText(children: React.ReactNode): string {\n return React.Children.toArray(children)\n .map((child) => (typeof child === 'string' || typeof child === 'number' ? String(child) : ''))\n .join('')\n}\n\n/** A mention chip; a mention of the reader stands out. */\nfunction MentionLink({ kind, id, text }: { kind: MentionKind; id: string; text: string }) {\n const currentUserId = useArbiSession().user?.external_id\n return (\n <MentionChip\n kind={kind}\n id={id}\n label={text.replace(/^@/, '')}\n isSelf={kind === 'user' && id === currentUserId}\n />\n )\n}\n\n/**\n * A link to elsewhere, as quiet text. Its menu (Open link / Copy link) is the deliberate step\n * the old confirmation dialog used to be; nothing opens until the menu's primary row is chosen.\n */\nexport function ExternalLink({ href, children }: React.ComponentPropsWithoutRef<'a'>) {\n return (\n <QuietLink href={href} kind=\"external\">\n {children}\n </QuietLink>\n )\n}\n\n/**\n * A workspace document referenced by a link's href rather than by its text.\n *\n * `rehypeDocEntityPills` turns a bare `doc-…` id into a pill, but it only walks\n * TEXT nodes — so `[NVDA DCF Valuation Report](…doc-abc12345…)`, which is how an\n * answer links an artifact it just saved, keeps the id in the href where the\n * plugin never looks. The link then fell through to `ExternalLink`, and opening\n * your own workspace document asked you to confirm an \"external link\" and\n * launched a new tab. It opens in the document viewer, like the pill and the\n * artifact card already do.\n */\nexport function InternalDocLink({\n docId,\n href,\n children,\n}: React.ComponentPropsWithoutRef<'a'> & { docId: string }) {\n const { openDocument } = useBlocksEnvironment()\n const workspaceId = useDocumentWorkspace()\n if (workspaceId) {\n return (\n <WorkspaceDocumentReference workspaceId={workspaceId} docId={docId}>\n {children}\n </WorkspaceDocumentReference>\n )\n }\n\n return (\n <QuietLink href={href} kind=\"document\" onOpen={() => openDocument(docId)}>\n {children}\n </QuietLink>\n )\n}\n\n/** A document of the workspace, as a pill: the host's chip, else the document entity. */\nexport function DocumentChip({ docId }: { docId: string }) {\n const render = useArbiHost().chat?.renderDocumentChip\n const workspaceId = useDocumentWorkspace()\n if (workspaceId) return <WorkspaceDocumentReference workspaceId={workspaceId} docId={docId} />\n return render ? <>{render(docId)}</> : <DefaultDocumentChip docId={docId} />\n}\n\nfunction DefaultDocumentChip({ docId }: { docId: string }) {\n const { data: doc } = useDocument(docId)\n const { openDocument } = useBlocksEnvironment()\n if (!doc)\n return (\n <EntityPill\n icon={<FileText className=\"w-3.5 h-3.5 flex-shrink-0\" />}\n label={docId}\n size=\"sm\"\n onClick={() => openDocument(docId)}\n data-testid=\"doc-entity-pill\"\n />\n )\n return (\n <DocumentEntity doc={doc} onClick={() => openDocument(docId)} data-testid=\"doc-entity-pill\" />\n )\n}\n\n/** An email of the person's mailbox, as a pill: the host's chip, else a plain \"Email\". */\nexport function MailChip({ mailId }: { mailId: string }) {\n const render = useArbiHost().chat?.renderMailChip\n if (render) return <>{render(mailId)}</>\n return (\n <EntityPill\n icon={<Mail className=\"w-3.5 h-3.5 flex-shrink-0\" />}\n label=\"Email\"\n size=\"sm\"\n data-testid=\"mail-entity-pill\"\n />\n )\n}\n\n/**\n * The conversation's overrides, layered on the kit's defaults. Module scope, so the reference is stable\n * and memoised markdown blocks do not re-parse.\n */\nconst conversationMarkdownComponents: Partial<Components> = {\n a: function ConversationMarkdownLink({\n href,\n children,\n ...props\n }: React.ComponentPropsWithoutRef<'a'>) {\n const deploymentDomain = useBlocksEnvironment().runtimeConfig.deploymentDomain\n // @mentions: `linkMentions` turned them into `#mention-<id>` links; draw them as chips.\n const mention = mentionFromHref(href)\n if (mention) {\n return <MentionLink kind={mention.kind} id={mention.id} text={childrenText(children)} />\n }\n // Bookmarks: in-page anchors are near-invisible text; the menu jumps or copies the place.\n if (href?.startsWith('#') && !href.startsWith('#cite-')) {\n return (\n <QuietLink href={href} kind=\"anchor\">\n {children}\n </QuietLink>\n )\n }\n // Citations, `cite:` references and bare links: the kit's link.\n if (!href || href.startsWith('#') || href.startsWith('cite:')) {\n return (\n <MarkdownLink href={href} {...props}>\n {children}\n </MarkdownLink>\n )\n }\n // A workspace document is not an external link, wherever it is hosted: it opens in the viewer.\n const docId = workspaceDocIdFromHref(href, deploymentDomain)\n if (docId) {\n return (\n <InternalDocLink docId={docId} href={href} {...props}>\n {children}\n </InternalDocLink>\n )\n }\n return (\n <ExternalLink href={href} {...props}>\n {children}\n </ExternalLink>\n )\n },\n code: function ConversationMarkdownCode(\n props: React.ComponentPropsWithoutRef<'code'> & { inline?: boolean }\n ) {\n const isStreaming = useContext(MarkdownStreamingContext)\n const { className, children } = props\n const language = /language-(\\w+)/.exec(className || '')?.[1]\n if (!language) {\n // Answers often backtick a bare doc id (`doc-f7b3eeb5`). The text-node pass skips code, so\n // the id would stay monospace text; show it as the document pill. Only a whole id (eight\n // alphanumerics): while streaming, a partial one (\"doc-e\") would be looked up and 404.\n const codeText = typeof children === 'string' ? children.trim() : ''\n if (/^doc-[a-zA-Z0-9]{8}$/.test(codeText)) return <DocumentChip docId={codeText} />\n if (/^eml-[a-zA-Z0-9]{8}$/.test(codeText)) return <MailChip mailId={codeText} />\n }\n // Mermaid lazy-loads its own bundle and re-renders SVG on every change. While streaming the\n // fence is almost always partial, so it stays a code block until generation completes.\n if (language === 'mermaid' && !isStreaming) {\n return <MermaidDiagram chart={String(children).replace(/\\n$/, '')} />\n }\n return <MarkdownCode {...props} />\n },\n span: ({ children, className, ...props }: React.ComponentPropsWithoutRef<'span'>) => {\n const docId = (props as Record<string, unknown>)['data-doc-id'] as string | undefined\n if (docId) return <DocumentChip docId={docId} />\n const mailId = (props as Record<string, unknown>)['data-mail-id'] as string | undefined\n if (mailId) return <MailChip mailId={mailId} />\n return (\n <span className={className} {...props}>\n {children}\n </span>\n )\n },\n}\n\n/** Bare `doc-…` / `eml-…` ids in text become `<span data-doc-id>` / `<span data-mail-id>` pills. */\nconst conversationRehypePlugins = [rehypeDocEntityPills]\n\nexport type ConnectedMarkdownProps = Omit<KitMarkdownRendererProps, 'rehypePlugins'>\n\n/**\n * The kit's renderer with the conversation's overrides; a caller's `components` (e.g. the citation\n * core's) still win over both.\n */\nfunction ConnectedMarkdownComponent({ components, ...props }: ConnectedMarkdownProps) {\n const merged = useMemo(\n () =>\n components\n ? { ...conversationMarkdownComponents, ...components }\n : conversationMarkdownComponents,\n [components]\n )\n return (\n <KitMarkdownRenderer {...props} components={merged} rehypePlugins={conversationRehypePlugins} />\n )\n}\n\nexport const ConnectedMarkdown = React.memo(ConnectedMarkdownComponent)\n","/**\n * The PDF document tools (markup, Freeze, signing, signature requests, productions) on the\n * signed-in session, for any host: the API client, the signed-in user, the host's notices and\n * document opening (`BlocksEnvironment`), and the shared caches a change refreshes. A host with its\n * own binding (its own lists to refresh, an XHR upload with progress, Mail) gives it as the host\n * configuration's `documentTools`, field by field. An enclosing `DocumentToolsProvider` (a dialog\n * with its own client) wins.\n */\n\nimport { useCallback, useMemo, type ReactNode } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { arbiQueryKeys, refreshDocuments, useArbi } from '@arbidocs/react'\nimport {\n DocumentToolsProvider,\n clientUpload,\n documentBytesKey,\n useOptionalDocumentTools,\n type DocumentChange,\n type DocumentToolsClient,\n type DocumentToolsEnvironment,\n type DocumentToolsNotify,\n type DocumentUploadRequest,\n} from '@arbidocs/react/document-tools'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useHost } from '../../provider/host'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\n\n/** What a host binds of the document tools itself; each absent field is the kit's own. */\nexport interface DocumentToolsHost {\n /** The API client the tools call. Default: the host `arbi`'s. */\n client?: DocumentToolsClient\n /** The deployment domain keys are derived for (signing). Default: the host `arbi`'s. */\n deploymentDomain?: string\n /** Open a document or a version the tools made. Default: the environment's `openDocument`. */\n openDocument?: (documentRef: string) => void\n /** Refresh the host's lists after a change. Default: the shared document caches. */\n onDocumentsChanged?: DocumentToolsEnvironment['onDocumentsChanged']\n /** Upload a derived copy. Default: through the API client, into the open workspace. */\n uploadDocument?: DocumentToolsEnvironment['uploadDocument']\n /**\n * Where \"View certificate\" goes for a signature `reference` (e.g. the site's own verify page).\n * Default: the certificate link the API returns (on the deployment domain).\n */\n certificateUrl?: (reference: string) => string\n /** Email a document (a hook): absent, or returning nothing, when mail is not offered. */\n useEmailDocument?: () => ((documentRef: string) => void) | undefined\n}\n\nconst NO_EMAIL = () => undefined\n\nexport function ConnectedDocumentToolsProvider({ children }: { children: ReactNode }) {\n const enclosing = useOptionalDocumentTools()\n return enclosing ? <>{children}</> : <OwnDocumentTools>{children}</OwnDocumentTools>\n}\n\nfunction OwnDocumentTools({ children }: { children: ReactNode }) {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const host = useHost().documentTools\n const { user, ensureWorkspaceOpen } = useConnectedWorkspace()\n const { notify: environmentNotify, openDocument: openInHost } = useBlocksEnvironment()\n const useEmailDocument = host?.useEmailDocument ?? NO_EMAIL\n const emailDocument = useEmailDocument()\n const client = host?.client ?? (arbi.isLoggedIn ? arbi.getClient().fetch : null)\n const signer = useMemo(\n () => (user ? { name: user.name, email: user.email, externalId: user.externalId } : null),\n [user]\n )\n const notify = useCallback<DocumentToolsNotify>(\n (message, kind, options) =>\n environmentNotify(message, kind, {\n description: options?.description,\n action: options?.action,\n }),\n [environmentNotify]\n )\n const ownDocumentsChanged = useCallback(\n async (ids: string[], change: DocumentChange) => {\n // The list carries each version's markup count and the copies; a signature or a saved\n // version is a new current version, with new versions and a new rendered PDF.\n const refresh: Promise<unknown>[] = [refreshDocuments(queryClient, arbi, ids)]\n if (change === 'signed' || change === 'version')\n for (const id of ids)\n refresh.push(\n queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentVersions(id) }),\n queryClient.invalidateQueries({ queryKey: documentBytesKey(id) })\n )\n await Promise.all(refresh)\n },\n [queryClient, arbi]\n )\n // The server files an upload in the session's open workspace: re-assert it first.\n const ownUpload = useCallback(\n async (request: DocumentUploadRequest) => {\n if (!client) throw new Error('Sign in to save a copy.')\n await ensureWorkspaceOpen()\n return clientUpload(client)(request)\n },\n [client, ensureWorkspaceOpen]\n )\n const ownOpenDocument = useCallback((ref: string) => openInHost(ref), [openInHost])\n if (!client) return <>{children}</>\n return (\n <DocumentToolsProvider\n client={client}\n deploymentDomain={host?.deploymentDomain}\n user={signer}\n notify={notify}\n openDocument={host?.openDocument ?? ownOpenDocument}\n onDocumentsChanged={host?.onDocumentsChanged ?? ownDocumentsChanged}\n uploadDocument={host?.uploadDocument ?? ownUpload}\n emailDocument={emailDocument}\n certificateUrl={host?.certificateUrl}\n >\n {children}\n </DocumentToolsProvider>\n )\n}\n","/**\n * What a host adds to the connected document viewer. The viewer reads documents, versions, PDFs,\n * markup and signatures on the signed-in session by itself; these are the host's own things it\n * cannot know: documents the host makes on the client (an artifact streaming in from a chat, an\n * unsaved draft), the host's dialogs and workflows a document action opens, and how the host lays\n * the viewer out. It is the host configuration's `viewer`. Every field is optional: without one the\n * viewer offers less (no Translate button, no draft controls), never something that does nothing.\n * What changes while the viewer is open is read through hooks (`use…`).\n */\n\nimport type { ReactNode } from 'react'\nimport type { components } from '@arbidocs/client'\nimport { useHost } from '../../provider/host'\n\n/** A document's record, as the viewer reads it. */\nexport type ViewerDocumentRecord = components['schemas']['DocResponse']\n\n/** An artifact being generated in a chat, shown in the viewer as it streams. */\nexport interface ViewerStreamingDocument {\n title?: string | null\n /** The content so far (Markdown, or the html/react source of a live artifact). */\n content: string\n /** How it is carried: a document draft, a live `html` / `react` artifact, an `image`. */\n mode?: string | null\n isComplete: boolean\n}\n\n/** A document the user started on the client, with no backend record until it is saved. */\nexport interface ViewerDraftDocument {\n kind: 'text' | 'audio' | 'photo' | 'video'\n title?: string | null\n /** A text draft's starting content. */\n content?: string | null\n}\n\nexport interface DocumentViewerSupport {\n /** The artifact streaming in as this document, if one is (a hook). */\n useStreamingDocument?: (documentId: string) => ViewerStreamingDocument | undefined\n /** The unsaved draft with this client id, if there is one (a hook). */\n useDraftDocument?: (draftId: string) => ViewerDraftDocument | undefined\n /** A draft's kind (text, photo, audio, video), in place of the tabs. */\n renderDraftKind?: (draftId: string) => ReactNode\n /** A draft's name (editable), in place of the title. */\n renderDraftTitle?: (draftId: string) => ReactNode\n /** The recorder of a photo, audio or video draft: the whole body of the viewer. */\n renderCaptureDraft?: (draftId: string) => ReactNode\n /** A text draft was saved as `documentId`; the viewer shows it next. */\n onDraftSaved?: (draftId: string, documentId: string) => void\n /** The copy of a document kept on this device, for when the network is down. */\n loadOfflineCopy?: (document: ViewerDocumentRecord) => Promise<Blob | undefined>\n /** Documents related to the one open (near duplicates), beside its name. */\n renderRelated?: (document: ViewerDocumentRecord) => ReactNode\n /** A document as a pill (the comparison's other side). Default: its name. */\n renderDocumentPill?: (documentId: string) => ReactNode\n /** Open the host's share dialog for the document. Default: share it with the workspace. */\n share?: (document: { id: string; name: string | undefined; isPrivate: boolean }) => void\n /** Ask the assistant about a version (`doc-…@v2`) open read-only. Absent: not offered. */\n askAboutVersion?: (versionRef: string) => void\n /** Translate the document (or the version) on screen. Absent: not offered. */\n translate?: (documentRef: string) => void\n /** Start an image generation from the image on screen. Absent: not offered. */\n useImageAsReference?: (documentId: string) => void\n /**\n * A citation being edited elsewhere (a fact's sources, a field's) picks its passages in the text\n * view: clicks and selections there are handed to it (a hook). Absent: passages are not pickable.\n */\n usePassageCitation?: () => PassageCitation | undefined\n /** Open the document's passages in the host's navigator (a passage's menu). Absent: not offered. */\n openInNavigator?: (documentId: string) => void\n /** Start a new label or field in the host's editor (the passage tagging panel). Absent: not offered. */\n createTag?: () => void\n /** How dates read (versions, signatures). Default: `fmtDate`. */\n formatDate?: (iso: string) => string\n /** Whether the viewer is shown in another window, where PDF pages render without the page's web\n * fonts (a hook). */\n useIsDetached?: () => boolean\n}\n\n/** A passage picked for a citation: its chunk and, when known, its page. */\nexport interface PickedPassage {\n chunk_id: string\n page?: number\n}\n\n/** The citation a host is editing, as the text view sees it. */\nexport interface PassageCitation {\n /** The citation picking passages now, and the document it picks in; null when none is. */\n active: { documentId: string; key: string | null } | null\n /** Passages to light (a fact's cited passages while its sources are open). */\n highlighted: readonly string[]\n /** Passages added to the citation. */\n pick: (passages: PickedPassage[]) => void\n /** Passages taken off it. */\n unpick: (chunkIds: string[]) => void\n}\n\nconst NO_SUPPORT: DocumentViewerSupport = {}\n\nexport function useDocumentViewerSupport(): DocumentViewerSupport {\n return useHost().viewer ?? NO_SUPPORT\n}\n\nconst NONE = () => undefined\nconst ATTACHED = () => false\n\n/** The artifact streaming in as this document (none without the host's). */\nexport function useViewerStreamingDocument(\n documentId: string\n): ViewerStreamingDocument | undefined {\n const useStreaming = useDocumentViewerSupport().useStreamingDocument ?? NONE\n return useStreaming(documentId)\n}\n\n/** The unsaved draft with this id (none without the host's). */\nexport function useViewerDraftDocument(draftId: string): ViewerDraftDocument | undefined {\n const useDraft = useDocumentViewerSupport().useDraftDocument ?? NONE\n return useDraft(draftId)\n}\n\n/** The citation picking passages (none without the host's). */\nexport function useViewerPassageCitation(): PassageCitation | undefined {\n const useCitation = useDocumentViewerSupport().usePassageCitation ?? NONE\n return useCitation()\n}\n\n/** Whether the viewer is in another window (never without the host's). */\nexport function useViewerIsDetached(): boolean {\n const useDetached = useDocumentViewerSupport().useIsDetached ?? ATTACHED\n return useDetached()\n}\n"]}
1
+ {"version":3,"sources":["../src/chat/mermaid-normalize.ts","../src/connection/conversation/MermaidDiagram.tsx","../src/connection/conversation/DocumentWorkspaceContext.tsx","../src/connection/conversation/ConnectedMarkdown.tsx","../src/connection/viewer/ConnectedDocumentToolsProvider.tsx","../src/connection/viewer/support.ts"],"names":["useState","useId","useEffect","jsxs","jsx","createContext","useContext","useBlocksEnvironment","React","useArbiSession","MentionChip","QuietLink","useArbiHost","Fragment","useDocument","EntityPill","FileText","DocumentEntity","Mail","mentionFromHref","MarkdownLink","workspaceDocIdFromHref","MarkdownStreamingContext","MarkdownCode","rehypeDocEntityPills","useMemo","KitMarkdownRenderer","useOptionalDocumentTools","useArbi","useQueryClient","useHost","useConnectedWorkspace","useCallback","refreshDocuments","arbiQueryKeys","documentBytesKey","clientUpload","DocumentToolsProvider"],"mappings":"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","file":"chunk-6MHGFCIW.cjs","sourcesContent":["/**\n * Defensive normalizer for single-line `graph` / `flowchart` Mermaid source.\n *\n * Some LLMs emit the entire diagram on one line. Mermaid's parser splits\n * statements on newlines, so a single-line graph fails outright. This helper\n * inserts newlines on safe statement boundaries so the diagram has a chance\n * of parsing. Only attempts normalization when:\n * 1. The source has no embedded newlines (i.e. is genuinely single-line), and\n * 2. The first directive is `graph` or `flowchart`.\n *\n * Other diagram types (sequenceDiagram, classDiagram, gantt, …) have very\n * different syntaxes — applying these heuristics to them would corrupt valid\n * input, so they're left untouched.\n *\n * Boundaries we split on:\n * - After the diagram-type header (`graph TD`, `flowchart LR`, …).\n * - Before each `style` / `classDef` / `class` / `linkStyle` / `click`\n * / `subgraph` keyword.\n * - Before/after `end` (closes a subgraph block).\n * - After a `]` (label close) that's followed by another node identifier\n * starting a new edge or node declaration.\n */\nexport function normalizeMermaidGraph(source: string): string {\n // Already multi-line — assume it's well-formed; don't touch it.\n if (/\\n/.test(source)) return source\n\n const headerMatch = source.match(/^\\s*(graph|flowchart)\\s+\\w+\\s+/)\n if (!headerMatch) return source\n\n const header = headerMatch[0].trimEnd()\n let body = source.slice(headerMatch[0].length)\n\n // Insert newline before keywords that always start a new statement.\n body = body.replace(/\\s+(style|classDef|class|linkStyle|click|subgraph)\\s/g, '\\n$1 ')\n\n // `end` closes a subgraph: put it on its own line, with a break after it\n // too so any trailing statements don't stay attached.\n body = body.replace(/\\s+end\\b\\s*/g, '\\nend\\n')\n\n // After a label close (`]`), if the next token looks like a Mermaid node id\n // followed by another `[` or `-->`, that's a new statement starting.\n body = body.replace(/\\]\\s+(?=[A-Za-z_][\\w-]*\\s*(?:\\[|-->))/g, ']\\n')\n\n // Collapse any accidental runs of blank lines we may have produced.\n body = body.replace(/\\n{2,}/g, '\\n')\n\n return `${header}\\n${body.trimStart()}`\n}\n","/**\n * MermaidDiagram Component\n *\n * Renders a Mermaid diagram from source code.\n * Used inside MarkdownRenderer to handle ```mermaid code blocks.\n * Lazy-loads the mermaid library to avoid bloating the initial bundle.\n */\n\nimport { useState, useEffect, useId } from 'react'\nimport { normalizeMermaidGraph } from '../../chat/mermaid-normalize'\n\ninterface MermaidDiagramProps {\n /** Mermaid diagram source code */\n chart: string\n}\n\n// Lazy-load and initialize mermaid once\nlet mermaidInstance: typeof import('mermaid').default | null = null\nlet mermaidLoadPromise: Promise<typeof import('mermaid').default> | null = null\n\nasync function getMermaid() {\n if (mermaidInstance) return mermaidInstance\n if (!mermaidLoadPromise) {\n mermaidLoadPromise = import('mermaid').then((mod) => {\n const m = mod.default\n m.initialize({\n startOnLoad: false,\n theme: 'default',\n securityLevel: 'strict',\n flowchart: { useMaxWidth: true, curve: 'basis' },\n })\n mermaidInstance = m\n return m\n })\n }\n return mermaidLoadPromise\n}\n\nexport function MermaidDiagram({ chart }: MermaidDiagramProps) {\n const [svg, setSvg] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const uniqueId = useId().replace(/:/g, '-')\n\n useEffect(() => {\n let cancelled = false\n\n async function render() {\n const mermaid = await getMermaid()\n const diagramId = `mermaid${uniqueId}`\n\n // Validate with parse() before render(). In Mermaid v11 a render() with\n // bad source can return a \"Syntax error in text\" bomb SVG instead of\n // throwing — and it appends DOM side-effects of its own — so a try/catch\n // around render() doesn't reliably catch failures and the bomb leaks\n // into the page (especially under React StrictMode where effects run\n // twice). parse() throws cleanly with no DOM side-effects.\n //\n // Defensive rescue: some LLMs emit single-line `graph`/`flowchart`\n // source. If the original parse fails, try a normalized variant. The\n // normalizer is a no-op on already-multi-line source and on non-graph\n // diagram types, so this only helps the bad-source case and never\n // corrupts valid input.\n let validSource: string | null = null\n let firstErr: unknown\n try {\n await mermaid.parse(chart)\n validSource = chart\n } catch (err) {\n firstErr = err\n const normalized = normalizeMermaidGraph(chart)\n if (normalized !== chart) {\n try {\n await mermaid.parse(normalized)\n validSource = normalized\n } catch (retryErr) {\n console.warn('Mermaid normalized parse also failed', retryErr)\n }\n }\n }\n\n if (cancelled) return\n\n if (!validSource) {\n console.warn('Mermaid parse failed, showing source', firstErr)\n setError('Failed to render diagram')\n setSvg(null)\n return\n }\n\n try {\n const { svg: renderedSvg } = await mermaid.render(diagramId, validSource)\n if (!cancelled) {\n setSvg(renderedSvg)\n setError(null)\n }\n } catch (renderErr) {\n if (!cancelled) {\n console.warn('Mermaid render failed despite parse success', renderErr)\n setError('Failed to render diagram')\n setSvg(null)\n }\n }\n }\n\n render()\n return () => {\n cancelled = true\n }\n }, [chart, uniqueId])\n\n if (error) {\n // Fall back to showing the raw source in a code block\n return (\n <div className=\"code-block\" data-testid=\"mermaid-error\">\n <div className=\"text-sm text-muted-foreground mb-1\">{error}</div>\n <code className=\"language-mermaid\">{chart}</code>\n </div>\n )\n }\n\n if (!svg) {\n return (\n <div\n className=\"flex items-center justify-center py-8 text-muted-foreground text-sm\"\n data-testid=\"mermaid-loading\"\n >\n Rendering diagram...\n </div>\n )\n }\n\n return (\n <div\n className=\"mermaid-diagram my-4 overflow-x-auto rounded-md border border-border bg-background p-4\"\n data-testid=\"mermaid-diagram\"\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n )\n}\n","/**\n * The workspace a conversation's document references belong to, when it is not the open one: an\n * agent's direct-message thread runs in the agent's workspace, so the documents it names are there.\n * A reference then opens that workspace first (`openDocument(id, { workspaceId })`).\n */\n\nimport { createContext, useContext, type ReactNode } from 'react'\nimport { useBlocksEnvironment } from '../../provider/environment'\n\n/** The workspace of the documents referenced inside it (null: the open workspace). */\nexport const DocumentWorkspaceContext = createContext<string | null>(null)\nexport const useDocumentWorkspace = () => useContext(DocumentWorkspaceContext)\n\n/** A reference to a document of another workspace: opening it opens that workspace first. */\nexport function WorkspaceDocumentReference({\n workspaceId,\n docId,\n children,\n className = 'inline-flex rounded-full border px-2 py-0.5 text-xs hover:bg-muted',\n}: {\n workspaceId: string\n docId: string\n children?: ReactNode\n className?: string\n}) {\n const { openDocument } = useBlocksEnvironment()\n return (\n <button\n type=\"button\"\n className={className}\n onClick={() => openDocument(docId, { workspaceId })}\n >\n {children ?? docId}\n </button>\n )\n}\n","/**\n * The conversation's markdown: the kit's `MarkdownRenderer` (`@arbidocs/react`: sanitised HTML,\n * slugs, lazy KaTeX, streaming blocks, tables, code) with what a conversation adds: @mention chips,\n * workspace documents opening in the viewer, quiet external links, document and email pills (the\n * host's chips, `ArbiChatHost.renderDocumentChip` / `renderMailChip`) and Mermaid diagrams.\n */\nimport { useArbiHost, useArbiSession, useDocument } from '@arbidocs/react'\nimport { mentionFromHref, type MentionKind } from '@arbidocs/react/shell'\nimport {\n EntityPill,\n MarkdownCode,\n MarkdownLink,\n MarkdownRenderer as KitMarkdownRenderer,\n MarkdownStreamingContext,\n type MarkdownRendererProps as KitMarkdownRendererProps,\n DocumentEntity,\n} from '@arbidocs/react/ui'\nimport React, { useContext, useMemo } from 'react'\nimport { FileText, Mail } from 'lucide-react'\n\n/** The markdown element overrides, as the kit's renderer takes them. */\ntype Components = NonNullable<KitMarkdownRendererProps['components']>\nimport { MentionChip } from '../../chat/MentionMenu'\nimport { QuietLink } from '../../citations/QuietMarks'\nimport { rehypeDocEntityPills } from '../../chat/rehype-doc-entity-pills'\nimport { workspaceDocIdFromHref } from '../../chat/doc-links'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { MermaidDiagram } from './MermaidDiagram'\nimport { useDocumentWorkspace, WorkspaceDocumentReference } from './DocumentWorkspaceContext'\n\n/** Plain text of a link's children (the `@Label` of a mention link). */\nfunction childrenText(children: React.ReactNode): string {\n return React.Children.toArray(children)\n .map((child) => (typeof child === 'string' || typeof child === 'number' ? String(child) : ''))\n .join('')\n}\n\n/** A mention chip; a mention of the reader stands out. */\nfunction MentionLink({ kind, id, text }: { kind: MentionKind; id: string; text: string }) {\n const currentUserId = useArbiSession().user?.external_id\n return (\n <MentionChip\n kind={kind}\n id={id}\n label={text.replace(/^@/, '')}\n isSelf={kind === 'user' && id === currentUserId}\n />\n )\n}\n\n/**\n * A link to elsewhere, as quiet text. Its menu (Open link / Copy link) is the deliberate step\n * the old confirmation dialog used to be; nothing opens until the menu's primary row is chosen.\n */\nexport function ExternalLink({ href, children }: React.ComponentPropsWithoutRef<'a'>) {\n return (\n <QuietLink href={href} kind=\"external\">\n {children}\n </QuietLink>\n )\n}\n\n/**\n * A workspace document referenced by a link's href rather than by its text.\n *\n * `rehypeDocEntityPills` turns a bare `doc-…` id into a pill, but it only walks\n * TEXT nodes — so `[NVDA DCF Valuation Report](…doc-abc12345…)`, which is how an\n * answer links an artifact it just saved, keeps the id in the href where the\n * plugin never looks. The link then fell through to `ExternalLink`, and opening\n * your own workspace document asked you to confirm an \"external link\" and\n * launched a new tab. It opens in the document viewer, like the pill and the\n * artifact card already do.\n */\nexport function InternalDocLink({\n docId,\n href,\n children,\n}: React.ComponentPropsWithoutRef<'a'> & { docId: string }) {\n const { openDocument } = useBlocksEnvironment()\n const workspaceId = useDocumentWorkspace()\n if (workspaceId) {\n return (\n <WorkspaceDocumentReference workspaceId={workspaceId} docId={docId}>\n {children}\n </WorkspaceDocumentReference>\n )\n }\n\n return (\n <QuietLink href={href} kind=\"document\" onOpen={() => openDocument(docId)}>\n {children}\n </QuietLink>\n )\n}\n\n/** A document of the workspace, as a pill: the host's chip, else the document entity. */\nexport function DocumentChip({ docId }: { docId: string }) {\n const render = useArbiHost().chat?.renderDocumentChip\n const workspaceId = useDocumentWorkspace()\n if (workspaceId) return <WorkspaceDocumentReference workspaceId={workspaceId} docId={docId} />\n return render ? <>{render(docId)}</> : <DefaultDocumentChip docId={docId} />\n}\n\nfunction DefaultDocumentChip({ docId }: { docId: string }) {\n const { data: doc } = useDocument(docId)\n const { openDocument } = useBlocksEnvironment()\n if (!doc)\n return (\n <EntityPill\n icon={<FileText className=\"w-3.5 h-3.5 flex-shrink-0\" />}\n label={docId}\n size=\"sm\"\n onClick={() => openDocument(docId)}\n data-testid=\"doc-entity-pill\"\n />\n )\n return (\n <DocumentEntity doc={doc} onClick={() => openDocument(docId)} data-testid=\"doc-entity-pill\" />\n )\n}\n\n/** An email of the person's mailbox, as a pill: the host's chip, else a plain \"Email\". */\nexport function MailChip({ mailId }: { mailId: string }) {\n const render = useArbiHost().chat?.renderMailChip\n if (render) return <>{render(mailId)}</>\n return (\n <EntityPill\n icon={<Mail className=\"w-3.5 h-3.5 flex-shrink-0\" />}\n label=\"Email\"\n size=\"sm\"\n data-testid=\"mail-entity-pill\"\n />\n )\n}\n\n/**\n * The conversation's overrides, layered on the kit's defaults. Module scope, so the reference is stable\n * and memoised markdown blocks do not re-parse.\n */\nconst conversationMarkdownComponents: Partial<Components> = {\n a: function ConversationMarkdownLink({\n href,\n children,\n ...props\n }: React.ComponentPropsWithoutRef<'a'>) {\n const deploymentDomain = useBlocksEnvironment().runtimeConfig.deploymentDomain\n // @mentions: `linkMentions` turned them into `#mention-<id>` links; draw them as chips.\n const mention = mentionFromHref(href)\n if (mention) {\n return <MentionLink kind={mention.kind} id={mention.id} text={childrenText(children)} />\n }\n // Bookmarks: in-page anchors are near-invisible text; the menu jumps or copies the place.\n if (href?.startsWith('#') && !href.startsWith('#cite-')) {\n return (\n <QuietLink href={href} kind=\"anchor\">\n {children}\n </QuietLink>\n )\n }\n // Citations, `cite:` references and bare links: the kit's link.\n if (!href || href.startsWith('#') || href.startsWith('cite:')) {\n return (\n <MarkdownLink href={href} {...props}>\n {children}\n </MarkdownLink>\n )\n }\n // A workspace document is not an external link, wherever it is hosted: it opens in the viewer.\n const docId = workspaceDocIdFromHref(href, deploymentDomain)\n if (docId) {\n return (\n <InternalDocLink docId={docId} href={href} {...props}>\n {children}\n </InternalDocLink>\n )\n }\n return (\n <ExternalLink href={href} {...props}>\n {children}\n </ExternalLink>\n )\n },\n code: function ConversationMarkdownCode(\n props: React.ComponentPropsWithoutRef<'code'> & { inline?: boolean }\n ) {\n const isStreaming = useContext(MarkdownStreamingContext)\n const { className, children } = props\n const language = /language-(\\w+)/.exec(className || '')?.[1]\n if (!language) {\n // Answers often backtick a bare doc id (`doc-f7b3eeb5`). The text-node pass skips code, so\n // the id would stay monospace text; show it as the document pill. Only a whole id (eight\n // alphanumerics): while streaming, a partial one (\"doc-e\") would be looked up and 404.\n const codeText = typeof children === 'string' ? children.trim() : ''\n if (/^doc-[a-zA-Z0-9]{8}$/.test(codeText)) return <DocumentChip docId={codeText} />\n if (/^eml-[a-zA-Z0-9]{8}$/.test(codeText)) return <MailChip mailId={codeText} />\n }\n // Mermaid lazy-loads its own bundle and re-renders SVG on every change. While streaming the\n // fence is almost always partial, so it stays a code block until generation completes.\n if (language === 'mermaid' && !isStreaming) {\n return <MermaidDiagram chart={String(children).replace(/\\n$/, '')} />\n }\n return <MarkdownCode {...props} />\n },\n span: ({ children, className, ...props }: React.ComponentPropsWithoutRef<'span'>) => {\n const docId = (props as Record<string, unknown>)['data-doc-id'] as string | undefined\n if (docId) return <DocumentChip docId={docId} />\n const mailId = (props as Record<string, unknown>)['data-mail-id'] as string | undefined\n if (mailId) return <MailChip mailId={mailId} />\n return (\n <span className={className} {...props}>\n {children}\n </span>\n )\n },\n}\n\n/** Bare `doc-…` / `eml-…` ids in text become `<span data-doc-id>` / `<span data-mail-id>` pills. */\nconst conversationRehypePlugins = [rehypeDocEntityPills]\n\nexport type ConnectedMarkdownProps = Omit<KitMarkdownRendererProps, 'rehypePlugins'>\n\n/**\n * The kit's renderer with the conversation's overrides; a caller's `components` (e.g. the citation\n * core's) still win over both.\n */\nfunction ConnectedMarkdownComponent({ components, ...props }: ConnectedMarkdownProps) {\n const merged = useMemo(\n () =>\n components\n ? { ...conversationMarkdownComponents, ...components }\n : conversationMarkdownComponents,\n [components]\n )\n return (\n <KitMarkdownRenderer {...props} components={merged} rehypePlugins={conversationRehypePlugins} />\n )\n}\n\nexport const ConnectedMarkdown = React.memo(ConnectedMarkdownComponent)\n","/**\n * The PDF document tools (markup, Freeze, signing, signature requests, productions) on the\n * signed-in session, for any host: the API client, the signed-in user, the host's notices and\n * document opening (`BlocksEnvironment`), and the shared caches a change refreshes. A host with its\n * own binding (its own lists to refresh, an XHR upload with progress, Mail) gives it as the host\n * configuration's `documentTools`, field by field. An enclosing `DocumentToolsProvider` (a dialog\n * with its own client) wins.\n */\n\nimport { useCallback, useMemo, type ReactNode } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { arbiQueryKeys, refreshDocuments, useArbi } from '@arbidocs/react'\nimport {\n DocumentToolsProvider,\n clientUpload,\n documentBytesKey,\n useOptionalDocumentTools,\n type DocumentChange,\n type DocumentToolsClient,\n type DocumentToolsEnvironment,\n type DocumentToolsNotify,\n type DocumentUploadRequest,\n} from '@arbidocs/react/document-tools'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useHost } from '../../provider/host'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\n\n/** What a host binds of the document tools itself; each absent field is the kit's own. */\nexport interface DocumentToolsHost {\n /** The API client the tools call. Default: the host `arbi`'s. */\n client?: DocumentToolsClient\n /** The deployment domain keys are derived for (signing). Default: the host `arbi`'s. */\n deploymentDomain?: string\n /** Open a document or a version the tools made. Default: the environment's `openDocument`. */\n openDocument?: (documentRef: string) => void\n /** Refresh the host's lists after a change. Default: the shared document caches. */\n onDocumentsChanged?: DocumentToolsEnvironment['onDocumentsChanged']\n /** Upload a derived copy. Default: through the API client, into the open workspace. */\n uploadDocument?: DocumentToolsEnvironment['uploadDocument']\n /**\n * Where \"View certificate\" goes for a signature `reference` (e.g. the site's own verify page).\n * Default: the certificate link the API returns (on the deployment domain).\n */\n certificateUrl?: (reference: string) => string\n /** Email a document (a hook): absent, or returning nothing, when mail is not offered. */\n useEmailDocument?: () => ((documentRef: string) => void) | undefined\n}\n\nconst NO_EMAIL = () => undefined\n\nexport function ConnectedDocumentToolsProvider({ children }: { children: ReactNode }) {\n const enclosing = useOptionalDocumentTools()\n return enclosing ? <>{children}</> : <OwnDocumentTools>{children}</OwnDocumentTools>\n}\n\nfunction OwnDocumentTools({ children }: { children: ReactNode }) {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const host = useHost().documentTools\n const { user, ensureWorkspaceOpen } = useConnectedWorkspace()\n const { notify: environmentNotify, openDocument: openInHost } = useBlocksEnvironment()\n const useEmailDocument = host?.useEmailDocument ?? NO_EMAIL\n const emailDocument = useEmailDocument()\n const client = host?.client ?? (arbi.isLoggedIn ? arbi.getClient().fetch : null)\n const signer = useMemo(\n () => (user ? { name: user.name, email: user.email, externalId: user.externalId } : null),\n [user]\n )\n const notify = useCallback<DocumentToolsNotify>(\n (message, kind, options) =>\n environmentNotify(message, kind, {\n description: options?.description,\n action: options?.action,\n }),\n [environmentNotify]\n )\n const ownDocumentsChanged = useCallback(\n async (ids: string[], change: DocumentChange) => {\n // The list carries each version's markup count and the copies; a signature or a saved\n // version is a new current version, with new versions and a new rendered PDF.\n const refresh: Promise<unknown>[] = [refreshDocuments(queryClient, arbi, ids)]\n if (change === 'signed' || change === 'version')\n for (const id of ids)\n refresh.push(\n queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentVersions(id) }),\n queryClient.invalidateQueries({ queryKey: documentBytesKey(id) })\n )\n await Promise.all(refresh)\n },\n [queryClient, arbi]\n )\n // The server files an upload in the session's open workspace: re-assert it first.\n const ownUpload = useCallback(\n async (request: DocumentUploadRequest) => {\n if (!client) throw new Error('Sign in to save a copy.')\n await ensureWorkspaceOpen()\n return clientUpload(client)(request)\n },\n [client, ensureWorkspaceOpen]\n )\n const ownOpenDocument = useCallback((ref: string) => openInHost(ref), [openInHost])\n if (!client) return <>{children}</>\n return (\n <DocumentToolsProvider\n client={client}\n deploymentDomain={host?.deploymentDomain}\n user={signer}\n notify={notify}\n openDocument={host?.openDocument ?? ownOpenDocument}\n onDocumentsChanged={host?.onDocumentsChanged ?? ownDocumentsChanged}\n uploadDocument={host?.uploadDocument ?? ownUpload}\n emailDocument={emailDocument}\n certificateUrl={host?.certificateUrl}\n >\n {children}\n </DocumentToolsProvider>\n )\n}\n","/**\n * What a host adds to the connected document viewer. The viewer reads documents, versions, PDFs,\n * markup and signatures on the signed-in session by itself; these are the host's own things it\n * cannot know: documents the host makes on the client (an artifact streaming in from a chat, an\n * unsaved draft), the host's dialogs and workflows a document action opens, and how the host lays\n * the viewer out. It is the host configuration's `viewer`. Every field is optional: without one the\n * viewer offers less (no Translate button, no draft controls), never something that does nothing.\n * What changes while the viewer is open is read through hooks (`use…`).\n */\n\nimport type { ReactNode } from 'react'\nimport type { components } from '@arbidocs/client'\nimport { useHost } from '../../provider/host'\n\n/** A document's record, as the viewer reads it. */\nexport type ViewerDocumentRecord = components['schemas']['DocResponse']\n\n/** An artifact being generated in a chat, shown in the viewer as it streams. */\nexport interface ViewerStreamingDocument {\n title?: string | null\n /** The content so far (Markdown, or the html/react source of a live artifact). */\n content: string\n /** How it is carried: a document draft, a live `html` / `react` artifact, an `image`. */\n mode?: string | null\n isComplete: boolean\n}\n\n/** A document the user started on the client, with no backend record until it is saved. */\nexport interface ViewerDraftDocument {\n kind: 'text' | 'audio' | 'photo' | 'video'\n title?: string | null\n /** A text draft's starting content. */\n content?: string | null\n}\n\nexport interface DocumentViewerSupport {\n /** The artifact streaming in as this document, if one is (a hook). */\n useStreamingDocument?: (documentId: string) => ViewerStreamingDocument | undefined\n /** The unsaved draft with this client id, if there is one (a hook). */\n useDraftDocument?: (draftId: string) => ViewerDraftDocument | undefined\n /** A draft's kind (text, photo, audio, video), in place of the tabs. */\n renderDraftKind?: (draftId: string) => ReactNode\n /** A draft's name (editable), in place of the title. */\n renderDraftTitle?: (draftId: string) => ReactNode\n /** The recorder of a photo, audio or video draft: the whole body of the viewer. */\n renderCaptureDraft?: (draftId: string) => ReactNode\n /** A text draft was saved as `documentId`; the viewer shows it next. */\n onDraftSaved?: (draftId: string, documentId: string) => void\n /** The copy of a document kept on this device, for when the network is down. */\n loadOfflineCopy?: (document: ViewerDocumentRecord) => Promise<Blob | undefined>\n /** Documents related to the one open (near duplicates), beside its name. */\n renderRelated?: (document: ViewerDocumentRecord) => ReactNode\n /** A document as a pill (the comparison's other side). Default: its name. */\n renderDocumentPill?: (documentId: string) => ReactNode\n /** Open the host's share dialog for the document. Default: share it with the workspace. */\n share?: (document: { id: string; name: string | undefined; isPrivate: boolean }) => void\n /** Ask the assistant about a version (`doc-…@v2`) open read-only. Absent: not offered. */\n askAboutVersion?: (versionRef: string) => void\n /** Translate the document (or the version) on screen. Absent: not offered. */\n translate?: (documentRef: string) => void\n /** Start an image generation from the image on screen. Absent: not offered. */\n useImageAsReference?: (documentId: string) => void\n /**\n * A citation being edited elsewhere (a fact's sources, a field's) picks its passages in the text\n * view: clicks and selections there are handed to it (a hook). Absent: passages are not pickable.\n */\n usePassageCitation?: () => PassageCitation | undefined\n /** Open the document's passages in the host's navigator (a passage's menu). Absent: not offered. */\n openInNavigator?: (documentId: string) => void\n /** Start a new label or field in the host's editor (the passage tagging panel). Absent: not offered. */\n createTag?: () => void\n /** How dates read (versions, signatures). Default: `fmtDate`. */\n formatDate?: (iso: string) => string\n /** Whether the viewer is shown in another window, where PDF pages render without the page's web\n * fonts (a hook). */\n useIsDetached?: () => boolean\n}\n\n/** A passage picked for a citation: its chunk and, when known, its page. */\nexport interface PickedPassage {\n chunk_id: string\n page?: number\n}\n\n/** The citation a host is editing, as the text view sees it. */\nexport interface PassageCitation {\n /** The citation picking passages now, and the document it picks in; null when none is. */\n active: { documentId: string; key: string | null } | null\n /** Passages to light (a fact's cited passages while its sources are open). */\n highlighted: readonly string[]\n /** Passages added to the citation. */\n pick: (passages: PickedPassage[]) => void\n /** Passages taken off it. */\n unpick: (chunkIds: string[]) => void\n}\n\nconst NO_SUPPORT: DocumentViewerSupport = {}\n\nexport function useDocumentViewerSupport(): DocumentViewerSupport {\n return useHost().viewer ?? NO_SUPPORT\n}\n\nconst NONE = () => undefined\nconst ATTACHED = () => false\n\n/** The artifact streaming in as this document (none without the host's). */\nexport function useViewerStreamingDocument(\n documentId: string\n): ViewerStreamingDocument | undefined {\n const useStreaming = useDocumentViewerSupport().useStreamingDocument ?? NONE\n return useStreaming(documentId)\n}\n\n/** The unsaved draft with this id (none without the host's). */\nexport function useViewerDraftDocument(draftId: string): ViewerDraftDocument | undefined {\n const useDraft = useDocumentViewerSupport().useDraftDocument ?? NONE\n return useDraft(draftId)\n}\n\n/** The citation picking passages (none without the host's). */\nexport function useViewerPassageCitation(): PassageCitation | undefined {\n const useCitation = useDocumentViewerSupport().usePassageCitation ?? NONE\n return useCitation()\n}\n\n/** Whether the viewer is in another window (never without the host's). */\nexport function useViewerIsDetached(): boolean {\n const useDetached = useDocumentViewerSupport().useIsDetached ?? ATTACHED\n return useDetached()\n}\n"]}
@@ -32,13 +32,13 @@ function watchGridTestIds(root, getItemsById, options) {
32
32
  }
33
33
  var cssVar = (name, alpha) => alpha === void 0 ? `hsl(var(--${name}))` : `hsl(var(--${name}) / ${alpha})`;
34
34
  var arbiTheme = themeQuartz.withParams({
35
- // Variant B palette: white canvas, quiet header, muted hover nudge, accent-tint selection.
35
+ // Match TagTable: a plain canvas, muted header, fine row borders and a rounded frame.
36
36
  // Every colour is a host CSS variable, so light/dark follow the app with no .dark overrides.
37
37
  backgroundColor: cssVar("background"),
38
38
  foregroundColor: cssVar("foreground"),
39
39
  borderColor: cssVar("border"),
40
- headerBackgroundColor: cssVar("background"),
41
- headerTextColor: cssVar("muted-foreground"),
40
+ headerBackgroundColor: cssVar("muted", 0.4),
41
+ headerTextColor: cssVar("foreground"),
42
42
  oddRowBackgroundColor: cssVar("background"),
43
43
  rowHoverColor: cssVar("muted", 0.6),
44
44
  // Checkbox-selected rows: a light accent tint. A row opened elsewhere (e.g. the viewer) may take
@@ -48,9 +48,8 @@ var arbiTheme = themeQuartz.withParams({
48
48
  accentColor: cssVar("primary"),
49
49
  inputFocusBorder: { color: cssVar("primary") },
50
50
  headerColumnBorder: false,
51
- // A faint short tick marks every column edge (so resizing is discoverable without a full
52
- // divider line); it strengthens while the header is hovered (see grid.css).
53
- headerColumnResizeHandleColor: cssVar("border"),
51
+ // Keep the header as quiet as TagTable; reveal resize handles on hover (see grid.css).
52
+ headerColumnResizeHandleColor: "transparent",
54
53
  headerColumnResizeHandleHeight: "40%",
55
54
  headerColumnResizeHandleWidth: 1,
56
55
  // Font settings — inherit the host app's font. A googleFont here never
@@ -58,12 +57,12 @@ var arbiTheme = themeQuartz.withParams({
58
57
  // browser's default SERIF and read as unstyled.
59
58
  fontFamily: "inherit",
60
59
  fontSize: 14,
61
- headerFontSize: 12.5,
60
+ headerFontSize: 14,
62
61
  headerFontWeight: 500,
63
62
  // Sizing
64
- headerHeight: 44,
63
+ headerHeight: 37,
65
64
  rowHeight: 40,
66
- cellHorizontalPadding: 16,
65
+ cellHorizontalPadding: 12,
67
66
  // Borders - structural settings only.
68
67
  // Row border is a real hairline in the theme border colour (not hardcoded
69
68
  // white, which was invisible on the light-mode background and wrong in dark
@@ -72,10 +71,10 @@ var arbiTheme = themeQuartz.withParams({
72
71
  rowBorder: { style: "solid", width: 1, color: "hsl(var(--border))" },
73
72
  columnBorder: false,
74
73
  // Row hairlines only
75
- wrapperBorder: false,
76
- // No rounded corners for clean look (except checkboxes)
77
- borderRadius: 0,
78
- wrapperBorderRadius: 0,
74
+ wrapperBorder: { style: "solid", width: 1, color: cssVar("border") },
75
+ // Use the same radius token as TagTable's rounded-lg container.
76
+ borderRadius: "var(--radius-lg, 8px)",
77
+ wrapperBorderRadius: "var(--radius-lg, 8px)",
79
78
  checkboxBorderRadius: 2
80
79
  // Keep checkboxes square
81
80
  });
@@ -429,9 +428,8 @@ function GridView({
429
428
  }, [rowHeight]);
430
429
  const containerClassName = useMemo(() => {
431
430
  const baseClass = className || "";
432
- const shadowClass = "shadow-sm";
433
431
  const alignClass = rowHeight ? "ag-cells-centered" : "";
434
- return [baseClass, shadowClass, alignClass].filter(Boolean).join(" ");
432
+ return [baseClass, alignClass].filter(Boolean).join(" ");
435
433
  }, [className, rowHeight]);
436
434
  if (isLoading) {
437
435
  const skeletonRowCount = 12;
@@ -439,12 +437,12 @@ function GridView({
439
437
  "div",
440
438
  {
441
439
  "data-testid": `${testId}-loading`,
442
- className: containerClassName,
440
+ className: `${containerClassName} overflow-hidden rounded-lg border border-border`,
443
441
  style: containerStyle,
444
442
  "aria-busy": "true",
445
443
  "aria-label": loadingMessage,
446
444
  children: [
447
- /* @__PURE__ */ jsxs("div", { className: "flex h-11 items-center gap-4 border-b border-border/40 px-4", children: [
445
+ /* @__PURE__ */ jsxs("div", { className: "flex h-[37px] items-center gap-4 border-b border-border bg-muted/40 px-3", children: [
448
446
  /* @__PURE__ */ jsx("div", { className: "h-3 w-6 rounded bg-muted animate-pulse" }),
449
447
  /* @__PURE__ */ jsx("div", { className: "h-3 w-32 rounded bg-muted animate-pulse" }),
450
448
  /* @__PURE__ */ jsx("div", { className: "h-3 w-24 rounded bg-muted animate-pulse" }),
@@ -452,7 +450,7 @@ function GridView({
452
450
  /* @__PURE__ */ jsx("div", { className: "h-3 w-28 rounded bg-muted animate-pulse" }),
453
451
  /* @__PURE__ */ jsx("div", { className: "h-3 w-16 rounded bg-muted animate-pulse ml-auto" })
454
452
  ] }),
455
- Array.from({ length: skeletonRowCount }).map((_, rowIdx) => /* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center gap-4 border-b border-border/20 px-4", children: [
453
+ Array.from({ length: skeletonRowCount }).map((_, rowIdx) => /* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center gap-4 border-b border-border px-3", children: [
456
454
  /* @__PURE__ */ jsx("div", { className: "h-4 w-4 rounded-sm bg-muted/70 animate-pulse" }),
457
455
  /* @__PURE__ */ jsx(
458
456
  "div",
@@ -536,5 +534,5 @@ function GridView({
536
534
  }
537
535
 
538
536
  export { GridView };
539
- //# sourceMappingURL=chunk-N5YEF3LC.js.map
540
- //# sourceMappingURL=chunk-N5YEF3LC.js.map
537
+ //# sourceMappingURL=chunk-7F5Z4K5W.js.map
538
+ //# sourceMappingURL=chunk-7F5Z4K5W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/files/grid-test-ids.ts","../src/files/GridView.tsx"],"names":[],"mappings":"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","file":"chunk-7F5Z4K5W.js","sourcesContent":["/**\n * Test-id hooks for AG Grid, which owns its row and cell DOM. AG Grid stamps every row with a\n * `row-id` attribute and every cell with `col-id`; these helpers turn them into `data-testid`s\n * a host chooses, so a custom UI keeps its own test-id scheme.\n */\n\nexport interface GridTestIdOptions<T> {\n /** Test id of the row for `item` (set on the centre-column row element). */\n getRowTestId?: (item: T) => string\n /** Test id of the cell in column `colId` of `item`. */\n getCellTestId?: (colId: string, item: T) => string\n}\n\n/** Stamp `data-testid`s onto the rows and cells under `root`. Idempotent. */\nexport function applyGridTestIds<T>(\n root: ParentNode,\n itemsById: Map<string, T>,\n { getRowTestId, getCellTestId }: GridTestIdOptions<T>\n): void {\n if (!getRowTestId && !getCellTestId) return\n root.querySelectorAll<HTMLElement>('.ag-center-cols-container .ag-row[row-id]').forEach((row) => {\n const item = itemsById.get(row.getAttribute('row-id') ?? '')\n if (item === undefined) return\n if (getRowTestId) row.setAttribute('data-testid', getRowTestId(item))\n if (getCellTestId) {\n row.querySelectorAll<HTMLElement>('.ag-cell[col-id]').forEach((cell) => {\n cell.setAttribute('data-testid', getCellTestId(cell.getAttribute('col-id') ?? '', item))\n })\n }\n })\n}\n\n/**\n * Keep the ids applied as AG Grid creates and recycles rows (it virtualises). Returns the\n * disconnect function.\n */\nexport function watchGridTestIds<T>(\n root: HTMLElement,\n getItemsById: () => Map<string, T>,\n options: GridTestIdOptions<T>\n): () => void {\n if (!options.getRowTestId && !options.getCellTestId) return () => {}\n const run = () => applyGridTestIds(root, getItemsById(), options)\n run()\n if (typeof MutationObserver === 'undefined') return () => {}\n const observer = new MutationObserver(run)\n observer.observe(root, { childList: true, subtree: true })\n return () => observer.disconnect()\n}\n","/**\n * GridView — a flexible AG Grid presentational core.\n *\n * Pure and app-agnostic: it owns no global state and pulls in no store. Column\n * state persistence (order / width / visibility / sort / filter) is exposed as a\n * controlled/uncontrolled prop pair — `gridState` (initial state, read once at\n * mount) and `onGridStateChange` (called whenever AG Grid's state changes). An\n * app wires those to wherever it keeps the state (Zustand, localStorage, a URL,\n * a server) via a thin adapter; the core stays decoupled.\n *\n * Themed here (colours/fonts/borders via the host CSS variables, so it inherits the host's\n * light/dark theme). The structural helper classes (cell-numeric, multiline clamp, scrollbars,\n * row kebabs) live in `@arbidocs/blocks/grid.css`, which the consuming app imports globally.\n */\n\nimport React, { useRef, useCallback, useMemo, useEffect } from 'react'\nimport { AgGridReact } from 'ag-grid-react'\nimport {\n ColDef,\n GridOptions,\n GridApi,\n IRowNode,\n GridState,\n themeQuartz,\n CellValueChangedEvent,\n GridReadyEvent,\n RowClickedEvent,\n} from 'ag-grid-community'\nimport { AllCommunityModule } from 'ag-grid-community'\nimport { BREAKPOINT_QUERIES, useMediaQuery } from '../lib/use-media-query'\nimport { watchGridTestIds } from './grid-test-ids'\n\n// Create the custom ARBI theme using themeQuartz\n// Colours reference the host CSS variables (hsl(var(--token))), so dark mode follows the app.\n// This enables dark mode support and consistent theming\nconst cssVar = (name: string, alpha?: number): string =>\n alpha === undefined ? `hsl(var(--${name}))` : `hsl(var(--${name}) / ${alpha})`\n\nconst arbiTheme = themeQuartz.withParams({\n // Match TagTable: a plain canvas, muted header, fine row borders and a rounded frame.\n // Every colour is a host CSS variable, so light/dark follow the app with no .dark overrides.\n backgroundColor: cssVar('background'),\n foregroundColor: cssVar('foreground'),\n borderColor: cssVar('border'),\n headerBackgroundColor: cssVar('muted', 0.4),\n headerTextColor: cssVar('foreground'),\n oddRowBackgroundColor: cssVar('background'),\n rowHoverColor: cssVar('muted', 0.6),\n // Checkbox-selected rows: a light accent tint. A row opened elsewhere (e.g. the viewer) may take\n // the full accent, so the two states stay distinguishable.\n selectedRowBackgroundColor: cssVar('accent', 0.6),\n rangeSelectionBackgroundColor: cssVar('accent'),\n accentColor: cssVar('primary'),\n inputFocusBorder: { color: cssVar('primary') },\n headerColumnBorder: false,\n // Keep the header as quiet as TagTable; reveal resize handles on hover (see grid.css).\n headerColumnResizeHandleColor: 'transparent',\n headerColumnResizeHandleHeight: '40%',\n headerColumnResizeHandleWidth: 1,\n\n // Font settings — inherit the host app's font. A googleFont here never\n // loaded under the apps' CSP, so every grid silently fell back to the\n // browser's default SERIF and read as unstyled.\n fontFamily: 'inherit',\n fontSize: 14,\n headerFontSize: 14,\n headerFontWeight: 500,\n\n // Sizing\n headerHeight: 37,\n rowHeight: 40,\n cellHorizontalPadding: 12,\n\n // Borders - structural settings only.\n // Row border is a real hairline in the theme border colour (not hardcoded\n // white, which was invisible on the light-mode background and wrong in dark\n // mode) so adjacent rows are clearly separated — important now that rows can\n // be tall and multi-line (e.g. the Abstract column).\n rowBorder: { style: 'solid', width: 1, color: 'hsl(var(--border))' },\n columnBorder: false, // Row hairlines only\n wrapperBorder: { style: 'solid', width: 1, color: cssVar('border') },\n\n // Use the same radius token as TagTable's rounded-lg container.\n borderRadius: 'var(--radius-lg, 8px)',\n wrapperBorderRadius: 'var(--radius-lg, 8px)',\n checkboxBorderRadius: 2, // Keep checkboxes square\n})\n\n// Selection configuration\nexport interface GridViewSelection<T> {\n mode: 'single' | 'multiple'\n selected: T[]\n onSelectionChange: (items: T[]) => void\n /**\n * Keep the grid's ticked rows equal to `selected` after mount (default: `selected` only seeds the\n * grid). For a host that changes the selection itself, e.g. ticking a parent ticks its sub-tasks.\n */\n controlled?: boolean\n}\n\n// Empty state configuration\nexport interface GridViewEmptyState {\n icon?: React.ReactNode\n title?: string\n message?: string\n action?: React.ReactNode\n}\n\n/** Grid events GridView binds itself; `gridOptions` may not override them. */\ntype GridViewOwnedEvent =\n | 'onGridReady'\n | 'onFirstDataRendered'\n | 'onModelUpdated'\n | 'onSelectionChanged'\n | 'onCellValueChanged'\n | 'onRowClicked'\n | 'onStateUpdated'\n | 'onColumnVisible'\n\n// Generic props to make this grid reusable with different data types\nexport interface GridViewProps<T> {\n // Core data\n items: T[]\n // Column configuration\n columnDefs: ColDef<T>[]\n // Row identity function\n getItemId: (item: T) => string\n // Selection handling\n selection?: GridViewSelection<T>\n // Empty state\n emptyState?: GridViewEmptyState\n // Loading state\n isLoading?: boolean\n loadingMessage?: string\n // Grid options. The events GridView handles itself are left out: they are spread over its own\n // handlers, so passing one here silently replaced them (an `onGridReady` here left the grid api\n // unset and selection never reached `selection.onSelectionChange`). Use the dedicated props.\n gridOptions?: Partial<Omit<GridOptions<T>, GridViewOwnedEvent>>\n // Grid initialization\n onGridReady?: (params: { api: GridApi<T> }) => void\n // Cell value changes\n onCellValueChanged?: (event: CellValueChangedEvent<T>) => void\n // Row click handler\n onRowClick?: (item: T) => void\n // State persistence.\n // The core is decoupled from any store: when `persistState` is on it seeds\n // AG Grid from `gridState` (read once at mount) and reports every subsequent\n // state change through `onGridStateChange`. An app-adapter wires these to its\n // own store. `gridId` is retained as an opaque identity hint for adapters\n // (the core itself does not read it).\n persistState?: boolean\n gridId?: string\n // Persisted column/sort/filter state to restore at mount (controlled input).\n gridState?: GridState\n // Called whenever AG Grid's state changes so an adapter can persist it.\n onGridStateChange?: (state: GridState) => void\n // Initial visible columns (applied when no saved state exists)\n initialVisibleColumns?: string[]\n // Basic styling\n className?: string\n height?: string | number\n // Per-instance row height. Applied via the theme (not just gridOptions) so the\n // theme's calculated line-height tracks it and cell content stays vertically\n // centered. Fixed height — keeps row virtualization on the fast path.\n rowHeight?: number\n testId?: string\n // Pinned rows\n pinnedBottomRowData?: T[]\n pinnedTopRowData?: T[]\n // Pagination (disabled by default)\n pagination?: boolean\n paginationPageSizeSelector?: number[]\n // Test-id hooks: the grid owns its row/cell DOM, so ids are stamped onto it after render.\n // `getRowTestId` names a row; `getCellTestId` a cell (by colId). Without them AG Grid's own\n // `row-id` / `col-id` attributes are still there to select by.\n getRowTestId?: (item: T) => string\n getCellTestId?: (colId: string, item: T) => string\n // Force empty-state UI even when items.length > 0.\n // Used when rows are present but all hidden by an external filter.\n showEmpty?: boolean\n}\n\n/** Minimum row height on coarse pointers: 44px touch target + the 1px row border + breathing room. */\nconst TOUCH_ROW_HEIGHT = 52\n\nexport function GridView<T>({\n items,\n columnDefs,\n getItemId,\n selection,\n emptyState,\n isLoading = false,\n loadingMessage = 'Loading...',\n gridOptions,\n onGridReady,\n onCellValueChanged,\n onRowClick,\n persistState = false,\n gridState,\n onGridStateChange,\n initialVisibleColumns,\n className = 'w-full',\n height = 500,\n rowHeight: rowHeightProp,\n testId = 'grid-view',\n pinnedBottomRowData,\n pinnedTopRowData,\n pagination = false,\n paginationPageSizeSelector,\n getRowTestId,\n getCellTestId,\n showEmpty,\n}: GridViewProps<T>) {\n // Reference to the grid API\n const gridApiRef = useRef<GridApi<T> | null>(null)\n\n // On touch screens rows grow to a 44px-hit-area-friendly height: AG Grid clips cell content\n // (pills, filename buttons, avatar chips) to the row, so a taller hit area needs a taller row.\n const isCoarsePointer = useMediaQuery(BREAKPOINT_QUERIES.coarsePointer)\n const rowHeight = isCoarsePointer\n ? Math.max(rowHeightProp ?? gridOptions?.rowHeight ?? 40, TOUCH_ROW_HEIGHT)\n : rowHeightProp\n\n // Initial row height, captured once so it can live in the (stable) default\n // grid options. rowHeight is NOT passed as a reactive prop — that would make\n // the AgGridReact wrapper re-process grid options on every change and snap\n // manually-resized columns back to their colDef widths. Subsequent changes are\n // applied imperatively (see effect below).\n const initialRowHeightRef = useRef(rowHeight)\n\n // Persisted state to seed the grid with — captured once at mount so a reactive\n // `gridState` prop (e.g. an adapter re-reading its store each render) can never\n // re-initialise the grid mid-session. Mirrors AG Grid's own initialState,\n // which is read once.\n const initialGridStateRef = useRef(gridState)\n\n // Get initial state for the grid (read once at mount)\n const initialState = useMemo(() => {\n if (!persistState) return undefined\n return initialGridStateRef.current\n }, [persistState])\n\n // Save grid state via the adapter using modern AG Grid state API\n const saveGridState = useCallback(() => {\n if (!persistState || !onGridStateChange || !gridApiRef.current) return\n\n // Use AG Grid's comprehensive state API to capture complete state\n // This includes: filters, sort, column order, column visibility, column widths, etc.\n const state = gridApiRef.current.getState()\n\n onGridStateChange(state)\n }, [persistState, onGridStateChange])\n\n // Ensure selection column is visible after grid initialization\n const ensureSelectionColumnVisible = useCallback(() => {\n if (!gridApiRef.current || !selection?.mode) return\n\n // IMPORTANT: Force selection column to be visible after state restoration\n // This ensures even old saved states don't hide the selection column\n // Also handles case where selection column is completely missing from state\n const currentState = gridApiRef.current.getColumnState()\n const selectionColumn = currentState.find((col) => col.colId === 'ag-Grid-SelectionColumn')\n const selectionColumnIndex = currentState.findIndex(\n (col) => col.colId === 'ag-Grid-SelectionColumn'\n )\n\n // Fix if column is hidden OR missing entirely OR not in first position\n if (!selectionColumn || selectionColumn.hide || selectionColumnIndex !== 0) {\n // Use setColumnsVisible for more reliable visibility control\n gridApiRef.current.setColumnsVisible(['ag-Grid-SelectionColumn'], true)\n\n // Also apply state to ensure proper width\n gridApiRef.current.applyColumnState({\n state: [\n {\n colId: 'ag-Grid-SelectionColumn',\n hide: false,\n width: selectionColumn?.width || 48,\n pinned: null, // Ensure not pinned in wrong position\n },\n ],\n defaultState: { hide: undefined },\n applyOrder: false,\n })\n\n // Move selection column to first position if it's not there\n if (selectionColumnIndex !== 0) {\n gridApiRef.current.moveColumns(['ag-Grid-SelectionColumn'], 0)\n }\n }\n }, [selection?.mode])\n\n // Stamp host test ids onto AG Grid's rows and cells (it virtualises, so keep watching).\n const containerRef = useRef<HTMLDivElement>(null)\n const itemsRef = useRef(items)\n itemsRef.current = items\n const getItemIdRef = useRef(getItemId)\n getItemIdRef.current = getItemId\n const hasTestIdHooks = Boolean(getRowTestId || getCellTestId)\n useEffect(() => {\n const root = containerRef.current\n if (!root || !hasTestIdHooks) return\n return watchGridTestIds(\n root,\n () => new Map(itemsRef.current.map((item) => [getItemIdRef.current(item), item])),\n { getRowTestId, getCellTestId }\n )\n }, [hasTestIdHooks, getRowTestId, getCellTestId, isLoading])\n\n // Handle row ID\n const getRowId = useCallback(\n (params: { data: T }) => {\n return getItemId(params.data)\n },\n [getItemId]\n )\n\n // Refs for selection — avoids handleGridReady/handleSelectionChanged recreating\n // when selection object changes (which happens on every selectionConfig recompute)\n const selectionRef = useRef(selection)\n selectionRef.current = selection\n\n const onSelectionChangeRef = useRef(selection?.onSelectionChange)\n onSelectionChangeRef.current = selection?.onSelectionChange\n\n const syncingSelectionRef = useRef(false)\n\n const handleSelectionChanged = useCallback(() => {\n if (syncingSelectionRef.current) return\n if (!onSelectionChangeRef.current || !gridApiRef.current) return\n\n const selectedNodes = gridApiRef.current.getSelectedNodes()\n const selectedData = selectedNodes\n .map((node) => node.data)\n .filter((item): item is T => item !== undefined)\n\n onSelectionChangeRef.current(selectedData)\n }, [])\n\n // Handle row clicks\n // A controlled selection: tick and untick rows so the grid shows exactly `selection.selected`.\n const controlledSelected = selection?.controlled ? selection.selected : undefined\n useEffect(() => {\n const api = gridApiRef.current\n if (!api || api.isDestroyed() || !controlledSelected) return\n const wanted = new Set(controlledSelected.map(getItemId))\n const tick: IRowNode<T>[] = []\n const untick: IRowNode<T>[] = []\n api.forEachNode((node) => {\n if (!node.data) return\n const want = wanted.has(getItemId(node.data))\n if (want && !node.isSelected()) tick.push(node)\n else if (!want && node.isSelected()) untick.push(node)\n })\n syncingSelectionRef.current = true\n try {\n if (tick.length) api.setNodesSelected({ nodes: tick, newValue: true, source: 'api' })\n if (untick.length) api.setNodesSelected({ nodes: untick, newValue: false, source: 'api' })\n } finally {\n syncingSelectionRef.current = false\n }\n }, [controlledSelected, getItemId])\n\n const handleRowClicked = useCallback(\n (event: RowClickedEvent<T>) => {\n if (!onRowClick || !event.data) return\n // Don't fire when the click originated from an interactive element inside the cell\n // (e.g. action buttons). AG Grid fires rowClicked regardless of DOM stopPropagation.\n const target = event.event?.target as HTMLElement | null\n if (target?.closest('button, input, a, select, textarea, [role=\"button\"]')) return\n onRowClick(event.data)\n },\n [onRowClick]\n )\n\n // The visibility the user actually intends, per colId. AG Grid re-processes the\n // column definitions on some React re-renders even when the `columnDefs`\n // reference is unchanged, and that reset restores each colDef's `hide` — so a\n // column the user turned on (e.g. via a fields menu) silently disappears the\n // next time the host re-renders (opening an editor, selecting a row, …). We\n // remember the intended visibility and restore it whenever such a reset fires.\n // A Map (not a Set of hidden ids) so a genuinely NEW column from a real\n // columnDefs change — one we've never seen — is left at its colDef default\n // rather than force-shown.\n const desiredHiddenRef = useRef<Map<string, boolean> | null>(null)\n\n const snapshotDesiredHidden = useCallback(() => {\n const api = gridApiRef.current\n if (!api) return\n desiredHiddenRef.current = new Map(api.getColumnState().map((c) => [c.colId, !!c.hide]))\n }, [])\n\n // Handle grid ready\n const handleGridReady = useCallback(\n (event: GridReadyEvent<T>) => {\n gridApiRef.current = event.api\n\n // Apply initial visible columns when no saved state exists\n // This prevents showing all columns by default for new users\n if (!initialState && initialVisibleColumns?.length) {\n const currentState = event.api.getColumnState()\n const stateMap = new Map(currentState.map((col) => [col.colId, col]))\n const visibleSet = new Set(initialVisibleColumns)\n\n // Build ordered state: selection column first (always visible), then visible columns, then hidden\n const selectionCol = stateMap.get('ag-Grid-SelectionColumn')\n const orderedState = [\n // Selection column first - ALWAYS visible, create if not in state\n selectionCol\n ? { ...selectionCol, hide: false }\n : { colId: 'ag-Grid-SelectionColumn', hide: false, width: 48 },\n // Visible columns in specified order\n ...initialVisibleColumns\n .filter((colId) => colId !== 'ag-Grid-SelectionColumn') // Don't duplicate selection column\n .map((colId) => {\n const col = stateMap.get(colId)\n return col ? { ...col, hide: false } : undefined\n }),\n // Hidden columns (everything else)\n ...currentState\n .filter((col) => col.colId !== 'ag-Grid-SelectionColumn' && !visibleSet.has(col.colId))\n .map((col) => ({ ...col, hide: true })),\n ].filter((col): col is NonNullable<typeof col> => col !== undefined)\n\n event.api.applyColumnState({ state: orderedState, applyOrder: true })\n }\n\n // When restoring persisted state, detect columns from columnDefs that\n // aren't in the saved state (e.g. newly added columns) and append them.\n // AG Grid's maintainColumnOrder adds them but may place them inconsistently;\n // this ensures they appear as hidden at the end so the navigator picks them up.\n if (initialState && initialVisibleColumns?.length) {\n const currentState = event.api.getColumnState()\n const savedColIds = new Set(\n initialState.columnOrder?.orderedColIds ?? currentState.map((c) => c.colId)\n )\n const newCols = currentState.filter(\n (col) => !savedColIds.has(col.colId) && col.colId !== 'ag-Grid-SelectionColumn'\n )\n if (newCols.length > 0) {\n // Make new columns visible if they're in the default visible set\n const defaultVisible = new Set(initialVisibleColumns)\n event.api.applyColumnState({\n state: newCols.map((col) => ({\n ...col,\n hide: !defaultVisible.has(col.colId),\n })),\n })\n }\n }\n\n // Ensure selection column is visible (in case saved state hides it)\n ensureSelectionColumnVisible()\n\n // Seed the intended column visibility from the state AG Grid settled on\n // (colDefs + restored persisted state) so a later colDef-driven reset can\n // be undone rather than silently hiding a user-shown column.\n snapshotDesiredHidden()\n\n // Call the provided onGridReady callback\n if (onGridReady) {\n onGridReady({ api: event.api })\n }\n\n // Restore selection state if needed (read from ref to keep callback stable)\n const sel = selectionRef.current\n if (sel && sel.selected.length > 0) {\n const selectedIds = new Set(sel.selected.map(getItemId))\n event.api.forEachNode((node) => {\n if (node.data && selectedIds.has(getItemId(node.data))) {\n node.setSelected(true)\n }\n })\n }\n },\n [\n onGridReady,\n getItemId,\n ensureSelectionColumnVisible,\n snapshotDesiredHidden,\n initialState,\n initialVisibleColumns,\n ]\n )\n\n // Undo AG Grid's colDef-driven visibility reset; record genuine user changes.\n const handleColumnVisible = useCallback(\n (event: { source?: string }) => {\n const api = gridApiRef.current\n if (!api) return\n // A columnDefs re-apply reports `gridOptionsChanged`; a real toggle reports\n // an interaction source (api, toolPanelUi, columnMenu, …).\n if (event.source === 'gridOptionsChanged') {\n const desired = desiredHiddenRef.current\n if (!desired) return\n // Only correct columns we've seen before (in the snapshot); a brand-new\n // column keeps its colDef default.\n const fixes = api\n .getColumnState()\n .filter(\n (c) =>\n c.colId !== 'ag-Grid-SelectionColumn' &&\n desired.has(c.colId) &&\n desired.get(c.colId) !== !!c.hide\n )\n .map((c) => ({ colId: c.colId, hide: desired.get(c.colId) }))\n if (fixes.length) api.applyColumnState({ state: fixes })\n } else {\n // Genuine change — this is now the intended visibility.\n snapshotDesiredHidden()\n }\n },\n [snapshotDesiredHidden]\n )\n\n // Handle first data rendered - no auto-sizing, let flex columns handle it\n const handleFirstDataRendered = useCallback(() => {\n // Columns with flex will auto-fill, columns with width stay fixed\n // Also ensure selection column is visible as a backup (handles timing issues with initialState)\n ensureSelectionColumnVisible()\n // Seed the intended visibility from the state AG Grid settled on (colDefs +\n // any restored persisted state), so later resets can be undone.\n snapshotDesiredHidden()\n }, [ensureSelectionColumnVisible, snapshotDesiredHidden])\n\n // Track when AG Grid processes row updates\n const handleModelUpdated = useCallback(() => {\n // AG Grid handles model updates internally\n }, [])\n\n // Track row data changes for AG Grid updates\n const prevItemsRef = useRef<T[]>([])\n useEffect(() => {\n prevItemsRef.current = items\n }, [items])\n\n // Handle state updates - save state when it changes (modern AG Grid approach)\n const handleStateUpdated = useCallback(() => {\n saveGridState()\n }, [saveGridState])\n\n // Removed problematic useEffect that caused unnecessary re-renders\n // AG Grid handles selection internally, only sync on initial load\n\n // Default grid options with minimal settings - memoized to prevent re-renders\n const defaultOptions: GridOptions<T> = useMemo(() => {\n return {\n // Initial row height (stable — captured once). Live changes go through the\n // imperative effect, not this option, to avoid column-state churn.\n rowHeight: initialRowHeightRef.current,\n suppressMenuHide: true, // Prevent hiding columns since we don't have enterprise sidebar\n maintainColumnOrder: true, // Preserve column order when columns are added/removed\n\n // Row virtualization: Render rows as needed for performance\n // rowBuffer renders extra rows above/below viewport for smoother scrolling\n rowBuffer: 10, // Render 10 extra rows above/below viewport for smooth scrolling\n suppressColumnVirtualisation: false, // Keep column virtualization enabled\n suppressRowVirtualisation: false, // ENABLE row virtualization - only render visible rows\n animateRows: false, // Disable row animations\n suppressColumnMoveAnimation: true, // Disable column move/resize animations\n\n // Efficient updates with React Query cache\n // getRowId enables change detection - grid only re-renders changed rows\n // Works perfectly with React Query's cache updates\n getRowId: getRowId,\n\n rowSelection: selection?.mode\n ? {\n mode: selection.mode === 'single' ? 'singleRow' : 'multiRow',\n selectAll: 'filtered', // Header checkbox selects all filtered rows (across all pages)\n // In multi-row mode, only checkboxes should toggle selection (clicking row body would replace selection)\n enableClickSelection: selection.mode === 'single',\n checkboxes: true,\n headerCheckbox: selection.mode === 'multiple',\n }\n : undefined,\n selectionColumnDef: selection?.mode\n ? {\n sortable: selection.mode === 'multiple',\n width: 48,\n lockVisible: true, // Cannot be hidden\n suppressMovable: true, // Cannot be moved\n }\n : undefined,\n // Use normal layout for better performance - autoHeight causes forced reflows\n domLayout: 'normal',\n // Stop editing when clicking outside the cell/grid\n stopEditingWhenCellsLoseFocus: true,\n // Additional performance optimizations\n suppressCellFocus: true, // Don't focus cells on click (faster)\n suppressRowHoverHighlight: true, // Disable hover highlight - reduces DOM manipulation during scroll\n suppressScrollOnNewData: true, // Don't scroll when data updates\n suppressAggFuncInHeader: true, // Don't show aggregation functions (faster)\n // Tooltip UX: the AG Grid default show-delay is 2 s which hurts\n // discoverability for cells where tooltips carry the \"reveal full\n // content\" affordance for non-editable users. 300 ms is snappy\n // without being accidental. tooltipInteraction lets users hover\n // onto the tooltip itself (e.g. to select / copy long text).\n // These are AG Grid's native tooltip controls — no React / Radix\n // provider involved, zero per-row cost; tooltip DOM is created on\n // demand when hover-delay elapses and destroyed on mouseout.\n tooltipShowDelay: 300,\n tooltipHideDelay: 4000,\n tooltipInteraction: true,\n // Pagination (disabled by default)\n pagination,\n paginationPageSizeSelector,\n defaultColDef: {\n sortable: true,\n resizable: true,\n unSortIcon: false, // Sort glyph only on the sorted column (every header carrying one was noise)\n sortingOrder: ['asc', 'desc', null], // 3-way sorting: asc → desc → unsorted (AG Grid default)\n wrapText: false, // Disable text wrapping for cleaner display\n autoHeight: false, // Use fixed row height from theme\n wrapHeaderText: false, // Disable header text wrapping for cleaner look\n autoHeaderHeight: false, // Fixed header height\n filterParams: {\n maxNumConditions: 1,\n buttons: ['reset'],\n },\n },\n }\n }, [selection?.mode, getRowId, pagination, paginationPageSizeSelector])\n\n // Combine default options with passed options - memoized to prevent re-renders\n const combinedOptions = useMemo(\n () => ({ ...defaultOptions, ...gridOptions }),\n [defaultOptions, gridOptions]\n )\n\n // Apply fixed height for better performance — autoHeight causes forced\n // reflows by measuring all rows, avoid it.\n //\n // Also derive the geometry the wrapping multiline columns (.cell-multiline —\n // Abstract, Author, custom text fields) need so their overflow clip lands on\n // a WHOLE-line boundary (never mid-line, which reads as a half-line\n // \"bleeding\" into the neighbouring row). All computed once here per\n // row-height change and handed to CSS as variables — zero per-row cost on the\n // million-row grid:\n // --multiline-line-clamp : whole number of lines that fit — drives the CSS\n // line-clamp that hides overflow lines entirely.\n // --multiline-pad-y : vertical cell padding, shrunk on very short rows so\n // at least one whole line always fits.\n // --multiline-max-h : cap of exactly N whole lines + TOP padding + borders.\n // Deliberately excludes the bottom padding: AG Grid\n // forces cell height, so overflow clips at the\n // padding-box edge and any bottom padding becomes a\n // window onto the next (clamped-away) line. Ending the\n // box right at line N's bottom puts the clip on the\n // line boundary; the row supplies the visual gap below.\n const containerStyle = useMemo(() => {\n const style: React.CSSProperties = { height }\n if (rowHeight) {\n const LINE_PX = 14 * 1.35 // grid font-size × multiline line-height (18.9px)\n const BORDER = 2 // multiline cell top + bottom border (1px each, border-box)\n const PREFERRED_PAD = 16 // preferred total vertical padding (8px top + 8px bottom)\n // Don't let padding eat the room a single line needs on short rows.\n const padTotal = Math.max(0, Math.min(PREFERRED_PAD, rowHeight - BORDER - LINE_PX))\n const lines = Math.max(1, Math.floor((rowHeight - BORDER - padTotal) / LINE_PX))\n const vars = style as Record<string, string | number>\n vars['--multiline-line-clamp'] = `${lines}`\n vars['--multiline-pad-y'] = `${padTotal / 2}px`\n vars['--multiline-max-h'] = `${lines * LINE_PX + padTotal / 2 + BORDER}px`\n }\n return style\n }, [height, rowHeight])\n\n // Apply rowHeight changes imperatively via the grid option (not the theme —\n // recreating the theme would re-initialise the grid). This only re-lays-out\n // rows; columns, row virtualization, and the transaction bus are untouched.\n useEffect(() => {\n const api = gridApiRef.current\n if (!api || api.isDestroyed() || !rowHeight) return\n api.setGridOption('rowHeight', rowHeight)\n api.resetRowHeights()\n }, [rowHeight])\n\n const containerClassName = useMemo(() => {\n const baseClass = className || ''\n // Height-adjustable grids vertically center cell content (CSS) so a\n // one-line cell or a lone pill sits in the middle of the row, and multi-line\n // text (e.g. Abstract) is balanced top-to-bottom — flagged here, applied in\n // grid.css.\n const alignClass = rowHeight ? 'ag-cells-centered' : ''\n return [baseClass, alignClass].filter(Boolean).join(' ')\n }, [className, rowHeight])\n\n // Show loading state — grey skeleton rows so the page transition feels instant\n if (isLoading) {\n const skeletonRowCount = 12\n return (\n <div\n data-testid={`${testId}-loading`}\n className={`${containerClassName} overflow-hidden rounded-lg border border-border`}\n style={containerStyle}\n aria-busy=\"true\"\n aria-label={loadingMessage}\n >\n {/* Header skeleton */}\n <div className=\"flex h-[37px] items-center gap-4 border-b border-border bg-muted/40 px-3\">\n <div className=\"h-3 w-6 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-32 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-20 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-28 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-16 rounded bg-muted animate-pulse ml-auto\" />\n </div>\n {/* Row skeletons */}\n {Array.from({ length: skeletonRowCount }).map((_, rowIdx) => (\n <div key={rowIdx} className=\"flex h-10 items-center gap-4 border-b border-border px-3\">\n <div className=\"h-4 w-4 rounded-sm bg-muted/70 animate-pulse\" />\n <div\n className=\"h-3 rounded bg-muted/70 animate-pulse\"\n style={{ width: `${20 + ((rowIdx * 17) % 40)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/60 animate-pulse\"\n style={{ width: `${8 + ((rowIdx * 11) % 12)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/60 animate-pulse\"\n style={{ width: `${6 + ((rowIdx * 7) % 10)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/50 animate-pulse ml-auto\"\n style={{ width: `${5 + ((rowIdx * 5) % 8)}%` }}\n />\n </div>\n ))}\n </div>\n )\n }\n\n // Show empty state\n // showEmpty lets callers force this UI (e.g. when an external filter hid\n // every row but the underlying items array is non-empty).\n if ((showEmpty ?? items.length === 0) && emptyState) {\n return (\n <div\n data-testid={`${testId}-empty`}\n // Capped by its container (a landscape phone is shorter than 24rem) and scrollable, with the\n // content centred by auto margins so a tall one still starts at the top.\n className=\"flex h-96 max-h-full flex-col items-center overflow-y-auto p-6 text-center\"\n >\n <div className=\"my-auto flex flex-col items-center\">\n {emptyState.icon && (\n <div className=\"text-muted-foreground/60 mb-4\">{emptyState.icon}</div>\n )}\n {emptyState.title && <h3 className=\"text-xl font-medium mb-2\">{emptyState.title}</h3>}\n {emptyState.message && (\n <p className=\"text-muted-foreground mb-6 max-w-md\">{emptyState.message}</p>\n )}\n {emptyState.action}\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={containerRef}\n className={containerClassName}\n style={containerStyle}\n data-testid={testId}\n >\n <AgGridReact\n theme={arbiTheme}\n modules={[AllCommunityModule]}\n columnDefs={columnDefs}\n rowData={items}\n pinnedBottomRowData={pinnedBottomRowData}\n pinnedTopRowData={pinnedTopRowData}\n getRowId={getRowId}\n initialState={initialState}\n onGridReady={handleGridReady}\n onFirstDataRendered={handleFirstDataRendered}\n onModelUpdated={handleModelUpdated}\n onSelectionChanged={handleSelectionChanged}\n onCellValueChanged={onCellValueChanged}\n onRowClicked={handleRowClicked}\n onStateUpdated={handleStateUpdated}\n onColumnVisible={handleColumnVisible}\n {...combinedOptions}\n />\n </div>\n )\n}\n"]}