eidos-ui 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.md +4 -0
  2. package/dist/Header.types-0XovUp0T.d.ts +79 -0
  3. package/dist/Header.types-Ce5Cj301.d.cts +79 -0
  4. package/dist/{Navigation.types-CpS3EYNz.d.ts → Navigation.types-By5HfPTi.d.ts} +8 -0
  5. package/dist/{Navigation.types-sUO9wqOp.d.cts → Navigation.types-_MrYqqUI.d.cts} +8 -0
  6. package/dist/{SegmentedControl.types-Dm4SnwCK.d.cts → SegmentedControl.types-BofrEYyd.d.cts} +16 -1
  7. package/dist/{SegmentedControl.types-CK8EiShd.d.ts → SegmentedControl.types-cjLwwBAm.d.ts} +16 -1
  8. package/dist/alert/index.cjs +4 -4
  9. package/dist/alert/index.js +3 -3
  10. package/dist/button/index.cjs +3 -3
  11. package/dist/button/index.js +2 -2
  12. package/dist/chip/index.cjs +3 -3
  13. package/dist/chip/index.js +2 -2
  14. package/dist/{chunk-RWOX2NJN.js → chunk-25PSIDPC.js} +2 -2
  15. package/dist/{chunk-IFVT5UCY.js → chunk-2QEKSRVX.js} +14 -10
  16. package/dist/chunk-2QEKSRVX.js.map +1 -0
  17. package/dist/{chunk-4BKTBV2I.js → chunk-2R77XZEP.js} +6 -2
  18. package/dist/chunk-2R77XZEP.js.map +1 -0
  19. package/dist/{chunk-H5HWFOWZ.js → chunk-2WP27QAN.js} +8 -8
  20. package/dist/{chunk-EXITZVB2.js → chunk-3RLGH45H.js} +6 -6
  21. package/dist/{chunk-442U3W6R.cjs → chunk-4MZ7HEQC.cjs} +5 -5
  22. package/dist/{chunk-442U3W6R.cjs.map → chunk-4MZ7HEQC.cjs.map} +1 -1
  23. package/dist/{chunk-R4PU2TBM.js → chunk-4ZWAJTNH.js} +3 -3
  24. package/dist/{chunk-RHOT7AEI.cjs → chunk-55J4LEKT.cjs} +8 -7
  25. package/dist/chunk-55J4LEKT.cjs.map +1 -0
  26. package/dist/{chunk-REVK7IGN.js → chunk-5WH3JMR5.js} +8 -7
  27. package/dist/chunk-5WH3JMR5.js.map +1 -0
  28. package/dist/{chunk-GT22EGJP.cjs → chunk-65PC3YDT.cjs} +14 -10
  29. package/dist/chunk-65PC3YDT.cjs.map +1 -0
  30. package/dist/{chunk-KQD7CQ4Z.cjs → chunk-6CSUUQ5M.cjs} +10 -6
  31. package/dist/chunk-6CSUUQ5M.cjs.map +1 -0
  32. package/dist/{chunk-GR2PMCVN.cjs → chunk-75TDY7XF.cjs} +5 -5
  33. package/dist/{chunk-GR2PMCVN.cjs.map → chunk-75TDY7XF.cjs.map} +1 -1
  34. package/dist/{chunk-FRUOA2QU.cjs → chunk-75VXB3H2.cjs} +7 -3
  35. package/dist/chunk-75VXB3H2.cjs.map +1 -0
  36. package/dist/{chunk-F26VIKNF.js → chunk-ATL7325T.js} +3 -3
  37. package/dist/{chunk-TEJIPPZR.js → chunk-BC5I2MYB.js} +7 -4
  38. package/dist/chunk-BC5I2MYB.js.map +1 -0
  39. package/dist/{chunk-GHQ6SQPI.js → chunk-BHVHM66Z.js} +6 -6
  40. package/dist/{chunk-N2IGZIEX.cjs → chunk-CJGFRPAS.cjs} +3 -3
  41. package/dist/{chunk-N2IGZIEX.cjs.map → chunk-CJGFRPAS.cjs.map} +1 -1
  42. package/dist/{chunk-GEHL4LKK.cjs → chunk-CUJBNRJJ.cjs} +8 -2
  43. package/dist/chunk-CUJBNRJJ.cjs.map +1 -0
  44. package/dist/{chunk-DAXZRNNO.cjs → chunk-D2SKXRKP.cjs} +8 -8
  45. package/dist/{chunk-DAXZRNNO.cjs.map → chunk-D2SKXRKP.cjs.map} +1 -1
  46. package/dist/{chunk-KBG77JHC.js → chunk-EAJHEYZM.js} +8 -2
  47. package/dist/chunk-EAJHEYZM.js.map +1 -0
  48. package/dist/{chunk-G77YR73R.cjs → chunk-EBSKRZXI.cjs} +8 -8
  49. package/dist/{chunk-G77YR73R.cjs.map → chunk-EBSKRZXI.cjs.map} +1 -1
  50. package/dist/{chunk-B5G5XVFJ.cjs → chunk-EH42ND5Q.cjs} +5 -5
  51. package/dist/{chunk-B5G5XVFJ.cjs.map → chunk-EH42ND5Q.cjs.map} +1 -1
  52. package/dist/{chunk-WUBQJVB7.cjs → chunk-EL3YXTOW.cjs} +9 -6
  53. package/dist/chunk-EL3YXTOW.cjs.map +1 -0
  54. package/dist/{chunk-Y53HCLGW.js → chunk-FALDCW2E.js} +2 -2
  55. package/dist/{chunk-D5IY2HUV.cjs → chunk-FXZJL2AM.cjs} +5 -5
  56. package/dist/{chunk-D5IY2HUV.cjs.map → chunk-FXZJL2AM.cjs.map} +1 -1
  57. package/dist/{chunk-KJZUYC4X.cjs → chunk-HI6WCX4T.cjs} +10 -9
  58. package/dist/chunk-HI6WCX4T.cjs.map +1 -0
  59. package/dist/{chunk-LFWPQYWX.cjs → chunk-I3CSPYHG.cjs} +3 -3
  60. package/dist/{chunk-LFWPQYWX.cjs.map → chunk-I3CSPYHG.cjs.map} +1 -1
  61. package/dist/{chunk-EZME5CLK.cjs → chunk-J5RMLZ4P.cjs} +3 -3
  62. package/dist/{chunk-EZME5CLK.cjs.map → chunk-J5RMLZ4P.cjs.map} +1 -1
  63. package/dist/{chunk-VHMOKXUT.js → chunk-JRLUZDKA.js} +8 -7
  64. package/dist/chunk-JRLUZDKA.js.map +1 -0
  65. package/dist/{chunk-LIFUHQH5.cjs → chunk-KBGFDHKD.cjs} +19 -19
  66. package/dist/{chunk-LIFUHQH5.cjs.map → chunk-KBGFDHKD.cjs.map} +1 -1
  67. package/dist/{chunk-ZHFPV43D.js → chunk-KNQ6NN6L.js} +5 -5
  68. package/dist/{chunk-2ZY7M72Q.js → chunk-KQJ3IAFT.js} +10 -7
  69. package/dist/chunk-KQJ3IAFT.js.map +1 -0
  70. package/dist/{chunk-74MBKLYI.js → chunk-L23WWO3D.js} +9 -5
  71. package/dist/chunk-L23WWO3D.js.map +1 -0
  72. package/dist/{chunk-YJXZR7RL.js → chunk-L5Q6UDY3.js} +4 -4
  73. package/dist/{chunk-5BX4Q76D.cjs → chunk-LVHZBCTA.cjs} +3 -3
  74. package/dist/{chunk-5BX4Q76D.cjs.map → chunk-LVHZBCTA.cjs.map} +1 -1
  75. package/dist/{chunk-SENVA467.js → chunk-M7PF4FKQ.js} +6 -2
  76. package/dist/chunk-M7PF4FKQ.js.map +1 -0
  77. package/dist/chunk-ND526PMG.cjs +145 -0
  78. package/dist/chunk-ND526PMG.cjs.map +1 -0
  79. package/dist/{chunk-TRLBYA5G.cjs → chunk-NEYLNRVG.cjs} +5 -5
  80. package/dist/{chunk-TRLBYA5G.cjs.map → chunk-NEYLNRVG.cjs.map} +1 -1
  81. package/dist/{chunk-ZEZK664O.js → chunk-NWJ6NETE.js} +13 -13
  82. package/dist/{chunk-U5FHQ73U.cjs → chunk-NZO2I5AL.cjs} +15 -12
  83. package/dist/chunk-NZO2I5AL.cjs.map +1 -0
  84. package/dist/{chunk-5ZL6PYU3.js → chunk-O2AACVSF.js} +3 -3
  85. package/dist/chunk-O3LG7B2J.cjs +186 -0
  86. package/dist/chunk-O3LG7B2J.cjs.map +1 -0
  87. package/dist/{chunk-SHYSLWQG.js → chunk-OAK7HFOJ.js} +4 -4
  88. package/dist/{chunk-QF2RAUPB.cjs → chunk-OAPOGYA5.cjs} +7 -3
  89. package/dist/chunk-OAPOGYA5.cjs.map +1 -0
  90. package/dist/{chunk-SKEWTQJ7.cjs → chunk-OMLXP2CK.cjs} +7 -7
  91. package/dist/{chunk-SKEWTQJ7.cjs.map → chunk-OMLXP2CK.cjs.map} +1 -1
  92. package/dist/{chunk-VSTQEHVZ.js → chunk-PR7CVQ4R.js} +10 -7
  93. package/dist/chunk-PR7CVQ4R.js.map +1 -0
  94. package/dist/{chunk-6HUHH6Y4.cjs → chunk-Q6ICDKQZ.cjs} +22 -19
  95. package/dist/chunk-Q6ICDKQZ.cjs.map +1 -0
  96. package/dist/{chunk-NGVOXM7P.js → chunk-QIITXVRG.js} +4 -4
  97. package/dist/{chunk-GI6VJYOS.js → chunk-QUDVJUZU.js} +3 -3
  98. package/dist/chunk-QZX3A4FX.js +886 -0
  99. package/dist/chunk-QZX3A4FX.js.map +1 -0
  100. package/dist/chunk-R3WPVTGY.cjs +886 -0
  101. package/dist/chunk-R3WPVTGY.cjs.map +1 -0
  102. package/dist/{chunk-SN6EWQDJ.js → chunk-RYOQYYDO.js} +3 -3
  103. package/dist/chunk-S4S4LB63.js +186 -0
  104. package/dist/chunk-S4S4LB63.js.map +1 -0
  105. package/dist/{chunk-67RFMV6K.js → chunk-T2KB3DJJ.js} +2 -2
  106. package/dist/{chunk-5VM2256W.cjs → chunk-TEVZHN5I.cjs} +11 -10
  107. package/dist/chunk-TEVZHN5I.cjs.map +1 -0
  108. package/dist/{chunk-RKA2OJRT.js → chunk-TJC7UELT.js} +18 -18
  109. package/dist/{chunk-SKTDGCWJ.cjs → chunk-UOOGS6N7.cjs} +48 -48
  110. package/dist/{chunk-SKTDGCWJ.cjs.map → chunk-UOOGS6N7.cjs.map} +1 -1
  111. package/dist/{chunk-SE7MWOC7.cjs → chunk-VRQBDTLT.cjs} +32 -32
  112. package/dist/{chunk-SE7MWOC7.cjs.map → chunk-VRQBDTLT.cjs.map} +1 -1
  113. package/dist/{chunk-AXBYJ2OY.cjs → chunk-WFEORBLC.cjs} +8 -8
  114. package/dist/{chunk-AXBYJ2OY.cjs.map → chunk-WFEORBLC.cjs.map} +1 -1
  115. package/dist/chunk-WKDT2XFQ.js +145 -0
  116. package/dist/chunk-WKDT2XFQ.js.map +1 -0
  117. package/dist/{chunk-APK5OQRV.cjs → chunk-WWYJNWJY.cjs} +6 -6
  118. package/dist/{chunk-APK5OQRV.cjs.map → chunk-WWYJNWJY.cjs.map} +1 -1
  119. package/dist/{chunk-A7WQINIG.js → chunk-X3U7SDOZ.js} +7 -6
  120. package/dist/chunk-X3U7SDOZ.js.map +1 -0
  121. package/dist/{chunk-LEMCJW57.js → chunk-YDPEHUMH.js} +2 -2
  122. package/dist/{chunk-GGSII6Y2.cjs → chunk-ZGT4LT5Y.cjs} +33 -33
  123. package/dist/{chunk-GGSII6Y2.cjs.map → chunk-ZGT4LT5Y.cjs.map} +1 -1
  124. package/dist/{chunk-LUL6RZ4M.cjs → chunk-ZNWIHUHZ.cjs} +3 -3
  125. package/dist/{chunk-LUL6RZ4M.cjs.map → chunk-ZNWIHUHZ.cjs.map} +1 -1
  126. package/dist/{chunk-S3CT536K.js → chunk-ZPDETHQ7.js} +2 -2
  127. package/dist/color-picker/index.cjs +4 -3
  128. package/dist/color-picker/index.cjs.map +1 -1
  129. package/dist/color-picker/index.js +3 -2
  130. package/dist/combobox/index.cjs +5 -5
  131. package/dist/combobox/index.js +4 -4
  132. package/dist/context-menu/index.cjs +5 -5
  133. package/dist/context-menu/index.js +4 -4
  134. package/dist/conversation/index.cjs +28 -0
  135. package/dist/conversation/index.cjs.map +1 -0
  136. package/dist/conversation/index.d.cts +254 -0
  137. package/dist/conversation/index.d.ts +254 -0
  138. package/dist/conversation/index.js +28 -0
  139. package/dist/conversation/index.js.map +1 -0
  140. package/dist/data-grid/index.cjs +16 -16
  141. package/dist/data-grid/index.d.cts +1 -1
  142. package/dist/data-grid/index.d.ts +1 -1
  143. package/dist/data-grid/index.js +15 -15
  144. package/dist/date-picker/index.cjs +7 -7
  145. package/dist/date-picker/index.js +6 -6
  146. package/dist/drawer/index.cjs +4 -4
  147. package/dist/drawer/index.js +3 -3
  148. package/dist/dropdown/index.cjs +3 -2
  149. package/dist/dropdown/index.cjs.map +1 -1
  150. package/dist/dropdown/index.js +2 -1
  151. package/dist/header/index.cjs +8 -4
  152. package/dist/header/index.cjs.map +1 -1
  153. package/dist/header/index.d.cts +35 -4
  154. package/dist/header/index.d.ts +35 -4
  155. package/dist/header/index.js +9 -5
  156. package/dist/index.cjs +66 -56
  157. package/dist/index.cjs.map +1 -1
  158. package/dist/index.css +1147 -295
  159. package/dist/index.d.cts +5 -4
  160. package/dist/index.d.ts +5 -4
  161. package/dist/index.js +84 -74
  162. package/dist/inline-edit/index.cjs +4 -4
  163. package/dist/inline-edit/index.js +3 -3
  164. package/dist/input/index.cjs +3 -3
  165. package/dist/input/index.js +2 -2
  166. package/dist/menu/index.cjs +4 -4
  167. package/dist/menu/index.js +3 -3
  168. package/dist/modal/index.cjs +4 -4
  169. package/dist/modal/index.js +3 -3
  170. package/dist/navigation/index.cjs +4 -4
  171. package/dist/navigation/index.d.cts +2 -2
  172. package/dist/navigation/index.d.ts +2 -2
  173. package/dist/navigation/index.js +3 -3
  174. package/dist/number-input/index.cjs +3 -2
  175. package/dist/number-input/index.cjs.map +1 -1
  176. package/dist/number-input/index.js +2 -1
  177. package/dist/page-layout/index.cjs +10 -9
  178. package/dist/page-layout/index.cjs.map +1 -1
  179. package/dist/page-layout/index.d.cts +2 -2
  180. package/dist/page-layout/index.d.ts +2 -2
  181. package/dist/page-layout/index.js +9 -8
  182. package/dist/pagination/index.cjs +7 -7
  183. package/dist/pagination/index.js +6 -6
  184. package/dist/segmented-control/index.cjs +3 -3
  185. package/dist/segmented-control/index.d.cts +2 -2
  186. package/dist/segmented-control/index.d.ts +2 -2
  187. package/dist/segmented-control/index.js +2 -2
  188. package/dist/select/index.cjs +5 -5
  189. package/dist/select/index.js +4 -4
  190. package/dist/snackbar/index.cjs +4 -4
  191. package/dist/snackbar/index.js +3 -3
  192. package/dist/split-button/index.cjs +5 -5
  193. package/dist/split-button/index.js +4 -4
  194. package/dist/table/index.cjs +16 -16
  195. package/dist/table/index.cjs.map +1 -1
  196. package/dist/table/index.js +15 -15
  197. package/dist/tabs/index.cjs +3 -3
  198. package/dist/tabs/index.js +2 -2
  199. package/dist/tag-input/index.cjs +5 -5
  200. package/dist/tag-input/index.js +4 -4
  201. package/dist/textarea/index.cjs +3 -3
  202. package/dist/textarea/index.js +2 -2
  203. package/dist/theme-editor/index.cjs +11 -11
  204. package/dist/theme-editor/index.js +10 -10
  205. package/dist/theme-provider/index.cjs +3 -3
  206. package/dist/theme-provider/index.js +2 -2
  207. package/dist/toolbar/index.cjs +6 -6
  208. package/dist/toolbar/index.js +5 -5
  209. package/package.json +1 -1
  210. package/dist/Header.types-B3QtuiL-.d.cts +0 -21
  211. package/dist/Header.types-C6w0FBY8.d.ts +0 -21
  212. package/dist/chunk-2ZY7M72Q.js.map +0 -1
  213. package/dist/chunk-4BKTBV2I.js.map +0 -1
  214. package/dist/chunk-5VM2256W.cjs.map +0 -1
  215. package/dist/chunk-6HUHH6Y4.cjs.map +0 -1
  216. package/dist/chunk-74MBKLYI.js.map +0 -1
  217. package/dist/chunk-A7WQINIG.js.map +0 -1
  218. package/dist/chunk-AAA6TR5I.cjs +0 -67
  219. package/dist/chunk-AAA6TR5I.cjs.map +0 -1
  220. package/dist/chunk-FRUOA2QU.cjs.map +0 -1
  221. package/dist/chunk-GEHL4LKK.cjs.map +0 -1
  222. package/dist/chunk-GT22EGJP.cjs.map +0 -1
  223. package/dist/chunk-IFVT5UCY.js.map +0 -1
  224. package/dist/chunk-KBG77JHC.js.map +0 -1
  225. package/dist/chunk-KJZUYC4X.cjs.map +0 -1
  226. package/dist/chunk-KQD7CQ4Z.cjs.map +0 -1
  227. package/dist/chunk-O5WEKLNF.js +0 -21
  228. package/dist/chunk-O5WEKLNF.js.map +0 -1
  229. package/dist/chunk-P7IQY5YH.js +0 -67
  230. package/dist/chunk-P7IQY5YH.js.map +0 -1
  231. package/dist/chunk-QF2RAUPB.cjs.map +0 -1
  232. package/dist/chunk-REVK7IGN.js.map +0 -1
  233. package/dist/chunk-RHOT7AEI.cjs.map +0 -1
  234. package/dist/chunk-SENVA467.js.map +0 -1
  235. package/dist/chunk-TEJIPPZR.js.map +0 -1
  236. package/dist/chunk-U5FHQ73U.cjs.map +0 -1
  237. package/dist/chunk-VHMOKXUT.js.map +0 -1
  238. package/dist/chunk-VSTQEHVZ.js.map +0 -1
  239. package/dist/chunk-WUBQJVB7.cjs.map +0 -1
  240. package/dist/chunk-Z4SLV6WG.cjs +0 -21
  241. package/dist/chunk-Z4SLV6WG.cjs.map +0 -1
  242. /package/dist/{chunk-RWOX2NJN.js.map → chunk-25PSIDPC.js.map} +0 -0
  243. /package/dist/{chunk-H5HWFOWZ.js.map → chunk-2WP27QAN.js.map} +0 -0
  244. /package/dist/{chunk-EXITZVB2.js.map → chunk-3RLGH45H.js.map} +0 -0
  245. /package/dist/{chunk-R4PU2TBM.js.map → chunk-4ZWAJTNH.js.map} +0 -0
  246. /package/dist/{chunk-F26VIKNF.js.map → chunk-ATL7325T.js.map} +0 -0
  247. /package/dist/{chunk-GHQ6SQPI.js.map → chunk-BHVHM66Z.js.map} +0 -0
  248. /package/dist/{chunk-Y53HCLGW.js.map → chunk-FALDCW2E.js.map} +0 -0
  249. /package/dist/{chunk-ZHFPV43D.js.map → chunk-KNQ6NN6L.js.map} +0 -0
  250. /package/dist/{chunk-YJXZR7RL.js.map → chunk-L5Q6UDY3.js.map} +0 -0
  251. /package/dist/{chunk-ZEZK664O.js.map → chunk-NWJ6NETE.js.map} +0 -0
  252. /package/dist/{chunk-5ZL6PYU3.js.map → chunk-O2AACVSF.js.map} +0 -0
  253. /package/dist/{chunk-SHYSLWQG.js.map → chunk-OAK7HFOJ.js.map} +0 -0
  254. /package/dist/{chunk-NGVOXM7P.js.map → chunk-QIITXVRG.js.map} +0 -0
  255. /package/dist/{chunk-GI6VJYOS.js.map → chunk-QUDVJUZU.js.map} +0 -0
  256. /package/dist/{chunk-SN6EWQDJ.js.map → chunk-RYOQYYDO.js.map} +0 -0
  257. /package/dist/{chunk-67RFMV6K.js.map → chunk-T2KB3DJJ.js.map} +0 -0
  258. /package/dist/{chunk-RKA2OJRT.js.map → chunk-TJC7UELT.js.map} +0 -0
  259. /package/dist/{chunk-LEMCJW57.js.map → chunk-YDPEHUMH.js.map} +0 -0
  260. /package/dist/{chunk-S3CT536K.js.map → chunk-ZPDETHQ7.js.map} +0 -0
@@ -0,0 +1,886 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkIYWAZEFIcjs = require('./chunk-IYWAZEFI.cjs');
4
+
5
+
6
+ var _chunkEQ6BNPTLcjs = require('./chunk-EQ6BNPTL.cjs');
7
+
8
+
9
+ var _chunkTROYIUDHcjs = require('./chunk-TROYIUDH.cjs');
10
+
11
+
12
+ var _chunkKV3V2CPHcjs = require('./chunk-KV3V2CPH.cjs');
13
+
14
+
15
+ var _chunkNEYLNRVGcjs = require('./chunk-NEYLNRVG.cjs');
16
+
17
+
18
+ var _chunkD2SKXRKPcjs = require('./chunk-D2SKXRKP.cjs');
19
+
20
+
21
+ var _chunkQ3GNKF74cjs = require('./chunk-Q3GNKF74.cjs');
22
+
23
+
24
+ var _chunkWWYJNWJYcjs = require('./chunk-WWYJNWJY.cjs');
25
+
26
+ // src/components/Conversation/Chat.component.tsx
27
+ var _react = require('react');
28
+ var _lucidereact = require('lucide-react');
29
+
30
+ // src/components/Conversation/MessageComposer.component.tsx
31
+
32
+
33
+
34
+ // src/components/Conversation/Conversation.hooks.ts
35
+
36
+ var useNewMessageIds = (messages, enabled) => {
37
+ const seen = _react.useRef.call(void 0, null);
38
+ const [fresh, setFresh] = _react.useState.call(void 0, () => /* @__PURE__ */ new Set());
39
+ _react.useEffect.call(void 0, () => {
40
+ if (seen.current === null) {
41
+ seen.current = new Set(messages.map((message) => message.id));
42
+ return;
43
+ }
44
+ if (!enabled) {
45
+ for (const message of messages) seen.current.add(message.id);
46
+ return;
47
+ }
48
+ const added = messages.filter((message) => !_optionalChain([seen, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.has, 'call', _4 => _4(message.id)]));
49
+ if (!added.length) return;
50
+ for (const message of added) seen.current.add(message.id);
51
+ setFresh(new Set(added.map((message) => message.id)));
52
+ }, [messages, enabled]);
53
+ return fresh;
54
+ };
55
+ var BOTTOM_THRESHOLD_PX = 48;
56
+ var useStickToBottom = (messages) => {
57
+ const scrollRef = _react.useRef.call(void 0, null);
58
+ const [atBottom, setAtBottom] = _react.useState.call(void 0, true);
59
+ const atBottomRef = _react.useRef.call(void 0, true);
60
+ const lastCount = _react.useRef.call(void 0, messages.length);
61
+ const scrollToBottom = _react.useCallback.call(void 0, (behavior = "smooth") => {
62
+ const node = scrollRef.current;
63
+ if (!node) return;
64
+ node.scrollTo({ top: node.scrollHeight, behavior });
65
+ }, []);
66
+ const handleScroll = _react.useCallback.call(void 0, () => {
67
+ const node = scrollRef.current;
68
+ if (!node) return;
69
+ const distance = node.scrollHeight - node.scrollTop - node.clientHeight;
70
+ const next = distance <= BOTTOM_THRESHOLD_PX;
71
+ atBottomRef.current = next;
72
+ setAtBottom((current) => current === next ? current : next);
73
+ }, []);
74
+ _react.useLayoutEffect.call(void 0, () => {
75
+ scrollToBottom("auto");
76
+ }, []);
77
+ _react.useLayoutEffect.call(void 0, () => {
78
+ if (messages.length > lastCount.current && atBottomRef.current) {
79
+ scrollToBottom("smooth");
80
+ }
81
+ lastCount.current = messages.length;
82
+ }, [messages.length, scrollToBottom]);
83
+ return { scrollRef, atBottom, scrollToBottom, handleScroll };
84
+ };
85
+ var useScrollAnchor = (scrollRef, messages) => {
86
+ const previous = _react.useRef.call(void 0, { height: 0, firstId: "", count: 0 });
87
+ _react.useLayoutEffect.call(void 0, () => {
88
+ const node = scrollRef.current;
89
+ if (!node) return;
90
+ const firstId = _nullishCoalesce(_optionalChain([messages, 'access', _5 => _5[0], 'optionalAccess', _6 => _6.id]), () => ( ""));
91
+ const before = previous.current;
92
+ const prepended = before.firstId !== "" && before.firstId !== firstId && messages.length > before.count;
93
+ if (prepended) {
94
+ node.scrollTop += node.scrollHeight - before.height;
95
+ }
96
+ previous.current = { height: node.scrollHeight, firstId, count: messages.length };
97
+ }, [messages, scrollRef]);
98
+ };
99
+ var useLoadMoreOnScrollTop = (scrollRef, {
100
+ hasMore,
101
+ loadingMore,
102
+ onLoadMore
103
+ }, thresholdPx = 80) => {
104
+ const armed = _react.useRef.call(void 0, true);
105
+ return _react.useCallback.call(void 0, () => {
106
+ const node = scrollRef.current;
107
+ if (!node) return;
108
+ if (node.scrollTop > thresholdPx) {
109
+ armed.current = true;
110
+ return;
111
+ }
112
+ if (!armed.current || !hasMore || loadingMore || !onLoadMore) return;
113
+ armed.current = false;
114
+ onLoadMore();
115
+ }, [scrollRef, hasMore, loadingMore, onLoadMore, thresholdPx]);
116
+ };
117
+ var useAutoGrow = (ref, value, maxHeight = 200) => {
118
+ _react.useLayoutEffect.call(void 0, () => {
119
+ const node = ref.current;
120
+ if (!node) return;
121
+ node.style.height = "auto";
122
+ const next = Math.min(node.scrollHeight, maxHeight);
123
+ node.style.height = `${next}px`;
124
+ node.style.overflowY = node.scrollHeight > maxHeight ? "auto" : "hidden";
125
+ }, [ref, value, maxHeight]);
126
+ };
127
+
128
+ // src/components/Conversation/Conversation.utils.ts
129
+ var timeFormat = new Intl.DateTimeFormat(void 0, {
130
+ hour: "2-digit",
131
+ minute: "2-digit"
132
+ });
133
+ var dateFormat = new Intl.DateTimeFormat(void 0, {
134
+ day: "numeric",
135
+ month: "long",
136
+ year: "numeric"
137
+ });
138
+ var dateFormatSameYear = new Intl.DateTimeFormat(void 0, {
139
+ day: "numeric",
140
+ month: "long"
141
+ });
142
+ var parseDate = (iso) => {
143
+ const date = new Date(iso);
144
+ return Number.isNaN(date.getTime()) ? null : date;
145
+ };
146
+ var formatMessageTime = (iso) => {
147
+ const date = parseDate(iso);
148
+ return date ? timeFormat.format(date) : iso;
149
+ };
150
+ var startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
151
+ var isSameDay = (a, b) => {
152
+ const first = parseDate(a);
153
+ const second = parseDate(b);
154
+ if (!first || !second) return false;
155
+ return startOfDay(first) === startOfDay(second);
156
+ };
157
+ var formatDateSeparator = (iso) => {
158
+ const date = parseDate(iso);
159
+ if (!date) return iso;
160
+ const now = /* @__PURE__ */ new Date();
161
+ const dayDelta = Math.round((startOfDay(now) - startOfDay(date)) / 864e5);
162
+ if (dayDelta === 0) return "Today";
163
+ if (dayDelta === 1) return "Yesterday";
164
+ return date.getFullYear() === now.getFullYear() ? dateFormatSameYear.format(date) : dateFormat.format(date);
165
+ };
166
+ var FILE_UNITS = ["B", "KB", "MB", "GB", "TB"];
167
+ var formatFileSize = (bytes) => {
168
+ if (!Number.isFinite(bytes) || bytes < 0) return "";
169
+ if (bytes < 1024) return `${bytes} B`;
170
+ let value = bytes;
171
+ let unit = 0;
172
+ while (value >= 1024 && unit < FILE_UNITS.length - 1) {
173
+ value /= 1024;
174
+ unit += 1;
175
+ }
176
+ return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${FILE_UNITS[unit]}`;
177
+ };
178
+ var continuesRun = (previous, message, windowMinutes) => {
179
+ if (!previous) return false;
180
+ if (previous.author.id !== message.author.id) return false;
181
+ if (!isSameDay(previous.sentAt, message.sentAt)) return false;
182
+ const before = parseDate(previous.sentAt);
183
+ const after = parseDate(message.sentAt);
184
+ if (!before || !after) return false;
185
+ return Math.abs(after.getTime() - before.getTime()) <= windowMinutes * 6e4;
186
+ };
187
+ var sortBySentAt = (messages) => [...messages].sort((a, b) => {
188
+ const first = _nullishCoalesce(_optionalChain([parseDate, 'call', _7 => _7(a.sentAt), 'optionalAccess', _8 => _8.getTime, 'call', _9 => _9()]), () => ( 0));
189
+ const second = _nullishCoalesce(_optionalChain([parseDate, 'call', _10 => _10(b.sentAt), 'optionalAccess', _11 => _11.getTime, 'call', _12 => _12()]), () => ( 0));
190
+ return first - second;
191
+ });
192
+ var buildThread = (messages) => {
193
+ const byId = new Map(messages.map((message) => [message.id, message]));
194
+ const rootIdOf = (message) => {
195
+ const seen = /* @__PURE__ */ new Set([message.id]);
196
+ let current = message;
197
+ while (current.parentId) {
198
+ const parent = byId.get(current.parentId);
199
+ if (!parent || seen.has(parent.id)) break;
200
+ seen.add(parent.id);
201
+ current = parent;
202
+ }
203
+ return current.id;
204
+ };
205
+ const nodes = /* @__PURE__ */ new Map();
206
+ const roots = [];
207
+ for (const message of messages) {
208
+ if (message.parentId && byId.has(message.parentId)) continue;
209
+ const node = { message, replies: [] };
210
+ nodes.set(message.id, node);
211
+ roots.push(node);
212
+ }
213
+ for (const message of messages) {
214
+ if (!message.parentId || !byId.has(message.parentId)) continue;
215
+ _optionalChain([nodes, 'access', _13 => _13.get, 'call', _14 => _14(rootIdOf(message)), 'optionalAccess', _15 => _15.replies, 'access', _16 => _16.push, 'call', _17 => _17(message)]);
216
+ }
217
+ for (const node of nodes.values()) {
218
+ node.replies = sortBySentAt(node.replies);
219
+ }
220
+ return roots;
221
+ };
222
+ var replyTargetName = (message, byId, rootId) => {
223
+ if (!message.parentId || message.parentId === rootId) return void 0;
224
+ return _optionalChain([byId, 'access', _18 => _18.get, 'call', _19 => _19(message.parentId), 'optionalAccess', _20 => _20.author, 'access', _21 => _21.name]);
225
+ };
226
+ var excerpt = (body, maxLength = 120) => {
227
+ const flat = body.replace(/\s+/g, " ").trim();
228
+ return flat.length > maxLength ? `${flat.slice(0, maxLength - 1)}\u2026` : flat;
229
+ };
230
+ var classNames = (...values) => values.filter(Boolean).join(" ");
231
+
232
+ // src/components/Conversation/MessageComposer.component.tsx
233
+ var _jsxruntime = require('react/jsx-runtime');
234
+ var MessageComposer = ({
235
+ value,
236
+ onChange,
237
+ onSubmit,
238
+ onCancel,
239
+ placeholder = "Write a message...",
240
+ submitLabel = "Send",
241
+ sendOnEnter = false,
242
+ parentId,
243
+ replyingTo,
244
+ allowAttachments = false,
245
+ attachmentAccept,
246
+ author,
247
+ disabled = false,
248
+ requireBody = true,
249
+ autoFocus = false,
250
+ maxLength,
251
+ className = ""
252
+ }) => {
253
+ const [internalBody, setInternalBody] = _react.useState.call(void 0, "");
254
+ const [attachments, setAttachments] = _react.useState.call(void 0, []);
255
+ const [pending, setPending] = _react.useState.call(void 0, false);
256
+ const textareaRef = _react.useRef.call(void 0, null);
257
+ const fileInputRef = _react.useRef.call(void 0, null);
258
+ const fileInputId = _react.useId.call(void 0, );
259
+ const isControlled = value !== void 0;
260
+ const body = isControlled ? value : internalBody;
261
+ useAutoGrow(textareaRef, body);
262
+ const setBody = _react.useCallback.call(void 0,
263
+ (next) => {
264
+ if (!isControlled) setInternalBody(next);
265
+ _optionalChain([onChange, 'optionalCall', _22 => _22(next)]);
266
+ },
267
+ [isControlled, onChange]
268
+ );
269
+ const canSubmit = !disabled && !pending && (!requireBody || body.trim().length > 0);
270
+ const submit = _react.useCallback.call(void 0, async () => {
271
+ if (!canSubmit) return;
272
+ const draft = { body: body.trim(), attachments, parentId };
273
+ const result = onSubmit(draft);
274
+ if (!(result instanceof Promise)) {
275
+ setBody("");
276
+ setAttachments([]);
277
+ return;
278
+ }
279
+ setPending(true);
280
+ try {
281
+ await result;
282
+ setBody("");
283
+ setAttachments([]);
284
+ } catch (e) {
285
+ } finally {
286
+ setPending(false);
287
+ }
288
+ }, [canSubmit, body, attachments, parentId, onSubmit, setBody]);
289
+ const handleKeyDown = (event) => {
290
+ if (!sendOnEnter) return;
291
+ if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
292
+ event.preventDefault();
293
+ void submit();
294
+ };
295
+ const addFiles = (list) => {
296
+ if (!_optionalChain([list, 'optionalAccess', _23 => _23.length])) return;
297
+ setAttachments((current) => [...current, ...Array.from(list)]);
298
+ if (fileInputRef.current) fileInputRef.current.value = "";
299
+ };
300
+ const removeAttachment = (index) => setAttachments((current) => current.filter((_, i) => i !== index));
301
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
302
+ "form",
303
+ {
304
+ className: classNames("eidos-message-composer", className),
305
+ onSubmit: (event) => {
306
+ event.preventDefault();
307
+ void submit();
308
+ },
309
+ children: [
310
+ replyingTo && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-reply-hint", children: [
311
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { children: [
312
+ "Replying to ",
313
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: replyingTo })
314
+ ] }),
315
+ onCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
316
+ _chunkWWYJNWJYcjs.Button,
317
+ {
318
+ variant: "text",
319
+ color: "secondary",
320
+ size: "sm",
321
+ icon: _lucidereact.X,
322
+ onClick: onCancel,
323
+ tooltip: "Cancel reply",
324
+ "aria-label": "Cancel reply"
325
+ }
326
+ )
327
+ ] }),
328
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-row", children: [
329
+ author && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-composer-avatar", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
330
+ _chunkQ3GNKF74cjs.Avatar,
331
+ {
332
+ src: author.avatarSrc,
333
+ name: author.name,
334
+ size: "sm",
335
+ color: _nullishCoalesce(author.avatarColor, () => ( "gray"))
336
+ }
337
+ ) }),
338
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-field", children: [
339
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
340
+ "textarea",
341
+ {
342
+ ref: textareaRef,
343
+ className: "eidos-composer-input",
344
+ value: body,
345
+ onChange: (event) => setBody(event.target.value),
346
+ onKeyDown: handleKeyDown,
347
+ placeholder,
348
+ disabled: disabled || pending,
349
+ rows: 1,
350
+ maxLength,
351
+ autoFocus,
352
+ "aria-label": placeholder
353
+ }
354
+ ),
355
+ attachments.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-composer-attachments", children: attachments.map((file, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
356
+ _chunkNEYLNRVGcjs.Chip,
357
+ {
358
+ size: "sm",
359
+ variant: "outlined",
360
+ color: "secondary",
361
+ preIcon: _lucidereact.Paperclip,
362
+ onRemove: () => removeAttachment(index),
363
+ children: [
364
+ file.name,
365
+ file.size > 0 && ` (${formatFileSize(file.size)})`
366
+ ]
367
+ }
368
+ ) }, `${file.name}-${file.size}-${index}`)) })
369
+ ] })
370
+ ] }),
371
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-actions", children: [
372
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-actions-start", children: [
373
+ allowAttachments && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
374
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
375
+ "input",
376
+ {
377
+ ref: fileInputRef,
378
+ id: fileInputId,
379
+ type: "file",
380
+ multiple: true,
381
+ accept: attachmentAccept,
382
+ className: "eidos-composer-file-input",
383
+ onChange: (event) => addFiles(event.target.files),
384
+ disabled: disabled || pending
385
+ }
386
+ ),
387
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
388
+ _chunkWWYJNWJYcjs.Button,
389
+ {
390
+ variant: "text",
391
+ color: "secondary",
392
+ size: "sm",
393
+ icon: _lucidereact.Paperclip,
394
+ tooltip: "Attach files",
395
+ "aria-label": "Attach files",
396
+ disabled: disabled || pending,
397
+ onClick: () => _optionalChain([fileInputRef, 'access', _24 => _24.current, 'optionalAccess', _25 => _25.click, 'call', _26 => _26()])
398
+ }
399
+ )
400
+ ] }),
401
+ sendOnEnter && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-composer-hint", children: [
402
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "kbd", { children: "Enter" }),
403
+ " to send \xB7 ",
404
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "kbd", { children: "Shift" }),
405
+ "+",
406
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "kbd", { children: "Enter" }),
407
+ " for a new line"
408
+ ] })
409
+ ] }),
410
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-composer-actions-end", children: [
411
+ onCancel && !replyingTo && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
412
+ _chunkWWYJNWJYcjs.Button,
413
+ {
414
+ variant: "text",
415
+ color: "secondary",
416
+ size: "sm",
417
+ onClick: onCancel,
418
+ disabled: pending,
419
+ children: "Cancel"
420
+ }
421
+ ),
422
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
423
+ _chunkWWYJNWJYcjs.Button,
424
+ {
425
+ type: "submit",
426
+ size: "sm",
427
+ color: "primary",
428
+ preIcon: _lucidereact.Send,
429
+ loading: pending,
430
+ disabled: !canSubmit,
431
+ children: submitLabel
432
+ }
433
+ )
434
+ ] })
435
+ ] })
436
+ ]
437
+ }
438
+ );
439
+ };
440
+ MessageComposer.displayName = "MessageComposer";
441
+
442
+ // src/components/Conversation/MessageItem.component.tsx
443
+
444
+
445
+ var AttachmentList = ({ attachments }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-message-attachments", children: attachments.map((attachment) => {
446
+ const label = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
447
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Paperclip, { "aria-hidden": "true" }),
448
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-attachment-name", children: attachment.name }),
449
+ attachment.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-attachment-size", children: formatFileSize(attachment.size) })
450
+ ] });
451
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-message-attachment", children: attachment.url ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
452
+ "a",
453
+ {
454
+ href: attachment.url,
455
+ className: "eidos-message-attachment-link",
456
+ target: "_blank",
457
+ rel: "noreferrer",
458
+ download: attachment.name,
459
+ children: label
460
+ }
461
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-attachment-link", children: label }) }, attachment.id);
462
+ }) });
463
+ var MessageItem = ({
464
+ message,
465
+ layout,
466
+ isOwn,
467
+ grouped,
468
+ isNew,
469
+ actions,
470
+ footer,
471
+ body,
472
+ onRetry,
473
+ replyingToName,
474
+ quoted,
475
+ onReply,
476
+ formatTimestamp
477
+ }) => {
478
+ const { author, status = "sent" } = message;
479
+ const timestamp = formatTimestamp ? formatTimestamp(message.sentAt) : formatMessageTime(message.sentAt);
480
+ const hasActions = Boolean(actions && actions.length > 0);
481
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
482
+ "li",
483
+ {
484
+ className: classNames(
485
+ "eidos-message",
486
+ `eidos-message--${layout}`,
487
+ isOwn && "eidos-message--own",
488
+ grouped && "eidos-message--grouped",
489
+ status !== "sent" && `eidos-message--${status}`,
490
+ isNew && "eidos-message--enter"
491
+ ),
492
+ "data-message-id": message.id,
493
+ children: [
494
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-message-avatar", children: !grouped && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
495
+ _chunkQ3GNKF74cjs.Avatar,
496
+ {
497
+ src: author.avatarSrc,
498
+ name: author.name,
499
+ size: "sm",
500
+ color: _nullishCoalesce(author.avatarColor, () => ( "gray"))
501
+ }
502
+ ) }),
503
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-message-main", children: [
504
+ !grouped && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-message-header", children: [
505
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-author", children: author.name }),
506
+ author.role && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEQ6BNPTLcjs.Pill, { size: "sm", variant: "outlined", color: "secondary", children: author.role }),
507
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "time", { className: "eidos-message-time", dateTime: message.sentAt, children: timestamp }),
508
+ message.edited && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-edited", children: "edited" })
509
+ ] }),
510
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-message-bubble", children: [
511
+ quoted && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "blockquote", { className: "eidos-message-quote", children: [
512
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-quote-author", children: quoted.author.name }),
513
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-message-quote-body", children: excerpt(quoted.body) })
514
+ ] }),
515
+ replyingToName && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-message-reply-target", children: [
516
+ "Replying to ",
517
+ replyingToName
518
+ ] }),
519
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-message-body", children: _nullishCoalesce(body, () => ( message.body)) }),
520
+ message.attachments && message.attachments.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AttachmentList, { attachments: message.attachments }),
521
+ grouped && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
522
+ "time",
523
+ {
524
+ className: "eidos-message-time eidos-message-time--inline",
525
+ dateTime: message.sentAt,
526
+ children: timestamp
527
+ }
528
+ )
529
+ ] }),
530
+ status === "sending" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-message-status", children: [
531
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkTROYIUDHcjs.Spinner, { size: "sm", color: "secondary" }),
532
+ "Sending\u2026"
533
+ ] }),
534
+ status === "failed" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-message-status eidos-message-status--failed", children: [
535
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { "aria-hidden": "true" }),
536
+ "Not sent",
537
+ onRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { variant: "text", color: "danger", size: "sm", preIcon: _lucidereact.RotateCw, onClick: onRetry, children: "Retry" })
538
+ ] }),
539
+ footer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-message-footer", children: footer }),
540
+ onReply && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-message-reply", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { variant: "text", color: "secondary", size: "sm", onClick: onReply, children: "Reply" }) })
541
+ ] }),
542
+ hasActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-message-actions", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
543
+ _chunkD2SKXRKPcjs.Menu,
544
+ {
545
+ items: _nullishCoalesce(actions, () => ( [])),
546
+ trigger: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
547
+ _chunkWWYJNWJYcjs.Button,
548
+ {
549
+ variant: "text",
550
+ color: "secondary",
551
+ size: "sm",
552
+ icon: _lucidereact.MoreHorizontal,
553
+ "aria-label": `Actions for ${author.name}'s message`
554
+ }
555
+ )
556
+ }
557
+ ) })
558
+ ]
559
+ }
560
+ );
561
+ };
562
+ MessageItem.displayName = "MessageItem";
563
+
564
+ // src/components/Conversation/Chat.component.tsx
565
+
566
+ var ChatSkeleton = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-chat-skeleton", "aria-hidden": "true", children: [0, 1, 2, 3].map((row) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
567
+ "div",
568
+ {
569
+ className: classNames(
570
+ "eidos-chat-skeleton-row",
571
+ row % 2 === 1 && "eidos-chat-skeleton-row--own"
572
+ ),
573
+ children: [
574
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIYWAZEFIcjs.Skeleton, { variant: "circular", width: 28, height: 28 }),
575
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIYWAZEFIcjs.Skeleton, { variant: "rounded", height: 48 })
576
+ ]
577
+ },
578
+ row
579
+ )) });
580
+ var Chat = ({
581
+ messages,
582
+ currentUserId,
583
+ onSend,
584
+ onRetry,
585
+ readOnly = false,
586
+ readOnlyMessage,
587
+ renderBody,
588
+ messageActions,
589
+ renderMessageFooter,
590
+ loading = false,
591
+ emptyContent,
592
+ hasMore = false,
593
+ loadingMore = false,
594
+ onLoadMore,
595
+ groupConsecutive = true,
596
+ groupWindowMinutes = 5,
597
+ showDateSeparators = true,
598
+ formatTimestamp,
599
+ animateNewMessages = true,
600
+ allowAttachments = false,
601
+ attachmentAccept,
602
+ typing,
603
+ unreadFromId,
604
+ placeholder = "Write a message...",
605
+ sendOnEnter = true,
606
+ ariaLabel = "Conversation",
607
+ className = ""
608
+ }) => {
609
+ const { scrollRef, atBottom, scrollToBottom, handleScroll } = useStickToBottom(messages);
610
+ const newIds = useNewMessageIds(messages, animateNewMessages);
611
+ useScrollAnchor(scrollRef, messages);
612
+ const loadMoreOnScroll = useLoadMoreOnScrollTop(scrollRef, { hasMore, loadingMore, onLoadMore });
613
+ const onScroll = _react.useCallback.call(void 0, () => {
614
+ handleScroll();
615
+ loadMoreOnScroll();
616
+ }, [handleScroll, loadMoreOnScroll]);
617
+ const byId = _react.useMemo.call(void 0, () => new Map(messages.map((message) => [message.id, message])), [messages]);
618
+ const unreadIndex = _react.useMemo.call(void 0, () => {
619
+ if (!unreadFromId) return -1;
620
+ return messages.findIndex((message) => message.id === unreadFromId);
621
+ }, [messages, unreadFromId]);
622
+ const showComposer = !readOnly && Boolean(onSend);
623
+ const isEmpty = !loading && messages.length === 0;
624
+ const renderMessage = (message, index) => {
625
+ const previous = messages[index - 1];
626
+ const actions = readOnly ? void 0 : _optionalChain([messageActions, 'optionalCall', _27 => _27(message)]);
627
+ const quoted = message.parentId ? byId.get(message.parentId) : void 0;
628
+ const nodes = [];
629
+ if (showDateSeparators && (!previous || !isSameDay(previous.sentAt, message.sentAt))) {
630
+ nodes.push(
631
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-conversation-separator", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: formatDateSeparator(message.sentAt) }) }, `date-${message.id}`)
632
+ );
633
+ }
634
+ if (index === unreadIndex) {
635
+ nodes.push(
636
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
637
+ "li",
638
+ {
639
+ className: "eidos-conversation-separator eidos-conversation-separator--unread",
640
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Unread messages" })
641
+ },
642
+ `unread-${message.id}`
643
+ )
644
+ );
645
+ }
646
+ const grouped = groupConsecutive && index !== unreadIndex && nodes.length === 0 && continuesRun(previous, message, groupWindowMinutes);
647
+ nodes.push(
648
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
649
+ MessageItem,
650
+ {
651
+ message,
652
+ layout: "chat",
653
+ isOwn: Boolean(currentUserId) && message.author.id === currentUserId,
654
+ grouped,
655
+ isNew: newIds.has(message.id),
656
+ actions,
657
+ footer: _optionalChain([renderMessageFooter, 'optionalCall', _28 => _28(message)]),
658
+ body: _optionalChain([renderBody, 'optionalCall', _29 => _29(message)]),
659
+ onRetry: !readOnly && onRetry ? () => onRetry(message) : void 0,
660
+ quoted,
661
+ formatTimestamp
662
+ },
663
+ message.id
664
+ )
665
+ );
666
+ return nodes;
667
+ };
668
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: classNames("eidos-chat", className), children: [
669
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
670
+ "div",
671
+ {
672
+ ref: scrollRef,
673
+ className: "eidos-chat-scroll",
674
+ onScroll,
675
+ role: "log",
676
+ "aria-live": "polite",
677
+ "aria-relevant": "additions",
678
+ "aria-busy": loading,
679
+ "aria-label": ariaLabel,
680
+ tabIndex: 0,
681
+ children: [
682
+ hasMore && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-chat-load-more", children: loadingMore ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-chat-loading-more", children: [
683
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkTROYIUDHcjs.Spinner, { size: "sm", color: "secondary" }),
684
+ "Loading earlier messages\u2026"
685
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { variant: "text", color: "secondary", size: "sm", onClick: onLoadMore, children: "Load earlier messages" }) }),
686
+ loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChatSkeleton, {}),
687
+ isEmpty && (_nullishCoalesce(emptyContent, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
688
+ _chunkKV3V2CPHcjs.EmptyState,
689
+ {
690
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.MessagesSquare, {}),
691
+ title: "No messages yet",
692
+ description: showComposer ? "Send the first message to start the conversation." : void 0,
693
+ size: "sm"
694
+ }
695
+ )))),
696
+ !loading && messages.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "eidos-conversation-list", children: messages.map(renderMessage) }),
697
+ typing && typing.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-chat-typing", "aria-live": "polite", children: [
698
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-chat-typing-dots", "aria-hidden": "true", children: [
699
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "i", {}),
700
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "i", {}),
701
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "i", {})
702
+ ] }),
703
+ typing.length === 1 ? `${typing[0].name} is typing\u2026` : `${typing.length} people are typing\u2026`
704
+ ] })
705
+ ]
706
+ }
707
+ ),
708
+ !atBottom && messages.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-chat-jump", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
709
+ _chunkWWYJNWJYcjs.Button,
710
+ {
711
+ size: "sm",
712
+ variant: "filled",
713
+ color: "secondary",
714
+ preIcon: _lucidereact.ArrowDown,
715
+ onClick: () => scrollToBottom("smooth"),
716
+ children: "Latest"
717
+ }
718
+ ) }),
719
+ showComposer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-chat-composer", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
720
+ MessageComposer,
721
+ {
722
+ onSubmit: onSend,
723
+ placeholder,
724
+ sendOnEnter,
725
+ allowAttachments,
726
+ attachmentAccept
727
+ }
728
+ ) }),
729
+ readOnly && readOnlyMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "eidos-conversation-readonly", children: readOnlyMessage })
730
+ ] });
731
+ };
732
+ Chat.displayName = "Chat";
733
+
734
+ // src/components/Conversation/CommentThread.component.tsx
735
+
736
+
737
+
738
+ var CommentSkeleton = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-comment-thread-skeleton", "aria-hidden": "true", children: [0, 1, 2].map((row) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-comment-thread-skeleton-row", children: [
739
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIYWAZEFIcjs.Skeleton, { variant: "circular", width: 28, height: 28 }),
740
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIYWAZEFIcjs.Skeleton, { variant: "text", lines: 2 })
741
+ ] }, row)) });
742
+ var CommentThread = ({
743
+ messages,
744
+ currentUserId,
745
+ onSend,
746
+ onReply,
747
+ onRetry,
748
+ readOnly = false,
749
+ readOnlyMessage,
750
+ renderBody,
751
+ messageActions,
752
+ renderMessageFooter,
753
+ loading = false,
754
+ emptyContent,
755
+ hasMore = false,
756
+ loadingMore = false,
757
+ onLoadMore,
758
+ groupConsecutive = true,
759
+ groupWindowMinutes = 5,
760
+ formatTimestamp,
761
+ animateNewMessages = true,
762
+ allowAttachments = false,
763
+ attachmentAccept,
764
+ order = "oldest-first",
765
+ composerPosition = "bottom",
766
+ placeholder = "Add a comment...",
767
+ sendOnEnter = false,
768
+ title,
769
+ ariaLabel = "Comments",
770
+ className = ""
771
+ }) => {
772
+ const [replyingToId, setReplyingToId] = _react.useState.call(void 0, null);
773
+ const newIds = useNewMessageIds(messages, animateNewMessages);
774
+ const byId = _react.useMemo.call(void 0, () => new Map(messages.map((message) => [message.id, message])), [messages]);
775
+ const roots = _react.useMemo.call(void 0, () => {
776
+ const thread = buildThread(messages);
777
+ const sorted = sortBySentAt(thread.map((node) => node.message));
778
+ const ordered = order === "newest-first" ? [...sorted].reverse() : sorted;
779
+ const nodeById = new Map(thread.map((node) => [node.message.id, node]));
780
+ return ordered.map((message) => nodeById.get(message.id));
781
+ }, [messages, order]);
782
+ const canReply = !readOnly && Boolean(onReply);
783
+ const showComposer = !readOnly && Boolean(onSend);
784
+ const isEmpty = !loading && messages.length === 0;
785
+ const total = messages.length;
786
+ const handleReply = _react.useCallback.call(void 0,
787
+ async (draft) => {
788
+ await _optionalChain([onReply, 'optionalCall', _30 => _30(draft)]);
789
+ setReplyingToId(null);
790
+ },
791
+ [onReply]
792
+ );
793
+ const renderComment = (message, options) => {
794
+ const actions = readOnly ? void 0 : _optionalChain([messageActions, 'optionalCall', _31 => _31(message)]);
795
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
796
+ MessageItem,
797
+ {
798
+ message,
799
+ layout: "comment",
800
+ isOwn: Boolean(currentUserId) && message.author.id === currentUserId,
801
+ grouped: groupConsecutive && continuesRun(options.previous, message, groupWindowMinutes),
802
+ isNew: newIds.has(message.id),
803
+ actions,
804
+ footer: _optionalChain([renderMessageFooter, 'optionalCall', _32 => _32(message)]),
805
+ body: _optionalChain([renderBody, 'optionalCall', _33 => _33(message)]),
806
+ onRetry: !readOnly && onRetry ? () => onRetry(message) : void 0,
807
+ replyingToName: options.isReply ? replyTargetName(message, byId, options.rootId) : void 0,
808
+ onReply: canReply ? () => setReplyingToId(message.id) : void 0,
809
+ formatTimestamp
810
+ },
811
+ message.id
812
+ );
813
+ };
814
+ const composer = showComposer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
815
+ MessageComposer,
816
+ {
817
+ onSubmit: onSend,
818
+ placeholder,
819
+ submitLabel: "Comment",
820
+ sendOnEnter,
821
+ allowAttachments,
822
+ attachmentAccept,
823
+ className: "eidos-comment-thread-composer"
824
+ }
825
+ );
826
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { className: classNames("eidos-comment-thread", className), "aria-label": ariaLabel, children: [
827
+ (title || total > 0) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "header", { className: "eidos-comment-thread-header", children: [
828
+ title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "eidos-comment-thread-title", children: title }),
829
+ total > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-comment-thread-count", children: [
830
+ total,
831
+ " ",
832
+ total === 1 ? "comment" : "comments"
833
+ ] })
834
+ ] }),
835
+ composerPosition === "top" && composer,
836
+ loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommentSkeleton, {}),
837
+ isEmpty && (_nullishCoalesce(emptyContent, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
838
+ _chunkKV3V2CPHcjs.EmptyState,
839
+ {
840
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.MessageSquare, {}),
841
+ title: "No comments yet",
842
+ description: showComposer ? "Start the discussion by leaving a comment." : void 0,
843
+ size: "sm"
844
+ }
845
+ )))),
846
+ !loading && roots.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "eidos-conversation-list eidos-comment-thread-list", "aria-busy": loadingMore, children: roots.map((node) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "eidos-comment-thread-node", children: [
847
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "eidos-conversation-list", children: renderComment(node.message, { rootId: node.message.id, isReply: false }) }),
848
+ node.replies.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "eidos-conversation-list eidos-comment-thread-replies", children: node.replies.map(
849
+ (reply, index) => renderComment(reply, {
850
+ rootId: node.message.id,
851
+ previous: node.replies[index - 1],
852
+ isReply: true
853
+ })
854
+ ) }),
855
+ replyingToId && (replyingToId === node.message.id || node.replies.some((reply) => reply.id === replyingToId)) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-comment-thread-reply-composer", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
856
+ MessageComposer,
857
+ {
858
+ onSubmit: handleReply,
859
+ onCancel: () => setReplyingToId(null),
860
+ parentId: replyingToId,
861
+ replyingTo: _optionalChain([byId, 'access', _34 => _34.get, 'call', _35 => _35(replyingToId), 'optionalAccess', _36 => _36.author, 'access', _37 => _37.name]),
862
+ placeholder: "Write a reply...",
863
+ submitLabel: "Reply",
864
+ sendOnEnter,
865
+ allowAttachments,
866
+ attachmentAccept,
867
+ autoFocus: true
868
+ }
869
+ ) })
870
+ ] }, node.message.id)) }),
871
+ hasMore && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-comment-thread-load-more", children: loadingMore ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-comment-thread-loading-more", children: [
872
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkTROYIUDHcjs.Spinner, { size: "sm", color: "secondary" }),
873
+ "Loading more comments\u2026"
874
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { variant: "outlined", color: "secondary", size: "sm", onClick: onLoadMore, children: "Load more comments" }) }),
875
+ composerPosition === "bottom" && composer,
876
+ readOnly && readOnlyMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "eidos-conversation-readonly", children: readOnlyMessage })
877
+ ] });
878
+ };
879
+ CommentThread.displayName = "CommentThread";
880
+
881
+
882
+
883
+
884
+
885
+ exports.MessageComposer = MessageComposer; exports.Chat = Chat; exports.CommentThread = CommentThread;
886
+ //# sourceMappingURL=chunk-R3WPVTGY.cjs.map