eidos-ui 1.0.0 → 1.0.2

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 (509) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +227 -175
  3. package/dist/accordion/index.cjs +2 -2
  4. package/dist/accordion/index.cjs.map +1 -1
  5. package/dist/accordion/index.js +1 -1
  6. package/dist/alert/index.cjs +5 -5
  7. package/dist/alert/index.cjs.map +1 -1
  8. package/dist/alert/index.js +4 -4
  9. package/dist/avatar/index.cjs +2 -2
  10. package/dist/avatar/index.cjs.map +1 -1
  11. package/dist/avatar/index.js +1 -1
  12. package/dist/badge/index.cjs.map +1 -1
  13. package/dist/breadcrumb/index.cjs +2 -2
  14. package/dist/breadcrumb/index.cjs.map +1 -1
  15. package/dist/breadcrumb/index.js +1 -1
  16. package/dist/button/index.cjs +4 -4
  17. package/dist/button/index.cjs.map +1 -1
  18. package/dist/button/index.js +3 -3
  19. package/dist/button-group/index.cjs +2 -2
  20. package/dist/button-group/index.cjs.map +1 -1
  21. package/dist/button-group/index.js +1 -1
  22. package/dist/card/index.cjs +2 -2
  23. package/dist/card/index.cjs.map +1 -1
  24. package/dist/card/index.js +1 -1
  25. package/dist/checkbox/index.cjs +2 -2
  26. package/dist/checkbox/index.cjs.map +1 -1
  27. package/dist/checkbox/index.js +1 -1
  28. package/dist/chip/index.cjs +4 -4
  29. package/dist/chip/index.cjs.map +1 -1
  30. package/dist/chip/index.js +3 -3
  31. package/dist/{chunk-OHUVWPFJ.js → chunk-2BC4M4QZ.js} +1 -1
  32. package/dist/chunk-2BC4M4QZ.js.map +1 -0
  33. package/dist/{chunk-OT3VZLN4.js → chunk-2BXCIWL7.js} +3 -3
  34. package/dist/chunk-2BXCIWL7.js.map +1 -0
  35. package/dist/{chunk-6QFT3BUD.cjs → chunk-2ROKOO22.cjs} +1 -1
  36. package/dist/chunk-2ROKOO22.cjs.map +1 -0
  37. package/dist/{chunk-AOV32YBE.js → chunk-2RXQMQYW.js} +1 -1
  38. package/dist/chunk-2RXQMQYW.js.map +1 -0
  39. package/dist/{chunk-VYV45YOK.cjs → chunk-2U7UJOOB.cjs} +17 -17
  40. package/dist/chunk-2U7UJOOB.cjs.map +1 -0
  41. package/dist/{chunk-UTENJWSE.cjs → chunk-366R4GKR.cjs} +1 -1
  42. package/dist/chunk-366R4GKR.cjs.map +1 -0
  43. package/dist/{chunk-TQCNQKWF.cjs → chunk-3CXULV4G.cjs} +1 -1
  44. package/dist/chunk-3CXULV4G.cjs.map +1 -0
  45. package/dist/{chunk-PEPYVWGY.cjs → chunk-3EPND5M2.cjs} +3 -3
  46. package/dist/chunk-3EPND5M2.cjs.map +1 -0
  47. package/dist/chunk-3ETWFS2N.cjs.map +1 -1
  48. package/dist/{chunk-GL4DHGQE.js → chunk-3HMKE2GJ.js} +5 -5
  49. package/dist/chunk-3HMKE2GJ.js.map +1 -0
  50. package/dist/{chunk-QYHTMEI5.js → chunk-3LBWAUCR.js} +1 -1
  51. package/dist/chunk-3LBWAUCR.js.map +1 -0
  52. package/dist/{chunk-E2B33QB7.js → chunk-3LHQUOGP.js} +4 -4
  53. package/dist/chunk-3LHQUOGP.js.map +1 -0
  54. package/dist/chunk-3RUIKBH4.cjs.map +1 -1
  55. package/dist/{chunk-DK4S3EHG.js → chunk-3TUCQAYL.js} +1 -1
  56. package/dist/chunk-3TUCQAYL.js.map +1 -0
  57. package/dist/{chunk-BBOUUHLO.js → chunk-3VRMTWUS.js} +5 -5
  58. package/dist/chunk-3VRMTWUS.js.map +1 -0
  59. package/dist/{chunk-SXF3TCYA.js → chunk-4BKTBV2I.js} +1 -1
  60. package/dist/chunk-4BKTBV2I.js.map +1 -0
  61. package/dist/{chunk-P74HNSNJ.cjs → chunk-4BQM5F76.cjs} +3 -3
  62. package/dist/chunk-4BQM5F76.cjs.map +1 -0
  63. package/dist/{chunk-Z7S4UQKY.js → chunk-4LM33LDV.js} +2 -2
  64. package/dist/chunk-4LM33LDV.js.map +1 -0
  65. package/dist/{chunk-GRH57M3E.js → chunk-4M3LZLOH.js} +3 -3
  66. package/dist/chunk-4M3LZLOH.js.map +1 -0
  67. package/dist/{chunk-M56IGNH7.cjs → chunk-4UJ7LG4W.cjs} +3 -3
  68. package/dist/chunk-4UJ7LG4W.cjs.map +1 -0
  69. package/dist/{chunk-P6ZBENAG.js → chunk-56B6RLOE.js} +3 -3
  70. package/dist/chunk-56B6RLOE.js.map +1 -0
  71. package/dist/{chunk-XSGUFMT4.js → chunk-5CLC3FJO.js} +1 -1
  72. package/dist/chunk-5CLC3FJO.js.map +1 -0
  73. package/dist/{chunk-VLC2OZV3.cjs → chunk-5O73AALP.cjs} +1 -1
  74. package/dist/chunk-5O73AALP.cjs.map +1 -0
  75. package/dist/{chunk-F54MVGKO.js → chunk-5WROPW7Z.js} +4 -4
  76. package/dist/chunk-5WROPW7Z.js.map +1 -0
  77. package/dist/{chunk-H56YUMFB.cjs → chunk-6A2ZKVST.cjs} +5 -5
  78. package/dist/chunk-6A2ZKVST.cjs.map +1 -0
  79. package/dist/{chunk-CJUZDUXW.cjs → chunk-6RGJAQCU.cjs} +5 -5
  80. package/dist/chunk-6RGJAQCU.cjs.map +1 -0
  81. package/dist/{chunk-P2BTQ33C.cjs → chunk-6U2H26A4.cjs} +4 -4
  82. package/dist/chunk-6U2H26A4.cjs.map +1 -0
  83. package/dist/{chunk-6USUVU6J.js → chunk-6ZAT5CGB.js} +1 -1
  84. package/dist/chunk-6ZAT5CGB.js.map +1 -0
  85. package/dist/{chunk-YKECQKOV.cjs → chunk-7AHZTHXR.cjs} +9 -9
  86. package/dist/chunk-7AHZTHXR.cjs.map +1 -0
  87. package/dist/{chunk-QYK4ECSZ.js → chunk-7HEUWGYW.js} +1 -1
  88. package/dist/chunk-7HEUWGYW.js.map +1 -0
  89. package/dist/{chunk-KF64C4QI.js → chunk-A3NE2C7C.js} +2 -2
  90. package/dist/chunk-A3NE2C7C.js.map +1 -0
  91. package/dist/{chunk-LTOHGCU4.cjs → chunk-A7Z2QAFZ.cjs} +7 -7
  92. package/dist/chunk-A7Z2QAFZ.cjs.map +1 -0
  93. package/dist/{chunk-ICHPPNFV.js → chunk-ALGX5X4N.js} +5 -5
  94. package/dist/chunk-ALGX5X4N.js.map +1 -0
  95. package/dist/{chunk-FNUOTM44.cjs → chunk-AYMD4D4M.cjs} +3 -3
  96. package/dist/chunk-AYMD4D4M.cjs.map +1 -0
  97. package/dist/{chunk-HQ4KZRFH.js → chunk-BOB5JJ7F.js} +3 -3
  98. package/dist/chunk-BOB5JJ7F.js.map +1 -0
  99. package/dist/{chunk-6GAIQ2IY.cjs → chunk-CBLWP43O.cjs} +47 -47
  100. package/dist/chunk-CBLWP43O.cjs.map +1 -0
  101. package/dist/{chunk-BTPCSBGP.js → chunk-CJVC3A4O.js} +2 -2
  102. package/dist/chunk-CJVC3A4O.js.map +1 -0
  103. package/dist/{chunk-ZBGTVTQJ.js → chunk-CMOBXLNA.js} +1 -1
  104. package/dist/chunk-CMOBXLNA.js.map +1 -0
  105. package/dist/{chunk-POX6JZLO.cjs → chunk-DKZTDYH5.cjs} +5 -5
  106. package/dist/chunk-DKZTDYH5.cjs.map +1 -0
  107. package/dist/{chunk-S25WB7KJ.js → chunk-DRXPTACG.js} +1 -1
  108. package/dist/chunk-DRXPTACG.js.map +1 -0
  109. package/dist/chunk-DZUJEN5N.cjs.map +1 -1
  110. package/dist/chunk-EACNRR3C.cjs.map +1 -1
  111. package/dist/{chunk-7IOOFKG3.js → chunk-EF4Y6Q35.js} +1 -1
  112. package/dist/chunk-EF4Y6Q35.js.map +1 -0
  113. package/dist/chunk-EQ6BNPTL.cjs.map +1 -1
  114. package/dist/{chunk-VZ43OLU6.cjs → chunk-EQEV7GPT.cjs} +7 -7
  115. package/dist/chunk-EQEV7GPT.cjs.map +1 -0
  116. package/dist/{chunk-ICJ3SV5I.cjs → chunk-FKXKBJUI.cjs} +1 -1
  117. package/dist/chunk-FKXKBJUI.cjs.map +1 -0
  118. package/dist/{chunk-BFYSYUA6.cjs → chunk-FMPXSF3H.cjs} +11 -11
  119. package/dist/chunk-FMPXSF3H.cjs.map +1 -0
  120. package/dist/chunk-FQZ6F7FQ.cjs.map +1 -1
  121. package/dist/{chunk-KV2FG7AN.cjs → chunk-FRUOA2QU.cjs} +1 -1
  122. package/dist/chunk-FRUOA2QU.cjs.map +1 -0
  123. package/dist/{chunk-CDV2OAS3.cjs → chunk-G5IGADJI.cjs} +7 -7
  124. package/dist/chunk-G5IGADJI.cjs.map +1 -0
  125. package/dist/{chunk-TBMVUI7S.cjs → chunk-GOR642KK.cjs} +1 -1
  126. package/dist/chunk-GOR642KK.cjs.map +1 -0
  127. package/dist/{chunk-XJBMEDQ5.js → chunk-H6CWTMAH.js} +1 -1
  128. package/dist/chunk-H6CWTMAH.js.map +1 -0
  129. package/dist/{chunk-2ZWBN3LK.cjs → chunk-HFZ5FKRG.cjs} +1 -1
  130. package/dist/chunk-HFZ5FKRG.cjs.map +1 -0
  131. package/dist/{chunk-QGZF5MOS.cjs → chunk-HLNKIAE5.cjs} +7 -7
  132. package/dist/chunk-HLNKIAE5.cjs.map +1 -0
  133. package/dist/chunk-I44YNYI6.cjs.map +1 -1
  134. package/dist/chunk-I6UOIS4J.cjs.map +1 -1
  135. package/dist/{chunk-LEZ4HSBD.cjs → chunk-IC2M4N7R.cjs} +34 -34
  136. package/dist/chunk-IC2M4N7R.cjs.map +1 -0
  137. package/dist/{chunk-G2FANEA2.cjs → chunk-IJ4DXG7D.cjs} +1 -1
  138. package/dist/chunk-IJ4DXG7D.cjs.map +1 -0
  139. package/dist/{chunk-SOGUWOSQ.cjs → chunk-IJYYHBZC.cjs} +3 -3
  140. package/dist/chunk-IJYYHBZC.cjs.map +1 -0
  141. package/dist/{chunk-SAFSEXMU.cjs → chunk-ISABZ2VX.cjs} +8 -8
  142. package/dist/chunk-ISABZ2VX.cjs.map +1 -0
  143. package/dist/{chunk-VTAABT55.js → chunk-IV4LM3MB.js} +6 -6
  144. package/dist/chunk-IV4LM3MB.js.map +1 -0
  145. package/dist/{chunk-KO2MKZDW.cjs → chunk-IXZMKIV5.cjs} +1 -1
  146. package/dist/chunk-IXZMKIV5.cjs.map +1 -0
  147. package/dist/{chunk-7KGV6YCG.cjs → chunk-IYWAZEFI.cjs} +1 -1
  148. package/dist/chunk-IYWAZEFI.cjs.map +1 -0
  149. package/dist/{chunk-E3XATJ63.js → chunk-IZBJW37N.js} +6 -6
  150. package/dist/chunk-IZBJW37N.js.map +1 -0
  151. package/dist/{chunk-HO7P6IJO.js → chunk-JC4WLVBG.js} +2 -2
  152. package/dist/chunk-JC4WLVBG.js.map +1 -0
  153. package/dist/{chunk-O6B4KB4D.js → chunk-JMD3P4CY.js} +5 -5
  154. package/dist/chunk-JMD3P4CY.js.map +1 -0
  155. package/dist/{chunk-T56K5IKQ.js → chunk-JV7Z3D3U.js} +2 -2
  156. package/dist/chunk-JV7Z3D3U.js.map +1 -0
  157. package/dist/{chunk-DFADZZ3K.js → chunk-K7IFNKMN.js} +3 -3
  158. package/dist/chunk-K7IFNKMN.js.map +1 -0
  159. package/dist/{chunk-C7F2VFAI.cjs → chunk-KIXFSXIN.cjs} +1 -1
  160. package/dist/chunk-KIXFSXIN.cjs.map +1 -0
  161. package/dist/{chunk-V5JNYS77.cjs → chunk-KV3V2CPH.cjs} +1 -1
  162. package/dist/chunk-KV3V2CPH.cjs.map +1 -0
  163. package/dist/{chunk-5TGBNYZK.cjs → chunk-KVIL4EP4.cjs} +1 -1
  164. package/dist/chunk-KVIL4EP4.cjs.map +1 -0
  165. package/dist/{chunk-PWIA4XQD.js → chunk-LUSLBNSG.js} +1 -1
  166. package/dist/chunk-LUSLBNSG.js.map +1 -0
  167. package/dist/{chunk-73EKJU4G.js → chunk-LYH3EKKQ.js} +1 -1
  168. package/dist/chunk-LYH3EKKQ.js.map +1 -0
  169. package/dist/{chunk-D7PGZ3M3.cjs → chunk-MW2S7PZ7.cjs} +5 -5
  170. package/dist/chunk-MW2S7PZ7.cjs.map +1 -0
  171. package/dist/{chunk-LQ3C3OR2.js → chunk-MZZ4SAFY.js} +1 -1
  172. package/dist/chunk-MZZ4SAFY.js.map +1 -0
  173. package/dist/{chunk-KKOZX64Z.js → chunk-NEQXEVHM.js} +1 -1
  174. package/dist/chunk-NEQXEVHM.js.map +1 -0
  175. package/dist/{chunk-NDLMU6HJ.js → chunk-NFIK3KMT.js} +9 -9
  176. package/dist/chunk-NFIK3KMT.js.map +1 -0
  177. package/dist/{chunk-3YPTYI7R.js → chunk-NQ4L6PYW.js} +1 -1
  178. package/dist/chunk-NQ4L6PYW.js.map +1 -0
  179. package/dist/{chunk-JFA5ABVE.js → chunk-NSITXZBU.js} +1 -1
  180. package/dist/chunk-NSITXZBU.js.map +1 -0
  181. package/dist/{chunk-2YQE26EK.js → chunk-O3I3RBZJ.js} +1 -1
  182. package/dist/chunk-O3I3RBZJ.js.map +1 -0
  183. package/dist/{chunk-O5ZPSZNY.cjs → chunk-OGKD5PLS.cjs} +6 -6
  184. package/dist/chunk-OGKD5PLS.cjs.map +1 -0
  185. package/dist/{chunk-7R7IFWGB.cjs → chunk-OZZHOEN5.cjs} +1 -1
  186. package/dist/chunk-OZZHOEN5.cjs.map +1 -0
  187. package/dist/{chunk-6P4WYB3B.js → chunk-P2GCAVUZ.js} +2 -2
  188. package/dist/chunk-P2GCAVUZ.js.map +1 -0
  189. package/dist/{chunk-L3UPSLJ5.cjs → chunk-PA4IT2XQ.cjs} +19 -19
  190. package/dist/chunk-PA4IT2XQ.cjs.map +1 -0
  191. package/dist/{chunk-N7HX5635.cjs → chunk-PJC7NZUV.cjs} +3 -3
  192. package/dist/chunk-PJC7NZUV.cjs.map +1 -0
  193. package/dist/{chunk-QP2A5ZMK.cjs → chunk-PTBBY4ZX.cjs} +1 -1
  194. package/dist/chunk-PTBBY4ZX.cjs.map +1 -0
  195. package/dist/{chunk-VFYG7GAH.js → chunk-PY2376XI.js} +2 -2
  196. package/dist/chunk-PY2376XI.js.map +1 -0
  197. package/dist/{chunk-R5UNLPQZ.cjs → chunk-Q3GNKF74.cjs} +1 -1
  198. package/dist/chunk-Q3GNKF74.cjs.map +1 -0
  199. package/dist/{chunk-YLKESEHQ.cjs → chunk-QF2RAUPB.cjs} +1 -1
  200. package/dist/chunk-QF2RAUPB.cjs.map +1 -0
  201. package/dist/{chunk-2HTBZGBP.cjs → chunk-QQIALSTX.cjs} +1 -1
  202. package/dist/chunk-QQIALSTX.cjs.map +1 -0
  203. package/dist/{chunk-6HGDQ4BM.js → chunk-S2EICHZK.js} +13 -13
  204. package/dist/chunk-S2EICHZK.js.map +1 -0
  205. package/dist/{chunk-5QG2I3FK.cjs → chunk-S77GR5YQ.cjs} +3 -3
  206. package/dist/chunk-S77GR5YQ.cjs.map +1 -0
  207. package/dist/{chunk-YCUT6NQ4.js → chunk-S7TWEVC3.js} +2 -2
  208. package/dist/chunk-S7TWEVC3.js.map +1 -0
  209. package/dist/{chunk-2JWY36LD.cjs → chunk-SDEKANNL.cjs} +1 -1
  210. package/dist/chunk-SDEKANNL.cjs.map +1 -0
  211. package/dist/{chunk-RSBQNIJZ.js → chunk-SENVA467.js} +1 -1
  212. package/dist/chunk-SENVA467.js.map +1 -0
  213. package/dist/chunk-SJDTFR3I.cjs.map +1 -1
  214. package/dist/chunk-SWPZ3HFY.cjs.map +1 -1
  215. package/dist/{chunk-R36SGSJX.cjs → chunk-TROYIUDH.cjs} +1 -1
  216. package/dist/chunk-TROYIUDH.cjs.map +1 -0
  217. package/dist/{chunk-3KAR5KCS.cjs → chunk-UGMONQGH.cjs} +11 -11
  218. package/dist/chunk-UGMONQGH.cjs.map +1 -0
  219. package/dist/{chunk-CKH36D7H.js → chunk-UTUPJOBY.js} +1 -1
  220. package/dist/chunk-UTUPJOBY.js.map +1 -0
  221. package/dist/{chunk-63N2KZZX.cjs → chunk-V2S6XWIQ.cjs} +1 -1
  222. package/dist/chunk-V2S6XWIQ.cjs.map +1 -0
  223. package/dist/{chunk-G36S5CWN.cjs → chunk-V5RS3JZN.cjs} +1 -1
  224. package/dist/chunk-V5RS3JZN.cjs.map +1 -0
  225. package/dist/chunk-VW32UTUE.cjs.map +1 -1
  226. package/dist/{chunk-4NUZP66U.js → chunk-VZYLJSV5.js} +3 -3
  227. package/dist/chunk-VZYLJSV5.js.map +1 -0
  228. package/dist/{chunk-GOVOQZYN.js → chunk-W2F6WDUX.js} +1 -1
  229. package/dist/chunk-W2F6WDUX.js.map +1 -0
  230. package/dist/{chunk-XMRMCWSQ.js → chunk-W3X3V72Q.js} +3 -3
  231. package/dist/chunk-W3X3V72Q.js.map +1 -0
  232. package/dist/{chunk-AUFCW7QU.cjs → chunk-W6IKHJ76.cjs} +3 -3
  233. package/dist/chunk-W6IKHJ76.cjs.map +1 -0
  234. package/dist/{chunk-A35Y5MRJ.js → chunk-WE5FTQGD.js} +3 -3
  235. package/dist/chunk-WE5FTQGD.js.map +1 -0
  236. package/dist/{chunk-FO5FNTJX.js → chunk-WIE7HDIM.js} +3 -3
  237. package/dist/chunk-WIE7HDIM.js.map +1 -0
  238. package/dist/{chunk-YZOVF7JV.cjs → chunk-WPTMMOA6.cjs} +9 -9
  239. package/dist/chunk-WPTMMOA6.cjs.map +1 -0
  240. package/dist/{chunk-HUNMRKGE.js → chunk-WTXASLBB.js} +2 -2
  241. package/dist/chunk-WTXASLBB.js.map +1 -0
  242. package/dist/chunk-XJAXKENE.cjs.map +1 -1
  243. package/dist/{chunk-TCX3QKF3.js → chunk-XJBWFDDE.js} +1 -1
  244. package/dist/chunk-XJBWFDDE.js.map +1 -0
  245. package/dist/{chunk-IYQX7PBO.cjs → chunk-XKQMEVOD.cjs} +1 -1
  246. package/dist/chunk-XKQMEVOD.cjs.map +1 -0
  247. package/dist/{chunk-KQKJVFYF.js → chunk-YQLCPKGV.js} +1 -1
  248. package/dist/chunk-YQLCPKGV.js.map +1 -0
  249. package/dist/{chunk-GI7WPGP2.cjs → chunk-YRK56AOP.cjs} +5 -5
  250. package/dist/chunk-YRK56AOP.cjs.map +1 -0
  251. package/dist/{chunk-H523JFY2.js → chunk-YV57RSPD.js} +1 -1
  252. package/dist/chunk-YV57RSPD.js.map +1 -0
  253. package/dist/{chunk-JORQYNJD.js → chunk-Z4ZY7L7W.js} +3 -3
  254. package/dist/chunk-Z4ZY7L7W.js.map +1 -0
  255. package/dist/{chunk-R5QPUQSI.cjs → chunk-Z5U4NJTW.cjs} +1 -1
  256. package/dist/chunk-Z5U4NJTW.cjs.map +1 -0
  257. package/dist/{chunk-5D3LIJYW.cjs → chunk-ZBKJ3EMK.cjs} +5 -5
  258. package/dist/chunk-ZBKJ3EMK.cjs.map +1 -0
  259. package/dist/{chunk-K5TKNT6I.cjs → chunk-ZMDZGL5A.cjs} +1 -1
  260. package/dist/chunk-ZMDZGL5A.cjs.map +1 -0
  261. package/dist/{chunk-OVYIBDGE.js → chunk-ZZSPQFMX.js} +1 -1
  262. package/dist/chunk-ZZSPQFMX.js.map +1 -0
  263. package/dist/color-picker/index.cjs +3 -3
  264. package/dist/color-picker/index.cjs.map +1 -1
  265. package/dist/color-picker/index.js +2 -2
  266. package/dist/combobox/index.cjs +6 -6
  267. package/dist/combobox/index.cjs.map +1 -1
  268. package/dist/combobox/index.js +5 -5
  269. package/dist/command-palette/index.cjs +3 -3
  270. package/dist/command-palette/index.cjs.map +1 -1
  271. package/dist/command-palette/index.js +2 -2
  272. package/dist/context-menu/index.cjs +7 -7
  273. package/dist/context-menu/index.cjs.map +1 -1
  274. package/dist/context-menu/index.js +6 -6
  275. package/dist/data-grid/index.cjs +17 -17
  276. package/dist/data-grid/index.cjs.map +1 -1
  277. package/dist/data-grid/index.js +16 -16
  278. package/dist/date-picker/index.cjs +8 -8
  279. package/dist/date-picker/index.cjs.map +1 -1
  280. package/dist/date-picker/index.js +7 -7
  281. package/dist/divider/index.cjs +2 -2
  282. package/dist/divider/index.cjs.map +1 -1
  283. package/dist/divider/index.js +1 -1
  284. package/dist/drawer/index.cjs +5 -5
  285. package/dist/drawer/index.cjs.map +1 -1
  286. package/dist/drawer/index.js +4 -4
  287. package/dist/dropdown/index.cjs +2 -2
  288. package/dist/dropdown/index.cjs.map +1 -1
  289. package/dist/dropdown/index.js +1 -1
  290. package/dist/empty-state/index.cjs +2 -2
  291. package/dist/empty-state/index.cjs.map +1 -1
  292. package/dist/empty-state/index.js +1 -1
  293. package/dist/file-upload/index.cjs +2 -2
  294. package/dist/file-upload/index.cjs.map +1 -1
  295. package/dist/file-upload/index.js +1 -1
  296. package/dist/footer/index.cjs +2 -2
  297. package/dist/footer/index.cjs.map +1 -1
  298. package/dist/footer/index.js +1 -1
  299. package/dist/header/index.cjs +5 -5
  300. package/dist/header/index.cjs.map +1 -1
  301. package/dist/header/index.js +4 -4
  302. package/dist/index.cjs +56 -56
  303. package/dist/index.cjs.map +1 -1
  304. package/dist/index.js +55 -55
  305. package/dist/inline-edit/index.cjs +5 -5
  306. package/dist/inline-edit/index.cjs.map +1 -1
  307. package/dist/inline-edit/index.js +4 -4
  308. package/dist/input/index.cjs +4 -4
  309. package/dist/input/index.cjs.map +1 -1
  310. package/dist/input/index.js +3 -3
  311. package/dist/kbd/index.cjs +2 -2
  312. package/dist/kbd/index.cjs.map +1 -1
  313. package/dist/kbd/index.js +1 -1
  314. package/dist/menu/index.cjs +6 -6
  315. package/dist/menu/index.cjs.map +1 -1
  316. package/dist/menu/index.js +5 -5
  317. package/dist/modal/index.cjs +5 -5
  318. package/dist/modal/index.cjs.map +1 -1
  319. package/dist/modal/index.js +4 -4
  320. package/dist/navigation/index.cjs +6 -6
  321. package/dist/navigation/index.cjs.map +1 -1
  322. package/dist/navigation/index.js +5 -5
  323. package/dist/number-input/index.cjs +2 -2
  324. package/dist/number-input/index.cjs.map +1 -1
  325. package/dist/number-input/index.js +1 -1
  326. package/dist/o-t-p-input/index.cjs +2 -2
  327. package/dist/o-t-p-input/index.cjs.map +1 -1
  328. package/dist/o-t-p-input/index.js +1 -1
  329. package/dist/page-layout/index.cjs +15 -15
  330. package/dist/page-layout/index.cjs.map +1 -1
  331. package/dist/page-layout/index.js +14 -14
  332. package/dist/pagination/index.cjs +8 -8
  333. package/dist/pagination/index.cjs.map +1 -1
  334. package/dist/pagination/index.js +7 -7
  335. package/dist/pill/index.cjs.map +1 -1
  336. package/dist/popover/index.cjs +2 -2
  337. package/dist/popover/index.cjs.map +1 -1
  338. package/dist/popover/index.js +1 -1
  339. package/dist/progress/index.cjs +2 -2
  340. package/dist/progress/index.cjs.map +1 -1
  341. package/dist/progress/index.js +1 -1
  342. package/dist/radio/index.cjs +2 -2
  343. package/dist/radio/index.cjs.map +1 -1
  344. package/dist/radio/index.js +1 -1
  345. package/dist/segmented-control/index.cjs +4 -4
  346. package/dist/segmented-control/index.cjs.map +1 -1
  347. package/dist/segmented-control/index.js +3 -3
  348. package/dist/select/index.cjs +6 -6
  349. package/dist/select/index.cjs.map +1 -1
  350. package/dist/select/index.js +5 -5
  351. package/dist/skeleton/index.cjs +2 -2
  352. package/dist/skeleton/index.cjs.map +1 -1
  353. package/dist/skeleton/index.js +1 -1
  354. package/dist/slider/index.cjs +2 -2
  355. package/dist/slider/index.cjs.map +1 -1
  356. package/dist/slider/index.js +1 -1
  357. package/dist/snackbar/index.cjs +5 -5
  358. package/dist/snackbar/index.cjs.map +1 -1
  359. package/dist/snackbar/index.js +4 -4
  360. package/dist/spinner/index.cjs +2 -2
  361. package/dist/spinner/index.cjs.map +1 -1
  362. package/dist/spinner/index.js +1 -1
  363. package/dist/split-button/index.cjs +7 -7
  364. package/dist/split-button/index.cjs.map +1 -1
  365. package/dist/split-button/index.js +6 -6
  366. package/dist/stepper/index.cjs +2 -2
  367. package/dist/stepper/index.cjs.map +1 -1
  368. package/dist/stepper/index.js +1 -1
  369. package/dist/switch/index.cjs +2 -2
  370. package/dist/switch/index.cjs.map +1 -1
  371. package/dist/switch/index.js +1 -1
  372. package/dist/table/index.cjs +17 -17
  373. package/dist/table/index.cjs.map +1 -1
  374. package/dist/table/index.js +16 -16
  375. package/dist/tabs/index.cjs +3 -3
  376. package/dist/tabs/index.cjs.map +1 -1
  377. package/dist/tabs/index.js +2 -2
  378. package/dist/tag-input/index.cjs +6 -6
  379. package/dist/tag-input/index.cjs.map +1 -1
  380. package/dist/tag-input/index.js +5 -5
  381. package/dist/textarea/index.cjs +4 -4
  382. package/dist/textarea/index.cjs.map +1 -1
  383. package/dist/textarea/index.js +3 -3
  384. package/dist/timeline/index.cjs +2 -2
  385. package/dist/timeline/index.cjs.map +1 -1
  386. package/dist/timeline/index.js +1 -1
  387. package/dist/toolbar/index.cjs +11 -11
  388. package/dist/toolbar/index.cjs.map +1 -1
  389. package/dist/toolbar/index.js +10 -10
  390. package/dist/tooltip/index.cjs +2 -2
  391. package/dist/tooltip/index.cjs.map +1 -1
  392. package/dist/tooltip/index.js +1 -1
  393. package/dist/tree-view/index.cjs +2 -2
  394. package/dist/tree-view/index.cjs.map +1 -1
  395. package/dist/tree-view/index.js +1 -1
  396. package/dist/virtual-list/index.cjs +3 -3
  397. package/dist/virtual-list/index.cjs.map +1 -1
  398. package/dist/virtual-list/index.js +2 -2
  399. package/package.json +114 -110
  400. package/dist/chunk-2HTBZGBP.cjs.map +0 -1
  401. package/dist/chunk-2JWY36LD.cjs.map +0 -1
  402. package/dist/chunk-2YQE26EK.js.map +0 -1
  403. package/dist/chunk-2ZWBN3LK.cjs.map +0 -1
  404. package/dist/chunk-3KAR5KCS.cjs.map +0 -1
  405. package/dist/chunk-3YPTYI7R.js.map +0 -1
  406. package/dist/chunk-4NUZP66U.js.map +0 -1
  407. package/dist/chunk-5D3LIJYW.cjs.map +0 -1
  408. package/dist/chunk-5QG2I3FK.cjs.map +0 -1
  409. package/dist/chunk-5TGBNYZK.cjs.map +0 -1
  410. package/dist/chunk-63N2KZZX.cjs.map +0 -1
  411. package/dist/chunk-6GAIQ2IY.cjs.map +0 -1
  412. package/dist/chunk-6HGDQ4BM.js.map +0 -1
  413. package/dist/chunk-6P4WYB3B.js.map +0 -1
  414. package/dist/chunk-6QFT3BUD.cjs.map +0 -1
  415. package/dist/chunk-6USUVU6J.js.map +0 -1
  416. package/dist/chunk-73EKJU4G.js.map +0 -1
  417. package/dist/chunk-7IOOFKG3.js.map +0 -1
  418. package/dist/chunk-7KGV6YCG.cjs.map +0 -1
  419. package/dist/chunk-7R7IFWGB.cjs.map +0 -1
  420. package/dist/chunk-A35Y5MRJ.js.map +0 -1
  421. package/dist/chunk-AOV32YBE.js.map +0 -1
  422. package/dist/chunk-AUFCW7QU.cjs.map +0 -1
  423. package/dist/chunk-BBOUUHLO.js.map +0 -1
  424. package/dist/chunk-BFYSYUA6.cjs.map +0 -1
  425. package/dist/chunk-BTPCSBGP.js.map +0 -1
  426. package/dist/chunk-C7F2VFAI.cjs.map +0 -1
  427. package/dist/chunk-CDV2OAS3.cjs.map +0 -1
  428. package/dist/chunk-CJUZDUXW.cjs.map +0 -1
  429. package/dist/chunk-CKH36D7H.js.map +0 -1
  430. package/dist/chunk-D7PGZ3M3.cjs.map +0 -1
  431. package/dist/chunk-DFADZZ3K.js.map +0 -1
  432. package/dist/chunk-DK4S3EHG.js.map +0 -1
  433. package/dist/chunk-E2B33QB7.js.map +0 -1
  434. package/dist/chunk-E3XATJ63.js.map +0 -1
  435. package/dist/chunk-F54MVGKO.js.map +0 -1
  436. package/dist/chunk-FNUOTM44.cjs.map +0 -1
  437. package/dist/chunk-FO5FNTJX.js.map +0 -1
  438. package/dist/chunk-G2FANEA2.cjs.map +0 -1
  439. package/dist/chunk-G36S5CWN.cjs.map +0 -1
  440. package/dist/chunk-GI7WPGP2.cjs.map +0 -1
  441. package/dist/chunk-GL4DHGQE.js.map +0 -1
  442. package/dist/chunk-GOVOQZYN.js.map +0 -1
  443. package/dist/chunk-GRH57M3E.js.map +0 -1
  444. package/dist/chunk-H523JFY2.js.map +0 -1
  445. package/dist/chunk-H56YUMFB.cjs.map +0 -1
  446. package/dist/chunk-HO7P6IJO.js.map +0 -1
  447. package/dist/chunk-HQ4KZRFH.js.map +0 -1
  448. package/dist/chunk-HUNMRKGE.js.map +0 -1
  449. package/dist/chunk-ICHPPNFV.js.map +0 -1
  450. package/dist/chunk-ICJ3SV5I.cjs.map +0 -1
  451. package/dist/chunk-IYQX7PBO.cjs.map +0 -1
  452. package/dist/chunk-JFA5ABVE.js.map +0 -1
  453. package/dist/chunk-JORQYNJD.js.map +0 -1
  454. package/dist/chunk-K5TKNT6I.cjs.map +0 -1
  455. package/dist/chunk-KF64C4QI.js.map +0 -1
  456. package/dist/chunk-KKOZX64Z.js.map +0 -1
  457. package/dist/chunk-KO2MKZDW.cjs.map +0 -1
  458. package/dist/chunk-KQKJVFYF.js.map +0 -1
  459. package/dist/chunk-KV2FG7AN.cjs.map +0 -1
  460. package/dist/chunk-L3UPSLJ5.cjs.map +0 -1
  461. package/dist/chunk-LEZ4HSBD.cjs.map +0 -1
  462. package/dist/chunk-LQ3C3OR2.js.map +0 -1
  463. package/dist/chunk-LTOHGCU4.cjs.map +0 -1
  464. package/dist/chunk-M56IGNH7.cjs.map +0 -1
  465. package/dist/chunk-N7HX5635.cjs.map +0 -1
  466. package/dist/chunk-NDLMU6HJ.js.map +0 -1
  467. package/dist/chunk-O5ZPSZNY.cjs.map +0 -1
  468. package/dist/chunk-O6B4KB4D.js.map +0 -1
  469. package/dist/chunk-OHUVWPFJ.js.map +0 -1
  470. package/dist/chunk-OT3VZLN4.js.map +0 -1
  471. package/dist/chunk-OVYIBDGE.js.map +0 -1
  472. package/dist/chunk-P2BTQ33C.cjs.map +0 -1
  473. package/dist/chunk-P6ZBENAG.js.map +0 -1
  474. package/dist/chunk-P74HNSNJ.cjs.map +0 -1
  475. package/dist/chunk-PEPYVWGY.cjs.map +0 -1
  476. package/dist/chunk-POX6JZLO.cjs.map +0 -1
  477. package/dist/chunk-PWIA4XQD.js.map +0 -1
  478. package/dist/chunk-QGZF5MOS.cjs.map +0 -1
  479. package/dist/chunk-QP2A5ZMK.cjs.map +0 -1
  480. package/dist/chunk-QYHTMEI5.js.map +0 -1
  481. package/dist/chunk-QYK4ECSZ.js.map +0 -1
  482. package/dist/chunk-R36SGSJX.cjs.map +0 -1
  483. package/dist/chunk-R5QPUQSI.cjs.map +0 -1
  484. package/dist/chunk-R5UNLPQZ.cjs.map +0 -1
  485. package/dist/chunk-RSBQNIJZ.js.map +0 -1
  486. package/dist/chunk-S25WB7KJ.js.map +0 -1
  487. package/dist/chunk-SAFSEXMU.cjs.map +0 -1
  488. package/dist/chunk-SOGUWOSQ.cjs.map +0 -1
  489. package/dist/chunk-SXF3TCYA.js.map +0 -1
  490. package/dist/chunk-T56K5IKQ.js.map +0 -1
  491. package/dist/chunk-TBMVUI7S.cjs.map +0 -1
  492. package/dist/chunk-TCX3QKF3.js.map +0 -1
  493. package/dist/chunk-TQCNQKWF.cjs.map +0 -1
  494. package/dist/chunk-UTENJWSE.cjs.map +0 -1
  495. package/dist/chunk-V5JNYS77.cjs.map +0 -1
  496. package/dist/chunk-VFYG7GAH.js.map +0 -1
  497. package/dist/chunk-VLC2OZV3.cjs.map +0 -1
  498. package/dist/chunk-VTAABT55.js.map +0 -1
  499. package/dist/chunk-VYV45YOK.cjs.map +0 -1
  500. package/dist/chunk-VZ43OLU6.cjs.map +0 -1
  501. package/dist/chunk-XJBMEDQ5.js.map +0 -1
  502. package/dist/chunk-XMRMCWSQ.js.map +0 -1
  503. package/dist/chunk-XSGUFMT4.js.map +0 -1
  504. package/dist/chunk-YCUT6NQ4.js.map +0 -1
  505. package/dist/chunk-YKECQKOV.cjs.map +0 -1
  506. package/dist/chunk-YLKESEHQ.cjs.map +0 -1
  507. package/dist/chunk-YZOVF7JV.cjs.map +0 -1
  508. package/dist/chunk-Z7S4UQKY.js.map +0 -1
  509. package/dist/chunk-ZBGTVTQJ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-LEZ4HSBD.cjs","../src/components/Table/Table.component.tsx"],"names":[],"mappings":"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","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-LEZ4HSBD.cjs","sourcesContent":[null,"import { useState, useMemo, useLayoutEffect, useRef } from 'react';\r\nimport React from 'react';\r\nimport {\r\n ChevronsUpDown,\r\n ArrowUp,\r\n ArrowDown,\r\n X,\r\n Check,\r\n Download,\r\n Columns3,\r\n AlignJustify,\r\n GripVertical,\r\n FolderOpen,\r\n SearchX,\r\n} from 'lucide-react';\r\nimport { DndContext, PointerSensor, KeyboardSensor, useSensor, useSensors } from '@dnd-kit/core';\r\nimport type { DragEndEvent } from '@dnd-kit/core';\r\nimport {\r\n SortableContext,\r\n horizontalListSortingStrategy,\r\n useSortable,\r\n sortableKeyboardCoordinates,\r\n arrayMove,\r\n} from '@dnd-kit/sortable';\r\nimport { CSS } from '@dnd-kit/utilities';\r\nimport type { TableColumn, TableProps, TableFilters, FilterValue } from './Table.types';\r\n\r\nexport type { TableColumn, TableProps, TableFilters, FilterValue };\r\nimport { Button } from '../Button';\r\nimport { Checkbox } from '../Checkbox';\r\nimport { Dropdown } from '../Dropdown';\r\nimport { EmptyState } from '../EmptyState';\r\nimport { Pagination } from '../Pagination';\r\nimport { SplitButton } from '../SplitButton';\r\nimport { Spinner } from '../Spinner';\r\nimport { TableFiltersDropdown } from './TableFiltersDropdown.component';\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\ntype Density = 'compact' | 'comfortable' | 'spacious';\r\n\r\nconst DENSITY_OPTIONS: { value: Density; label: string }[] = [\r\n { value: 'compact', label: 'Compact' },\r\n { value: 'comfortable', label: 'Comfortable' },\r\n { value: 'spacious', label: 'Spacious' },\r\n];\r\n\r\n// ── CSV helpers ───────────────────────────────────────────────────────────────\r\n\r\nfunction escapeCsvValue(value: string): string {\r\n if (value.includes(',') || value.includes('\\n') || value.includes('\"')) {\r\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n return value;\r\n}\r\n\r\n// ── SortableColumnHeader ──────────────────────────────────────────────────────\r\n// Defined as a standalone component so it can legally call useSortable().\r\n// Only rendered when draggableColumns=true (inside a DndContext + SortableContext).\r\n\r\ninterface SortableThProps {\r\n id: string;\r\n column: { label: string };\r\n isSortable: boolean;\r\n isCurrentlySorted: boolean;\r\n sortDirection: 'asc' | 'desc' | null;\r\n alignment: string;\r\n columnType: string;\r\n columnWidth: string | undefined;\r\n pinnedClass: string;\r\n stickyStyle: React.CSSProperties;\r\n onSortClick: () => void;\r\n}\r\n\r\nfunction SortableColumnHeader({\r\n id,\r\n column,\r\n isSortable,\r\n isCurrentlySorted,\r\n sortDirection,\r\n alignment,\r\n columnType,\r\n columnWidth,\r\n pinnedClass,\r\n stickyStyle,\r\n onSortClick,\r\n}: SortableThProps) {\r\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\r\n id,\r\n });\r\n\r\n const transformStr = CSS.Transform.toString(transform);\r\n\r\n const thClassName = [\r\n 'eidos-table-header-cell',\r\n `eidos-table-header-cell-${columnType}`,\r\n isSortable ? 'eidos-table-sortable' : '',\r\n isCurrentlySorted ? 'eidos-table-sorted' : '',\r\n `eidos-table-align-${alignment}`,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <th\r\n ref={setNodeRef as React.LegacyRef<HTMLTableCellElement>}\r\n className={thClassName}\r\n style={{\r\n width: columnWidth,\r\n ...stickyStyle,\r\n ...(transformStr ? { transform: transformStr } : {}),\r\n transition: transition ?? undefined,\r\n opacity: isDragging ? 0.5 : 1,\r\n }}\r\n data-col-key={id}\r\n onClick={() => isSortable && onSortClick()}\r\n {...attributes}\r\n >\r\n {/* Grip - absolutely positioned in the left padding zone so it never\r\n displaces the column label or causes layout shift on hover. */}\r\n <span\r\n className=\"eidos-table-drag-handle\"\r\n {...listeners}\r\n onClick={(e) => e.stopPropagation()}\r\n title=\"Drag to reorder\"\r\n >\r\n <GripVertical size={12} />\r\n </span>\r\n <div className={`eidos-table-header-content eidos-table-align-${alignment}`}>\r\n <span className=\"eidos-table-header-label\">{column.label}</span>\r\n {isSortable && (\r\n <div className=\"eidos-table-sort-indicator\">\r\n {sortDirection === 'asc' && <ArrowUp size={14} />}\r\n {sortDirection === 'desc' && <ArrowDown size={14} />}\r\n {!sortDirection && <ChevronsUpDown size={14} />}\r\n </div>\r\n )}\r\n </div>\r\n </th>\r\n );\r\n}\r\n\r\n// ── Table ─────────────────────────────────────────────────────────────────────\r\n\r\nexport const Table = <T extends Record<string, unknown>>({\r\n data,\r\n columns,\r\n loading = false,\r\n emptyMessage = 'No data available',\r\n onRowClick,\r\n className,\r\n showFooter = false,\r\n totalItems,\r\n showPagination = false,\r\n pageSize = 25,\r\n pageSizeOptions = [10, 25, 50, 100],\r\n onSortChange,\r\n currentSort,\r\n filters = {},\r\n onFiltersChange,\r\n defaultFilters,\r\n showFilters = false,\r\n // Selection\r\n selectable = false,\r\n rowKey,\r\n selectedRows: controlledSelected,\r\n defaultSelectedRows = [],\r\n onSelectionChange,\r\n bulkActions = [],\r\n // New features\r\n density = 'comfortable',\r\n showDensity = false,\r\n showColumnVisibility = false,\r\n showExport = false,\r\n draggableColumns = false,\r\n onColumnReorder,\r\n}: TableProps<T>) => {\r\n // ── Column ordering (drag-reorder) ────────────────────────────────────────\r\n const [columnOrder, setColumnOrder] = useState<string[]>(() => columns.map((c) => String(c.key)));\r\n\r\n // Derived-state reset: when the set of column keys changes, reset the order.\r\n // Calling setState during render is the React-idiomatic way to do this.\r\n const columnKeysSignature = columns.map((c) => String(c.key)).join('\\0');\r\n const prevKeysRef = useRef(columnKeysSignature);\r\n if (prevKeysRef.current !== columnKeysSignature) {\r\n prevKeysRef.current = columnKeysSignature;\r\n setColumnOrder(columns.map((c) => String(c.key)));\r\n }\r\n\r\n const orderedColumns = useMemo(() => {\r\n const orderMap = new Map(columnOrder.map((key, idx) => [key, idx]));\r\n return [...columns].sort((a, b) => {\r\n const ai = orderMap.get(String(a.key)) ?? Infinity;\r\n const bi = orderMap.get(String(b.key)) ?? Infinity;\r\n return ai - bi;\r\n });\r\n }, [columns, columnOrder]);\r\n\r\n // ── Density (internal state when showDensity=true) ────────────────────────\r\n const [internalDensity, setInternalDensity] = useState<Density>(density as Density);\r\n // When showDensity is true the table owns density; otherwise respect the prop.\r\n const effectiveDensity: Density = showDensity ? internalDensity : (density as Density);\r\n\r\n // ── Column visibility ─────────────────────────────────────────────────────\r\n const [hiddenColumnKeys, setHiddenColumnKeys] = useState<Set<string>>(() => new Set<string>());\r\n\r\n const visibleColumns = useMemo(\r\n () => orderedColumns.filter((c) => !hiddenColumnKeys.has(String(c.key))),\r\n [orderedColumns, hiddenColumnKeys],\r\n );\r\n\r\n // ── Pinned / sticky columns ────────────────────────────────────────────────\r\n const theadRef = useRef<HTMLTableSectionElement>(null);\r\n const [pinnedOffsets, setPinnedOffsets] = useState<\r\n Map<string, { side: 'left' | 'right'; offset: number }>\r\n >(new Map());\r\n\r\n useLayoutEffect(() => {\r\n const hasPinned = visibleColumns.some((c) => c.pin);\r\n if (!hasPinned || !theadRef.current) {\r\n setPinnedOffsets(new Map());\r\n return;\r\n }\r\n\r\n const headerRow = theadRef.current.querySelector('tr');\r\n if (!headerRow) return;\r\n\r\n const cells = Array.from(headerRow.querySelectorAll<HTMLTableCellElement>('th[data-col-key]'));\r\n\r\n const newOffsets = new Map<string, { side: 'left' | 'right'; offset: number }>();\r\n\r\n // Left-pinned: scan left-to-right.\r\n // Checkbox (when selectable) counts as a left-pinned element.\r\n let leftAccum = 0;\r\n for (const cell of cells) {\r\n const key = cell.dataset.colKey!;\r\n if (key === '__checkbox__') {\r\n newOffsets.set(key, { side: 'left', offset: leftAccum });\r\n leftAccum += cell.offsetWidth;\r\n } else {\r\n const col = visibleColumns.find((c) => String(c.key) === key);\r\n if (col?.pin === 'left') {\r\n newOffsets.set(key, { side: 'left', offset: leftAccum });\r\n leftAccum += cell.offsetWidth;\r\n }\r\n }\r\n }\r\n\r\n // Right-pinned: scan right-to-left.\r\n let rightAccum = 0;\r\n for (let i = cells.length - 1; i >= 0; i--) {\r\n const cell = cells[i];\r\n const key = cell.dataset.colKey!;\r\n const col = visibleColumns.find((c) => String(c.key) === key);\r\n if (col?.pin === 'right') {\r\n newOffsets.set(key, { side: 'right', offset: rightAccum });\r\n rightAccum += cell.offsetWidth;\r\n }\r\n }\r\n\r\n setPinnedOffsets(newOffsets);\r\n }, [visibleColumns, selectable]);\r\n\r\n // ── Selection state (controlled / uncontrolled) ──────────────────────────\r\n const isControlledSelection = controlledSelected !== undefined;\r\n const [internalSelected, setInternalSelected] = useState<string[]>(defaultSelectedRows);\r\n const selectedSet = useMemo(\r\n () => new Set(isControlledSelection ? controlledSelected : internalSelected),\r\n [isControlledSelection, controlledSelected, internalSelected],\r\n );\r\n\r\n /** Stable string key for a row - uses `rowKey` prop, then \"id\", then index. */\r\n const getRowKey = (item: T, index: number): string => {\r\n if (rowKey) return String(item[rowKey]);\r\n if ('id' in item) return String(item.id);\r\n return String(index);\r\n };\r\n\r\n const commitSelection = (keys: string[]) => {\r\n if (!isControlledSelection) setInternalSelected(keys);\r\n const rows = data.filter((item, idx) => keys.includes(getRowKey(item, idx)));\r\n onSelectionChange?.(keys, rows);\r\n };\r\n\r\n const toggleRow = (key: string) => {\r\n const next = selectedSet.has(key)\r\n ? [...selectedSet].filter((k) => k !== key)\r\n : [...selectedSet, key];\r\n commitSelection(next);\r\n };\r\n\r\n const allKeys = useMemo(\r\n () => data.map((item, idx) => getRowKey(item, idx)),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [data, rowKey],\r\n );\r\n\r\n const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));\r\n const someSelected = !allSelected && allKeys.some((k) => selectedSet.has(k));\r\n\r\n const toggleAll = () => {\r\n commitSelection(allSelected ? [] : allKeys);\r\n };\r\n\r\n const clearSelection = () => commitSelection([]);\r\n\r\n // ── Pagination ────────────────────────────────────────────────────────────\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [currentPageSize, setCurrentPageSize] = useState(pageSize);\r\n\r\n const displayData = useMemo(() => {\r\n if (!showPagination) return data;\r\n const startIndex = (currentPage - 1) * currentPageSize;\r\n return data.slice(startIndex, startIndex + currentPageSize);\r\n }, [data, showPagination, currentPage, currentPageSize]);\r\n\r\n const totalPages = Math.ceil(data.length / currentPageSize);\r\n\r\n const handleSort = (key: string) => {\r\n const newDirection =\r\n currentSort?.key === key && currentSort?.direction === 'asc' ? 'desc' : 'asc';\r\n onSortChange?.(key, newDirection);\r\n };\r\n\r\n const handlePageChange = (page: number) => setCurrentPage(page);\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setCurrentPageSize(newPageSize);\r\n setCurrentPage(1);\r\n };\r\n\r\n // ── Derived UI state ──────────────────────────────────────────────────────\r\n const hasSelection = selectedSet.size > 0;\r\n const showToolbar =\r\n (showFilters && !!onFiltersChange) ||\r\n showColumnVisibility ||\r\n showExport ||\r\n showDensity ||\r\n (selectable && hasSelection);\r\n\r\n const selectedItems = useMemo(\r\n () => data.filter((item, idx) => selectedSet.has(getRowKey(item, idx))),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [data, selectedSet, rowKey],\r\n );\r\n\r\n // ── CSV Export ────────────────────────────────────────────────────────────\r\n const getRawValue = (item: T, column: TableColumn<T>): string => {\r\n const value =\r\n typeof column.key === 'string' && column.key.includes('.')\r\n ? (column.key as string)\r\n .split('.')\r\n .reduce(\r\n (obj: unknown, k: string) => (obj as Record<string, unknown>)?.[k],\r\n item as unknown,\r\n )\r\n : item[column.key as keyof T];\r\n return String(value ?? '');\r\n };\r\n\r\n const handleExportCsv = () => {\r\n const headers = visibleColumns.map((c) => escapeCsvValue(c.label)).join(',');\r\n const rows = data.map((item) =>\r\n visibleColumns.map((col) => escapeCsvValue(getRawValue(item, col))).join(','),\r\n );\r\n const csv = [headers, ...rows].join('\\n');\r\n const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\r\n const url = URL.createObjectURL(blob);\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.download = 'export.csv';\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n URL.revokeObjectURL(url);\r\n };\r\n\r\n // ── DnD setup ─────────────────────────────────────────────────────────────\r\n const sensors = useSensors(\r\n useSensor(PointerSensor),\r\n useSensor(KeyboardSensor, {\r\n coordinateGetter: sortableKeyboardCoordinates,\r\n }),\r\n );\r\n\r\n const handleDragEnd = (event: DragEndEvent) => {\r\n const { active, over } = event;\r\n if (!over || active.id === over.id) return;\r\n\r\n const activeId = String(active.id);\r\n const overId = String(over.id);\r\n const oldIndex = columnOrder.indexOf(activeId);\r\n const newIndex = columnOrder.indexOf(overId);\r\n if (oldIndex === -1 || newIndex === -1) return;\r\n\r\n const newOrder = arrayMove(columnOrder, oldIndex, newIndex);\r\n setColumnOrder(newOrder);\r\n\r\n if (onColumnReorder) {\r\n const orderMap = new Map(newOrder.map((key, idx) => [key, idx]));\r\n const reordered = [...columns].sort((a, b) => {\r\n const ai = orderMap.get(String(a.key)) ?? Infinity;\r\n const bi = orderMap.get(String(b.key)) ?? Infinity;\r\n return ai - bi;\r\n });\r\n onColumnReorder(reordered);\r\n }\r\n };\r\n\r\n // ── Helpers ───────────────────────────────────────────────────────────────\r\n\r\n /** Returns sticky style + className for body <td> cells (zIndex: 1). */\r\n const getCellPinnedProps = (\r\n colKey: string,\r\n ): { style: React.CSSProperties; className: string } => {\r\n const pinInfo = pinnedOffsets.get(colKey);\r\n if (!pinInfo) return { style: {}, className: '' };\r\n return {\r\n style: {\r\n position: 'sticky',\r\n [pinInfo.side]: pinInfo.offset,\r\n zIndex: 1,\r\n },\r\n className:\r\n pinInfo.side === 'left'\r\n ? 'eidos-table-cell--pinned-left'\r\n : 'eidos-table-cell--pinned-right',\r\n };\r\n };\r\n\r\n /** Returns sticky style + className for header <th> cells (zIndex: 3). */\r\n const getHeaderPinnedProps = (\r\n colKey: string,\r\n ): { style: React.CSSProperties; className: string } => {\r\n const pinInfo = pinnedOffsets.get(colKey);\r\n if (!pinInfo) return { style: {}, className: '' };\r\n return {\r\n style: {\r\n position: 'sticky',\r\n [pinInfo.side]: pinInfo.offset,\r\n zIndex: 3,\r\n },\r\n className:\r\n pinInfo.side === 'left'\r\n ? 'eidos-table-header-cell--pinned-left'\r\n : 'eidos-table-header-cell--pinned-right',\r\n };\r\n };\r\n\r\n // ── Density class ─────────────────────────────────────────────────────────\r\n const densityClass = effectiveDensity !== 'comfortable' ? `eidos-table--${effectiveDensity}` : '';\r\n\r\n // ── Loading ───────────────────────────────────────────────────────────────\r\n if (loading) {\r\n return (\r\n <div className={`eidos-table-container ${className || ''}`}>\r\n <div className=\"eidos-table-loading\">\r\n <Spinner size=\"md\" />\r\n <p>Loading...</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // ── Density panel (Dropdown content) ──────────────────────────────────────\r\n const densityPanel = (\r\n <div className=\"eidos-table-menu-panel\">\r\n {DENSITY_OPTIONS.map((option) => (\r\n <button\r\n key={option.value}\r\n className={[\r\n 'eidos-table-menu-item',\r\n effectiveDensity === option.value ? 'eidos-table-menu-item--active' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => setInternalDensity(option.value)}\r\n >\r\n <span className=\"eidos-table-menu-item-check\">\r\n {effectiveDensity === option.value && <Check size={14} />}\r\n </span>\r\n <span>{option.label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n\r\n // ── Column visibility panel (Dropdown content) ────────────────────────────\r\n const columnVisibilityPanel = (\r\n <div className=\"eidos-table-menu-panel\">\r\n {/* Use orderedColumns so list order mirrors current column order */}\r\n {orderedColumns.map((col) => {\r\n const key = String(col.key);\r\n const isVisible = !hiddenColumnKeys.has(key);\r\n const isLastVisible = visibleColumns.length === 1 && isVisible;\r\n return (\r\n <button\r\n key={key}\r\n className={['eidos-table-menu-item', isVisible ? 'eidos-table-menu-item--active' : '']\r\n .filter(Boolean)\r\n .join(' ')}\r\n disabled={isLastVisible}\r\n onClick={() => {\r\n setHiddenColumnKeys((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(key)) next.delete(key);\r\n else next.add(key);\r\n return next;\r\n });\r\n }}\r\n >\r\n <Checkbox\r\n checked={isVisible}\r\n disabled={isLastVisible}\r\n size=\"sm\"\r\n onChange={() => {\r\n /* click handled by parent button */\r\n }}\r\n />\r\n <span>{col.label}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n\r\n // ── SortableContext items: visible column keys only ───────────────────────\r\n const sortableItems = visibleColumns.map((c) => String(c.key));\r\n\r\n // ── Main JSX ──────────────────────────────────────────────────────────────\r\n const tableContent = (\r\n <div className={`eidos-table-container ${className || ''}`}>\r\n {/* ── Toolbar ───────────────────────────────────────────────────────── */}\r\n {showToolbar && (\r\n <div className=\"eidos-table-toolbar\">\r\n {/* Left - bulk actions / selection info */}\r\n <div className=\"eidos-table-toolbar-left\">\r\n {selectable && hasSelection && (\r\n <>\r\n <span className=\"eidos-table-selection-count\">{selectedSet.size} selected</span>\r\n\r\n {bulkActions.length > 0 && (\r\n <div className=\"eidos-table-bulk-actions\">\r\n {bulkActions.map((action) => {\r\n const isDisabled =\r\n typeof action.disabled === 'function'\r\n ? action.disabled(selectedItems)\r\n : (action.disabled ?? false);\r\n\r\n if (action.type === 'split-button') {\r\n return (\r\n <SplitButton\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n preIcon={action.icon}\r\n disabled={isDisabled}\r\n label={action.label}\r\n onClick={() => action.onClick(selectedItems)}\r\n options={action.options.map((option) => ({\r\n id: option.id,\r\n label: option.label,\r\n icon: option.icon,\r\n disabled: option.disabled,\r\n onClick: () => option.onClick(selectedItems),\r\n }))}\r\n />\r\n );\r\n }\r\n\r\n return action.label ? (\r\n <Button\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n preIcon={action.icon}\r\n posIcon={action.posIcon}\r\n disabled={isDisabled}\r\n onClick={() => action.onClick(selectedItems)}\r\n >\r\n {action.label}\r\n </Button>\r\n ) : action.icon ? (\r\n <Button\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n icon={action.icon}\r\n disabled={isDisabled}\r\n onClick={() => action.onClick(selectedItems)}\r\n />\r\n ) : null;\r\n })}\r\n </div>\r\n )}\r\n\r\n <button\r\n className=\"eidos-table-clear-selection\"\r\n onClick={clearSelection}\r\n aria-label=\"Clear selection\"\r\n >\r\n <X size={14} />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Right - density, column visibility, export, filter */}\r\n <div className=\"eidos-table-toolbar-right\">\r\n {showDensity && (\r\n <Dropdown\r\n placement=\"bottom\"\r\n align=\"end\"\r\n autoWidth={false}\r\n trigger={\r\n <Button variant=\"text\" size=\"sm\" preIcon={AlignJustify}>\r\n Density\r\n </Button>\r\n }\r\n content={densityPanel}\r\n />\r\n )}\r\n\r\n {showColumnVisibility && (\r\n <Dropdown\r\n placement=\"bottom\"\r\n align=\"end\"\r\n autoWidth={false}\r\n trigger={\r\n <Button variant=\"text\" size=\"sm\" preIcon={Columns3}>\r\n Columns\r\n </Button>\r\n }\r\n content={columnVisibilityPanel}\r\n />\r\n )}\r\n\r\n {showExport && (\r\n <Button\r\n variant=\"text\"\r\n size=\"sm\"\r\n icon={Download}\r\n onClick={handleExportCsv}\r\n tooltip=\"Export CSV\"\r\n />\r\n )}\r\n\r\n {showFilters && onFiltersChange && (\r\n <TableFiltersDropdown\r\n columns={columns}\r\n filters={filters}\r\n onFiltersChange={onFiltersChange}\r\n defaultFilters={defaultFilters}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* ── Table (wrapped for horizontal scroll) ─────────────────────────── */}\r\n <div className=\"eidos-table-scroll\">\r\n <table\r\n className={[\r\n 'eidos-table',\r\n densityClass,\r\n draggableColumns ? 'eidos-table--draggable-columns' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n >\r\n <thead ref={theadRef}>\r\n <tr>\r\n {selectable && (\r\n <th\r\n className={[\r\n 'eidos-table-header-cell',\r\n 'eidos-table-checkbox-cell',\r\n getHeaderPinnedProps('__checkbox__').className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={getHeaderPinnedProps('__checkbox__').style}\r\n data-col-key=\"__checkbox__\"\r\n >\r\n <Checkbox\r\n size=\"sm\"\r\n checked={allSelected}\r\n indeterminate={someSelected}\r\n onChange={toggleAll}\r\n aria-label=\"Select all rows\"\r\n />\r\n </th>\r\n )}\r\n\r\n {/* ── Headers: draggable or plain ──────────────────────────── */}\r\n {draggableColumns\r\n ? visibleColumns.map((column) => {\r\n const colKey = String(column.key);\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const isSortable = !!column.sortable;\r\n const isCurrentlySorted = currentSort?.key === colKey;\r\n const sortDirection = isCurrentlySorted\r\n ? (currentSort!.direction as 'asc' | 'desc')\r\n : null;\r\n const alignment = column.align || 'left';\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getHeaderPinnedProps(colKey);\r\n\r\n return (\r\n <SortableColumnHeader\r\n key={colKey}\r\n id={colKey}\r\n column={column}\r\n isSortable={isSortable}\r\n isCurrentlySorted={!!isCurrentlySorted}\r\n sortDirection={sortDirection}\r\n alignment={alignment}\r\n columnType={columnType}\r\n columnWidth={columnWidth}\r\n pinnedClass={pinnedClass}\r\n stickyStyle={pinnedStyle}\r\n onSortClick={() => handleSort(colKey)}\r\n />\r\n );\r\n })\r\n : visibleColumns.map((column, index) => {\r\n const colKey = String(column.key);\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const isSortable = column.sortable;\r\n const isCurrentlySorted = currentSort?.key === colKey;\r\n const sortDirection = isCurrentlySorted ? currentSort!.direction : null;\r\n const alignment = column.align || 'left';\r\n const alignmentClass = `eidos-table-align-${alignment}`;\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getHeaderPinnedProps(colKey);\r\n\r\n return (\r\n <th\r\n key={index}\r\n className={[\r\n 'eidos-table-header-cell',\r\n `eidos-table-header-cell-${columnType}`,\r\n isSortable ? 'eidos-table-sortable' : '',\r\n isCurrentlySorted ? 'eidos-table-sorted' : '',\r\n alignmentClass,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ width: columnWidth, ...pinnedStyle }}\r\n data-col-key={colKey}\r\n onClick={() => isSortable && handleSort(colKey)}\r\n >\r\n <div className={`eidos-table-header-content ${alignmentClass}`}>\r\n <span>{column.label}</span>\r\n {isSortable && (\r\n <div className=\"eidos-table-sort-indicator\">\r\n {sortDirection === 'asc' && <ArrowUp size={14} />}\r\n {sortDirection === 'desc' && <ArrowDown size={14} />}\r\n {!sortDirection && <ChevronsUpDown size={14} />}\r\n </div>\r\n )}\r\n </div>\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {displayData.length > 0 ? (\r\n displayData.map((item, rowIndex) => {\r\n const globalIndex = showPagination\r\n ? (currentPage - 1) * currentPageSize + rowIndex\r\n : rowIndex;\r\n const key = getRowKey(item, globalIndex);\r\n const isSelected = selectedSet.has(key);\r\n\r\n return (\r\n <tr\r\n key={key}\r\n className={[\r\n 'eidos-table-row',\r\n onRowClick ? 'eidos-table-clickable' : '',\r\n isSelected ? 'eidos-table-row--selected' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => onRowClick?.(item)}\r\n >\r\n {selectable && (\r\n <td\r\n className={[\r\n 'eidos-table-cell',\r\n 'eidos-table-checkbox-cell',\r\n getCellPinnedProps('__checkbox__').className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={getCellPinnedProps('__checkbox__').style}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n toggleRow(key);\r\n }}\r\n >\r\n {/* Wrap in a span so Checkbox click-events don't\r\n bubble to the <td> and cause a double-toggle.\r\n The <td> onClick handles toggling when the user\r\n clicks the cell margin outside the checkbox. */}\r\n <span onClick={(e) => e.stopPropagation()}>\r\n <Checkbox\r\n size=\"sm\"\r\n checked={isSelected}\r\n onChange={() => toggleRow(key)}\r\n aria-label={`Select row ${globalIndex + 1}`}\r\n />\r\n </span>\r\n </td>\r\n )}\r\n {visibleColumns.map((column, colIndex) => {\r\n const colKey = String(column.key);\r\n const value =\r\n typeof column.key === 'string' && column.key.includes('.')\r\n ? (column.key as string)\r\n .split('.')\r\n .reduce(\r\n (obj: unknown, k: string) => (obj as Record<string, unknown>)?.[k],\r\n item as unknown,\r\n )\r\n : item[column.key as keyof T];\r\n\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const alignment = column.align || 'left';\r\n const alignmentClass = `eidos-table-align-${alignment}`;\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getCellPinnedProps(colKey);\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n className={[\r\n 'eidos-table-cell',\r\n `eidos-table-cell-${columnType}`,\r\n alignmentClass,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ width: columnWidth, ...pinnedStyle }}\r\n // `type: 'action'` cells exist specifically to hold\r\n // interactive controls (a row-actions Menu/button,\r\n // typically) - without this, clicking them bubbles\r\n // straight into `onRowClick` on the <tr> below,\r\n // e.g. opening a details drawer at the same time as\r\n // (or instead of) the action itself. Mirrors the\r\n // selectable checkbox cell's own stopPropagation\r\n // above, for the same reason.\r\n onClick={columnType === 'action' ? (e) => e.stopPropagation() : undefined}\r\n >\r\n {column.render ? column.render(value, item) : String(value ?? '')}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })\r\n ) : (\r\n <tr className=\"eidos-table-empty-row\">\r\n <td\r\n colSpan={selectable ? visibleColumns.length + 1 : visibleColumns.length}\r\n className=\"eidos-table-cell eidos-table-empty-cell\"\r\n >\r\n {Object.keys(filters).length > 0 ? (\r\n <EmptyState\r\n icon={<SearchX />}\r\n title=\"No results found\"\r\n description=\"Try adjusting your filters or search terms.\"\r\n action={\r\n onFiltersChange ? (\r\n <Button\r\n size=\"sm\"\r\n variant=\"outlined\"\r\n color=\"primary\"\r\n onClick={() => onFiltersChange({})}\r\n >\r\n Clear filters\r\n </Button>\r\n ) : undefined\r\n }\r\n size=\"sm\"\r\n />\r\n ) : (\r\n <EmptyState\r\n icon={<FolderOpen />}\r\n title={emptyMessage}\r\n description=\"There are no records to display.\"\r\n size=\"sm\"\r\n />\r\n )}\r\n </td>\r\n </tr>\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* ── Footer / Pagination ───────────────────────────────────────────── */}\r\n {showFooter && (\r\n <div className=\"eidos-table-footer\">\r\n <div className=\"eidos-table-footer-content\">\r\n {showPagination && data.length > 0 ? (\r\n <Pagination\r\n page={currentPage}\r\n totalPages={totalPages}\r\n onChange={handlePageChange}\r\n totalItems={totalItems ?? data.length}\r\n pageSize={currentPageSize}\r\n onPageSizeChange={handlePageSizeChange}\r\n pageSizeOptions={pageSizeOptions}\r\n size=\"sm\"\r\n />\r\n ) : (\r\n <span className=\"eidos-table-results-info\">\r\n Showing {data.length} of {totalItems ?? data.length} results\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n\r\n // ── Wrap with DnD context when draggableColumns=true ─────────────────────\r\n if (draggableColumns) {\r\n return (\r\n <DndContext sensors={sensors} onDragEnd={handleDragEnd}>\r\n <SortableContext items={sortableItems} strategy={horizontalListSortingStrategy}>\r\n {tableContent}\r\n </SortableContext>\r\n </DndContext>\r\n );\r\n }\r\n\r\n return tableContent;\r\n};\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Divider/Divider.component.tsx"],"sourcesContent":["import React from 'react';\r\nimport type { DividerProps } from './Divider.types';\r\n\r\nexport const Divider: React.FC<DividerProps> = ({\r\n direction = 'horizontal',\r\n className = '',\r\n ...rest\r\n}) => {\r\n return (\r\n <div\r\n role=\"separator\"\r\n {...rest}\r\n className={['eidos-divider', `eidos-divider--${direction}`, className]\r\n .filter(Boolean)\r\n .join(' ')}\r\n />\r\n );\r\n};\r\n"],"mappings":";AASI;AANG,IAAM,UAAkC,CAAC;AAAA,EAC9C,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,GAAG;AACL,MAAM;AACJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACJ,GAAG;AAAA,MACJ,WAAW,CAAC,iBAAiB,kBAAkB,SAAS,IAAI,SAAS,EAClE,OAAO,OAAO,EACd,KAAK,GAAG;AAAA;AAAA,EACb;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-LTOHGCU4.cjs","../src/components/Button/Button.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACNA,2CAA6B;AAoDjB,+CAAA;AA/CL,IAAM,OAAA,EAAgC,CAAC;AAAA,EAC5C,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,IAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,QAAA,EAAU,KAAA;AAAA,EACV,YAAA,EAAc,YAAA;AAAA,EACd,OAAA;AAAA,EACA,UAAA,EAAY,EAAA;AAAA,EACZ,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAA,GAAM;AACJ,EAAA,MAAM,WAAA,EAAa,CAAC,CAAC,IAAA;AAErB,EAAA,GAAA,CAAI,UAAA,EAAY;AACd,IAAA,GAAA,CAAI,QAAA,EAAU;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,wCAAwC,CAAA;AAAA,IAC1D;AACA,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA;AAAA,IACzD;AACA,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA;AAAA,IACzD;AAAA,EACF;AAEA,EAAA,MAAM,cAAA,EAAgB;AAAA,IACpB,cAAA;AAAA,IACA,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAA;AACF,IAAA;AACD,IAAA;AACP,IAAA;AACF,IAAA;AACD,IAAA;AACX,IAAA;AAGS,EAAA;AAGT,EAAA;AAIQ,IAAA;AACG,sBAAA;AAGA,sBAAA;AACH,IAAA;AAGA,IAAA;AAMJ,EAAA;AACyB,IAAA;AAGrB,IAAA;AAKqB,IAAA;AAG7B,EAAA;AAGe,EAAA;AACnB;AAagE;AACtD,EAAA;AACV;ADnC6B;AACA;AACA;AACA;AACA","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-LTOHGCU4.cjs","sourcesContent":[null,"import React from 'react';\r\nimport { LoaderCircle } from 'lucide-react';\r\nimport { Tooltip } from '../Tooltip';\r\nimport { ButtonProps, IconButtonProps } from './Button.types';\r\nimport { renderIcon } from '../../utils';\r\n\r\nexport const Button: React.FC<ButtonProps> = ({\r\n variant = 'filled',\r\n color = 'primary',\r\n size = 'md',\r\n disabled = false,\r\n loading = false,\r\n loadingText = 'Loading...',\r\n tooltip,\r\n className = '',\r\n preIcon,\r\n posIcon,\r\n icon,\r\n children,\r\n ...buttonProps\r\n}) => {\r\n const isIconOnly = !!icon;\r\n\r\n if (isIconOnly) {\r\n if (children) {\r\n throw new Error('Icon-only buttons cannot have children');\r\n }\r\n if (preIcon) {\r\n throw new Error('Icon-only buttons cannot have preIcon');\r\n }\r\n if (posIcon) {\r\n throw new Error('Icon-only buttons cannot have posIcon');\r\n }\r\n }\r\n\r\n const buttonClasses = [\r\n 'eidos-button',\r\n `eidos-button--${variant}`,\r\n `eidos-button--${color}`,\r\n `eidos-button--${size}`,\r\n isIconOnly && 'eidos-button--icon-only',\r\n disabled && 'eidos-button--disabled',\r\n loading && 'eidos-button--loading',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const buttonContent = (\r\n <button type=\"button\" {...buttonProps} className={buttonClasses} disabled={disabled || loading}>\r\n {loading ? (\r\n <>\r\n {!isIconOnly && (\r\n <>\r\n <span className=\"eidos-button--loading-spinner\">\r\n <LoaderCircle className=\"eidos-button--spinner-icon\" />\r\n </span>\r\n <span className=\"eidos-button--copy\">{loadingText}</span>\r\n </>\r\n )}\r\n {isIconOnly && (\r\n <span className=\"eidos-button--loading-spinner\">\r\n <LoaderCircle className=\"eidos-button--spinner-icon\" />\r\n </span>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n {preIcon && renderIcon(preIcon, 'eidos-button--pre-icon')}\r\n\r\n {isIconOnly && icon ? (\r\n renderIcon(icon, 'eidos-button--icon')\r\n ) : (\r\n <span className=\"eidos-button--copy\">{children}</span>\r\n )}\r\n\r\n {posIcon && renderIcon(posIcon, 'eidos-button--pos-icon')}\r\n </>\r\n )}\r\n </button>\r\n );\r\n\r\n return tooltip ? <Tooltip message={tooltip}>{buttonContent}</Tooltip> : buttonContent;\r\n};\r\n\r\n/**\r\n * IconButton - Convenience wrapper for icon-only buttons\r\n *\r\n * @example\r\n * ```tsx\r\n * import { IconButton } from 'eidos-ui';\r\n * import { Plus } from 'lucide-react';\r\n *\r\n * <IconButton icon={Plus} tooltip=\"Add item\" />\r\n * ```\r\n */\r\nexport const IconButton: React.FC<IconButtonProps> = (props) => {\r\n return <Button {...props} />;\r\n};\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-M56IGNH7.cjs","../src/components/InlineEdit/InlineEdit.component.tsx"],"names":[],"mappings":"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","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-M56IGNH7.cjs","sourcesContent":[null,"import React, { useState, useRef, useCallback } from 'react';\r\nimport { Pencil } from 'lucide-react';\r\nimport { Input } from '../Input/Input.component';\r\nimport type { InlineEditProps } from './InlineEdit.types';\r\nimport './InlineEdit.scss';\r\n\r\nexport const InlineEdit: React.FC<InlineEditProps> = ({\r\n value,\r\n onChange,\r\n onConfirm,\r\n onCancel,\r\n editing: editingProp,\r\n onEditingChange,\r\n type = 'text',\r\n placeholder,\r\n trigger = 'click',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n confirmOnBlur = true,\r\n renderDisplay,\r\n showEditIcon = true,\r\n inputVariant = 'outlined',\r\n className = '',\r\n}) => {\r\n const isControlled = editingProp !== undefined;\r\n const [internalEditing, setInternalEditing] = useState(false);\r\n const editing = isControlled ? editingProp : internalEditing;\r\n\r\n // Track the value at the moment editing begins so Esc can revert to it.\r\n const valueAtEditStart = useRef(value);\r\n\r\n // Local draft while editing - keeps Input value in sync without forcing the\r\n // parent to wire `onChange` just to see live keystrokes.\r\n const [draft, setDraft] = useState(value);\r\n\r\n // ------------------------------------------------------------------\r\n // Editing state helpers\r\n // ------------------------------------------------------------------\r\n\r\n const openEdit = useCallback(() => {\r\n if (disabled) return;\r\n valueAtEditStart.current = value;\r\n setDraft(value);\r\n if (!isControlled) setInternalEditing(true);\r\n onEditingChange?.(true);\r\n }, [disabled, isControlled, onEditingChange, value]);\r\n\r\n const closeEdit = useCallback(() => {\r\n if (!isControlled) setInternalEditing(false);\r\n onEditingChange?.(false);\r\n }, [isControlled, onEditingChange]);\r\n\r\n const confirm = useCallback(() => {\r\n closeEdit();\r\n onConfirm?.(draft);\r\n }, [closeEdit, draft, onConfirm]);\r\n\r\n const cancel = useCallback(() => {\r\n // Revert the draft AND propagate the original value so the parent stays in\r\n // sync when `onChange` is used to maintain external state.\r\n setDraft(valueAtEditStart.current);\r\n onChange?.(valueAtEditStart.current);\r\n closeEdit();\r\n onCancel?.();\r\n }, [closeEdit, onChange, onCancel]);\r\n\r\n // ------------------------------------------------------------------\r\n // Input handlers\r\n // ------------------------------------------------------------------\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n setDraft(e.target.value);\r\n onChange?.(e.target.value);\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === 'Enter') {\r\n e.preventDefault();\r\n // Stop propagation so parent grids/tables don't double-handle Enter.\r\n e.stopPropagation();\r\n confirm();\r\n } else if (e.key === 'Escape') {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n cancel();\r\n }\r\n // Tab and Arrow keys intentionally bubble - consumers like DataGrid own\r\n // Tab-to-next-cell and arrow-key navigation at the container level.\r\n };\r\n\r\n const handleBlur = () => {\r\n if (confirmOnBlur) confirm();\r\n };\r\n\r\n // ------------------------------------------------------------------\r\n // Trigger props for display mode\r\n // ------------------------------------------------------------------\r\n\r\n const displayTriggerProps =\r\n trigger === 'doubleClick' ? { onDoubleClick: openEdit } : { onClick: openEdit };\r\n\r\n // ------------------------------------------------------------------\r\n // Render: edit mode\r\n // ------------------------------------------------------------------\r\n\r\n if (editing) {\r\n return (\r\n <Input\r\n type={type}\r\n variant={inputVariant}\r\n size={size}\r\n value={draft}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n onBlur={handleBlur}\r\n placeholder={placeholder}\r\n fullWidth={fullWidth}\r\n clearable={false}\r\n autoFocus\r\n className={`eidos-inline-edit eidos-inline-edit--editing ${className}`}\r\n />\r\n );\r\n }\r\n\r\n // ------------------------------------------------------------------\r\n // Render: display mode\r\n // ------------------------------------------------------------------\r\n\r\n const isEmpty = !value;\r\n\r\n return (\r\n <span\r\n role=\"button\"\r\n tabIndex={disabled ? undefined : 0}\r\n aria-label={disabled ? undefined : 'Click to edit'}\r\n className={[\r\n 'eidos-inline-edit',\r\n `eidos-inline-edit--${size}`,\r\n fullWidth ? 'eidos-inline-edit--full-width' : '',\r\n disabled ? 'eidos-inline-edit--disabled' : '',\r\n isEmpty ? 'eidos-inline-edit--empty' : '',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n {...(disabled ? {} : displayTriggerProps)}\r\n onKeyDown={\r\n disabled\r\n ? undefined\r\n : (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n openEdit();\r\n }\r\n }\r\n }\r\n >\r\n <span className=\"eidos-inline-edit__text\">\r\n {renderDisplay\r\n ? renderDisplay(value)\r\n : value || <span className=\"eidos-inline-edit__placeholder\">{placeholder}</span>}\r\n </span>\r\n {!disabled && showEditIcon && (\r\n <span className=\"eidos-inline-edit__icon\" aria-hidden>\r\n <Pencil />\r\n </span>\r\n )}\r\n </span>\r\n );\r\n};\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-N7HX5635.cjs","../src/components/Drawer/Drawer.component.tsx"],"names":[],"mappings":"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","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-N7HX5635.cjs","sourcesContent":[null,"import React, { useEffect, useCallback, useId, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { X } from 'lucide-react';\r\nimport { Button } from '../Button';\r\nimport type { DrawerProps } from './Drawer.types';\r\n\r\nexport const Drawer: React.FC<DrawerProps> = ({\r\n isOpen,\r\n onClose,\r\n placement = 'right',\r\n title,\r\n children,\r\n actions,\r\n size = 'md',\r\n closeOnBackdropClick = true,\r\n closeOnEscape = true,\r\n className = '',\r\n}) => {\r\n const titleId = useId();\r\n const bodyId = useId();\r\n\r\n // ── Animation state ────────────────────────────────────────────────────────\r\n // isMounted: whether the portal DOM node exists at all.\r\n // isVisible: whether the '--open' CSS class is applied (drives the transition).\r\n //\r\n // On open: mount first → one rAF → apply --open (browser sees initial\r\n // closed position before transitioning, so the animation fires).\r\n // On close: remove --open (CSS transition plays) → after 300 ms unmount.\r\n // 300 ms matches the CSS `transition: 0.3s` in Drawer.scss.\r\n const TRANSITION_MS = 300;\r\n const [isMounted, setIsMounted] = useState(isOpen);\r\n const [isVisible, setIsVisible] = useState(isOpen);\r\n\r\n useEffect(() => {\r\n let raf1 = 0;\r\n let raf2 = 0;\r\n let timerId: ReturnType<typeof setTimeout>;\r\n\r\n if (isOpen) {\r\n setIsMounted(true);\r\n // Double rAF: React 18 automatic batching means setIsMounted(true) may\r\n // not produce a committed browser paint before the first rAF fires.\r\n // The second frame guarantees the panel is rendered in its off-screen\r\n // (closed) position before the CSS transition begins.\r\n raf1 = requestAnimationFrame(() => {\r\n raf2 = requestAnimationFrame(() => setIsVisible(true));\r\n });\r\n } else {\r\n setIsVisible(false);\r\n timerId = setTimeout(() => setIsMounted(false), TRANSITION_MS);\r\n }\r\n\r\n return () => {\r\n cancelAnimationFrame(raf1);\r\n cancelAnimationFrame(raf2);\r\n clearTimeout(timerId);\r\n };\r\n }, [isOpen]);\r\n\r\n // ── Escape key + scroll lock (tied to isOpen, not isMounted) ───────────────\r\n const handleEscapeKey = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (closeOnEscape && event.key === 'Escape' && isOpen) {\r\n onClose();\r\n }\r\n },\r\n [closeOnEscape, isOpen, onClose],\r\n );\r\n\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.addEventListener('keydown', handleEscapeKey);\r\n document.body.style.overflow = 'hidden';\r\n }\r\n return () => {\r\n document.removeEventListener('keydown', handleEscapeKey);\r\n document.body.style.overflow = '';\r\n };\r\n }, [isOpen, handleEscapeKey]);\r\n\r\n // ── Backdrop click ─────────────────────────────────────────────────────────\r\n const handleBackdropClick = useCallback(\r\n (event: React.MouseEvent) => {\r\n if (closeOnBackdropClick && event.target === event.currentTarget) {\r\n onClose();\r\n }\r\n },\r\n [closeOnBackdropClick, onClose],\r\n );\r\n\r\n if (!isMounted) return null;\r\n\r\n return createPortal(\r\n <div\r\n className={[\r\n 'eidos-drawer',\r\n `eidos-drawer--${placement}`,\r\n isVisible && 'eidos-drawer--open',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n >\r\n {/* Backdrop */}\r\n <div className=\"eidos-drawer-backdrop\" onClick={handleBackdropClick} aria-hidden=\"true\" />\r\n\r\n {/* Panel */}\r\n <div\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby={title ? titleId : undefined}\r\n aria-describedby={bodyId}\r\n className={[\r\n 'eidos-drawer-panel',\r\n `eidos-drawer-panel--${size}`,\r\n `eidos-drawer-panel--${placement}`,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n >\r\n {/* Header */}\r\n <div className=\"eidos-drawer-header\">\r\n {title && (\r\n <h3 id={titleId} className=\"eidos-drawer-title\">\r\n {title}\r\n </h3>\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"eidos-drawer-close\"\r\n onClick={onClose}\r\n aria-label=\"Close drawer\"\r\n >\r\n <X aria-hidden=\"true\" />\r\n </button>\r\n </div>\r\n\r\n {/* Body */}\r\n <div id={bodyId} className=\"eidos-drawer-body\">\r\n {children}\r\n </div>\r\n\r\n {/* Footer - only rendered when actions are provided */}\r\n {actions && actions.length > 0 && (\r\n <div className=\"eidos-drawer-footer\">\r\n {actions.map((action) => (\r\n <Button\r\n key={action.id}\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color}\r\n disabled={action.disabled}\r\n loading={action.loading}\r\n onClick={action.onClick}\r\n >\r\n {action.label}\r\n </Button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n};\r\n\r\nDrawer.displayName = 'Drawer';\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Table/Table.component.tsx"],"sourcesContent":["import { useState, useMemo, useLayoutEffect, useRef } from 'react';\r\nimport React from 'react';\r\nimport {\r\n ChevronsUpDown,\r\n ArrowUp,\r\n ArrowDown,\r\n X,\r\n Check,\r\n Download,\r\n Columns3,\r\n AlignJustify,\r\n GripVertical,\r\n FolderOpen,\r\n SearchX,\r\n} from 'lucide-react';\r\nimport { DndContext, PointerSensor, KeyboardSensor, useSensor, useSensors } from '@dnd-kit/core';\r\nimport type { DragEndEvent } from '@dnd-kit/core';\r\nimport {\r\n SortableContext,\r\n horizontalListSortingStrategy,\r\n useSortable,\r\n sortableKeyboardCoordinates,\r\n arrayMove,\r\n} from '@dnd-kit/sortable';\r\nimport { CSS } from '@dnd-kit/utilities';\r\nimport type { TableColumn, TableProps, TableFilters, FilterValue } from './Table.types';\r\n\r\nexport type { TableColumn, TableProps, TableFilters, FilterValue };\r\nimport { Button } from '../Button';\r\nimport { Checkbox } from '../Checkbox';\r\nimport { Dropdown } from '../Dropdown';\r\nimport { EmptyState } from '../EmptyState';\r\nimport { Pagination } from '../Pagination';\r\nimport { SplitButton } from '../SplitButton';\r\nimport { Spinner } from '../Spinner';\r\nimport { TableFiltersDropdown } from './TableFiltersDropdown.component';\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\ntype Density = 'compact' | 'comfortable' | 'spacious';\r\n\r\nconst DENSITY_OPTIONS: { value: Density; label: string }[] = [\r\n { value: 'compact', label: 'Compact' },\r\n { value: 'comfortable', label: 'Comfortable' },\r\n { value: 'spacious', label: 'Spacious' },\r\n];\r\n\r\n// ── CSV helpers ───────────────────────────────────────────────────────────────\r\n\r\nfunction escapeCsvValue(value: string): string {\r\n if (value.includes(',') || value.includes('\\n') || value.includes('\"')) {\r\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n return value;\r\n}\r\n\r\n// ── SortableColumnHeader ──────────────────────────────────────────────────────\r\n// Defined as a standalone component so it can legally call useSortable().\r\n// Only rendered when draggableColumns=true (inside a DndContext + SortableContext).\r\n\r\ninterface SortableThProps {\r\n id: string;\r\n column: { label: string };\r\n isSortable: boolean;\r\n isCurrentlySorted: boolean;\r\n sortDirection: 'asc' | 'desc' | null;\r\n alignment: string;\r\n columnType: string;\r\n columnWidth: string | undefined;\r\n pinnedClass: string;\r\n stickyStyle: React.CSSProperties;\r\n onSortClick: () => void;\r\n}\r\n\r\nfunction SortableColumnHeader({\r\n id,\r\n column,\r\n isSortable,\r\n isCurrentlySorted,\r\n sortDirection,\r\n alignment,\r\n columnType,\r\n columnWidth,\r\n pinnedClass,\r\n stickyStyle,\r\n onSortClick,\r\n}: SortableThProps) {\r\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\r\n id,\r\n });\r\n\r\n const transformStr = CSS.Transform.toString(transform);\r\n\r\n const thClassName = [\r\n 'eidos-table-header-cell',\r\n `eidos-table-header-cell-${columnType}`,\r\n isSortable ? 'eidos-table-sortable' : '',\r\n isCurrentlySorted ? 'eidos-table-sorted' : '',\r\n `eidos-table-align-${alignment}`,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <th\r\n ref={setNodeRef as React.LegacyRef<HTMLTableCellElement>}\r\n className={thClassName}\r\n style={{\r\n width: columnWidth,\r\n ...stickyStyle,\r\n ...(transformStr ? { transform: transformStr } : {}),\r\n transition: transition ?? undefined,\r\n opacity: isDragging ? 0.5 : 1,\r\n }}\r\n data-col-key={id}\r\n onClick={() => isSortable && onSortClick()}\r\n {...attributes}\r\n >\r\n {/* Grip - absolutely positioned in the left padding zone so it never\r\n displaces the column label or causes layout shift on hover. */}\r\n <span\r\n className=\"eidos-table-drag-handle\"\r\n {...listeners}\r\n onClick={(e) => e.stopPropagation()}\r\n title=\"Drag to reorder\"\r\n >\r\n <GripVertical size={12} />\r\n </span>\r\n <div className={`eidos-table-header-content eidos-table-align-${alignment}`}>\r\n <span className=\"eidos-table-header-label\">{column.label}</span>\r\n {isSortable && (\r\n <div className=\"eidos-table-sort-indicator\">\r\n {sortDirection === 'asc' && <ArrowUp size={14} />}\r\n {sortDirection === 'desc' && <ArrowDown size={14} />}\r\n {!sortDirection && <ChevronsUpDown size={14} />}\r\n </div>\r\n )}\r\n </div>\r\n </th>\r\n );\r\n}\r\n\r\n// ── Table ─────────────────────────────────────────────────────────────────────\r\n\r\nexport const Table = <T extends Record<string, unknown>>({\r\n data,\r\n columns,\r\n loading = false,\r\n emptyMessage = 'No data available',\r\n onRowClick,\r\n className,\r\n showFooter = false,\r\n totalItems,\r\n showPagination = false,\r\n pageSize = 25,\r\n pageSizeOptions = [10, 25, 50, 100],\r\n onSortChange,\r\n currentSort,\r\n filters = {},\r\n onFiltersChange,\r\n defaultFilters,\r\n showFilters = false,\r\n // Selection\r\n selectable = false,\r\n rowKey,\r\n selectedRows: controlledSelected,\r\n defaultSelectedRows = [],\r\n onSelectionChange,\r\n bulkActions = [],\r\n // New features\r\n density = 'comfortable',\r\n showDensity = false,\r\n showColumnVisibility = false,\r\n showExport = false,\r\n draggableColumns = false,\r\n onColumnReorder,\r\n}: TableProps<T>) => {\r\n // ── Column ordering (drag-reorder) ────────────────────────────────────────\r\n const [columnOrder, setColumnOrder] = useState<string[]>(() => columns.map((c) => String(c.key)));\r\n\r\n // Derived-state reset: when the set of column keys changes, reset the order.\r\n // Calling setState during render is the React-idiomatic way to do this.\r\n const columnKeysSignature = columns.map((c) => String(c.key)).join('\\0');\r\n const prevKeysRef = useRef(columnKeysSignature);\r\n if (prevKeysRef.current !== columnKeysSignature) {\r\n prevKeysRef.current = columnKeysSignature;\r\n setColumnOrder(columns.map((c) => String(c.key)));\r\n }\r\n\r\n const orderedColumns = useMemo(() => {\r\n const orderMap = new Map(columnOrder.map((key, idx) => [key, idx]));\r\n return [...columns].sort((a, b) => {\r\n const ai = orderMap.get(String(a.key)) ?? Infinity;\r\n const bi = orderMap.get(String(b.key)) ?? Infinity;\r\n return ai - bi;\r\n });\r\n }, [columns, columnOrder]);\r\n\r\n // ── Density (internal state when showDensity=true) ────────────────────────\r\n const [internalDensity, setInternalDensity] = useState<Density>(density as Density);\r\n // When showDensity is true the table owns density; otherwise respect the prop.\r\n const effectiveDensity: Density = showDensity ? internalDensity : (density as Density);\r\n\r\n // ── Column visibility ─────────────────────────────────────────────────────\r\n const [hiddenColumnKeys, setHiddenColumnKeys] = useState<Set<string>>(() => new Set<string>());\r\n\r\n const visibleColumns = useMemo(\r\n () => orderedColumns.filter((c) => !hiddenColumnKeys.has(String(c.key))),\r\n [orderedColumns, hiddenColumnKeys],\r\n );\r\n\r\n // ── Pinned / sticky columns ────────────────────────────────────────────────\r\n const theadRef = useRef<HTMLTableSectionElement>(null);\r\n const [pinnedOffsets, setPinnedOffsets] = useState<\r\n Map<string, { side: 'left' | 'right'; offset: number }>\r\n >(new Map());\r\n\r\n useLayoutEffect(() => {\r\n const hasPinned = visibleColumns.some((c) => c.pin);\r\n if (!hasPinned || !theadRef.current) {\r\n setPinnedOffsets(new Map());\r\n return;\r\n }\r\n\r\n const headerRow = theadRef.current.querySelector('tr');\r\n if (!headerRow) return;\r\n\r\n const cells = Array.from(headerRow.querySelectorAll<HTMLTableCellElement>('th[data-col-key]'));\r\n\r\n const newOffsets = new Map<string, { side: 'left' | 'right'; offset: number }>();\r\n\r\n // Left-pinned: scan left-to-right.\r\n // Checkbox (when selectable) counts as a left-pinned element.\r\n let leftAccum = 0;\r\n for (const cell of cells) {\r\n const key = cell.dataset.colKey!;\r\n if (key === '__checkbox__') {\r\n newOffsets.set(key, { side: 'left', offset: leftAccum });\r\n leftAccum += cell.offsetWidth;\r\n } else {\r\n const col = visibleColumns.find((c) => String(c.key) === key);\r\n if (col?.pin === 'left') {\r\n newOffsets.set(key, { side: 'left', offset: leftAccum });\r\n leftAccum += cell.offsetWidth;\r\n }\r\n }\r\n }\r\n\r\n // Right-pinned: scan right-to-left.\r\n let rightAccum = 0;\r\n for (let i = cells.length - 1; i >= 0; i--) {\r\n const cell = cells[i];\r\n const key = cell.dataset.colKey!;\r\n const col = visibleColumns.find((c) => String(c.key) === key);\r\n if (col?.pin === 'right') {\r\n newOffsets.set(key, { side: 'right', offset: rightAccum });\r\n rightAccum += cell.offsetWidth;\r\n }\r\n }\r\n\r\n setPinnedOffsets(newOffsets);\r\n }, [visibleColumns, selectable]);\r\n\r\n // ── Selection state (controlled / uncontrolled) ──────────────────────────\r\n const isControlledSelection = controlledSelected !== undefined;\r\n const [internalSelected, setInternalSelected] = useState<string[]>(defaultSelectedRows);\r\n const selectedSet = useMemo(\r\n () => new Set(isControlledSelection ? controlledSelected : internalSelected),\r\n [isControlledSelection, controlledSelected, internalSelected],\r\n );\r\n\r\n /** Stable string key for a row - uses `rowKey` prop, then \"id\", then index. */\r\n const getRowKey = (item: T, index: number): string => {\r\n if (rowKey) return String(item[rowKey]);\r\n if ('id' in item) return String(item.id);\r\n return String(index);\r\n };\r\n\r\n const commitSelection = (keys: string[]) => {\r\n if (!isControlledSelection) setInternalSelected(keys);\r\n const rows = data.filter((item, idx) => keys.includes(getRowKey(item, idx)));\r\n onSelectionChange?.(keys, rows);\r\n };\r\n\r\n const toggleRow = (key: string) => {\r\n const next = selectedSet.has(key)\r\n ? [...selectedSet].filter((k) => k !== key)\r\n : [...selectedSet, key];\r\n commitSelection(next);\r\n };\r\n\r\n const allKeys = useMemo(\r\n () => data.map((item, idx) => getRowKey(item, idx)),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [data, rowKey],\r\n );\r\n\r\n const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));\r\n const someSelected = !allSelected && allKeys.some((k) => selectedSet.has(k));\r\n\r\n const toggleAll = () => {\r\n commitSelection(allSelected ? [] : allKeys);\r\n };\r\n\r\n const clearSelection = () => commitSelection([]);\r\n\r\n // ── Pagination ────────────────────────────────────────────────────────────\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [currentPageSize, setCurrentPageSize] = useState(pageSize);\r\n\r\n const displayData = useMemo(() => {\r\n if (!showPagination) return data;\r\n const startIndex = (currentPage - 1) * currentPageSize;\r\n return data.slice(startIndex, startIndex + currentPageSize);\r\n }, [data, showPagination, currentPage, currentPageSize]);\r\n\r\n const totalPages = Math.ceil(data.length / currentPageSize);\r\n\r\n const handleSort = (key: string) => {\r\n const newDirection =\r\n currentSort?.key === key && currentSort?.direction === 'asc' ? 'desc' : 'asc';\r\n onSortChange?.(key, newDirection);\r\n };\r\n\r\n const handlePageChange = (page: number) => setCurrentPage(page);\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setCurrentPageSize(newPageSize);\r\n setCurrentPage(1);\r\n };\r\n\r\n // ── Derived UI state ──────────────────────────────────────────────────────\r\n const hasSelection = selectedSet.size > 0;\r\n const showToolbar =\r\n (showFilters && !!onFiltersChange) ||\r\n showColumnVisibility ||\r\n showExport ||\r\n showDensity ||\r\n (selectable && hasSelection);\r\n\r\n const selectedItems = useMemo(\r\n () => data.filter((item, idx) => selectedSet.has(getRowKey(item, idx))),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [data, selectedSet, rowKey],\r\n );\r\n\r\n // ── CSV Export ────────────────────────────────────────────────────────────\r\n const getRawValue = (item: T, column: TableColumn<T>): string => {\r\n const value =\r\n typeof column.key === 'string' && column.key.includes('.')\r\n ? (column.key as string)\r\n .split('.')\r\n .reduce(\r\n (obj: unknown, k: string) => (obj as Record<string, unknown>)?.[k],\r\n item as unknown,\r\n )\r\n : item[column.key as keyof T];\r\n return String(value ?? '');\r\n };\r\n\r\n const handleExportCsv = () => {\r\n const headers = visibleColumns.map((c) => escapeCsvValue(c.label)).join(',');\r\n const rows = data.map((item) =>\r\n visibleColumns.map((col) => escapeCsvValue(getRawValue(item, col))).join(','),\r\n );\r\n const csv = [headers, ...rows].join('\\n');\r\n const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\r\n const url = URL.createObjectURL(blob);\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.download = 'export.csv';\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n URL.revokeObjectURL(url);\r\n };\r\n\r\n // ── DnD setup ─────────────────────────────────────────────────────────────\r\n const sensors = useSensors(\r\n useSensor(PointerSensor),\r\n useSensor(KeyboardSensor, {\r\n coordinateGetter: sortableKeyboardCoordinates,\r\n }),\r\n );\r\n\r\n const handleDragEnd = (event: DragEndEvent) => {\r\n const { active, over } = event;\r\n if (!over || active.id === over.id) return;\r\n\r\n const activeId = String(active.id);\r\n const overId = String(over.id);\r\n const oldIndex = columnOrder.indexOf(activeId);\r\n const newIndex = columnOrder.indexOf(overId);\r\n if (oldIndex === -1 || newIndex === -1) return;\r\n\r\n const newOrder = arrayMove(columnOrder, oldIndex, newIndex);\r\n setColumnOrder(newOrder);\r\n\r\n if (onColumnReorder) {\r\n const orderMap = new Map(newOrder.map((key, idx) => [key, idx]));\r\n const reordered = [...columns].sort((a, b) => {\r\n const ai = orderMap.get(String(a.key)) ?? Infinity;\r\n const bi = orderMap.get(String(b.key)) ?? Infinity;\r\n return ai - bi;\r\n });\r\n onColumnReorder(reordered);\r\n }\r\n };\r\n\r\n // ── Helpers ───────────────────────────────────────────────────────────────\r\n\r\n /** Returns sticky style + className for body <td> cells (zIndex: 1). */\r\n const getCellPinnedProps = (\r\n colKey: string,\r\n ): { style: React.CSSProperties; className: string } => {\r\n const pinInfo = pinnedOffsets.get(colKey);\r\n if (!pinInfo) return { style: {}, className: '' };\r\n return {\r\n style: {\r\n position: 'sticky',\r\n [pinInfo.side]: pinInfo.offset,\r\n zIndex: 1,\r\n },\r\n className:\r\n pinInfo.side === 'left'\r\n ? 'eidos-table-cell--pinned-left'\r\n : 'eidos-table-cell--pinned-right',\r\n };\r\n };\r\n\r\n /** Returns sticky style + className for header <th> cells (zIndex: 3). */\r\n const getHeaderPinnedProps = (\r\n colKey: string,\r\n ): { style: React.CSSProperties; className: string } => {\r\n const pinInfo = pinnedOffsets.get(colKey);\r\n if (!pinInfo) return { style: {}, className: '' };\r\n return {\r\n style: {\r\n position: 'sticky',\r\n [pinInfo.side]: pinInfo.offset,\r\n zIndex: 3,\r\n },\r\n className:\r\n pinInfo.side === 'left'\r\n ? 'eidos-table-header-cell--pinned-left'\r\n : 'eidos-table-header-cell--pinned-right',\r\n };\r\n };\r\n\r\n // ── Density class ─────────────────────────────────────────────────────────\r\n const densityClass = effectiveDensity !== 'comfortable' ? `eidos-table--${effectiveDensity}` : '';\r\n\r\n // ── Loading ───────────────────────────────────────────────────────────────\r\n if (loading) {\r\n return (\r\n <div className={`eidos-table-container ${className || ''}`}>\r\n <div className=\"eidos-table-loading\">\r\n <Spinner size=\"md\" />\r\n <p>Loading...</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // ── Density panel (Dropdown content) ──────────────────────────────────────\r\n const densityPanel = (\r\n <div className=\"eidos-table-menu-panel\">\r\n {DENSITY_OPTIONS.map((option) => (\r\n <button\r\n key={option.value}\r\n className={[\r\n 'eidos-table-menu-item',\r\n effectiveDensity === option.value ? 'eidos-table-menu-item--active' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => setInternalDensity(option.value)}\r\n >\r\n <span className=\"eidos-table-menu-item-check\">\r\n {effectiveDensity === option.value && <Check size={14} />}\r\n </span>\r\n <span>{option.label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n\r\n // ── Column visibility panel (Dropdown content) ────────────────────────────\r\n const columnVisibilityPanel = (\r\n <div className=\"eidos-table-menu-panel\">\r\n {/* Use orderedColumns so list order mirrors current column order */}\r\n {orderedColumns.map((col) => {\r\n const key = String(col.key);\r\n const isVisible = !hiddenColumnKeys.has(key);\r\n const isLastVisible = visibleColumns.length === 1 && isVisible;\r\n return (\r\n <button\r\n key={key}\r\n className={['eidos-table-menu-item', isVisible ? 'eidos-table-menu-item--active' : '']\r\n .filter(Boolean)\r\n .join(' ')}\r\n disabled={isLastVisible}\r\n onClick={() => {\r\n setHiddenColumnKeys((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(key)) next.delete(key);\r\n else next.add(key);\r\n return next;\r\n });\r\n }}\r\n >\r\n <Checkbox\r\n checked={isVisible}\r\n disabled={isLastVisible}\r\n size=\"sm\"\r\n onChange={() => {\r\n /* click handled by parent button */\r\n }}\r\n />\r\n <span>{col.label}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n\r\n // ── SortableContext items: visible column keys only ───────────────────────\r\n const sortableItems = visibleColumns.map((c) => String(c.key));\r\n\r\n // ── Main JSX ──────────────────────────────────────────────────────────────\r\n const tableContent = (\r\n <div className={`eidos-table-container ${className || ''}`}>\r\n {/* ── Toolbar ───────────────────────────────────────────────────────── */}\r\n {showToolbar && (\r\n <div className=\"eidos-table-toolbar\">\r\n {/* Left - bulk actions / selection info */}\r\n <div className=\"eidos-table-toolbar-left\">\r\n {selectable && hasSelection && (\r\n <>\r\n <span className=\"eidos-table-selection-count\">{selectedSet.size} selected</span>\r\n\r\n {bulkActions.length > 0 && (\r\n <div className=\"eidos-table-bulk-actions\">\r\n {bulkActions.map((action) => {\r\n const isDisabled =\r\n typeof action.disabled === 'function'\r\n ? action.disabled(selectedItems)\r\n : (action.disabled ?? false);\r\n\r\n if (action.type === 'split-button') {\r\n return (\r\n <SplitButton\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n preIcon={action.icon}\r\n disabled={isDisabled}\r\n label={action.label}\r\n onClick={() => action.onClick(selectedItems)}\r\n options={action.options.map((option) => ({\r\n id: option.id,\r\n label: option.label,\r\n icon: option.icon,\r\n disabled: option.disabled,\r\n onClick: () => option.onClick(selectedItems),\r\n }))}\r\n />\r\n );\r\n }\r\n\r\n return action.label ? (\r\n <Button\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n preIcon={action.icon}\r\n posIcon={action.posIcon}\r\n disabled={isDisabled}\r\n onClick={() => action.onClick(selectedItems)}\r\n >\r\n {action.label}\r\n </Button>\r\n ) : action.icon ? (\r\n <Button\r\n key={action.id}\r\n size=\"sm\"\r\n variant={action.variant ?? 'outlined'}\r\n color={action.color ?? 'secondary'}\r\n icon={action.icon}\r\n disabled={isDisabled}\r\n onClick={() => action.onClick(selectedItems)}\r\n />\r\n ) : null;\r\n })}\r\n </div>\r\n )}\r\n\r\n <button\r\n className=\"eidos-table-clear-selection\"\r\n onClick={clearSelection}\r\n aria-label=\"Clear selection\"\r\n >\r\n <X size={14} />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Right - density, column visibility, export, filter */}\r\n <div className=\"eidos-table-toolbar-right\">\r\n {showDensity && (\r\n <Dropdown\r\n placement=\"bottom\"\r\n align=\"end\"\r\n autoWidth={false}\r\n trigger={\r\n <Button variant=\"text\" size=\"sm\" preIcon={AlignJustify}>\r\n Density\r\n </Button>\r\n }\r\n content={densityPanel}\r\n />\r\n )}\r\n\r\n {showColumnVisibility && (\r\n <Dropdown\r\n placement=\"bottom\"\r\n align=\"end\"\r\n autoWidth={false}\r\n trigger={\r\n <Button variant=\"text\" size=\"sm\" preIcon={Columns3}>\r\n Columns\r\n </Button>\r\n }\r\n content={columnVisibilityPanel}\r\n />\r\n )}\r\n\r\n {showExport && (\r\n <Button\r\n variant=\"text\"\r\n size=\"sm\"\r\n icon={Download}\r\n onClick={handleExportCsv}\r\n tooltip=\"Export CSV\"\r\n />\r\n )}\r\n\r\n {showFilters && onFiltersChange && (\r\n <TableFiltersDropdown\r\n columns={columns}\r\n filters={filters}\r\n onFiltersChange={onFiltersChange}\r\n defaultFilters={defaultFilters}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* ── Table (wrapped for horizontal scroll) ─────────────────────────── */}\r\n <div className=\"eidos-table-scroll\">\r\n <table\r\n className={[\r\n 'eidos-table',\r\n densityClass,\r\n draggableColumns ? 'eidos-table--draggable-columns' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n >\r\n <thead ref={theadRef}>\r\n <tr>\r\n {selectable && (\r\n <th\r\n className={[\r\n 'eidos-table-header-cell',\r\n 'eidos-table-checkbox-cell',\r\n getHeaderPinnedProps('__checkbox__').className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={getHeaderPinnedProps('__checkbox__').style}\r\n data-col-key=\"__checkbox__\"\r\n >\r\n <Checkbox\r\n size=\"sm\"\r\n checked={allSelected}\r\n indeterminate={someSelected}\r\n onChange={toggleAll}\r\n aria-label=\"Select all rows\"\r\n />\r\n </th>\r\n )}\r\n\r\n {/* ── Headers: draggable or plain ──────────────────────────── */}\r\n {draggableColumns\r\n ? visibleColumns.map((column) => {\r\n const colKey = String(column.key);\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const isSortable = !!column.sortable;\r\n const isCurrentlySorted = currentSort?.key === colKey;\r\n const sortDirection = isCurrentlySorted\r\n ? (currentSort!.direction as 'asc' | 'desc')\r\n : null;\r\n const alignment = column.align || 'left';\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getHeaderPinnedProps(colKey);\r\n\r\n return (\r\n <SortableColumnHeader\r\n key={colKey}\r\n id={colKey}\r\n column={column}\r\n isSortable={isSortable}\r\n isCurrentlySorted={!!isCurrentlySorted}\r\n sortDirection={sortDirection}\r\n alignment={alignment}\r\n columnType={columnType}\r\n columnWidth={columnWidth}\r\n pinnedClass={pinnedClass}\r\n stickyStyle={pinnedStyle}\r\n onSortClick={() => handleSort(colKey)}\r\n />\r\n );\r\n })\r\n : visibleColumns.map((column, index) => {\r\n const colKey = String(column.key);\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const isSortable = column.sortable;\r\n const isCurrentlySorted = currentSort?.key === colKey;\r\n const sortDirection = isCurrentlySorted ? currentSort!.direction : null;\r\n const alignment = column.align || 'left';\r\n const alignmentClass = `eidos-table-align-${alignment}`;\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getHeaderPinnedProps(colKey);\r\n\r\n return (\r\n <th\r\n key={index}\r\n className={[\r\n 'eidos-table-header-cell',\r\n `eidos-table-header-cell-${columnType}`,\r\n isSortable ? 'eidos-table-sortable' : '',\r\n isCurrentlySorted ? 'eidos-table-sorted' : '',\r\n alignmentClass,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ width: columnWidth, ...pinnedStyle }}\r\n data-col-key={colKey}\r\n onClick={() => isSortable && handleSort(colKey)}\r\n >\r\n <div className={`eidos-table-header-content ${alignmentClass}`}>\r\n <span>{column.label}</span>\r\n {isSortable && (\r\n <div className=\"eidos-table-sort-indicator\">\r\n {sortDirection === 'asc' && <ArrowUp size={14} />}\r\n {sortDirection === 'desc' && <ArrowDown size={14} />}\r\n {!sortDirection && <ChevronsUpDown size={14} />}\r\n </div>\r\n )}\r\n </div>\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {displayData.length > 0 ? (\r\n displayData.map((item, rowIndex) => {\r\n const globalIndex = showPagination\r\n ? (currentPage - 1) * currentPageSize + rowIndex\r\n : rowIndex;\r\n const key = getRowKey(item, globalIndex);\r\n const isSelected = selectedSet.has(key);\r\n\r\n return (\r\n <tr\r\n key={key}\r\n className={[\r\n 'eidos-table-row',\r\n onRowClick ? 'eidos-table-clickable' : '',\r\n isSelected ? 'eidos-table-row--selected' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => onRowClick?.(item)}\r\n >\r\n {selectable && (\r\n <td\r\n className={[\r\n 'eidos-table-cell',\r\n 'eidos-table-checkbox-cell',\r\n getCellPinnedProps('__checkbox__').className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={getCellPinnedProps('__checkbox__').style}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n toggleRow(key);\r\n }}\r\n >\r\n {/* Wrap in a span so Checkbox click-events don't\r\n bubble to the <td> and cause a double-toggle.\r\n The <td> onClick handles toggling when the user\r\n clicks the cell margin outside the checkbox. */}\r\n <span onClick={(e) => e.stopPropagation()}>\r\n <Checkbox\r\n size=\"sm\"\r\n checked={isSelected}\r\n onChange={() => toggleRow(key)}\r\n aria-label={`Select row ${globalIndex + 1}`}\r\n />\r\n </span>\r\n </td>\r\n )}\r\n {visibleColumns.map((column, colIndex) => {\r\n const colKey = String(column.key);\r\n const value =\r\n typeof column.key === 'string' && column.key.includes('.')\r\n ? (column.key as string)\r\n .split('.')\r\n .reduce(\r\n (obj: unknown, k: string) => (obj as Record<string, unknown>)?.[k],\r\n item as unknown,\r\n )\r\n : item[column.key as keyof T];\r\n\r\n const columnType = column.type || 'data';\r\n const columnWidth =\r\n column.type === 'icon' ? 'var(--component-size-lg)' : column.width;\r\n const alignment = column.align || 'left';\r\n const alignmentClass = `eidos-table-align-${alignment}`;\r\n const { style: pinnedStyle, className: pinnedClass } =\r\n getCellPinnedProps(colKey);\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n className={[\r\n 'eidos-table-cell',\r\n `eidos-table-cell-${columnType}`,\r\n alignmentClass,\r\n pinnedClass,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ width: columnWidth, ...pinnedStyle }}\r\n // `type: 'action'` cells exist specifically to hold\r\n // interactive controls (a row-actions Menu/button,\r\n // typically) - without this, clicking them bubbles\r\n // straight into `onRowClick` on the <tr> below,\r\n // e.g. opening a details drawer at the same time as\r\n // (or instead of) the action itself. Mirrors the\r\n // selectable checkbox cell's own stopPropagation\r\n // above, for the same reason.\r\n onClick={columnType === 'action' ? (e) => e.stopPropagation() : undefined}\r\n >\r\n {column.render ? column.render(value, item) : String(value ?? '')}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n );\r\n })\r\n ) : (\r\n <tr className=\"eidos-table-empty-row\">\r\n <td\r\n colSpan={selectable ? visibleColumns.length + 1 : visibleColumns.length}\r\n className=\"eidos-table-cell eidos-table-empty-cell\"\r\n >\r\n {Object.keys(filters).length > 0 ? (\r\n <EmptyState\r\n icon={<SearchX />}\r\n title=\"No results found\"\r\n description=\"Try adjusting your filters or search terms.\"\r\n action={\r\n onFiltersChange ? (\r\n <Button\r\n size=\"sm\"\r\n variant=\"outlined\"\r\n color=\"primary\"\r\n onClick={() => onFiltersChange({})}\r\n >\r\n Clear filters\r\n </Button>\r\n ) : undefined\r\n }\r\n size=\"sm\"\r\n />\r\n ) : (\r\n <EmptyState\r\n icon={<FolderOpen />}\r\n title={emptyMessage}\r\n description=\"There are no records to display.\"\r\n size=\"sm\"\r\n />\r\n )}\r\n </td>\r\n </tr>\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* ── Footer / Pagination ───────────────────────────────────────────── */}\r\n {showFooter && (\r\n <div className=\"eidos-table-footer\">\r\n <div className=\"eidos-table-footer-content\">\r\n {showPagination && data.length > 0 ? (\r\n <Pagination\r\n page={currentPage}\r\n totalPages={totalPages}\r\n onChange={handlePageChange}\r\n totalItems={totalItems ?? data.length}\r\n pageSize={currentPageSize}\r\n onPageSizeChange={handlePageSizeChange}\r\n pageSizeOptions={pageSizeOptions}\r\n size=\"sm\"\r\n />\r\n ) : (\r\n <span className=\"eidos-table-results-info\">\r\n Showing {data.length} of {totalItems ?? data.length} results\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n\r\n // ── Wrap with DnD context when draggableColumns=true ─────────────────────\r\n if (draggableColumns) {\r\n return (\r\n <DndContext sensors={sensors} onDragEnd={handleDragEnd}>\r\n <SortableContext items={sortableItems} strategy={horizontalListSortingStrategy}>\r\n {tableContent}\r\n </SortableContext>\r\n </DndContext>\r\n );\r\n }\r\n\r\n return tableContent;\r\n};\r\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-O5ZPSZNY.cjs","../src/components/Chip/Chip.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACNA,2CAAkB;AAqDd,+CAAA;AAhDG,IAAM,KAAA,EAA4B,CAAC;AAAA,EACxC,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,IAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,UAAA,EAAY,KAAA;AAAA,EACZ,OAAA;AAAA,EACA,UAAA,EAAY,EAAA;AAAA,EACZ,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAA,GAAM;AACJ,EAAA,MAAM,YAAA,EAAc,CAAC,CAAC,OAAA;AACtB,EAAA,MAAM,YAAA,EAAc,CAAC,CAAC,QAAA;AAGtB,EAAA,MAAM,YAAA,EAAc;AAAA,IAClB,YAAA;AAAA,IACA,CAAA,YAAA,EAAe,OAAO,CAAA,CAAA;AACF,IAAA;AACD,IAAA;AACP,IAAA;AACG,IAAA;AACA,IAAA;AACF,IAAA;AACb,IAAA;AAGM,EAAA;AAEY,EAAA;AACD,IAAA;AACT,IAAA;AACV,EAAA;AAEsB,EAAA;AACF,IAAA;AACD,IAAA;AACR,IAAA;AACX,EAAA;AAGoB,EAAA;AAGlB,EAAA;AAAC,IAAA;AAAA,IAAA;AACY,MAAA;AACD,MAAA;AACD,MAAA;AACH,MAAA;AACI,MAAA;AAER,MAAA;AAEqB,QAAA;AACI,UAAA;AACL,UAAA;AACd,QAAA;AAEF,MAAA;AAEF,MAAA;AAEH,MAAA;AAAW,QAAA;AAEZ,wBAAA;AAEY,QAAA;AAGV,QAAA;AAAC,UAAA;AAAA,UAAA;AACW,YAAA;AACD,YAAA;AACT,YAAA;AACW,YAAA;AACN,YAAA;AAEL,YAAA;AAAuC,UAAA;AACzC,QAAA;AAAA,MAAA;AAAA,IAAA;AAEJ,EAAA;AAGe,EAAA;AACnB;ADV2B;AACA;AACA;AACA","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-O5ZPSZNY.cjs","sourcesContent":[null,"import React from 'react';\r\nimport { X } from 'lucide-react';\r\nimport type { ChipProps } from './Chip.types';\r\nimport { Tooltip } from '../Tooltip/Tooltip.component';\r\nimport { renderIcon } from '../../utils';\r\n\r\nexport const Chip: React.FC<ChipProps> = ({\r\n variant = 'filled',\r\n color = 'primary',\r\n size = 'md',\r\n disabled = false,\r\n fullWidth = false,\r\n tooltip,\r\n className = '',\r\n preIcon,\r\n posIcon,\r\n children,\r\n onClick,\r\n onRemove,\r\n ...chipProps\r\n}) => {\r\n const isClickable = !!onClick;\r\n const isRemovable = !!onRemove;\r\n\r\n // Build CSS classes\r\n const chipClasses = [\r\n 'eidos-chip',\r\n `eidos-chip--${variant}`,\r\n `eidos-chip--${color}`,\r\n `eidos-chip--${size}`,\r\n disabled && 'eidos-chip--disabled',\r\n isClickable && 'eidos-chip--clickable',\r\n isRemovable && 'eidos-chip--removable',\r\n fullWidth && 'eidos-chip--full-width',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const handleClick = () => {\r\n if (disabled || !onClick) return;\r\n onClick();\r\n };\r\n\r\n const handleRemove = (e: React.MouseEvent) => {\r\n e.stopPropagation(); // Prevent chip click when removing\r\n if (disabled || !onRemove) return;\r\n onRemove();\r\n };\r\n\r\n // Use div when removable to avoid nested buttons, button only when clickable without remove\r\n const ChipElement = isClickable && !isRemovable ? 'button' : 'div';\r\n\r\n const chipContent = (\r\n <ChipElement\r\n className={chipClasses}\r\n disabled={ChipElement === 'button' ? disabled : undefined}\r\n onClick={isClickable ? handleClick : undefined}\r\n role={ChipElement === 'div' && isClickable ? 'button' : undefined}\r\n tabIndex={ChipElement === 'div' && isClickable ? 0 : undefined}\r\n onKeyDown={\r\n ChipElement === 'div' && isClickable\r\n ? (e) => {\r\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\r\n e.preventDefault();\r\n handleClick();\r\n }\r\n }\r\n : undefined\r\n }\r\n {...chipProps}\r\n >\r\n {preIcon && renderIcon(preIcon, 'eidos-chip--pre-icon')}\r\n\r\n <span className=\"eidos-chip--copy\">{children}</span>\r\n\r\n {posIcon && renderIcon(posIcon, 'eidos-chip--pos-icon')}\r\n\r\n {isRemovable && (\r\n <button\r\n className=\"eidos-chip--remove-button\"\r\n onClick={handleRemove}\r\n disabled={disabled}\r\n aria-label=\"Remove\"\r\n type=\"button\"\r\n >\r\n <X className=\"eidos-chip--remove-icon\" />\r\n </button>\r\n )}\r\n </ChipElement>\r\n );\r\n\r\n return tooltip ? <Tooltip message={tooltip}>{chipContent}</Tooltip> : chipContent;\r\n};\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Menu/Menu.component.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\r\nimport { ChevronRight } from 'lucide-react';\r\nimport type { MenuProps, MenuItemType, MenuItem, MenuWrapperProps } from './Menu.types';\r\nimport { Dropdown } from '../Dropdown/Dropdown.component';\r\nimport { Tooltip } from '../Tooltip/Tooltip.component';\r\nimport { Kbd } from '../Kbd/Kbd.component';\r\nimport { renderIcon } from '../../utils';\r\n\r\n/**\r\n * MenuPanel - the bare menu list, without any trigger or dropdown wrapper.\r\n * Exported for use in SplitButton, ContextMenu, and other consumers that need\r\n * to render the menu content inside their own Dropdown / portal.\r\n */\r\nexport const MenuPanel: React.FC<MenuProps> = ({ items, className = '', onItemClick }) => {\r\n // Handle menu item click\r\n const handleItemClick = useCallback(\r\n (item: MenuItem) => {\r\n if (item.disabled) return;\r\n\r\n // Execute the item's onClick handler first\r\n if (item.onClick) {\r\n item.onClick();\r\n }\r\n\r\n // Then call the onItemClick callback (which will close the dropdown)\r\n if (onItemClick) {\r\n onItemClick(item);\r\n }\r\n },\r\n [onItemClick],\r\n );\r\n\r\n // Render individual menu item\r\n const renderMenuItem = (item: MenuItemType): React.ReactNode => {\r\n switch (item.type) {\r\n case 'item':\r\n return (\r\n <li\r\n key={item.id}\r\n className={[\r\n 'eidos-menu-item',\r\n item.disabled ? 'eidos-menu-item--disabled' : '',\r\n item.color ? `eidos-menu-item--${item.color}` : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => handleItemClick(item)}\r\n >\r\n {item.icon && renderIcon(item.icon, 'eidos-menu-icon')}\r\n <span className={`eidos-menu-label`}>{item.label}</span>\r\n {item.shortcut && (\r\n <Kbd size=\"sm\" className=\"eidos-menu-shortcut\">\r\n {item.shortcut}\r\n </Kbd>\r\n )}\r\n </li>\r\n );\r\n\r\n case 'component':\r\n return (\r\n <li key={item.id} className={`eidos-menu-component-item`}>\r\n {item.component}\r\n </li>\r\n );\r\n\r\n case 'separator':\r\n return <li key={item.id} className={`eidos-menu-separator`} />;\r\n\r\n case 'nested': {\r\n const triggerElement = (\r\n <div className={`eidos-menu-nested-trigger`}>\r\n {item.icon && renderIcon(item.icon, 'eidos-menu-icon')}\r\n <span className={`eidos-menu-label`}>{item.label}</span>\r\n <ChevronRight className={`eidos-menu-nested-arrow`} />\r\n </div>\r\n );\r\n\r\n return (\r\n <li key={item.id} className={`eidos-menu-nested-item`}>\r\n <Dropdown\r\n trigger={triggerElement}\r\n content={<MenuPanel items={item.items} onItemClick={onItemClick} />}\r\n placement=\"right\"\r\n isNested={true}\r\n fullWidth\r\n />\r\n </li>\r\n );\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n return <ul className={`eidos-menu ${className}`}>{items.map(renderMenuItem)}</ul>;\r\n};\r\n\r\nexport const Menu: React.FC<MenuWrapperProps> = ({\r\n trigger,\r\n items,\r\n minWidth,\r\n maxWidth,\r\n minHeight,\r\n maxHeight,\r\n autoWidth = true,\r\n triggerRef,\r\n closeOnItemClick = true,\r\n tooltip,\r\n}) => {\r\n const handleItemClick = useCallback(\r\n (_item: MenuItem) => {\r\n // Note: item.onClick is already called in MenuPanel's handleItemClick\r\n // Here we only handle closing the dropdown if needed\r\n\r\n if (closeOnItemClick) {\r\n // Use a small delay to ensure the onClick handler completes\r\n setTimeout(() => {\r\n // Create a synthetic click event outside the dropdown to close it\r\n const event = new MouseEvent('mousedown', {\r\n bubbles: true,\r\n cancelable: true,\r\n view: window,\r\n });\r\n document.dispatchEvent(event);\r\n }, 10);\r\n }\r\n },\r\n [closeOnItemClick],\r\n );\r\n\r\n const dropdown = (\r\n <Dropdown\r\n trigger={trigger}\r\n content={<MenuPanel items={items} onItemClick={handleItemClick} />}\r\n minWidth={minWidth}\r\n maxWidth={maxWidth}\r\n minHeight={minHeight}\r\n maxHeight={maxHeight}\r\n autoWidth={autoWidth}\r\n triggerRef={triggerRef}\r\n />\r\n );\r\n\r\n return tooltip ? <Tooltip message={tooltip}>{dropdown}</Tooltip> : dropdown;\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAgB,mBAAmB;AACnC,SAAS,oBAAoB;AAoCnB,SAYE,KAZF;AAxBH,IAAM,YAAiC,CAAC,EAAE,OAAO,YAAY,IAAI,YAAY,MAAM;AAExF,QAAM,kBAAkB;AAAA,IACtB,CAAC,SAAmB;AAClB,UAAI,KAAK,SAAU;AAGnB,UAAI,KAAK,SAAS;AAChB,aAAK,QAAQ;AAAA,MACf;AAGA,UAAI,aAAa;AACf,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAGA,QAAM,iBAAiB,CAAC,SAAwC;AAC9D,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,WAAW;AAAA,cACT;AAAA,cACA,KAAK,WAAW,8BAA8B;AAAA,cAC9C,KAAK,QAAQ,oBAAoB,KAAK,KAAK,KAAK;AAAA,YAClD,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,YACX,SAAS,MAAM,gBAAgB,IAAI;AAAA,YAElC;AAAA,mBAAK,QAAQ,WAAW,KAAK,MAAM,iBAAiB;AAAA,cACrD,oBAAC,UAAK,WAAW,oBAAqB,eAAK,OAAM;AAAA,cAChD,KAAK,YACJ,oBAAC,OAAI,MAAK,MAAK,WAAU,uBACtB,eAAK,UACR;AAAA;AAAA;AAAA,UAfG,KAAK;AAAA,QAiBZ;AAAA,MAGJ,KAAK;AACH,eACE,oBAAC,QAAiB,WAAW,6BAC1B,eAAK,aADC,KAAK,EAEd;AAAA,MAGJ,KAAK;AACH,eAAO,oBAAC,QAAiB,WAAW,0BAApB,KAAK,EAAuC;AAAA,MAE9D,KAAK,UAAU;AACb,cAAM,iBACJ,qBAAC,SAAI,WAAW,6BACb;AAAA,eAAK,QAAQ,WAAW,KAAK,MAAM,iBAAiB;AAAA,UACrD,oBAAC,UAAK,WAAW,oBAAqB,eAAK,OAAM;AAAA,UACjD,oBAAC,gBAAa,WAAW,2BAA2B;AAAA,WACtD;AAGF,eACE,oBAAC,QAAiB,WAAW,0BAC3B;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,SAAS,oBAAC,aAAU,OAAO,KAAK,OAAO,aAA0B;AAAA,YACjE,WAAU;AAAA,YACV,UAAU;AAAA,YACV,WAAS;AAAA;AAAA,QACX,KAPO,KAAK,EAQd;AAAA,MAEJ;AAAA,MAEA;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,SAAO,oBAAC,QAAG,WAAW,cAAc,SAAS,IAAK,gBAAM,IAAI,cAAc,GAAE;AAC9E;AAEO,IAAM,OAAmC,CAAC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,mBAAmB;AAAA,EACnB;AACF,MAAM;AACJ,QAAM,kBAAkB;AAAA,IACtB,CAAC,UAAoB;AAInB,UAAI,kBAAkB;AAEpB,mBAAW,MAAM;AAEf,gBAAM,QAAQ,IAAI,WAAW,aAAa;AAAA,YACxC,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,MAAM;AAAA,UACR,CAAC;AACD,mBAAS,cAAc,KAAK;AAAA,QAC9B,GAAG,EAAE;AAAA,MACP;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB;AAAA,EACnB;AAEA,QAAM,WACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,oBAAC,aAAU,OAAc,aAAa,iBAAiB;AAAA,MAChE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAGF,SAAO,UAAU,oBAAC,WAAQ,SAAS,SAAU,oBAAS,IAAa;AACrE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Slider/Slider.component.tsx"],"sourcesContent":["import React, { forwardRef, useState } from 'react';\r\nimport type { SliderProps } from './Slider.types';\r\n\r\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(\r\n (\r\n {\r\n value,\r\n defaultValue,\r\n min,\r\n max,\r\n step,\r\n onChange,\r\n color = 'primary',\r\n size = 'md',\r\n disabled = false,\r\n showValue = false,\r\n showMinMax = false,\r\n label,\r\n unit,\r\n blockedRange,\r\n className = '',\r\n },\r\n ref,\r\n ) => {\r\n const minVal = min ?? 0;\r\n const maxVal = max ?? 100;\r\n\r\n // Clamp a raw value against the blocked range boundary.\r\n const clamp = (v: number) => (blockedRange && v > blockedRange.min ? blockedRange.min : v);\r\n\r\n const isControlled = value !== undefined;\r\n const [localValue, setLocalValue] = useState<number>(clamp(defaultValue ?? minVal));\r\n const currentValue = isControlled ? clamp(value!) : localValue;\r\n\r\n const fillPct = ((currentValue - minVal) / (maxVal - minVal)) * 100;\r\n const blockedStartPct = blockedRange\r\n ? ((blockedRange.min - minVal) / (maxVal - minVal)) * 100\r\n : null;\r\n\r\n // CSS custom properties drive the track gradient via the\r\n // ::-webkit-slider-runnable-track pseudo-element in Slider.scss.\r\n // --s-block defaults to 100% so the danger segment collapses to zero\r\n // width when there is no blocked range.\r\n const sliderStyle: React.CSSProperties = {\r\n '--s-fill': `${fillPct}%`,\r\n '--s-color': `var(--${color}-color)`,\r\n '--s-empty': 'var(--gray-200)',\r\n ...(blockedStartPct !== null && { '--s-block': `${blockedStartPct}%` }),\r\n } as React.CSSProperties;\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const newValue = clamp(Number(e.target.value));\r\n if (!isControlled) setLocalValue(newValue);\r\n onChange?.(newValue);\r\n };\r\n\r\n // Effective max for ARIA - the blocked zone is not a valid value.\r\n const effectiveMax = blockedRange ? blockedRange.min : maxVal;\r\n\r\n const fmt = (v: number) => `${v}${unit ?? ''}`;\r\n\r\n const rootClasses = [\r\n 'eidos-slider',\r\n `eidos-slider--${color}`,\r\n `eidos-slider--${size}`,\r\n disabled && 'eidos-slider--disabled',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <div className={rootClasses}>\r\n {(label || showValue) && (\r\n <div className=\"eidos-slider-top\">\r\n {label && <span className=\"eidos-slider-label\">{label}</span>}\r\n {showValue && <span className=\"eidos-slider-value\">{fmt(currentValue)}</span>}\r\n </div>\r\n )}\r\n\r\n <input\r\n ref={ref}\r\n type=\"range\"\r\n className=\"eidos-slider-input\"\r\n min={minVal}\r\n max={maxVal}\r\n step={step ?? 1}\r\n value={currentValue}\r\n disabled={disabled}\r\n onChange={handleChange}\r\n aria-label={label ?? 'Slider'}\r\n aria-valuemin={minVal}\r\n aria-valuemax={effectiveMax}\r\n aria-valuenow={currentValue}\r\n style={sliderStyle}\r\n />\r\n\r\n {showMinMax && (\r\n <div className=\"eidos-slider-minmax\">\r\n <span>{fmt(minVal)}</span>\r\n <span>{fmt(maxVal)}</span>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nSlider.displayName = 'Slider';\r\n"],"mappings":";AAAA,SAAgB,YAAY,gBAAgB;AA0ElC,SACY,KADZ;AAvEH,IAAM,SAAS;AAAA,EACpB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd,GACA,QACG;AACH,UAAM,SAAS,OAAO;AACtB,UAAM,SAAS,OAAO;AAGtB,UAAM,QAAQ,CAAC,MAAe,gBAAgB,IAAI,aAAa,MAAM,aAAa,MAAM;AAExF,UAAM,eAAe,UAAU;AAC/B,UAAM,CAAC,YAAY,aAAa,IAAI,SAAiB,MAAM,gBAAgB,MAAM,CAAC;AAClF,UAAM,eAAe,eAAe,MAAM,KAAM,IAAI;AAEpD,UAAM,WAAY,eAAe,WAAW,SAAS,UAAW;AAChE,UAAM,kBAAkB,gBAClB,aAAa,MAAM,WAAW,SAAS,UAAW,MACpD;AAMJ,UAAM,cAAmC;AAAA,MACvC,YAAY,GAAG,OAAO;AAAA,MACtB,aAAa,SAAS,KAAK;AAAA,MAC3B,aAAa;AAAA,MACb,GAAI,oBAAoB,QAAQ,EAAE,aAAa,GAAG,eAAe,IAAI;AAAA,IACvE;AAEA,UAAM,eAAe,CAAC,MAA2C;AAC/D,YAAM,WAAW,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;AAC7C,UAAI,CAAC,aAAc,eAAc,QAAQ;AACzC,iBAAW,QAAQ;AAAA,IACrB;AAGA,UAAM,eAAe,eAAe,aAAa,MAAM;AAEvD,UAAM,MAAM,CAAC,MAAc,GAAG,CAAC,GAAG,QAAQ,EAAE;AAE5C,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,iBAAiB,KAAK;AAAA,MACtB,iBAAiB,IAAI;AAAA,MACrB,YAAY;AAAA,MACZ;AAAA,IACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,WACE,qBAAC,SAAI,WAAW,aACZ;AAAA,gBAAS,cACT,qBAAC,SAAI,WAAU,oBACZ;AAAA,iBAAS,oBAAC,UAAK,WAAU,sBAAsB,iBAAM;AAAA,QACrD,aAAa,oBAAC,UAAK,WAAU,sBAAsB,cAAI,YAAY,GAAE;AAAA,SACxE;AAAA,MAGF;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAK;AAAA,UACL,WAAU;AAAA,UACV,KAAK;AAAA,UACL,KAAK;AAAA,UACL,MAAM,QAAQ;AAAA,UACd,OAAO;AAAA,UACP;AAAA,UACA,UAAU;AAAA,UACV,cAAY,SAAS;AAAA,UACrB,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,OAAO;AAAA;AAAA,MACT;AAAA,MAEC,cACC,qBAAC,SAAI,WAAU,uBACb;AAAA,4BAAC,UAAM,cAAI,MAAM,GAAE;AAAA,QACnB,oBAAC,UAAM,cAAI,MAAM,GAAE;AAAA,SACrB;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Modal/Modal.component.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useId, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { Button } from '../Button/Button.component';\r\nimport type { ModalProps } from './Modal.types';\r\nimport { renderIcon } from '../../utils';\r\n\r\nexport const Modal: React.FC<ModalProps> = ({\r\n isOpen,\r\n onClose,\r\n title,\r\n icon,\r\n type,\r\n children,\r\n actions = [],\r\n closeOnBackdropClick = true,\r\n closeOnEscape = true,\r\n size = 'md',\r\n className = '',\r\n}) => {\r\n const titleId = useId();\r\n const bodyId = useId();\r\n\r\n // ── Animation state ────────────────────────────────────────────────────────\r\n // isMounted: whether the portal DOM node exists at all.\r\n // isVisible: whether the '--is-open' CSS class is applied (drives the transition).\r\n //\r\n // On open: mount first → one rAF → apply --is-open (browser sees the\r\n // initial faded/scaled-down state before transitioning, so the\r\n // animation fires instead of just painting straight into \"open\").\r\n // On close: remove --is-open (CSS transition plays) → after 200 ms unmount.\r\n // 200 ms matches the CSS `transition: 0.2s` in Modal.scss.\r\n const TRANSITION_MS = 200;\r\n const [isMounted, setIsMounted] = useState(isOpen);\r\n const [isVisible, setIsVisible] = useState(isOpen);\r\n\r\n useEffect(() => {\r\n let raf1 = 0;\r\n let raf2 = 0;\r\n let timerId: ReturnType<typeof setTimeout>;\r\n\r\n if (isOpen) {\r\n setIsMounted(true);\r\n // Double rAF: React 18 automatic batching means setIsMounted(true) may\r\n // not produce a committed browser paint before the first rAF fires.\r\n // The second frame guarantees the modal is rendered in its closed\r\n // (faded/scaled-down) state before the CSS transition begins.\r\n raf1 = requestAnimationFrame(() => {\r\n raf2 = requestAnimationFrame(() => setIsVisible(true));\r\n });\r\n } else {\r\n setIsVisible(false);\r\n timerId = setTimeout(() => setIsMounted(false), TRANSITION_MS);\r\n }\r\n\r\n return () => {\r\n cancelAnimationFrame(raf1);\r\n cancelAnimationFrame(raf2);\r\n clearTimeout(timerId);\r\n };\r\n }, [isOpen]);\r\n\r\n // Handle escape key\r\n const handleEscapeKey = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (closeOnEscape && event.key === 'Escape' && isOpen) {\r\n onClose();\r\n }\r\n },\r\n [closeOnEscape, isOpen, onClose],\r\n );\r\n\r\n // Handle backdrop click\r\n const handleBackdropClick = useCallback(\r\n (event: React.MouseEvent) => {\r\n if (closeOnBackdropClick && event.target === event.currentTarget) {\r\n onClose();\r\n }\r\n },\r\n [closeOnBackdropClick, onClose],\r\n );\r\n\r\n // Add/remove escape key listener (tied to isOpen, not isMounted)\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.addEventListener('keydown', handleEscapeKey);\r\n // Prevent body scroll when modal is open\r\n document.body.style.overflow = 'hidden';\r\n }\r\n\r\n return () => {\r\n document.removeEventListener('keydown', handleEscapeKey);\r\n document.body.style.overflow = '';\r\n };\r\n }, [isOpen, handleEscapeKey]);\r\n\r\n if (!isMounted) return null;\r\n\r\n const modalContent = (\r\n <div className={`eidos-modal ${isVisible ? 'eidos-modal--is-open' : ''} ${className}`}>\r\n <div className=\"eidos-modal-backdrop\" onClick={handleBackdropClick} aria-hidden=\"true\" />\r\n <div\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby={title ? titleId : undefined}\r\n aria-describedby={bodyId}\r\n className={`eidos-modal-content eidos-modal-content--${size}`}\r\n >\r\n {title && (\r\n <div className={`eidos-modal-header ${type ? `eidos-modal-header--${type}` : ''}`}>\r\n <h4 id={titleId}>\r\n {icon && renderIcon(icon, 'eidos-modal-icon')} {title}\r\n </h4>\r\n </div>\r\n )}\r\n\r\n <div id={bodyId} className=\"eidos-modal-body\">\r\n {children}\r\n </div>\r\n\r\n {actions.length > 0 && (\r\n <div className={`eidos-modal-footer`}>\r\n {actions.map((action) => (\r\n <Button\r\n key={action.id}\r\n variant={action.variant || 'outlined'}\r\n size={action.size || 'md'}\r\n color={action.color}\r\n disabled={action.disabled}\r\n loading={action.loading}\r\n onClick={action.onClick}\r\n >\r\n {action.label}\r\n </Button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n\r\n return createPortal(modalContent, document.body);\r\n};\r\n\r\nModal.displayName = 'Modal';\r\n"],"mappings":";;;;;;;;AAAA,SAAgB,WAAW,aAAa,OAAO,gBAAgB;AAC/D,SAAS,oBAAoB;AAkGvB,cAUM,YAVN;AA7FC,IAAM,QAA8B,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,CAAC;AAAA,EACX,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,YAAY;AACd,MAAM;AACJ,QAAM,UAAU,MAAM;AACtB,QAAM,SAAS,MAAM;AAWrB,QAAM,gBAAgB;AACtB,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,MAAM;AACjD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,MAAM;AAEjD,YAAU,MAAM;AACd,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI;AAEJ,QAAI,QAAQ;AACV,mBAAa,IAAI;AAKjB,aAAO,sBAAsB,MAAM;AACjC,eAAO,sBAAsB,MAAM,aAAa,IAAI,CAAC;AAAA,MACvD,CAAC;AAAA,IACH,OAAO;AACL,mBAAa,KAAK;AAClB,gBAAU,WAAW,MAAM,aAAa,KAAK,GAAG,aAAa;AAAA,IAC/D;AAEA,WAAO,MAAM;AACX,2BAAqB,IAAI;AACzB,2BAAqB,IAAI;AACzB,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,kBAAkB;AAAA,IACtB,CAAC,UAAyB;AACxB,UAAI,iBAAiB,MAAM,QAAQ,YAAY,QAAQ;AACrD,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,eAAe,QAAQ,OAAO;AAAA,EACjC;AAGA,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA4B;AAC3B,UAAI,wBAAwB,MAAM,WAAW,MAAM,eAAe;AAChE,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,sBAAsB,OAAO;AAAA,EAChC;AAGA,YAAU,MAAM;AACd,QAAI,QAAQ;AACV,eAAS,iBAAiB,WAAW,eAAe;AAEpD,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAEA,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,eAAe;AACvD,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,QAAQ,eAAe,CAAC;AAE5B,MAAI,CAAC,UAAW,QAAO;AAEvB,QAAM,eACJ,qBAAC,SAAI,WAAW,eAAe,YAAY,yBAAyB,EAAE,IAAI,SAAS,IACjF;AAAA,wBAAC,SAAI,WAAU,wBAAuB,SAAS,qBAAqB,eAAY,QAAO;AAAA,IACvF;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,mBAAiB,QAAQ,UAAU;AAAA,QACnC,oBAAkB;AAAA,QAClB,WAAW,4CAA4C,IAAI;AAAA,QAE1D;AAAA,mBACC,oBAAC,SAAI,WAAW,sBAAsB,OAAO,uBAAuB,IAAI,KAAK,EAAE,IAC7E,+BAAC,QAAG,IAAI,SACL;AAAA,oBAAQ,WAAW,MAAM,kBAAkB;AAAA,YAAE;AAAA,YAAE;AAAA,aAClD,GACF;AAAA,UAGF,oBAAC,SAAI,IAAI,QAAQ,WAAU,oBACxB,UACH;AAAA,UAEC,QAAQ,SAAS,KAChB,oBAAC,SAAI,WAAW,sBACb,kBAAQ,IAAI,CAAC,WACZ;AAAA,YAAC;AAAA;AAAA,cAEC,SAAS,OAAO,WAAW;AAAA,cAC3B,MAAM,OAAO,QAAQ;AAAA,cACrB,OAAO,OAAO;AAAA,cACd,UAAU,OAAO;AAAA,cACjB,SAAS,OAAO;AAAA,cAChB,SAAS,OAAO;AAAA,cAEf,iBAAO;AAAA;AAAA,YARH,OAAO;AAAA,UASd,CACD,GACH;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAGF,SAAO,aAAa,cAAc,SAAS,IAAI;AACjD;AAEA,MAAM,cAAc;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/OTPInput/OTPInput.component.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useId } from 'react';\r\nimport { CircleAlert } from 'lucide-react';\r\nimport type { OTPInputProps } from './OTPInput.types';\r\nimport './OTPInput.scss';\r\n\r\nexport const OTPInput: React.FC<OTPInputProps> = ({\r\n length = 6,\r\n value,\r\n defaultValue = '',\r\n onChange,\r\n onComplete,\r\n type = 'numeric',\r\n mask = false,\r\n size = 'md',\r\n disabled = false,\r\n error,\r\n label,\r\n hint,\r\n autoFocus = false,\r\n className = '',\r\n}) => {\r\n const generatedId = useId();\r\n const labelId = `otp-label-${generatedId}`;\r\n const hintId = `otp-hint-${generatedId}`;\r\n const errorId = `otp-error-${generatedId}`;\r\n\r\n const isControlled = value !== undefined;\r\n\r\n // Split a string into an array of `length` single characters, padding with ''\r\n const splitToSlots = (src: string): string[] => Array.from({ length }, (_v, i) => src[i] ?? '');\r\n\r\n const [slots, setSlots] = useState<string[]>(() =>\r\n splitToSlots(isControlled ? (value ?? '') : defaultValue),\r\n );\r\n\r\n // A ref that always mirrors the latest slots value so that event handlers\r\n // never operate on stale closure state during rapid sequential keystrokes.\r\n const slotsRef = useRef<string[]>(slots);\r\n\r\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\r\n\r\n // Array of refs - one per slot input\r\n const inputRefs = useRef<Array<HTMLInputElement | null>>([]);\r\n\r\n // Sync internal slots when the controlled `value` prop changes\r\n useEffect(() => {\r\n if (isControlled) {\r\n const synced = splitToSlots(value ?? '');\r\n slotsRef.current = synced;\r\n setSlots(synced);\r\n }\r\n // splitToSlots is stable within a render; length is in deps\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [value, length, isControlled]);\r\n\r\n // AutoFocus: focus first empty slot on mount\r\n useEffect(() => {\r\n if (!autoFocus) return;\r\n const firstEmptyIdx = slots.findIndex((s) => s === '');\r\n const targetIdx = firstEmptyIdx === -1 ? 0 : firstEmptyIdx;\r\n inputRefs.current[targetIdx]?.focus();\r\n // Intentionally runs only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n\r\n // ── Core state update ──────────────────────────────────────────────────────\r\n\r\n /**\r\n * Apply a new slots array, propagate onChange, and fire onComplete if every\r\n * slot is filled. In controlled mode we do NOT call setSlots - the parent\r\n * drives state via the `value` prop.\r\n */\r\n const commitChange = (newSlots: string[]) => {\r\n // Keep the ref in sync BEFORE state update so the next synchronous\r\n // handler (rapid typing) reads the correct value from the ref.\r\n slotsRef.current = newSlots;\r\n if (!isControlled) setSlots(newSlots);\r\n const fullValue = newSlots.join('');\r\n onChange?.(fullValue);\r\n if (newSlots.every((s) => s !== '')) {\r\n onComplete?.(fullValue);\r\n }\r\n };\r\n\r\n // ── Event handlers ─────────────────────────────────────────────────────────\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\r\n const rawValue = e.target.value;\r\n // When maxLength=1 is enforced, rawValue is 0–1 chars.\r\n // When the browser transiently allows 2 chars (typed over existing), we\r\n // take the last character - that's always the newly entered one.\r\n const char = rawValue.slice(-1);\r\n\r\n if (!char) return; // Deletes are handled by onKeyDown\r\n\r\n // Guard: numeric mode rejects non-digit characters\r\n if (type === 'numeric' && !/^\\d$/.test(char)) return;\r\n\r\n // Read from slotsRef (not the stale `slots` closure) so rapid keystrokes\r\n // don't overwrite each other when React hasn't re-rendered yet.\r\n const newSlots = [...slotsRef.current];\r\n newSlots[index] = char;\r\n commitChange(newSlots);\r\n\r\n // Advance focus to the next slot\r\n if (index < length - 1) {\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => {\r\n // ── Numeric mode: block non-digit, non-control key presses ──────────────\r\n if (type === 'numeric') {\r\n const controlKeys = [\r\n 'Backspace',\r\n 'Delete',\r\n 'Tab',\r\n 'Escape',\r\n 'ArrowLeft',\r\n 'ArrowRight',\r\n 'Home',\r\n 'End',\r\n ];\r\n const isDigit = /^\\d$/.test(e.key);\r\n const isControlKey = e.ctrlKey || e.metaKey;\r\n if (!isDigit && !controlKeys.includes(e.key) && !isControlKey) {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n // ── Backspace ────────────────────────────────────────────────────────────\r\n if (e.key === 'Backspace') {\r\n e.preventDefault(); // Prevent the browser from also firing onChange\r\n if (slotsRef.current[index] !== '') {\r\n // Clear the current slot\r\n const newSlots = [...slotsRef.current];\r\n newSlots[index] = '';\r\n commitChange(newSlots);\r\n } else if (index > 0) {\r\n // Move focus to the previous slot and clear it\r\n const newSlots = [...slotsRef.current];\r\n newSlots[index - 1] = '';\r\n commitChange(newSlots);\r\n inputRefs.current[index - 1]?.focus();\r\n }\r\n return;\r\n }\r\n\r\n // ── Arrow navigation ─────────────────────────────────────────────────────\r\n if (e.key === 'ArrowLeft' && index > 0) {\r\n e.preventDefault();\r\n inputRefs.current[index - 1]?.focus();\r\n return;\r\n }\r\n if (e.key === 'ArrowRight' && index < length - 1) {\r\n e.preventDefault();\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>, index: number) => {\r\n e.preventDefault();\r\n const pasted = e.clipboardData.getData('text/plain');\r\n // Strip non-digits in numeric mode\r\n const filtered = type === 'numeric' ? pasted.replace(/\\D/g, '') : pasted;\r\n if (!filtered) return;\r\n\r\n const newSlots = [...slotsRef.current];\r\n let charsPlaced = 0;\r\n for (let i = index; i < length && charsPlaced < filtered.length; i++) {\r\n newSlots[i] = filtered[charsPlaced];\r\n charsPlaced++;\r\n }\r\n commitChange(newSlots);\r\n\r\n // Focus the slot after the last pasted character\r\n const nextFocusIdx = Math.min(index + charsPlaced, length - 1);\r\n inputRefs.current[nextFocusIdx]?.focus();\r\n };\r\n\r\n // ── CSS class builders ─────────────────────────────────────────────────────\r\n\r\n const containerClasses = [\r\n 'eidos-otp',\r\n `eidos-otp--${size}`,\r\n disabled && 'eidos-otp--disabled',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const slotClasses = (index: number) =>\r\n [\r\n 'eidos-otp-slot',\r\n // Show \"filled\" accent only when there's no error overriding the colour\r\n slots[index] !== '' && !error && 'eidos-otp-slot--filled',\r\n focusedIndex === index && 'eidos-otp-slot--focused',\r\n error && 'eidos-otp-slot--error',\r\n disabled && 'eidos-otp-slot--disabled',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n // Accessible description: prefer error, fall back to hint\r\n const describedBy = error ? errorId : hint ? hintId : undefined;\r\n\r\n return (\r\n <div className={containerClasses}>\r\n {label && (\r\n <label id={labelId} className=\"eidos-otp-label\">\r\n {label}\r\n </label>\r\n )}\r\n\r\n <div\r\n className=\"eidos-otp-slots\"\r\n role=\"group\"\r\n aria-labelledby={label ? labelId : undefined}\r\n aria-describedby={describedBy}\r\n >\r\n {Array.from({ length }, (_v, index) => (\r\n <div key={index} className={slotClasses(index)}>\r\n <input\r\n ref={(el) => {\r\n inputRefs.current[index] = el;\r\n }}\r\n type={mask ? 'password' : 'text'}\r\n inputMode={type === 'numeric' ? 'numeric' : 'text'}\r\n maxLength={2}\r\n value={slots[index]}\r\n disabled={disabled}\r\n aria-label={`Digit ${index + 1} of ${length}`}\r\n autoComplete={index === 0 ? 'one-time-code' : 'off'}\r\n onChange={(e) => handleChange(e, index)}\r\n onKeyDown={(e) => handleKeyDown(e, index)}\r\n onPaste={(e) => handlePaste(e, index)}\r\n onFocus={() => setFocusedIndex(index)}\r\n onBlur={() => setFocusedIndex(null)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {hint && !error && (\r\n <span id={hintId} className=\"eidos-otp-hint\">\r\n {hint}\r\n </span>\r\n )}\r\n\r\n {error && (\r\n <span id={errorId} className=\"eidos-otp-error-message\" role=\"alert\">\r\n <CircleAlert aria-hidden=\"true\" />\r\n {error}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nOTPInput.displayName = 'OTPInput';\r\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-P2BTQ33C.cjs","../src/components/Textarea/Textarea.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACPA,8BAAmD;AACnD,2CAA4B;AAyGlB,+CAAA;AApGH,IAAM,SAAA,EAAW,+BAAA;AAAA,EACtB,CACE;AAAA,IACE,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,IAAA;AAAA,IACP,SAAA,EAAW,KAAA;AAAA,IACX,QAAA,EAAU,KAAA;AAAA,IACV,UAAA,EAAY,EAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,KAAA;AAAA,IACA,KAAA;AAAA,IACA,cAAA;AAAA,IACA,iBAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA,EAAO,CAAA;AAAA,IACP,OAAA,EAAS,UAAA;AAAA,IACT,UAAA,EAAY,KAAA;AAAA,IACZ,SAAA;AAAA,IACA,EAAA;AAAA,IACA,GAAG;AAAA,EACL,CAAA,EACA,GAAA,EAAA,GACG;AACH,IAAA,MAAM,YAAA,EAAc,0BAAA,CAAM;AAC1B,IAAA,MAAM,WAAA,EAAa,GAAA,GAAM,CAAA,SAAA,EAAY,WAAW,CAAA,CAAA;AAKD,IAAA;AAGE,IAAA;AACJ,IAAA;AACG,IAAA;AAEZ,IAAA;AAGS,IAAA;AAGvB,IAAA;AAE8C,IAAA;AAC/C,MAAA;AACW,QAAA;AAC9B,MAAA;AAC8B,sBAAA;AAChC,IAAA;AAIyB,IAAA;AACvB,MAAA;AACa,MAAA;AACb,MAAA;AAGS,IAAA;AAEY,IAAA;AACrB,MAAA;AACkC,MAAA;AACF,MAAA;AACD,MAAA;AAClB,MAAA;AACF,MAAA;AACE,MAAA;AACJ,MAAA;AAGA,IAAA;AAEa,IAAA;AACtB,MAAA;AAC0B,MAAA;AACF,MAAA;AACD,MAAA;AACS,MAAA;AACnB,MAAA;AACF,MAAA;AACF,MAAA;AAGA,IAAA;AAEU,IAAA;AACnB,MAAA;AACoB,MAAA;AACF,MAAA;AACT,MAAA;AAGA,IAAA;AAGO,IAAA;AAEL,MAAA;AACW,wBAAA;AACK,QAAA;AAGjB,QAAA;AAUN,MAAA;AAGc,sBAAA;AACd,wBAAA;AAAC,UAAA;AAAA,UAAA;AACC,YAAA;AACI,YAAA;AACO,YAAA;AACX,YAAA;AACA,YAAA;AACsB,YAAA;AAClB,YAAA;AACG,YAAA;AACS,YAAA;AACG,cAAA;AACY,8BAAA;AAC/B,YAAA;AACe,YAAA;AACK,cAAA;AACU,8BAAA;AAC9B,YAAA;AACU,YAAA;AAAA,UAAA;AACZ,QAAA;AAGE,QAAA;AAC8B,UAAA;AAAO,UAAA;AAAE,UAAA;AACvC,QAAA;AAEJ,MAAA;AAGO,MAAA;AACU,wBAAA;AACN,wBAAA;AACT,MAAA;AAEJ,IAAA;AAEJ,EAAA;AACF;AAEuB;AD1C8B;AACA;AACA;AACA","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-P2BTQ33C.cjs","sourcesContent":[null,"import React, { forwardRef, useState, useId } from 'react';\r\nimport { CircleAlert } from 'lucide-react';\r\nimport { renderIcon } from '../../utils';\r\nimport type { TextareaProps } from './Textarea.types';\r\nimport { Tooltip } from '../Tooltip/Tooltip.component';\r\n\r\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(\r\n (\r\n {\r\n variant = 'filled',\r\n color = 'primary',\r\n size = 'md',\r\n disabled = false,\r\n loading = false,\r\n className = '',\r\n fullWidth = false,\r\n label,\r\n error,\r\n disclaimerIcon,\r\n disclaimerContent,\r\n required,\r\n rows = 4,\r\n resize = 'vertical',\r\n showCount = false,\r\n maxLength,\r\n id,\r\n ...textareaProps\r\n },\r\n ref,\r\n ) => {\r\n const generatedId = useId();\r\n const textareaId = id || `textarea-${generatedId}`;\r\n\r\n // Extract defaultValue so it never reaches the native <textarea> alongside `value`.\r\n // Same reasoning as Input: we always set value={currentValue}, so having defaultValue\r\n // in the spread as well triggers React's controlled/uncontrolled warning.\r\n const { defaultValue, ...restTextareaProps } = textareaProps;\r\n\r\n // Determine if using controlled or uncontrolled mode\r\n const isControlled = restTextareaProps.value !== undefined;\r\n const [localValue, setLocalValue] = useState(defaultValue != null ? String(defaultValue) : '');\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n const currentValue = isControlled ? restTextareaProps.value : localValue;\r\n\r\n // Label floats when the field has content (same logic as Input)\r\n const shouldFloatLabel = Boolean(currentValue) || Boolean(defaultValue);\r\n\r\n const isRequired =\r\n required || Boolean('required' in restTextareaProps && restTextareaProps.required);\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n if (!isControlled) {\r\n setLocalValue(e.target.value);\r\n }\r\n restTextareaProps.onChange?.(e);\r\n };\r\n\r\n // ── Class lists ──────────────────────────────────────────────────────────\r\n\r\n const containerClasses = [\r\n 'eidos-textarea-container',\r\n fullWidth && 'eidos-textarea-container--fullWidth',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const wrapperClasses = [\r\n 'eidos-textarea-wrapper',\r\n `eidos-textarea-wrapper--${variant}`,\r\n `eidos-textarea-wrapper--${color}`,\r\n `eidos-textarea-wrapper--${size}`,\r\n fullWidth && 'eidos-textarea-wrapper--fullWidth',\r\n loading && 'eidos-textarea-wrapper--loading',\r\n isFocused && 'eidos-textarea-wrapper--focused',\r\n error && 'eidos-textarea-wrapper--error',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const textareaClasses = [\r\n 'eidos-textarea',\r\n `eidos-textarea--${variant}`,\r\n `eidos-textarea--${color}`,\r\n `eidos-textarea--${size}`,\r\n `eidos-textarea--resize-${resize}`,\r\n fullWidth && 'eidos-textarea--fullWidth',\r\n loading && 'eidos-textarea--loading',\r\n error && 'eidos-textarea--error',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const labelClasses = [\r\n 'eidos-textarea-label',\r\n shouldFloatLabel && 'eidos-textarea-label--floating',\r\n disclaimerIcon && 'eidos-textarea-label--with-icon',\r\n error && 'eidos-textarea-label--error',\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <div className={containerClasses}>\r\n {label && (\r\n <label htmlFor={textareaId} className={labelClasses}>\r\n <span className=\"eidos-textarea-label-text\">{label}</span>\r\n {isRequired && <span className=\"eidos-textarea-required-asterisk\">*</span>}\r\n {disclaimerIcon &&\r\n (disclaimerContent ? (\r\n <Tooltip message={disclaimerContent}>\r\n <span className=\"eidos-textarea-disclaimer-icon\">\r\n {renderIcon(disclaimerIcon, 'eidos-textarea-disclaimer-icon-svg')}\r\n </span>\r\n </Tooltip>\r\n ) : (\r\n <span className=\"eidos-textarea-disclaimer-icon\">\r\n {renderIcon(disclaimerIcon, 'eidos-textarea-disclaimer-icon-svg')}\r\n </span>\r\n ))}\r\n </label>\r\n )}\r\n\r\n <div className={wrapperClasses}>\r\n <textarea\r\n ref={ref}\r\n id={textareaId}\r\n className={textareaClasses}\r\n rows={rows}\r\n maxLength={maxLength}\r\n disabled={disabled || loading}\r\n {...restTextareaProps}\r\n value={currentValue}\r\n onFocus={(e) => {\r\n setIsFocused(true);\r\n restTextareaProps.onFocus?.(e);\r\n }}\r\n onBlur={(e) => {\r\n setIsFocused(false);\r\n restTextareaProps.onBlur?.(e);\r\n }}\r\n onChange={handleChange}\r\n />\r\n\r\n {showCount && maxLength && (\r\n <span className=\"eidos-textarea-count\">\r\n {String(currentValue ?? '').length}/{maxLength}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {error && (\r\n <div className=\"eidos-textarea-error-message\">\r\n <CircleAlert className=\"eidos-textarea-error-icon\" />\r\n <span>{error}</span>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nTextarea.displayName = 'Textarea';\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Pagination/Pagination.component.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\r\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';\r\nimport { Button } from '../Button';\r\nimport { Select } from '../Select';\r\nimport type { PaginationProps } from './Pagination.types';\r\n\r\n// ── Ellipsis range helper ─────────────────────────────────────────────────────\r\n\r\nconst ELLIPSIS = 'ellipsis' as const;\r\ntype PageItem = number | typeof ELLIPSIS;\r\n\r\nfunction usePaginationRange(page: number, totalPages: number, siblingCount: number): PageItem[] {\r\n const totalShown = siblingCount * 2 + 5;\r\n\r\n if (totalPages <= totalShown) {\r\n return Array.from({ length: totalPages }, (_, i) => i + 1);\r\n }\r\n\r\n const leftSibling = Math.max(page - siblingCount, 1);\r\n const rightSibling = Math.min(page + siblingCount, totalPages);\r\n\r\n const showLeftEllipsis = leftSibling > 2;\r\n const showRightEllipsis = rightSibling < totalPages - 1;\r\n\r\n const items: PageItem[] = [1];\r\n\r\n if (showLeftEllipsis) {\r\n items.push(ELLIPSIS);\r\n } else {\r\n for (let i = 2; i < leftSibling; i++) items.push(i);\r\n }\r\n\r\n for (let i = leftSibling; i <= rightSibling; i++) {\r\n if (i !== 1 && i !== totalPages) items.push(i);\r\n }\r\n\r\n if (showRightEllipsis) {\r\n items.push(ELLIPSIS);\r\n } else {\r\n for (let i = rightSibling + 1; i < totalPages; i++) items.push(i);\r\n }\r\n\r\n items.push(totalPages);\r\n\r\n return items;\r\n}\r\n\r\n// ── Component ─────────────────────────────────────────────────────────────────\r\n\r\nexport const Pagination: React.FC<PaginationProps> = ({\r\n page,\r\n totalPages,\r\n onChange,\r\n siblingCount = 1,\r\n showFirstLast = false,\r\n color = 'primary',\r\n size = 'sm',\r\n disabled = false,\r\n className = '',\r\n // Table-footer mode\r\n totalItems,\r\n pageSize,\r\n onPageSizeChange,\r\n pageSizeOptions = [10, 25, 50, 100],\r\n}) => {\r\n const items = usePaginationRange(page, totalPages, siblingCount);\r\n\r\n // ── Active-page editable input ─────────────────────────────────────────────\r\n const [inputValue, setInputValue] = useState(String(page));\r\n useEffect(() => {\r\n setInputValue(String(page));\r\n }, [page]);\r\n\r\n const commitInput = (raw: string) => {\r\n const val = parseInt(raw, 10);\r\n if (!isNaN(val) && val >= 1 && val <= totalPages && val !== page) {\r\n onChange(val);\r\n } else {\r\n setInputValue(String(page)); // revert on invalid or same-page\r\n }\r\n };\r\n\r\n // ── Layout flags ───────────────────────────────────────────────────────────\r\n const hasResults = totalItems !== undefined && pageSize !== undefined;\r\n const hasPageSize = !!onPageSizeChange && pageSize !== undefined;\r\n const tableMode = hasResults || hasPageSize;\r\n\r\n const startItem = hasResults ? (totalItems === 0 ? 0 : (page - 1) * pageSize! + 1) : undefined;\r\n const endItem = hasResults ? Math.min(page * pageSize!, totalItems!) : undefined;\r\n\r\n const rootClasses = [\r\n 'eidos-pagination',\r\n `eidos-pagination--${size}`,\r\n tableMode && 'eidos-pagination--table',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n // ── Navigation block ───────────────────────────────────────────────────────\r\n const nav = (\r\n <nav aria-label=\"Pagination\" className=\"eidos-pagination-nav\">\r\n {showFirstLast && (\r\n <Button\r\n variant=\"text\"\r\n size={size}\r\n icon={ChevronsLeft}\r\n disabled={page === 1 || disabled}\r\n onClick={() => onChange(1)}\r\n aria-label=\"First page\"\r\n />\r\n )}\r\n\r\n <Button\r\n variant=\"text\"\r\n size={size}\r\n icon={ChevronLeft}\r\n disabled={page === 1 || disabled}\r\n onClick={() => onChange(page - 1)}\r\n aria-label=\"Previous page\"\r\n />\r\n\r\n {items.map((item, i) =>\r\n item === ELLIPSIS ? (\r\n <span key={`ellipsis-${i}`} className=\"eidos-pagination-ellipsis\" aria-hidden=\"true\">\r\n …\r\n </span>\r\n ) : item === page ? (\r\n // Active page - styled as filled chip, editable via keyboard/click\r\n <input\r\n key=\"active-page\"\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n className={[\r\n 'eidos-pagination-page',\r\n 'eidos-pagination-page--active',\r\n `eidos-pagination-page--${color}`,\r\n ].join(' ')}\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onFocus={(e) => e.target.select()}\r\n onBlur={() => commitInput(inputValue)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n commitInput(inputValue);\r\n e.currentTarget.blur();\r\n } else if (e.key === 'Escape') {\r\n setInputValue(String(page));\r\n e.currentTarget.blur();\r\n }\r\n }}\r\n aria-label={`Page ${page} of ${totalPages}, editable`}\r\n aria-current=\"page\"\r\n disabled={disabled}\r\n />\r\n ) : (\r\n <button\r\n key={item}\r\n type=\"button\"\r\n className=\"eidos-pagination-page\"\r\n onClick={() => onChange(item)}\r\n disabled={disabled}\r\n aria-label={`Page ${item}`}\r\n >\r\n {item}\r\n </button>\r\n ),\r\n )}\r\n\r\n <Button\r\n variant=\"text\"\r\n size={size}\r\n icon={ChevronRight}\r\n disabled={page === totalPages || disabled}\r\n onClick={() => onChange(page + 1)}\r\n aria-label=\"Next page\"\r\n />\r\n\r\n {showFirstLast && (\r\n <Button\r\n variant=\"text\"\r\n size={size}\r\n icon={ChevronsRight}\r\n disabled={page === totalPages || disabled}\r\n onClick={() => onChange(totalPages)}\r\n aria-label=\"Last page\"\r\n />\r\n )}\r\n </nav>\r\n );\r\n\r\n // ── Standalone mode ────────────────────────────────────────────────────────\r\n if (!tableMode) {\r\n return <div className={rootClasses}>{nav}</div>;\r\n }\r\n\r\n // ── Table-footer mode ──────────────────────────────────────────────────────\r\n return (\r\n <div className={rootClasses}>\r\n {hasResults && (\r\n <span className=\"eidos-pagination-info\">\r\n Showing {startItem}-{endItem} of {totalItems} results\r\n </span>\r\n )}\r\n\r\n <div className=\"eidos-pagination-controls\">\r\n {hasPageSize && (\r\n <div className=\"eidos-pagination-size\">\r\n <label className=\"eidos-pagination-size-label\">Show:</label>\r\n <Select\r\n value={String(pageSize)}\r\n onChange={(val) => onPageSizeChange(Number(val))}\r\n options={pageSizeOptions.map((n) => ({\r\n id: String(n),\r\n value: String(n),\r\n label: String(n),\r\n }))}\r\n clearable={false}\r\n disabled={disabled}\r\n inputProps={{ size: 'sm', width: '3ch' }}\r\n />\r\n </div>\r\n )}\r\n\r\n {totalPages > 1 && nav}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nPagination.displayName = 'Pagination';\r\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-P74HNSNJ.cjs","../src/components/ContextMenu/ContextMenu.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACA;ACJA,8BAAgE;AAChE,qCAA6B;AAkHzB,+CAAA;AAnFG,IAAM,YAAA,EAA0C,CAAC;AAAA,EACtD,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,EAAW,KAAA;AAAA,EACX,UAAA,EAAY;AACd,CAAA,EAAA,GAAM;AACJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,EAAA,EAAI,6BAAA,KAAc,CAAA;AAC1C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,EAAA,EAAI,6BAAA,EAAyB,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,EAAE,CAAC,CAAA;AACrE,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,EAAA,EAAI,6BAAA,KAAc,CAAA;AACtD,EAAA,MAAM,QAAA,EAAU,2BAAA,IAA2B,CAAA;AAE3C,EAAA,MAAM,MAAA,EAAQ,gCAAA,CAAY,EAAA,GAAM;AAC9B,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,EACvB,CAAA,EAAG,CAAC,CAAC,CAAA;AAGL,EAAA,8BAAA,CAAU,EAAA,GAAM;AACd,IAAA,GAAA,CAAI,CAAC,OAAA,GAAU,CAAC,OAAA,CAAQ,OAAA,EAAS,MAAA;AAEjC,IAAA,MAAM,KAAA,EAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,MAAM,EAAE,KAAA,EAAO,OAAO,EAAA,EAAI,IAAA,CAAK,qBAAA,CAAsB,CAAA;AACrD,IAAA,MAAM,GAAA,EAAK,MAAA,CAAO,UAAA;AAClB,IAAA,MAAM,GAAA,EAAK,MAAA,CAAO,WAAA;AAClB,IAAA,MAAM,IAAA,EAAM,CAAA;AAEZ,IAAA,MAAM,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,GAAA,EAAK,MAAA,EAAQ,GAAG,CAAA;AACtD,IAAA,MAAM,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,GAAA,EAAK,OAAA,EAAS,GAAG,CAAA;AAEvD,IAAA,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,CAAA,EAAA;AACD,IAAA;AACD,IAAA;AACG,EAAA;AAGL,EAAA;AACD,IAAA;AAEP,IAAA;AACQ,MAAA;AACJ,QAAA;AACR,MAAA;AACF,IAAA;AAES,IAAA;AACI,IAAA;AACG,EAAA;AAGF,EAAA;AACD,IAAA;AAEP,IAAA;AACU,MAAA;AAChB,IAAA;AAEM,IAAA;AAEG,IAAA;AACF,IAAA;AACM,IAAA;AACF,MAAA;AACF,MAAA;AACT,IAAA;AACgB,EAAA;AAEZ,EAAA;AACU,IAAA;AACG,IAAA;AACC,IAAA;AACJ,IAAA;AACE,IAAA;AACG,IAAA;AACrB,EAAA;AAEM,EAAA;AACiB,IAAA;AACb,MAAA;AACR,IAAA;AACM,IAAA;AACR,EAAA;AAGE,EAAA;AACE,oBAAA;AAAC,MAAA;AAAA,MAAA;AACa,QAAA;AACG,QAAA;AAEd,QAAA;AAAA,MAAA;AACH,IAAA;AAGE,IAAA;AACE,sBAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACM,UAAA;AACT,YAAA;AACA,YAAA;AAEQ,UAAA;AAEH,UAAA;AACA,YAAA;AACC,YAAA;AACR,UAAA;AAEA,UAAA;AAAuD,QAAA;AACzD,MAAA;AACS,MAAA;AACX,IAAA;AACJ,EAAA;AAEJ;AD3CuB;AACA;AACA;AACA","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-P74HNSNJ.cjs","sourcesContent":[null,"import React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { MenuPanel } from '../Menu';\r\nimport type { MenuItem } from '../Menu';\r\nimport type { ContextMenuProps } from './ContextMenu.types';\r\n\r\ninterface MenuPosition {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * ContextMenu - wraps any content and attaches a right-click (or long-press)\r\n * triggered menu positioned at the cursor.\r\n *\r\n * The browser's native context menu is suppressed when `disabled` is false.\r\n * The menu closes on: click outside, item selection, Escape, and scroll.\r\n *\r\n * @example\r\n * ```tsx\r\n * <ContextMenu\r\n * items={[\r\n * { type: 'item', id: 'copy', label: 'Copy', icon: Copy, onClick: () => copy() },\r\n * { type: 'item', id: 'cut', label: 'Cut', icon: Scissors, onClick: () => cut() },\r\n * { type: 'separator', id: 'sep1' },\r\n * { type: 'item', id: 'delete', label: 'Delete', icon: Trash2, onClick: () => remove(), disabled: true },\r\n * ]}\r\n * >\r\n * <div className=\"canvas-area\">...</div>\r\n * </ContextMenu>\r\n * ```\r\n */\r\nexport const ContextMenu: React.FC<ContextMenuProps> = ({\r\n items,\r\n children,\r\n disabled = false,\r\n className = '',\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [position, setPosition] = useState<MenuPosition>({ x: 0, y: 0 });\r\n const [isPositioned, setIsPositioned] = useState(false);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n\r\n const close = useCallback(() => {\r\n setIsOpen(false);\r\n setIsPositioned(false);\r\n }, []);\r\n\r\n // Measure the menu panel after it renders and clamp to viewport edges.\r\n useEffect(() => {\r\n if (!isOpen || !menuRef.current) return;\r\n\r\n const menu = menuRef.current;\r\n const { width, height } = menu.getBoundingClientRect();\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n const GAP = 4; // px clearance from viewport edge\r\n\r\n const clampedX = Math.min(position.x, vw - width - GAP);\r\n const clampedY = Math.min(position.y, vh - height - GAP);\r\n\r\n menu.style.left = `${Math.max(GAP, clampedX)}px`;\r\n menu.style.top = `${Math.max(GAP, clampedY)}px`;\r\n setIsPositioned(true);\r\n }, [isOpen, position]);\r\n\r\n // Close on click outside.\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n const handleMouseDown = (e: MouseEvent) => {\r\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\r\n close();\r\n }\r\n };\r\n\r\n document.addEventListener('mousedown', handleMouseDown);\r\n return () => document.removeEventListener('mousedown', handleMouseDown);\r\n }, [isOpen, close]);\r\n\r\n // Close on Escape or scroll.\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') close();\r\n };\r\n\r\n const handleScroll = () => close();\r\n\r\n document.addEventListener('keydown', handleKeyDown);\r\n window.addEventListener('scroll', handleScroll, true); // capture: catches nested scrollers\r\n return () => {\r\n document.removeEventListener('keydown', handleKeyDown);\r\n window.removeEventListener('scroll', handleScroll, true);\r\n };\r\n }, [isOpen, close]);\r\n\r\n const handleContextMenu = (e: React.MouseEvent) => {\r\n if (disabled) return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setIsOpen(true);\r\n setIsPositioned(false);\r\n setPosition({ x: e.clientX, y: e.clientY });\r\n };\r\n\r\n const handleItemClick = useCallback(\r\n (_item: MenuItem) => {\r\n close();\r\n },\r\n [close],\r\n );\r\n\r\n return (\r\n <>\r\n <div\r\n className={['eidos-context-menu-target', className].filter(Boolean).join(' ')}\r\n onContextMenu={handleContextMenu}\r\n >\r\n {children}\r\n </div>\r\n\r\n {isOpen &&\r\n createPortal(\r\n <div\r\n ref={menuRef}\r\n className={[\r\n 'eidos-context-menu-panel',\r\n isPositioned && 'eidos-context-menu-panel--positioned',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{\r\n top: position.y,\r\n left: position.x,\r\n }}\r\n >\r\n <MenuPanel items={items} onItemClick={handleItemClick} />\r\n </div>,\r\n document.body,\r\n )}\r\n </>\r\n );\r\n};\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-PEPYVWGY.cjs","../src/components/CommandPalette/CommandPalette.component.tsx"],"names":[],"mappings":"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","file":"/Users/pedromealha/Documents/Repositories/Personal/eidos-ui/dist/chunk-PEPYVWGY.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { ArrowDown, ArrowUp, Command, CornerDownLeft, Search } from 'lucide-react';\r\nimport type { CommandItem, CommandPaletteProps } from './CommandPalette.types';\r\nimport { Kbd } from '../Kbd';\r\nimport './CommandPalette.scss';\r\n\r\n// ── Constants ──────────────────────────────────────────────────────────────────\r\n\r\n/** Must match the CSS transition duration in CommandPalette.scss */\r\nconst TRANSITION_MS = 200;\r\n\r\n// ── Pure helpers ───────────────────────────────────────────────────────────────\r\n\r\nfunction filterItems(items: CommandItem[], query: string): CommandItem[] {\r\n const q = query.trim().toLowerCase();\r\n if (!q) return items;\r\n return items.filter(({ label, description, keywords }) => {\r\n return (\r\n label.toLowerCase().includes(q) ||\r\n (description?.toLowerCase().includes(q) ?? false) ||\r\n (keywords?.some((k) => k.toLowerCase().includes(q)) ?? false)\r\n );\r\n });\r\n}\r\n\r\ninterface Group {\r\n label: string | null;\r\n items: CommandItem[];\r\n}\r\n\r\n/**\r\n * Groups items while preserving the order in which groups first appear.\r\n * Items with no `group` property are placed in a leading implicit section\r\n * (label: null) so that labelled groups always follow them.\r\n */\r\nfunction buildGroups(items: CommandItem[]): Group[] {\r\n const groups: Group[] = [];\r\n const groupMap = new Map<string, Group>();\r\n\r\n for (const item of items) {\r\n const key = item.group ?? '';\r\n let group = groupMap.get(key);\r\n if (!group) {\r\n group = { label: item.group ?? null, items: [] };\r\n groups.push(group);\r\n groupMap.set(key, group);\r\n }\r\n group.items.push(item);\r\n }\r\n\r\n return groups;\r\n}\r\n\r\n// ── Component ──────────────────────────────────────────────────────────────────\r\n\r\nexport const CommandPalette: React.FC<CommandPaletteProps> = ({\r\n open: openProp,\r\n defaultOpen = false,\r\n onClose,\r\n onOpen,\r\n shortcutKey = 'k',\r\n items,\r\n onSelect,\r\n placeholder = 'Search commands…',\r\n emptyText = 'No commands found',\r\n maxHeight = 360,\r\n className = '',\r\n footer,\r\n trigger,\r\n triggerLabel = 'Search',\r\n}) => {\r\n const dialogId = useId();\r\n const listId = `${dialogId}-list`;\r\n\r\n // ── Controlled / uncontrolled open state ───────────────────────────────────\r\n // Omitting `open` lets the palette own its state entirely, which combined\r\n // with the shortcut listener below means it needs zero external\r\n // useState/useEffect to work. Passing `open` (+ `onClose`, optionally\r\n // `onOpen`) keeps full external control for consumers who need it (syncing\r\n // with a URL, another piece of app state, etc).\r\n const isControlled = openProp !== undefined;\r\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\r\n const open = isControlled ? (openProp as boolean) : internalOpen;\r\n\r\n const close = useCallback(() => {\r\n if (!isControlled) setInternalOpen(false);\r\n onClose?.();\r\n }, [isControlled, onClose]);\r\n\r\n // Shared \"open\" path - uncontrolled flips the internal state directly;\r\n // controlled defers to `onOpen` since the palette can't change `open`\r\n // itself. Used by both the keyboard shortcut below and the inline\r\n // `trigger`'s click handler.\r\n const openPalette = useCallback(() => {\r\n if (isControlled) {\r\n onOpen?.();\r\n } else {\r\n setInternalOpen(true);\r\n }\r\n }, [isControlled, onOpen]);\r\n\r\n // Global keyboard shortcut - Cmd/Ctrl+<shortcutKey> opens the palette.\r\n useEffect(() => {\r\n if (!shortcutKey) return;\r\n\r\n const handler = (e: KeyboardEvent) => {\r\n if (!(e.metaKey || e.ctrlKey) || e.key.toLowerCase() !== shortcutKey.toLowerCase()) return;\r\n e.preventDefault();\r\n openPalette();\r\n };\r\n\r\n window.addEventListener('keydown', handler);\r\n return () => window.removeEventListener('keydown', handler);\r\n }, [shortcutKey, openPalette]);\r\n\r\n // ── Animation state machine (mirrors the Drawer pattern) ─────────────────\r\n // isMounted → portal exists in the DOM (controls render/null)\r\n // isVisible → CSS --visible modifier is applied (drives transitions)\r\n //\r\n // Opening: isMounted=true → double rAF → isVisible=true → CSS transitions fire\r\n // Closing: isVisible=false → CSS transitions reverse → after TRANSITION_MS → isMounted=false\r\n const [isMounted, setIsMounted] = useState(open);\r\n const [isVisible, setIsVisible] = useState(open);\r\n\r\n useEffect(() => {\r\n let raf1 = 0;\r\n let raf2 = 0;\r\n let timerId: ReturnType<typeof setTimeout>;\r\n\r\n if (open) {\r\n setIsMounted(true);\r\n // Double rAF: ensures the browser has painted the initial off-screen\r\n // state before the CSS transition begins (React 18 automatic batching\r\n // means a single rAF is not always sufficient).\r\n raf1 = requestAnimationFrame(() => {\r\n raf2 = requestAnimationFrame(() => setIsVisible(true));\r\n });\r\n } else {\r\n setIsVisible(false);\r\n timerId = setTimeout(() => setIsMounted(false), TRANSITION_MS);\r\n }\r\n\r\n return () => {\r\n cancelAnimationFrame(raf1);\r\n cancelAnimationFrame(raf2);\r\n clearTimeout(timerId);\r\n };\r\n }, [open]);\r\n\r\n // ── Search state ───────────────────────────────────────────────────────────\r\n const [query, setQuery] = useState('');\r\n const [focusedIndex, setFocusedIndex] = useState(0);\r\n\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());\r\n\r\n // Derived lists - memoised to stabilise scroll-effect deps\r\n const filtered = useMemo(() => filterItems(items, query), [items, query]);\r\n const navigable = useMemo(() => filtered.filter((item) => !item.disabled), [filtered]);\r\n const groups = useMemo(() => buildGroups(filtered), [filtered]);\r\n\r\n // Reset search query and selection when the palette is opened\r\n useEffect(() => {\r\n if (open) {\r\n setQuery('');\r\n setFocusedIndex(0);\r\n }\r\n }, [open]);\r\n\r\n // Auto-focus the search input after the entry animation begins\r\n useEffect(() => {\r\n if (isVisible) {\r\n inputRef.current?.focus();\r\n }\r\n }, [isVisible]);\r\n\r\n // Reset focused index to 0 whenever the filtered list changes\r\n useEffect(() => {\r\n setFocusedIndex(0);\r\n }, [query]);\r\n\r\n // Scroll the focused item into view during keyboard navigation\r\n useEffect(() => {\r\n const focusedItem = navigable[focusedIndex];\r\n if (!focusedItem) return;\r\n itemRefs.current.get(focusedItem.id)?.scrollIntoView({ block: 'nearest' });\r\n }, [focusedIndex, navigable]);\r\n\r\n // Body scroll lock (tied to open, not to isMounted, so it releases promptly\r\n // when the consumer decides to close - even before the exit animation ends)\r\n useEffect(() => {\r\n if (open) {\r\n document.body.style.overflow = 'hidden';\r\n }\r\n return () => {\r\n document.body.style.overflow = '';\r\n };\r\n }, [open]);\r\n\r\n // ── Interaction handlers ───────────────────────────────────────────────────\r\n\r\n const selectItem = useCallback(\r\n (item: CommandItem) => {\r\n if (item.disabled) return;\r\n item.action?.();\r\n onSelect?.(item);\r\n close();\r\n },\r\n [close, onSelect],\r\n );\r\n\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent) => {\r\n switch (e.key) {\r\n case 'ArrowDown': {\r\n e.preventDefault();\r\n if (navigable.length === 0) return;\r\n setFocusedIndex((i) => (i + 1) % navigable.length);\r\n break;\r\n }\r\n case 'ArrowUp': {\r\n e.preventDefault();\r\n if (navigable.length === 0) return;\r\n setFocusedIndex((i) => (i - 1 + navigable.length) % navigable.length);\r\n break;\r\n }\r\n case 'Enter': {\r\n e.preventDefault();\r\n const item = navigable[focusedIndex];\r\n if (item) selectItem(item);\r\n break;\r\n }\r\n case 'Escape': {\r\n e.preventDefault();\r\n close();\r\n break;\r\n }\r\n }\r\n },\r\n [focusedIndex, navigable, close, selectItem],\r\n );\r\n\r\n const handleBackdropClick = useCallback(\r\n (e: React.MouseEvent<HTMLDivElement>) => {\r\n // Only fire when the click lands directly on the backdrop element,\r\n // not on any child (the dialog itself or its contents).\r\n if (e.target === e.currentTarget) {\r\n close();\r\n }\r\n },\r\n [close],\r\n );\r\n\r\n // ── Render ─────────────────────────────────────────────────────────────────\r\n\r\n // The inline trigger (if any) must render regardless of `isMounted` - it's\r\n // what opens the palette in the first place, so it can't be gated behind\r\n // the portal's own mount state.\r\n const triggerNode =\r\n trigger === true ? (\r\n <button type=\"button\" className=\"eidos-cmd-trigger-default\" onClick={openPalette}>\r\n <span>{triggerLabel}</span>\r\n {shortcutKey && (\r\n <Kbd size=\"sm\" className=\"eidos-cmd-trigger-kbd\">\r\n <Command size={10} />\r\n {shortcutKey.toUpperCase()}\r\n </Kbd>\r\n )}\r\n </button>\r\n ) : trigger ? (\r\n <div className=\"eidos-cmd-trigger\" role=\"button\" tabIndex={0} onClick={openPalette}>\r\n {trigger}\r\n </div>\r\n ) : null;\r\n\r\n if (!isMounted) return triggerNode;\r\n\r\n const maxHeightValue = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;\r\n\r\n return (\r\n <>\r\n {triggerNode}\r\n {createPortal(\r\n <div\r\n className={['eidos-cmd-backdrop', isVisible && 'eidos-cmd-backdrop--visible']\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={handleBackdropClick}\r\n aria-hidden={!open}\r\n >\r\n <div\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label=\"Command palette\"\r\n id={dialogId}\r\n className={['eidos-cmd-dialog', isVisible && 'eidos-cmd-dialog--visible', className]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {/* ── Search ──────────────────────────────────────────────────────── */}\r\n <div className=\"eidos-cmd-search\">\r\n <Search className=\"eidos-cmd-search-icon\" size={18} aria-hidden=\"true\" />\r\n\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n role=\"combobox\"\r\n aria-expanded=\"true\"\r\n aria-controls={listId}\r\n aria-autocomplete=\"list\"\r\n aria-label={placeholder}\r\n className=\"eidos-cmd-input\"\r\n placeholder={placeholder}\r\n value={query}\r\n onChange={(e) => setQuery(e.target.value)}\r\n spellCheck={false}\r\n autoComplete=\"off\"\r\n />\r\n\r\n {/* Reminds users of the configured shortcut, if any */}\r\n {shortcutKey && (\r\n <div className=\"eidos-cmd-search-badge\" aria-hidden=\"true\">\r\n <Command size={11} />\r\n <span>{shortcutKey.toUpperCase()}</span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* ── Results list ─────────────────────────────────────────────────── */}\r\n <div\r\n id={listId}\r\n role=\"listbox\"\r\n aria-label=\"Commands\"\r\n className=\"eidos-cmd-list\"\r\n style={{ maxHeight: maxHeightValue }}\r\n >\r\n {filtered.length === 0 ? (\r\n <p className=\"eidos-cmd-empty\" role=\"status\">\r\n {emptyText}\r\n </p>\r\n ) : (\r\n groups.map((group) => (\r\n <div\r\n key={group.label ?? '__ungrouped__'}\r\n role=\"group\"\r\n aria-label={group.label ?? undefined}\r\n >\r\n {group.label && (\r\n <div className=\"eidos-cmd-group-label\" aria-hidden=\"true\">\r\n {group.label}\r\n </div>\r\n )}\r\n\r\n {group.items.map((item) => {\r\n const isFocused = navigable[focusedIndex]?.id === item.id;\r\n const Icon = item.icon;\r\n\r\n return (\r\n <div\r\n key={item.id}\r\n ref={(el) => {\r\n if (el) {\r\n itemRefs.current.set(item.id, el);\r\n } else {\r\n itemRefs.current.delete(item.id);\r\n }\r\n }}\r\n role=\"option\"\r\n aria-selected={isFocused}\r\n aria-disabled={item.disabled}\r\n className={[\r\n 'eidos-cmd-item',\r\n isFocused && 'eidos-cmd-item--focused',\r\n item.disabled && 'eidos-cmd-item--disabled',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n onClick={() => selectItem(item)}\r\n onMouseEnter={() => {\r\n if (!item.disabled) {\r\n const idx = navigable.findIndex((n) => n.id === item.id);\r\n if (idx !== -1) setFocusedIndex(idx);\r\n }\r\n }}\r\n >\r\n {Icon && (\r\n <span className=\"eidos-cmd-item-icon\" aria-hidden=\"true\">\r\n <Icon size={16} />\r\n </span>\r\n )}\r\n\r\n <div className=\"eidos-cmd-item-body\">\r\n <div className=\"eidos-cmd-item-label\">{item.label}</div>\r\n {item.description && (\r\n <div className=\"eidos-cmd-item-description\">{item.description}</div>\r\n )}\r\n </div>\r\n\r\n {item.shortcut && item.shortcut.length > 0 && (\r\n <div\r\n className=\"eidos-cmd-item-shortcut\"\r\n aria-label={`Shortcut: ${item.shortcut.join(' ')}`}\r\n >\r\n {item.shortcut.map((key, i) => (\r\n <kbd key={i} className=\"eidos-cmd-kbd\">\r\n {key}\r\n </kbd>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ))\r\n )}\r\n </div>\r\n\r\n {/* ── Footer ───────────────────────────────────────────────────────── */}\r\n <div className=\"eidos-cmd-footer\">\r\n <div className=\"eidos-cmd-hints\" aria-hidden=\"true\">\r\n <span>\r\n <ArrowUp size={11} />\r\n <ArrowDown size={11} /> Navigate\r\n </span>\r\n <span>\r\n <CornerDownLeft size={11} /> Select\r\n </span>\r\n <span>Esc Close</span>\r\n </div>\r\n\r\n {footer && <div className=\"eidos-cmd-footer-slot\">{footer}</div>}\r\n </div>\r\n </div>\r\n </div>,\r\n document.body,\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nCommandPalette.displayName = 'CommandPalette';\r\n"]}