eidos-ui 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.md +4 -0
  2. package/dist/Header.types-0XovUp0T.d.ts +79 -0
  3. package/dist/Header.types-Ce5Cj301.d.cts +79 -0
  4. package/dist/{Navigation.types-CpS3EYNz.d.ts → Navigation.types-By5HfPTi.d.ts} +8 -0
  5. package/dist/{Navigation.types-sUO9wqOp.d.cts → Navigation.types-_MrYqqUI.d.cts} +8 -0
  6. package/dist/{SegmentedControl.types-Dm4SnwCK.d.cts → SegmentedControl.types-BofrEYyd.d.cts} +16 -1
  7. package/dist/{SegmentedControl.types-CK8EiShd.d.ts → SegmentedControl.types-cjLwwBAm.d.ts} +16 -1
  8. package/dist/alert/index.cjs +4 -4
  9. package/dist/alert/index.js +3 -3
  10. package/dist/button/index.cjs +3 -3
  11. package/dist/button/index.js +2 -2
  12. package/dist/chip/index.cjs +3 -3
  13. package/dist/chip/index.js +2 -2
  14. package/dist/{chunk-RWOX2NJN.js → chunk-25PSIDPC.js} +2 -2
  15. package/dist/{chunk-IFVT5UCY.js → chunk-2QEKSRVX.js} +14 -10
  16. package/dist/chunk-2QEKSRVX.js.map +1 -0
  17. package/dist/{chunk-4BKTBV2I.js → chunk-2R77XZEP.js} +6 -2
  18. package/dist/chunk-2R77XZEP.js.map +1 -0
  19. package/dist/{chunk-H5HWFOWZ.js → chunk-2WP27QAN.js} +8 -8
  20. package/dist/{chunk-EXITZVB2.js → chunk-3RLGH45H.js} +6 -6
  21. package/dist/{chunk-442U3W6R.cjs → chunk-4MZ7HEQC.cjs} +5 -5
  22. package/dist/{chunk-442U3W6R.cjs.map → chunk-4MZ7HEQC.cjs.map} +1 -1
  23. package/dist/{chunk-R4PU2TBM.js → chunk-4ZWAJTNH.js} +3 -3
  24. package/dist/{chunk-RHOT7AEI.cjs → chunk-55J4LEKT.cjs} +8 -7
  25. package/dist/chunk-55J4LEKT.cjs.map +1 -0
  26. package/dist/{chunk-REVK7IGN.js → chunk-5WH3JMR5.js} +8 -7
  27. package/dist/chunk-5WH3JMR5.js.map +1 -0
  28. package/dist/{chunk-GT22EGJP.cjs → chunk-65PC3YDT.cjs} +14 -10
  29. package/dist/chunk-65PC3YDT.cjs.map +1 -0
  30. package/dist/{chunk-KQD7CQ4Z.cjs → chunk-6CSUUQ5M.cjs} +10 -6
  31. package/dist/chunk-6CSUUQ5M.cjs.map +1 -0
  32. package/dist/{chunk-GR2PMCVN.cjs → chunk-75TDY7XF.cjs} +5 -5
  33. package/dist/{chunk-GR2PMCVN.cjs.map → chunk-75TDY7XF.cjs.map} +1 -1
  34. package/dist/{chunk-FRUOA2QU.cjs → chunk-75VXB3H2.cjs} +7 -3
  35. package/dist/chunk-75VXB3H2.cjs.map +1 -0
  36. package/dist/{chunk-F26VIKNF.js → chunk-ATL7325T.js} +3 -3
  37. package/dist/{chunk-TEJIPPZR.js → chunk-BC5I2MYB.js} +7 -4
  38. package/dist/chunk-BC5I2MYB.js.map +1 -0
  39. package/dist/{chunk-GHQ6SQPI.js → chunk-BHVHM66Z.js} +6 -6
  40. package/dist/{chunk-N2IGZIEX.cjs → chunk-CJGFRPAS.cjs} +3 -3
  41. package/dist/{chunk-N2IGZIEX.cjs.map → chunk-CJGFRPAS.cjs.map} +1 -1
  42. package/dist/{chunk-GEHL4LKK.cjs → chunk-CUJBNRJJ.cjs} +8 -2
  43. package/dist/chunk-CUJBNRJJ.cjs.map +1 -0
  44. package/dist/{chunk-DAXZRNNO.cjs → chunk-D2SKXRKP.cjs} +8 -8
  45. package/dist/{chunk-DAXZRNNO.cjs.map → chunk-D2SKXRKP.cjs.map} +1 -1
  46. package/dist/{chunk-KBG77JHC.js → chunk-EAJHEYZM.js} +8 -2
  47. package/dist/chunk-EAJHEYZM.js.map +1 -0
  48. package/dist/{chunk-G77YR73R.cjs → chunk-EBSKRZXI.cjs} +8 -8
  49. package/dist/{chunk-G77YR73R.cjs.map → chunk-EBSKRZXI.cjs.map} +1 -1
  50. package/dist/{chunk-B5G5XVFJ.cjs → chunk-EH42ND5Q.cjs} +5 -5
  51. package/dist/{chunk-B5G5XVFJ.cjs.map → chunk-EH42ND5Q.cjs.map} +1 -1
  52. package/dist/{chunk-WUBQJVB7.cjs → chunk-EL3YXTOW.cjs} +9 -6
  53. package/dist/chunk-EL3YXTOW.cjs.map +1 -0
  54. package/dist/{chunk-Y53HCLGW.js → chunk-FALDCW2E.js} +2 -2
  55. package/dist/{chunk-D5IY2HUV.cjs → chunk-FXZJL2AM.cjs} +5 -5
  56. package/dist/{chunk-D5IY2HUV.cjs.map → chunk-FXZJL2AM.cjs.map} +1 -1
  57. package/dist/{chunk-KJZUYC4X.cjs → chunk-HI6WCX4T.cjs} +10 -9
  58. package/dist/chunk-HI6WCX4T.cjs.map +1 -0
  59. package/dist/{chunk-LFWPQYWX.cjs → chunk-I3CSPYHG.cjs} +3 -3
  60. package/dist/{chunk-LFWPQYWX.cjs.map → chunk-I3CSPYHG.cjs.map} +1 -1
  61. package/dist/{chunk-EZME5CLK.cjs → chunk-J5RMLZ4P.cjs} +3 -3
  62. package/dist/{chunk-EZME5CLK.cjs.map → chunk-J5RMLZ4P.cjs.map} +1 -1
  63. package/dist/{chunk-VHMOKXUT.js → chunk-JRLUZDKA.js} +8 -7
  64. package/dist/chunk-JRLUZDKA.js.map +1 -0
  65. package/dist/{chunk-LIFUHQH5.cjs → chunk-KBGFDHKD.cjs} +19 -19
  66. package/dist/{chunk-LIFUHQH5.cjs.map → chunk-KBGFDHKD.cjs.map} +1 -1
  67. package/dist/{chunk-ZHFPV43D.js → chunk-KNQ6NN6L.js} +5 -5
  68. package/dist/{chunk-2ZY7M72Q.js → chunk-KQJ3IAFT.js} +10 -7
  69. package/dist/chunk-KQJ3IAFT.js.map +1 -0
  70. package/dist/{chunk-74MBKLYI.js → chunk-L23WWO3D.js} +9 -5
  71. package/dist/chunk-L23WWO3D.js.map +1 -0
  72. package/dist/{chunk-YJXZR7RL.js → chunk-L5Q6UDY3.js} +4 -4
  73. package/dist/{chunk-5BX4Q76D.cjs → chunk-LVHZBCTA.cjs} +3 -3
  74. package/dist/{chunk-5BX4Q76D.cjs.map → chunk-LVHZBCTA.cjs.map} +1 -1
  75. package/dist/{chunk-SENVA467.js → chunk-M7PF4FKQ.js} +6 -2
  76. package/dist/chunk-M7PF4FKQ.js.map +1 -0
  77. package/dist/chunk-ND526PMG.cjs +145 -0
  78. package/dist/chunk-ND526PMG.cjs.map +1 -0
  79. package/dist/{chunk-TRLBYA5G.cjs → chunk-NEYLNRVG.cjs} +5 -5
  80. package/dist/{chunk-TRLBYA5G.cjs.map → chunk-NEYLNRVG.cjs.map} +1 -1
  81. package/dist/{chunk-ZEZK664O.js → chunk-NWJ6NETE.js} +13 -13
  82. package/dist/{chunk-U5FHQ73U.cjs → chunk-NZO2I5AL.cjs} +15 -12
  83. package/dist/chunk-NZO2I5AL.cjs.map +1 -0
  84. package/dist/{chunk-5ZL6PYU3.js → chunk-O2AACVSF.js} +3 -3
  85. package/dist/chunk-O3LG7B2J.cjs +186 -0
  86. package/dist/chunk-O3LG7B2J.cjs.map +1 -0
  87. package/dist/{chunk-SHYSLWQG.js → chunk-OAK7HFOJ.js} +4 -4
  88. package/dist/{chunk-QF2RAUPB.cjs → chunk-OAPOGYA5.cjs} +7 -3
  89. package/dist/chunk-OAPOGYA5.cjs.map +1 -0
  90. package/dist/{chunk-SKEWTQJ7.cjs → chunk-OMLXP2CK.cjs} +7 -7
  91. package/dist/{chunk-SKEWTQJ7.cjs.map → chunk-OMLXP2CK.cjs.map} +1 -1
  92. package/dist/{chunk-VSTQEHVZ.js → chunk-PR7CVQ4R.js} +10 -7
  93. package/dist/chunk-PR7CVQ4R.js.map +1 -0
  94. package/dist/{chunk-6HUHH6Y4.cjs → chunk-Q6ICDKQZ.cjs} +22 -19
  95. package/dist/chunk-Q6ICDKQZ.cjs.map +1 -0
  96. package/dist/{chunk-NGVOXM7P.js → chunk-QIITXVRG.js} +4 -4
  97. package/dist/{chunk-GI6VJYOS.js → chunk-QUDVJUZU.js} +3 -3
  98. package/dist/chunk-QZX3A4FX.js +886 -0
  99. package/dist/chunk-QZX3A4FX.js.map +1 -0
  100. package/dist/chunk-R3WPVTGY.cjs +886 -0
  101. package/dist/chunk-R3WPVTGY.cjs.map +1 -0
  102. package/dist/{chunk-SN6EWQDJ.js → chunk-RYOQYYDO.js} +3 -3
  103. package/dist/chunk-S4S4LB63.js +186 -0
  104. package/dist/chunk-S4S4LB63.js.map +1 -0
  105. package/dist/{chunk-67RFMV6K.js → chunk-T2KB3DJJ.js} +2 -2
  106. package/dist/{chunk-5VM2256W.cjs → chunk-TEVZHN5I.cjs} +11 -10
  107. package/dist/chunk-TEVZHN5I.cjs.map +1 -0
  108. package/dist/{chunk-RKA2OJRT.js → chunk-TJC7UELT.js} +18 -18
  109. package/dist/{chunk-SKTDGCWJ.cjs → chunk-UOOGS6N7.cjs} +48 -48
  110. package/dist/{chunk-SKTDGCWJ.cjs.map → chunk-UOOGS6N7.cjs.map} +1 -1
  111. package/dist/{chunk-SE7MWOC7.cjs → chunk-VRQBDTLT.cjs} +32 -32
  112. package/dist/{chunk-SE7MWOC7.cjs.map → chunk-VRQBDTLT.cjs.map} +1 -1
  113. package/dist/{chunk-AXBYJ2OY.cjs → chunk-WFEORBLC.cjs} +8 -8
  114. package/dist/{chunk-AXBYJ2OY.cjs.map → chunk-WFEORBLC.cjs.map} +1 -1
  115. package/dist/chunk-WKDT2XFQ.js +145 -0
  116. package/dist/chunk-WKDT2XFQ.js.map +1 -0
  117. package/dist/{chunk-APK5OQRV.cjs → chunk-WWYJNWJY.cjs} +6 -6
  118. package/dist/{chunk-APK5OQRV.cjs.map → chunk-WWYJNWJY.cjs.map} +1 -1
  119. package/dist/{chunk-A7WQINIG.js → chunk-X3U7SDOZ.js} +7 -6
  120. package/dist/chunk-X3U7SDOZ.js.map +1 -0
  121. package/dist/{chunk-LEMCJW57.js → chunk-YDPEHUMH.js} +2 -2
  122. package/dist/{chunk-GGSII6Y2.cjs → chunk-ZGT4LT5Y.cjs} +33 -33
  123. package/dist/{chunk-GGSII6Y2.cjs.map → chunk-ZGT4LT5Y.cjs.map} +1 -1
  124. package/dist/{chunk-LUL6RZ4M.cjs → chunk-ZNWIHUHZ.cjs} +3 -3
  125. package/dist/{chunk-LUL6RZ4M.cjs.map → chunk-ZNWIHUHZ.cjs.map} +1 -1
  126. package/dist/{chunk-S3CT536K.js → chunk-ZPDETHQ7.js} +2 -2
  127. package/dist/color-picker/index.cjs +4 -3
  128. package/dist/color-picker/index.cjs.map +1 -1
  129. package/dist/color-picker/index.js +3 -2
  130. package/dist/combobox/index.cjs +5 -5
  131. package/dist/combobox/index.js +4 -4
  132. package/dist/context-menu/index.cjs +5 -5
  133. package/dist/context-menu/index.js +4 -4
  134. package/dist/conversation/index.cjs +28 -0
  135. package/dist/conversation/index.cjs.map +1 -0
  136. package/dist/conversation/index.d.cts +254 -0
  137. package/dist/conversation/index.d.ts +254 -0
  138. package/dist/conversation/index.js +28 -0
  139. package/dist/conversation/index.js.map +1 -0
  140. package/dist/data-grid/index.cjs +16 -16
  141. package/dist/data-grid/index.d.cts +1 -1
  142. package/dist/data-grid/index.d.ts +1 -1
  143. package/dist/data-grid/index.js +15 -15
  144. package/dist/date-picker/index.cjs +7 -7
  145. package/dist/date-picker/index.js +6 -6
  146. package/dist/drawer/index.cjs +4 -4
  147. package/dist/drawer/index.js +3 -3
  148. package/dist/dropdown/index.cjs +3 -2
  149. package/dist/dropdown/index.cjs.map +1 -1
  150. package/dist/dropdown/index.js +2 -1
  151. package/dist/header/index.cjs +8 -4
  152. package/dist/header/index.cjs.map +1 -1
  153. package/dist/header/index.d.cts +35 -4
  154. package/dist/header/index.d.ts +35 -4
  155. package/dist/header/index.js +9 -5
  156. package/dist/index.cjs +66 -56
  157. package/dist/index.cjs.map +1 -1
  158. package/dist/index.css +1147 -295
  159. package/dist/index.d.cts +5 -4
  160. package/dist/index.d.ts +5 -4
  161. package/dist/index.js +84 -74
  162. package/dist/inline-edit/index.cjs +4 -4
  163. package/dist/inline-edit/index.js +3 -3
  164. package/dist/input/index.cjs +3 -3
  165. package/dist/input/index.js +2 -2
  166. package/dist/menu/index.cjs +4 -4
  167. package/dist/menu/index.js +3 -3
  168. package/dist/modal/index.cjs +4 -4
  169. package/dist/modal/index.js +3 -3
  170. package/dist/navigation/index.cjs +4 -4
  171. package/dist/navigation/index.d.cts +2 -2
  172. package/dist/navigation/index.d.ts +2 -2
  173. package/dist/navigation/index.js +3 -3
  174. package/dist/number-input/index.cjs +3 -2
  175. package/dist/number-input/index.cjs.map +1 -1
  176. package/dist/number-input/index.js +2 -1
  177. package/dist/page-layout/index.cjs +10 -9
  178. package/dist/page-layout/index.cjs.map +1 -1
  179. package/dist/page-layout/index.d.cts +2 -2
  180. package/dist/page-layout/index.d.ts +2 -2
  181. package/dist/page-layout/index.js +9 -8
  182. package/dist/pagination/index.cjs +7 -7
  183. package/dist/pagination/index.js +6 -6
  184. package/dist/segmented-control/index.cjs +3 -3
  185. package/dist/segmented-control/index.d.cts +2 -2
  186. package/dist/segmented-control/index.d.ts +2 -2
  187. package/dist/segmented-control/index.js +2 -2
  188. package/dist/select/index.cjs +5 -5
  189. package/dist/select/index.js +4 -4
  190. package/dist/snackbar/index.cjs +4 -4
  191. package/dist/snackbar/index.js +3 -3
  192. package/dist/split-button/index.cjs +5 -5
  193. package/dist/split-button/index.js +4 -4
  194. package/dist/table/index.cjs +16 -16
  195. package/dist/table/index.cjs.map +1 -1
  196. package/dist/table/index.js +15 -15
  197. package/dist/tabs/index.cjs +3 -3
  198. package/dist/tabs/index.js +2 -2
  199. package/dist/tag-input/index.cjs +5 -5
  200. package/dist/tag-input/index.js +4 -4
  201. package/dist/textarea/index.cjs +3 -3
  202. package/dist/textarea/index.js +2 -2
  203. package/dist/theme-editor/index.cjs +11 -11
  204. package/dist/theme-editor/index.js +10 -10
  205. package/dist/theme-provider/index.cjs +3 -3
  206. package/dist/theme-provider/index.js +2 -2
  207. package/dist/toolbar/index.cjs +6 -6
  208. package/dist/toolbar/index.js +5 -5
  209. package/package.json +1 -1
  210. package/dist/Header.types-B3QtuiL-.d.cts +0 -21
  211. package/dist/Header.types-C6w0FBY8.d.ts +0 -21
  212. package/dist/chunk-2ZY7M72Q.js.map +0 -1
  213. package/dist/chunk-4BKTBV2I.js.map +0 -1
  214. package/dist/chunk-5VM2256W.cjs.map +0 -1
  215. package/dist/chunk-6HUHH6Y4.cjs.map +0 -1
  216. package/dist/chunk-74MBKLYI.js.map +0 -1
  217. package/dist/chunk-A7WQINIG.js.map +0 -1
  218. package/dist/chunk-AAA6TR5I.cjs +0 -67
  219. package/dist/chunk-AAA6TR5I.cjs.map +0 -1
  220. package/dist/chunk-FRUOA2QU.cjs.map +0 -1
  221. package/dist/chunk-GEHL4LKK.cjs.map +0 -1
  222. package/dist/chunk-GT22EGJP.cjs.map +0 -1
  223. package/dist/chunk-IFVT5UCY.js.map +0 -1
  224. package/dist/chunk-KBG77JHC.js.map +0 -1
  225. package/dist/chunk-KJZUYC4X.cjs.map +0 -1
  226. package/dist/chunk-KQD7CQ4Z.cjs.map +0 -1
  227. package/dist/chunk-O5WEKLNF.js +0 -21
  228. package/dist/chunk-O5WEKLNF.js.map +0 -1
  229. package/dist/chunk-P7IQY5YH.js +0 -67
  230. package/dist/chunk-P7IQY5YH.js.map +0 -1
  231. package/dist/chunk-QF2RAUPB.cjs.map +0 -1
  232. package/dist/chunk-REVK7IGN.js.map +0 -1
  233. package/dist/chunk-RHOT7AEI.cjs.map +0 -1
  234. package/dist/chunk-SENVA467.js.map +0 -1
  235. package/dist/chunk-TEJIPPZR.js.map +0 -1
  236. package/dist/chunk-U5FHQ73U.cjs.map +0 -1
  237. package/dist/chunk-VHMOKXUT.js.map +0 -1
  238. package/dist/chunk-VSTQEHVZ.js.map +0 -1
  239. package/dist/chunk-WUBQJVB7.cjs.map +0 -1
  240. package/dist/chunk-Z4SLV6WG.cjs +0 -21
  241. package/dist/chunk-Z4SLV6WG.cjs.map +0 -1
  242. /package/dist/{chunk-RWOX2NJN.js.map → chunk-25PSIDPC.js.map} +0 -0
  243. /package/dist/{chunk-H5HWFOWZ.js.map → chunk-2WP27QAN.js.map} +0 -0
  244. /package/dist/{chunk-EXITZVB2.js.map → chunk-3RLGH45H.js.map} +0 -0
  245. /package/dist/{chunk-R4PU2TBM.js.map → chunk-4ZWAJTNH.js.map} +0 -0
  246. /package/dist/{chunk-F26VIKNF.js.map → chunk-ATL7325T.js.map} +0 -0
  247. /package/dist/{chunk-GHQ6SQPI.js.map → chunk-BHVHM66Z.js.map} +0 -0
  248. /package/dist/{chunk-Y53HCLGW.js.map → chunk-FALDCW2E.js.map} +0 -0
  249. /package/dist/{chunk-ZHFPV43D.js.map → chunk-KNQ6NN6L.js.map} +0 -0
  250. /package/dist/{chunk-YJXZR7RL.js.map → chunk-L5Q6UDY3.js.map} +0 -0
  251. /package/dist/{chunk-ZEZK664O.js.map → chunk-NWJ6NETE.js.map} +0 -0
  252. /package/dist/{chunk-5ZL6PYU3.js.map → chunk-O2AACVSF.js.map} +0 -0
  253. /package/dist/{chunk-SHYSLWQG.js.map → chunk-OAK7HFOJ.js.map} +0 -0
  254. /package/dist/{chunk-NGVOXM7P.js.map → chunk-QIITXVRG.js.map} +0 -0
  255. /package/dist/{chunk-GI6VJYOS.js.map → chunk-QUDVJUZU.js.map} +0 -0
  256. /package/dist/{chunk-SN6EWQDJ.js.map → chunk-RYOQYYDO.js.map} +0 -0
  257. /package/dist/{chunk-67RFMV6K.js.map → chunk-T2KB3DJJ.js.map} +0 -0
  258. /package/dist/{chunk-RKA2OJRT.js.map → chunk-TJC7UELT.js.map} +0 -0
  259. /package/dist/{chunk-LEMCJW57.js.map → chunk-YDPEHUMH.js.map} +0 -0
  260. /package/dist/{chunk-S3CT536K.js.map → chunk-ZPDETHQ7.js.map} +0 -0
@@ -13,26 +13,26 @@
13
13
 
14
14
 
15
15
 
16
- var _chunkU5FHQ73Ucjs = require('./chunk-U5FHQ73U.cjs');
16
+ var _chunkNZO2I5ALcjs = require('./chunk-NZO2I5AL.cjs');
17
17
 
18
18
 
19
19
  var _chunkOZZHOEN5cjs = require('./chunk-OZZHOEN5.cjs');
20
20
 
21
21
 
22
- var _chunkV5RS3JZNcjs = require('./chunk-V5RS3JZN.cjs');
22
+ var _chunkHI6WCX4Tcjs = require('./chunk-HI6WCX4T.cjs');
23
23
 
24
24
 
25
- var _chunk5BX4Q76Dcjs = require('./chunk-5BX4Q76D.cjs');
25
+ var _chunkV5RS3JZNcjs = require('./chunk-V5RS3JZN.cjs');
26
26
 
27
27
 
28
- var _chunkKJZUYC4Xcjs = require('./chunk-KJZUYC4X.cjs');
28
+ var _chunkLVHZBCTAcjs = require('./chunk-LVHZBCTA.cjs');
29
29
 
30
30
 
31
- var _chunkB5G5XVFJcjs = require('./chunk-B5G5XVFJ.cjs');
31
+ var _chunkEH42ND5Qcjs = require('./chunk-EH42ND5Q.cjs');
32
32
 
33
33
 
34
34
 
35
- var _chunkAPK5OQRVcjs = require('./chunk-APK5OQRV.cjs');
35
+ var _chunkWWYJNWJYcjs = require('./chunk-WWYJNWJY.cjs');
36
36
 
37
37
 
38
38
  var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
@@ -41,7 +41,7 @@ var _chunkZ5U4NJTWcjs = require('./chunk-Z5U4NJTW.cjs');
41
41
  var _react = require('react');
42
42
  var _lucidereact = require('lucide-react');
43
43
  var _jsxruntime = require('react/jsx-runtime');
44
- var PAGE_SURFACE = _chunkU5FHQ73Ucjs.CONTRAST_LIGHT;
44
+ var PAGE_SURFACE = _chunkNZO2I5ALcjs.CONTRAST_LIGHT;
45
45
  var EDGE_MIN_RATIO = 1.5;
46
46
  var COLOR_LABELS = {
47
47
  primary: "Primary",
@@ -58,7 +58,7 @@ var FONT_STACKS = [
58
58
  // matches an option exactly. A hand-copied shorter stack did not match, and
59
59
  // the row fell back to showing a synthetic "custom" entry instead of the
60
60
  // name of the font actually in use.
61
- { label: "Plus Jakarta Sans (theme default)", value: _chunkU5FHQ73Ucjs.defaultTheme.typography.fontFamily },
61
+ { label: "Plus Jakarta Sans (theme default)", value: _chunkNZO2I5ALcjs.defaultTheme.typography.fontFamily },
62
62
  { label: "System UI", value: "system-ui, -apple-system, 'Segoe UI', sans-serif" },
63
63
  { label: "Helvetica / Arial", value: "Helvetica, Arial, sans-serif" },
64
64
  { label: "Georgia", value: "Georgia, 'Times New Roman', serif" },
@@ -66,7 +66,7 @@ var FONT_STACKS = [
66
66
  { label: "Serif (generic)", value: "serif" }
67
67
  ];
68
68
  var MONO_STACKS = [
69
- { label: "JetBrains Mono (theme default)", value: _chunkU5FHQ73Ucjs.defaultTheme.typography.monoFamily },
69
+ { label: "JetBrains Mono (theme default)", value: _chunkNZO2I5ALcjs.defaultTheme.typography.monoFamily },
70
70
  { label: "Menlo / Consolas", value: "Menlo, Consolas, monospace" },
71
71
  { label: "Courier New", value: "'Courier New', Courier, monospace" },
72
72
  { label: "Monospace (generic)", value: "monospace" }
@@ -88,7 +88,7 @@ var GRADE_BADGE = {
88
88
  };
89
89
  var diagnose = (key, base, explicitContrast) => {
90
90
  if (!isFill(key)) {
91
- const ratio2 = _chunkU5FHQ73Ucjs.contrastRatio.call(void 0, base, PAGE_SURFACE);
91
+ const ratio2 = _chunkNZO2I5ALcjs.contrastRatio.call(void 0, base, PAGE_SURFACE);
92
92
  const grade2 = gradeFor(ratio2);
93
93
  return {
94
94
  grade: grade2,
@@ -96,10 +96,10 @@ var diagnose = (key, base, explicitContrast) => {
96
96
  detail: `Link text on the page background: ${ratio2.toFixed(2)}:1 against white.${_nullishCoalesce(GRADE_CAVEAT[grade2], () => ( ""))}`
97
97
  };
98
98
  }
99
- const foreground = _nullishCoalesce(explicitContrast, () => ( _chunkU5FHQ73Ucjs.pickContrast.call(void 0, base)));
100
- const ratio = _chunkU5FHQ73Ucjs.contrastRatio.call(void 0, base, foreground);
101
- const name = foreground.toLowerCase() === _chunkU5FHQ73Ucjs.CONTRAST_DARK ? "dark" : "white";
102
- const edge = _chunkU5FHQ73Ucjs.contrastRatio.call(void 0, base, PAGE_SURFACE);
99
+ const foreground = _nullishCoalesce(explicitContrast, () => ( _chunkNZO2I5ALcjs.pickContrast.call(void 0, base)));
100
+ const ratio = _chunkNZO2I5ALcjs.contrastRatio.call(void 0, base, foreground);
101
+ const name = foreground.toLowerCase() === _chunkNZO2I5ALcjs.CONTRAST_DARK ? "dark" : "white";
102
+ const edge = _chunkNZO2I5ALcjs.contrastRatio.call(void 0, base, PAGE_SURFACE);
103
103
  const grade = gradeFor(ratio);
104
104
  return {
105
105
  grade,
@@ -121,14 +121,14 @@ var FontRow = ({
121
121
  const inputRef = _react.useRef.call(void 0, null);
122
122
  const [error, setError] = _react.useState.call(void 0, null);
123
123
  const [, onFontsLoaded] = _react.useReducer.call(void 0, (count) => count + 1, 0);
124
- _react.useEffect.call(void 0, () => _chunkU5FHQ73Ucjs.subscribeToFontLoads.call(void 0, onFontsLoaded), [onFontsLoaded]);
124
+ _react.useEffect.call(void 0, () => _chunkNZO2I5ALcjs.subscribeToFontLoads.call(void 0, onFontsLoaded), [onFontsLoaded]);
125
125
  const baseOptions = _react.useMemo.call(void 0, () => {
126
126
  const known = options.some((o) => o.value === value);
127
127
  return known ? options : [...options, { label: `${firstFamily(value)} (custom)`, value }];
128
128
  }, [options, value]);
129
129
  const selectOptions = baseOptions.map((option) => ({
130
130
  id: option.value,
131
- label: _chunkU5FHQ73Ucjs.isFontStackAvailable.call(void 0, option.value) ? option.label : `${option.label} - not installed`,
131
+ label: _chunkNZO2I5ALcjs.isFontStackAvailable.call(void 0, option.value) ? option.label : `${option.label} - not installed`,
132
132
  value: option.value
133
133
  }));
134
134
  const handleFile = _react.useCallback.call(void 0,
@@ -136,8 +136,8 @@ var FontRow = ({
136
136
  if (!file) return;
137
137
  setError(null);
138
138
  try {
139
- const family = await _chunkU5FHQ73Ucjs.registerFontFile.call(void 0, file);
140
- const stack = _chunkU5FHQ73Ucjs.toFontStack.call(void 0, family, mono);
139
+ const family = await _chunkNZO2I5ALcjs.registerFontFile.call(void 0, file);
140
+ const stack = _chunkNZO2I5ALcjs.toFontStack.call(void 0, family, mono);
141
141
  onUploaded({ label: `${family} (this session)`, value: stack }, file, family);
142
142
  onChange(stack);
143
143
  } catch (cause) {
@@ -148,11 +148,11 @@ var FontRow = ({
148
148
  },
149
149
  [mono, onChange, onUploaded]
150
150
  );
151
- const unavailable = !_chunkU5FHQ73Ucjs.isFontStackAvailable.call(void 0, value);
151
+ const unavailable = !_chunkNZO2I5ALcjs.isFontStackAvailable.call(void 0, value);
152
152
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-theme-editor-row eidos-theme-editor-row--wide", children: [
153
153
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-theme-editor-row__label", children: label }),
154
154
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-theme-editor-row__control", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
155
- _chunkKJZUYC4Xcjs.Select,
155
+ _chunkHI6WCX4Tcjs.Select,
156
156
  {
157
157
  options: selectOptions,
158
158
  value,
@@ -178,7 +178,7 @@ var FontRow = ({
178
178
  ] }),
179
179
  allowUpload && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-theme-editor-row__actions", children: [
180
180
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
181
- _chunkAPK5OQRVcjs.Button,
181
+ _chunkWWYJNWJYcjs.Button,
182
182
  {
183
183
  variant: "text",
184
184
  color: "secondary",
@@ -194,7 +194,7 @@ var FontRow = ({
194
194
  {
195
195
  ref: inputRef,
196
196
  type: "file",
197
- accept: _chunkU5FHQ73Ucjs.FONT_ACCEPT,
197
+ accept: _chunkNZO2I5ALcjs.FONT_ACCEPT,
198
198
  className: "eidos-theme-editor-file",
199
199
  onChange: (event) => {
200
200
  void handleFile(_optionalChain([event, 'access', _11 => _11.target, 'access', _12 => _12.files, 'optionalAccess', _13 => _13[0]]));
@@ -206,7 +206,7 @@ var FontRow = ({
206
206
  ] });
207
207
  };
208
208
  var ThemeEditor = ({
209
- colors = _chunkU5FHQ73Ucjs.THEME_COLOR_KEYS,
209
+ colors = _chunkNZO2I5ALcjs.THEME_COLOR_KEYS,
210
210
  fontOptions = FONT_STACKS,
211
211
  monoFontOptions = MONO_STACKS,
212
212
  allowFontUpload = true,
@@ -216,7 +216,7 @@ var ThemeEditor = ({
216
216
  hideCssExport = false,
217
217
  className
218
218
  }) => {
219
- const { theme, resolvedTheme, setTheme, updateTheme, resetTheme, isDefault, toCss } = _chunkU5FHQ73Ucjs.useTheme.call(void 0, );
219
+ const { theme, resolvedTheme, setTheme, updateTheme, resetTheme, isDefault, toCss } = _chunkNZO2I5ALcjs.useTheme.call(void 0, );
220
220
  const [copied, setCopied] = _react.useState.call(void 0, false);
221
221
  const [uploaded, setUploaded] = _react.useState.call(void 0, []);
222
222
  const [monoUploaded, setMonoUploaded] = _react.useState.call(void 0, []);
@@ -258,7 +258,7 @@ var ThemeEditor = ({
258
258
  done();
259
259
  }, [toCss]);
260
260
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: ["eidos-theme-editor", className].filter(Boolean).join(" "), children: [
261
- (failing.length > 0 || invisible.length > 0) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkB5G5XVFJcjs.Alert, { variant: "warning", title: "Contrast issues", children: [
261
+ (failing.length > 0 || invisible.length > 0) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkEH42ND5Qcjs.Alert, { variant: "warning", title: "Contrast issues", children: [
262
262
  failing.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { children: [
263
263
  "Cannot reach WCAG AA (4.5:1) with either foreground:",
264
264
  " ",
@@ -282,7 +282,7 @@ var ThemeEditor = ({
282
282
  const overridden = _optionalChain([theme, 'access', _18 => _18.colors, 'optionalAccess', _19 => _19[key]]) !== void 0;
283
283
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-theme-editor-row", children: [
284
284
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-theme-editor-row__label", children: COLOR_LABELS[key] }),
285
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk5BX4Q76Dcjs.ColorPicker, { value: base, onChange: (hex) => setColor(key, hex), size: "md" }),
285
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkLVHZBCTAcjs.ColorPicker, { value: base, onChange: (hex) => setColor(key, hex), size: "md" }),
286
286
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-theme-editor-row__diagnostics", children: [
287
287
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZ5U4NJTWcjs.Tooltip, { message: detail, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: `eidos-theme-editor-badge eidos-theme-editor-badge--${grade}`, children: [
288
288
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, badge.icon, { className: "eidos-theme-editor-badge__icon" }),
@@ -294,7 +294,7 @@ var ThemeEditor = ({
294
294
  ] }) })
295
295
  ] }),
296
296
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-theme-editor-row__actions", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
297
- _chunkAPK5OQRVcjs.IconButton,
297
+ _chunkWWYJNWJYcjs.IconButton,
298
298
  {
299
299
  icon: "RotateCcw",
300
300
  variant: "text",
@@ -355,8 +355,8 @@ var ThemeEditor = ({
355
355
  _chunkOZZHOEN5cjs.Slider,
356
356
  {
357
357
  value: resolvedTheme.typography.fontScale,
358
- min: _chunkU5FHQ73Ucjs.FONT_SCALE_MIN,
359
- max: _chunkU5FHQ73Ucjs.FONT_SCALE_MAX,
358
+ min: _chunkNZO2I5ALcjs.FONT_SCALE_MIN,
359
+ max: _chunkNZO2I5ALcjs.FONT_SCALE_MAX,
360
360
  step: 0.025,
361
361
  showValue: true,
362
362
  showMinMax: true,
@@ -368,9 +368,9 @@ var ThemeEditor = ({
368
368
  ] })
369
369
  ] }),
370
370
  (!hideReset || !hideCssExport) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-theme-editor-actions", children: [
371
- !hideReset && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAPK5OQRVcjs.Button, { variant: "outlined", color: "secondary", disabled: isDefault, onClick: resetTheme, children: "Reset all" }),
371
+ !hideReset && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWWYJNWJYcjs.Button, { variant: "outlined", color: "secondary", disabled: isDefault, onClick: resetTheme, children: "Reset all" }),
372
372
  !hideCssExport && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
373
- _chunkAPK5OQRVcjs.Button,
373
+ _chunkWWYJNWJYcjs.Button,
374
374
  {
375
375
  variant: "outlined",
376
376
  preIcon: copied ? "Check" : "Clipboard",
@@ -387,4 +387,4 @@ ThemeEditor.displayName = "ThemeEditor";
387
387
 
388
388
 
389
389
  exports.ThemeEditor = ThemeEditor;
390
- //# sourceMappingURL=chunk-SE7MWOC7.cjs.map
390
+ //# sourceMappingURL=chunk-VRQBDTLT.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-SE7MWOC7.cjs","../src/components/ThemeEditor/ThemeEditor.component.tsx"],"names":["ratio","grade"],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-SE7MWOC7.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\nimport { CircleCheck, CircleX, TriangleAlert } from 'lucide-react';\nimport { Alert } from '../Alert';\nimport { Button, IconButton } from '../Button';\nimport { Card } from '../Card';\nimport { ColorPicker } from '../ColorPicker';\nimport { Select } from '../Select';\nimport { Slider } from '../Slider';\nimport { Tooltip } from '../Tooltip';\nimport { useTheme } from '../ThemeProvider';\nimport type { ThemeColorKey, ThemeFontOption } from '../ThemeProvider';\nimport {\n THEME_COLOR_KEYS,\n FONT_SCALE_MAX,\n FONT_SCALE_MIN,\n defaultTheme,\n} from '../ThemeProvider/ThemeProvider.tokens';\nimport {\n CONTRAST_DARK,\n CONTRAST_LIGHT,\n contrastRatio,\n pickContrast,\n} from '../ThemeProvider/ThemeProvider.color';\nimport {\n FONT_ACCEPT,\n isFontStackAvailable,\n registerFontFile,\n subscribeToFontLoads,\n toFontStack,\n} from '../ThemeProvider/ThemeProvider.fonts';\nimport type { ThemeEditorProps } from './ThemeEditor.types';\n\n/** The page surface every diagnostic is measured against - `--white`. */\nconst PAGE_SURFACE = CONTRAST_LIGHT;\n\n/** Below this, a fill is effectively invisible against the page behind it. */\nconst EDGE_MIN_RATIO = 1.5;\n\nconst COLOR_LABELS: Record<ThemeColorKey, string> = {\n primary: 'Primary',\n secondary: 'Secondary',\n success: 'Success',\n danger: 'Danger',\n warning: 'Warning',\n info: 'Info',\n hyperlink: 'Hyperlink',\n};\n\n/** `hyperlink` is only ever text on a surface, so it is graded differently. */\nconst isFill = (key: ThemeColorKey): boolean => key !== 'hyperlink';\n\n/**\n * Built-in stacks, deliberately limited to fonts that can be relied on.\n *\n * A dropdown implies its entries are available, but a font stack is only a list\n * of *names* - nothing here can install a font. So the list is restricted to\n * generic families (guaranteed by CSS), `system-ui` (whatever the OS provides),\n * and the handful of genuinely web-safe faces. Fonts like Inter, which are not\n * installed anywhere by default, were removed: offering one is offering a\n * choice that silently does nothing on most machines.\n *\n * The preset is included because it is the shipped default and therefore has to\n * be representable - and note that `eidos-ui` does not ship the Plus Jakarta\n * Sans file either, so it renders only where the consumer provides it. That is\n * exactly why unavailable options are labelled as such.\n *\n * Anything beyond this belongs to the consuming app, via `fontOptions`.\n */\nconst FONT_STACKS: ThemeFontOption[] = [\n // Taken from the preset rather than retyped, so the shipped default always\n // matches an option exactly. A hand-copied shorter stack did not match, and\n // the row fell back to showing a synthetic \"custom\" entry instead of the\n // name of the font actually in use.\n { label: 'Plus Jakarta Sans (theme default)', value: defaultTheme.typography.fontFamily! },\n { label: 'System UI', value: \"system-ui, -apple-system, 'Segoe UI', sans-serif\" },\n { label: 'Helvetica / Arial', value: 'Helvetica, Arial, sans-serif' },\n { label: 'Georgia', value: \"Georgia, 'Times New Roman', serif\" },\n { label: 'Sans-serif (generic)', value: 'sans-serif' },\n { label: 'Serif (generic)', value: 'serif' },\n];\n\nconst MONO_STACKS: ThemeFontOption[] = [\n { label: 'JetBrains Mono (theme default)', value: defaultTheme.typography.monoFamily! },\n { label: 'Menlo / Consolas', value: 'Menlo, Consolas, monospace' },\n { label: 'Courier New', value: \"'Courier New', Courier, monospace\" },\n { label: 'Monospace (generic)', value: 'monospace' },\n];\n\ntype Grade = 'aa' | 'aa-large' | 'fail';\n\nconst gradeFor = (ratio: number): Grade => (ratio >= 4.5 ? 'aa' : ratio >= 3 ? 'aa-large' : 'fail');\n\n/** Spelled out for the middle grade, which is the one that misleads. */\nconst GRADE_CAVEAT: Partial<Record<Grade, string>> = {\n 'aa-large':\n ' WCAG AA needs 4.5:1 for normal text and allows 3:1 only at 24px or larger - button and label text here is around 12px, so this does not pass.',\n fail: ' Below 3:1, which fails WCAG AA at every text size.',\n};\n\n/**\n * Severity is carried by an icon and the label text, not by colour.\n *\n * These badges cannot use `Pill`, or any themed `--x-color`: the theme being\n * edited also styles this editor, so a washed-out `success` colour would render\n * the \"passes AA\" badge illegible at precisely the moment it is reporting that\n * a colour is illegible. The badge styling comes from the gray ramp, which is\n * deliberately not themeable.\n *\n * Not relying on colour alone also satisfies WCAG 1.4.1 (Use of Colour).\n */\nconst GRADE_BADGE: Record<\n Grade,\n { label: string; icon: React.ComponentType<{ className?: string }> }\n> = {\n aa: { label: 'AA', icon: CircleCheck },\n // Named for what it means in practice, not just for the threshold it clears.\n // WCAG's relaxed 3:1 tier applies only to text at 24px (or 18.7px bold) and\n // above, and nothing in this library is that large - `--font-size-sm` is\n // ~12.25px at the default root size. A bare \"AA large only\" reads as a pass\n // when for every component here it is a fail.\n 'aa-large': { label: 'Too low for body text', icon: TriangleAlert },\n fail: { label: 'Fails AA', icon: CircleX },\n};\n\ninterface Diagnostic {\n grade: Grade;\n ratio: number;\n /** What the ratio describes, for the tooltip. */\n detail: string;\n /** Set when the fill is too close to the page surface to be seen. */\n edgeWarning?: string;\n}\n\nconst diagnose = (key: ThemeColorKey, base: string, explicitContrast?: string): Diagnostic => {\n if (!isFill(key)) {\n // Link text sits on the page, so the page is what it must contrast with.\n const ratio = contrastRatio(base, PAGE_SURFACE);\n const grade = gradeFor(ratio);\n return {\n grade,\n ratio,\n detail: `Link text on the page background: ${ratio.toFixed(2)}:1 against white.${GRADE_CAVEAT[grade] ?? ''}`,\n };\n }\n\n const foreground = explicitContrast ?? pickContrast(base);\n const ratio = contrastRatio(base, foreground);\n const name = foreground.toLowerCase() === CONTRAST_DARK ? 'dark' : 'white';\n const edge = contrastRatio(base, PAGE_SURFACE);\n\n const grade = gradeFor(ratio);\n\n return {\n grade,\n ratio,\n detail: `${name === 'white' ? 'White' : 'Near-black'} text on this fill is ${ratio.toFixed(2)}:1.${\n explicitContrast ? ' Foreground pinned via the theme.' : ''\n }${GRADE_CAVEAT[grade] ?? ''}`,\n edgeWarning:\n edge < EDGE_MIN_RATIO\n ? `Only ${edge.toFixed(2)}:1 against the page background - this fill is barely distinguishable from the page it sits on.`\n : undefined,\n };\n};\n\ninterface FontRowProps {\n label: string;\n /** Stack currently applied, used to pick the matching option. */\n value: string;\n options: ThemeFontOption[];\n mono: boolean;\n allowUpload: boolean;\n onChange: (stack: string) => void;\n onUploaded: (option: ThemeFontOption, file: File, family: string) => void;\n}\n\n/** Pulls the first family out of a stack, unquoted. */\nconst firstFamily = (stack: string): string =>\n stack\n .split(',')[0]\n ?.trim()\n .replace(/^['\"]|['\"]$/g, '') || 'Custom';\n\n/**\n * One font row: a `Select` over the known stacks, an optional upload, and an\n * availability warning.\n *\n * Uses `Select` rather than `Combobox` deliberately. `Combobox` filters its\n * options against the text in the field, and the field holds a full font stack\n * (`'Plus Jakarta Sans', -apple-system, …`) which matches no option label - so\n * the list read \"No results found\" until the text was cleared by hand. A font\n * is a choice from a known set, not a search.\n */\nconst FontRow: React.FC<FontRowProps> = ({\n label,\n value,\n options,\n mono,\n allowUpload,\n onChange,\n onUploaded,\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Web fonts load asynchronously, so the first render always sees them as\n // unavailable. Without re-checking once they arrive, the row would sit on a\n // stale \"not installed\" warning for a font that is rendering perfectly.\n // The reducer exists only to schedule that re-render; its value is unused.\n const [, onFontsLoaded] = useReducer((count: number) => count + 1, 0);\n useEffect(() => subscribeToFontLoads(onFontsLoaded), [onFontsLoaded]);\n\n const baseOptions = useMemo(() => {\n // A stack the theme carries but that isn't in the list (loaded by the host\n // app, or set programmatically) still needs to be selectable, labelled with\n // its own first family so the row names the font actually in use.\n const known = options.some((o) => o.value === value);\n return known ? options : [...options, { label: `${firstFamily(value)} (custom)`, value }];\n }, [options, value]);\n\n // Probed on every render rather than memoised: availability changes over time\n // as fonts load, so a cached answer is a wrong answer. Four canvas\n // measurements are far cheaper than getting this wrong.\n //\n // Availability is annotated per option rather than filtered or disabled. A\n // theme is shared across machines, so a font present here may be absent for\n // the next user - and vice versa, which would mean hiding a font someone\n // legitimately wants. Annotating keeps every choice selectable while making\n // the list stop implying that a name is a guarantee.\n const selectOptions = baseOptions.map((option) => ({\n id: option.value,\n label: isFontStackAvailable(option.value) ? option.label : `${option.label} - not installed`,\n value: option.value,\n }));\n\n const handleFile = useCallback(\n async (file: File | undefined) => {\n if (!file) return;\n setError(null);\n try {\n const family = await registerFontFile(file);\n const stack = toFontStack(family, mono);\n onUploaded({ label: `${family} (this session)`, value: stack }, file, family);\n onChange(stack);\n } catch (cause) {\n setError(\n cause instanceof Error ? cause.message : 'That file could not be loaded as a font.',\n );\n }\n },\n [mono, onChange, onUploaded],\n );\n\n const unavailable = !isFontStackAvailable(value);\n\n return (\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">{label}</span>\n\n <div className=\"eidos-theme-editor-row__control\">\n <Select\n options={selectOptions}\n value={value}\n onChange={(next) => onChange(Array.isArray(next) ? next[0] : next)}\n fullWidth\n />\n </div>\n\n {/* Occasional - lives before the action so it can never displace it. */}\n <div className=\"eidos-theme-editor-row__diagnostics\">\n {unavailable && (\n <Tooltip\n message={`${firstFamily(value)} isn't available here, so the browser is rendering the next family in the stack instead. Upload the file, or have your app serve it, to use it.`}\n >\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--aa-large\">\n <TriangleAlert className=\"eidos-theme-editor-badge__icon\" />\n Not installed\n </span>\n </Tooltip>\n )}\n {error && (\n <Tooltip message={error}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Upload failed\n </span>\n </Tooltip>\n )}\n </div>\n\n {allowUpload && (\n <div className=\"eidos-theme-editor-row__actions\">\n <Button\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n preIcon=\"Upload\"\n onClick={() => inputRef.current?.click()}\n tooltip=\"Load a font file to use it right away. Not saved - see onFontUpload to persist it.\"\n >\n Upload\n </Button>\n {/* Plain input rather than FileUpload: this is a single inline\n action in a dense row, not a drop zone. */}\n <input\n ref={inputRef}\n type=\"file\"\n accept={FONT_ACCEPT}\n className=\"eidos-theme-editor-file\"\n onChange={(event) => {\n void handleFile(event.target.files?.[0]);\n // Allow re-picking the same file after a failure.\n event.target.value = '';\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\n/**\n * Live editor for the active `ThemeProvider` theme.\n *\n * Renders no preview of its own: the provider writes tokens to\n * `document.documentElement`, so the surrounding page is the preview.\n *\n * Contrast readouts are diagnostics only - a colour that fails is still\n * applied. Automatically \"correcting\" a chosen colour would mean silently\n * rendering something other than what was picked.\n */\nexport const ThemeEditor: React.FC<ThemeEditorProps> = ({\n colors = THEME_COLOR_KEYS as ThemeColorKey[],\n fontOptions = FONT_STACKS,\n monoFontOptions = MONO_STACKS,\n allowFontUpload = true,\n onFontUpload,\n hideTypography = false,\n hideReset = false,\n hideCssExport = false,\n className,\n}) => {\n const { theme, resolvedTheme, setTheme, updateTheme, resetTheme, isDefault, toCss } = useTheme();\n const [copied, setCopied] = useState(false);\n\n // Fonts registered through the upload control this session. Kept local\n // because font *data* cannot live in a ThemeConfig - see the .mdx.\n const [uploaded, setUploaded] = useState<ThemeFontOption[]>([]);\n const [monoUploaded, setMonoUploaded] = useState<ThemeFontOption[]>([]);\n\n const setColor = useCallback(\n (key: ThemeColorKey, hex: string) => {\n const current = theme.colors?.[key];\n // Only the base is written here. A `contrast` pinned in the theme is\n // preserved rather than dropped, since the editor never sets one.\n const pinned = typeof current === 'object' ? current.contrast : undefined;\n updateTheme({ colors: { [key]: pinned ? { base: hex, contrast: pinned } : hex } });\n },\n [theme.colors, updateTheme],\n );\n\n const resetColor = useCallback(\n (key: ThemeColorKey) => {\n // Must go through setTheme, not updateTheme: updateTheme merges, so a key\n // left out of the patch keeps its existing value instead of being removed.\n // Removal is what restores the preset, since resolveTheme fills gaps.\n const nextColors = { ...theme.colors };\n delete nextColors[key];\n setTheme({ ...theme, colors: nextColors });\n },\n [theme, setTheme],\n );\n\n const diagnostics = useMemo(\n () =>\n colors.map((key) => {\n const { base, contrast } = resolvedTheme.colors[key];\n return { key, base, ...diagnose(key, base, contrast) };\n }),\n [colors, resolvedTheme],\n );\n\n const failing = diagnostics.filter((d) => d.grade === 'fail');\n const invisible = diagnostics.filter((d) => d.edgeWarning);\n\n const copyCss = useCallback(() => {\n const css = toCss();\n const done = () => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1600);\n };\n if (navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(css).then(done, done);\n return;\n }\n done();\n }, [toCss]);\n\n return (\n <div className={['eidos-theme-editor', className].filter(Boolean).join(' ')}>\n {(failing.length > 0 || invisible.length > 0) && (\n <Alert variant=\"warning\" title=\"Contrast issues\">\n {failing.length > 0 && (\n <p>\n Cannot reach WCAG AA (4.5:1) with either foreground:{' '}\n {failing.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n {invisible.length > 0 && (\n <p>\n Too close to the page background to read as a filled surface:{' '}\n {invisible.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n </Alert>\n )}\n\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Colours</span>\n <span className=\"eidos-theme-editor-section__hint\">\n Shades, tints and foregrounds are derived from each base colour.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n {diagnostics.map(({ key, base, grade, ratio, detail, edgeWarning }) => {\n const badge = GRADE_BADGE[grade];\n const overridden = theme.colors?.[key] !== undefined;\n return (\n <div className=\"eidos-theme-editor-row\" key={key}>\n <span className=\"eidos-theme-editor-row__label\">{COLOR_LABELS[key]}</span>\n\n {/* `md` rather than `sm`: the size drives the panel's\n saturation/brightness canvas, and 120px is cramped for\n picking a lightness precisely. */}\n <ColorPicker value={base} onChange={(hex) => setColor(key, hex)} size=\"md\" />\n\n <div className=\"eidos-theme-editor-row__diagnostics\">\n <Tooltip message={detail}>\n <span className={`eidos-theme-editor-badge eidos-theme-editor-badge--${grade}`}>\n <badge.icon className=\"eidos-theme-editor-badge__icon\" />\n {`${ratio.toFixed(2)}:1 ${badge.label}`}\n </span>\n </Tooltip>\n {edgeWarning && (\n <Tooltip message={edgeWarning}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Invisible on page\n </span>\n </Tooltip>\n )}\n </div>\n\n <div className=\"eidos-theme-editor-row__actions\">\n <IconButton\n icon=\"RotateCcw\"\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n disabled={!overridden}\n onClick={() => resetColor(key)}\n tooltip={overridden ? `Reset ${COLOR_LABELS[key]} to the preset` : 'Unchanged'}\n aria-label={`Reset ${COLOR_LABELS[key]}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n </Card>\n\n {!hideTypography && (\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Typography</span>\n <span className=\"eidos-theme-editor-section__hint\">\n A stack only names a font - upload the file to use one the browser doesn&apos;t\n already have. Spacing is declared in <code>em</code>, so the scale moves padding with\n the text.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n <FontRow\n label=\"Body font\"\n value={resolvedTheme.typography.fontFamily}\n options={[...fontOptions, ...uploaded]}\n mono={false}\n allowUpload={allowFontUpload}\n onChange={(fontFamily) => updateTheme({ typography: { fontFamily } })}\n onUploaded={(option, file, family) => {\n setUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, false);\n }}\n />\n\n <FontRow\n label=\"Mono font\"\n value={resolvedTheme.typography.monoFamily}\n options={[...monoFontOptions, ...monoUploaded]}\n mono\n allowUpload={allowFontUpload}\n onChange={(monoFamily) => updateTheme({ typography: { monoFamily } })}\n onUploaded={(option, file, family) => {\n setMonoUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, true);\n }}\n />\n\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">Scale</span>\n <div className=\"eidos-theme-editor-row__control\">\n <Slider\n value={resolvedTheme.typography.fontScale}\n min={FONT_SCALE_MIN}\n max={FONT_SCALE_MAX}\n step={0.025}\n showValue\n showMinMax\n unit=\"×\"\n onChange={(value) => updateTheme({ typography: { fontScale: value } })}\n />\n </div>\n </div>\n </div>\n </Card>\n )}\n\n {(!hideReset || !hideCssExport) && (\n <div className=\"eidos-theme-editor-actions\">\n {!hideReset && (\n <Button variant=\"outlined\" color=\"secondary\" disabled={isDefault} onClick={resetTheme}>\n Reset all\n </Button>\n )}\n {!hideCssExport && (\n <Button\n variant=\"outlined\"\n preIcon={copied ? 'Check' : 'Clipboard'}\n onClick={copyCss}\n tooltip=\"Copy the resolved tokens as a :root block you can paste into your own stylesheet\"\n >\n {copied ? 'Copied' : 'Copy as CSS'}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n\nThemeEditor.displayName = 'ThemeEditor';\n"]}
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-VRQBDTLT.cjs","../src/components/ThemeEditor/ThemeEditor.component.tsx"],"names":["ratio","grade"],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-VRQBDTLT.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\nimport { CircleCheck, CircleX, TriangleAlert } from 'lucide-react';\nimport { Alert } from '../Alert';\nimport { Button, IconButton } from '../Button';\nimport { Card } from '../Card';\nimport { ColorPicker } from '../ColorPicker';\nimport { Select } from '../Select';\nimport { Slider } from '../Slider';\nimport { Tooltip } from '../Tooltip';\nimport { useTheme } from '../ThemeProvider';\nimport type { ThemeColorKey, ThemeFontOption } from '../ThemeProvider';\nimport {\n THEME_COLOR_KEYS,\n FONT_SCALE_MAX,\n FONT_SCALE_MIN,\n defaultTheme,\n} from '../ThemeProvider/ThemeProvider.tokens';\nimport {\n CONTRAST_DARK,\n CONTRAST_LIGHT,\n contrastRatio,\n pickContrast,\n} from '../ThemeProvider/ThemeProvider.color';\nimport {\n FONT_ACCEPT,\n isFontStackAvailable,\n registerFontFile,\n subscribeToFontLoads,\n toFontStack,\n} from '../ThemeProvider/ThemeProvider.fonts';\nimport type { ThemeEditorProps } from './ThemeEditor.types';\n\n/** The page surface every diagnostic is measured against - `--white`. */\nconst PAGE_SURFACE = CONTRAST_LIGHT;\n\n/** Below this, a fill is effectively invisible against the page behind it. */\nconst EDGE_MIN_RATIO = 1.5;\n\nconst COLOR_LABELS: Record<ThemeColorKey, string> = {\n primary: 'Primary',\n secondary: 'Secondary',\n success: 'Success',\n danger: 'Danger',\n warning: 'Warning',\n info: 'Info',\n hyperlink: 'Hyperlink',\n};\n\n/** `hyperlink` is only ever text on a surface, so it is graded differently. */\nconst isFill = (key: ThemeColorKey): boolean => key !== 'hyperlink';\n\n/**\n * Built-in stacks, deliberately limited to fonts that can be relied on.\n *\n * A dropdown implies its entries are available, but a font stack is only a list\n * of *names* - nothing here can install a font. So the list is restricted to\n * generic families (guaranteed by CSS), `system-ui` (whatever the OS provides),\n * and the handful of genuinely web-safe faces. Fonts like Inter, which are not\n * installed anywhere by default, were removed: offering one is offering a\n * choice that silently does nothing on most machines.\n *\n * The preset is included because it is the shipped default and therefore has to\n * be representable - and note that `eidos-ui` does not ship the Plus Jakarta\n * Sans file either, so it renders only where the consumer provides it. That is\n * exactly why unavailable options are labelled as such.\n *\n * Anything beyond this belongs to the consuming app, via `fontOptions`.\n */\nconst FONT_STACKS: ThemeFontOption[] = [\n // Taken from the preset rather than retyped, so the shipped default always\n // matches an option exactly. A hand-copied shorter stack did not match, and\n // the row fell back to showing a synthetic \"custom\" entry instead of the\n // name of the font actually in use.\n { label: 'Plus Jakarta Sans (theme default)', value: defaultTheme.typography.fontFamily! },\n { label: 'System UI', value: \"system-ui, -apple-system, 'Segoe UI', sans-serif\" },\n { label: 'Helvetica / Arial', value: 'Helvetica, Arial, sans-serif' },\n { label: 'Georgia', value: \"Georgia, 'Times New Roman', serif\" },\n { label: 'Sans-serif (generic)', value: 'sans-serif' },\n { label: 'Serif (generic)', value: 'serif' },\n];\n\nconst MONO_STACKS: ThemeFontOption[] = [\n { label: 'JetBrains Mono (theme default)', value: defaultTheme.typography.monoFamily! },\n { label: 'Menlo / Consolas', value: 'Menlo, Consolas, monospace' },\n { label: 'Courier New', value: \"'Courier New', Courier, monospace\" },\n { label: 'Monospace (generic)', value: 'monospace' },\n];\n\ntype Grade = 'aa' | 'aa-large' | 'fail';\n\nconst gradeFor = (ratio: number): Grade => (ratio >= 4.5 ? 'aa' : ratio >= 3 ? 'aa-large' : 'fail');\n\n/** Spelled out for the middle grade, which is the one that misleads. */\nconst GRADE_CAVEAT: Partial<Record<Grade, string>> = {\n 'aa-large':\n ' WCAG AA needs 4.5:1 for normal text and allows 3:1 only at 24px or larger - button and label text here is around 12px, so this does not pass.',\n fail: ' Below 3:1, which fails WCAG AA at every text size.',\n};\n\n/**\n * Severity is carried by an icon and the label text, not by colour.\n *\n * These badges cannot use `Pill`, or any themed `--x-color`: the theme being\n * edited also styles this editor, so a washed-out `success` colour would render\n * the \"passes AA\" badge illegible at precisely the moment it is reporting that\n * a colour is illegible. The badge styling comes from the gray ramp, which is\n * deliberately not themeable.\n *\n * Not relying on colour alone also satisfies WCAG 1.4.1 (Use of Colour).\n */\nconst GRADE_BADGE: Record<\n Grade,\n { label: string; icon: React.ComponentType<{ className?: string }> }\n> = {\n aa: { label: 'AA', icon: CircleCheck },\n // Named for what it means in practice, not just for the threshold it clears.\n // WCAG's relaxed 3:1 tier applies only to text at 24px (or 18.7px bold) and\n // above, and nothing in this library is that large - `--font-size-sm` is\n // ~12.25px at the default root size. A bare \"AA large only\" reads as a pass\n // when for every component here it is a fail.\n 'aa-large': { label: 'Too low for body text', icon: TriangleAlert },\n fail: { label: 'Fails AA', icon: CircleX },\n};\n\ninterface Diagnostic {\n grade: Grade;\n ratio: number;\n /** What the ratio describes, for the tooltip. */\n detail: string;\n /** Set when the fill is too close to the page surface to be seen. */\n edgeWarning?: string;\n}\n\nconst diagnose = (key: ThemeColorKey, base: string, explicitContrast?: string): Diagnostic => {\n if (!isFill(key)) {\n // Link text sits on the page, so the page is what it must contrast with.\n const ratio = contrastRatio(base, PAGE_SURFACE);\n const grade = gradeFor(ratio);\n return {\n grade,\n ratio,\n detail: `Link text on the page background: ${ratio.toFixed(2)}:1 against white.${GRADE_CAVEAT[grade] ?? ''}`,\n };\n }\n\n const foreground = explicitContrast ?? pickContrast(base);\n const ratio = contrastRatio(base, foreground);\n const name = foreground.toLowerCase() === CONTRAST_DARK ? 'dark' : 'white';\n const edge = contrastRatio(base, PAGE_SURFACE);\n\n const grade = gradeFor(ratio);\n\n return {\n grade,\n ratio,\n detail: `${name === 'white' ? 'White' : 'Near-black'} text on this fill is ${ratio.toFixed(2)}:1.${\n explicitContrast ? ' Foreground pinned via the theme.' : ''\n }${GRADE_CAVEAT[grade] ?? ''}`,\n edgeWarning:\n edge < EDGE_MIN_RATIO\n ? `Only ${edge.toFixed(2)}:1 against the page background - this fill is barely distinguishable from the page it sits on.`\n : undefined,\n };\n};\n\ninterface FontRowProps {\n label: string;\n /** Stack currently applied, used to pick the matching option. */\n value: string;\n options: ThemeFontOption[];\n mono: boolean;\n allowUpload: boolean;\n onChange: (stack: string) => void;\n onUploaded: (option: ThemeFontOption, file: File, family: string) => void;\n}\n\n/** Pulls the first family out of a stack, unquoted. */\nconst firstFamily = (stack: string): string =>\n stack\n .split(',')[0]\n ?.trim()\n .replace(/^['\"]|['\"]$/g, '') || 'Custom';\n\n/**\n * One font row: a `Select` over the known stacks, an optional upload, and an\n * availability warning.\n *\n * Uses `Select` rather than `Combobox` deliberately. `Combobox` filters its\n * options against the text in the field, and the field holds a full font stack\n * (`'Plus Jakarta Sans', -apple-system, …`) which matches no option label - so\n * the list read \"No results found\" until the text was cleared by hand. A font\n * is a choice from a known set, not a search.\n */\nconst FontRow: React.FC<FontRowProps> = ({\n label,\n value,\n options,\n mono,\n allowUpload,\n onChange,\n onUploaded,\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Web fonts load asynchronously, so the first render always sees them as\n // unavailable. Without re-checking once they arrive, the row would sit on a\n // stale \"not installed\" warning for a font that is rendering perfectly.\n // The reducer exists only to schedule that re-render; its value is unused.\n const [, onFontsLoaded] = useReducer((count: number) => count + 1, 0);\n useEffect(() => subscribeToFontLoads(onFontsLoaded), [onFontsLoaded]);\n\n const baseOptions = useMemo(() => {\n // A stack the theme carries but that isn't in the list (loaded by the host\n // app, or set programmatically) still needs to be selectable, labelled with\n // its own first family so the row names the font actually in use.\n const known = options.some((o) => o.value === value);\n return known ? options : [...options, { label: `${firstFamily(value)} (custom)`, value }];\n }, [options, value]);\n\n // Probed on every render rather than memoised: availability changes over time\n // as fonts load, so a cached answer is a wrong answer. Four canvas\n // measurements are far cheaper than getting this wrong.\n //\n // Availability is annotated per option rather than filtered or disabled. A\n // theme is shared across machines, so a font present here may be absent for\n // the next user - and vice versa, which would mean hiding a font someone\n // legitimately wants. Annotating keeps every choice selectable while making\n // the list stop implying that a name is a guarantee.\n const selectOptions = baseOptions.map((option) => ({\n id: option.value,\n label: isFontStackAvailable(option.value) ? option.label : `${option.label} - not installed`,\n value: option.value,\n }));\n\n const handleFile = useCallback(\n async (file: File | undefined) => {\n if (!file) return;\n setError(null);\n try {\n const family = await registerFontFile(file);\n const stack = toFontStack(family, mono);\n onUploaded({ label: `${family} (this session)`, value: stack }, file, family);\n onChange(stack);\n } catch (cause) {\n setError(\n cause instanceof Error ? cause.message : 'That file could not be loaded as a font.',\n );\n }\n },\n [mono, onChange, onUploaded],\n );\n\n const unavailable = !isFontStackAvailable(value);\n\n return (\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">{label}</span>\n\n <div className=\"eidos-theme-editor-row__control\">\n <Select\n options={selectOptions}\n value={value}\n onChange={(next) => onChange(Array.isArray(next) ? next[0] : next)}\n fullWidth\n />\n </div>\n\n {/* Occasional - lives before the action so it can never displace it. */}\n <div className=\"eidos-theme-editor-row__diagnostics\">\n {unavailable && (\n <Tooltip\n message={`${firstFamily(value)} isn't available here, so the browser is rendering the next family in the stack instead. Upload the file, or have your app serve it, to use it.`}\n >\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--aa-large\">\n <TriangleAlert className=\"eidos-theme-editor-badge__icon\" />\n Not installed\n </span>\n </Tooltip>\n )}\n {error && (\n <Tooltip message={error}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Upload failed\n </span>\n </Tooltip>\n )}\n </div>\n\n {allowUpload && (\n <div className=\"eidos-theme-editor-row__actions\">\n <Button\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n preIcon=\"Upload\"\n onClick={() => inputRef.current?.click()}\n tooltip=\"Load a font file to use it right away. Not saved - see onFontUpload to persist it.\"\n >\n Upload\n </Button>\n {/* Plain input rather than FileUpload: this is a single inline\n action in a dense row, not a drop zone. */}\n <input\n ref={inputRef}\n type=\"file\"\n accept={FONT_ACCEPT}\n className=\"eidos-theme-editor-file\"\n onChange={(event) => {\n void handleFile(event.target.files?.[0]);\n // Allow re-picking the same file after a failure.\n event.target.value = '';\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\n/**\n * Live editor for the active `ThemeProvider` theme.\n *\n * Renders no preview of its own: the provider writes tokens to\n * `document.documentElement`, so the surrounding page is the preview.\n *\n * Contrast readouts are diagnostics only - a colour that fails is still\n * applied. Automatically \"correcting\" a chosen colour would mean silently\n * rendering something other than what was picked.\n */\nexport const ThemeEditor: React.FC<ThemeEditorProps> = ({\n colors = THEME_COLOR_KEYS as ThemeColorKey[],\n fontOptions = FONT_STACKS,\n monoFontOptions = MONO_STACKS,\n allowFontUpload = true,\n onFontUpload,\n hideTypography = false,\n hideReset = false,\n hideCssExport = false,\n className,\n}) => {\n const { theme, resolvedTheme, setTheme, updateTheme, resetTheme, isDefault, toCss } = useTheme();\n const [copied, setCopied] = useState(false);\n\n // Fonts registered through the upload control this session. Kept local\n // because font *data* cannot live in a ThemeConfig - see the .mdx.\n const [uploaded, setUploaded] = useState<ThemeFontOption[]>([]);\n const [monoUploaded, setMonoUploaded] = useState<ThemeFontOption[]>([]);\n\n const setColor = useCallback(\n (key: ThemeColorKey, hex: string) => {\n const current = theme.colors?.[key];\n // Only the base is written here. A `contrast` pinned in the theme is\n // preserved rather than dropped, since the editor never sets one.\n const pinned = typeof current === 'object' ? current.contrast : undefined;\n updateTheme({ colors: { [key]: pinned ? { base: hex, contrast: pinned } : hex } });\n },\n [theme.colors, updateTheme],\n );\n\n const resetColor = useCallback(\n (key: ThemeColorKey) => {\n // Must go through setTheme, not updateTheme: updateTheme merges, so a key\n // left out of the patch keeps its existing value instead of being removed.\n // Removal is what restores the preset, since resolveTheme fills gaps.\n const nextColors = { ...theme.colors };\n delete nextColors[key];\n setTheme({ ...theme, colors: nextColors });\n },\n [theme, setTheme],\n );\n\n const diagnostics = useMemo(\n () =>\n colors.map((key) => {\n const { base, contrast } = resolvedTheme.colors[key];\n return { key, base, ...diagnose(key, base, contrast) };\n }),\n [colors, resolvedTheme],\n );\n\n const failing = diagnostics.filter((d) => d.grade === 'fail');\n const invisible = diagnostics.filter((d) => d.edgeWarning);\n\n const copyCss = useCallback(() => {\n const css = toCss();\n const done = () => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1600);\n };\n if (navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(css).then(done, done);\n return;\n }\n done();\n }, [toCss]);\n\n return (\n <div className={['eidos-theme-editor', className].filter(Boolean).join(' ')}>\n {(failing.length > 0 || invisible.length > 0) && (\n <Alert variant=\"warning\" title=\"Contrast issues\">\n {failing.length > 0 && (\n <p>\n Cannot reach WCAG AA (4.5:1) with either foreground:{' '}\n {failing.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n {invisible.length > 0 && (\n <p>\n Too close to the page background to read as a filled surface:{' '}\n {invisible.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n </Alert>\n )}\n\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Colours</span>\n <span className=\"eidos-theme-editor-section__hint\">\n Shades, tints and foregrounds are derived from each base colour.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n {diagnostics.map(({ key, base, grade, ratio, detail, edgeWarning }) => {\n const badge = GRADE_BADGE[grade];\n const overridden = theme.colors?.[key] !== undefined;\n return (\n <div className=\"eidos-theme-editor-row\" key={key}>\n <span className=\"eidos-theme-editor-row__label\">{COLOR_LABELS[key]}</span>\n\n {/* `md` rather than `sm`: the size drives the panel's\n saturation/brightness canvas, and 120px is cramped for\n picking a lightness precisely. */}\n <ColorPicker value={base} onChange={(hex) => setColor(key, hex)} size=\"md\" />\n\n <div className=\"eidos-theme-editor-row__diagnostics\">\n <Tooltip message={detail}>\n <span className={`eidos-theme-editor-badge eidos-theme-editor-badge--${grade}`}>\n <badge.icon className=\"eidos-theme-editor-badge__icon\" />\n {`${ratio.toFixed(2)}:1 ${badge.label}`}\n </span>\n </Tooltip>\n {edgeWarning && (\n <Tooltip message={edgeWarning}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Invisible on page\n </span>\n </Tooltip>\n )}\n </div>\n\n <div className=\"eidos-theme-editor-row__actions\">\n <IconButton\n icon=\"RotateCcw\"\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n disabled={!overridden}\n onClick={() => resetColor(key)}\n tooltip={overridden ? `Reset ${COLOR_LABELS[key]} to the preset` : 'Unchanged'}\n aria-label={`Reset ${COLOR_LABELS[key]}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n </Card>\n\n {!hideTypography && (\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Typography</span>\n <span className=\"eidos-theme-editor-section__hint\">\n A stack only names a font - upload the file to use one the browser doesn&apos;t\n already have. Spacing is declared in <code>em</code>, so the scale moves padding with\n the text.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n <FontRow\n label=\"Body font\"\n value={resolvedTheme.typography.fontFamily}\n options={[...fontOptions, ...uploaded]}\n mono={false}\n allowUpload={allowFontUpload}\n onChange={(fontFamily) => updateTheme({ typography: { fontFamily } })}\n onUploaded={(option, file, family) => {\n setUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, false);\n }}\n />\n\n <FontRow\n label=\"Mono font\"\n value={resolvedTheme.typography.monoFamily}\n options={[...monoFontOptions, ...monoUploaded]}\n mono\n allowUpload={allowFontUpload}\n onChange={(monoFamily) => updateTheme({ typography: { monoFamily } })}\n onUploaded={(option, file, family) => {\n setMonoUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, true);\n }}\n />\n\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">Scale</span>\n <div className=\"eidos-theme-editor-row__control\">\n <Slider\n value={resolvedTheme.typography.fontScale}\n min={FONT_SCALE_MIN}\n max={FONT_SCALE_MAX}\n step={0.025}\n showValue\n showMinMax\n unit=\"×\"\n onChange={(value) => updateTheme({ typography: { fontScale: value } })}\n />\n </div>\n </div>\n </div>\n </Card>\n )}\n\n {(!hideReset || !hideCssExport) && (\n <div className=\"eidos-theme-editor-actions\">\n {!hideReset && (\n <Button variant=\"outlined\" color=\"secondary\" disabled={isDefault} onClick={resetTheme}>\n Reset all\n </Button>\n )}\n {!hideCssExport && (\n <Button\n variant=\"outlined\"\n preIcon={copied ? 'Check' : 'Clipboard'}\n onClick={copyCss}\n tooltip=\"Copy the resolved tokens as a :root block you can paste into your own stylesheet\"\n >\n {copied ? 'Copied' : 'Copy as CSS'}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n\nThemeEditor.displayName = 'ThemeEditor';\n"]}
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkKJZUYC4Xcjs = require('./chunk-KJZUYC4X.cjs');
3
+ var _chunkHI6WCX4Tcjs = require('./chunk-HI6WCX4T.cjs');
4
4
 
5
5
 
6
- var _chunkAPK5OQRVcjs = require('./chunk-APK5OQRV.cjs');
6
+ var _chunkWWYJNWJYcjs = require('./chunk-WWYJNWJY.cjs');
7
7
 
8
8
  // src/components/Pagination/Pagination.component.tsx
9
9
  var _react = require('react');
@@ -78,7 +78,7 @@ var Pagination = ({
78
78
  ].filter(Boolean).join(" ");
79
79
  const nav = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { "aria-label": "Pagination", className: "eidos-pagination-nav", children: [
80
80
  showFirstLast && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
81
- _chunkAPK5OQRVcjs.Button,
81
+ _chunkWWYJNWJYcjs.Button,
82
82
  {
83
83
  variant: "text",
84
84
  size,
@@ -89,7 +89,7 @@ var Pagination = ({
89
89
  }
90
90
  ),
91
91
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
92
- _chunkAPK5OQRVcjs.Button,
92
+ _chunkWWYJNWJYcjs.Button,
93
93
  {
94
94
  variant: "text",
95
95
  size,
@@ -145,7 +145,7 @@ var Pagination = ({
145
145
  )
146
146
  ),
147
147
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
148
- _chunkAPK5OQRVcjs.Button,
148
+ _chunkWWYJNWJYcjs.Button,
149
149
  {
150
150
  variant: "text",
151
151
  size,
@@ -156,7 +156,7 @@ var Pagination = ({
156
156
  }
157
157
  ),
158
158
  showFirstLast && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
159
- _chunkAPK5OQRVcjs.Button,
159
+ _chunkWWYJNWJYcjs.Button,
160
160
  {
161
161
  variant: "text",
162
162
  size,
@@ -184,7 +184,7 @@ var Pagination = ({
184
184
  hasPageSize && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "eidos-pagination-size", children: [
185
185
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { className: "eidos-pagination-size-label", children: "Show:" }),
186
186
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
187
- _chunkKJZUYC4Xcjs.Select,
187
+ _chunkHI6WCX4Tcjs.Select,
188
188
  {
189
189
  value: String(pageSize),
190
190
  onChange: (val) => onPageSizeChange(Number(val)),
@@ -208,4 +208,4 @@ Pagination.displayName = "Pagination";
208
208
 
209
209
 
210
210
  exports.Pagination = Pagination;
211
- //# sourceMappingURL=chunk-AXBYJ2OY.cjs.map
211
+ //# sourceMappingURL=chunk-WFEORBLC.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-AXBYJ2OY.cjs","../src/components/Pagination/Pagination.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-AXBYJ2OY.cjs","sourcesContent":[null,"import React, { useState, useEffect } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';\nimport { Button } from '../Button';\nimport { Select } from '../Select';\nimport type { PaginationProps } from './Pagination.types';\n\n// ── Ellipsis range helper ─────────────────────────────────────────────────────\n\nconst ELLIPSIS = 'ellipsis' as const;\ntype PageItem = number | typeof ELLIPSIS;\n\nfunction usePaginationRange(page: number, totalPages: number, siblingCount: number): PageItem[] {\n const totalShown = siblingCount * 2 + 5;\n\n if (totalPages <= totalShown) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const leftSibling = Math.max(page - siblingCount, 1);\n const rightSibling = Math.min(page + siblingCount, totalPages);\n\n const showLeftEllipsis = leftSibling > 2;\n const showRightEllipsis = rightSibling < totalPages - 1;\n\n const items: PageItem[] = [1];\n\n if (showLeftEllipsis) {\n items.push(ELLIPSIS);\n } else {\n for (let i = 2; i < leftSibling; i++) items.push(i);\n }\n\n for (let i = leftSibling; i <= rightSibling; i++) {\n if (i !== 1 && i !== totalPages) items.push(i);\n }\n\n if (showRightEllipsis) {\n items.push(ELLIPSIS);\n } else {\n for (let i = rightSibling + 1; i < totalPages; i++) items.push(i);\n }\n\n items.push(totalPages);\n\n return items;\n}\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport const Pagination: React.FC<PaginationProps> = ({\n page,\n totalPages,\n onChange,\n siblingCount = 1,\n showFirstLast = false,\n color = 'primary',\n size = 'sm',\n disabled = false,\n className = '',\n // Table-footer mode\n totalItems,\n pageSize,\n onPageSizeChange,\n pageSizeOptions = [10, 25, 50, 100],\n}) => {\n const items = usePaginationRange(page, totalPages, siblingCount);\n\n // ── Active-page editable input ─────────────────────────────────────────────\n const [inputValue, setInputValue] = useState(String(page));\n useEffect(() => {\n setInputValue(String(page));\n }, [page]);\n\n const commitInput = (raw: string) => {\n const val = parseInt(raw, 10);\n if (!isNaN(val) && val >= 1 && val <= totalPages && val !== page) {\n onChange(val);\n } else {\n setInputValue(String(page)); // revert on invalid or same-page\n }\n };\n\n // ── Layout flags ───────────────────────────────────────────────────────────\n const hasResults = totalItems !== undefined && pageSize !== undefined;\n const hasPageSize = !!onPageSizeChange && pageSize !== undefined;\n const tableMode = hasResults || hasPageSize;\n\n const startItem = hasResults ? (totalItems === 0 ? 0 : (page - 1) * pageSize! + 1) : undefined;\n const endItem = hasResults ? Math.min(page * pageSize!, totalItems!) : undefined;\n\n const rootClasses = [\n 'eidos-pagination',\n `eidos-pagination--${size}`,\n tableMode && 'eidos-pagination--table',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n // ── Navigation block ───────────────────────────────────────────────────────\n const nav = (\n <nav aria-label=\"Pagination\" className=\"eidos-pagination-nav\">\n {showFirstLast && (\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronsLeft}\n disabled={page === 1 || disabled}\n onClick={() => onChange(1)}\n aria-label=\"First page\"\n />\n )}\n\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronLeft}\n disabled={page === 1 || disabled}\n onClick={() => onChange(page - 1)}\n aria-label=\"Previous page\"\n />\n\n {items.map((item, i) =>\n item === ELLIPSIS ? (\n <span key={`ellipsis-${i}`} className=\"eidos-pagination-ellipsis\" aria-hidden=\"true\">\n …\n </span>\n ) : item === page ? (\n // Active page - styled as filled chip, editable via keyboard/click\n <input\n key=\"active-page\"\n type=\"text\"\n inputMode=\"numeric\"\n className={[\n 'eidos-pagination-page',\n 'eidos-pagination-page--active',\n `eidos-pagination-page--${color}`,\n ].join(' ')}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onFocus={(e) => e.target.select()}\n onBlur={() => commitInput(inputValue)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n commitInput(inputValue);\n e.currentTarget.blur();\n } else if (e.key === 'Escape') {\n setInputValue(String(page));\n e.currentTarget.blur();\n }\n }}\n aria-label={`Page ${page} of ${totalPages}, editable`}\n aria-current=\"page\"\n disabled={disabled}\n />\n ) : (\n <button\n key={item}\n type=\"button\"\n className=\"eidos-pagination-page\"\n onClick={() => onChange(item)}\n disabled={disabled}\n aria-label={`Page ${item}`}\n >\n {item}\n </button>\n ),\n )}\n\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronRight}\n disabled={page === totalPages || disabled}\n onClick={() => onChange(page + 1)}\n aria-label=\"Next page\"\n />\n\n {showFirstLast && (\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronsRight}\n disabled={page === totalPages || disabled}\n onClick={() => onChange(totalPages)}\n aria-label=\"Last page\"\n />\n )}\n </nav>\n );\n\n // ── Standalone mode ────────────────────────────────────────────────────────\n if (!tableMode) {\n return <div className={rootClasses}>{nav}</div>;\n }\n\n // ── Table-footer mode ──────────────────────────────────────────────────────\n return (\n <div className={rootClasses}>\n {hasResults && (\n <span className=\"eidos-pagination-info\">\n Showing {startItem}-{endItem} of {totalItems} results\n </span>\n )}\n\n <div className=\"eidos-pagination-controls\">\n {hasPageSize && (\n <div className=\"eidos-pagination-size\">\n <label className=\"eidos-pagination-size-label\">Show:</label>\n <Select\n value={String(pageSize)}\n onChange={(val) => onPageSizeChange(Number(val))}\n options={pageSizeOptions.map((n) => ({\n id: String(n),\n value: String(n),\n label: String(n),\n }))}\n clearable={false}\n disabled={disabled}\n // Sizes the whole field, chevron and padding included - wide\n // enough for a 3-digit page size. `'3ch'` used to work here only\n // because `Input.width` sized the inner <input> and let the\n // chrome overflow it; now that it sizes the field, 3ch left no\n // room for the value at all.\n inputProps={{ size: 'sm', width: 72 }}\n />\n </div>\n )}\n\n {totalPages > 1 && nav}\n </div>\n </div>\n );\n};\n\nPagination.displayName = 'Pagination';\n"]}
1
+ {"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-WFEORBLC.cjs","../src/components/Pagination/Pagination.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-WFEORBLC.cjs","sourcesContent":[null,"import React, { useState, useEffect } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';\nimport { Button } from '../Button';\nimport { Select } from '../Select';\nimport type { PaginationProps } from './Pagination.types';\n\n// ── Ellipsis range helper ─────────────────────────────────────────────────────\n\nconst ELLIPSIS = 'ellipsis' as const;\ntype PageItem = number | typeof ELLIPSIS;\n\nfunction usePaginationRange(page: number, totalPages: number, siblingCount: number): PageItem[] {\n const totalShown = siblingCount * 2 + 5;\n\n if (totalPages <= totalShown) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const leftSibling = Math.max(page - siblingCount, 1);\n const rightSibling = Math.min(page + siblingCount, totalPages);\n\n const showLeftEllipsis = leftSibling > 2;\n const showRightEllipsis = rightSibling < totalPages - 1;\n\n const items: PageItem[] = [1];\n\n if (showLeftEllipsis) {\n items.push(ELLIPSIS);\n } else {\n for (let i = 2; i < leftSibling; i++) items.push(i);\n }\n\n for (let i = leftSibling; i <= rightSibling; i++) {\n if (i !== 1 && i !== totalPages) items.push(i);\n }\n\n if (showRightEllipsis) {\n items.push(ELLIPSIS);\n } else {\n for (let i = rightSibling + 1; i < totalPages; i++) items.push(i);\n }\n\n items.push(totalPages);\n\n return items;\n}\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport const Pagination: React.FC<PaginationProps> = ({\n page,\n totalPages,\n onChange,\n siblingCount = 1,\n showFirstLast = false,\n color = 'primary',\n size = 'sm',\n disabled = false,\n className = '',\n // Table-footer mode\n totalItems,\n pageSize,\n onPageSizeChange,\n pageSizeOptions = [10, 25, 50, 100],\n}) => {\n const items = usePaginationRange(page, totalPages, siblingCount);\n\n // ── Active-page editable input ─────────────────────────────────────────────\n const [inputValue, setInputValue] = useState(String(page));\n useEffect(() => {\n setInputValue(String(page));\n }, [page]);\n\n const commitInput = (raw: string) => {\n const val = parseInt(raw, 10);\n if (!isNaN(val) && val >= 1 && val <= totalPages && val !== page) {\n onChange(val);\n } else {\n setInputValue(String(page)); // revert on invalid or same-page\n }\n };\n\n // ── Layout flags ───────────────────────────────────────────────────────────\n const hasResults = totalItems !== undefined && pageSize !== undefined;\n const hasPageSize = !!onPageSizeChange && pageSize !== undefined;\n const tableMode = hasResults || hasPageSize;\n\n const startItem = hasResults ? (totalItems === 0 ? 0 : (page - 1) * pageSize! + 1) : undefined;\n const endItem = hasResults ? Math.min(page * pageSize!, totalItems!) : undefined;\n\n const rootClasses = [\n 'eidos-pagination',\n `eidos-pagination--${size}`,\n tableMode && 'eidos-pagination--table',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n // ── Navigation block ───────────────────────────────────────────────────────\n const nav = (\n <nav aria-label=\"Pagination\" className=\"eidos-pagination-nav\">\n {showFirstLast && (\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronsLeft}\n disabled={page === 1 || disabled}\n onClick={() => onChange(1)}\n aria-label=\"First page\"\n />\n )}\n\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronLeft}\n disabled={page === 1 || disabled}\n onClick={() => onChange(page - 1)}\n aria-label=\"Previous page\"\n />\n\n {items.map((item, i) =>\n item === ELLIPSIS ? (\n <span key={`ellipsis-${i}`} className=\"eidos-pagination-ellipsis\" aria-hidden=\"true\">\n …\n </span>\n ) : item === page ? (\n // Active page - styled as filled chip, editable via keyboard/click\n <input\n key=\"active-page\"\n type=\"text\"\n inputMode=\"numeric\"\n className={[\n 'eidos-pagination-page',\n 'eidos-pagination-page--active',\n `eidos-pagination-page--${color}`,\n ].join(' ')}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onFocus={(e) => e.target.select()}\n onBlur={() => commitInput(inputValue)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n commitInput(inputValue);\n e.currentTarget.blur();\n } else if (e.key === 'Escape') {\n setInputValue(String(page));\n e.currentTarget.blur();\n }\n }}\n aria-label={`Page ${page} of ${totalPages}, editable`}\n aria-current=\"page\"\n disabled={disabled}\n />\n ) : (\n <button\n key={item}\n type=\"button\"\n className=\"eidos-pagination-page\"\n onClick={() => onChange(item)}\n disabled={disabled}\n aria-label={`Page ${item}`}\n >\n {item}\n </button>\n ),\n )}\n\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronRight}\n disabled={page === totalPages || disabled}\n onClick={() => onChange(page + 1)}\n aria-label=\"Next page\"\n />\n\n {showFirstLast && (\n <Button\n variant=\"text\"\n size={size}\n icon={ChevronsRight}\n disabled={page === totalPages || disabled}\n onClick={() => onChange(totalPages)}\n aria-label=\"Last page\"\n />\n )}\n </nav>\n );\n\n // ── Standalone mode ────────────────────────────────────────────────────────\n if (!tableMode) {\n return <div className={rootClasses}>{nav}</div>;\n }\n\n // ── Table-footer mode ──────────────────────────────────────────────────────\n return (\n <div className={rootClasses}>\n {hasResults && (\n <span className=\"eidos-pagination-info\">\n Showing {startItem}-{endItem} of {totalItems} results\n </span>\n )}\n\n <div className=\"eidos-pagination-controls\">\n {hasPageSize && (\n <div className=\"eidos-pagination-size\">\n <label className=\"eidos-pagination-size-label\">Show:</label>\n <Select\n value={String(pageSize)}\n onChange={(val) => onPageSizeChange(Number(val))}\n options={pageSizeOptions.map((n) => ({\n id: String(n),\n value: String(n),\n label: String(n),\n }))}\n clearable={false}\n disabled={disabled}\n // Sizes the whole field, chevron and padding included - wide\n // enough for a 3-digit page size. `'3ch'` used to work here only\n // because `Input.width` sized the inner <input> and let the\n // chrome overflow it; now that it sizes the field, 3ch left no\n // room for the value at all.\n inputProps={{ size: 'sm', width: 72 }}\n />\n </div>\n )}\n\n {totalPages > 1 && nav}\n </div>\n </div>\n );\n};\n\nPagination.displayName = 'Pagination';\n"]}
@@ -0,0 +1,145 @@
1
+ import {
2
+ Popover
3
+ } from "./chunk-5HUZYY54.js";
4
+ import {
5
+ Avatar
6
+ } from "./chunk-XJBWFDDE.js";
7
+ import {
8
+ Button
9
+ } from "./chunk-L5Q6UDY3.js";
10
+ import {
11
+ devWarn,
12
+ renderIcon
13
+ } from "./chunk-EAJHEYZM.js";
14
+
15
+ // src/components/Header/Header.component.tsx
16
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
17
+ import { jsx, jsxs } from "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 = useRef(null);
31
+ const [isNarrow, setIsNarrow] = useState(false);
32
+ const [overflowOpen, setOverflowOpen] = useState(false);
33
+ const measure = useCallback(() => {
34
+ const element = rootRef.current;
35
+ if (!element) return;
36
+ setIsNarrow(element.getBoundingClientRect().width <= collapseActionsBelow);
37
+ }, [collapseActionsBelow]);
38
+ useLayoutEffect(() => {
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 = 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
+ useEffect(() => {
56
+ if (!isCollapsed && overflowOpen) setOverflowOpen(false);
57
+ }, [isCollapsed, overflowOpen]);
58
+ const renderOverflowAction = (action, index) => {
59
+ const handleClick = (event) => {
60
+ action.onClick?.(event);
61
+ setOverflowOpen(false);
62
+ };
63
+ if (action.icon && !action.children && action.tooltip) {
64
+ const { icon, tooltip, ...rest } = action;
65
+ return /* @__PURE__ */ jsx(Button, { ...rest, size: "md", preIcon: icon, onClick: handleClick, children: tooltip }, index);
66
+ }
67
+ return /* @__PURE__ */ jsx(Button, { ...action, size: "md", onClick: handleClick }, index);
68
+ };
69
+ const titles = /* @__PURE__ */ jsxs("div", { className: "eidos-header__titles", children: [
70
+ /* @__PURE__ */ jsx("h1", { className: "eidos-header__title", children: title }),
71
+ subtitle && /* @__PURE__ */ jsx("span", { className: "eidos-header__subtitle", children: subtitle }),
72
+ !!meta?.length && /* @__PURE__ */ jsx("div", { className: "eidos-header__meta", children: meta.map((item, index) => /* @__PURE__ */ jsxs("span", { className: "eidos-header__meta-item", children: [
73
+ item.icon && renderIcon(item.icon, "eidos-header__meta-icon"),
74
+ item.label && /* @__PURE__ */ jsx("span", { className: "eidos-header__meta-label", children: item.label }),
75
+ /* @__PURE__ */ jsx("span", { className: "eidos-header__meta-value", children: item.value })
76
+ ] }, index)) })
77
+ ] });
78
+ return /* @__PURE__ */ jsx("div", { className: classes, ref: rootRef, children: /* @__PURE__ */ jsxs("div", { className: "eidos-header__content", children: [
79
+ media ? /* @__PURE__ */ jsxs("div", { className: "eidos-header__lead", children: [
80
+ /* @__PURE__ */ jsx("div", { className: "eidos-header__media", children: media }),
81
+ titles
82
+ ] }) : titles,
83
+ /* @__PURE__ */ jsxs("div", { className: "eidos-header__actions", children: [
84
+ overflowActions.length > 0 && /* @__PURE__ */ jsx(
85
+ 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__ */ jsx(
96
+ 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__ */ jsx("div", { className: "eidos-header__overflow-actions", children: overflowActions.map(renderOverflowAction) })
107
+ }
108
+ ),
109
+ inlineActions.map((action, index) => /* @__PURE__ */ jsx(Button, { size: "md", ...action }, index))
110
+ ] })
111
+ ] }) });
112
+ };
113
+
114
+ // src/components/Header/IdentityHeader.component.tsx
115
+ import { jsx as jsx2 } from "react/jsx-runtime";
116
+ var IdentityHeader = ({
117
+ avatar,
118
+ media,
119
+ variant = "hero",
120
+ className = "",
121
+ ...rest
122
+ }) => {
123
+ if (avatar && media) {
124
+ devWarn(
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 = media ?? (avatar ? /* @__PURE__ */ jsx2(Avatar, { size: "lg", ...avatar }) : void 0);
130
+ return /* @__PURE__ */ jsx2(
131
+ Header,
132
+ {
133
+ ...rest,
134
+ variant,
135
+ media: resolvedMedia,
136
+ className: ["eidos-identity-header", className].filter(Boolean).join(" ")
137
+ }
138
+ );
139
+ };
140
+
141
+ export {
142
+ Header,
143
+ IdentityHeader
144
+ };
145
+ //# sourceMappingURL=chunk-WKDT2XFQ.js.map