eidos-ui 3.1.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/README.md +4 -0
  2. package/dist/Header.types-0XovUp0T.d.ts +79 -0
  3. package/dist/Header.types-Ce5Cj301.d.cts +79 -0
  4. package/dist/{Navigation.types-CpS3EYNz.d.ts → Navigation.types-By5HfPTi.d.ts} +8 -0
  5. package/dist/{Navigation.types-sUO9wqOp.d.cts → Navigation.types-_MrYqqUI.d.cts} +8 -0
  6. package/dist/{SegmentedControl.types-Dm4SnwCK.d.cts → SegmentedControl.types-BofrEYyd.d.cts} +16 -1
  7. package/dist/{SegmentedControl.types-CK8EiShd.d.ts → SegmentedControl.types-cjLwwBAm.d.ts} +16 -1
  8. package/dist/alert/index.cjs +4 -4
  9. package/dist/alert/index.js +3 -3
  10. package/dist/button/index.cjs +3 -3
  11. package/dist/button/index.js +2 -2
  12. package/dist/chip/index.cjs +3 -3
  13. package/dist/chip/index.js +2 -2
  14. package/dist/{chunk-RWOX2NJN.js → chunk-25PSIDPC.js} +2 -2
  15. package/dist/{chunk-IFVT5UCY.js → chunk-2QEKSRVX.js} +14 -10
  16. package/dist/chunk-2QEKSRVX.js.map +1 -0
  17. package/dist/{chunk-4BKTBV2I.js → chunk-2R77XZEP.js} +6 -2
  18. package/dist/chunk-2R77XZEP.js.map +1 -0
  19. package/dist/{chunk-SYWSXSHY.js → chunk-2WP27QAN.js} +8 -8
  20. package/dist/{chunk-EXITZVB2.js → chunk-3RLGH45H.js} +6 -6
  21. package/dist/{chunk-442U3W6R.cjs → chunk-4MZ7HEQC.cjs} +5 -5
  22. package/dist/{chunk-442U3W6R.cjs.map → chunk-4MZ7HEQC.cjs.map} +1 -1
  23. package/dist/{chunk-R4PU2TBM.js → chunk-4ZWAJTNH.js} +3 -3
  24. package/dist/{chunk-RHOT7AEI.cjs → chunk-55J4LEKT.cjs} +8 -7
  25. package/dist/chunk-55J4LEKT.cjs.map +1 -0
  26. package/dist/{chunk-REVK7IGN.js → chunk-5WH3JMR5.js} +8 -7
  27. package/dist/chunk-5WH3JMR5.js.map +1 -0
  28. package/dist/{chunk-GT22EGJP.cjs → chunk-65PC3YDT.cjs} +14 -10
  29. package/dist/chunk-65PC3YDT.cjs.map +1 -0
  30. package/dist/{chunk-KQD7CQ4Z.cjs → chunk-6CSUUQ5M.cjs} +10 -6
  31. package/dist/chunk-6CSUUQ5M.cjs.map +1 -0
  32. package/dist/{chunk-GR2PMCVN.cjs → chunk-75TDY7XF.cjs} +5 -5
  33. package/dist/{chunk-GR2PMCVN.cjs.map → chunk-75TDY7XF.cjs.map} +1 -1
  34. package/dist/{chunk-FRUOA2QU.cjs → chunk-75VXB3H2.cjs} +7 -3
  35. package/dist/chunk-75VXB3H2.cjs.map +1 -0
  36. package/dist/{chunk-F26VIKNF.js → chunk-ATL7325T.js} +3 -3
  37. package/dist/{chunk-TEJIPPZR.js → chunk-BC5I2MYB.js} +7 -4
  38. package/dist/chunk-BC5I2MYB.js.map +1 -0
  39. package/dist/{chunk-GHQ6SQPI.js → chunk-BHVHM66Z.js} +6 -6
  40. package/dist/{chunk-N2IGZIEX.cjs → chunk-CJGFRPAS.cjs} +3 -3
  41. package/dist/{chunk-N2IGZIEX.cjs.map → chunk-CJGFRPAS.cjs.map} +1 -1
  42. package/dist/{chunk-GEHL4LKK.cjs → chunk-CUJBNRJJ.cjs} +8 -2
  43. package/dist/chunk-CUJBNRJJ.cjs.map +1 -0
  44. package/dist/{chunk-DAXZRNNO.cjs → chunk-D2SKXRKP.cjs} +8 -8
  45. package/dist/{chunk-DAXZRNNO.cjs.map → chunk-D2SKXRKP.cjs.map} +1 -1
  46. package/dist/{chunk-KBG77JHC.js → chunk-EAJHEYZM.js} +8 -2
  47. package/dist/chunk-EAJHEYZM.js.map +1 -0
  48. package/dist/{chunk-G77YR73R.cjs → chunk-EBSKRZXI.cjs} +8 -8
  49. package/dist/{chunk-G77YR73R.cjs.map → chunk-EBSKRZXI.cjs.map} +1 -1
  50. package/dist/{chunk-B5G5XVFJ.cjs → chunk-EH42ND5Q.cjs} +5 -5
  51. package/dist/{chunk-B5G5XVFJ.cjs.map → chunk-EH42ND5Q.cjs.map} +1 -1
  52. package/dist/{chunk-WUBQJVB7.cjs → chunk-EL3YXTOW.cjs} +9 -6
  53. package/dist/chunk-EL3YXTOW.cjs.map +1 -0
  54. package/dist/{chunk-Y53HCLGW.js → chunk-FALDCW2E.js} +2 -2
  55. package/dist/{chunk-D5IY2HUV.cjs → chunk-FXZJL2AM.cjs} +5 -5
  56. package/dist/{chunk-D5IY2HUV.cjs.map → chunk-FXZJL2AM.cjs.map} +1 -1
  57. package/dist/{chunk-KJZUYC4X.cjs → chunk-HI6WCX4T.cjs} +10 -9
  58. package/dist/chunk-HI6WCX4T.cjs.map +1 -0
  59. package/dist/{chunk-LFWPQYWX.cjs → chunk-I3CSPYHG.cjs} +3 -3
  60. package/dist/{chunk-LFWPQYWX.cjs.map → chunk-I3CSPYHG.cjs.map} +1 -1
  61. package/dist/{chunk-EZME5CLK.cjs → chunk-J5RMLZ4P.cjs} +3 -3
  62. package/dist/{chunk-EZME5CLK.cjs.map → chunk-J5RMLZ4P.cjs.map} +1 -1
  63. package/dist/{chunk-VHMOKXUT.js → chunk-JRLUZDKA.js} +8 -7
  64. package/dist/chunk-JRLUZDKA.js.map +1 -0
  65. package/dist/{chunk-LIFUHQH5.cjs → chunk-KBGFDHKD.cjs} +19 -19
  66. package/dist/{chunk-LIFUHQH5.cjs.map → chunk-KBGFDHKD.cjs.map} +1 -1
  67. package/dist/{chunk-ZHFPV43D.js → chunk-KNQ6NN6L.js} +5 -5
  68. package/dist/{chunk-GWQEADRJ.js → chunk-KQJ3IAFT.js} +2 -2
  69. package/dist/{chunk-74MBKLYI.js → chunk-L23WWO3D.js} +9 -5
  70. package/dist/chunk-L23WWO3D.js.map +1 -0
  71. package/dist/{chunk-YJXZR7RL.js → chunk-L5Q6UDY3.js} +4 -4
  72. package/dist/{chunk-5BX4Q76D.cjs → chunk-LVHZBCTA.cjs} +3 -3
  73. package/dist/{chunk-5BX4Q76D.cjs.map → chunk-LVHZBCTA.cjs.map} +1 -1
  74. package/dist/{chunk-SENVA467.js → chunk-M7PF4FKQ.js} +6 -2
  75. package/dist/chunk-M7PF4FKQ.js.map +1 -0
  76. package/dist/chunk-ND526PMG.cjs +145 -0
  77. package/dist/chunk-ND526PMG.cjs.map +1 -0
  78. package/dist/{chunk-TRLBYA5G.cjs → chunk-NEYLNRVG.cjs} +5 -5
  79. package/dist/{chunk-TRLBYA5G.cjs.map → chunk-NEYLNRVG.cjs.map} +1 -1
  80. package/dist/{chunk-ZEZK664O.js → chunk-NWJ6NETE.js} +13 -13
  81. package/dist/{chunk-SEDKUITE.cjs → chunk-NZO2I5AL.cjs} +7 -7
  82. package/dist/{chunk-SEDKUITE.cjs.map → chunk-NZO2I5AL.cjs.map} +1 -1
  83. package/dist/{chunk-5ZL6PYU3.js → chunk-O2AACVSF.js} +3 -3
  84. package/dist/chunk-O3LG7B2J.cjs +186 -0
  85. package/dist/chunk-O3LG7B2J.cjs.map +1 -0
  86. package/dist/{chunk-SHYSLWQG.js → chunk-OAK7HFOJ.js} +4 -4
  87. package/dist/{chunk-QF2RAUPB.cjs → chunk-OAPOGYA5.cjs} +7 -3
  88. package/dist/chunk-OAPOGYA5.cjs.map +1 -0
  89. package/dist/{chunk-SKEWTQJ7.cjs → chunk-OMLXP2CK.cjs} +7 -7
  90. package/dist/{chunk-SKEWTQJ7.cjs.map → chunk-OMLXP2CK.cjs.map} +1 -1
  91. package/dist/{chunk-VSTQEHVZ.js → chunk-PR7CVQ4R.js} +10 -7
  92. package/dist/chunk-PR7CVQ4R.js.map +1 -0
  93. package/dist/{chunk-6HUHH6Y4.cjs → chunk-Q6ICDKQZ.cjs} +22 -19
  94. package/dist/chunk-Q6ICDKQZ.cjs.map +1 -0
  95. package/dist/{chunk-NGVOXM7P.js → chunk-QIITXVRG.js} +4 -4
  96. package/dist/{chunk-GI6VJYOS.js → chunk-QUDVJUZU.js} +3 -3
  97. package/dist/chunk-QZX3A4FX.js +886 -0
  98. package/dist/chunk-QZX3A4FX.js.map +1 -0
  99. package/dist/chunk-R3WPVTGY.cjs +886 -0
  100. package/dist/chunk-R3WPVTGY.cjs.map +1 -0
  101. package/dist/{chunk-SN6EWQDJ.js → chunk-RYOQYYDO.js} +3 -3
  102. package/dist/chunk-S4S4LB63.js +186 -0
  103. package/dist/chunk-S4S4LB63.js.map +1 -0
  104. package/dist/{chunk-67RFMV6K.js → chunk-T2KB3DJJ.js} +2 -2
  105. package/dist/{chunk-5VM2256W.cjs → chunk-TEVZHN5I.cjs} +11 -10
  106. package/dist/chunk-TEVZHN5I.cjs.map +1 -0
  107. package/dist/{chunk-RKA2OJRT.js → chunk-TJC7UELT.js} +18 -18
  108. package/dist/{chunk-SKTDGCWJ.cjs → chunk-UOOGS6N7.cjs} +48 -48
  109. package/dist/{chunk-SKTDGCWJ.cjs.map → chunk-UOOGS6N7.cjs.map} +1 -1
  110. package/dist/{chunk-JRYTZ5B2.cjs → chunk-VRQBDTLT.cjs} +32 -32
  111. package/dist/{chunk-JRYTZ5B2.cjs.map → chunk-VRQBDTLT.cjs.map} +1 -1
  112. package/dist/{chunk-AXBYJ2OY.cjs → chunk-WFEORBLC.cjs} +8 -8
  113. package/dist/{chunk-AXBYJ2OY.cjs.map → chunk-WFEORBLC.cjs.map} +1 -1
  114. package/dist/chunk-WKDT2XFQ.js +145 -0
  115. package/dist/chunk-WKDT2XFQ.js.map +1 -0
  116. package/dist/{chunk-APK5OQRV.cjs → chunk-WWYJNWJY.cjs} +6 -6
  117. package/dist/{chunk-APK5OQRV.cjs.map → chunk-WWYJNWJY.cjs.map} +1 -1
  118. package/dist/{chunk-A7WQINIG.js → chunk-X3U7SDOZ.js} +7 -6
  119. package/dist/chunk-X3U7SDOZ.js.map +1 -0
  120. package/dist/{chunk-LEMCJW57.js → chunk-YDPEHUMH.js} +2 -2
  121. package/dist/{chunk-GGSII6Y2.cjs → chunk-ZGT4LT5Y.cjs} +33 -33
  122. package/dist/{chunk-GGSII6Y2.cjs.map → chunk-ZGT4LT5Y.cjs.map} +1 -1
  123. package/dist/{chunk-LUL6RZ4M.cjs → chunk-ZNWIHUHZ.cjs} +3 -3
  124. package/dist/{chunk-LUL6RZ4M.cjs.map → chunk-ZNWIHUHZ.cjs.map} +1 -1
  125. package/dist/{chunk-S3CT536K.js → chunk-ZPDETHQ7.js} +2 -2
  126. package/dist/color-picker/index.cjs +4 -3
  127. package/dist/color-picker/index.cjs.map +1 -1
  128. package/dist/color-picker/index.js +3 -2
  129. package/dist/combobox/index.cjs +5 -5
  130. package/dist/combobox/index.js +4 -4
  131. package/dist/context-menu/index.cjs +5 -5
  132. package/dist/context-menu/index.js +4 -4
  133. package/dist/conversation/index.cjs +28 -0
  134. package/dist/conversation/index.cjs.map +1 -0
  135. package/dist/conversation/index.d.cts +254 -0
  136. package/dist/conversation/index.d.ts +254 -0
  137. package/dist/conversation/index.js +28 -0
  138. package/dist/conversation/index.js.map +1 -0
  139. package/dist/data-grid/index.cjs +16 -16
  140. package/dist/data-grid/index.d.cts +1 -1
  141. package/dist/data-grid/index.d.ts +1 -1
  142. package/dist/data-grid/index.js +15 -15
  143. package/dist/date-picker/index.cjs +7 -7
  144. package/dist/date-picker/index.js +6 -6
  145. package/dist/drawer/index.cjs +4 -4
  146. package/dist/drawer/index.js +3 -3
  147. package/dist/dropdown/index.cjs +3 -2
  148. package/dist/dropdown/index.cjs.map +1 -1
  149. package/dist/dropdown/index.js +2 -1
  150. package/dist/header/index.cjs +8 -4
  151. package/dist/header/index.cjs.map +1 -1
  152. package/dist/header/index.d.cts +35 -4
  153. package/dist/header/index.d.ts +35 -4
  154. package/dist/header/index.js +9 -5
  155. package/dist/index.cjs +66 -56
  156. package/dist/index.cjs.map +1 -1
  157. package/dist/index.css +1015 -167
  158. package/dist/index.d.cts +5 -4
  159. package/dist/index.d.ts +5 -4
  160. package/dist/index.js +84 -74
  161. package/dist/inline-edit/index.cjs +4 -4
  162. package/dist/inline-edit/index.js +3 -3
  163. package/dist/input/index.cjs +3 -3
  164. package/dist/input/index.js +2 -2
  165. package/dist/menu/index.cjs +4 -4
  166. package/dist/menu/index.js +3 -3
  167. package/dist/modal/index.cjs +4 -4
  168. package/dist/modal/index.js +3 -3
  169. package/dist/navigation/index.cjs +4 -4
  170. package/dist/navigation/index.d.cts +2 -2
  171. package/dist/navigation/index.d.ts +2 -2
  172. package/dist/navigation/index.js +3 -3
  173. package/dist/number-input/index.cjs +3 -2
  174. package/dist/number-input/index.cjs.map +1 -1
  175. package/dist/number-input/index.js +2 -1
  176. package/dist/page-layout/index.cjs +10 -9
  177. package/dist/page-layout/index.cjs.map +1 -1
  178. package/dist/page-layout/index.d.cts +2 -2
  179. package/dist/page-layout/index.d.ts +2 -2
  180. package/dist/page-layout/index.js +9 -8
  181. package/dist/pagination/index.cjs +7 -7
  182. package/dist/pagination/index.js +6 -6
  183. package/dist/segmented-control/index.cjs +3 -3
  184. package/dist/segmented-control/index.d.cts +2 -2
  185. package/dist/segmented-control/index.d.ts +2 -2
  186. package/dist/segmented-control/index.js +2 -2
  187. package/dist/select/index.cjs +5 -5
  188. package/dist/select/index.js +4 -4
  189. package/dist/snackbar/index.cjs +4 -4
  190. package/dist/snackbar/index.js +3 -3
  191. package/dist/split-button/index.cjs +5 -5
  192. package/dist/split-button/index.js +4 -4
  193. package/dist/table/index.cjs +16 -16
  194. package/dist/table/index.cjs.map +1 -1
  195. package/dist/table/index.js +15 -15
  196. package/dist/tabs/index.cjs +3 -3
  197. package/dist/tabs/index.js +2 -2
  198. package/dist/tag-input/index.cjs +5 -5
  199. package/dist/tag-input/index.js +4 -4
  200. package/dist/textarea/index.cjs +3 -3
  201. package/dist/textarea/index.js +2 -2
  202. package/dist/theme-editor/index.cjs +11 -11
  203. package/dist/theme-editor/index.js +10 -10
  204. package/dist/theme-provider/index.cjs +3 -3
  205. package/dist/theme-provider/index.js +2 -2
  206. package/dist/toolbar/index.cjs +6 -6
  207. package/dist/toolbar/index.js +5 -5
  208. package/package.json +1 -1
  209. package/dist/Header.types-B3QtuiL-.d.cts +0 -21
  210. package/dist/Header.types-C6w0FBY8.d.ts +0 -21
  211. package/dist/chunk-4BKTBV2I.js.map +0 -1
  212. package/dist/chunk-5VM2256W.cjs.map +0 -1
  213. package/dist/chunk-6HUHH6Y4.cjs.map +0 -1
  214. package/dist/chunk-74MBKLYI.js.map +0 -1
  215. package/dist/chunk-A7WQINIG.js.map +0 -1
  216. package/dist/chunk-AAA6TR5I.cjs +0 -67
  217. package/dist/chunk-AAA6TR5I.cjs.map +0 -1
  218. package/dist/chunk-FRUOA2QU.cjs.map +0 -1
  219. package/dist/chunk-GEHL4LKK.cjs.map +0 -1
  220. package/dist/chunk-GT22EGJP.cjs.map +0 -1
  221. package/dist/chunk-IFVT5UCY.js.map +0 -1
  222. package/dist/chunk-KBG77JHC.js.map +0 -1
  223. package/dist/chunk-KJZUYC4X.cjs.map +0 -1
  224. package/dist/chunk-KQD7CQ4Z.cjs.map +0 -1
  225. package/dist/chunk-O5WEKLNF.js +0 -21
  226. package/dist/chunk-O5WEKLNF.js.map +0 -1
  227. package/dist/chunk-P7IQY5YH.js +0 -67
  228. package/dist/chunk-P7IQY5YH.js.map +0 -1
  229. package/dist/chunk-QF2RAUPB.cjs.map +0 -1
  230. package/dist/chunk-REVK7IGN.js.map +0 -1
  231. package/dist/chunk-RHOT7AEI.cjs.map +0 -1
  232. package/dist/chunk-SENVA467.js.map +0 -1
  233. package/dist/chunk-TEJIPPZR.js.map +0 -1
  234. package/dist/chunk-VHMOKXUT.js.map +0 -1
  235. package/dist/chunk-VSTQEHVZ.js.map +0 -1
  236. package/dist/chunk-WUBQJVB7.cjs.map +0 -1
  237. package/dist/chunk-Z4SLV6WG.cjs +0 -21
  238. package/dist/chunk-Z4SLV6WG.cjs.map +0 -1
  239. /package/dist/{chunk-RWOX2NJN.js.map → chunk-25PSIDPC.js.map} +0 -0
  240. /package/dist/{chunk-SYWSXSHY.js.map → chunk-2WP27QAN.js.map} +0 -0
  241. /package/dist/{chunk-EXITZVB2.js.map → chunk-3RLGH45H.js.map} +0 -0
  242. /package/dist/{chunk-R4PU2TBM.js.map → chunk-4ZWAJTNH.js.map} +0 -0
  243. /package/dist/{chunk-F26VIKNF.js.map → chunk-ATL7325T.js.map} +0 -0
  244. /package/dist/{chunk-GHQ6SQPI.js.map → chunk-BHVHM66Z.js.map} +0 -0
  245. /package/dist/{chunk-Y53HCLGW.js.map → chunk-FALDCW2E.js.map} +0 -0
  246. /package/dist/{chunk-ZHFPV43D.js.map → chunk-KNQ6NN6L.js.map} +0 -0
  247. /package/dist/{chunk-GWQEADRJ.js.map → chunk-KQJ3IAFT.js.map} +0 -0
  248. /package/dist/{chunk-YJXZR7RL.js.map → chunk-L5Q6UDY3.js.map} +0 -0
  249. /package/dist/{chunk-ZEZK664O.js.map → chunk-NWJ6NETE.js.map} +0 -0
  250. /package/dist/{chunk-5ZL6PYU3.js.map → chunk-O2AACVSF.js.map} +0 -0
  251. /package/dist/{chunk-SHYSLWQG.js.map → chunk-OAK7HFOJ.js.map} +0 -0
  252. /package/dist/{chunk-NGVOXM7P.js.map → chunk-QIITXVRG.js.map} +0 -0
  253. /package/dist/{chunk-GI6VJYOS.js.map → chunk-QUDVJUZU.js.map} +0 -0
  254. /package/dist/{chunk-SN6EWQDJ.js.map → chunk-RYOQYYDO.js.map} +0 -0
  255. /package/dist/{chunk-67RFMV6K.js.map → chunk-T2KB3DJJ.js.map} +0 -0
  256. /package/dist/{chunk-RKA2OJRT.js.map → chunk-TJC7UELT.js.map} +0 -0
  257. /package/dist/{chunk-LEMCJW57.js.map → chunk-YDPEHUMH.js.map} +0 -0
  258. /package/dist/{chunk-S3CT536K.js.map → chunk-ZPDETHQ7.js.map} +0 -0
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  Dropdown
3
- } from "./chunk-4BKTBV2I.js";
3
+ } from "./chunk-2R77XZEP.js";
4
4
  import {
5
5
  Kbd
6
6
  } from "./chunk-LYH3EKKQ.js";
7
- import {
8
- renderIcon
9
- } from "./chunk-KBG77JHC.js";
10
7
  import {
11
8
  Tooltip
12
9
  } from "./chunk-YV57RSPD.js";
10
+ import {
11
+ renderIcon
12
+ } from "./chunk-EAJHEYZM.js";
13
13
 
14
14
  // src/components/Menu/Menu.component.tsx
15
15
  import { useCallback } from "react";
@@ -122,4 +122,4 @@ export {
122
122
  MenuPanel,
123
123
  Menu
124
124
  };
125
- //# sourceMappingURL=chunk-ZHFPV43D.js.map
125
+ //# sourceMappingURL=chunk-KNQ6NN6L.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  devWarn
3
- } from "./chunk-KBG77JHC.js";
3
+ } from "./chunk-EAJHEYZM.js";
4
4
 
5
5
  // src/components/ThemeProvider/ThemeProvider.component.tsx
6
6
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -521,4 +521,4 @@ export {
521
521
  isFontAvailable,
522
522
  isFontStackAvailable
523
523
  };
524
- //# sourceMappingURL=chunk-GWQEADRJ.js.map
524
+ //# sourceMappingURL=chunk-KQJ3IAFT.js.map
@@ -1,6 +1,8 @@
1
1
  import {
2
+ dualModifier,
3
+ fullWidthModifier,
2
4
  renderIcon
3
- } from "./chunk-KBG77JHC.js";
5
+ } from "./chunk-EAJHEYZM.js";
4
6
 
5
7
  // src/components/Tabs/Tabs.component.tsx
6
8
  import React, { useState, useRef, useContext, useEffect, useLayoutEffect } from "react";
@@ -45,7 +47,7 @@ var Tab = ({
45
47
  `eidos-tab--${size}`,
46
48
  isActive && "eidos-tab--active",
47
49
  disabled && "eidos-tab--disabled",
48
- fullWidth && "eidos-tab--fullWidth",
50
+ fullWidth && fullWidthModifier("eidos-tab"),
49
51
  className
50
52
  ].filter(Boolean).join(" ");
51
53
  return /* @__PURE__ */ jsxs(
@@ -186,11 +188,11 @@ var Tabs = ({
186
188
  const listClasses = [
187
189
  "eidos-tabs-list",
188
190
  `eidos-tabs-list--${size}`,
189
- fullWidth && "eidos-tabs-list--fullWidth",
191
+ fullWidth && fullWidthModifier("eidos-tabs-list"),
190
192
  // With buttons, they are the affordance - a native scrollbar underneath
191
193
  // them is redundant, and on a space-taking one it would also sit over the
192
194
  // `line` variant's rule.
193
- hasScrollButtons && "eidos-tabs-list--hideScrollbar"
195
+ hasScrollButtons && dualModifier("eidos-tabs-list", "hide-scrollbar", "hideScrollbar")
194
196
  ].filter(Boolean).join(" ");
195
197
  const showPrevButton = hasScrollButtons && scrollState.canScrollPrev;
196
198
  const showNextButton = hasScrollButtons && scrollState.canScrollNext;
@@ -216,6 +218,7 @@ var Tabs = ({
216
218
  type: "button",
217
219
  className: scrollButtonClasses("prev"),
218
220
  onClick: () => scrollByStep(-1),
221
+ onMouseDown: (event) => event.preventDefault(),
219
222
  tabIndex: -1,
220
223
  "aria-hidden": "true",
221
224
  children: /* @__PURE__ */ jsx(ChevronLeft, { className: "eidos-tabs-scroll-button-icon" })
@@ -231,6 +234,7 @@ var Tabs = ({
231
234
  type: "button",
232
235
  className: scrollButtonClasses("next"),
233
236
  onClick: () => scrollByStep(1),
237
+ onMouseDown: (event) => event.preventDefault(),
234
238
  tabIndex: -1,
235
239
  "aria-hidden": "true",
236
240
  children: /* @__PURE__ */ jsx(ChevronRight, { className: "eidos-tabs-scroll-button-icon" })
@@ -247,4 +251,4 @@ export {
247
251
  TabPanel,
248
252
  Tabs
249
253
  };
250
- //# sourceMappingURL=chunk-74MBKLYI.js.map
254
+ //# sourceMappingURL=chunk-L23WWO3D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Tabs/Tabs.component.tsx"],"sourcesContent":["import React, { useState, useRef, useContext, useEffect, useLayoutEffect } from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { renderIcon, dualModifier, fullWidthModifier } from '../../utils';\nimport type { TabsProps, TabProps, TabPanelProps, TabsContextValue } from './Tabs.types';\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\nconst TabsContext = React.createContext<TabsContextValue | null>(null);\n\nconst useTabsContext = (): TabsContextValue => {\n const ctx = useContext(TabsContext);\n if (!ctx) throw new Error('Tab/TabPanel must be used inside <Tabs>');\n return ctx;\n};\n\n// ============================================================================\n// TAB - individual tab trigger button\n// Defined before Tabs so Tabs can use `child.type === Tab` for child separation.\n// ============================================================================\n\nexport const Tab: React.FC<TabProps> = ({\n value,\n children,\n disabled = false,\n icon,\n className = '',\n}) => {\n const { activeValue, onSelect, size, fullWidth, listRef } = useTabsContext();\n const isActive = activeValue === value;\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n const list = listRef.current;\n if (!list) return;\n\n const allTabs = Array.from(\n list.querySelectorAll('[role=\"tab\"]:not([disabled])'),\n ) as HTMLElement[];\n const currentIndex = allTabs.indexOf(e.currentTarget);\n if (currentIndex === -1) return;\n\n let targetIndex = -1;\n if (e.key === 'ArrowRight') targetIndex = (currentIndex + 1) % allTabs.length;\n else if (e.key === 'ArrowLeft')\n targetIndex = (currentIndex - 1 + allTabs.length) % allTabs.length;\n else if (e.key === 'Home') targetIndex = 0;\n else if (e.key === 'End') targetIndex = allTabs.length - 1;\n\n if (targetIndex !== -1) {\n e.preventDefault();\n allTabs[targetIndex].focus();\n }\n };\n\n const tabClasses = [\n 'eidos-tab',\n `eidos-tab--${size}`,\n isActive && 'eidos-tab--active',\n disabled && 'eidos-tab--disabled',\n fullWidth && fullWidthModifier('eidos-tab'),\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n id={`eidos-tab-${value}`}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={`eidos-tabpanel-${value}`}\n tabIndex={isActive ? 0 : -1}\n disabled={disabled}\n className={tabClasses}\n onClick={() => !disabled && onSelect(value)}\n onKeyDown={handleKeyDown}\n type=\"button\"\n >\n {icon && <span className=\"eidos-tab-icon\">{renderIcon(icon, 'eidos-tab-icon-svg')}</span>}\n <span className=\"eidos-tab-label\">{children}</span>\n </button>\n );\n};\n\nTab.displayName = 'Tab';\n\n// ============================================================================\n// TAB PANEL - content region shown when its value matches the active tab\n// Defined before Tabs for the same `child.type === TabPanel` check.\n// ============================================================================\n\nexport const TabPanel: React.FC<TabPanelProps> = ({ value, children, className = '' }) => {\n const { activeValue } = useTabsContext();\n const isActive = activeValue === value;\n\n if (!isActive) return null;\n\n return (\n <div\n id={`eidos-tabpanel-${value}`}\n role=\"tabpanel\"\n aria-labelledby={`eidos-tab-${value}`}\n tabIndex={0}\n className={['eidos-tab-panel', className].filter(Boolean).join(' ')}\n >\n {children}\n </div>\n );\n};\n\nTabPanel.displayName = 'TabPanel';\n\n// ============================================================================\n// TABS - root container; provides context, separates tab/panel children\n// ============================================================================\n\nexport const Tabs: React.FC<TabsProps> = ({\n value,\n defaultValue,\n onChange,\n variant = 'line',\n size = 'md',\n color = 'primary',\n fullWidth = false,\n scrollButtons = 'auto',\n className = '',\n children,\n}) => {\n const isControlled = value !== undefined;\n const [localValue, setLocalValue] = useState(defaultValue ?? '');\n const activeValue = isControlled ? value! : localValue;\n\n // Separate Tab and TabPanel children so the list and panels render in\n // distinct DOM regions, regardless of how the consumer orders them.\n const tabChildren: React.ReactElement[] = [];\n const panelChildren: React.ReactElement[] = [];\n\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return;\n if (child.type === Tab) {\n tabChildren.push(child);\n } else if (child.type === TabPanel) {\n panelChildren.push(child);\n }\n });\n\n const listRef = useRef<HTMLDivElement>(null);\n const indicatorRef = useRef<HTMLSpanElement>(null);\n // Tracks whether the indicator has been positioned at least once so we can\n // skip the CSS transition on the very first render and avoid it animating\n // from the top-left corner to the initial tab.\n const hasPositioned = useRef(false);\n\n useLayoutEffect(() => {\n if (variant !== 'line') return;\n const list = listRef.current;\n const indicator = indicatorRef.current;\n if (!list || !indicator) return;\n\n const activeTab = list.querySelector('[aria-selected=\"true\"]') as HTMLElement | null;\n if (!activeTab) return;\n\n // Suppress the CSS transition on the initial paint so the indicator snaps\n // into place rather than sliding from 0.\n if (!hasPositioned.current) {\n indicator.style.transition = 'none';\n }\n\n indicator.style.left = `${activeTab.offsetLeft}px`;\n indicator.style.width = `${activeTab.offsetWidth}px`;\n\n if (!hasPositioned.current) {\n // Force a synchronous reflow so the browser commits the no-transition\n // position before we re-enable the transition for future clicks.\n void indicator.offsetWidth;\n indicator.style.transition = '';\n hasPositioned.current = true;\n }\n }, [activeValue, variant, fullWidth]);\n\n // The list scrolls horizontally when the strip is wider than its container,\n // so an activated tab can sit outside the scrollport - reachable by keyboard\n // (`End`) or by a controlled `value` change, but invisible. `scrollLeft` is\n // adjusted directly rather than via `scrollIntoView`, which walks the whole\n // ancestor chain and would scroll the page vertically when the strip is below\n // the fold.\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list) return;\n\n const activeTab = list.querySelector('[aria-selected=\"true\"]') as HTMLElement | null;\n if (!activeTab) return;\n\n const left = activeTab.offsetLeft;\n const right = left + activeTab.offsetWidth;\n\n if (left < list.scrollLeft) {\n list.scrollLeft = left;\n } else if (right > list.scrollLeft + list.clientWidth) {\n list.scrollLeft = right - list.clientWidth;\n }\n }, [activeValue]);\n\n // Whether either end of the strip has content hidden past it. Drives both\n // the presence of the scroll buttons (neither end scrollable = the strip\n // fits, so no buttons) and their disabled state at the extremes.\n const [scrollState, setScrollState] = useState({ canScrollPrev: false, canScrollNext: false });\n const hasScrollButtons = scrollButtons !== 'none';\n\n useEffect(() => {\n if (!hasScrollButtons) return;\n const list = listRef.current;\n if (!list) return;\n\n const update = () => {\n const maxScroll = list.scrollWidth - list.clientWidth;\n // 1px of tolerance: fractional layout widths leave a sub-pixel remainder\n // at either end that would otherwise keep a button enabled for a scroll\n // that can no longer move anything.\n const canScrollPrev = list.scrollLeft > 1;\n const canScrollNext = list.scrollLeft < maxScroll - 1;\n setScrollState((previous) =>\n previous.canScrollPrev === canScrollPrev && previous.canScrollNext === canScrollNext\n ? previous\n : { canScrollPrev, canScrollNext },\n );\n };\n\n update();\n list.addEventListener('scroll', update, { passive: true });\n\n // The list's own box stays the same width when a tab's label reflows or a\n // font finishes loading, so the tabs have to be observed as well as the\n // container - only their sizes tell us the strip started overflowing.\n const observer = new ResizeObserver(update);\n observer.observe(list);\n Array.from(list.children).forEach((child) => observer.observe(child));\n\n return () => {\n list.removeEventListener('scroll', update);\n observer.disconnect();\n };\n }, [hasScrollButtons, tabChildren.length, size, variant, fullWidth]);\n\n const scrollByStep = (direction: -1 | 1) => {\n const list = listRef.current;\n if (!list) return;\n\n // A step just short of a full page keeps a tab of context on screen, the\n // same way a paged scrollbar click does.\n const step = list.clientWidth * 0.8;\n const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n list.scrollBy({ left: direction * step, behavior: reducedMotion ? 'auto' : 'smooth' });\n };\n\n const onSelect = (newValue: string) => {\n if (!isControlled) {\n setLocalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const rootClasses = ['eidos-tabs', `eidos-tabs--${variant}`, `eidos-tabs--${color}`, className]\n .filter(Boolean)\n .join(' ');\n\n const listClasses = [\n 'eidos-tabs-list',\n `eidos-tabs-list--${size}`,\n fullWidth && fullWidthModifier('eidos-tabs-list'),\n // With buttons, they are the affordance - a native scrollbar underneath\n // them is redundant, and on a space-taking one it would also sit over the\n // `line` variant's rule.\n hasScrollButtons && dualModifier('eidos-tabs-list', 'hide-scrollbar', 'hideScrollbar'),\n ]\n .filter(Boolean)\n .join(' ');\n\n // Each button exists only while its own direction has somewhere to go: none\n // at all when the strip fits, and none at the end you have reached. A\n // disabled button would be pointing at nothing. They are positioned\n // absolutely, so appearing and disappearing never moves the tabs.\n const showPrevButton = hasScrollButtons && scrollState.canScrollPrev;\n const showNextButton = hasScrollButtons && scrollState.canScrollNext;\n\n const scrollButtonClasses = (direction: 'prev' | 'next') =>\n [\n 'eidos-tabs-scroll-button',\n `eidos-tabs-scroll-button--${direction}`,\n `eidos-tabs-scroll-button--${size}`,\n ].join(' ');\n\n const contextValue: TabsContextValue = {\n activeValue,\n onSelect,\n variant,\n size,\n color,\n fullWidth,\n listRef,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <div className={rootClasses}>\n {/* The buttons are siblings of the tab list, never children of it:\n `role=\"tablist\"` only accepts tabs. They are also hidden from\n assistive tech and skipped by Tab, because they are a pointer\n affordance for something the keyboard already does - arrow keys\n move between tabs and scroll the active one into view. */}\n <div className=\"eidos-tabs-bar\">\n {showPrevButton && (\n <button\n type=\"button\"\n className={scrollButtonClasses('prev')}\n onClick={() => scrollByStep(-1)}\n // `tabIndex={-1}` keeps these out of the tab order but does not\n // stop a click from focusing them, and focus inside an\n // `aria-hidden` subtree is an error the browser reports\n // (\"Blocked aria-hidden on an element because its descendant\n // retained focus\"). Suppressing the default mousedown keeps\n // them unfocusable by pointer too; the click still fires.\n // `inert` would prevent the click as well, so it is no help.\n onMouseDown={(event) => event.preventDefault()}\n tabIndex={-1}\n aria-hidden=\"true\"\n >\n <ChevronLeft className=\"eidos-tabs-scroll-button-icon\" />\n </button>\n )}\n\n <div ref={listRef} className={listClasses} role=\"tablist\">\n {tabChildren}\n {variant === 'line' && (\n <span ref={indicatorRef} className=\"eidos-tabs-indicator\" aria-hidden=\"true\" />\n )}\n </div>\n\n {showNextButton && (\n <button\n type=\"button\"\n className={scrollButtonClasses('next')}\n onClick={() => scrollByStep(1)}\n onMouseDown={(event) => event.preventDefault()} // see the prev button\n tabIndex={-1}\n aria-hidden=\"true\"\n >\n <ChevronRight className=\"eidos-tabs-scroll-button-icon\" />\n </button>\n )}\n </div>\n\n <div className=\"eidos-tabs-panels\">{panelChildren}</div>\n </div>\n </TabsContext.Provider>\n );\n};\n\nTabs.displayName = 'Tabs';\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
- import {
2
- renderIcon
3
- } from "./chunk-KBG77JHC.js";
4
1
  import {
5
2
  Tooltip
6
3
  } from "./chunk-YV57RSPD.js";
4
+ import {
5
+ renderIcon
6
+ } from "./chunk-EAJHEYZM.js";
7
7
 
8
8
  // src/components/Button/Button.component.tsx
9
9
  import { LoaderCircle } from "lucide-react";
@@ -66,4 +66,4 @@ export {
66
66
  Button,
67
67
  IconButton
68
68
  };
69
- //# sourceMappingURL=chunk-YJXZR7RL.js.map
69
+ //# sourceMappingURL=chunk-L5Q6UDY3.js.map
@@ -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 _chunkFRUOA2QUcjs = require('./chunk-FRUOA2QU.cjs');
3
+ var _chunk75VXB3H2cjs = require('./chunk-75VXB3H2.cjs');
4
4
 
5
5
  // src/components/ColorPicker/ColorPicker.component.tsx
6
6
  var _react = require('react');
@@ -496,7 +496,7 @@ var ColorPicker = ({
496
496
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: rootClasses, children: [
497
497
  label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-color-picker-label", children: label }),
498
498
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
499
- _chunkFRUOA2QUcjs.Dropdown,
499
+ _chunk75VXB3H2cjs.Dropdown,
500
500
  {
501
501
  trigger: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
502
502
  "button",
@@ -531,4 +531,4 @@ ColorPicker.displayName = "ColorPicker";
531
531
 
532
532
 
533
533
  exports.ColorPicker = ColorPicker;
534
- //# sourceMappingURL=chunk-5BX4Q76D.cjs.map
534
+ //# sourceMappingURL=chunk-LVHZBCTA.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-5BX4Q76D.cjs","../src/components/ColorPicker/ColorPicker.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-5BX4Q76D.cjs","sourcesContent":[null,"import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { Dropdown } from '../Dropdown/Dropdown.component';\nimport type {\n ColorPickerProps,\n HSVColor,\n RGBColor,\n HSLColor,\n ColorFormat,\n} from './ColorPicker.types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_SWATCHES: string[] = [\n '#ef4444',\n '#f97316',\n '#f59e0b',\n '#10b981',\n '#06b6d4',\n '#6366f1',\n '#8b5cf6',\n '#ec4899',\n '#64748b',\n '#1e293b',\n];\n\n// ============================================================================\n// Pure colour-utility functions\n// ============================================================================\n\nfunction hsvToRgb(h: number, s: number, v: number): RGBColor {\n // h: 0–360, s: 0–100, v: 0–100 → r,g,b: 0–255\n const sn = s / 100;\n const vn = v / 100;\n const c = vn * sn;\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n const m = vn - c;\n\n let r: number, g: number, b: number;\n if (h < 60) {\n r = c;\n g = x;\n b = 0;\n } else if (h < 120) {\n r = x;\n g = c;\n b = 0;\n } else if (h < 180) {\n r = 0;\n g = c;\n b = x;\n } else if (h < 240) {\n r = 0;\n g = x;\n b = c;\n } else if (h < 300) {\n r = x;\n g = 0;\n b = c;\n } else {\n r = c;\n g = 0;\n b = x;\n }\n\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\nfunction rgbToHsv(r: number, g: number, b: number): HSVColor {\n // r,g,b: 0–255 → h: 0–360, s: 0–100, v: 0–100\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n\n const v = max * 100;\n const s = max === 0 ? 0 : (delta / max) * 100;\n\n let h = 0;\n if (delta !== 0) {\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = h * 60;\n if (h < 0) h += 360;\n }\n\n // Deliberately NOT rounded. HSV is this component's internal state, and\n // rounding s/v to whole percent makes the hex -> HSV -> hex round trip lossy:\n // `#5c5de8` came back as `#5d5de8`, so a controlled `value` displayed a\n // different colour than the one passed in, and any interaction committed the\n // drifted value. `hsvToRgb` already rounds to whole channels at the end, so\n // precision is only needed in between. Every consumer of these floats (the\n // hue gradient, the thumb offsets, the hue slider) accepts them.\n return { h, s, v };\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n const ch = (n: number) =>\n Math.round(Math.max(0, Math.min(255, n)))\n .toString(16)\n .padStart(2, '0');\n return `#${ch(r)}${ch(g)}${ch(b)}`;\n}\n\nfunction hexToRgb(hex: string): RGBColor | null {\n const c = hex.trim().replace(/^#/, '');\n let r: number, g: number, b: number;\n\n if (c.length === 3) {\n r = parseInt(c[0] + c[0], 16);\n g = parseInt(c[1] + c[1], 16);\n b = parseInt(c[2] + c[2], 16);\n } else if (c.length === 6) {\n r = parseInt(c.slice(0, 2), 16);\n g = parseInt(c.slice(2, 4), 16);\n b = parseInt(c.slice(4, 6), 16);\n } else {\n return null;\n }\n\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { r, g, b };\n}\n\nfunction rgbToHsl(r: number, g: number, b: number): HSLColor {\n // r,g,b: 0–255 → h: 0–360, s: 0–100, l: 0–100\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n let s = 0;\n\n if (delta !== 0) {\n s = delta / (1 - Math.abs(2 * l - 1));\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = h * 60;\n if (h < 0) h += 360;\n }\n\n return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\nfunction hslToRgb(h: number, s: number, l: number): RGBColor {\n // h: 0–360, s: 0–100, l: 0–100 → r,g,b: 0–255\n const sn = s / 100;\n const ln = l / 100;\n const c = (1 - Math.abs(2 * ln - 1)) * sn;\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n const m = ln - c / 2;\n\n let r: number, g: number, b: number;\n if (h < 60) {\n r = c;\n g = x;\n b = 0;\n } else if (h < 120) {\n r = x;\n g = c;\n b = 0;\n } else if (h < 180) {\n r = 0;\n g = c;\n b = x;\n } else if (h < 240) {\n r = 0;\n g = x;\n b = c;\n } else if (h < 300) {\n r = x;\n g = 0;\n b = c;\n } else {\n r = c;\n g = 0;\n b = x;\n }\n\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\n// ============================================================================\n// Format helpers\n// ============================================================================\n\nfunction colorToText(hsv: HSVColor, alpha: number, fmt: ColorFormat): string {\n const rgb = hsvToRgb(hsv.h, hsv.s, hsv.v);\n\n switch (fmt) {\n case 'hex':\n return rgbToHex(rgb.r, rgb.g, rgb.b);\n case 'rgb':\n return alpha < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha.toFixed(2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n case 'hsl': {\n const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);\n return alpha < 1\n ? `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha.toFixed(2)})`\n : `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;\n }\n }\n}\n\nfunction parseColorText(text: string): RGBColor | null {\n const t = text.trim();\n\n // Try hex (with or without leading #)\n const hexCandidate = t.startsWith('#') ? t : /^[0-9a-f]{3,6}$/i.test(t) ? `#${t}` : null;\n if (hexCandidate) return hexToRgb(hexCandidate);\n\n // Try rgb() / rgba()\n const rgbMatch = t.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i);\n if (rgbMatch) {\n return {\n r: parseInt(rgbMatch[1], 10),\n g: parseInt(rgbMatch[2], 10),\n b: parseInt(rgbMatch[3], 10),\n };\n }\n\n // Try hsl() / hsla()\n const hslMatch = t.match(/hsla?\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?/i);\n if (hslMatch) {\n return hslToRgb(\n parseInt(hslMatch[1], 10),\n parseInt(hslMatch[2], 10),\n parseInt(hslMatch[3], 10),\n );\n }\n\n return null;\n}\n\n/** Parse a hex string to HSVColor, falling back to red on failure. */\nfunction hexToHsv(hex: string): HSVColor {\n const rgb = hexToRgb(hex);\n return rgb ? rgbToHsv(rgb.r, rgb.g, rgb.b) : { h: 0, s: 100, v: 100 };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({\n value,\n defaultValue,\n onChange,\n format = 'hex',\n showAlpha = false,\n showSwatches = true,\n swatches = DEFAULT_SWATCHES,\n disabled = false,\n size = 'md',\n inline = false,\n label,\n className = '',\n}) => {\n // ── Initial hex (only used on first render by useState) ──────────────────\n const initialHex = value ?? defaultValue ?? '#6366f1';\n\n // ── State ─────────────────────────────────────────────────────────────────\n const [hsv, setHsv] = useState<HSVColor>(() => hexToHsv(initialHex));\n const [alpha, setAlpha] = useState<number>(1);\n const [activeFormat, setActiveFormat] = useState<ColorFormat>(format);\n const [inputText, setInputText] = useState<string>(() =>\n colorToText(hexToHsv(initialHex), 1, format),\n );\n const [copied, setCopied] = useState(false);\n\n // ── Refs - give event handlers always-fresh values without stale closures ──\n const hsvRef = useRef<HSVColor>(hsv);\n hsvRef.current = hsv;\n\n const alphaRef = useRef<number>(alpha);\n alphaRef.current = alpha;\n\n const activeFormatRef = useRef<ColorFormat>(activeFormat);\n activeFormatRef.current = activeFormat;\n\n // onChange is stored in a ref so applyColor never becomes stale\n const onChangeRef = useRef<ColorPickerProps['onChange']>(onChange);\n onChangeRef.current = onChange;\n\n const inputFocusedRef = useRef(false);\n const canvasRef = useRef<HTMLDivElement>(null);\n\n // Refs for in-flight drag listeners - cleaned up on mouseup and on unmount\n const dragHandlersRef = useRef<{\n move: (e: MouseEvent) => void;\n up: () => void;\n } | null>(null);\n\n const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // ── Derived ───────────────────────────────────────────────────────────────\n const currentRgb = hsvToRgb(hsv.h, hsv.s, hsv.v);\n const currentHex = rgbToHex(currentRgb.r, currentRgb.g, currentRgb.b);\n\n // ── Sync from controlled `value` prop ─────────────────────────────────────\n // Runs only when `value` changes. We normalize both sides to the same\n // hex format before comparing so that round-trip conversions don't trigger\n // spurious updates (which would overwrite the preserved hue when s/v = 0).\n useEffect(() => {\n if (value === undefined) return;\n const rgb = hexToRgb(value);\n if (!rgb) return;\n const newHsv = rgbToHsv(rgb.r, rgb.g, rgb.b);\n const newNormalised = rgbToHex(\n ...(Object.values(hsvToRgb(newHsv.h, newHsv.s, newHsv.v)) as [number, number, number]),\n );\n // currentHex is captured from this render - guards against echo loops\n // when the parent echoes back our own onChange emission\n if (newNormalised === currentHex) return;\n setHsv(newHsv);\n if (!inputFocusedRef.current) {\n setInputText(colorToText(newHsv, alphaRef.current, activeFormatRef.current));\n }\n }, [value, currentHex]);\n\n // ── Cleanup drag listeners and timers on unmount ──────────────────────────\n useEffect(() => {\n return () => {\n if (dragHandlersRef.current) {\n document.removeEventListener('mousemove', dragHandlersRef.current.move);\n document.removeEventListener('mouseup', dragHandlersRef.current.up);\n }\n if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);\n };\n }, []);\n\n // ── Core: apply a new HSV + alpha, emit onChange ───────────────────────────\n // Stable (empty dep array) - reads live values exclusively via refs.\n const applyColor = useCallback((newHsv: HSVColor, newAlpha: number) => {\n setHsv(newHsv);\n setAlpha(newAlpha);\n\n if (!inputFocusedRef.current) {\n setInputText(colorToText(newHsv, newAlpha, activeFormatRef.current));\n }\n\n const rgb = hsvToRgb(newHsv.h, newHsv.s, newHsv.v);\n const hex = rgbToHex(rgb.r, rgb.g, rgb.b);\n onChangeRef.current?.(hex);\n }, []);\n\n // ── 2-D saturation / brightness canvas ────────────────────────────────────\n const handleCanvasMouseDown = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n\n const pick = (clientX: number, clientY: number) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const s = Math.max(0, Math.min(100, ((clientX - rect.left) / rect.width) * 100));\n const v = Math.max(0, Math.min(100, 100 - ((clientY - rect.top) / rect.height) * 100));\n applyColor({ h: hsvRef.current.h, s, v }, alphaRef.current);\n };\n\n pick(e.clientX, e.clientY);\n\n const handleMouseMove = (me: MouseEvent) => pick(me.clientX, me.clientY);\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n dragHandlersRef.current = null;\n };\n\n dragHandlersRef.current = { move: handleMouseMove, up: handleMouseUp };\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n },\n [disabled, applyColor],\n );\n\n // ── Hue slider ────────────────────────────────────────────────────────────\n const handleHueChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n applyColor({ ...hsvRef.current, h: Number(e.target.value) }, alphaRef.current);\n },\n [applyColor],\n );\n\n // ── Alpha slider ──────────────────────────────────────────────────────────\n const handleAlphaChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n applyColor(hsvRef.current, Number(e.target.value) / 100);\n },\n [applyColor],\n );\n\n // ── Format toggle ─────────────────────────────────────────────────────────\n const handleFormatChange = useCallback((fmt: ColorFormat) => {\n setActiveFormat(fmt);\n setInputText(colorToText(hsvRef.current, alphaRef.current, fmt));\n }, []);\n\n // ── Text-input commit (Enter / blur) ──────────────────────────────────────\n const handleInputCommit = useCallback(() => {\n const rgb = parseColorText(inputText);\n if (!rgb) {\n // Invalid - reset to the current valid colour\n setInputText(colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current));\n return;\n }\n const newHsv = rgbToHsv(rgb.r, rgb.g, rgb.b);\n applyColor(newHsv, alphaRef.current);\n // Always normalise the text after a commit (even if the input still has focus)\n setInputText(colorToText(newHsv, alphaRef.current, activeFormatRef.current));\n }, [inputText, applyColor]);\n\n // ── Swatch click ──────────────────────────────────────────────────────────\n const handleSwatchClick = useCallback(\n (hex: string) => {\n const rgb = hexToRgb(hex);\n if (!rgb) return;\n applyColor(rgbToHsv(rgb.r, rgb.g, rgb.b), alphaRef.current);\n },\n [applyColor],\n );\n\n // ── Copy to clipboard ─────────────────────────────────────────────────────\n const handleCopy = useCallback(() => {\n const text = colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current);\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);\n copiedTimerRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard access denied - silently ignore\n });\n }, []);\n\n // ── Alpha-slider background gradient ─────────────────────────────────────\n // We use a transparent-to-current-colour gradient layered over a checkerboard\n // so the alpha slider always shows the correct colour transition.\n const transparentColor = `rgba(${currentRgb.r}, ${currentRgb.g}, ${currentRgb.b}, 0)`;\n\n const alphaTrackBg = {\n backgroundImage: [\n `linear-gradient(to right, ${transparentColor}, ${currentHex})`,\n 'linear-gradient(45deg, #e2e8f0 25%, transparent 25%)',\n 'linear-gradient(-45deg, #e2e8f0 25%, transparent 25%)',\n 'linear-gradient(45deg, transparent 75%, #e2e8f0 75%)',\n 'linear-gradient(-45deg, transparent 75%, #e2e8f0 75%)',\n ].join(', '),\n backgroundSize: '100%, 8px 8px, 8px 8px, 8px 8px, 8px 8px',\n backgroundPosition: '0 0, 0 0, 0 4px, 4px -4px, -4px 0',\n };\n\n // ── Picker panel (shared between inline and popover modes) ────────────────\n //\n // The size modifier has to live on the panel itself, not only on the root:\n // in popover mode the panel is portaled to document.body by Dropdown, so\n // anything inside it that sized itself off a `.eidos-color-picker--{size}`\n // ancestor matched nothing and collapsed. That is what removed the\n // saturation/brightness canvas entirely from every non-inline picker.\n const panel = (\n <div\n className={`eidos-color-picker-panel eidos-color-picker-panel--${size}${\n inline ? ' eidos-color-picker-panel--inline' : ''\n }`}\n >\n {/* 2-D sat / brightness canvas */}\n <div\n ref={canvasRef}\n className=\"eidos-color-picker-canvas\"\n style={{\n background: [\n 'linear-gradient(to top, #000, transparent)',\n `linear-gradient(to right, #fff, hsl(${hsv.h}, 100%, 50%))`,\n ].join(', '),\n }}\n onMouseDown={handleCanvasMouseDown}\n role=\"presentation\"\n >\n <div\n className=\"eidos-color-picker-thumb\"\n style={{\n // Rounded for display only - hsv.s/v are unrounded floats so the\n // hex round trip stays lossless (see rgbToHsv).\n left: `${hsv.s.toFixed(2)}%`,\n top: `${(100 - hsv.v).toFixed(2)}%`,\n background: currentHex,\n }}\n />\n </div>\n\n {/* Sliders */}\n <div className=\"eidos-color-picker-sliders\">\n {/* Hue */}\n <input\n type=\"range\"\n className=\"eidos-color-picker-hue\"\n min={0}\n max={360}\n step={1}\n value={hsv.h}\n disabled={disabled}\n onChange={handleHueChange}\n aria-label=\"Hue\"\n />\n\n {/* Alpha */}\n {showAlpha && (\n <div className=\"eidos-color-picker-alpha-wrapper\">\n <div className=\"eidos-color-picker-alpha-bg\" style={alphaTrackBg} />\n <input\n type=\"range\"\n className=\"eidos-color-picker-alpha\"\n min={0}\n max={100}\n step={1}\n value={Math.round(alpha * 100)}\n disabled={disabled}\n onChange={handleAlphaChange}\n aria-label=\"Opacity\"\n />\n </div>\n )}\n </div>\n\n {/* Text input + format toggles + copy */}\n <div className=\"eidos-color-picker-inputs\">\n <div className=\"eidos-color-picker-format-btns\" role=\"group\" aria-label=\"Colour format\">\n {(['hex', 'rgb', 'hsl'] as ColorFormat[]).map((fmt) => (\n <button\n key={fmt}\n type=\"button\"\n className={[\n 'eidos-color-picker-format-btn',\n activeFormat === fmt && 'eidos-color-picker-format-btn--active',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => handleFormatChange(fmt)}\n disabled={disabled}\n aria-pressed={activeFormat === fmt}\n >\n {fmt.toUpperCase()}\n </button>\n ))}\n </div>\n\n <input\n type=\"text\"\n className=\"eidos-color-picker-input\"\n value={inputText}\n disabled={disabled}\n spellCheck={false}\n aria-label=\"Colour value\"\n onChange={(e) => setInputText(e.target.value)}\n onFocus={() => {\n inputFocusedRef.current = true;\n }}\n onBlur={() => {\n inputFocusedRef.current = false;\n handleInputCommit();\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleInputCommit();\n if (e.key === 'Escape') {\n setInputText(colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current));\n }\n }}\n />\n\n <button\n type=\"button\"\n className={['eidos-color-picker-copy', copied && 'eidos-color-picker-copy--copied']\n .filter(Boolean)\n .join(' ')}\n onClick={handleCopy}\n disabled={disabled}\n aria-label=\"Copy colour value\"\n title=\"Copy colour value\"\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n </div>\n\n {/* Swatches */}\n {showSwatches && (\n <div className=\"eidos-color-picker-swatches\" role=\"group\" aria-label=\"Colour presets\">\n {swatches.map((swatchHex) => (\n <button\n key={swatchHex}\n type=\"button\"\n className={[\n 'eidos-color-picker-swatch',\n currentHex === swatchHex && 'eidos-color-picker-swatch--active',\n ]\n .filter(Boolean)\n .join(' ')}\n style={{ background: swatchHex }}\n onClick={() => handleSwatchClick(swatchHex)}\n disabled={disabled}\n aria-label={`Select ${swatchHex}`}\n title={swatchHex}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // ── Root element classes ───────────────────────────────────────────────────\n const rootClasses = [\n 'eidos-color-picker',\n `eidos-color-picker--${size}`,\n disabled && 'eidos-color-picker--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n // ── Inline mode ───────────────────────────────────────────────────────────\n if (inline) {\n return (\n <div className={rootClasses}>\n {label && <span className=\"eidos-color-picker-label\">{label}</span>}\n {panel}\n </div>\n );\n }\n\n // ── Popover (trigger + Dropdown) ──────────────────────────────────────────\n return (\n <div className={rootClasses}>\n {label && <span className=\"eidos-color-picker-label\">{label}</span>}\n <Dropdown\n trigger={\n <button\n type=\"button\"\n className=\"eidos-color-picker-trigger\"\n disabled={disabled}\n aria-label={label ?? 'Open colour picker'}\n >\n <span\n className=\"eidos-color-picker-trigger-swatch\"\n style={{ background: currentHex }}\n />\n <span className=\"eidos-color-picker-trigger-value\">{currentHex}</span>\n </button>\n }\n content={panel}\n placement=\"bottom\"\n autoWidth={false}\n minWidth={260}\n disabled={disabled}\n />\n </div>\n );\n};\n\nColorPicker.displayName = 'ColorPicker';\n"]}
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-LVHZBCTA.cjs","../src/components/ColorPicker/ColorPicker.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-LVHZBCTA.cjs","sourcesContent":[null,"import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { Dropdown } from '../Dropdown/Dropdown.component';\nimport type {\n ColorPickerProps,\n HSVColor,\n RGBColor,\n HSLColor,\n ColorFormat,\n} from './ColorPicker.types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_SWATCHES: string[] = [\n '#ef4444',\n '#f97316',\n '#f59e0b',\n '#10b981',\n '#06b6d4',\n '#6366f1',\n '#8b5cf6',\n '#ec4899',\n '#64748b',\n '#1e293b',\n];\n\n// ============================================================================\n// Pure colour-utility functions\n// ============================================================================\n\nfunction hsvToRgb(h: number, s: number, v: number): RGBColor {\n // h: 0–360, s: 0–100, v: 0–100 → r,g,b: 0–255\n const sn = s / 100;\n const vn = v / 100;\n const c = vn * sn;\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n const m = vn - c;\n\n let r: number, g: number, b: number;\n if (h < 60) {\n r = c;\n g = x;\n b = 0;\n } else if (h < 120) {\n r = x;\n g = c;\n b = 0;\n } else if (h < 180) {\n r = 0;\n g = c;\n b = x;\n } else if (h < 240) {\n r = 0;\n g = x;\n b = c;\n } else if (h < 300) {\n r = x;\n g = 0;\n b = c;\n } else {\n r = c;\n g = 0;\n b = x;\n }\n\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\nfunction rgbToHsv(r: number, g: number, b: number): HSVColor {\n // r,g,b: 0–255 → h: 0–360, s: 0–100, v: 0–100\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n\n const v = max * 100;\n const s = max === 0 ? 0 : (delta / max) * 100;\n\n let h = 0;\n if (delta !== 0) {\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = h * 60;\n if (h < 0) h += 360;\n }\n\n // Deliberately NOT rounded. HSV is this component's internal state, and\n // rounding s/v to whole percent makes the hex -> HSV -> hex round trip lossy:\n // `#5c5de8` came back as `#5d5de8`, so a controlled `value` displayed a\n // different colour than the one passed in, and any interaction committed the\n // drifted value. `hsvToRgb` already rounds to whole channels at the end, so\n // precision is only needed in between. Every consumer of these floats (the\n // hue gradient, the thumb offsets, the hue slider) accepts them.\n return { h, s, v };\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n const ch = (n: number) =>\n Math.round(Math.max(0, Math.min(255, n)))\n .toString(16)\n .padStart(2, '0');\n return `#${ch(r)}${ch(g)}${ch(b)}`;\n}\n\nfunction hexToRgb(hex: string): RGBColor | null {\n const c = hex.trim().replace(/^#/, '');\n let r: number, g: number, b: number;\n\n if (c.length === 3) {\n r = parseInt(c[0] + c[0], 16);\n g = parseInt(c[1] + c[1], 16);\n b = parseInt(c[2] + c[2], 16);\n } else if (c.length === 6) {\n r = parseInt(c.slice(0, 2), 16);\n g = parseInt(c.slice(2, 4), 16);\n b = parseInt(c.slice(4, 6), 16);\n } else {\n return null;\n }\n\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { r, g, b };\n}\n\nfunction rgbToHsl(r: number, g: number, b: number): HSLColor {\n // r,g,b: 0–255 → h: 0–360, s: 0–100, l: 0–100\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n let s = 0;\n\n if (delta !== 0) {\n s = delta / (1 - Math.abs(2 * l - 1));\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = h * 60;\n if (h < 0) h += 360;\n }\n\n return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\nfunction hslToRgb(h: number, s: number, l: number): RGBColor {\n // h: 0–360, s: 0–100, l: 0–100 → r,g,b: 0–255\n const sn = s / 100;\n const ln = l / 100;\n const c = (1 - Math.abs(2 * ln - 1)) * sn;\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n const m = ln - c / 2;\n\n let r: number, g: number, b: number;\n if (h < 60) {\n r = c;\n g = x;\n b = 0;\n } else if (h < 120) {\n r = x;\n g = c;\n b = 0;\n } else if (h < 180) {\n r = 0;\n g = c;\n b = x;\n } else if (h < 240) {\n r = 0;\n g = x;\n b = c;\n } else if (h < 300) {\n r = x;\n g = 0;\n b = c;\n } else {\n r = c;\n g = 0;\n b = x;\n }\n\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\n// ============================================================================\n// Format helpers\n// ============================================================================\n\nfunction colorToText(hsv: HSVColor, alpha: number, fmt: ColorFormat): string {\n const rgb = hsvToRgb(hsv.h, hsv.s, hsv.v);\n\n switch (fmt) {\n case 'hex':\n return rgbToHex(rgb.r, rgb.g, rgb.b);\n case 'rgb':\n return alpha < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha.toFixed(2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n case 'hsl': {\n const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);\n return alpha < 1\n ? `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha.toFixed(2)})`\n : `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;\n }\n }\n}\n\nfunction parseColorText(text: string): RGBColor | null {\n const t = text.trim();\n\n // Try hex (with or without leading #)\n const hexCandidate = t.startsWith('#') ? t : /^[0-9a-f]{3,6}$/i.test(t) ? `#${t}` : null;\n if (hexCandidate) return hexToRgb(hexCandidate);\n\n // Try rgb() / rgba()\n const rgbMatch = t.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i);\n if (rgbMatch) {\n return {\n r: parseInt(rgbMatch[1], 10),\n g: parseInt(rgbMatch[2], 10),\n b: parseInt(rgbMatch[3], 10),\n };\n }\n\n // Try hsl() / hsla()\n const hslMatch = t.match(/hsla?\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?/i);\n if (hslMatch) {\n return hslToRgb(\n parseInt(hslMatch[1], 10),\n parseInt(hslMatch[2], 10),\n parseInt(hslMatch[3], 10),\n );\n }\n\n return null;\n}\n\n/** Parse a hex string to HSVColor, falling back to red on failure. */\nfunction hexToHsv(hex: string): HSVColor {\n const rgb = hexToRgb(hex);\n return rgb ? rgbToHsv(rgb.r, rgb.g, rgb.b) : { h: 0, s: 100, v: 100 };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({\n value,\n defaultValue,\n onChange,\n format = 'hex',\n showAlpha = false,\n showSwatches = true,\n swatches = DEFAULT_SWATCHES,\n disabled = false,\n size = 'md',\n inline = false,\n label,\n className = '',\n}) => {\n // ── Initial hex (only used on first render by useState) ──────────────────\n const initialHex = value ?? defaultValue ?? '#6366f1';\n\n // ── State ─────────────────────────────────────────────────────────────────\n const [hsv, setHsv] = useState<HSVColor>(() => hexToHsv(initialHex));\n const [alpha, setAlpha] = useState<number>(1);\n const [activeFormat, setActiveFormat] = useState<ColorFormat>(format);\n const [inputText, setInputText] = useState<string>(() =>\n colorToText(hexToHsv(initialHex), 1, format),\n );\n const [copied, setCopied] = useState(false);\n\n // ── Refs - give event handlers always-fresh values without stale closures ──\n const hsvRef = useRef<HSVColor>(hsv);\n hsvRef.current = hsv;\n\n const alphaRef = useRef<number>(alpha);\n alphaRef.current = alpha;\n\n const activeFormatRef = useRef<ColorFormat>(activeFormat);\n activeFormatRef.current = activeFormat;\n\n // onChange is stored in a ref so applyColor never becomes stale\n const onChangeRef = useRef<ColorPickerProps['onChange']>(onChange);\n onChangeRef.current = onChange;\n\n const inputFocusedRef = useRef(false);\n const canvasRef = useRef<HTMLDivElement>(null);\n\n // Refs for in-flight drag listeners - cleaned up on mouseup and on unmount\n const dragHandlersRef = useRef<{\n move: (e: MouseEvent) => void;\n up: () => void;\n } | null>(null);\n\n const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // ── Derived ───────────────────────────────────────────────────────────────\n const currentRgb = hsvToRgb(hsv.h, hsv.s, hsv.v);\n const currentHex = rgbToHex(currentRgb.r, currentRgb.g, currentRgb.b);\n\n // ── Sync from controlled `value` prop ─────────────────────────────────────\n // Runs only when `value` changes. We normalize both sides to the same\n // hex format before comparing so that round-trip conversions don't trigger\n // spurious updates (which would overwrite the preserved hue when s/v = 0).\n useEffect(() => {\n if (value === undefined) return;\n const rgb = hexToRgb(value);\n if (!rgb) return;\n const newHsv = rgbToHsv(rgb.r, rgb.g, rgb.b);\n const newNormalised = rgbToHex(\n ...(Object.values(hsvToRgb(newHsv.h, newHsv.s, newHsv.v)) as [number, number, number]),\n );\n // currentHex is captured from this render - guards against echo loops\n // when the parent echoes back our own onChange emission\n if (newNormalised === currentHex) return;\n setHsv(newHsv);\n if (!inputFocusedRef.current) {\n setInputText(colorToText(newHsv, alphaRef.current, activeFormatRef.current));\n }\n }, [value, currentHex]);\n\n // ── Cleanup drag listeners and timers on unmount ──────────────────────────\n useEffect(() => {\n return () => {\n if (dragHandlersRef.current) {\n document.removeEventListener('mousemove', dragHandlersRef.current.move);\n document.removeEventListener('mouseup', dragHandlersRef.current.up);\n }\n if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);\n };\n }, []);\n\n // ── Core: apply a new HSV + alpha, emit onChange ───────────────────────────\n // Stable (empty dep array) - reads live values exclusively via refs.\n const applyColor = useCallback((newHsv: HSVColor, newAlpha: number) => {\n setHsv(newHsv);\n setAlpha(newAlpha);\n\n if (!inputFocusedRef.current) {\n setInputText(colorToText(newHsv, newAlpha, activeFormatRef.current));\n }\n\n const rgb = hsvToRgb(newHsv.h, newHsv.s, newHsv.v);\n const hex = rgbToHex(rgb.r, rgb.g, rgb.b);\n onChangeRef.current?.(hex);\n }, []);\n\n // ── 2-D saturation / brightness canvas ────────────────────────────────────\n const handleCanvasMouseDown = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n\n const pick = (clientX: number, clientY: number) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const s = Math.max(0, Math.min(100, ((clientX - rect.left) / rect.width) * 100));\n const v = Math.max(0, Math.min(100, 100 - ((clientY - rect.top) / rect.height) * 100));\n applyColor({ h: hsvRef.current.h, s, v }, alphaRef.current);\n };\n\n pick(e.clientX, e.clientY);\n\n const handleMouseMove = (me: MouseEvent) => pick(me.clientX, me.clientY);\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n dragHandlersRef.current = null;\n };\n\n dragHandlersRef.current = { move: handleMouseMove, up: handleMouseUp };\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n },\n [disabled, applyColor],\n );\n\n // ── Hue slider ────────────────────────────────────────────────────────────\n const handleHueChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n applyColor({ ...hsvRef.current, h: Number(e.target.value) }, alphaRef.current);\n },\n [applyColor],\n );\n\n // ── Alpha slider ──────────────────────────────────────────────────────────\n const handleAlphaChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n applyColor(hsvRef.current, Number(e.target.value) / 100);\n },\n [applyColor],\n );\n\n // ── Format toggle ─────────────────────────────────────────────────────────\n const handleFormatChange = useCallback((fmt: ColorFormat) => {\n setActiveFormat(fmt);\n setInputText(colorToText(hsvRef.current, alphaRef.current, fmt));\n }, []);\n\n // ── Text-input commit (Enter / blur) ──────────────────────────────────────\n const handleInputCommit = useCallback(() => {\n const rgb = parseColorText(inputText);\n if (!rgb) {\n // Invalid - reset to the current valid colour\n setInputText(colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current));\n return;\n }\n const newHsv = rgbToHsv(rgb.r, rgb.g, rgb.b);\n applyColor(newHsv, alphaRef.current);\n // Always normalise the text after a commit (even if the input still has focus)\n setInputText(colorToText(newHsv, alphaRef.current, activeFormatRef.current));\n }, [inputText, applyColor]);\n\n // ── Swatch click ──────────────────────────────────────────────────────────\n const handleSwatchClick = useCallback(\n (hex: string) => {\n const rgb = hexToRgb(hex);\n if (!rgb) return;\n applyColor(rgbToHsv(rgb.r, rgb.g, rgb.b), alphaRef.current);\n },\n [applyColor],\n );\n\n // ── Copy to clipboard ─────────────────────────────────────────────────────\n const handleCopy = useCallback(() => {\n const text = colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current);\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);\n copiedTimerRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard access denied - silently ignore\n });\n }, []);\n\n // ── Alpha-slider background gradient ─────────────────────────────────────\n // We use a transparent-to-current-colour gradient layered over a checkerboard\n // so the alpha slider always shows the correct colour transition.\n const transparentColor = `rgba(${currentRgb.r}, ${currentRgb.g}, ${currentRgb.b}, 0)`;\n\n const alphaTrackBg = {\n backgroundImage: [\n `linear-gradient(to right, ${transparentColor}, ${currentHex})`,\n 'linear-gradient(45deg, #e2e8f0 25%, transparent 25%)',\n 'linear-gradient(-45deg, #e2e8f0 25%, transparent 25%)',\n 'linear-gradient(45deg, transparent 75%, #e2e8f0 75%)',\n 'linear-gradient(-45deg, transparent 75%, #e2e8f0 75%)',\n ].join(', '),\n backgroundSize: '100%, 8px 8px, 8px 8px, 8px 8px, 8px 8px',\n backgroundPosition: '0 0, 0 0, 0 4px, 4px -4px, -4px 0',\n };\n\n // ── Picker panel (shared between inline and popover modes) ────────────────\n //\n // The size modifier has to live on the panel itself, not only on the root:\n // in popover mode the panel is portaled to document.body by Dropdown, so\n // anything inside it that sized itself off a `.eidos-color-picker--{size}`\n // ancestor matched nothing and collapsed. That is what removed the\n // saturation/brightness canvas entirely from every non-inline picker.\n const panel = (\n <div\n className={`eidos-color-picker-panel eidos-color-picker-panel--${size}${\n inline ? ' eidos-color-picker-panel--inline' : ''\n }`}\n >\n {/* 2-D sat / brightness canvas */}\n <div\n ref={canvasRef}\n className=\"eidos-color-picker-canvas\"\n style={{\n background: [\n 'linear-gradient(to top, #000, transparent)',\n `linear-gradient(to right, #fff, hsl(${hsv.h}, 100%, 50%))`,\n ].join(', '),\n }}\n onMouseDown={handleCanvasMouseDown}\n role=\"presentation\"\n >\n <div\n className=\"eidos-color-picker-thumb\"\n style={{\n // Rounded for display only - hsv.s/v are unrounded floats so the\n // hex round trip stays lossless (see rgbToHsv).\n left: `${hsv.s.toFixed(2)}%`,\n top: `${(100 - hsv.v).toFixed(2)}%`,\n background: currentHex,\n }}\n />\n </div>\n\n {/* Sliders */}\n <div className=\"eidos-color-picker-sliders\">\n {/* Hue */}\n <input\n type=\"range\"\n className=\"eidos-color-picker-hue\"\n min={0}\n max={360}\n step={1}\n value={hsv.h}\n disabled={disabled}\n onChange={handleHueChange}\n aria-label=\"Hue\"\n />\n\n {/* Alpha */}\n {showAlpha && (\n <div className=\"eidos-color-picker-alpha-wrapper\">\n <div className=\"eidos-color-picker-alpha-bg\" style={alphaTrackBg} />\n <input\n type=\"range\"\n className=\"eidos-color-picker-alpha\"\n min={0}\n max={100}\n step={1}\n value={Math.round(alpha * 100)}\n disabled={disabled}\n onChange={handleAlphaChange}\n aria-label=\"Opacity\"\n />\n </div>\n )}\n </div>\n\n {/* Text input + format toggles + copy */}\n <div className=\"eidos-color-picker-inputs\">\n <div className=\"eidos-color-picker-format-btns\" role=\"group\" aria-label=\"Colour format\">\n {(['hex', 'rgb', 'hsl'] as ColorFormat[]).map((fmt) => (\n <button\n key={fmt}\n type=\"button\"\n className={[\n 'eidos-color-picker-format-btn',\n activeFormat === fmt && 'eidos-color-picker-format-btn--active',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => handleFormatChange(fmt)}\n disabled={disabled}\n aria-pressed={activeFormat === fmt}\n >\n {fmt.toUpperCase()}\n </button>\n ))}\n </div>\n\n <input\n type=\"text\"\n className=\"eidos-color-picker-input\"\n value={inputText}\n disabled={disabled}\n spellCheck={false}\n aria-label=\"Colour value\"\n onChange={(e) => setInputText(e.target.value)}\n onFocus={() => {\n inputFocusedRef.current = true;\n }}\n onBlur={() => {\n inputFocusedRef.current = false;\n handleInputCommit();\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleInputCommit();\n if (e.key === 'Escape') {\n setInputText(colorToText(hsvRef.current, alphaRef.current, activeFormatRef.current));\n }\n }}\n />\n\n <button\n type=\"button\"\n className={['eidos-color-picker-copy', copied && 'eidos-color-picker-copy--copied']\n .filter(Boolean)\n .join(' ')}\n onClick={handleCopy}\n disabled={disabled}\n aria-label=\"Copy colour value\"\n title=\"Copy colour value\"\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n </div>\n\n {/* Swatches */}\n {showSwatches && (\n <div className=\"eidos-color-picker-swatches\" role=\"group\" aria-label=\"Colour presets\">\n {swatches.map((swatchHex) => (\n <button\n key={swatchHex}\n type=\"button\"\n className={[\n 'eidos-color-picker-swatch',\n currentHex === swatchHex && 'eidos-color-picker-swatch--active',\n ]\n .filter(Boolean)\n .join(' ')}\n style={{ background: swatchHex }}\n onClick={() => handleSwatchClick(swatchHex)}\n disabled={disabled}\n aria-label={`Select ${swatchHex}`}\n title={swatchHex}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // ── Root element classes ───────────────────────────────────────────────────\n const rootClasses = [\n 'eidos-color-picker',\n `eidos-color-picker--${size}`,\n disabled && 'eidos-color-picker--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n // ── Inline mode ───────────────────────────────────────────────────────────\n if (inline) {\n return (\n <div className={rootClasses}>\n {label && <span className=\"eidos-color-picker-label\">{label}</span>}\n {panel}\n </div>\n );\n }\n\n // ── Popover (trigger + Dropdown) ──────────────────────────────────────────\n return (\n <div className={rootClasses}>\n {label && <span className=\"eidos-color-picker-label\">{label}</span>}\n <Dropdown\n trigger={\n <button\n type=\"button\"\n className=\"eidos-color-picker-trigger\"\n disabled={disabled}\n aria-label={label ?? 'Open colour picker'}\n >\n <span\n className=\"eidos-color-picker-trigger-swatch\"\n style={{ background: currentHex }}\n />\n <span className=\"eidos-color-picker-trigger-value\">{currentHex}</span>\n </button>\n }\n content={panel}\n placement=\"bottom\"\n autoWidth={false}\n minWidth={260}\n disabled={disabled}\n />\n </div>\n );\n};\n\nColorPicker.displayName = 'ColorPicker';\n"]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ fullWidthModifier
3
+ } from "./chunk-EAJHEYZM.js";
4
+
1
5
  // src/components/NumberInput/NumberInput.component.tsx
2
6
  import { forwardRef, useState, useEffect, useId } from "react";
3
7
  import { Minus, Plus } from "lucide-react";
@@ -95,7 +99,7 @@ var NumberInput = forwardRef(
95
99
  const rootClasses = [
96
100
  "eidos-number-input",
97
101
  `eidos-number-input--${size}`,
98
- fullWidth && "eidos-number-input--fullWidth",
102
+ fullWidth && fullWidthModifier("eidos-number-input"),
99
103
  error && "eidos-number-input--error",
100
104
  className
101
105
  ].filter(Boolean).join(" ");
@@ -196,4 +200,4 @@ NumberInput.displayName = "NumberInput";
196
200
  export {
197
201
  NumberInput
198
202
  };
199
- //# sourceMappingURL=chunk-SENVA467.js.map
203
+ //# sourceMappingURL=chunk-M7PF4FKQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/NumberInput/NumberInput.component.tsx"],"sourcesContent":["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\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-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 className=\"eidos-number-input-error\" role=\"alert\">\n {errorMessage}\n </span>\n )}\n </div>\n );\n },\n);\n\nNumberInput.displayName = 'NumberInput';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,145 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunk3E7TKBQIcjs = require('./chunk-3E7TKBQI.cjs');
4
+
5
+
6
+ var _chunkQ3GNKF74cjs = require('./chunk-Q3GNKF74.cjs');
7
+
8
+
9
+ var _chunkWWYJNWJYcjs = require('./chunk-WWYJNWJY.cjs');
10
+
11
+
12
+
13
+ var _chunkCUJBNRJJcjs = require('./chunk-CUJBNRJJ.cjs');
14
+
15
+ // src/components/Header/Header.component.tsx
16
+ var _react = require('react');
17
+ var _jsxruntime = require('react/jsx-runtime');
18
+ var Header = ({
19
+ title,
20
+ subtitle,
21
+ media,
22
+ meta,
23
+ variant = "default",
24
+ actions,
25
+ collapseActionsBelow = 640,
26
+ actionsVisibleWhenCollapsed = 1,
27
+ className = ""
28
+ }) => {
29
+ const classes = ["eidos-header", `eidos-header--${variant}`, className].filter(Boolean).join(" ");
30
+ const rootRef = _react.useRef.call(void 0, null);
31
+ const [isNarrow, setIsNarrow] = _react.useState.call(void 0, false);
32
+ const [overflowOpen, setOverflowOpen] = _react.useState.call(void 0, false);
33
+ const measure = _react.useCallback.call(void 0, () => {
34
+ const element = rootRef.current;
35
+ if (!element) return;
36
+ setIsNarrow(element.getBoundingClientRect().width <= collapseActionsBelow);
37
+ }, [collapseActionsBelow]);
38
+ _react.useLayoutEffect.call(void 0, () => {
39
+ if (!collapseActionsBelow) {
40
+ setIsNarrow(false);
41
+ return;
42
+ }
43
+ measure();
44
+ const element = rootRef.current;
45
+ if (!element || typeof ResizeObserver === "undefined") return;
46
+ const observer = new ResizeObserver(measure);
47
+ observer.observe(element);
48
+ return () => observer.disconnect();
49
+ }, [collapseActionsBelow, measure]);
50
+ const allActions = _nullishCoalesce(actions, () => ( []));
51
+ const keptCount = Math.max(0, actionsVisibleWhenCollapsed);
52
+ const isCollapsed = isNarrow && !!collapseActionsBelow && allActions.length > keptCount;
53
+ const overflowActions = isCollapsed ? allActions.slice(0, allActions.length - keptCount) : [];
54
+ const inlineActions = isCollapsed ? allActions.slice(allActions.length - keptCount) : allActions;
55
+ _react.useEffect.call(void 0, () => {
56
+ if (!isCollapsed && overflowOpen) setOverflowOpen(false);
57
+ }, [isCollapsed, overflowOpen]);
58
+ const renderOverflowAction = (action, index) => {
59
+ const handleClick = (event) => {
60
+ _optionalChain([action, 'access', _ => _.onClick, 'optionalCall', _2 => _2(event)]);
61
+ setOverflowOpen(false);
62
+ };
63
+ if (action.icon && !action.children && action.tooltip) {
64
+ const { icon, tooltip, ...rest } = action;
65
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { ...rest, size: "md", preIcon: icon, onClick: handleClick, children: tooltip }, index);
66
+ }
67
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { ...action, size: "md", onClick: handleClick }, index);
68
+ };
69
+ const titles = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-header__titles", children: [
70
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "eidos-header__title", children: title }),
71
+ subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-header__subtitle", children: subtitle }),
72
+ !!_optionalChain([meta, 'optionalAccess', _3 => _3.length]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-header__meta", children: meta.map((item, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "eidos-header__meta-item", children: [
73
+ item.icon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, item.icon, "eidos-header__meta-icon"),
74
+ item.label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-header__meta-label", children: item.label }),
75
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-header__meta-value", children: item.value })
76
+ ] }, index)) })
77
+ ] });
78
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: classes, ref: rootRef, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-header__content", children: [
79
+ media ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-header__lead", children: [
80
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-header__media", children: media }),
81
+ titles
82
+ ] }) : titles,
83
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-header__actions", children: [
84
+ overflowActions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
85
+ _chunk3E7TKBQIcjs.Popover,
86
+ {
87
+ isOpen: overflowOpen,
88
+ onOpenChange: setOverflowOpen,
89
+ placement: "bottom",
90
+ maxWidth: 260,
91
+ className: "eidos-header__overflow-trigger",
92
+ trigger: (
93
+ // No `aria-haspopup`/`aria-expanded` here: Popover already
94
+ // sets both on the wrapper it renders around this button.
95
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
96
+ _chunkWWYJNWJYcjs.Button,
97
+ {
98
+ icon: "ellipsis",
99
+ size: "md",
100
+ variant: "outlined",
101
+ color: "secondary",
102
+ "aria-label": `${overflowActions.length} more actions`
103
+ }
104
+ )
105
+ ),
106
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-header__overflow-actions", children: overflowActions.map(renderOverflowAction) })
107
+ }
108
+ ),
109
+ inlineActions.map((action, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { size: "md", ...action }, index))
110
+ ] })
111
+ ] }) });
112
+ };
113
+
114
+ // src/components/Header/IdentityHeader.component.tsx
115
+
116
+ var IdentityHeader = ({
117
+ avatar,
118
+ media,
119
+ variant = "hero",
120
+ className = "",
121
+ ...rest
122
+ }) => {
123
+ if (avatar && media) {
124
+ _chunkCUJBNRJJcjs.devWarn.call(void 0,
125
+ "identity-header-avatar-and-media",
126
+ "IdentityHeader received both `avatar` and `media`. `media` takes precedence - drop `avatar` to silence this."
127
+ );
128
+ }
129
+ const resolvedMedia = _nullishCoalesce(media, () => ( (avatar ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQ3GNKF74cjs.Avatar, { size: "lg", ...avatar }) : void 0)));
130
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
131
+ Header,
132
+ {
133
+ ...rest,
134
+ variant,
135
+ media: resolvedMedia,
136
+ className: ["eidos-identity-header", className].filter(Boolean).join(" ")
137
+ }
138
+ );
139
+ };
140
+
141
+
142
+
143
+
144
+ exports.Header = Header; exports.IdentityHeader = IdentityHeader;
145
+ //# sourceMappingURL=chunk-ND526PMG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-ND526PMG.cjs","../src/components/Header/Header.component.tsx","../src/components/Header/IdentityHeader.component.tsx"],"names":["jsx"],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACdA,8BAAiF;AAsFzE,+CAAA;AA/ED,IAAM,OAAA,EAAgC,CAAC;AAAA,EAC5C,KAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,EAAU,SAAA;AAAA,EACV,OAAA;AAAA,EACA,qBAAA,EAAuB,GAAA;AAAA,EACvB,4BAAA,EAA8B,CAAA;AAAA,EAC9B,UAAA,EAAY;AACd,CAAA,EAAA,GAAM;AACJ,EAAA,MAAM,QAAA,EAAU,CAAC,cAAA,EAAgB,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAA;AAEd,EAAA;AACG,EAAA;AACQ,EAAA;AASpB,EAAA;AACR,IAAA;AACV,IAAA;AACuC,IAAA;AAC9B,EAAA;AAQH,EAAA;AACO,IAAA;AACR,MAAA;AACjB,MAAA;AACF,IAAA;AAEQ,IAAA;AAEgB,IAAA;AAC+B,IAAA;AAEZ,IAAA;AACnB,IAAA;AACS,IAAA;AACD,EAAA;AAEH,EAAA;AAC0B,EAAA;AACC,EAAA;AAIA,EAAA;AACL,EAAA;AAIrC,EAAA;AACyC,IAAA;AAC3B,EAAA;AAE6C,EAAA;AACZ,IAAA;AACrC,sBAAA;AACD,MAAA;AACvB,IAAA;AAKuD,IAAA;AAClB,MAAA;AAEE,MAAA;AAIvC,IAAA;AAE4C,IAAA;AAC9C,EAAA;AAGiB,EAAA;AACC,oBAAA;AACe,IAAA;AAEtB,IAAA;AAGqC,MAAA;AACf,MAAA;AACL,sBAAA;AAGtB,IAAA;AAEJ,EAAA;AAIyB,EAAA;AASJ,IAAA;AACE,sBAAA;AACd,MAAA;AAGH,IAAA;AAEa,oBAAA;AAEX,MAAA;AAAC,QAAA;AAAA,QAAA;AACS,UAAA;AACM,UAAA;AACJ,UAAA;AACA,UAAA;AAGA,UAAA;AACV,UAAA;AAAA;AAAA;AAGE,4BAAA;AAAC,cAAA;AAAA,cAAA;AACM,gBAAA;AACA,gBAAA;AACG,gBAAA;AACF,gBAAA;AAC+B,gBAAA;AAAA,cAAA;AACvC,YAAA;AAAA,UAAA;AAGa,UAAA;AAEf,QAAA;AACF,MAAA;AAGA,MAAA;AAEJ,IAAA;AAEJ,EAAA;AAEJ;ADpD4D;AACA;AEnFjB;AAdmB;AAC5D,EAAA;AACA,EAAA;AACU,EAAA;AACE,EAAA;AACT,EAAA;AACC;AACiB,EAAA;AACnB,IAAA;AACE,MAAA;AACA,MAAA;AACF,IAAA;AACF,EAAA;AAEyCA,EAAAA;AAGvCA,EAAAA;AAAC,IAAA;AAAA,IAAA;AACK,MAAA;AACJ,MAAA;AACO,MAAA;AACyC,MAAA;AAAwB,IAAA;AAC1E,EAAA;AAEJ;AFmG4D;AACA;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-ND526PMG.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport type { HeaderActionProps, HeaderProps } from './Header.types';\nimport './Header.scss';\nimport { Button } from '../Button';\nimport { Popover } from '../Popover';\nimport { renderIcon } from '../../utils';\n\nexport const Header: React.FC<HeaderProps> = ({\n title,\n subtitle,\n media,\n meta,\n variant = 'default',\n actions,\n collapseActionsBelow = 640,\n actionsVisibleWhenCollapsed = 1,\n className = '',\n}) => {\n const classes = ['eidos-header', `eidos-header--${variant}`, className].filter(Boolean).join(' ');\n\n const rootRef = useRef<HTMLDivElement>(null);\n const [isNarrow, setIsNarrow] = useState(false);\n const [overflowOpen, setOverflowOpen] = useState(false);\n\n // Measures the header's own box rather than the viewport, so the collapse\n // point matches the container queries in Header.scss - a viewport query\n // would disagree with them by the width of PageLayout's navigation rail,\n // which is itself collapsible. The 1px hero border makes this border-box\n // reading differ from the container query's content-box one by 2px; that is\n // far below any threshold worth caring about, and using one measurement for\n // both the initial pass and the observer keeps it to a single code path.\n const measure = useCallback(() => {\n const element = rootRef.current;\n if (!element) return;\n setIsNarrow(element.getBoundingClientRect().width <= collapseActionsBelow);\n }, [collapseActionsBelow]);\n\n // `useLayoutEffect` for the first measurement specifically: ResizeObserver\n // delivers its initial callback asynchronously, so relying on it alone\n // would paint the full action row for a frame before collapsing it. Reading\n // the box synchronously here collapses before paint instead. Nothing runs\n // during SSR, so the server renders the uncollapsed row and hydration\n // matches - the same client-only posture Navigation's `collapseBelow` has.\n useLayoutEffect(() => {\n if (!collapseActionsBelow) {\n setIsNarrow(false);\n return;\n }\n\n measure();\n\n const element = rootRef.current;\n if (!element || typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [collapseActionsBelow, measure]);\n\n const allActions = actions ?? [];\n const keptCount = Math.max(0, actionsVisibleWhenCollapsed);\n const isCollapsed = isNarrow && !!collapseActionsBelow && allActions.length > keptCount;\n\n // The *last* actions stay inline: a primary call to action is conventionally\n // rightmost, which is also how Header's own stories order them.\n const overflowActions = isCollapsed ? allActions.slice(0, allActions.length - keptCount) : [];\n const inlineActions = isCollapsed ? allActions.slice(allActions.length - keptCount) : allActions;\n\n // A portalled popover would otherwise stay on screen after the header grows\n // back past the threshold and its trigger stops being rendered.\n useEffect(() => {\n if (!isCollapsed && overflowOpen) setOverflowOpen(false);\n }, [isCollapsed, overflowOpen]);\n\n const renderOverflowAction = (action: HeaderActionProps, index: number) => {\n const handleClick: HeaderActionProps['onClick'] = (event) => {\n action.onClick?.(event);\n setOverflowOpen(false);\n };\n\n // An icon-only action has no visible label, which is fine in a horizontal\n // row of small buttons and useless in a vertical list. Its tooltip is\n // already the label, so promote it rather than showing a bare glyph.\n if (action.icon && !action.children && action.tooltip) {\n const { icon, tooltip, ...rest } = action;\n return (\n <Button key={index} {...rest} size=\"md\" preIcon={icon} onClick={handleClick}>\n {tooltip}\n </Button>\n );\n }\n\n return <Button key={index} {...action} size=\"md\" onClick={handleClick} />;\n };\n\n const titles = (\n <div className=\"eidos-header__titles\">\n <h1 className=\"eidos-header__title\">{title}</h1>\n {subtitle && <span className=\"eidos-header__subtitle\">{subtitle}</span>}\n {!!meta?.length && (\n <div className=\"eidos-header__meta\">\n {meta.map((item, index) => (\n <span key={index} className=\"eidos-header__meta-item\">\n {item.icon && renderIcon(item.icon, 'eidos-header__meta-icon')}\n {item.label && <span className=\"eidos-header__meta-label\">{item.label}</span>}\n <span className=\"eidos-header__meta-value\">{item.value}</span>\n </span>\n ))}\n </div>\n )}\n </div>\n );\n\n return (\n <div className={classes} ref={rootRef}>\n <div className=\"eidos-header__content\">\n {/* The `__lead` wrapper only exists when there is media to group with\n the titles. Media and titles need a tighter gap than titles and\n actions do, and a flex container has a single gap - but rendering\n the wrapper unconditionally would change the markup for every\n existing consumer, and the `eidos-*` class names are documented as\n targetable. */}\n {media ? (\n <div className=\"eidos-header__lead\">\n <div className=\"eidos-header__media\">{media}</div>\n {titles}\n </div>\n ) : (\n titles\n )}\n <div className=\"eidos-header__actions\">\n {overflowActions.length > 0 && (\n <Popover\n isOpen={overflowOpen}\n onOpenChange={setOverflowOpen}\n placement=\"bottom\"\n maxWidth={260}\n // Popover puts `className` on its trigger wrapper, which is the\n // element that actually becomes a flex item of `__actions`.\n className=\"eidos-header__overflow-trigger\"\n trigger={\n // No `aria-haspopup`/`aria-expanded` here: Popover already\n // sets both on the wrapper it renders around this button.\n <Button\n icon=\"ellipsis\"\n size=\"md\"\n variant=\"outlined\"\n color=\"secondary\"\n aria-label={`${overflowActions.length} more actions`}\n />\n }\n >\n <div className=\"eidos-header__overflow-actions\">\n {overflowActions.map(renderOverflowAction)}\n </div>\n </Popover>\n )}\n {inlineActions.map((action, index) => (\n <Button key={index} size=\"md\" {...action} />\n ))}\n </div>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { IdentityHeaderProps } from './IdentityHeader.types';\nimport { Header } from './Header.component';\nimport { Avatar } from '../Avatar';\nimport { devWarn } from '../../utils';\n\n/**\n * `Header` preconfigured for the \"this page is about one person or entity\"\n * shape - an avatar beside the name, supporting facts below it, actions on\n * the end - which account and profile pages share. Settings-style pages want\n * a plain `Header` instead; they have no identity to lead with.\n *\n * Deliberately thin: it pins `variant=\"hero\"`, types the avatar so consumers\n * don't have to import `Avatar` to fill the slot, and gives the shape a name\n * worth discovering. Everything else is `Header`.\n */\nexport const IdentityHeader: React.FC<IdentityHeaderProps> = ({\n avatar,\n media,\n variant = 'hero',\n className = '',\n ...rest\n}) => {\n if (avatar && media) {\n devWarn(\n 'identity-header-avatar-and-media',\n 'IdentityHeader received both `avatar` and `media`. `media` takes precedence - drop `avatar` to silence this.',\n );\n }\n\n const resolvedMedia = media ?? (avatar ? <Avatar size=\"lg\" {...avatar} /> : undefined);\n\n return (\n <Header\n {...rest}\n variant={variant}\n media={resolvedMedia}\n className={['eidos-identity-header', className].filter(Boolean).join(' ')}\n />\n );\n};\n"]}
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkGEHL4LKKcjs = require('./chunk-GEHL4LKK.cjs');
3
+ var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
4
4
 
5
5
 
6
- var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
6
+ var _chunkCUJBNRJJcjs = require('./chunk-CUJBNRJJ.cjs');
7
7
 
8
8
  // src/components/Chip/Chip.component.tsx
9
9
  var _lucidereact = require('lucide-react');
@@ -62,9 +62,9 @@ var Chip = ({
62
62
  } : void 0,
63
63
  ...chipProps,
64
64
  children: [
65
- preIcon && _chunkGEHL4LKKcjs.renderIcon.call(void 0, preIcon, "eidos-chip--pre-icon"),
65
+ preIcon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, preIcon, "eidos-chip--pre-icon"),
66
66
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-chip--copy", children }),
67
- posIcon && _chunkGEHL4LKKcjs.renderIcon.call(void 0, posIcon, "eidos-chip--pos-icon"),
67
+ posIcon && _chunkCUJBNRJJcjs.renderIcon.call(void 0, posIcon, "eidos-chip--pos-icon"),
68
68
  isRemovable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
69
69
  "button",
70
70
  {
@@ -85,4 +85,4 @@ var Chip = ({
85
85
 
86
86
 
87
87
  exports.Chip = Chip;
88
- //# sourceMappingURL=chunk-TRLBYA5G.cjs.map
88
+ //# sourceMappingURL=chunk-NEYLNRVG.cjs.map