eidos-ui 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +17 -5
  2. package/dist/{Input.types-XrJTI0JC.d.ts → Input.types-CSDMaZNe.d.ts} +10 -0
  3. package/dist/{Input.types-DFZNyJGF.d.cts → Input.types-D7-sWq-q.d.cts} +10 -0
  4. package/dist/{Menu.types-DNIpjSAK.d.ts → Menu.types-BN4g1-3A.d.ts} +9 -0
  5. package/dist/{Menu.types-DwcuCZM7.d.cts → Menu.types-CTnUijv5.d.cts} +9 -0
  6. package/dist/{Select.types-B4kDpkGB.d.ts → Select.types-C2tGy1vj.d.ts} +11 -1
  7. package/dist/{Select.types-CAkT2ACt.d.cts → Select.types-ok-03rLo.d.cts} +11 -1
  8. package/dist/{Table.types-CPj-udMc.d.cts → Table.types-D-9tC0kJ.d.cts} +2 -3
  9. package/dist/{Table.types-CZZ7QWAI.d.ts → Table.types-D8pmgxKA.d.ts} +2 -3
  10. package/dist/{Toolbar.types-RN0klQzu.d.ts → Toolbar.types-CKnQC_TW.d.ts} +1 -1
  11. package/dist/{Toolbar.types-DSk8z2iy.d.cts → Toolbar.types-DUz2mxct.d.cts} +1 -1
  12. package/dist/alert/index.cjs +5 -5
  13. package/dist/alert/index.js +4 -4
  14. package/dist/button/index.cjs +4 -4
  15. package/dist/button/index.js +3 -3
  16. package/dist/checkbox/index.cjs +2 -2
  17. package/dist/checkbox/index.js +1 -1
  18. package/dist/chip/index.cjs +4 -4
  19. package/dist/chip/index.js +3 -3
  20. package/dist/{chunk-ITXDSQT2.js → chunk-24HKKSKX.js} +94 -102
  21. package/dist/chunk-24HKKSKX.js.map +1 -0
  22. package/dist/{chunk-GDQWSCJQ.js → chunk-26SO4LZ5.js} +4 -4
  23. package/dist/{chunk-GPRJYPIG.js → chunk-2JW3WSBF.js} +6 -4
  24. package/dist/chunk-2JW3WSBF.js.map +1 -0
  25. package/dist/{chunk-MHZIBV2C.js → chunk-2PCCGQOH.js} +90 -19
  26. package/dist/chunk-2PCCGQOH.js.map +1 -0
  27. package/dist/{chunk-3EPND5M2.cjs → chunk-2T7ZMMH5.cjs} +72 -19
  28. package/dist/chunk-2T7ZMMH5.cjs.map +1 -0
  29. package/dist/chunk-35LGEPLP.cjs +134 -0
  30. package/dist/chunk-35LGEPLP.cjs.map +1 -0
  31. package/dist/{chunk-R4M6SNUU.cjs → chunk-36JFXFM2.cjs} +48 -37
  32. package/dist/chunk-36JFXFM2.cjs.map +1 -0
  33. package/dist/{chunk-ND526PMG.cjs → chunk-3KBBJZHK.cjs} +11 -11
  34. package/dist/{chunk-ND526PMG.cjs.map → chunk-3KBBJZHK.cjs.map} +1 -1
  35. package/dist/{chunk-EH42ND5Q.cjs → chunk-3RWZC6OW.cjs} +5 -5
  36. package/dist/{chunk-EH42ND5Q.cjs.map → chunk-3RWZC6OW.cjs.map} +1 -1
  37. package/dist/{chunk-G5N3C6AU.cjs → chunk-3ZRFOKDM.cjs} +36 -36
  38. package/dist/{chunk-G5N3C6AU.cjs.map → chunk-3ZRFOKDM.cjs.map} +1 -1
  39. package/dist/{chunk-I5XR2V4A.cjs → chunk-4AO5RKV5.cjs} +87 -96
  40. package/dist/chunk-4AO5RKV5.cjs.map +1 -0
  41. package/dist/{chunk-5HUZYY54.js → chunk-4J25XZDI.js} +23 -13
  42. package/dist/chunk-4J25XZDI.js.map +1 -0
  43. package/dist/{chunk-FXZJL2AM.cjs → chunk-4JSTBA4F.cjs} +12 -6
  44. package/dist/chunk-4JSTBA4F.cjs.map +1 -0
  45. package/dist/{chunk-GG5YGESX.js → chunk-4LNTZPSQ.js} +4 -3
  46. package/dist/chunk-4LNTZPSQ.js.map +1 -0
  47. package/dist/{chunk-3EUTXQDB.js → chunk-5XH2PHT2.js} +31 -24
  48. package/dist/chunk-5XH2PHT2.js.map +1 -0
  49. package/dist/{chunk-OJDYTCMO.cjs → chunk-66UQTF57.cjs} +69 -62
  50. package/dist/chunk-66UQTF57.cjs.map +1 -0
  51. package/dist/{chunk-MCWTQT3M.cjs → chunk-6JHVXWDV.cjs} +125 -54
  52. package/dist/chunk-6JHVXWDV.cjs.map +1 -0
  53. package/dist/chunk-75GFIQRU.js +88 -0
  54. package/dist/chunk-75GFIQRU.js.map +1 -0
  55. package/dist/{chunk-55J4LEKT.cjs → chunk-7BFODYNL.cjs} +11 -8
  56. package/dist/chunk-7BFODYNL.cjs.map +1 -0
  57. package/dist/{chunk-TEVZHN5I.cjs → chunk-7VJCGKVP.cjs} +28 -15
  58. package/dist/chunk-7VJCGKVP.cjs.map +1 -0
  59. package/dist/{chunk-KQJ3IAFT.js → chunk-A3LMUPG3.js} +2 -2
  60. package/dist/{chunk-O2AACVSF.js → chunk-AR2ZOO6L.js} +3 -3
  61. package/dist/{chunk-Z5U4NJTW.cjs → chunk-BEOECPVJ.cjs} +50 -23
  62. package/dist/chunk-BEOECPVJ.cjs.map +1 -0
  63. package/dist/{chunk-E7FGY7BJ.js → chunk-BFKPJ627.js} +5 -4
  64. package/dist/chunk-BFKPJ627.js.map +1 -0
  65. package/dist/{chunk-M7PF4FKQ.js → chunk-D7SQ7LHJ.js} +6 -3
  66. package/dist/chunk-D7SQ7LHJ.js.map +1 -0
  67. package/dist/chunk-DA375AI6.cjs +88 -0
  68. package/dist/chunk-DA375AI6.cjs.map +1 -0
  69. package/dist/{chunk-H6CWTMAH.js → chunk-DGXHR6FV.js} +5 -2
  70. package/dist/chunk-DGXHR6FV.js.map +1 -0
  71. package/dist/{chunk-ZNWIHUHZ.cjs → chunk-DU5JKTHK.cjs} +12 -4
  72. package/dist/chunk-DU5JKTHK.cjs.map +1 -0
  73. package/dist/{chunk-HALVTKW7.js → chunk-FIVMMCGM.js} +72 -81
  74. package/dist/chunk-FIVMMCGM.js.map +1 -0
  75. package/dist/{chunk-RYOQYYDO.js → chunk-GIEDIAPD.js} +12 -6
  76. package/dist/chunk-GIEDIAPD.js.map +1 -0
  77. package/dist/{chunk-NQ4L6PYW.js → chunk-GOF6A4M4.js} +2 -2
  78. package/dist/{chunk-NQ4L6PYW.js.map → chunk-GOF6A4M4.js.map} +1 -1
  79. package/dist/{chunk-L23WWO3D.js → chunk-GPVGGBIR.js} +2 -2
  80. package/dist/{chunk-OAK7HFOJ.js → chunk-GWHZFX2H.js} +21 -16
  81. package/dist/chunk-GWHZFX2H.js.map +1 -0
  82. package/dist/{chunk-HYDNZXPU.js → chunk-H2RS6Z6Q.js} +41 -25
  83. package/dist/{chunk-HYDNZXPU.js.map → chunk-H2RS6Z6Q.js.map} +1 -1
  84. package/dist/{chunk-2QEKSRVX.js → chunk-HEX4IMLO.js} +4 -4
  85. package/dist/{chunk-QJRKXT54.cjs → chunk-HMEREPDB.cjs} +7 -7
  86. package/dist/{chunk-QJRKXT54.cjs.map → chunk-HMEREPDB.cjs.map} +1 -1
  87. package/dist/{chunk-TTO7JXDB.cjs → chunk-HNGFRRVZ.cjs} +3 -3
  88. package/dist/{chunk-TTO7JXDB.cjs.map → chunk-HNGFRRVZ.cjs.map} +1 -1
  89. package/dist/{chunk-CJGFRPAS.cjs → chunk-I6M6CVI2.cjs} +4 -4
  90. package/dist/chunk-I6M6CVI2.cjs.map +1 -0
  91. package/dist/chunk-J76JHN7J.cjs +225 -0
  92. package/dist/chunk-J76JHN7J.cjs.map +1 -0
  93. package/dist/{chunk-YW65NAKH.cjs → chunk-JCKGAAPZ.cjs} +7 -7
  94. package/dist/{chunk-YW65NAKH.cjs.map → chunk-JCKGAAPZ.cjs.map} +1 -1
  95. package/dist/{chunk-6CPCNQKV.js → chunk-JHX6JK3M.js} +79 -75
  96. package/dist/chunk-JHX6JK3M.js.map +1 -0
  97. package/dist/{chunk-YV57RSPD.js → chunk-JNY7TUDS.js} +49 -22
  98. package/dist/chunk-JNY7TUDS.js.map +1 -0
  99. package/dist/{chunk-O3LG7B2J.cjs → chunk-JPYJQ4TF.cjs} +13 -5
  100. package/dist/chunk-JPYJQ4TF.cjs.map +1 -0
  101. package/dist/{chunk-PY2376XI.js → chunk-JT4KVXJK.js} +68 -15
  102. package/dist/chunk-JT4KVXJK.js.map +1 -0
  103. package/dist/{chunk-AOGNTG3W.cjs → chunk-KBQD4JLK.cjs} +5 -4
  104. package/dist/chunk-KBQD4JLK.cjs.map +1 -0
  105. package/dist/{chunk-P2JM22BF.cjs → chunk-KIZVY57H.cjs} +82 -78
  106. package/dist/chunk-KIZVY57H.cjs.map +1 -0
  107. package/dist/{chunk-QQIALSTX.cjs → chunk-KPMIIGHH.cjs} +27 -17
  108. package/dist/chunk-KPMIIGHH.cjs.map +1 -0
  109. package/dist/{chunk-ZXJU3TQD.cjs → chunk-KREHT4AQ.cjs} +11 -10
  110. package/dist/chunk-KREHT4AQ.cjs.map +1 -0
  111. package/dist/{chunk-S4S4LB63.js → chunk-L65MHFMD.js} +11 -3
  112. package/dist/chunk-L65MHFMD.js.map +1 -0
  113. package/dist/{chunk-OGC44JFZ.cjs → chunk-LQXFXXMJ.cjs} +8 -7
  114. package/dist/chunk-LQXFXXMJ.cjs.map +1 -0
  115. package/dist/{chunk-25PSIDPC.js → chunk-MPIVBAMY.js} +79 -21
  116. package/dist/chunk-MPIVBAMY.js.map +1 -0
  117. package/dist/{chunk-7SVDYEKM.js → chunk-MQAOXZD4.js} +28 -14
  118. package/dist/chunk-MQAOXZD4.js.map +1 -0
  119. package/dist/{chunk-6CSUUQ5M.cjs → chunk-NOQF7UQ5.cjs} +6 -6
  120. package/dist/{chunk-6CSUUQ5M.cjs.map → chunk-NOQF7UQ5.cjs.map} +1 -1
  121. package/dist/{chunk-OU7DCYIA.js → chunk-O3QM3BFE.js} +2 -2
  122. package/dist/{chunk-WKDT2XFQ.js → chunk-OOCCSMWM.js} +4 -4
  123. package/dist/chunk-P4XZH3OR.js +225 -0
  124. package/dist/chunk-P4XZH3OR.js.map +1 -0
  125. package/dist/{chunk-ZWAFL2B3.cjs → chunk-PMSENLOA.cjs} +37 -27
  126. package/dist/chunk-PMSENLOA.cjs.map +1 -0
  127. package/dist/{chunk-L5W2XC6M.js → chunk-RHFD2Z5V.js} +8 -8
  128. package/dist/chunk-RHHZRTWM.js +134 -0
  129. package/dist/chunk-RHHZRTWM.js.map +1 -0
  130. package/dist/{chunk-NZO2I5AL.cjs → chunk-RJVHR45I.cjs} +7 -7
  131. package/dist/{chunk-NZO2I5AL.cjs.map → chunk-RJVHR45I.cjs.map} +1 -1
  132. package/dist/{chunk-E6SE552P.cjs → chunk-RUDXHT76.cjs} +41 -25
  133. package/dist/chunk-RUDXHT76.cjs.map +1 -0
  134. package/dist/{chunk-SXGCRHBZ.js → chunk-SDUGYJGW.js} +24 -14
  135. package/dist/chunk-SDUGYJGW.js.map +1 -0
  136. package/dist/{chunk-VPRUHE35.js → chunk-SFFKQQ5Z.js} +4 -4
  137. package/dist/{chunk-2RXQMQYW.js → chunk-SXL4DMZ7.js} +27 -17
  138. package/dist/{chunk-2RXQMQYW.js.map → chunk-SXL4DMZ7.js.map} +1 -1
  139. package/dist/{chunk-OAPOGYA5.cjs → chunk-TC5IC6OP.cjs} +7 -4
  140. package/dist/chunk-TC5IC6OP.cjs.map +1 -0
  141. package/dist/{chunk-T2KB3DJJ.js → chunk-THCTUBX6.js} +12 -4
  142. package/dist/chunk-THCTUBX6.js.map +1 -0
  143. package/dist/{chunk-NEYLNRVG.cjs → chunk-TTLFY76J.cjs} +21 -16
  144. package/dist/chunk-TTLFY76J.cjs.map +1 -0
  145. package/dist/{chunk-ZZSPQFMX.js → chunk-U233KQZX.js} +2 -1
  146. package/dist/{chunk-ZZSPQFMX.js.map → chunk-U233KQZX.js.map} +1 -1
  147. package/dist/{chunk-65PC3YDT.cjs → chunk-V4BZWBZT.cjs} +7 -7
  148. package/dist/{chunk-65PC3YDT.cjs.map → chunk-V4BZWBZT.cjs.map} +1 -1
  149. package/dist/{chunk-FKXKBJUI.cjs → chunk-VHO6JPRR.cjs} +2 -1
  150. package/dist/chunk-VHO6JPRR.cjs.map +1 -0
  151. package/dist/{chunk-3E7TKBQI.cjs → chunk-VQGLVBPL.cjs} +24 -14
  152. package/dist/chunk-VQGLVBPL.cjs.map +1 -0
  153. package/dist/{chunk-27ZWUEPE.js → chunk-WE2SBWZ6.js} +20 -9
  154. package/dist/chunk-WE2SBWZ6.js.map +1 -0
  155. package/dist/{chunk-TQGO5WK6.js → chunk-WNDDS367.js} +7 -6
  156. package/dist/chunk-WNDDS367.js.map +1 -0
  157. package/dist/{chunk-Q5KQVBQP.cjs → chunk-X3BVQBXD.cjs} +18 -16
  158. package/dist/chunk-X3BVQBXD.cjs.map +1 -0
  159. package/dist/{chunk-J5RMLZ4P.cjs → chunk-XERBOFYZ.cjs} +80 -22
  160. package/dist/chunk-XERBOFYZ.cjs.map +1 -0
  161. package/dist/{chunk-3CXULV4G.cjs → chunk-XRVRGRC3.cjs} +2 -2
  162. package/dist/{chunk-3CXULV4G.cjs.map → chunk-XRVRGRC3.cjs.map} +1 -1
  163. package/dist/{chunk-K7T25Y3A.cjs → chunk-XZLSHEHE.cjs} +41 -27
  164. package/dist/chunk-XZLSHEHE.cjs.map +1 -0
  165. package/dist/{chunk-JRLUZDKA.js → chunk-YAKTVIVK.js} +20 -7
  166. package/dist/chunk-YAKTVIVK.js.map +1 -0
  167. package/dist/{chunk-IJ4DXG7D.cjs → chunk-YJNQLH2L.cjs} +5 -2
  168. package/dist/chunk-YJNQLH2L.cjs.map +1 -0
  169. package/dist/{chunk-ZPDETHQ7.js → chunk-YP4HUBKN.js} +3 -3
  170. package/dist/{chunk-ZPDETHQ7.js.map → chunk-YP4HUBKN.js.map} +1 -1
  171. package/dist/{chunk-5WH3JMR5.js → chunk-YXRKBKFB.js} +7 -4
  172. package/dist/chunk-YXRKBKFB.js.map +1 -0
  173. package/dist/{chunk-ACNTH2OQ.cjs → chunk-ZMRINZIO.cjs} +98 -106
  174. package/dist/chunk-ZMRINZIO.cjs.map +1 -0
  175. package/dist/color-picker/index.cjs +4 -4
  176. package/dist/color-picker/index.d.cts +8 -0
  177. package/dist/color-picker/index.d.ts +8 -0
  178. package/dist/color-picker/index.js +3 -3
  179. package/dist/combobox/index.cjs +6 -6
  180. package/dist/combobox/index.js +5 -5
  181. package/dist/command-palette/index.cjs +3 -2
  182. package/dist/command-palette/index.cjs.map +1 -1
  183. package/dist/command-palette/index.js +2 -1
  184. package/dist/context-menu/index.cjs +6 -6
  185. package/dist/context-menu/index.d.cts +1 -1
  186. package/dist/context-menu/index.d.ts +1 -1
  187. package/dist/context-menu/index.js +5 -5
  188. package/dist/conversation/index.cjs +8 -8
  189. package/dist/conversation/index.d.cts +1 -1
  190. package/dist/conversation/index.d.ts +1 -1
  191. package/dist/conversation/index.js +7 -7
  192. package/dist/data-grid/index.cjs +16 -16
  193. package/dist/data-grid/index.d.cts +14 -15
  194. package/dist/data-grid/index.d.ts +14 -15
  195. package/dist/data-grid/index.js +15 -15
  196. package/dist/date-picker/index.cjs +8 -8
  197. package/dist/date-picker/index.d.cts +12 -2
  198. package/dist/date-picker/index.d.ts +12 -2
  199. package/dist/date-picker/index.js +7 -7
  200. package/dist/drawer/index.cjs +5 -5
  201. package/dist/drawer/index.js +4 -4
  202. package/dist/dropdown/index.cjs +3 -3
  203. package/dist/dropdown/index.d.cts +34 -0
  204. package/dist/dropdown/index.d.ts +34 -0
  205. package/dist/dropdown/index.js +2 -2
  206. package/dist/file-upload/index.cjs +2 -2
  207. package/dist/file-upload/index.js +1 -1
  208. package/dist/header/index.cjs +6 -6
  209. package/dist/header/index.js +5 -5
  210. package/dist/index.cjs +42 -42
  211. package/dist/index.css +112 -40
  212. package/dist/index.d.cts +5 -5
  213. package/dist/index.d.ts +5 -5
  214. package/dist/index.js +41 -41
  215. package/dist/inline-edit/index.cjs +5 -5
  216. package/dist/inline-edit/index.js +4 -4
  217. package/dist/input/index.cjs +4 -4
  218. package/dist/input/index.d.cts +2 -2
  219. package/dist/input/index.d.ts +2 -2
  220. package/dist/input/index.js +3 -3
  221. package/dist/menu/index.cjs +5 -5
  222. package/dist/menu/index.d.cts +23 -2
  223. package/dist/menu/index.d.ts +23 -2
  224. package/dist/menu/index.js +4 -4
  225. package/dist/modal/index.cjs +5 -5
  226. package/dist/modal/index.js +4 -4
  227. package/dist/navigation/index.cjs +5 -5
  228. package/dist/navigation/index.js +4 -4
  229. package/dist/number-input/index.cjs +3 -3
  230. package/dist/number-input/index.js +2 -2
  231. package/dist/o-t-p-input/index.cjs +2 -2
  232. package/dist/o-t-p-input/index.js +1 -1
  233. package/dist/page-layout/index.cjs +12 -12
  234. package/dist/page-layout/index.d.cts +2 -2
  235. package/dist/page-layout/index.d.ts +2 -2
  236. package/dist/page-layout/index.js +11 -11
  237. package/dist/pagination/index.cjs +8 -8
  238. package/dist/pagination/index.js +7 -7
  239. package/dist/popover/index.cjs +3 -2
  240. package/dist/popover/index.cjs.map +1 -1
  241. package/dist/popover/index.d.cts +3 -1
  242. package/dist/popover/index.d.ts +3 -1
  243. package/dist/popover/index.js +2 -1
  244. package/dist/radio/index.cjs +2 -2
  245. package/dist/radio/index.js +1 -1
  246. package/dist/segmented-control/index.cjs +4 -4
  247. package/dist/segmented-control/index.js +3 -3
  248. package/dist/select/index.cjs +6 -6
  249. package/dist/select/index.d.cts +3 -3
  250. package/dist/select/index.d.ts +3 -3
  251. package/dist/select/index.js +5 -5
  252. package/dist/snackbar/index.cjs +5 -5
  253. package/dist/snackbar/index.d.cts +4 -0
  254. package/dist/snackbar/index.d.ts +4 -0
  255. package/dist/snackbar/index.js +4 -4
  256. package/dist/split-button/index.cjs +6 -6
  257. package/dist/split-button/index.js +5 -5
  258. package/dist/table/index.cjs +14 -14
  259. package/dist/table/index.d.cts +2 -2
  260. package/dist/table/index.d.ts +2 -2
  261. package/dist/table/index.js +13 -13
  262. package/dist/tabs/index.cjs +3 -3
  263. package/dist/tabs/index.js +2 -2
  264. package/dist/tag-input/index.cjs +6 -6
  265. package/dist/tag-input/index.js +5 -5
  266. package/dist/textarea/index.cjs +4 -4
  267. package/dist/textarea/index.js +3 -3
  268. package/dist/theme-editor/index.cjs +11 -11
  269. package/dist/theme-editor/index.js +10 -10
  270. package/dist/theme-provider/index.cjs +3 -3
  271. package/dist/theme-provider/index.js +2 -2
  272. package/dist/toolbar/index.cjs +8 -8
  273. package/dist/toolbar/index.d.cts +3 -3
  274. package/dist/toolbar/index.d.ts +3 -3
  275. package/dist/toolbar/index.js +7 -7
  276. package/dist/tooltip/index.cjs +3 -2
  277. package/dist/tooltip/index.cjs.map +1 -1
  278. package/dist/tooltip/index.js +2 -1
  279. package/dist/virtual-list/index.cjs +2 -2
  280. package/dist/virtual-list/index.js +1 -1
  281. package/package.json +7 -2
  282. package/dist/chunk-25PSIDPC.js.map +0 -1
  283. package/dist/chunk-27ZWUEPE.js.map +0 -1
  284. package/dist/chunk-3E7TKBQI.cjs.map +0 -1
  285. package/dist/chunk-3EPND5M2.cjs.map +0 -1
  286. package/dist/chunk-3EUTXQDB.js.map +0 -1
  287. package/dist/chunk-55J4LEKT.cjs.map +0 -1
  288. package/dist/chunk-5HUZYY54.js.map +0 -1
  289. package/dist/chunk-5WH3JMR5.js.map +0 -1
  290. package/dist/chunk-6CPCNQKV.js.map +0 -1
  291. package/dist/chunk-7SVDYEKM.js.map +0 -1
  292. package/dist/chunk-ACNTH2OQ.cjs.map +0 -1
  293. package/dist/chunk-AOGNTG3W.cjs.map +0 -1
  294. package/dist/chunk-BNVQ34FD.js +0 -125
  295. package/dist/chunk-BNVQ34FD.js.map +0 -1
  296. package/dist/chunk-CJGFRPAS.cjs.map +0 -1
  297. package/dist/chunk-CUJBNRJJ.cjs +0 -38
  298. package/dist/chunk-CUJBNRJJ.cjs.map +0 -1
  299. package/dist/chunk-E6SE552P.cjs.map +0 -1
  300. package/dist/chunk-E7FGY7BJ.js.map +0 -1
  301. package/dist/chunk-EAJHEYZM.js +0 -38
  302. package/dist/chunk-EAJHEYZM.js.map +0 -1
  303. package/dist/chunk-FKXKBJUI.cjs.map +0 -1
  304. package/dist/chunk-FXZJL2AM.cjs.map +0 -1
  305. package/dist/chunk-GG5YGESX.js.map +0 -1
  306. package/dist/chunk-GPRJYPIG.js.map +0 -1
  307. package/dist/chunk-H6CWTMAH.js.map +0 -1
  308. package/dist/chunk-HALVTKW7.js.map +0 -1
  309. package/dist/chunk-I5XR2V4A.cjs.map +0 -1
  310. package/dist/chunk-IJ4DXG7D.cjs.map +0 -1
  311. package/dist/chunk-ITXDSQT2.js.map +0 -1
  312. package/dist/chunk-J5RMLZ4P.cjs.map +0 -1
  313. package/dist/chunk-JRLUZDKA.js.map +0 -1
  314. package/dist/chunk-K7T25Y3A.cjs.map +0 -1
  315. package/dist/chunk-L5Q6UDY3.js +0 -69
  316. package/dist/chunk-L5Q6UDY3.js.map +0 -1
  317. package/dist/chunk-M7PF4FKQ.js.map +0 -1
  318. package/dist/chunk-MCWTQT3M.cjs.map +0 -1
  319. package/dist/chunk-MHZIBV2C.js.map +0 -1
  320. package/dist/chunk-NEYLNRVG.cjs.map +0 -1
  321. package/dist/chunk-O3LG7B2J.cjs.map +0 -1
  322. package/dist/chunk-OAK7HFOJ.js.map +0 -1
  323. package/dist/chunk-OAPOGYA5.cjs.map +0 -1
  324. package/dist/chunk-OGC44JFZ.cjs.map +0 -1
  325. package/dist/chunk-OJDYTCMO.cjs.map +0 -1
  326. package/dist/chunk-P2JM22BF.cjs.map +0 -1
  327. package/dist/chunk-PY2376XI.js.map +0 -1
  328. package/dist/chunk-Q5KQVBQP.cjs.map +0 -1
  329. package/dist/chunk-QQIALSTX.cjs.map +0 -1
  330. package/dist/chunk-R4M6SNUU.cjs.map +0 -1
  331. package/dist/chunk-RYOQYYDO.js.map +0 -1
  332. package/dist/chunk-S4S4LB63.js.map +0 -1
  333. package/dist/chunk-SXGCRHBZ.js.map +0 -1
  334. package/dist/chunk-T2KB3DJJ.js.map +0 -1
  335. package/dist/chunk-TEVZHN5I.cjs.map +0 -1
  336. package/dist/chunk-TQGO5WK6.js.map +0 -1
  337. package/dist/chunk-VXO2MYYH.cjs +0 -125
  338. package/dist/chunk-VXO2MYYH.cjs.map +0 -1
  339. package/dist/chunk-WWYJNWJY.cjs +0 -69
  340. package/dist/chunk-WWYJNWJY.cjs.map +0 -1
  341. package/dist/chunk-YV57RSPD.js.map +0 -1
  342. package/dist/chunk-Z5U4NJTW.cjs.map +0 -1
  343. package/dist/chunk-ZNWIHUHZ.cjs.map +0 -1
  344. package/dist/chunk-ZWAFL2B3.cjs.map +0 -1
  345. package/dist/chunk-ZXJU3TQD.cjs.map +0 -1
  346. /package/dist/{chunk-GDQWSCJQ.js.map → chunk-26SO4LZ5.js.map} +0 -0
  347. /package/dist/{chunk-KQJ3IAFT.js.map → chunk-A3LMUPG3.js.map} +0 -0
  348. /package/dist/{chunk-O2AACVSF.js.map → chunk-AR2ZOO6L.js.map} +0 -0
  349. /package/dist/{chunk-L23WWO3D.js.map → chunk-GPVGGBIR.js.map} +0 -0
  350. /package/dist/{chunk-2QEKSRVX.js.map → chunk-HEX4IMLO.js.map} +0 -0
  351. /package/dist/{chunk-OU7DCYIA.js.map → chunk-O3QM3BFE.js.map} +0 -0
  352. /package/dist/{chunk-WKDT2XFQ.js.map → chunk-OOCCSMWM.js.map} +0 -0
  353. /package/dist/{chunk-L5W2XC6M.js.map → chunk-RHFD2Z5V.js.map} +0 -0
  354. /package/dist/{chunk-VPRUHE35.js.map → chunk-SFFKQQ5Z.js.map} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CommandPalette
3
- } from "./chunk-PY2376XI.js";
3
+ } from "./chunk-JT4KVXJK.js";
4
4
  import {
5
5
  Menu
6
- } from "./chunk-BNVQ34FD.js";
6
+ } from "./chunk-P4XZH3OR.js";
7
7
  import {
8
8
  Avatar
9
9
  } from "./chunk-XJBWFDDE.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-DRXPTACG.js";
13
13
  import {
14
14
  IconButton
15
- } from "./chunk-L5Q6UDY3.js";
15
+ } from "./chunk-75GFIQRU.js";
16
16
 
17
17
  // src/components/Toolbar/Toolbar.component.tsx
18
18
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -42,4 +42,4 @@ var Toolbar = ({
42
42
  export {
43
43
  Toolbar
44
44
  };
45
- //# sourceMappingURL=chunk-VPRUHE35.js.map
45
+ //# sourceMappingURL=chunk-SFFKQQ5Z.js.map
@@ -81,24 +81,34 @@ var RadioGroup = ({
81
81
  onChange?.(optionValue);
82
82
  };
83
83
  const groupClasses = ["eidos-radio-group", `eidos-radio-group--${direction}`, className].filter(Boolean).join(" ");
84
+ const errorId = `${name}-error`;
84
85
  return /* @__PURE__ */ jsxs("div", { children: [
85
- /* @__PURE__ */ jsx("div", { className: groupClasses, children: options.map((option) => /* @__PURE__ */ jsx(
86
- Radio,
86
+ /* @__PURE__ */ jsx(
87
+ "div",
87
88
  {
88
- name,
89
- value: option.value,
90
- checked: currentValue === option.value,
91
- onChange: (e) => {
92
- if (e.target.checked) handleOptionChange(option.value);
93
- },
94
- disabled: disabled || option.disabled,
95
- label: option.label,
96
- color,
97
- size
98
- },
99
- option.value
100
- )) }),
101
- error && /* @__PURE__ */ jsxs("div", { className: "eidos-radio-error-message", children: [
89
+ className: groupClasses,
90
+ role: "radiogroup",
91
+ "aria-invalid": error ? true : void 0,
92
+ "aria-describedby": error ? errorId : void 0,
93
+ children: options.map((option) => /* @__PURE__ */ jsx(
94
+ Radio,
95
+ {
96
+ name,
97
+ value: option.value,
98
+ checked: currentValue === option.value,
99
+ onChange: (e) => {
100
+ if (e.target.checked) handleOptionChange(option.value);
101
+ },
102
+ disabled: disabled || option.disabled,
103
+ label: option.label,
104
+ color,
105
+ size
106
+ },
107
+ option.value
108
+ ))
109
+ }
110
+ ),
111
+ error && /* @__PURE__ */ jsxs("div", { id: errorId, className: "eidos-radio-error-message", children: [
102
112
  /* @__PURE__ */ jsx(CircleAlert, {}),
103
113
  /* @__PURE__ */ jsx("span", { children: error })
104
114
  ] })
@@ -110,4 +120,4 @@ export {
110
120
  Radio,
111
121
  RadioGroup
112
122
  };
113
- //# sourceMappingURL=chunk-2RXQMQYW.js.map
123
+ //# sourceMappingURL=chunk-SXL4DMZ7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Radio/Radio.component.tsx"],"sourcesContent":["import React, { forwardRef, useId, useState } from 'react';\nimport { CircleAlert } from 'lucide-react';\nimport type { RadioProps, RadioGroupProps } from './Radio.types';\n\n// ============================================================================\n// Radio\n// ============================================================================\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n label,\n color = 'primary',\n size = 'md',\n className = '',\n disabled = false,\n id,\n checked,\n defaultChecked,\n onChange,\n ...inputProps\n },\n ref,\n ) => {\n const generatedId = useId();\n const radioId = id || `radio-${generatedId}`;\n\n // Track checked state for the visual control:\n // - controlled mode: `checked` prop drives the visual\n // - uncontrolled mode (standalone Radio): local state mirrors the native input\n const isControlled = checked !== undefined;\n const [localChecked, setLocalChecked] = useState<boolean>(defaultChecked ?? false);\n\n // `??` only falls back when `checked` is undefined – `false` is kept as-is\n const isChecked = checked ?? localChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setLocalChecked(e.target.checked);\n }\n onChange?.(e);\n };\n\n const wrapperClasses = [\n 'eidos-radio-wrapper',\n `eidos-radio-wrapper--${color}`,\n `eidos-radio-wrapper--${size}`,\n disabled && 'eidos-radio-wrapper--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const controlClasses = [\n 'eidos-radio-control',\n isChecked && 'eidos-radio-control--checked',\n disabled && 'eidos-radio-control--disabled',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <label className={wrapperClasses}>\n <input\n ref={ref}\n type=\"radio\"\n id={radioId}\n className=\"eidos-radio-input\"\n disabled={disabled}\n onChange={handleChange}\n {...(isControlled ? { checked } : { defaultChecked })}\n {...inputProps}\n />\n <span className={controlClasses}>\n <span className=\"eidos-radio-dot\" />\n </span>\n {label && <span className=\"eidos-radio-label\">{label}</span>}\n </label>\n );\n },\n);\n\nRadio.displayName = 'Radio';\n\n// ============================================================================\n// RadioGroup\n//\n// Design note: RadioGroup always passes a controlled `checked` prop to every\n// Radio child so that the selection dot stays in sync across the full group.\n// For the \"uncontrolled\" case (defaultValue), RadioGroup owns the state\n// internally – individual Radios never need to manage it themselves.\n// ============================================================================\n\nexport const RadioGroup: React.FC<RadioGroupProps> = ({\n name,\n value: valueProp,\n defaultValue,\n onChange,\n options,\n direction = 'vertical',\n color = 'primary',\n size = 'md',\n disabled = false,\n error,\n className = '',\n}) => {\n const isControlled = valueProp !== undefined;\n const [localValue, setLocalValue] = useState<string | undefined>(defaultValue);\n\n // currentValue is always defined when valueProp is provided (controlled)\n const currentValue = isControlled ? valueProp : localValue;\n\n const handleOptionChange = (optionValue: string) => {\n if (!isControlled) {\n setLocalValue(optionValue);\n }\n onChange?.(optionValue);\n };\n\n const groupClasses = ['eidos-radio-group', `eidos-radio-group--${direction}`, className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div>\n <div className={groupClasses}>\n {options.map((option) => (\n <Radio\n key={option.value}\n name={name}\n value={option.value}\n checked={currentValue === option.value}\n onChange={(e) => {\n if (e.target.checked) handleOptionChange(option.value);\n }}\n disabled={disabled || option.disabled}\n label={option.label}\n color={color}\n size={size}\n />\n ))}\n </div>\n\n {error && (\n <div className=\"eidos-radio-error-message\">\n <CircleAlert />\n <span>{error}</span>\n </div>\n )}\n </div>\n );\n};\n\nRadioGroup.displayName = 'RadioGroup';\n"],"mappings":";AAAA,SAAgB,YAAY,OAAO,gBAAgB;AACnD,SAAS,mBAAmB;AA6DtB,SACE,KADF;AAtDC,IAAM,QAAQ;AAAA,EACnB,CACE;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,MAAM;AAC1B,UAAM,UAAU,MAAM,SAAS,WAAW;AAK1C,UAAM,eAAe,YAAY;AACjC,UAAM,CAAC,cAAc,eAAe,IAAI,SAAkB,kBAAkB,KAAK;AAGjF,UAAM,YAAY,WAAW;AAE7B,UAAM,eAAe,CAAC,MAA2C;AAC/D,UAAI,CAAC,cAAc;AACjB,wBAAgB,EAAE,OAAO,OAAO;AAAA,MAClC;AACA,iBAAW,CAAC;AAAA,IACd;AAEA,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA,wBAAwB,KAAK;AAAA,MAC7B,wBAAwB,IAAI;AAAA,MAC5B,YAAY;AAAA,MACZ;AAAA,IACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA,aAAa;AAAA,MACb,YAAY;AAAA,IACd,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,WACE,qBAAC,WAAM,WAAW,gBAChB;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAK;AAAA,UACL,IAAI;AAAA,UACJ,WAAU;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACT,GAAI,eAAe,EAAE,QAAQ,IAAI,EAAE,eAAe;AAAA,UAClD,GAAG;AAAA;AAAA,MACN;AAAA,MACA,oBAAC,UAAK,WAAW,gBACf,8BAAC,UAAK,WAAU,mBAAkB,GACpC;AAAA,MACC,SAAS,oBAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA,OACvD;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;AAWb,IAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EACA,YAAY;AACd,MAAM;AACJ,QAAM,eAAe,cAAc;AACnC,QAAM,CAAC,YAAY,aAAa,IAAI,SAA6B,YAAY;AAG7E,QAAM,eAAe,eAAe,YAAY;AAEhD,QAAM,qBAAqB,CAAC,gBAAwB;AAClD,QAAI,CAAC,cAAc;AACjB,oBAAc,WAAW;AAAA,IAC3B;AACA,eAAW,WAAW;AAAA,EACxB;AAEA,QAAM,eAAe,CAAC,qBAAqB,sBAAsB,SAAS,IAAI,SAAS,EACpF,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,qBAAC,SACC;AAAA,wBAAC,SAAI,WAAW,cACb,kBAAQ,IAAI,CAAC,WACZ;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA,OAAO,OAAO;AAAA,QACd,SAAS,iBAAiB,OAAO;AAAA,QACjC,UAAU,CAAC,MAAM;AACf,cAAI,EAAE,OAAO,QAAS,oBAAmB,OAAO,KAAK;AAAA,QACvD;AAAA,QACA,UAAU,YAAY,OAAO;AAAA,QAC7B,OAAO,OAAO;AAAA,QACd;AAAA,QACA;AAAA;AAAA,MAVK,OAAO;AAAA,IAWd,CACD,GACH;AAAA,IAEC,SACC,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAC,eAAY;AAAA,MACb,oBAAC,UAAM,iBAAM;AAAA,OACf;AAAA,KAEJ;AAEJ;AAEA,WAAW,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/components/Radio/Radio.component.tsx"],"sourcesContent":["import React, { forwardRef, useId, useState } from 'react';\nimport { CircleAlert } from 'lucide-react';\nimport type { RadioProps, RadioGroupProps } from './Radio.types';\n\n// ============================================================================\n// Radio\n// ============================================================================\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n label,\n color = 'primary',\n size = 'md',\n className = '',\n disabled = false,\n id,\n checked,\n defaultChecked,\n onChange,\n ...inputProps\n },\n ref,\n ) => {\n const generatedId = useId();\n const radioId = id || `radio-${generatedId}`;\n\n // Track checked state for the visual control:\n // - controlled mode: `checked` prop drives the visual\n // - uncontrolled mode (standalone Radio): local state mirrors the native input\n const isControlled = checked !== undefined;\n const [localChecked, setLocalChecked] = useState<boolean>(defaultChecked ?? false);\n\n // `??` only falls back when `checked` is undefined – `false` is kept as-is\n const isChecked = checked ?? localChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setLocalChecked(e.target.checked);\n }\n onChange?.(e);\n };\n\n const wrapperClasses = [\n 'eidos-radio-wrapper',\n `eidos-radio-wrapper--${color}`,\n `eidos-radio-wrapper--${size}`,\n disabled && 'eidos-radio-wrapper--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const controlClasses = [\n 'eidos-radio-control',\n isChecked && 'eidos-radio-control--checked',\n disabled && 'eidos-radio-control--disabled',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <label className={wrapperClasses}>\n <input\n ref={ref}\n type=\"radio\"\n id={radioId}\n className=\"eidos-radio-input\"\n disabled={disabled}\n onChange={handleChange}\n {...(isControlled ? { checked } : { defaultChecked })}\n {...inputProps}\n />\n <span className={controlClasses}>\n <span className=\"eidos-radio-dot\" />\n </span>\n {label && <span className=\"eidos-radio-label\">{label}</span>}\n </label>\n );\n },\n);\n\nRadio.displayName = 'Radio';\n\n// ============================================================================\n// RadioGroup\n//\n// Design note: RadioGroup always passes a controlled `checked` prop to every\n// Radio child so that the selection dot stays in sync across the full group.\n// For the \"uncontrolled\" case (defaultValue), RadioGroup owns the state\n// internally – individual Radios never need to manage it themselves.\n// ============================================================================\n\nexport const RadioGroup: React.FC<RadioGroupProps> = ({\n name,\n value: valueProp,\n defaultValue,\n onChange,\n options,\n direction = 'vertical',\n color = 'primary',\n size = 'md',\n disabled = false,\n error,\n className = '',\n}) => {\n const isControlled = valueProp !== undefined;\n const [localValue, setLocalValue] = useState<string | undefined>(defaultValue);\n\n // currentValue is always defined when valueProp is provided (controlled)\n const currentValue = isControlled ? valueProp : localValue;\n\n const handleOptionChange = (optionValue: string) => {\n if (!isControlled) {\n setLocalValue(optionValue);\n }\n onChange?.(optionValue);\n };\n\n const groupClasses = ['eidos-radio-group', `eidos-radio-group--${direction}`, className]\n .filter(Boolean)\n .join(' ');\n\n // Associates the visible error with the group. Without it the message is\n // just a red line of text below the options - obvious to look at, absent\n // from the accessibility tree (SC 3.3.1). See the fuller note in `Input`.\n const errorId = `${name}-error`;\n\n return (\n <div>\n {/* `role=\"radiogroup\"` so the options are announced as one choice\n rather than a run of unrelated radios - and so there is something\n for the error to attach to. The error belongs to the group, not to\n any single option. */}\n <div\n className={groupClasses}\n role=\"radiogroup\"\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? errorId : undefined}\n >\n {options.map((option) => (\n <Radio\n key={option.value}\n name={name}\n value={option.value}\n checked={currentValue === option.value}\n onChange={(e) => {\n if (e.target.checked) handleOptionChange(option.value);\n }}\n disabled={disabled || option.disabled}\n label={option.label}\n color={color}\n size={size}\n />\n ))}\n </div>\n\n {error && (\n <div id={errorId} className=\"eidos-radio-error-message\">\n <CircleAlert />\n <span>{error}</span>\n </div>\n )}\n </div>\n );\n};\n\nRadioGroup.displayName = 'RadioGroup';\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkCUJBNRJJcjs = require('./chunk-CUJBNRJJ.cjs');
3
+ var _chunk35LGEPLPcjs = require('./chunk-35LGEPLP.cjs');
4
4
 
5
5
  // src/components/NumberInput/NumberInput.component.tsx
6
6
  var _react = require('react');
@@ -31,6 +31,7 @@ var NumberInput = _react.forwardRef.call(void 0,
31
31
  }, ref) => {
32
32
  const generatedId = _react.useId.call(void 0, );
33
33
  const inputId = id || `number-input-${generatedId}`;
34
+ const errorId = `${inputId}-error`;
34
35
  const isControlled = value !== void 0;
35
36
  const [localValue, setLocalValue] = _react.useState.call(void 0, defaultValue);
36
37
  const [inputText, setInputText] = _react.useState.call(void 0, defaultValue.toFixed(precision));
@@ -99,7 +100,7 @@ var NumberInput = _react.forwardRef.call(void 0,
99
100
  const rootClasses = [
100
101
  "eidos-number-input",
101
102
  `eidos-number-input--${size}`,
102
- fullWidth && _chunkCUJBNRJJcjs.fullWidthModifier.call(void 0, "eidos-number-input"),
103
+ fullWidth && _chunk35LGEPLPcjs.fullWidthModifier.call(void 0, "eidos-number-input"),
103
104
  error && "eidos-number-input--error",
104
105
  className
105
106
  ].filter(Boolean).join(" ");
@@ -150,6 +151,8 @@ var NumberInput = _react.forwardRef.call(void 0,
150
151
  readOnly,
151
152
  inputMode: "decimal",
152
153
  role: "spinbutton",
154
+ "aria-invalid": error ? true : void 0,
155
+ "aria-describedby": error && errorMessage ? errorId : void 0,
153
156
  "aria-valuemin": min,
154
157
  "aria-valuemax": max,
155
158
  "aria-valuenow": currentValue,
@@ -191,7 +194,7 @@ var NumberInput = _react.forwardRef.call(void 0,
191
194
  }
192
195
  ),
193
196
  helperText && !error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-number-input-helper", children: helperText }),
194
- error && errorMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-number-input-error", role: "alert", children: errorMessage })
197
+ error && errorMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: errorId, className: "eidos-number-input-error", role: "alert", children: errorMessage })
195
198
  ] });
196
199
  }
197
200
  );
@@ -200,4 +203,4 @@ NumberInput.displayName = "NumberInput";
200
203
 
201
204
 
202
205
  exports.NumberInput = NumberInput;
203
- //# sourceMappingURL=chunk-OAPOGYA5.cjs.map
206
+ //# sourceMappingURL=chunk-TC5IC6OP.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-TC5IC6OP.cjs","../src/components/NumberInput/NumberInput.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACA;ACJA,8BAA8D;AAC9D,2CAA4B;AAuJlB,+CAAA;AAnJH,IAAM,YAAA,EAAc,+BAAA;AAAA,EACzB,CACE;AAAA,IACE,KAAA;AAAA,IACA,aAAA,EAAe,CAAA;AAAA,IACf,QAAA;AAAA,IACA,GAAA;AAAA,IACA,GAAA;AAAA,IACA,KAAA,EAAO,CAAA;AAAA,IACP,UAAA,EAAY,CAAA;AAAA,IACZ,WAAA;AAAA,IACA,SAAA,EAAW,KAAA;AAAA,IACX,SAAA,EAAW,KAAA;AAAA,IACX,KAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA,EAAQ,KAAA;AAAA,IACR,YAAA;AAAA,IACA,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY,KAAA;AAAA,IACZ,YAAA,EAAc,IAAA;AAAA,IACd,UAAA,EAAY,EAAA;AAAA,IACZ,EAAA;AAAA,IACA;AAAA,EACF,CAAA,EACA,GAAA,EAAA,GACG;AACH,IAAA,MAAM,YAAA,EAAc,0BAAA,CAAM;AAC1B,IAAA,MAAM,QAAA,EAAU,GAAA,GAAM,CAAA,aAAA,EAAgB,WAAW,CAAA,CAAA;AAKvB,IAAA;AAGK,IAAA;AACsB,IAAA;AAGF,IAAA;AACH,IAAA;AAEH,IAAA;AAI7B,IAAA;AACI,MAAA;AACM,MAAA;AACT,QAAA;AACiC,QAAA;AACA,QAAA;AACH,QAAA;AAC5C,MAAA;AACmC,IAAA;AAGM,IAAA;AAC7B,MAAA;AACiC,MAAA;AACA,MAAA;AACH,MAAA;AAC7C,IAAA;AAEwC,IAAA;AACL,MAAA;AACO,MAAA;AACtB,sBAAA;AACpB,IAAA;AAG8B,IAAA;AACF,MAAA;AACK,MAAA;AACjC,IAAA;AAE8B,IAAA;AACF,MAAA;AACK,MAAA;AACjC,IAAA;AAG8B,IAAA;AACgB,MAAA;AAC3B,MAAA;AACnB,IAAA;AAEqE,IAAA;AACxC,MAAA;AAC7B,IAAA;AAE6B,IAAA;AACT,MAAA;AACiB,MAAA;AACf,MAAA;AACe,QAAA;AACO,QAAA;AACtB,wBAAA;AACqB,QAAA;AAClC,MAAA;AAEuC,QAAA;AAC9C,MAAA;AACF,IAAA;AAGyD,IAAA;AAC9B,MAAA;AACN,QAAA;AACD,QAAA;AACgB,MAAA;AACf,QAAA;AACD,QAAA;AAClB,MAAA;AACF,IAAA;AAK4C,IAAA;AACK,IAAA;AAGT,IAAA;AACA,IAAA;AAGpB,IAAA;AAClB,MAAA;AAC2B,MAAA;AACI,MAAA;AACtB,MAAA;AACT,MAAA;AAGS,IAAA;AAEY,IAAA;AACrB,MAAA;AACY,MAAA;AAGH,IAAA;AAGO,IAAA;AAEL,MAAA;AAKT,sBAAA;AAAC,QAAA;AAAA,QAAA;AACY,UAAA;AACqB,UAAA;AACS,UAAA;AACA,UAAA;AACA,UAAA;AACF,UAAA;AACZ,UAAA;AACe,UAAA;AAChB,UAAA;AAE1B,UAAA;AAAA,4BAAA;AAAC,cAAA;AAAA,cAAA;AACM,gBAAA;AACK,gBAAA;AACD,gBAAA;AACC,gBAAA;AACC,gBAAA;AAEV,gBAAA;AAAM,cAAA;AACT,YAAA;AAEe,4BAAA;AAGb,YAAA;AAAC,cAAA;AAAA,cAAA;AACK,gBAAA;AACC,gBAAA;AACK,gBAAA;AACH,gBAAA;AACG,gBAAA;AACD,gBAAA;AACD,gBAAA;AACG,gBAAA;AACX,gBAAA;AACA,gBAAA;AACA,gBAAA;AACU,gBAAA;AACL,gBAAA;AACwB,gBAAA;AACF,gBAAA;AACZ,gBAAA;AACA,gBAAA;AACA,gBAAA;AACM,gBAAA;AAAA,cAAA;AAGjB,YAAA;AAOO,4BAAA;AAEf,4BAAA;AAAC,cAAA;AAAA,cAAA;AACM,gBAAA;AACK,gBAAA;AACD,gBAAA;AACC,gBAAA;AACC,gBAAA;AAEL,gBAAA;AAAA,cAAA;AACR,YAAA;AAAA,UAAA;AAAA,QAAA;AACF,MAAA;AAGA,sBAAA;AAAC,QAAA;AAAA,QAAA;AACC,UAAA;AACK,UAAA;AACL,UAAA;AACO,UAAA;AACS,UAAA;AAAC,UAAA;AACP,UAAA;AACA,UAAA;AACE,UAAA;AACZ,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AAAA,QAAA;AACF,MAAA;AAE0B,MAAA;AAGvB,MAAA;AAIL,IAAA;AAEJ,EAAA;AACF;AAE0B;ADnD4B;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-TC5IC6OP.cjs","sourcesContent":[null,"import React, { forwardRef, useState, useEffect, useId } from 'react';\nimport { Minus, Plus } from 'lucide-react';\nimport { fullWidthModifier } from '../../utils';\nimport type { NumberInputProps } from './NumberInput.types';\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n value,\n defaultValue = 0,\n onChange,\n min,\n max,\n step = 1,\n precision = 0,\n placeholder,\n disabled = false,\n readOnly = false,\n label,\n helperText,\n error = false,\n errorMessage,\n size = 'md',\n fullWidth = false,\n allowTyping = true,\n className = '',\n id,\n name,\n },\n ref,\n ) => {\n const generatedId = useId();\n const inputId = id || `number-input-${generatedId}`;\n // Associates the visible error with the control. Without it the message\n // is just a red line of text sitting near the field - obvious to look\n // at, absent from the accessibility tree (SC 3.3.1). See the fuller\n // note in `Input`.\n const errorId = `${inputId}-error`;\n\n // Controlled / uncontrolled bridge\n const isControlled = value !== undefined;\n const [localValue, setLocalValue] = useState<number>(defaultValue);\n\n // Intermediate text while the user is actively typing\n const [inputText, setInputText] = useState<string>(defaultValue.toFixed(precision));\n const [isFocused, setIsFocused] = useState(false);\n\n const currentValue = isControlled ? value! : localValue;\n\n // When min/max props change (e.g. via Storybook controls), clamp the\n // uncontrolled localValue so the display never shows an out-of-range value.\n useEffect(() => {\n if (isControlled) return;\n setLocalValue((prev) => {\n let result = prev;\n if (min !== undefined) result = Math.max(min, result);\n if (max !== undefined) result = Math.min(max, result);\n return parseFloat(result.toFixed(precision));\n });\n }, [min, max, precision, isControlled]);\n\n // Clamp to [min, max] and apply precision rounding\n const clampValue = (raw: number): number => {\n let result = raw;\n if (min !== undefined) result = Math.max(min, result);\n if (max !== undefined) result = Math.min(max, result);\n return parseFloat(result.toFixed(precision));\n };\n\n const commitValue = (newVal: number) => {\n const clamped = clampValue(newVal);\n if (!isControlled) setLocalValue(clamped);\n onChange?.(clamped);\n };\n\n // ── Stepper buttons ────────────────────────────────────────────────────\n const handleDecrement = () => {\n if (disabled || readOnly) return;\n commitValue(currentValue - step);\n };\n\n const handleIncrement = () => {\n if (disabled || readOnly) return;\n commitValue(currentValue + step);\n };\n\n // ── Typing mode handlers ───────────────────────────────────────────────\n const handleTextFocus = () => {\n setInputText(currentValue.toFixed(precision));\n setIsFocused(true);\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInputText(e.target.value);\n };\n\n const handleTextBlur = () => {\n setIsFocused(false);\n const parsed = parseFloat(inputText);\n if (!isNaN(parsed)) {\n const clamped = clampValue(parsed);\n if (!isControlled) setLocalValue(clamped);\n onChange?.(clamped);\n setInputText(clamped.toFixed(precision));\n } else {\n // Revert to the last known-good value\n setInputText(currentValue.toFixed(precision));\n }\n };\n\n // ArrowUp / ArrowDown keyboard support for both display modes\n const handleDisplayKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n };\n\n // ── Display value ──────────────────────────────────────────────────────\n // Show intermediate inputText while focused in typing mode;\n // otherwise always derive from the real (controlled/uncontrolled) value.\n const formattedValue = currentValue.toFixed(precision);\n const displayedText = allowTyping && isFocused ? inputText : formattedValue;\n\n // ── Disabled states for buttons ────────────────────────────────────────\n const isDecrementDisabled = disabled || readOnly || (min !== undefined && currentValue <= min);\n const isIncrementDisabled = disabled || readOnly || (max !== undefined && currentValue >= max);\n\n // ── CSS classes ────────────────────────────────────────────────────────\n const rootClasses = [\n 'eidos-number-input',\n `eidos-number-input--${size}`,\n fullWidth && fullWidthModifier('eidos-number-input'),\n error && 'eidos-number-input--error',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const controlClasses = [\n 'eidos-number-input-control',\n disabled && 'eidos-number-input-control--disabled',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={rootClasses}>\n {label && (\n <label htmlFor={allowTyping ? inputId : undefined} className=\"eidos-number-input-label\">\n {label}\n </label>\n )}\n\n <div\n className={controlClasses}\n role={allowTyping ? undefined : 'spinbutton'}\n aria-valuemin={allowTyping ? undefined : min}\n aria-valuemax={allowTyping ? undefined : max}\n aria-valuenow={allowTyping ? undefined : currentValue}\n aria-label={allowTyping ? undefined : (label ?? 'Number input')}\n aria-disabled={disabled || undefined}\n tabIndex={!allowTyping && !disabled ? 0 : undefined}\n onKeyDown={!allowTyping ? handleDisplayKeyDown : undefined}\n >\n <button\n type=\"button\"\n className=\"eidos-number-input-btn\"\n onClick={handleDecrement}\n disabled={isDecrementDisabled}\n aria-label=\"Decrease\"\n >\n <Minus />\n </button>\n\n <div className=\"eidos-number-input-divider\" aria-hidden=\"true\" />\n\n {allowTyping ? (\n <input\n id={inputId}\n type=\"text\"\n className=\"eidos-number-input-display\"\n value={displayedText}\n onChange={handleTextChange}\n onFocus={handleTextFocus}\n onBlur={handleTextBlur}\n onKeyDown={handleDisplayKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n inputMode=\"decimal\"\n role=\"spinbutton\"\n aria-invalid={error ? true : undefined}\n aria-describedby={error && errorMessage ? errorId : undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={currentValue}\n aria-label={label ?? 'Number input'}\n />\n ) : (\n <span className=\"eidos-number-input-display\" aria-hidden=\"true\">\n {placeholder && formattedValue === (0).toFixed(precision) && !isFocused\n ? placeholder\n : formattedValue}\n </span>\n )}\n\n <div className=\"eidos-number-input-divider\" aria-hidden=\"true\" />\n\n <button\n type=\"button\"\n className=\"eidos-number-input-btn\"\n onClick={handleIncrement}\n disabled={isIncrementDisabled}\n aria-label=\"Increase\"\n >\n <Plus />\n </button>\n </div>\n\n {/* Hidden native <input type=\"number\"> for form integration */}\n <input\n ref={ref}\n type=\"number\"\n name={name}\n value={currentValue}\n onChange={() => {}}\n className=\"eidos-number-input-hidden\"\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={disabled}\n readOnly={readOnly}\n min={min}\n max={max}\n step={step}\n />\n\n {helperText && !error && <span className=\"eidos-number-input-helper\">{helperText}</span>}\n\n {error && errorMessage && (\n <span id={errorId} className=\"eidos-number-input-error\" role=\"alert\">\n {errorMessage}\n </span>\n )}\n </div>\n );\n },\n);\n\nNumberInput.displayName = 'NumberInput';\n"]}
@@ -1,9 +1,13 @@
1
1
  import {
2
2
  Button
3
- } from "./chunk-L5Q6UDY3.js";
3
+ } from "./chunk-75GFIQRU.js";
4
+ import {
5
+ useDialogFocus,
6
+ useIsClient
7
+ } from "./chunk-RHHZRTWM.js";
4
8
 
5
9
  // src/components/Drawer/Drawer.component.tsx
6
- import { useEffect, useCallback, useId, useState } from "react";
10
+ import { useEffect, useCallback, useId, useRef, useState } from "react";
7
11
  import { createPortal } from "react-dom";
8
12
  import { X } from "lucide-react";
9
13
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -21,6 +25,8 @@ var Drawer = ({
21
25
  }) => {
22
26
  const titleId = useId();
23
27
  const bodyId = useId();
28
+ const panelRef = useRef(null);
29
+ const isClient = useIsClient();
24
30
  const TRANSITION_MS = 300;
25
31
  const [isMounted, setIsMounted] = useState(isOpen);
26
32
  const [isVisible, setIsVisible] = useState(isOpen);
@@ -69,7 +75,8 @@ var Drawer = ({
69
75
  },
70
76
  [closeOnBackdropClick, onClose]
71
77
  );
72
- if (!isMounted) return null;
78
+ useDialogFocus(isClient && isOpen && isVisible, panelRef);
79
+ if (!isClient || !isMounted) return null;
73
80
  return createPortal(
74
81
  /* @__PURE__ */ jsxs(
75
82
  "div",
@@ -85,6 +92,7 @@ var Drawer = ({
85
92
  /* @__PURE__ */ jsxs(
86
93
  "div",
87
94
  {
95
+ ref: panelRef,
88
96
  role: "dialog",
89
97
  "aria-modal": "true",
90
98
  "aria-labelledby": title ? titleId : void 0,
@@ -135,4 +143,4 @@ Drawer.displayName = "Drawer";
135
143
  export {
136
144
  Drawer
137
145
  };
138
- //# sourceMappingURL=chunk-T2KB3DJJ.js.map
146
+ //# sourceMappingURL=chunk-THCTUBX6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Drawer/Drawer.component.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useId, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { Button } from '../Button';\nimport type { DrawerProps } from './Drawer.types';\nimport { useDialogFocus, useIsClient } from '../../utils';\n\nexport const Drawer: React.FC<DrawerProps> = ({\n isOpen,\n onClose,\n placement = 'right',\n title,\n children,\n actions,\n size = 'md',\n closeOnBackdropClick = true,\n closeOnEscape = true,\n className = '',\n}) => {\n const titleId = useId();\n const bodyId = useId();\n const panelRef = useRef<HTMLDivElement>(null);\n const isClient = useIsClient();\n\n // ── Animation state ────────────────────────────────────────────────────────\n // isMounted: whether the portal DOM node exists at all.\n // isVisible: whether the '--open' CSS class is applied (drives the transition).\n //\n // On open: mount first → one rAF → apply --open (browser sees initial\n // closed position before transitioning, so the animation fires).\n // On close: remove --open (CSS transition plays) → after 300 ms unmount.\n // 300 ms matches the CSS `transition: 0.3s` in Drawer.scss.\n const TRANSITION_MS = 300;\n const [isMounted, setIsMounted] = useState(isOpen);\n const [isVisible, setIsVisible] = useState(isOpen);\n\n useEffect(() => {\n let raf1 = 0;\n let raf2 = 0;\n let timerId: ReturnType<typeof setTimeout>;\n\n if (isOpen) {\n setIsMounted(true);\n // Double rAF: React 18 automatic batching means setIsMounted(true) may\n // not produce a committed browser paint before the first rAF fires.\n // The second frame guarantees the panel is rendered in its off-screen\n // (closed) position before the CSS transition begins.\n raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setIsVisible(true));\n });\n } else {\n setIsVisible(false);\n timerId = setTimeout(() => setIsMounted(false), TRANSITION_MS);\n }\n\n return () => {\n cancelAnimationFrame(raf1);\n cancelAnimationFrame(raf2);\n clearTimeout(timerId);\n };\n }, [isOpen]);\n\n // ── Escape key + scroll lock (tied to isOpen, not isMounted) ───────────────\n const handleEscapeKey = useCallback(\n (event: KeyboardEvent) => {\n if (closeOnEscape && event.key === 'Escape' && isOpen) {\n onClose();\n }\n },\n [closeOnEscape, isOpen, onClose],\n );\n\n useEffect(() => {\n if (isOpen) {\n document.addEventListener('keydown', handleEscapeKey);\n document.body.style.overflow = 'hidden';\n }\n return () => {\n document.removeEventListener('keydown', handleEscapeKey);\n document.body.style.overflow = '';\n };\n }, [isOpen, handleEscapeKey]);\n\n // ── Backdrop click ─────────────────────────────────────────────────────────\n const handleBackdropClick = useCallback(\n (event: React.MouseEvent) => {\n if (closeOnBackdropClick && event.target === event.currentTarget) {\n onClose();\n }\n },\n [closeOnBackdropClick, onClose],\n );\n\n // Keyed to `isVisible` rather than `isOpen` or `isMounted` - see the note\n // on `Modal`. The panel is translated off-screen until `--open` lands two\n // frames after mounting, and focusing something that is off-screen scrolls\n // the page to chase it.\n // `isClient` for the same reason as `Modal`: a drawer that starts open would\n // otherwise run this against a ref whose portal has not rendered yet.\n useDialogFocus(isClient && isOpen && isVisible, panelRef);\n\n // Same reason as `Modal`: `isMounted` starts as `isOpen`, so a drawer that\n // starts open would portal on its first render and throw under SSR.\n if (!isClient || !isMounted) return null;\n\n return createPortal(\n <div\n className={[\n 'eidos-drawer',\n `eidos-drawer--${placement}`,\n isVisible && 'eidos-drawer--open',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {/* Backdrop */}\n <div className=\"eidos-drawer-backdrop\" onClick={handleBackdropClick} aria-hidden=\"true\" />\n\n {/* Panel */}\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={bodyId}\n className={[\n 'eidos-drawer-panel',\n `eidos-drawer-panel--${size}`,\n `eidos-drawer-panel--${placement}`,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {/* Header */}\n <div className=\"eidos-drawer-header\">\n {title && (\n <h3 id={titleId} className=\"eidos-drawer-title\">\n {title}\n </h3>\n )}\n <button\n type=\"button\"\n className=\"eidos-drawer-close\"\n onClick={onClose}\n aria-label=\"Close drawer\"\n >\n <X aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Body */}\n <div id={bodyId} className=\"eidos-drawer-body\">\n {children}\n </div>\n\n {/* Footer - only rendered when actions are provided */}\n {actions && actions.length > 0 && (\n <div className=\"eidos-drawer-footer\">\n {actions.map((action) => (\n <Button\n key={action.id}\n variant={action.variant ?? 'outlined'}\n color={action.color}\n disabled={action.disabled}\n loading={action.loading}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n </div>,\n document.body,\n );\n};\n\nDrawer.displayName = 'Drawer';\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
3
+ var _chunkBEOECPVJcjs = require('./chunk-BEOECPVJ.cjs');
4
4
 
5
5
 
6
- var _chunkCUJBNRJJcjs = require('./chunk-CUJBNRJJ.cjs');
6
+ var _chunk35LGEPLPcjs = require('./chunk-35LGEPLP.cjs');
7
7
 
8
8
  // src/components/Chip/Chip.component.tsx
9
9
  var _lucidereact = require('lucide-react');
@@ -45,26 +45,31 @@ var Chip = ({
45
45
  if (disabled || !onRemove) return;
46
46
  onRemove();
47
47
  };
48
+ const hasBothControls = isClickable && isRemovable;
48
49
  const ChipElement = isClickable && !isRemovable ? "button" : "div";
50
+ const body = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
51
+ preIcon && _chunk35LGEPLPcjs.renderIcon.call(void 0, preIcon, "eidos-chip--pre-icon"),
52
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-chip--copy", children }),
53
+ posIcon && _chunk35LGEPLPcjs.renderIcon.call(void 0, posIcon, "eidos-chip--pos-icon")
54
+ ] });
49
55
  const chipContent = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
50
56
  ChipElement,
51
57
  {
52
58
  className: chipClasses,
53
59
  disabled: ChipElement === "button" ? disabled : void 0,
54
- onClick: isClickable ? handleClick : void 0,
55
- role: ChipElement === "div" && isClickable ? "button" : void 0,
56
- tabIndex: ChipElement === "div" && isClickable ? 0 : void 0,
57
- onKeyDown: ChipElement === "div" && isClickable ? (e) => {
58
- if ((e.key === "Enter" || e.key === " ") && !disabled) {
59
- e.preventDefault();
60
- handleClick();
61
- }
62
- } : void 0,
60
+ onClick: isClickable && !hasBothControls ? handleClick : void 0,
63
61
  ...chipProps,
64
62
  children: [
65
- preIcon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, preIcon, "eidos-chip--pre-icon"),
66
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-chip--copy", children }),
67
- posIcon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, posIcon, "eidos-chip--pos-icon"),
63
+ hasBothControls ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
64
+ "button",
65
+ {
66
+ type: "button",
67
+ className: "eidos-chip--action",
68
+ onClick: handleClick,
69
+ disabled,
70
+ children: body
71
+ }
72
+ ) : body,
68
73
  isRemovable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
69
74
  "button",
70
75
  {
@@ -79,10 +84,10 @@ var Chip = ({
79
84
  ]
80
85
  }
81
86
  );
82
- return tooltip ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZ5U4NJTWcjs.Tooltip, { message: tooltip, children: chipContent }) : chipContent;
87
+ return tooltip ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBEOECPVJcjs.Tooltip, { message: tooltip, children: chipContent }) : chipContent;
83
88
  };
84
89
 
85
90
 
86
91
 
87
92
  exports.Chip = Chip;
88
- //# sourceMappingURL=chunk-NEYLNRVG.cjs.map
93
+ //# sourceMappingURL=chunk-TTLFY76J.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-TTLFY76J.cjs","../src/components/Chip/Chip.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACNA,2CAAkB;AAoEd,+CAAA;AA/DG,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;AAiBwB,EAAA;AACJ,EAAA;AAGlB,EAAA;AACyB,IAAA;AAEtB,oBAAA;AAEsB,IAAA;AACzB,EAAA;AAIA,EAAA;AAAC,IAAA;AAAA,IAAA;AACY,MAAA;AACD,MAAA;AACD,MAAA;AACL,MAAA;AAEH,MAAA;AACC,QAAA;AAAC,UAAA;AAAA,UAAA;AACM,YAAA;AACK,YAAA;AACD,YAAA;AACT,YAAA;AAEC,YAAA;AAAA,UAAA;AAGH,QAAA;AAIA,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;ADzB2B;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-TTLFY76J.cjs","sourcesContent":[null,"import React from 'react';\nimport { X } from 'lucide-react';\nimport type { ChipProps } from './Chip.types';\nimport { Tooltip } from '../Tooltip/Tooltip.component';\nimport { renderIcon } from '../../utils';\n\nexport const Chip: React.FC<ChipProps> = ({\n variant = 'filled',\n color = 'primary',\n size = 'md',\n disabled = false,\n fullWidth = false,\n tooltip,\n className = '',\n preIcon,\n posIcon,\n children,\n onClick,\n onRemove,\n ...chipProps\n}) => {\n const isClickable = !!onClick;\n const isRemovable = !!onRemove;\n\n // Build CSS classes\n const chipClasses = [\n 'eidos-chip',\n `eidos-chip--${variant}`,\n `eidos-chip--${color}`,\n `eidos-chip--${size}`,\n disabled && 'eidos-chip--disabled',\n isClickable && 'eidos-chip--clickable',\n isRemovable && 'eidos-chip--removable',\n fullWidth && 'eidos-chip--full-width',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const handleClick = () => {\n if (disabled || !onClick) return;\n onClick();\n };\n\n const handleRemove = (e: React.MouseEvent) => {\n e.stopPropagation(); // Prevent chip click when removing\n if (disabled || !onRemove) return;\n onRemove();\n };\n\n // A chip that is both clickable and removable holds *two* controls, so it\n // has to render them as siblings.\n //\n // The previous shape switched the outer element to a `<div>` when\n // removable - the comment said \"to avoid nested buttons\" - and then gave\n // that div `role=\"button\"` and `tabIndex={0}`. That is the same defect\n // wearing a different hat: a button containing a button, which is invalid\n // (`nested-interactive`) and leaves a screen reader announcing a control\n // inside a control. It is the same shape already fixed on `Dropdown` and\n // `DataGrid`'s rows.\n //\n // Now the outer element is a plain container whenever there is a remove\n // button, and the chip's own action moves to an inner `<button>` wrapping\n // just the content. Each control is separately reachable and separately\n // named.\n const hasBothControls = isClickable && isRemovable;\n const ChipElement = isClickable && !isRemovable ? 'button' : 'div';\n\n const body = (\n <>\n {preIcon && renderIcon(preIcon, 'eidos-chip--pre-icon')}\n\n <span className=\"eidos-chip--copy\">{children}</span>\n\n {posIcon && renderIcon(posIcon, 'eidos-chip--pos-icon')}\n </>\n );\n\n const chipContent = (\n <ChipElement\n className={chipClasses}\n disabled={ChipElement === 'button' ? disabled : undefined}\n onClick={isClickable && !hasBothControls ? handleClick : undefined}\n {...chipProps}\n >\n {hasBothControls ? (\n <button\n type=\"button\"\n className=\"eidos-chip--action\"\n onClick={handleClick}\n disabled={disabled}\n >\n {body}\n </button>\n ) : (\n body\n )}\n\n {isRemovable && (\n <button\n className=\"eidos-chip--remove-button\"\n onClick={handleRemove}\n disabled={disabled}\n aria-label=\"Remove\"\n type=\"button\"\n >\n <X className=\"eidos-chip--remove-icon\" />\n </button>\n )}\n </ChipElement>\n );\n\n return tooltip ? <Tooltip message={tooltip}>{chipContent}</Tooltip> : chipContent;\n};\n"]}
@@ -144,6 +144,7 @@ var OTPInput = ({
144
144
  {
145
145
  className: "eidos-otp-slots",
146
146
  role: "group",
147
+ "aria-invalid": error ? true : void 0,
147
148
  "aria-labelledby": label ? labelId : void 0,
148
149
  "aria-describedby": describedBy,
149
150
  children: Array.from({ length }, (_v, index) => /* @__PURE__ */ jsx("div", { className: slotClasses(index), children: /* @__PURE__ */ jsx(
@@ -180,4 +181,4 @@ OTPInput.displayName = "OTPInput";
180
181
  export {
181
182
  OTPInput
182
183
  };
183
- //# sourceMappingURL=chunk-ZZSPQFMX.js.map
184
+ //# sourceMappingURL=chunk-U233KQZX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/OTPInput/OTPInput.component.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useId } from 'react';\nimport { CircleAlert } from 'lucide-react';\nimport type { OTPInputProps } from './OTPInput.types';\nimport './OTPInput.scss';\n\nexport const OTPInput: React.FC<OTPInputProps> = ({\n length = 6,\n value,\n defaultValue = '',\n onChange,\n onComplete,\n type = 'numeric',\n mask = false,\n size = 'md',\n disabled = false,\n error,\n label,\n hint,\n autoFocus = false,\n className = '',\n}) => {\n const generatedId = useId();\n const labelId = `otp-label-${generatedId}`;\n const hintId = `otp-hint-${generatedId}`;\n const errorId = `otp-error-${generatedId}`;\n\n const isControlled = value !== undefined;\n\n // Split a string into an array of `length` single characters, padding with ''\n const splitToSlots = (src: string): string[] => Array.from({ length }, (_v, i) => src[i] ?? '');\n\n const [slots, setSlots] = useState<string[]>(() =>\n splitToSlots(isControlled ? (value ?? '') : defaultValue),\n );\n\n // A ref that always mirrors the latest slots value so that event handlers\n // never operate on stale closure state during rapid sequential keystrokes.\n const slotsRef = useRef<string[]>(slots);\n\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n\n // Array of refs - one per slot input\n const inputRefs = useRef<Array<HTMLInputElement | null>>([]);\n\n // Sync internal slots when the controlled `value` prop changes\n useEffect(() => {\n if (isControlled) {\n const synced = splitToSlots(value ?? '');\n slotsRef.current = synced;\n setSlots(synced);\n }\n // splitToSlots is stable within a render; length is in deps\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, length, isControlled]);\n\n // AutoFocus: focus first empty slot on mount\n useEffect(() => {\n if (!autoFocus) return;\n const firstEmptyIdx = slots.findIndex((s) => s === '');\n const targetIdx = firstEmptyIdx === -1 ? 0 : firstEmptyIdx;\n inputRefs.current[targetIdx]?.focus();\n // Intentionally runs only on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Core state update ──────────────────────────────────────────────────────\n\n /**\n * Apply a new slots array, propagate onChange, and fire onComplete if every\n * slot is filled. In controlled mode we do NOT call setSlots - the parent\n * drives state via the `value` prop.\n */\n const commitChange = (newSlots: string[]) => {\n // Keep the ref in sync BEFORE state update so the next synchronous\n // handler (rapid typing) reads the correct value from the ref.\n slotsRef.current = newSlots;\n if (!isControlled) setSlots(newSlots);\n const fullValue = newSlots.join('');\n onChange?.(fullValue);\n if (newSlots.every((s) => s !== '')) {\n onComplete?.(fullValue);\n }\n };\n\n // ── Event handlers ─────────────────────────────────────────────────────────\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n const rawValue = e.target.value;\n // When maxLength=1 is enforced, rawValue is 0–1 chars.\n // When the browser transiently allows 2 chars (typed over existing), we\n // take the last character - that's always the newly entered one.\n const char = rawValue.slice(-1);\n\n if (!char) return; // Deletes are handled by onKeyDown\n\n // Guard: numeric mode rejects non-digit characters\n if (type === 'numeric' && !/^\\d$/.test(char)) return;\n\n // Read from slotsRef (not the stale `slots` closure) so rapid keystrokes\n // don't overwrite each other when React hasn't re-rendered yet.\n const newSlots = [...slotsRef.current];\n newSlots[index] = char;\n commitChange(newSlots);\n\n // Advance focus to the next slot\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => {\n // ── Numeric mode: block non-digit, non-control key presses ──────────────\n if (type === 'numeric') {\n const controlKeys = [\n 'Backspace',\n 'Delete',\n 'Tab',\n 'Escape',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ];\n const isDigit = /^\\d$/.test(e.key);\n const isControlKey = e.ctrlKey || e.metaKey;\n if (!isDigit && !controlKeys.includes(e.key) && !isControlKey) {\n e.preventDefault();\n return;\n }\n }\n\n // ── Backspace ────────────────────────────────────────────────────────────\n if (e.key === 'Backspace') {\n e.preventDefault(); // Prevent the browser from also firing onChange\n if (slotsRef.current[index] !== '') {\n // Clear the current slot\n const newSlots = [...slotsRef.current];\n newSlots[index] = '';\n commitChange(newSlots);\n } else if (index > 0) {\n // Move focus to the previous slot and clear it\n const newSlots = [...slotsRef.current];\n newSlots[index - 1] = '';\n commitChange(newSlots);\n inputRefs.current[index - 1]?.focus();\n }\n return;\n }\n\n // ── Arrow navigation ─────────────────────────────────────────────────────\n if (e.key === 'ArrowLeft' && index > 0) {\n e.preventDefault();\n inputRefs.current[index - 1]?.focus();\n return;\n }\n if (e.key === 'ArrowRight' && index < length - 1) {\n e.preventDefault();\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>, index: number) => {\n e.preventDefault();\n const pasted = e.clipboardData.getData('text/plain');\n // Strip non-digits in numeric mode\n const filtered = type === 'numeric' ? pasted.replace(/\\D/g, '') : pasted;\n if (!filtered) return;\n\n const newSlots = [...slotsRef.current];\n let charsPlaced = 0;\n for (let i = index; i < length && charsPlaced < filtered.length; i++) {\n newSlots[i] = filtered[charsPlaced];\n charsPlaced++;\n }\n commitChange(newSlots);\n\n // Focus the slot after the last pasted character\n const nextFocusIdx = Math.min(index + charsPlaced, length - 1);\n inputRefs.current[nextFocusIdx]?.focus();\n };\n\n // ── CSS class builders ─────────────────────────────────────────────────────\n\n const containerClasses = [\n 'eidos-otp',\n `eidos-otp--${size}`,\n disabled && 'eidos-otp--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const slotClasses = (index: number) =>\n [\n 'eidos-otp-slot',\n // Show \"filled\" accent only when there's no error overriding the colour\n slots[index] !== '' && !error && 'eidos-otp-slot--filled',\n focusedIndex === index && 'eidos-otp-slot--focused',\n error && 'eidos-otp-slot--error',\n disabled && 'eidos-otp-slot--disabled',\n ]\n .filter(Boolean)\n .join(' ');\n\n // Accessible description: prefer error, fall back to hint\n const describedBy = error ? errorId : hint ? hintId : undefined;\n\n return (\n <div className={containerClasses}>\n {label && (\n <label id={labelId} className=\"eidos-otp-label\">\n {label}\n </label>\n )}\n\n <div\n className=\"eidos-otp-slots\"\n role=\"group\"\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={describedBy}\n >\n {Array.from({ length }, (_v, index) => (\n <div key={index} className={slotClasses(index)}>\n <input\n ref={(el) => {\n inputRefs.current[index] = el;\n }}\n type={mask ? 'password' : 'text'}\n inputMode={type === 'numeric' ? 'numeric' : 'text'}\n maxLength={2}\n value={slots[index]}\n disabled={disabled}\n aria-label={`Digit ${index + 1} of ${length}`}\n autoComplete={index === 0 ? 'one-time-code' : 'off'}\n onChange={(e) => handleChange(e, index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onPaste={(e) => handlePaste(e, index)}\n onFocus={() => setFocusedIndex(index)}\n onBlur={() => setFocusedIndex(null)}\n />\n </div>\n ))}\n </div>\n\n {hint && !error && (\n <span id={hintId} className=\"eidos-otp-hint\">\n {hint}\n </span>\n )}\n\n {error && (\n <span id={errorId} className=\"eidos-otp-error-message\" role=\"alert\">\n <CircleAlert aria-hidden=\"true\" />\n {error}\n </span>\n )}\n </div>\n );\n};\n\nOTPInput.displayName = 'OTPInput';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/components/OTPInput/OTPInput.component.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useId } from 'react';\nimport { CircleAlert } from 'lucide-react';\nimport type { OTPInputProps } from './OTPInput.types';\nimport './OTPInput.scss';\n\nexport const OTPInput: React.FC<OTPInputProps> = ({\n length = 6,\n value,\n defaultValue = '',\n onChange,\n onComplete,\n type = 'numeric',\n mask = false,\n size = 'md',\n disabled = false,\n error,\n label,\n hint,\n autoFocus = false,\n className = '',\n}) => {\n const generatedId = useId();\n const labelId = `otp-label-${generatedId}`;\n const hintId = `otp-hint-${generatedId}`;\n const errorId = `otp-error-${generatedId}`;\n\n const isControlled = value !== undefined;\n\n // Split a string into an array of `length` single characters, padding with ''\n const splitToSlots = (src: string): string[] => Array.from({ length }, (_v, i) => src[i] ?? '');\n\n const [slots, setSlots] = useState<string[]>(() =>\n splitToSlots(isControlled ? (value ?? '') : defaultValue),\n );\n\n // A ref that always mirrors the latest slots value so that event handlers\n // never operate on stale closure state during rapid sequential keystrokes.\n const slotsRef = useRef<string[]>(slots);\n\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n\n // Array of refs - one per slot input\n const inputRefs = useRef<Array<HTMLInputElement | null>>([]);\n\n // Sync internal slots when the controlled `value` prop changes\n useEffect(() => {\n if (isControlled) {\n const synced = splitToSlots(value ?? '');\n slotsRef.current = synced;\n setSlots(synced);\n }\n // splitToSlots is stable within a render; length is in deps\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, length, isControlled]);\n\n // AutoFocus: focus first empty slot on mount\n useEffect(() => {\n if (!autoFocus) return;\n const firstEmptyIdx = slots.findIndex((s) => s === '');\n const targetIdx = firstEmptyIdx === -1 ? 0 : firstEmptyIdx;\n inputRefs.current[targetIdx]?.focus();\n // Intentionally runs only on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Core state update ──────────────────────────────────────────────────────\n\n /**\n * Apply a new slots array, propagate onChange, and fire onComplete if every\n * slot is filled. In controlled mode we do NOT call setSlots - the parent\n * drives state via the `value` prop.\n */\n const commitChange = (newSlots: string[]) => {\n // Keep the ref in sync BEFORE state update so the next synchronous\n // handler (rapid typing) reads the correct value from the ref.\n slotsRef.current = newSlots;\n if (!isControlled) setSlots(newSlots);\n const fullValue = newSlots.join('');\n onChange?.(fullValue);\n if (newSlots.every((s) => s !== '')) {\n onComplete?.(fullValue);\n }\n };\n\n // ── Event handlers ─────────────────────────────────────────────────────────\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n const rawValue = e.target.value;\n // When maxLength=1 is enforced, rawValue is 0–1 chars.\n // When the browser transiently allows 2 chars (typed over existing), we\n // take the last character - that's always the newly entered one.\n const char = rawValue.slice(-1);\n\n if (!char) return; // Deletes are handled by onKeyDown\n\n // Guard: numeric mode rejects non-digit characters\n if (type === 'numeric' && !/^\\d$/.test(char)) return;\n\n // Read from slotsRef (not the stale `slots` closure) so rapid keystrokes\n // don't overwrite each other when React hasn't re-rendered yet.\n const newSlots = [...slotsRef.current];\n newSlots[index] = char;\n commitChange(newSlots);\n\n // Advance focus to the next slot\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => {\n // ── Numeric mode: block non-digit, non-control key presses ──────────────\n if (type === 'numeric') {\n const controlKeys = [\n 'Backspace',\n 'Delete',\n 'Tab',\n 'Escape',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ];\n const isDigit = /^\\d$/.test(e.key);\n const isControlKey = e.ctrlKey || e.metaKey;\n if (!isDigit && !controlKeys.includes(e.key) && !isControlKey) {\n e.preventDefault();\n return;\n }\n }\n\n // ── Backspace ────────────────────────────────────────────────────────────\n if (e.key === 'Backspace') {\n e.preventDefault(); // Prevent the browser from also firing onChange\n if (slotsRef.current[index] !== '') {\n // Clear the current slot\n const newSlots = [...slotsRef.current];\n newSlots[index] = '';\n commitChange(newSlots);\n } else if (index > 0) {\n // Move focus to the previous slot and clear it\n const newSlots = [...slotsRef.current];\n newSlots[index - 1] = '';\n commitChange(newSlots);\n inputRefs.current[index - 1]?.focus();\n }\n return;\n }\n\n // ── Arrow navigation ─────────────────────────────────────────────────────\n if (e.key === 'ArrowLeft' && index > 0) {\n e.preventDefault();\n inputRefs.current[index - 1]?.focus();\n return;\n }\n if (e.key === 'ArrowRight' && index < length - 1) {\n e.preventDefault();\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>, index: number) => {\n e.preventDefault();\n const pasted = e.clipboardData.getData('text/plain');\n // Strip non-digits in numeric mode\n const filtered = type === 'numeric' ? pasted.replace(/\\D/g, '') : pasted;\n if (!filtered) return;\n\n const newSlots = [...slotsRef.current];\n let charsPlaced = 0;\n for (let i = index; i < length && charsPlaced < filtered.length; i++) {\n newSlots[i] = filtered[charsPlaced];\n charsPlaced++;\n }\n commitChange(newSlots);\n\n // Focus the slot after the last pasted character\n const nextFocusIdx = Math.min(index + charsPlaced, length - 1);\n inputRefs.current[nextFocusIdx]?.focus();\n };\n\n // ── CSS class builders ─────────────────────────────────────────────────────\n\n const containerClasses = [\n 'eidos-otp',\n `eidos-otp--${size}`,\n disabled && 'eidos-otp--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const slotClasses = (index: number) =>\n [\n 'eidos-otp-slot',\n // Show \"filled\" accent only when there's no error overriding the colour\n slots[index] !== '' && !error && 'eidos-otp-slot--filled',\n focusedIndex === index && 'eidos-otp-slot--focused',\n error && 'eidos-otp-slot--error',\n disabled && 'eidos-otp-slot--disabled',\n ]\n .filter(Boolean)\n .join(' ');\n\n // Accessible description: prefer error, fall back to hint\n const describedBy = error ? errorId : hint ? hintId : undefined;\n\n return (\n <div className={containerClasses}>\n {label && (\n <label id={labelId} className=\"eidos-otp-label\">\n {label}\n </label>\n )}\n\n <div\n className=\"eidos-otp-slots\"\n role=\"group\"\n aria-invalid={error ? true : undefined}\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={describedBy}\n >\n {Array.from({ length }, (_v, index) => (\n <div key={index} className={slotClasses(index)}>\n <input\n ref={(el) => {\n inputRefs.current[index] = el;\n }}\n type={mask ? 'password' : 'text'}\n inputMode={type === 'numeric' ? 'numeric' : 'text'}\n maxLength={2}\n value={slots[index]}\n disabled={disabled}\n aria-label={`Digit ${index + 1} of ${length}`}\n autoComplete={index === 0 ? 'one-time-code' : 'off'}\n onChange={(e) => handleChange(e, index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onPaste={(e) => handlePaste(e, index)}\n onFocus={() => setFocusedIndex(index)}\n onBlur={() => setFocusedIndex(null)}\n />\n </div>\n ))}\n </div>\n\n {hint && !error && (\n <span id={hintId} className=\"eidos-otp-hint\">\n {hint}\n </span>\n )}\n\n {error && (\n <span id={errorId} className=\"eidos-otp-error-message\" role=\"alert\">\n <CircleAlert aria-hidden=\"true\" />\n {error}\n </span>\n )}\n </div>\n );\n};\n\nOTPInput.displayName = 'OTPInput';\n"],"mappings":"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","names":[]}
@@ -3,13 +3,13 @@
3
3
  var _chunkQ3GNKF74cjs = require('./chunk-Q3GNKF74.cjs');
4
4
 
5
5
 
6
- var _chunkWWYJNWJYcjs = require('./chunk-WWYJNWJY.cjs');
6
+ var _chunkDA375AI6cjs = require('./chunk-DA375AI6.cjs');
7
7
 
8
8
 
9
- var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
9
+ var _chunkBEOECPVJcjs = require('./chunk-BEOECPVJ.cjs');
10
10
 
11
11
 
12
- var _chunkCUJBNRJJcjs = require('./chunk-CUJBNRJJ.cjs');
12
+ var _chunk35LGEPLPcjs = require('./chunk-35LGEPLP.cjs');
13
13
 
14
14
  // src/components/Navigation/Navigation.component.tsx
15
15
  var _react = require('react');
@@ -88,7 +88,7 @@ var Navigation = ({
88
88
  ] })
89
89
  }
90
90
  ),
91
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-navigation__items", children: items.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-navigation__item-wrapper", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZ5U4NJTWcjs.Tooltip, { message: item.label, placement: "right", disabled: !collapsed, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
91
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-navigation__items", children: items.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-navigation__item-wrapper", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBEOECPVJcjs.Tooltip, { message: item.label, placement: "right", disabled: !collapsed, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
92
92
  "button",
93
93
  {
94
94
  type: "button",
@@ -101,14 +101,14 @@ var Navigation = ({
101
101
  "aria-current": item.active ? "page" : void 0,
102
102
  "aria-label": collapsed ? item.label : void 0,
103
103
  children: [
104
- item.icon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, item.icon, "eidos-navigation__item-icon"),
104
+ item.icon && _chunk35LGEPLPcjs.renderIcon.call(void 0, item.icon, "eidos-navigation__item-icon"),
105
105
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-navigation__item-label", "aria-hidden": collapsed || void 0, children: item.label })
106
106
  ]
107
107
  }
108
108
  ) }) }, item.id)) }),
109
109
  footer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-navigation__footer", children: footer }),
110
110
  collapsible && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-navigation__toggle", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
111
- _chunkWWYJNWJYcjs.IconButton,
111
+ _chunkDA375AI6cjs.IconButton,
112
112
  {
113
113
  icon: collapsed ? _lucidereact.SquareChevronRight : _lucidereact.SquareChevronLeft,
114
114
  variant: "text",
@@ -126,4 +126,4 @@ Navigation.displayName = "Navigation";
126
126
 
127
127
 
128
128
  exports.Navigation = Navigation;
129
- //# sourceMappingURL=chunk-65PC3YDT.cjs.map
129
+ //# sourceMappingURL=chunk-V4BZWBZT.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-65PC3YDT.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-65PC3YDT.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { SquareChevronLeft, SquareChevronRight } from 'lucide-react';\nimport type { NavigationLogo, NavigationProps } from './Navigation.types';\nimport { Avatar } from '../Avatar';\nimport { IconButton } from '../Button';\nimport { Tooltip } from '../Tooltip';\nimport { renderIcon } from '../../utils';\nimport './Navigation.scss';\n\n/**\n * Renders a custom brand logo, guaranteeing correct aspect-ratio rendering\n * regardless of whether the source image is vertical, horizontal, or square\n * - and regardless of how much width is actually available, expanded or\n * collapsed. Deliberately no JS sizing/measurement at all: a fixed `height`,\n * `width: auto` (derived from the image's own intrinsic ratio), a `max-width`\n * expressed as `min(72px, 100%)` (see `.eidos-navigation__brand-logo` in\n * Navigation.scss) so it never renders wider than whatever space its\n * container - the rail, expanded or collapsed - actually has, and\n * `object-fit: contain` so it's letterboxed rather than distorted if that\n * ever clamps it below its natural width-at-32px-tall. Centering is handled\n * separately, at the row level - see `&__brand--logo-only` in Navigation.scss.\n */\nconst NavigationBrandLogo: React.FC<{ logo: NavigationLogo }> = ({ logo }) => (\n <img src={logo.src} alt={logo.alt} className=\"eidos-navigation__brand-logo\" />\n);\n\nexport const Navigation: React.FC<NavigationProps> = ({\n brand,\n items,\n footer,\n collapsed: collapsedProp,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseBelow = 768,\n collapsible = true,\n className = '',\n}) => {\n // ── Controlled / uncontrolled collapsed state ─────────────────────────────\n // Mirrors CommandPalette's `open`/`defaultOpen` pattern - omitting\n // `collapsed` lets Navigation own its state entirely, while passing it\n // (+ `onCollapsedChange`) keeps full external control for consumers who\n // need to persist the preference or drive it from a responsive breakpoint.\n const isControlled = collapsedProp !== undefined;\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = isControlled ? collapsedProp : internalCollapsed;\n\n // Shared by the manual toggle button and `collapseBelow` below - uncontrolled\n // flips the internal state directly, controlled defers to `onCollapsedChange`\n // since Navigation can't change `collapsed` itself.\n const applyCollapsed = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n },\n [isControlled, onCollapsedChange],\n );\n\n const toggleCollapsed = useCallback(() => {\n applyCollapsed(!collapsed);\n }, [applyCollapsed, collapsed]);\n\n // Read by the breakpoint effect below so it does not depend on\n // `applyCollapsed`'s identity. A consumer passing an inline\n // `onCollapsedChange` gives that callback a new identity every render,\n // which would re-run the effect - and re-apply the media query's answer -\n // on every render, overriding any manual toggle made in between crossings.\n // That is the one thing `collapseBelow` is documented not to do.\n const applyCollapsedRef = useRef(applyCollapsed);\n useEffect(() => {\n applyCollapsedRef.current = applyCollapsed;\n });\n\n // Auto-collapse/expand at a viewport breakpoint. `matchMedia`'s `change`\n // event only fires exactly at the crossing point, not on every resize\n // tick, so a manual toggle in between crossings is left alone until the\n // viewport actually crosses the breakpoint again.\n useEffect(() => {\n // `0` opts out, as documented - and it has to be checked here rather\n // than relying on `(max-width: 0px)` never matching, because the mount\n // pass below would otherwise still run.\n if (!collapseBelow) return;\n if (typeof window === 'undefined' || !window.matchMedia) return;\n\n const query = window.matchMedia(`(max-width: ${collapseBelow}px)`);\n\n // On mount this may only *collapse*, never expand. `defaultCollapsed`\n // (or a controlled `collapsed`) is the consumer's stated starting point,\n // and applying `query.matches` unconditionally threw it away one commit\n // after the first paint: on any viewport wider than the breakpoint the\n // rail visibly started collapsed and then sprang open. Crossings below\n // still drive both directions, which is what \"collapses and re-expands\"\n // refers to.\n if (query.matches) applyCollapsedRef.current(true);\n\n const handleChange = (event: MediaQueryListEvent) => applyCollapsedRef.current(event.matches);\n query.addEventListener('change', handleChange);\n return () => query.removeEventListener('change', handleChange);\n }, [collapseBelow]);\n\n const classes = ['eidos-navigation', collapsed && 'eidos-navigation--collapsed', className]\n .filter(Boolean)\n .join(' ');\n\n // A `logo` brand has no `name` text alongside it (see the discriminated\n // union in Navigation.types.ts), so there's never a second, variable-width\n // sibling competing for space - unlike the `name` variant, it's always\n // safe to just center it outright, in both expanded and collapsed states,\n // with nothing further to compute. See `&__brand--logo-only` in\n // Navigation.scss.\n const brandClasses = [\n 'eidos-navigation__brand',\n brand.logo && 'eidos-navigation__brand--logo-only',\n brand.onClick && 'eidos-navigation__brand--clickable',\n ]\n .filter(Boolean)\n .join(' ');\n\n const brandAccessibleName = brand.logo ? brand.logo.alt : brand.name;\n\n return (\n <nav className={classes} aria-label=\"Main\">\n <div\n className={brandClasses}\n onClick={brand.onClick}\n role={brand.onClick ? 'button' : undefined}\n tabIndex={brand.onClick ? 0 : undefined}\n // Only a real interactive control (role=\"button\") reliably exposes\n // `aria-label` as its accessible name - a plain, non-interactive div\n // doesn't, so the visible (if currently faded) text remains the only\n // way assistive tech gets the brand name in that case.\n aria-label={brand.onClick ? brandAccessibleName : undefined}\n onKeyDown={\n brand.onClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n brand.onClick?.();\n }\n }\n : undefined\n }\n >\n {brand.logo ? (\n <NavigationBrandLogo logo={brand.logo} />\n ) : (\n <>\n <Avatar name={brand.name} shape=\"square\" size=\"sm\" />\n {/* Only redundant with the wrapper's own `aria-label` when\n `brand.onClick` is set (see the note on it above) - otherwise\n this is the only accessible text for the brand at all. */}\n <span\n className=\"eidos-navigation__brand-name\"\n aria-hidden={brand.onClick ? true : undefined}\n >\n {brand.name}\n </span>\n </>\n )}\n </div>\n\n <ul className=\"eidos-navigation__items\">\n {items.map((item) => (\n <li key={item.id} className=\"eidos-navigation__item-wrapper\">\n {/* Always wrapped (disabled rather than omitted while expanded)\n so the button underneath is never unmounted/remounted across\n a collapse toggle - that would otherwise reset its own CSS\n transitions (gap, padding, justify-content) partway through\n the rail's width animation, snapping instead of easing. */}\n <Tooltip message={item.label} placement=\"right\" disabled={!collapsed}>\n <button\n type=\"button\"\n className={[\n 'eidos-navigation__item',\n item.active && 'eidos-navigation__item--active',\n ]\n .filter(Boolean)\n .join(' ')}\n disabled={item.disabled}\n onClick={item.onClick}\n aria-current={item.active ? 'page' : undefined}\n // The label fades out visually while collapsed (see\n // `.eidos-navigation__item-label` in Navigation.scss) but\n // isn't removed from the DOM, so it's given directly as the\n // accessible name here instead of relying on the (also\n // fading) visible text, and hidden from assistive tech below\n // to avoid it being announced twice alongside the `Tooltip`.\n aria-label={collapsed ? item.label : undefined}\n >\n {item.icon && renderIcon(item.icon, 'eidos-navigation__item-icon')}\n <span className=\"eidos-navigation__item-label\" aria-hidden={collapsed || undefined}>\n {item.label}\n </span>\n </button>\n </Tooltip>\n </li>\n ))}\n </ul>\n\n {footer && <div className=\"eidos-navigation__footer\">{footer}</div>}\n\n {/* Floats half in/half out of the rail's right edge (see `&__toggle`\n in Navigation.scss) rather than sitting in its own row - a\n dedicated row reserved space in the flex column even when there\n were too few items to need it.\n\n The positioning has to live on this wrapping `<span>`, not on the\n `IconButton` itself: its `tooltip` prop makes `Button` wrap it in\n `Tooltip`'s own `.eidos-tooltip-trigger` div, which - not the\n button - is the actual flex child of `.eidos-navigation`. Removing\n only the inner button from flow left that outer wrapper still\n in-flow, still consuming space and still getting `gap` applied\n around it, which is exactly why a gap remained. */}\n {collapsible && (\n <span className=\"eidos-navigation__toggle\">\n <IconButton\n icon={collapsed ? SquareChevronRight : SquareChevronLeft}\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n tooltip={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n onClick={toggleCollapsed}\n />\n </span>\n )}\n </nav>\n );\n};\n\nNavigation.displayName = 'Navigation';\n"]}
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-V4BZWBZT.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACbA,8BAAgE;AAChE,2CAAsD;AAsBpD,+CAAA;AADF,IAAM,oBAAA,EAA0D,CAAC,EAAE,KAAK,CAAA,EAAA,mBACtE,6BAAA,KAAC,EAAA,EAAI,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,SAAA,EAAU,+BAAA,CAA+B,CAAA;AAGvE,IAAM,WAAA,EAAwC,CAAC;AAAA,EACpD,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,EAAW,aAAA;AAAA,EACX,iBAAA,EAAmB,KAAA;AAAA,EACnB,iBAAA;AAAA,EACA,cAAA,EAAgB,GAAA;AAAA,EAChB,YAAA,EAAc,IAAA;AAAA,EACd,UAAA,EAAY;AACd,CAAA,EAAA,GAAM;AAMJ,EAAA,MAAM,aAAA,EAAe,cAAA,IAAkB,KAAA,CAAA;AACvC,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,EAAA,EAAI,6BAAA,gBAAyB,CAAA;AAC3E,EAAA,MAAM,UAAA,EAAY,aAAA,EAAe,cAAA,EAAgB,iBAAA;AAKjD,EAAA,MAAM,eAAA,EAAiB,gCAAA;AAAA,IACrB,CAAC,IAAA,EAAA,GAAkB;AACjB,MAAA,GAAA,CAAI,CAAC,YAAA,EAAc,oBAAA,CAAqB,IAAI,CAAA;AAC5C,sBAAA,iBAAA,wBAAA,CAAoB,IAAI,GAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,YAAA,EAAc,iBAAiB;AAAA,EAClC,CAAA;AAEA,EAAA,MAAM,gBAAA,EAAkB,gCAAA,CAAY,EAAA,GAAM;AACxC,IAAA,cAAA,CAAe,CAAC,SAAS,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,cAAA,EAAgB,SAAS,CAAC,CAAA;AAQ9B,EAAA,MAAM,kBAAA,EAAoB,2BAAA,cAAqB,CAAA;AAC/C,EAAA,8BAAA,CAAU,EAAA,GAAM;AACd,IAAA,iBAAA,CAAkB,QAAA,EAAU,cAAA;AAAA,EAC9B,CAAC,CAAA;AAMD,EAAA,8BAAA,CAAU,EAAA,GAAM;AAId,IAAA,GAAA,CAAI,CAAC,aAAA,EAAe,MAAA;AACpB,IAAA,GAAA,CAAI,OAAO,OAAA,IAAW,YAAA,GAAe,CAAC,MAAA,CAAO,UAAA,EAAY,MAAA;AAEzD,IAAA,MAAM,MAAA,EAAQ,MAAA,CAAO,UAAA,CAAW,CAAA,YAAA,EAAe,aAAa,CAAA,GAAA,CAAK,CAAA;AASjE,IAAA,GAAA,CAAI,KAAA,CAAM,OAAA,EAAS,iBAAA,CAAkB,OAAA,CAAQ,IAAI,CAAA;AAEjD,IAAA,MAAM,aAAA,EAAe,CAAC,KAAA,EAAA,GAA+B,iBAAA,CAAkB,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AAC5F,IAAA,KAAA,CAAM,gBAAA,CAAiB,QAAA,EAAU,YAAY,CAAA;AAC7C,IAAA,OAAO,CAAA,EAAA,GAAM,KAAA,CAAM,mBAAA,CAAoB,QAAA,EAAU,YAAY,CAAA;AAAA,EAC/D,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,MAAM,QAAA,EAAU,CAAC,kBAAA,EAAoB,UAAA,GAAa,6BAAA,EAA+B,SAAS,CAAA,CACvF,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AAQX,EAAA,MAAM,aAAA,EAAe;AAAA,IACnB,yBAAA;AAAA,IACA,KAAA,CAAM,KAAA,GAAQ,oCAAA;AAAA,IACd,KAAA,CAAM,QAAA,GAAW;AAAA,EACnB,CAAA,CACG,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AAEX,EAAA,MAAM,oBAAA,EAAsB,KAAA,CAAM,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,IAAA;AAEhE,EAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,OAAA,EAAS,YAAA,EAAW,MAAA,EAClC,QAAA,EAAA;AAAA,oBAAA,6BAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,YAAA;AAAA,QACX,OAAA,EAAS,KAAA,CAAM,OAAA;AAAA,QACf,IAAA,EAAM,KAAA,CAAM,QAAA,EAAU,SAAA,EAAW,KAAA,CAAA;AAAA,QACjC,QAAA,EAAU,KAAA,CAAM,QAAA,EAAU,EAAA,EAAI,KAAA,CAAA;AAAA,QAK9B,YAAA,EAAY,KAAA,CAAM,QAAA,EAAU,oBAAA,EAAsB,KAAA,CAAA;AAAA,QAClD,SAAA,EACE,KAAA,CAAM,QAAA,EACF,CAAC,CAAA,EAAA,GAAM;AACL,UAAA,GAAA,CAAI,CAAA,CAAE,IAAA,IAAQ,QAAA,GAAW,CAAA,CAAE,IAAA,IAAQ,GAAA,EAAK;AACtC,YAAA,CAAA,CAAE,cAAA,CAAe,CAAA;AACjB,4BAAA,KAAA,qBAAM,OAAA,0BAAA,CAAU,GAAA;AAAA,UAClB;AAAA,QACF,EAAA,EACA,KAAA,CAAA;AAAA,QAGL,QAAA,EAAA,KAAA,CAAM,KAAA,kBACL,6BAAA,mBAAC,EAAA,EAAoB,IAAA,EAAM,KAAA,CAAM,KAAA,CAAM,EAAA,kBAEvC,8BAAA,oBAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAA,6BAAA,wBAAC,EAAA,EAAO,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM,KAAA,EAAM,QAAA,EAAS,IAAA,EAAK,KAAA,CAAK,CAAA;AAAA,0BAInD,6BAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,8BAAA;AAAA,cACV,aAAA,EAAa,KAAA,CAAM,QAAA,EAAU,KAAA,EAAO,KAAA,CAAA;AAAA,cAEnC,QAAA,EAAA,KAAA,CAAM;AAAA,YAAA;AAAA,UACT;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAEJ,CAAA;AAAA,oBAEA,6BAAA,IAAC,EAAA,EAAG,SAAA,EAAU,yBAAA,EACX,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAA,mBACV,6BAAA,IAAC,EAAA,EAAiB,SAAA,EAAU,gCAAA,EAM1B,QAAA,kBAAA,6BAAA,yBAAC,EAAA,EAAQ,OAAA,EAAS,IAAA,CAAK,KAAA,EAAO,SAAA,EAAU,OAAA,EAAQ,QAAA,EAAU,CAAC,SAAA,EACzD,QAAA,kBAAA,8BAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW;AAAA,UACT,wBAAA;AAAA,UACA,IAAA,CAAK,OAAA,GAAU;AAAA,QACjB,CAAA,CACG,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AAAA,QACX,QAAA,EAAU,IAAA,CAAK,QAAA;AAAA,QACf,OAAA,EAAS,IAAA,CAAK,OAAA;AAAA,QACd,cAAA,EAAc,IAAA,CAAK,OAAA,EAAS,OAAA,EAAS,KAAA,CAAA;AAAA,QAOrC,YAAA,EAAY,UAAA,EAAY,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAA;AAAA,QAEpC,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,KAAA,GAAQ,0CAAA,IAAW,CAAK,IAAA,EAAM,6BAA6B,CAAA;AAAA,0BACjE,6BAAA,MAAC,EAAA,EAAK,SAAA,EAAU,8BAAA,EAA+B,aAAA,EAAa,UAAA,GAAa,KAAA,CAAA,EACtE,QAAA,EAAA,IAAA,CAAK,MAAA,CACR;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,EAAA,CACF,EAAA,CAAA,EA/BO,IAAA,CAAK,EAgCd,CACD,EAAA,CACH,CAAA;AAAA,IAEC,OAAA,mBAAU,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAA,OAAA,CAAO,CAAA;AAAA,IAc5D,YAAA,mBACC,6BAAA,MAAC,EAAA,EAAK,SAAA,EAAU,0BAAA,EACd,QAAA,kBAAA,6BAAA;AAAA,MAAC,4BAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,UAAA,EAAY,gCAAA,EAAqB,8BAAA;AAAA,QACvC,OAAA,EAAQ,MAAA;AAAA,QACR,KAAA,EAAM,WAAA;AAAA,QACN,IAAA,EAAK,IAAA;AAAA,QACL,OAAA,EAAS,UAAA,EAAY,oBAAA,EAAsB,qBAAA;AAAA,QAC3C,YAAA,EAAY,UAAA,EAAY,oBAAA,EAAsB,qBAAA;AAAA,QAC9C,OAAA,EAAS;AAAA,MAAA;AAAA,IACX,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,CAAA;AAEJ,CAAA;AAEA,UAAA,CAAW,YAAA,EAAc,YAAA;ADzGzB;AACA;AACE;AACF,gCAAC","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-V4BZWBZT.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { SquareChevronLeft, SquareChevronRight } from 'lucide-react';\nimport type { NavigationLogo, NavigationProps } from './Navigation.types';\nimport { Avatar } from '../Avatar';\nimport { IconButton } from '../Button';\nimport { Tooltip } from '../Tooltip';\nimport { renderIcon } from '../../utils';\nimport './Navigation.scss';\n\n/**\n * Renders a custom brand logo, guaranteeing correct aspect-ratio rendering\n * regardless of whether the source image is vertical, horizontal, or square\n * - and regardless of how much width is actually available, expanded or\n * collapsed. Deliberately no JS sizing/measurement at all: a fixed `height`,\n * `width: auto` (derived from the image's own intrinsic ratio), a `max-width`\n * expressed as `min(72px, 100%)` (see `.eidos-navigation__brand-logo` in\n * Navigation.scss) so it never renders wider than whatever space its\n * container - the rail, expanded or collapsed - actually has, and\n * `object-fit: contain` so it's letterboxed rather than distorted if that\n * ever clamps it below its natural width-at-32px-tall. Centering is handled\n * separately, at the row level - see `&__brand--logo-only` in Navigation.scss.\n */\nconst NavigationBrandLogo: React.FC<{ logo: NavigationLogo }> = ({ logo }) => (\n <img src={logo.src} alt={logo.alt} className=\"eidos-navigation__brand-logo\" />\n);\n\nexport const Navigation: React.FC<NavigationProps> = ({\n brand,\n items,\n footer,\n collapsed: collapsedProp,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseBelow = 768,\n collapsible = true,\n className = '',\n}) => {\n // ── Controlled / uncontrolled collapsed state ─────────────────────────────\n // Mirrors CommandPalette's `open`/`defaultOpen` pattern - omitting\n // `collapsed` lets Navigation own its state entirely, while passing it\n // (+ `onCollapsedChange`) keeps full external control for consumers who\n // need to persist the preference or drive it from a responsive breakpoint.\n const isControlled = collapsedProp !== undefined;\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = isControlled ? collapsedProp : internalCollapsed;\n\n // Shared by the manual toggle button and `collapseBelow` below - uncontrolled\n // flips the internal state directly, controlled defers to `onCollapsedChange`\n // since Navigation can't change `collapsed` itself.\n const applyCollapsed = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n },\n [isControlled, onCollapsedChange],\n );\n\n const toggleCollapsed = useCallback(() => {\n applyCollapsed(!collapsed);\n }, [applyCollapsed, collapsed]);\n\n // Read by the breakpoint effect below so it does not depend on\n // `applyCollapsed`'s identity. A consumer passing an inline\n // `onCollapsedChange` gives that callback a new identity every render,\n // which would re-run the effect - and re-apply the media query's answer -\n // on every render, overriding any manual toggle made in between crossings.\n // That is the one thing `collapseBelow` is documented not to do.\n const applyCollapsedRef = useRef(applyCollapsed);\n useEffect(() => {\n applyCollapsedRef.current = applyCollapsed;\n });\n\n // Auto-collapse/expand at a viewport breakpoint. `matchMedia`'s `change`\n // event only fires exactly at the crossing point, not on every resize\n // tick, so a manual toggle in between crossings is left alone until the\n // viewport actually crosses the breakpoint again.\n useEffect(() => {\n // `0` opts out, as documented - and it has to be checked here rather\n // than relying on `(max-width: 0px)` never matching, because the mount\n // pass below would otherwise still run.\n if (!collapseBelow) return;\n if (typeof window === 'undefined' || !window.matchMedia) return;\n\n const query = window.matchMedia(`(max-width: ${collapseBelow}px)`);\n\n // On mount this may only *collapse*, never expand. `defaultCollapsed`\n // (or a controlled `collapsed`) is the consumer's stated starting point,\n // and applying `query.matches` unconditionally threw it away one commit\n // after the first paint: on any viewport wider than the breakpoint the\n // rail visibly started collapsed and then sprang open. Crossings below\n // still drive both directions, which is what \"collapses and re-expands\"\n // refers to.\n if (query.matches) applyCollapsedRef.current(true);\n\n const handleChange = (event: MediaQueryListEvent) => applyCollapsedRef.current(event.matches);\n query.addEventListener('change', handleChange);\n return () => query.removeEventListener('change', handleChange);\n }, [collapseBelow]);\n\n const classes = ['eidos-navigation', collapsed && 'eidos-navigation--collapsed', className]\n .filter(Boolean)\n .join(' ');\n\n // A `logo` brand has no `name` text alongside it (see the discriminated\n // union in Navigation.types.ts), so there's never a second, variable-width\n // sibling competing for space - unlike the `name` variant, it's always\n // safe to just center it outright, in both expanded and collapsed states,\n // with nothing further to compute. See `&__brand--logo-only` in\n // Navigation.scss.\n const brandClasses = [\n 'eidos-navigation__brand',\n brand.logo && 'eidos-navigation__brand--logo-only',\n brand.onClick && 'eidos-navigation__brand--clickable',\n ]\n .filter(Boolean)\n .join(' ');\n\n const brandAccessibleName = brand.logo ? brand.logo.alt : brand.name;\n\n return (\n <nav className={classes} aria-label=\"Main\">\n <div\n className={brandClasses}\n onClick={brand.onClick}\n role={brand.onClick ? 'button' : undefined}\n tabIndex={brand.onClick ? 0 : undefined}\n // Only a real interactive control (role=\"button\") reliably exposes\n // `aria-label` as its accessible name - a plain, non-interactive div\n // doesn't, so the visible (if currently faded) text remains the only\n // way assistive tech gets the brand name in that case.\n aria-label={brand.onClick ? brandAccessibleName : undefined}\n onKeyDown={\n brand.onClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n brand.onClick?.();\n }\n }\n : undefined\n }\n >\n {brand.logo ? (\n <NavigationBrandLogo logo={brand.logo} />\n ) : (\n <>\n <Avatar name={brand.name} shape=\"square\" size=\"sm\" />\n {/* Only redundant with the wrapper's own `aria-label` when\n `brand.onClick` is set (see the note on it above) - otherwise\n this is the only accessible text for the brand at all. */}\n <span\n className=\"eidos-navigation__brand-name\"\n aria-hidden={brand.onClick ? true : undefined}\n >\n {brand.name}\n </span>\n </>\n )}\n </div>\n\n <ul className=\"eidos-navigation__items\">\n {items.map((item) => (\n <li key={item.id} className=\"eidos-navigation__item-wrapper\">\n {/* Always wrapped (disabled rather than omitted while expanded)\n so the button underneath is never unmounted/remounted across\n a collapse toggle - that would otherwise reset its own CSS\n transitions (gap, padding, justify-content) partway through\n the rail's width animation, snapping instead of easing. */}\n <Tooltip message={item.label} placement=\"right\" disabled={!collapsed}>\n <button\n type=\"button\"\n className={[\n 'eidos-navigation__item',\n item.active && 'eidos-navigation__item--active',\n ]\n .filter(Boolean)\n .join(' ')}\n disabled={item.disabled}\n onClick={item.onClick}\n aria-current={item.active ? 'page' : undefined}\n // The label fades out visually while collapsed (see\n // `.eidos-navigation__item-label` in Navigation.scss) but\n // isn't removed from the DOM, so it's given directly as the\n // accessible name here instead of relying on the (also\n // fading) visible text, and hidden from assistive tech below\n // to avoid it being announced twice alongside the `Tooltip`.\n aria-label={collapsed ? item.label : undefined}\n >\n {item.icon && renderIcon(item.icon, 'eidos-navigation__item-icon')}\n <span className=\"eidos-navigation__item-label\" aria-hidden={collapsed || undefined}>\n {item.label}\n </span>\n </button>\n </Tooltip>\n </li>\n ))}\n </ul>\n\n {footer && <div className=\"eidos-navigation__footer\">{footer}</div>}\n\n {/* Floats half in/half out of the rail's right edge (see `&__toggle`\n in Navigation.scss) rather than sitting in its own row - a\n dedicated row reserved space in the flex column even when there\n were too few items to need it.\n\n The positioning has to live on this wrapping `<span>`, not on the\n `IconButton` itself: its `tooltip` prop makes `Button` wrap it in\n `Tooltip`'s own `.eidos-tooltip-trigger` div, which - not the\n button - is the actual flex child of `.eidos-navigation`. Removing\n only the inner button from flow left that outer wrapper still\n in-flow, still consuming space and still getting `gap` applied\n around it, which is exactly why a gap remained. */}\n {collapsible && (\n <span className=\"eidos-navigation__toggle\">\n <IconButton\n icon={collapsed ? SquareChevronRight : SquareChevronLeft}\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n tooltip={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n onClick={toggleCollapsed}\n />\n </span>\n )}\n </nav>\n );\n};\n\nNavigation.displayName = 'Navigation';\n"]}
@@ -144,6 +144,7 @@ var OTPInput = ({
144
144
  {
145
145
  className: "eidos-otp-slots",
146
146
  role: "group",
147
+ "aria-invalid": error ? true : void 0,
147
148
  "aria-labelledby": label ? labelId : void 0,
148
149
  "aria-describedby": describedBy,
149
150
  children: Array.from({ length }, (_v, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: slotClasses(index), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -180,4 +181,4 @@ OTPInput.displayName = "OTPInput";
180
181
 
181
182
 
182
183
  exports.OTPInput = OTPInput;
183
- //# sourceMappingURL=chunk-FKXKBJUI.cjs.map
184
+ //# sourceMappingURL=chunk-VHO6JPRR.cjs.map