@techzyapp/ui-library 1.0.41 → 1.0.42

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 (528) hide show
  1. package/README.md +14 -8
  2. package/dist/AdminRoot-DufZpgdm.js +100 -0
  3. package/dist/AdminRoot-DufZpgdm.js.map +1 -0
  4. package/dist/AdminRoot-DwJ5jdXr.cjs +2 -0
  5. package/dist/AdminRoot-DwJ5jdXr.cjs.map +1 -0
  6. package/dist/Alert-C8BBxL_7.cjs +2 -0
  7. package/dist/Alert-C8BBxL_7.cjs.map +1 -0
  8. package/dist/Alert-D6oBxBdP.js +70 -0
  9. package/dist/Alert-D6oBxBdP.js.map +1 -0
  10. package/dist/AuthLayout-exuNQicH.cjs.map +1 -1
  11. package/dist/AuthLayout-q8pbCGdt.js.map +1 -1
  12. package/dist/{Breadcrumbs-B6Pii2Y_.cjs → Breadcrumbs-B-olYVdw.cjs} +2 -2
  13. package/dist/Breadcrumbs-B-olYVdw.cjs.map +1 -0
  14. package/dist/{Breadcrumbs-DKYJOdHZ.js → Breadcrumbs-cXET6OM5.js} +3 -3
  15. package/dist/Breadcrumbs-cXET6OM5.js.map +1 -0
  16. package/dist/{Button-CjsnB8gX.js → Button-0ZgdNjX-.js} +2 -2
  17. package/dist/{Button-CjsnB8gX.js.map → Button-0ZgdNjX-.js.map} +1 -1
  18. package/dist/{Button-ClVfHGBc.cjs → Button-CwrDiZek.cjs} +2 -2
  19. package/dist/{Button-ClVfHGBc.cjs.map → Button-CwrDiZek.cjs.map} +1 -1
  20. package/dist/{Calendar-CQaPEukM.js → Calendar-CxzdnzdK.js} +3 -3
  21. package/dist/{Calendar-CQaPEukM.js.map → Calendar-CxzdnzdK.js.map} +1 -1
  22. package/dist/{Calendar-BzGVX4F4.cjs → Calendar-d3CX5UJp.cjs} +2 -2
  23. package/dist/{Calendar-BzGVX4F4.cjs.map → Calendar-d3CX5UJp.cjs.map} +1 -1
  24. package/dist/Card-CjqStov5.js +129 -0
  25. package/dist/Card-CjqStov5.js.map +1 -0
  26. package/dist/Card-CxnUoWsi.cjs +2 -0
  27. package/dist/Card-CxnUoWsi.cjs.map +1 -0
  28. package/dist/{Chip-Dp8skUZ2.cjs → Chip-BkU3yx6G.cjs} +2 -2
  29. package/dist/Chip-BkU3yx6G.cjs.map +1 -0
  30. package/dist/{Chip-BjSNgaAf.js → Chip-CzJjbaKx.js} +2 -2
  31. package/dist/Chip-CzJjbaKx.js.map +1 -0
  32. package/dist/ChoiceCardGroup-C7Eengyd.cjs +2 -0
  33. package/dist/ChoiceCardGroup-C7Eengyd.cjs.map +1 -0
  34. package/dist/ChoiceCardGroup-q0yN-TeQ.js +180 -0
  35. package/dist/{ChoiceCardGroup-143hR0v_.cjs.map → ChoiceCardGroup-q0yN-TeQ.js.map} +1 -1
  36. package/dist/{CodeBlock-CcJjS0_q.js → CodeBlock-BHcvQrs9.js} +3 -3
  37. package/dist/CodeBlock-BHcvQrs9.js.map +1 -0
  38. package/dist/{CodeBlock-o_VSkAek.cjs → CodeBlock-DRBQ_S5t.cjs} +2 -2
  39. package/dist/CodeBlock-DRBQ_S5t.cjs.map +1 -0
  40. package/dist/{ColorPicker-C1hZcAbH.js → ColorPicker-BQKFdTNr.js} +51 -51
  41. package/dist/{ColorPicker-C1hZcAbH.js.map → ColorPicker-BQKFdTNr.js.map} +1 -1
  42. package/dist/ColorPicker-BzCEMN7B.cjs +2 -0
  43. package/dist/{ColorPicker-DY6Vk1uS.cjs.map → ColorPicker-BzCEMN7B.cjs.map} +1 -1
  44. package/dist/{ColorPickerPanel-BuzwmkPN.js → ColorPickerPanel-DKTKC9KH.js} +2 -2
  45. package/dist/{ColorPickerPanel-BuzwmkPN.js.map → ColorPickerPanel-DKTKC9KH.js.map} +1 -1
  46. package/dist/{ColorPickerPanel-CDrHbCfG.cjs → ColorPickerPanel-kl2jUix-.cjs} +2 -2
  47. package/dist/{ColorPickerPanel-CDrHbCfG.cjs.map → ColorPickerPanel-kl2jUix-.cjs.map} +1 -1
  48. package/dist/{ColorRamp-CVnOYlu3.cjs → ColorRamp-n7muILK3.cjs} +2 -2
  49. package/dist/{ColorRamp-CVnOYlu3.cjs.map → ColorRamp-n7muILK3.cjs.map} +1 -1
  50. package/dist/{ColorRamp-CePqEkMR.js → ColorRamp-yfMyJCyx.js} +2 -2
  51. package/dist/{ColorRamp-CePqEkMR.js.map → ColorRamp-yfMyJCyx.js.map} +1 -1
  52. package/dist/{ConfigProvider-DELhJlqo.cjs → ConfigProvider-BaiTKZKC.cjs} +2 -2
  53. package/dist/ConfigProvider-BaiTKZKC.cjs.map +1 -0
  54. package/dist/{ConfigProvider-Bgu85MsI.js → ConfigProvider-D61cpCz-.js} +2 -2
  55. package/dist/ConfigProvider-D61cpCz-.js.map +1 -0
  56. package/dist/{CopyButton-CjPyKpky.cjs → CopyButton-DlSi82gv.cjs} +2 -2
  57. package/dist/{CopyButton-CjPyKpky.cjs.map → CopyButton-DlSi82gv.cjs.map} +1 -1
  58. package/dist/{CopyButton-CgDeyJ3A.js → CopyButton-ecxn-ghi.js} +3 -3
  59. package/dist/{CopyButton-CgDeyJ3A.js.map → CopyButton-ecxn-ghi.js.map} +1 -1
  60. package/dist/DatePicker-BjZ_P21i.cjs +2 -0
  61. package/dist/{DatePicker-CwZ_-ElE.cjs.map → DatePicker-BjZ_P21i.cjs.map} +1 -1
  62. package/dist/{DatePicker-tid4OuJ2.js → DatePicker-CAGpJbDi.js} +42 -42
  63. package/dist/{DatePicker-tid4OuJ2.js.map → DatePicker-CAGpJbDi.js.map} +1 -1
  64. package/dist/{DateTimePicker-C2871cuc.js → DateTimePicker-BJmF0Su6.js} +50 -50
  65. package/dist/DateTimePicker-BJmF0Su6.js.map +1 -0
  66. package/dist/DateTimePicker-DZqWQeUL.cjs +2 -0
  67. package/dist/DateTimePicker-DZqWQeUL.cjs.map +1 -0
  68. package/dist/{DescriptionList-BWw0Fe6U.cjs → DescriptionList-CvPDn-kh.cjs} +2 -2
  69. package/dist/DescriptionList-CvPDn-kh.cjs.map +1 -0
  70. package/dist/{DescriptionList-BP4CDME5.js → DescriptionList-Knq5eCiY.js} +4 -4
  71. package/dist/DescriptionList-Knq5eCiY.js.map +1 -0
  72. package/dist/{Dropdown-DYYhzKSo.cjs → Dropdown-CMjURWYd.cjs} +2 -2
  73. package/dist/{Dropdown-DYYhzKSo.cjs.map → Dropdown-CMjURWYd.cjs.map} +1 -1
  74. package/dist/{Dropdown-CcC-Hwx4.js → Dropdown-CnDBlB02.js} +2 -2
  75. package/dist/{Dropdown-CcC-Hwx4.js.map → Dropdown-CnDBlB02.js.map} +1 -1
  76. package/dist/{EmptyState-DGHOD_jy.cjs → EmptyState-CX1g47y_.cjs} +2 -2
  77. package/dist/{EmptyState-DGHOD_jy.cjs.map → EmptyState-CX1g47y_.cjs.map} +1 -1
  78. package/dist/{EmptyState-BlmQtbSs.js → EmptyState-Dqtpmtje.js} +2 -2
  79. package/dist/{EmptyState-BlmQtbSs.js.map → EmptyState-Dqtpmtje.js.map} +1 -1
  80. package/dist/{ErrorBoundary-DL194IyB.cjs → ErrorBoundary-B8KwWXXp.cjs} +2 -2
  81. package/dist/{ErrorBoundary-DL194IyB.cjs.map → ErrorBoundary-B8KwWXXp.cjs.map} +1 -1
  82. package/dist/{ErrorBoundary-ukRaS6uS.js → ErrorBoundary-Dos7VLb-.js} +3 -3
  83. package/dist/{ErrorBoundary-ukRaS6uS.js.map → ErrorBoundary-Dos7VLb-.js.map} +1 -1
  84. package/dist/{ErrorState-BjEA0VfF.cjs → ErrorState-CwCqd2PU.cjs} +2 -2
  85. package/dist/{ErrorState-BjEA0VfF.cjs.map → ErrorState-CwCqd2PU.cjs.map} +1 -1
  86. package/dist/{ErrorState-Hfd_0MeE.js → ErrorState-KhzrGIJ-.js} +7 -7
  87. package/dist/{ErrorState-Hfd_0MeE.js.map → ErrorState-KhzrGIJ-.js.map} +1 -1
  88. package/dist/{FileCard-COc4rHe-.cjs → FileCard-DEc10T2G.cjs} +2 -2
  89. package/dist/FileCard-DEc10T2G.cjs.map +1 -0
  90. package/dist/{FileCard-CWwB8CWF.js → FileCard-SSuFS13E.js} +3 -3
  91. package/dist/FileCard-SSuFS13E.js.map +1 -0
  92. package/dist/{FileUploader-Bqy_fV7l.cjs → FileUploader-D58_6kDA.cjs} +2 -2
  93. package/dist/FileUploader-D58_6kDA.cjs.map +1 -0
  94. package/dist/{FileUploader--WOmlhSh.js → FileUploader-DfYOBFa4.js} +5 -5
  95. package/dist/FileUploader-DfYOBFa4.js.map +1 -0
  96. package/dist/{Flag-C48Zfhvb.cjs → Flag-B1ZvZVXi.cjs} +2 -2
  97. package/dist/{Flag-C48Zfhvb.cjs.map → Flag-B1ZvZVXi.cjs.map} +1 -1
  98. package/dist/{Flag-fgMTTcy8.js → Flag-BEIqYQZg.js} +2 -2
  99. package/dist/{Flag-fgMTTcy8.js.map → Flag-BEIqYQZg.js.map} +1 -1
  100. package/dist/FloatingPanel-C5c_eMQ0.js.map +1 -1
  101. package/dist/FloatingPanel-tGCG2nhA.cjs.map +1 -1
  102. package/dist/{FullscreenToggle-GjsMn1GO.js → FullscreenToggle-I_In47BB.js} +3 -3
  103. package/dist/{FullscreenToggle-GjsMn1GO.js.map → FullscreenToggle-I_In47BB.js.map} +1 -1
  104. package/dist/{FullscreenToggle-DuLaUzi_.cjs → FullscreenToggle-Po769CoC.cjs} +2 -2
  105. package/dist/{FullscreenToggle-DuLaUzi_.cjs.map → FullscreenToggle-Po769CoC.cjs.map} +1 -1
  106. package/dist/{IconButton-D3ZpI0XL.cjs → IconButton-CxSXEYce.cjs} +2 -2
  107. package/dist/{IconButton-D3ZpI0XL.cjs.map → IconButton-CxSXEYce.cjs.map} +1 -1
  108. package/dist/{IconButton-t1OhAMNc.js → IconButton-D9MCwRK_.js} +2 -2
  109. package/dist/{IconButton-t1OhAMNc.js.map → IconButton-D9MCwRK_.js.map} +1 -1
  110. package/dist/{List-CwuAJDTi.js → List-2Y3ktTcF.js} +2 -2
  111. package/dist/{List-CwuAJDTi.js.map → List-2Y3ktTcF.js.map} +1 -1
  112. package/dist/{List-B5Ppe9R1.cjs → List-CKoNx21F.cjs} +2 -2
  113. package/dist/{List-B5Ppe9R1.cjs.map → List-CKoNx21F.cjs.map} +1 -1
  114. package/dist/{ListItem-BWNIbyTh.js → ListItem-2Lr5_NRY.js} +15 -15
  115. package/dist/{ListItem-BWNIbyTh.js.map → ListItem-2Lr5_NRY.js.map} +1 -1
  116. package/dist/ListItem-DkCYXucd.cjs +2 -0
  117. package/dist/{ListItem-Qo1Tt6Fi.cjs.map → ListItem-DkCYXucd.cjs.map} +1 -1
  118. package/dist/{Loader-Cywaf7ju.cjs → Loader-5zp2MPm5.cjs} +2 -2
  119. package/dist/{Loader-Cywaf7ju.cjs.map → Loader-5zp2MPm5.cjs.map} +1 -1
  120. package/dist/{Loader-De8_GqR1.js → Loader-Bluu6z0-.js} +2 -2
  121. package/dist/{Loader-De8_GqR1.js.map → Loader-Bluu6z0-.js.map} +1 -1
  122. package/dist/{LocationPicker-DBsxCYi9.cjs → LocationPicker-CGHXTIml.cjs} +2 -2
  123. package/dist/{LocationPicker-DBsxCYi9.cjs.map → LocationPicker-CGHXTIml.cjs.map} +1 -1
  124. package/dist/{LocationPicker-UfyDBvhp.js → LocationPicker-hULpHBVG.js} +7 -7
  125. package/dist/{LocationPicker-UfyDBvhp.js.map → LocationPicker-hULpHBVG.js.map} +1 -1
  126. package/dist/{Modal-Dfwc9eIq.js → Modal-C6Zgwz_6.js} +3 -3
  127. package/dist/Modal-C6Zgwz_6.js.map +1 -0
  128. package/dist/{Modal--5EbLfMz.cjs → Modal-D9_OG53G.cjs} +2 -2
  129. package/dist/Modal-D9_OG53G.cjs.map +1 -0
  130. package/dist/{MultiSelect-lBAEcAlR.cjs → MultiSelect-BdPvjiTj.cjs} +2 -2
  131. package/dist/{MultiSelect-lBAEcAlR.cjs.map → MultiSelect-BdPvjiTj.cjs.map} +1 -1
  132. package/dist/{MultiSelect-q__o8HyU.js → MultiSelect-CHLMpim4.js} +4 -4
  133. package/dist/{MultiSelect-q__o8HyU.js.map → MultiSelect-CHLMpim4.js.map} +1 -1
  134. package/dist/{NumberField-CXH0B1Bt.js → NumberField-BlpFmetF.js} +3 -3
  135. package/dist/{NumberField-CXH0B1Bt.js.map → NumberField-BlpFmetF.js.map} +1 -1
  136. package/dist/{NumberField-DSicjq5R.cjs → NumberField-C-FZ-uRI.cjs} +2 -2
  137. package/dist/{NumberField-DSicjq5R.cjs.map → NumberField-C-FZ-uRI.cjs.map} +1 -1
  138. package/dist/OtpField-D4-r7I0A.js +174 -0
  139. package/dist/OtpField-D4-r7I0A.js.map +1 -0
  140. package/dist/OtpField-Drjy2wwq.cjs +2 -0
  141. package/dist/OtpField-Drjy2wwq.cjs.map +1 -0
  142. package/dist/{PageError-MHbSl1oT.cjs → PageError-DXUOkE14.cjs} +2 -2
  143. package/dist/{PageError-MHbSl1oT.cjs.map → PageError-DXUOkE14.cjs.map} +1 -1
  144. package/dist/{PageError-VYc07Q7W.js → PageError-DyDj1wQZ.js} +5 -5
  145. package/dist/{PageError-VYc07Q7W.js.map → PageError-DyDj1wQZ.js.map} +1 -1
  146. package/dist/{PageLayout-Bt6U_80d.cjs → PageLayout-CoG0AaUs.cjs} +2 -2
  147. package/dist/PageLayout-CoG0AaUs.cjs.map +1 -0
  148. package/dist/{PageLayout-Df1SOlr7.js → PageLayout-nsJa8CbT.js} +4 -4
  149. package/dist/PageLayout-nsJa8CbT.js.map +1 -0
  150. package/dist/{PageNotFound-BWfaomjC.js → PageNotFound-BNNwMkwE.js} +5 -5
  151. package/dist/{PageNotFound-BWfaomjC.js.map → PageNotFound-BNNwMkwE.js.map} +1 -1
  152. package/dist/{PageNotFound-e4ITkqDC.cjs → PageNotFound-CGSxT_n9.cjs} +2 -2
  153. package/dist/{PageNotFound-e4ITkqDC.cjs.map → PageNotFound-CGSxT_n9.cjs.map} +1 -1
  154. package/dist/Pagination-CZtewveA.cjs +2 -0
  155. package/dist/Pagination-CZtewveA.cjs.map +1 -0
  156. package/dist/Pagination-tuWRnGwR.js +139 -0
  157. package/dist/Pagination-tuWRnGwR.js.map +1 -0
  158. package/dist/{PaletteField-D4c-Q1PG.js → PaletteField-CTPl3D43.js} +3 -3
  159. package/dist/{PaletteField-D4c-Q1PG.js.map → PaletteField-CTPl3D43.js.map} +1 -1
  160. package/dist/{PaletteField-DnUpn2zP.cjs → PaletteField-PDcu2vUp.cjs} +2 -2
  161. package/dist/{PaletteField-DnUpn2zP.cjs.map → PaletteField-PDcu2vUp.cjs.map} +1 -1
  162. package/dist/{PhoneField-BTB2_Lo1.cjs → PhoneField-BPYg5ZHW.cjs} +2 -2
  163. package/dist/{PhoneField-BTB2_Lo1.cjs.map → PhoneField-BPYg5ZHW.cjs.map} +1 -1
  164. package/dist/{PhoneField-BY5hapKk.js → PhoneField-pdWDCszb.js} +4 -4
  165. package/dist/{PhoneField-BY5hapKk.js.map → PhoneField-pdWDCszb.js.map} +1 -1
  166. package/dist/{Popconfirm-BXa5qLHY.js → Popconfirm-CMVzLaC_.js} +3 -3
  167. package/dist/{Popconfirm-BXa5qLHY.js.map → Popconfirm-CMVzLaC_.js.map} +1 -1
  168. package/dist/{Popconfirm-PkVgBrL-.cjs → Popconfirm-cNpJmkuR.cjs} +2 -2
  169. package/dist/{Popconfirm-PkVgBrL-.cjs.map → Popconfirm-cNpJmkuR.cjs.map} +1 -1
  170. package/dist/Popover-DsYUT23r.cjs.map +1 -1
  171. package/dist/Popover-WaVH3jsN.js.map +1 -1
  172. package/dist/{Progress-bId4RkgJ.js → Progress-BNEFGn-O.js} +2 -2
  173. package/dist/{Progress-bId4RkgJ.js.map → Progress-BNEFGn-O.js.map} +1 -1
  174. package/dist/{Progress-R_Vt4gJA.cjs → Progress-x12Rkh06.cjs} +2 -2
  175. package/dist/{Progress-R_Vt4gJA.cjs.map → Progress-x12Rkh06.cjs.map} +1 -1
  176. package/dist/QrCode-CrNJZV_8.js +81 -0
  177. package/dist/QrCode-CrNJZV_8.js.map +1 -0
  178. package/dist/QrCode-TcQQE0h7.cjs +2 -0
  179. package/dist/QrCode-TcQQE0h7.cjs.map +1 -0
  180. package/dist/{RemoveDialog-Dh_q5jZF.js → RemoveDialog-ARFp1UJM.js} +5 -5
  181. package/dist/{RemoveDialog-Dh_q5jZF.js.map → RemoveDialog-ARFp1UJM.js.map} +1 -1
  182. package/dist/{RemoveDialog-Cvj-DaiY.cjs → RemoveDialog-IWOAQFNK.cjs} +2 -2
  183. package/dist/{RemoveDialog-Cvj-DaiY.cjs.map → RemoveDialog-IWOAQFNK.cjs.map} +1 -1
  184. package/dist/RichTextEditor-C9jT2cLl.cjs +2 -0
  185. package/dist/RichTextEditor-C9jT2cLl.cjs.map +1 -0
  186. package/dist/{RichTextEditor-Dv-LDsN-.js → RichTextEditor-DrwJUEYz.js} +148 -148
  187. package/dist/RichTextEditor-DrwJUEYz.js.map +1 -0
  188. package/dist/RootLayout-CZ2GQ8XA.js +647 -0
  189. package/dist/RootLayout-CZ2GQ8XA.js.map +1 -0
  190. package/dist/RootLayout-DStUP263.cjs +2 -0
  191. package/dist/RootLayout-DStUP263.cjs.map +1 -0
  192. package/dist/{Select-DdkJXkw-.cjs → Select-C2DIfuoB.cjs} +2 -2
  193. package/dist/{Select-DdkJXkw-.cjs.map → Select-C2DIfuoB.cjs.map} +1 -1
  194. package/dist/{Select-Bw8Q86ts.js → Select-KGsA8PbI.js} +3 -3
  195. package/dist/{Select-Bw8Q86ts.js.map → Select-KGsA8PbI.js.map} +1 -1
  196. package/dist/{Sidebar-CGL5hvpl.js → Sidebar-_pcwxdd8.js} +133 -131
  197. package/dist/{Sidebar-CGL5hvpl.js.map → Sidebar-_pcwxdd8.js.map} +1 -1
  198. package/dist/Sidebar-wK1_xaY_.cjs +2 -0
  199. package/dist/{Sidebar-CfEx7W7i.cjs.map → Sidebar-wK1_xaY_.cjs.map} +1 -1
  200. package/dist/Slider-CXAz9SUY.cjs +2 -0
  201. package/dist/Slider-CXAz9SUY.cjs.map +1 -0
  202. package/dist/Slider-Cpc5_dPl.js +185 -0
  203. package/dist/Slider-Cpc5_dPl.js.map +1 -0
  204. package/dist/{SpeedDial-jOxWEd09.cjs → SpeedDial-BT_boD06.cjs} +2 -2
  205. package/dist/{SpeedDial-jOxWEd09.cjs.map → SpeedDial-BT_boD06.cjs.map} +1 -1
  206. package/dist/{SpeedDial-C-yLmnk7.js → SpeedDial-SMMfes9f.js} +2 -2
  207. package/dist/{SpeedDial-C-yLmnk7.js.map → SpeedDial-SMMfes9f.js.map} +1 -1
  208. package/dist/{Stepper-D7An-ugU.cjs → Stepper-BmA_DjTS.cjs} +2 -2
  209. package/dist/Stepper-BmA_DjTS.cjs.map +1 -0
  210. package/dist/{Stepper-DYpiLhzD.js → Stepper-CR0Mlkq7.js} +2 -2
  211. package/dist/Stepper-CR0Mlkq7.js.map +1 -0
  212. package/dist/{Table-BhaH8EKZ.cjs → Table-BkjY1Lwt.cjs} +2 -2
  213. package/dist/Table-BkjY1Lwt.cjs.map +1 -0
  214. package/dist/{Table-DK4GBKS3.js → Table-D-F68lcm.js} +18 -18
  215. package/dist/Table-D-F68lcm.js.map +1 -0
  216. package/dist/{Tabs-6x4vC8je.cjs → Tabs-Cgp6D1WP.cjs} +2 -2
  217. package/dist/{Tabs-6x4vC8je.cjs.map → Tabs-Cgp6D1WP.cjs.map} +1 -1
  218. package/dist/{Tabs-CWiDeqqW.js → Tabs-DP0aZ5TB.js} +2 -2
  219. package/dist/{Tabs-CWiDeqqW.js.map → Tabs-DP0aZ5TB.js.map} +1 -1
  220. package/dist/TagsField-9nKu6ZW4.cjs +2 -0
  221. package/dist/TagsField-9nKu6ZW4.cjs.map +1 -0
  222. package/dist/{TagsField-Cg9YVl7G.js → TagsField-CcY9MTMw.js} +64 -64
  223. package/dist/TagsField-CcY9MTMw.js.map +1 -0
  224. package/dist/{TextField-5nQkU8HP.js → TextField-0WvJsHhA.js} +3 -3
  225. package/dist/{TextField-5nQkU8HP.js.map → TextField-0WvJsHhA.js.map} +1 -1
  226. package/dist/{TextField-BRaoadxk.cjs → TextField-C5MgCQIV.cjs} +2 -2
  227. package/dist/{TextField-BRaoadxk.cjs.map → TextField-C5MgCQIV.cjs.map} +1 -1
  228. package/dist/{ThemeToggle-DhaVEyPL.cjs → ThemeToggle-BvcCxRpF.cjs} +2 -2
  229. package/dist/{ThemeToggle-DhaVEyPL.cjs.map → ThemeToggle-BvcCxRpF.cjs.map} +1 -1
  230. package/dist/{ThemeToggle-DXpbooYn.js → ThemeToggle-DmCePuTy.js} +3 -3
  231. package/dist/{ThemeToggle-DXpbooYn.js.map → ThemeToggle-DmCePuTy.js.map} +1 -1
  232. package/dist/{TimeColumns-girAEgEN.cjs → TimeColumns-Q-vsHFZU.cjs} +2 -2
  233. package/dist/{TimeColumns-girAEgEN.cjs.map → TimeColumns-Q-vsHFZU.cjs.map} +1 -1
  234. package/dist/{TimeColumns-C_gdJn__.js → TimeColumns-WJRHQuFv.js} +2 -2
  235. package/dist/{TimeColumns-C_gdJn__.js.map → TimeColumns-WJRHQuFv.js.map} +1 -1
  236. package/dist/TimePicker-CvbQFzBf.cjs +2 -0
  237. package/dist/{TimePicker-_Ak5yB_5.cjs.map → TimePicker-CvbQFzBf.cjs.map} +1 -1
  238. package/dist/{TimePicker-DHdsY8kQ.js → TimePicker-DJDuSxAg.js} +54 -54
  239. package/dist/{TimePicker-DHdsY8kQ.js.map → TimePicker-DJDuSxAg.js.map} +1 -1
  240. package/dist/{Toaster-Dput5iLU.js → Toaster-Bb5YEN5j.js} +2 -2
  241. package/dist/{Toaster-Dput5iLU.js.map → Toaster-Bb5YEN5j.js.map} +1 -1
  242. package/dist/{Toaster-fjyF8W3F.cjs → Toaster-Dy1AonLa.cjs} +2 -2
  243. package/dist/{Toaster-fjyF8W3F.cjs.map → Toaster-Dy1AonLa.cjs.map} +1 -1
  244. package/dist/TranslatedFields-CuK5KKzE.cjs +2 -0
  245. package/dist/TranslatedFields-CuK5KKzE.cjs.map +1 -0
  246. package/dist/TranslatedFields-DKXznBtD.js +86 -0
  247. package/dist/TranslatedFields-DKXznBtD.js.map +1 -0
  248. package/dist/{UserCard-B9bzkZph.cjs → UserCard-DbudGMvG.cjs} +2 -2
  249. package/dist/UserCard-DbudGMvG.cjs.map +1 -0
  250. package/dist/{UserCard-DYK6S-nr.js → UserCard-UG_Cwe-Y.js} +3 -3
  251. package/dist/UserCard-UG_Cwe-Y.js.map +1 -0
  252. package/dist/app/AdminRoot.d.cts +5 -2
  253. package/dist/app/AdminRoot.d.ts +5 -2
  254. package/dist/components/Alert/Alert.d.cts +1 -1
  255. package/dist/components/Alert/Alert.d.ts +1 -1
  256. package/dist/components/Alert/index.cjs +1 -1
  257. package/dist/components/Alert/index.js +1 -1
  258. package/dist/components/AuthLayout/AuthLayout.d.cts +2 -2
  259. package/dist/components/AuthLayout/AuthLayout.d.ts +2 -2
  260. package/dist/components/Breadcrumbs/Breadcrumbs.d.cts +2 -1
  261. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +2 -1
  262. package/dist/components/Breadcrumbs/index.cjs +1 -1
  263. package/dist/components/Breadcrumbs/index.js +1 -1
  264. package/dist/components/Button/index.cjs +1 -1
  265. package/dist/components/Button/index.js +1 -1
  266. package/dist/components/Card/Card.d.cts +1 -1
  267. package/dist/components/Card/Card.d.ts +1 -1
  268. package/dist/components/Card/index.cjs +1 -1
  269. package/dist/components/Card/index.js +1 -1
  270. package/dist/components/Chip/Chip.d.cts +1 -1
  271. package/dist/components/Chip/Chip.d.ts +1 -1
  272. package/dist/components/Chip/index.cjs +1 -1
  273. package/dist/components/Chip/index.js +1 -1
  274. package/dist/components/ChoiceCard/ChoiceCard.d.cts +1 -1
  275. package/dist/components/ChoiceCard/ChoiceCard.d.ts +1 -1
  276. package/dist/components/ChoiceCard/index.cjs +1 -1
  277. package/dist/components/ChoiceCard/index.js +1 -1
  278. package/dist/components/CodeBlock/CodeBlock.d.cts +1 -1
  279. package/dist/components/CodeBlock/CodeBlock.d.ts +1 -1
  280. package/dist/components/CodeBlock/index.cjs +1 -1
  281. package/dist/components/CodeBlock/index.js +1 -1
  282. package/dist/components/ColorPicker/index.cjs +1 -1
  283. package/dist/components/ColorPicker/index.js +1 -1
  284. package/dist/components/ColorRamp/index.cjs +1 -1
  285. package/dist/components/ColorRamp/index.js +1 -1
  286. package/dist/components/CopyButton/index.cjs +1 -1
  287. package/dist/components/CopyButton/index.js +1 -1
  288. package/dist/components/DatePicker/index.cjs +1 -1
  289. package/dist/components/DatePicker/index.js +1 -1
  290. package/dist/components/DateTimePicker/DateTimePicker.d.cts +2 -2
  291. package/dist/components/DateTimePicker/DateTimePicker.d.ts +2 -2
  292. package/dist/components/DateTimePicker/index.cjs +1 -1
  293. package/dist/components/DateTimePicker/index.js +1 -1
  294. package/dist/components/DescriptionList/DescriptionList.d.cts +1 -1
  295. package/dist/components/DescriptionList/DescriptionList.d.ts +1 -1
  296. package/dist/components/DescriptionList/index.cjs +1 -1
  297. package/dist/components/DescriptionList/index.js +1 -1
  298. package/dist/components/Dropdown/index.cjs +1 -1
  299. package/dist/components/Dropdown/index.js +1 -1
  300. package/dist/components/EmptyState/index.cjs +1 -1
  301. package/dist/components/EmptyState/index.js +1 -1
  302. package/dist/components/ErrorState/index.cjs +1 -1
  303. package/dist/components/ErrorState/index.js +2 -2
  304. package/dist/components/FileCard/FileCard.d.cts +5 -2
  305. package/dist/components/FileCard/FileCard.d.ts +5 -2
  306. package/dist/components/FileCard/index.cjs +1 -1
  307. package/dist/components/FileCard/index.js +1 -1
  308. package/dist/components/FileUploader/FileUploader.d.cts +5 -5
  309. package/dist/components/FileUploader/FileUploader.d.ts +5 -5
  310. package/dist/components/FileUploader/index.cjs +1 -1
  311. package/dist/components/FileUploader/index.js +1 -1
  312. package/dist/components/Flag/index.cjs +1 -1
  313. package/dist/components/Flag/index.js +1 -1
  314. package/dist/components/FloatingPanel/FloatingPanel.d.cts +6 -5
  315. package/dist/components/FloatingPanel/FloatingPanel.d.ts +6 -5
  316. package/dist/components/FullscreenToggle/index.cjs +1 -1
  317. package/dist/components/FullscreenToggle/index.js +1 -1
  318. package/dist/components/IconButton/index.cjs +1 -1
  319. package/dist/components/IconButton/index.js +1 -1
  320. package/dist/components/List/index.cjs +1 -1
  321. package/dist/components/List/index.js +2 -2
  322. package/dist/components/Loader/Loader.d.cts +1 -1
  323. package/dist/components/Loader/Loader.d.ts +1 -1
  324. package/dist/components/Loader/index.cjs +1 -1
  325. package/dist/components/Loader/index.js +1 -1
  326. package/dist/components/LocationPicker/index.cjs +1 -1
  327. package/dist/components/LocationPicker/index.js +1 -1
  328. package/dist/components/Modal/Modal.d.cts +1 -1
  329. package/dist/components/Modal/Modal.d.ts +1 -1
  330. package/dist/components/Modal/index.cjs +1 -1
  331. package/dist/components/Modal/index.js +1 -1
  332. package/dist/components/MultiSelect/index.cjs +1 -1
  333. package/dist/components/MultiSelect/index.js +1 -1
  334. package/dist/components/NumberField/index.cjs +1 -1
  335. package/dist/components/NumberField/index.js +1 -1
  336. package/dist/components/OtpField/OtpField.d.cts +1 -1
  337. package/dist/components/OtpField/OtpField.d.ts +1 -1
  338. package/dist/components/OtpField/index.cjs +1 -1
  339. package/dist/components/OtpField/index.js +1 -1
  340. package/dist/components/PageError/index.cjs +1 -1
  341. package/dist/components/PageError/index.js +1 -1
  342. package/dist/components/PageLayout/PageLayout.d.cts +2 -2
  343. package/dist/components/PageLayout/PageLayout.d.ts +2 -2
  344. package/dist/components/PageLayout/index.cjs +1 -1
  345. package/dist/components/PageLayout/index.js +1 -1
  346. package/dist/components/PageNotFound/index.cjs +1 -1
  347. package/dist/components/PageNotFound/index.js +1 -1
  348. package/dist/components/Pagination/index.cjs +1 -1
  349. package/dist/components/Pagination/index.js +1 -1
  350. package/dist/components/PaletteField/index.cjs +1 -1
  351. package/dist/components/PaletteField/index.js +1 -1
  352. package/dist/components/PhoneField/index.cjs +1 -1
  353. package/dist/components/PhoneField/index.js +1 -1
  354. package/dist/components/Popconfirm/index.cjs +1 -1
  355. package/dist/components/Popconfirm/index.js +1 -1
  356. package/dist/components/Popover/Popover.d.cts +1 -1
  357. package/dist/components/Popover/Popover.d.ts +1 -1
  358. package/dist/components/Progress/index.cjs +1 -1
  359. package/dist/components/Progress/index.js +1 -1
  360. package/dist/components/QrCode/QrCode.d.cts +5 -2
  361. package/dist/components/QrCode/QrCode.d.ts +5 -2
  362. package/dist/components/QrCode/index.cjs +1 -1
  363. package/dist/components/QrCode/index.js +1 -1
  364. package/dist/components/RemoveDialog/index.cjs +1 -1
  365. package/dist/components/RemoveDialog/index.js +1 -1
  366. package/dist/components/RichTextEditor/RichTextEditor.d.cts +1 -1
  367. package/dist/components/RichTextEditor/RichTextEditor.d.ts +1 -1
  368. package/dist/components/RichTextEditor/index.cjs +1 -1
  369. package/dist/components/RichTextEditor/index.js +1 -1
  370. package/dist/components/RootLayout/RootLayout.d.cts +12 -5
  371. package/dist/components/RootLayout/RootLayout.d.ts +12 -5
  372. package/dist/components/RootLayout/index.cjs +1 -1
  373. package/dist/components/RootLayout/index.js +1 -1
  374. package/dist/components/Select/index.cjs +1 -1
  375. package/dist/components/Select/index.js +1 -1
  376. package/dist/components/Sidebar/index.cjs +1 -1
  377. package/dist/components/Sidebar/index.js +1 -1
  378. package/dist/components/Slider/Slider.d.cts +2 -2
  379. package/dist/components/Slider/Slider.d.ts +2 -2
  380. package/dist/components/Slider/index.cjs +1 -1
  381. package/dist/components/Slider/index.js +1 -1
  382. package/dist/components/SpeedDial/index.cjs +1 -1
  383. package/dist/components/SpeedDial/index.js +1 -1
  384. package/dist/components/Stepper/Stepper.d.cts +2 -2
  385. package/dist/components/Stepper/Stepper.d.ts +2 -2
  386. package/dist/components/Stepper/index.cjs +1 -1
  387. package/dist/components/Stepper/index.js +1 -1
  388. package/dist/components/Table/Table.d.cts +1 -1
  389. package/dist/components/Table/Table.d.ts +1 -1
  390. package/dist/components/Table/index.cjs +1 -1
  391. package/dist/components/Table/index.js +1 -1
  392. package/dist/components/Tabs/index.cjs +1 -1
  393. package/dist/components/Tabs/index.js +1 -1
  394. package/dist/components/TagsField/TagsField.d.cts +1 -1
  395. package/dist/components/TagsField/TagsField.d.ts +1 -1
  396. package/dist/components/TagsField/index.cjs +1 -1
  397. package/dist/components/TagsField/index.js +1 -1
  398. package/dist/components/TextField/index.cjs +1 -1
  399. package/dist/components/TextField/index.js +1 -1
  400. package/dist/components/ThemeToggle/index.cjs +1 -1
  401. package/dist/components/ThemeToggle/index.js +1 -1
  402. package/dist/components/TimePicker/index.cjs +1 -1
  403. package/dist/components/TimePicker/index.js +1 -1
  404. package/dist/components/Toast/index.cjs +1 -1
  405. package/dist/components/Toast/index.js +1 -1
  406. package/dist/components/TranslatedFields/TranslatedFields.d.cts +1 -1
  407. package/dist/components/TranslatedFields/TranslatedFields.d.ts +1 -1
  408. package/dist/components/TranslatedFields/index.cjs +1 -1
  409. package/dist/components/TranslatedFields/index.js +1 -1
  410. package/dist/components/UserCard/UserCard.d.cts +6 -5
  411. package/dist/components/UserCard/UserCard.d.ts +6 -5
  412. package/dist/components/UserCard/index.cjs +1 -1
  413. package/dist/components/UserCard/index.js +1 -1
  414. package/dist/entries/app.cjs +1 -1
  415. package/dist/entries/app.js +1 -1
  416. package/dist/entries/components.cjs +1 -1
  417. package/dist/entries/components.js +56 -56
  418. package/dist/entries/i18n.cjs +1 -1
  419. package/dist/entries/i18n.js +2 -2
  420. package/dist/entries/theme.cjs +1 -1
  421. package/dist/entries/theme.js +1 -1
  422. package/dist/form/useForm.d.cts +1 -1
  423. package/dist/form/useForm.d.ts +1 -1
  424. package/dist/hooks/useMediaQuery.d.cts +3 -3
  425. package/dist/hooks/useMediaQuery.d.ts +3 -3
  426. package/dist/i18n/messages.d.cts +20 -0
  427. package/dist/i18n/messages.d.ts +20 -0
  428. package/dist/index.cjs +1 -1
  429. package/dist/index.css +3 -3
  430. package/dist/index.js +59 -59
  431. package/dist/{messages-BasxRpyx.js → messages-BiRLMy1E.js} +177 -37
  432. package/dist/messages-BiRLMy1E.js.map +1 -0
  433. package/dist/{messages-CElolVGm.cjs → messages-C_fRRCg6.cjs} +9 -9
  434. package/dist/messages-C_fRRCg6.cjs.map +1 -0
  435. package/dist/theme/ConfigProvider.d.cts +19 -10
  436. package/dist/theme/ConfigProvider.d.ts +19 -10
  437. package/dist/useForm-CGbJ44Gp.js.map +1 -1
  438. package/dist/useForm-CSw6r1n1.cjs.map +1 -1
  439. package/dist/{useHomeTo-BnjXms11.cjs → useHomeTo-BaM7kBDh.cjs} +2 -2
  440. package/dist/{useHomeTo-BnjXms11.cjs.map → useHomeTo-BaM7kBDh.cjs.map} +1 -1
  441. package/dist/{useHomeTo-Btkk0RSB.js → useHomeTo-DQj9tVZI.js} +2 -2
  442. package/dist/{useHomeTo-Btkk0RSB.js.map → useHomeTo-DQj9tVZI.js.map} +1 -1
  443. package/dist/useMediaQuery-CHMrI6Dy.cjs.map +1 -1
  444. package/dist/useMediaQuery-DrDUrkmJ.js.map +1 -1
  445. package/dist/{useOptionMenu-IebDGoqk.cjs → useOptionMenu-BKC1y6oj.cjs} +2 -2
  446. package/dist/{useOptionMenu-IebDGoqk.cjs.map → useOptionMenu-BKC1y6oj.cjs.map} +1 -1
  447. package/dist/{useOptionMenu-DeW68na-.js → useOptionMenu-Dom1-bqm.js} +5 -5
  448. package/dist/{useOptionMenu-DeW68na-.js.map → useOptionMenu-Dom1-bqm.js.map} +1 -1
  449. package/package.json +1 -1
  450. package/dist/AdminRoot-aOYQtzF0.js +0 -109
  451. package/dist/AdminRoot-aOYQtzF0.js.map +0 -1
  452. package/dist/AdminRoot-ajWIf94J.cjs +0 -2
  453. package/dist/AdminRoot-ajWIf94J.cjs.map +0 -1
  454. package/dist/Alert-5tpyGb2M.cjs +0 -2
  455. package/dist/Alert-5tpyGb2M.cjs.map +0 -1
  456. package/dist/Alert-Dz0sNGpz.js +0 -70
  457. package/dist/Alert-Dz0sNGpz.js.map +0 -1
  458. package/dist/Breadcrumbs-B6Pii2Y_.cjs.map +0 -1
  459. package/dist/Breadcrumbs-DKYJOdHZ.js.map +0 -1
  460. package/dist/Card-CIRGqg3P.cjs +0 -2
  461. package/dist/Card-CIRGqg3P.cjs.map +0 -1
  462. package/dist/Card-Co3A4Qgo.js +0 -128
  463. package/dist/Card-Co3A4Qgo.js.map +0 -1
  464. package/dist/Chip-BjSNgaAf.js.map +0 -1
  465. package/dist/Chip-Dp8skUZ2.cjs.map +0 -1
  466. package/dist/ChoiceCardGroup-143hR0v_.cjs +0 -2
  467. package/dist/ChoiceCardGroup-Cx8CtmPl.js +0 -180
  468. package/dist/ChoiceCardGroup-Cx8CtmPl.js.map +0 -1
  469. package/dist/CodeBlock-CcJjS0_q.js.map +0 -1
  470. package/dist/CodeBlock-o_VSkAek.cjs.map +0 -1
  471. package/dist/ColorPicker-DY6Vk1uS.cjs +0 -2
  472. package/dist/ConfigProvider-Bgu85MsI.js.map +0 -1
  473. package/dist/ConfigProvider-DELhJlqo.cjs.map +0 -1
  474. package/dist/DatePicker-CwZ_-ElE.cjs +0 -2
  475. package/dist/DateTimePicker-C2871cuc.js.map +0 -1
  476. package/dist/DateTimePicker-DdEPtw9U.cjs +0 -2
  477. package/dist/DateTimePicker-DdEPtw9U.cjs.map +0 -1
  478. package/dist/DescriptionList-BP4CDME5.js.map +0 -1
  479. package/dist/DescriptionList-BWw0Fe6U.cjs.map +0 -1
  480. package/dist/FileCard-COc4rHe-.cjs.map +0 -1
  481. package/dist/FileCard-CWwB8CWF.js.map +0 -1
  482. package/dist/FileUploader--WOmlhSh.js.map +0 -1
  483. package/dist/FileUploader-Bqy_fV7l.cjs.map +0 -1
  484. package/dist/ListItem-Qo1Tt6Fi.cjs +0 -2
  485. package/dist/Modal--5EbLfMz.cjs.map +0 -1
  486. package/dist/Modal-Dfwc9eIq.js.map +0 -1
  487. package/dist/OtpField-Dy-LKTi9.js +0 -174
  488. package/dist/OtpField-Dy-LKTi9.js.map +0 -1
  489. package/dist/OtpField-KHwdaajC.cjs +0 -2
  490. package/dist/OtpField-KHwdaajC.cjs.map +0 -1
  491. package/dist/PageLayout-Bt6U_80d.cjs.map +0 -1
  492. package/dist/PageLayout-Df1SOlr7.js.map +0 -1
  493. package/dist/Pagination-DDMq_7OZ.js +0 -139
  494. package/dist/Pagination-DDMq_7OZ.js.map +0 -1
  495. package/dist/Pagination-UMeckhmY.cjs +0 -2
  496. package/dist/Pagination-UMeckhmY.cjs.map +0 -1
  497. package/dist/QrCode-B9YbQNVc.js +0 -80
  498. package/dist/QrCode-B9YbQNVc.js.map +0 -1
  499. package/dist/QrCode-CNVYpz9j.cjs +0 -2
  500. package/dist/QrCode-CNVYpz9j.cjs.map +0 -1
  501. package/dist/RichTextEditor-Dv-LDsN-.js.map +0 -1
  502. package/dist/RichTextEditor-lmPGowSR.cjs +0 -2
  503. package/dist/RichTextEditor-lmPGowSR.cjs.map +0 -1
  504. package/dist/RootLayout-B_ZtI-L_.cjs +0 -2
  505. package/dist/RootLayout-B_ZtI-L_.cjs.map +0 -1
  506. package/dist/RootLayout-DIOquzrU.js +0 -642
  507. package/dist/RootLayout-DIOquzrU.js.map +0 -1
  508. package/dist/Sidebar-CfEx7W7i.cjs +0 -2
  509. package/dist/Slider-0joKXhPo.cjs +0 -2
  510. package/dist/Slider-0joKXhPo.cjs.map +0 -1
  511. package/dist/Slider-CwZYxDO0.js +0 -184
  512. package/dist/Slider-CwZYxDO0.js.map +0 -1
  513. package/dist/Stepper-D7An-ugU.cjs.map +0 -1
  514. package/dist/Stepper-DYpiLhzD.js.map +0 -1
  515. package/dist/Table-BhaH8EKZ.cjs.map +0 -1
  516. package/dist/Table-DK4GBKS3.js.map +0 -1
  517. package/dist/TagsField-Cg9YVl7G.js.map +0 -1
  518. package/dist/TagsField-DwZLCIeb.cjs +0 -2
  519. package/dist/TagsField-DwZLCIeb.cjs.map +0 -1
  520. package/dist/TimePicker-_Ak5yB_5.cjs +0 -2
  521. package/dist/TranslatedFields-B-BU17IV.cjs +0 -2
  522. package/dist/TranslatedFields-B-BU17IV.cjs.map +0 -1
  523. package/dist/TranslatedFields-JnqLgUiF.js +0 -86
  524. package/dist/TranslatedFields-JnqLgUiF.js.map +0 -1
  525. package/dist/UserCard-B9bzkZph.cjs.map +0 -1
  526. package/dist/UserCard-DYK6S-nr.js.map +0 -1
  527. package/dist/messages-BasxRpyx.js.map +0 -1
  528. package/dist/messages-CElolVGm.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useOptionMenu-IebDGoqk.cjs","sources":["../src/components/OptionMenu/OptionMenu.tsx","../src/components/OptionMenu/useOptionMenu.ts"],"sourcesContent":["import type { KeyboardEvent, ReactNode, RefObject } from 'react'\nimport { clsx } from 'clsx'\nimport { useT } from '../../theme'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport { List, ListItem, type ListItemSize } from '../List'\nimport { Loader } from '../Loader'\nimport { Typography } from '../Typography'\nimport type { OptionMenuState, SelectOption } from './useOptionMenu'\nimport styles from './OptionMenu.module.css'\n\nexport interface OptionMenuProps {\n /** The state from `useOptionMenu`. */\n menu: OptionMenuState\n /** What the panel anchors under (and matches the width of) — also excluded from outside-click. */\n anchorRef: RefObject<HTMLElement | null>\n /** Row size. */\n size: ListItemSize\n /** Search box placeholder + accessible label. Defaults to the localized \"Search…\". */\n searchPlaceholder?: string\n /** Show a loader row instead of the options (server-side search in flight). */\n loading?: boolean\n /** Text next to the loader. Defaults to the localized \"Loading…\". */\n loadingText?: ReactNode\n /** Empty-result content — a node or `(query) => node`. Defaults to the localized \"No Options\". */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Tick the selected option(s). Defaults to `true`. */\n showSelectedTick?: boolean\n /** `aria-multiselectable` on the listbox. */\n multiselectable?: boolean\n /** Labels the listbox (the field label id). */\n labelledBy?: string\n /** Accessible label for the listbox when there's no visible label. */\n ariaLabel?: string\n /** Wraps the search box's key handling (e.g. MultiSelect's Backspace-removes-a-chip). */\n onSearchKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void\n /** Extra class on the panel. */\n className?: string\n}\n\n/**\n * The option popover shared by `Select`, `MultiSelect` and `PhoneField` (internal): a `FloatingPanel`\n * anchored under the field, an optional sticky search box (`role=\"combobox\"`, `aria-activedescendant`),\n * and a scrolling `role=\"listbox\"` of `ListItem` options — icon, label, the option's `trailing`, a tick\n * when selected, the keyboard highlight, disabled rows inert, `group`ed options under a labelled heading —\n * plus the loading and empty rows. All state\n * and keys live in `useOptionMenu`; this only renders it.\n */\nexport function OptionMenu({\n menu,\n anchorRef,\n size,\n searchPlaceholder,\n loading = false,\n loadingText,\n noOptionsText,\n showSelectedTick = true,\n multiselectable = false,\n labelledBy,\n ariaLabel,\n onSearchKeyDown,\n className,\n}: OptionMenuProps) {\n const t = useT()\n const searchPh = searchPlaceholder ?? t('common.search')\n const { filteredOptions, highlightedIndex } = menu\n\n const renderOption = ({ opt, index }: { opt: SelectOption; index: number }) => {\n const selected = menu.isSelected(opt)\n const tick = selected && showSelectedTick\n return (\n <ListItem\n key={opt.value}\n id={menu.optionId(index)}\n role=\"option\"\n tabIndex={-1}\n aria-selected={selected}\n aria-current={undefined}\n clickable\n selected={selected}\n disabled={opt.disabled}\n icon={opt.icon}\n className={clsx(index === highlightedIndex && styles.active)}\n trailing={\n opt.trailing != null || tick ? (\n <span className={styles.trailing}>\n {opt.trailing}\n {tick && <Icon name=\"TickCircle\" size=\"sm\" />}\n </span>\n ) : undefined\n }\n onMouseEnter={() => !opt.disabled && menu.setHighlightedIndex(index)}\n // keep focus where it is (trigger / search box) — a multi-select stays open and typing keeps\n // working; a single-select refocuses its trigger on close anyway\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => menu.pick(opt)}\n >\n {opt.label}\n </ListItem>\n )\n }\n\n // consecutive runs of the same `group` (the hook already gathered them) → a labelled role=\"group\"\n // each; ungrouped runs render as plain rows\n const renderRows = (rows: { opt: SelectOption; index: number }[]) => {\n if (!rows.some((r) => r.opt.group != null)) return rows.map(renderOption)\n const runs: { group: string | undefined; rows: typeof rows }[] = []\n for (const row of rows) {\n const last = runs[runs.length - 1]\n if (last && last.group === row.opt.group) last.rows.push(row)\n else runs.push({ group: row.opt.group, rows: [row] })\n }\n return runs.map((run, i) => {\n if (run.group == null) return run.rows.map(renderOption)\n const headingId = `${menu.listboxId}-group-${i}`\n return (\n <div key={`group-${i}`} role=\"group\" aria-labelledby={headingId} className={styles.group}>\n <Typography\n as=\"div\"\n id={headingId}\n role=\"presentation\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.groupLabel}\n >\n {run.group}\n </Typography>\n {run.rows.map(renderOption)}\n </div>\n )\n })\n }\n\n return (\n <FloatingPanel\n ref={menu.popoverRef}\n open={menu.open}\n triggerRef={anchorRef}\n onClose={menu.closeMenu}\n matchTriggerWidth\n className={clsx(styles.popover, className)}\n >\n {menu.searchable && (\n <div className={styles.search}>\n <Icon name=\"SearchNormal\" size=\"sm\" className={styles.searchIcon} aria-hidden=\"true\" />\n <input\n ref={menu.searchInputRef}\n className={styles.searchInput}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={menu.listboxId}\n aria-activedescendant={menu.activeId}\n aria-autocomplete=\"list\"\n aria-label={searchPh}\n placeholder={searchPh}\n value={menu.searchQuery}\n spellCheck={false}\n autoComplete=\"off\"\n onChange={(e) => menu.setSearchQuery(e.target.value)}\n onKeyDown={onSearchKeyDown ?? menu.handleKeyDown}\n />\n </div>\n )}\n\n {/* the listbox always carries its id (even when empty) so aria-controls never dangles */}\n <List\n role=\"listbox\"\n id={menu.listboxId}\n aria-labelledby={labelledBy}\n aria-label={labelledBy ? undefined : ariaLabel}\n aria-multiselectable={multiselectable || undefined}\n size={size}\n className={styles.listbox}\n // clear the mouse highlight when the pointer leaves the list (no lingering hover)\n onMouseLeave={() => menu.setHighlightedIndex(-1)}\n >\n {loading ? (\n <div className={styles.loading}>\n <Loader size=\"sm\" />\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {loadingText ?? t('common.loading')}\n </Typography>\n </div>\n ) : filteredOptions.length === 0 ? (\n <div className={styles.noOptions}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {noOptionsText == null\n ? t('select.noOptions')\n : typeof noOptionsText === 'function'\n ? noOptionsText(menu.searchQuery)\n : noOptionsText}\n </Typography>\n </div>\n ) : (\n renderRows(filteredOptions.map((opt, index) => ({ opt, index })))\n )}\n </List>\n </FloatingPanel>\n )\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type RefObject,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { IconName } from '../../icons/names'\n\n/** A single selectable option — shared by `Select`, `MultiSelect` and `PhoneField`. */\nexport interface SelectOption {\n /** The value committed when this option is chosen. */\n value: string\n /** Display + search text. */\n label: string\n /** Greys out and blocks selecting this option. */\n disabled?: boolean\n /** Leading icon — a known `IconName` (rendered as `<Icon>`) or any node. */\n icon?: IconName | ReactNode\n /**\n * Extra search terms matched alongside the label (case-insensitive, substring) — e.g. a currency's\n * code (`'USD'`) or a country's calling code (`'995'`). Never shown.\n */\n keywords?: readonly string[]\n /** Content on the right of the row, before the selected tick (e.g. a code or a count). */\n trailing?: ReactNode\n /**\n * Group heading. Options sharing a `group` are listed together under it (groups in order of first\n * appearance, options keeping their order within a group); options without one stay ungrouped.\n */\n group?: string\n}\n\n/**\n * Stable-group the options: each group gathered at its first appearance, order kept within a group. A\n * list with no `group` at all is returned untouched (the common case costs nothing).\n */\nexport function groupOptions<T extends SelectOption>(options: readonly T[]): readonly T[] {\n if (!options.some((o) => o.group != null)) return options\n const buckets = new Map<string | undefined, T[]>()\n for (const o of options) {\n const bucket = buckets.get(o.group)\n if (bucket) bucket.push(o)\n else buckets.set(o.group, [o])\n }\n return [...buckets.values()].flat()\n}\n\nexport interface UseOptionMenuOptions {\n /** Base for the listbox / option ids (`${idBase}-listbox`, `${idBase}-opt-${i}`). */\n idBase: string\n options: readonly SelectOption[]\n /** Whether an option is selected (drives the initial highlight when `highlightSelected`). */\n isSelected: (option: SelectOption) => boolean\n /** Called when an option is picked (Enter / Space / click). */\n onPick: (option: SelectOption) => void\n /** Close the menu after a pick (single-select) or keep it open (multi-select). Defaults to `true`. */\n closeOnPick?: boolean\n /** On open, highlight the selected option (single-select) instead of the first. Defaults to `true`. */\n highlightSelected?: boolean\n /** Show a search box that filters by label + keywords. */\n searchable?: boolean\n /** The consumer filters `options` itself (server-side search) — skip the local filter. */\n onSearchChange?: (query: string) => void\n disabled?: boolean\n /** The element focus returns to when the menu closes with `refocus` (the trigger / the input). */\n focusRef: RefObject<HTMLElement | null>\n /** Runs on every close (e.g. mark a form field touched). */\n onClose?: () => void\n}\n\n/**\n * The state + keyboard model behind every option popover (internal): open / close, the search query\n * and its label + keywords filter, the highlighted row (skipping disabled ones), type-ahead when not\n * searchable, and one `handleKeyDown` for the trigger and the search box — Arrow / Home / End move,\n * Enter / Space pick, Escape closes (refocusing), Tab closes and moves on. Render it with `OptionMenu`.\n */\nexport function useOptionMenu({\n idBase,\n options,\n isSelected,\n onPick,\n closeOnPick = true,\n highlightSelected = true,\n searchable = false,\n onSearchChange,\n disabled = false,\n focusRef,\n onClose,\n}: UseOptionMenuOptions) {\n const listboxId = `${idBase}-listbox`\n const optionId = useCallback((index: number) => `${idBase}-opt-${index}`, [idBase])\n\n const [open, setOpen] = useState(false)\n const [searchQuery, setSearchQueryState] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const searchInputRef = useRef<HTMLInputElement | null>(null)\n // the floating panel forwards its node here, for the focus-leaves-the-widget check on blur\n const popoverRef = useRef<HTMLDivElement | null>(null)\n const typeahead = useRef({ buffer: '', timer: 0 })\n // latest callbacks without re-creating the stable handlers\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n // local filter by label + keywords (skipped when the consumer owns the options — server search), then\n // grouped, so the flat index the keyboard walks is exactly the rendered order\n const filteredOptions = useMemo(() => {\n const q = searchQuery.trim().toLowerCase()\n const matches =\n !searchable || onSearchChange || !q\n ? options\n : options.filter(\n (o) =>\n o.label.toLowerCase().includes(q) ||\n o.keywords?.some((k) => k.toLowerCase().includes(q)),\n )\n return groupOptions(matches)\n }, [searchable, onSearchChange, searchQuery, options])\n\n const findEnabled = useCallback(\n (start: number, delta: number) => {\n let i = start\n while (i >= 0 && i < filteredOptions.length) {\n if (!filteredOptions[i].disabled) return i\n i += delta\n }\n return -1\n },\n [filteredOptions],\n )\n\n // single dismiss path: clears the search + type-ahead, notifies, optionally refocuses\n const closeMenu = useCallback(\n (refocus: boolean) => {\n setOpen(false)\n setSearchQueryState('')\n window.clearTimeout(typeahead.current.timer)\n typeahead.current.buffer = ''\n onCloseRef.current?.()\n if (refocus) focusRef.current?.focus()\n },\n [focusRef],\n )\n\n // on open: highlight the selected option (or the first enabled), focus the search box\n useEffect(() => {\n if (!open) return\n const selIdx = highlightSelected ? filteredOptions.findIndex(isSelected) : -1\n setHighlightedIndex(\n selIdx >= 0 && !filteredOptions[selIdx].disabled ? selIdx : findEnabled(0, 1),\n )\n if (searchable) requestAnimationFrame(() => searchInputRef.current?.focus())\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n // keep the highlighted option scrolled into view\n useEffect(() => {\n if (!open || highlightedIndex < 0) return\n document.getElementById(optionId(highlightedIndex))?.scrollIntoView?.({ block: 'nearest' })\n }, [open, highlightedIndex, optionId])\n\n // a new search → re-anchor the highlight to the first match\n useEffect(() => {\n if (open && searchable) setHighlightedIndex(findEnabled(0, 1))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchQuery])\n\n // the option count changed while open (async load / list shrink) → keep the highlight in range\n useEffect(() => {\n if (open) setHighlightedIndex((i) => (i < filteredOptions.length ? i : findEnabled(0, 1)))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filteredOptions.length])\n\n const openMenu = () => {\n if (!disabled) setOpen(true)\n }\n const toggleMenu = () => (open ? closeMenu(false) : openMenu())\n\n const setSearchQuery = (query: string) => {\n setSearchQueryState(query)\n onSearchChange?.(query)\n }\n\n const pick = (option: SelectOption | undefined) => {\n if (!option || option.disabled) return\n onPick(option)\n if (closeOnPick) closeMenu(true)\n }\n\n const moveHighlight = (delta: number) => {\n setHighlightedIndex((cur) => {\n const start = cur < 0 ? (delta > 0 ? 0 : filteredOptions.length - 1) : cur + delta\n const found = findEnabled(start, delta)\n return found === -1 ? cur : found\n })\n }\n\n // type-ahead (no search box): jump to the option whose label starts with the typed buffer\n const handleTypeahead = (char: string) => {\n const t = typeahead.current\n window.clearTimeout(t.timer)\n t.buffer += char.toLowerCase()\n t.timer = window.setTimeout(() => (t.buffer = ''), 500)\n const match = filteredOptions.findIndex(\n (o) => !o.disabled && o.label.toLowerCase().startsWith(t.buffer),\n )\n if (match >= 0) setHighlightedIndex(match)\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n open ? moveHighlight(1) : openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n open ? moveHighlight(-1) : openMenu()\n break\n case 'Enter':\n event.preventDefault()\n if (!open) openMenu()\n else pick(filteredOptions[highlightedIndex])\n break\n case ' ':\n // Space opens a closed menu; picks only when open without a search box (so search can type spaces)\n if (!open) {\n event.preventDefault()\n openMenu()\n } else if (!searchable) {\n event.preventDefault()\n pick(filteredOptions[highlightedIndex])\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation() // don't let FloatingPanel's own Escape also fire closeMenu\n closeMenu(true)\n }\n break\n case 'Tab':\n // refocus the trigger so Tab continues from the field's visual spot, not the portaled search\n // input's DOM position (end of <body>); no preventDefault — let Tab move on\n if (open) closeMenu(true)\n break\n case 'Home':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(0, 1))\n }\n break\n case 'End':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(filteredOptions.length - 1, -1))\n }\n break\n default:\n if (\n !searchable &&\n open &&\n event.key.length === 1 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n handleTypeahead(event.key)\n }\n }\n }\n\n const activeId = open && highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined\n\n return {\n open,\n openMenu,\n closeMenu,\n toggleMenu,\n searchable,\n searchQuery,\n setSearchQuery,\n filteredOptions,\n highlightedIndex,\n setHighlightedIndex,\n isSelected,\n pick,\n handleKeyDown,\n listboxId,\n optionId,\n activeId,\n searchInputRef,\n popoverRef,\n }\n}\n\n/** Everything `useOptionMenu` returns — pass it to `<OptionMenu menu={…} />`. */\nexport type OptionMenuState = ReturnType<typeof useOptionMenu>\n"],"names":["OptionMenu","menu","anchorRef","size","searchPlaceholder","loading","loadingText","noOptionsText","showSelectedTick","multiselectable","labelledBy","ariaLabel","onSearchKeyDown","className","t","useT","searchPh","filteredOptions","highlightedIndex","renderOption","opt","index","selected","tick","jsx","ListItem","clsx","styles","jsxs","Icon","e","renderRows","rows","r","runs","row","last","run","i","headingId","Typography","FloatingPanel","List","Loader","groupOptions","options","o","buckets","bucket","useOptionMenu","idBase","isSelected","onPick","closeOnPick","highlightSelected","searchable","onSearchChange","disabled","focusRef","onClose","listboxId","optionId","useCallback","open","setOpen","useState","searchQuery","setSearchQueryState","setHighlightedIndex","searchInputRef","useRef","popoverRef","typeahead","onCloseRef","useMemo","q","matches","_a","k","findEnabled","start","delta","closeMenu","refocus","_b","useEffect","selIdx","openMenu","toggleMenu","setSearchQuery","query","pick","option","moveHighlight","cur","found","handleTypeahead","char","match","handleKeyDown","event","activeId"],"mappings":"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"}
1
+ {"version":3,"file":"useOptionMenu-BKC1y6oj.cjs","sources":["../src/components/OptionMenu/OptionMenu.tsx","../src/components/OptionMenu/useOptionMenu.ts"],"sourcesContent":["import type { KeyboardEvent, ReactNode, RefObject } from 'react'\nimport { clsx } from 'clsx'\nimport { useT } from '../../theme'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport { List, ListItem, type ListItemSize } from '../List'\nimport { Loader } from '../Loader'\nimport { Typography } from '../Typography'\nimport type { OptionMenuState, SelectOption } from './useOptionMenu'\nimport styles from './OptionMenu.module.css'\n\nexport interface OptionMenuProps {\n /** The state from `useOptionMenu`. */\n menu: OptionMenuState\n /** What the panel anchors under (and matches the width of) — also excluded from outside-click. */\n anchorRef: RefObject<HTMLElement | null>\n /** Row size. */\n size: ListItemSize\n /** Search box placeholder + accessible label. Defaults to the localized \"Search…\". */\n searchPlaceholder?: string\n /** Show a loader row instead of the options (server-side search in flight). */\n loading?: boolean\n /** Text next to the loader. Defaults to the localized \"Loading…\". */\n loadingText?: ReactNode\n /** Empty-result content — a node or `(query) => node`. Defaults to the localized \"No Options\". */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Tick the selected option(s). Defaults to `true`. */\n showSelectedTick?: boolean\n /** `aria-multiselectable` on the listbox. */\n multiselectable?: boolean\n /** Labels the listbox (the field label id). */\n labelledBy?: string\n /** Accessible label for the listbox when there's no visible label. */\n ariaLabel?: string\n /** Wraps the search box's key handling (e.g. MultiSelect's Backspace-removes-a-chip). */\n onSearchKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void\n /** Extra class on the panel. */\n className?: string\n}\n\n/**\n * The option popover shared by `Select`, `MultiSelect` and `PhoneField` (internal): a `FloatingPanel`\n * anchored under the field, an optional sticky search box (`role=\"combobox\"`, `aria-activedescendant`),\n * and a scrolling `role=\"listbox\"` of `ListItem` options — icon, label, the option's `trailing`, a tick\n * when selected, the keyboard highlight, disabled rows inert, `group`ed options under a labelled heading —\n * plus the loading and empty rows. All state\n * and keys live in `useOptionMenu`; this only renders it.\n */\nexport function OptionMenu({\n menu,\n anchorRef,\n size,\n searchPlaceholder,\n loading = false,\n loadingText,\n noOptionsText,\n showSelectedTick = true,\n multiselectable = false,\n labelledBy,\n ariaLabel,\n onSearchKeyDown,\n className,\n}: OptionMenuProps) {\n const t = useT()\n const searchPh = searchPlaceholder ?? t('common.search')\n const { filteredOptions, highlightedIndex } = menu\n\n const renderOption = ({ opt, index }: { opt: SelectOption; index: number }) => {\n const selected = menu.isSelected(opt)\n const tick = selected && showSelectedTick\n return (\n <ListItem\n key={opt.value}\n id={menu.optionId(index)}\n role=\"option\"\n tabIndex={-1}\n aria-selected={selected}\n aria-current={undefined}\n clickable\n selected={selected}\n disabled={opt.disabled}\n icon={opt.icon}\n className={clsx(index === highlightedIndex && styles.active)}\n trailing={\n opt.trailing != null || tick ? (\n <span className={styles.trailing}>\n {opt.trailing}\n {tick && <Icon name=\"TickCircle\" size=\"sm\" />}\n </span>\n ) : undefined\n }\n onMouseEnter={() => !opt.disabled && menu.setHighlightedIndex(index)}\n // keep focus where it is (trigger / search box) — a multi-select stays open and typing keeps\n // working; a single-select refocuses its trigger on close anyway\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => menu.pick(opt)}\n >\n {opt.label}\n </ListItem>\n )\n }\n\n // consecutive runs of the same `group` (the hook already gathered them) → a labelled role=\"group\"\n // each; ungrouped runs render as plain rows\n const renderRows = (rows: { opt: SelectOption; index: number }[]) => {\n if (!rows.some((r) => r.opt.group != null)) return rows.map(renderOption)\n const runs: { group: string | undefined; rows: typeof rows }[] = []\n for (const row of rows) {\n const last = runs[runs.length - 1]\n if (last && last.group === row.opt.group) last.rows.push(row)\n else runs.push({ group: row.opt.group, rows: [row] })\n }\n return runs.map((run, i) => {\n if (run.group == null) return run.rows.map(renderOption)\n const headingId = `${menu.listboxId}-group-${i}`\n return (\n <div key={`group-${i}`} role=\"group\" aria-labelledby={headingId} className={styles.group}>\n <Typography\n as=\"div\"\n id={headingId}\n role=\"presentation\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.groupLabel}\n >\n {run.group}\n </Typography>\n {run.rows.map(renderOption)}\n </div>\n )\n })\n }\n\n return (\n <FloatingPanel\n ref={menu.popoverRef}\n open={menu.open}\n triggerRef={anchorRef}\n onClose={menu.closeMenu}\n matchTriggerWidth\n className={clsx(styles.popover, className)}\n >\n {menu.searchable && (\n <div className={styles.search}>\n <Icon name=\"SearchNormal\" size=\"sm\" className={styles.searchIcon} aria-hidden=\"true\" />\n <input\n ref={menu.searchInputRef}\n className={styles.searchInput}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={menu.listboxId}\n aria-activedescendant={menu.activeId}\n aria-autocomplete=\"list\"\n aria-label={searchPh}\n placeholder={searchPh}\n value={menu.searchQuery}\n spellCheck={false}\n autoComplete=\"off\"\n onChange={(e) => menu.setSearchQuery(e.target.value)}\n onKeyDown={onSearchKeyDown ?? menu.handleKeyDown}\n />\n </div>\n )}\n\n {/* the listbox always carries its id (even when empty) so aria-controls never dangles */}\n <List\n role=\"listbox\"\n id={menu.listboxId}\n aria-labelledby={labelledBy}\n aria-label={labelledBy ? undefined : ariaLabel}\n aria-multiselectable={multiselectable || undefined}\n size={size}\n className={styles.listbox}\n // clear the mouse highlight when the pointer leaves the list (no lingering hover)\n onMouseLeave={() => menu.setHighlightedIndex(-1)}\n >\n {loading ? (\n <div className={styles.loading}>\n <Loader size=\"sm\" />\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {loadingText ?? t('common.loading')}\n </Typography>\n </div>\n ) : filteredOptions.length === 0 ? (\n <div className={styles.noOptions}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {noOptionsText == null\n ? t('select.noOptions')\n : typeof noOptionsText === 'function'\n ? noOptionsText(menu.searchQuery)\n : noOptionsText}\n </Typography>\n </div>\n ) : (\n renderRows(filteredOptions.map((opt, index) => ({ opt, index })))\n )}\n </List>\n </FloatingPanel>\n )\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type RefObject,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { IconName } from '../../icons/names'\n\n/** A single selectable option — shared by `Select`, `MultiSelect` and `PhoneField`. */\nexport interface SelectOption {\n /** The value committed when this option is chosen. */\n value: string\n /** Display + search text. */\n label: string\n /** Greys out and blocks selecting this option. */\n disabled?: boolean\n /** Leading icon — a known `IconName` (rendered as `<Icon>`) or any node. */\n icon?: IconName | ReactNode\n /**\n * Extra search terms matched alongside the label (case-insensitive, substring) — e.g. a currency's\n * code (`'USD'`) or a country's calling code (`'995'`). Never shown.\n */\n keywords?: readonly string[]\n /** Content on the right of the row, before the selected tick (e.g. a code or a count). */\n trailing?: ReactNode\n /**\n * Group heading. Options sharing a `group` are listed together under it (groups in order of first\n * appearance, options keeping their order within a group); options without one stay ungrouped.\n */\n group?: string\n}\n\n/**\n * Stable-group the options: each group gathered at its first appearance, order kept within a group. A\n * list with no `group` at all is returned untouched (the common case costs nothing).\n */\nexport function groupOptions<T extends SelectOption>(options: readonly T[]): readonly T[] {\n if (!options.some((o) => o.group != null)) return options\n const buckets = new Map<string | undefined, T[]>()\n for (const o of options) {\n const bucket = buckets.get(o.group)\n if (bucket) bucket.push(o)\n else buckets.set(o.group, [o])\n }\n return [...buckets.values()].flat()\n}\n\nexport interface UseOptionMenuOptions {\n /** Base for the listbox / option ids (`${idBase}-listbox`, `${idBase}-opt-${i}`). */\n idBase: string\n options: readonly SelectOption[]\n /** Whether an option is selected (drives the initial highlight when `highlightSelected`). */\n isSelected: (option: SelectOption) => boolean\n /** Called when an option is picked (Enter / Space / click). */\n onPick: (option: SelectOption) => void\n /** Close the menu after a pick (single-select) or keep it open (multi-select). Defaults to `true`. */\n closeOnPick?: boolean\n /** On open, highlight the selected option (single-select) instead of the first. Defaults to `true`. */\n highlightSelected?: boolean\n /** Show a search box that filters by label + keywords. */\n searchable?: boolean\n /** The consumer filters `options` itself (server-side search) — skip the local filter. */\n onSearchChange?: (query: string) => void\n disabled?: boolean\n /** The element focus returns to when the menu closes with `refocus` (the trigger / the input). */\n focusRef: RefObject<HTMLElement | null>\n /** Runs on every close (e.g. mark a form field touched). */\n onClose?: () => void\n}\n\n/**\n * The state + keyboard model behind every option popover (internal): open / close, the search query\n * and its label + keywords filter, the highlighted row (skipping disabled ones), type-ahead when not\n * searchable, and one `handleKeyDown` for the trigger and the search box — Arrow / Home / End move,\n * Enter / Space pick, Escape closes (refocusing), Tab closes and moves on. Render it with `OptionMenu`.\n */\nexport function useOptionMenu({\n idBase,\n options,\n isSelected,\n onPick,\n closeOnPick = true,\n highlightSelected = true,\n searchable = false,\n onSearchChange,\n disabled = false,\n focusRef,\n onClose,\n}: UseOptionMenuOptions) {\n const listboxId = `${idBase}-listbox`\n const optionId = useCallback((index: number) => `${idBase}-opt-${index}`, [idBase])\n\n const [open, setOpen] = useState(false)\n const [searchQuery, setSearchQueryState] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const searchInputRef = useRef<HTMLInputElement | null>(null)\n // the floating panel forwards its node here, for the focus-leaves-the-widget check on blur\n const popoverRef = useRef<HTMLDivElement | null>(null)\n const typeahead = useRef({ buffer: '', timer: 0 })\n // latest callbacks without re-creating the stable handlers\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n // local filter by label + keywords (skipped when the consumer owns the options — server search), then\n // grouped, so the flat index the keyboard walks is exactly the rendered order\n const filteredOptions = useMemo(() => {\n const q = searchQuery.trim().toLowerCase()\n const matches =\n !searchable || onSearchChange || !q\n ? options\n : options.filter(\n (o) =>\n o.label.toLowerCase().includes(q) ||\n o.keywords?.some((k) => k.toLowerCase().includes(q)),\n )\n return groupOptions(matches)\n }, [searchable, onSearchChange, searchQuery, options])\n\n const findEnabled = useCallback(\n (start: number, delta: number) => {\n let i = start\n while (i >= 0 && i < filteredOptions.length) {\n if (!filteredOptions[i].disabled) return i\n i += delta\n }\n return -1\n },\n [filteredOptions],\n )\n\n // single dismiss path: clears the search + type-ahead, notifies, optionally refocuses\n const closeMenu = useCallback(\n (refocus: boolean) => {\n setOpen(false)\n setSearchQueryState('')\n window.clearTimeout(typeahead.current.timer)\n typeahead.current.buffer = ''\n onCloseRef.current?.()\n if (refocus) focusRef.current?.focus()\n },\n [focusRef],\n )\n\n // on open: highlight the selected option (or the first enabled), focus the search box\n useEffect(() => {\n if (!open) return\n const selIdx = highlightSelected ? filteredOptions.findIndex(isSelected) : -1\n setHighlightedIndex(\n selIdx >= 0 && !filteredOptions[selIdx].disabled ? selIdx : findEnabled(0, 1),\n )\n if (searchable) requestAnimationFrame(() => searchInputRef.current?.focus())\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n // keep the highlighted option scrolled into view\n useEffect(() => {\n if (!open || highlightedIndex < 0) return\n document.getElementById(optionId(highlightedIndex))?.scrollIntoView?.({ block: 'nearest' })\n }, [open, highlightedIndex, optionId])\n\n // a new search → re-anchor the highlight to the first match\n useEffect(() => {\n if (open && searchable) setHighlightedIndex(findEnabled(0, 1))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchQuery])\n\n // the option count changed while open (async load / list shrink) → keep the highlight in range\n useEffect(() => {\n if (open) setHighlightedIndex((i) => (i < filteredOptions.length ? i : findEnabled(0, 1)))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filteredOptions.length])\n\n const openMenu = () => {\n if (!disabled) setOpen(true)\n }\n const toggleMenu = () => (open ? closeMenu(false) : openMenu())\n\n const setSearchQuery = (query: string) => {\n setSearchQueryState(query)\n onSearchChange?.(query)\n }\n\n const pick = (option: SelectOption | undefined) => {\n if (!option || option.disabled) return\n onPick(option)\n if (closeOnPick) closeMenu(true)\n }\n\n const moveHighlight = (delta: number) => {\n setHighlightedIndex((cur) => {\n const start = cur < 0 ? (delta > 0 ? 0 : filteredOptions.length - 1) : cur + delta\n const found = findEnabled(start, delta)\n return found === -1 ? cur : found\n })\n }\n\n // type-ahead (no search box): jump to the option whose label starts with the typed buffer\n const handleTypeahead = (char: string) => {\n const t = typeahead.current\n window.clearTimeout(t.timer)\n t.buffer += char.toLowerCase()\n t.timer = window.setTimeout(() => (t.buffer = ''), 500)\n const match = filteredOptions.findIndex(\n (o) => !o.disabled && o.label.toLowerCase().startsWith(t.buffer),\n )\n if (match >= 0) setHighlightedIndex(match)\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n open ? moveHighlight(1) : openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n open ? moveHighlight(-1) : openMenu()\n break\n case 'Enter':\n event.preventDefault()\n if (!open) openMenu()\n else pick(filteredOptions[highlightedIndex])\n break\n case ' ':\n // Space opens a closed menu; picks only when open without a search box (so search can type spaces)\n if (!open) {\n event.preventDefault()\n openMenu()\n } else if (!searchable) {\n event.preventDefault()\n pick(filteredOptions[highlightedIndex])\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation() // don't let FloatingPanel's own Escape also fire closeMenu\n closeMenu(true)\n }\n break\n case 'Tab':\n // refocus the trigger so Tab continues from the field's visual spot, not the portaled search\n // input's DOM position (end of <body>); no preventDefault — let Tab move on\n if (open) closeMenu(true)\n break\n case 'Home':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(0, 1))\n }\n break\n case 'End':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(filteredOptions.length - 1, -1))\n }\n break\n default:\n if (\n !searchable &&\n open &&\n event.key.length === 1 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n handleTypeahead(event.key)\n }\n }\n }\n\n const activeId = open && highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined\n\n return {\n open,\n openMenu,\n closeMenu,\n toggleMenu,\n searchable,\n searchQuery,\n setSearchQuery,\n filteredOptions,\n highlightedIndex,\n setHighlightedIndex,\n isSelected,\n pick,\n handleKeyDown,\n listboxId,\n optionId,\n activeId,\n searchInputRef,\n popoverRef,\n }\n}\n\n/** Everything `useOptionMenu` returns — pass it to `<OptionMenu menu={…} />`. */\nexport type OptionMenuState = ReturnType<typeof useOptionMenu>\n"],"names":["OptionMenu","menu","anchorRef","size","searchPlaceholder","loading","loadingText","noOptionsText","showSelectedTick","multiselectable","labelledBy","ariaLabel","onSearchKeyDown","className","t","useT","searchPh","filteredOptions","highlightedIndex","renderOption","opt","index","selected","tick","jsx","ListItem","clsx","styles","jsxs","Icon","e","renderRows","rows","r","runs","row","last","run","i","headingId","Typography","FloatingPanel","List","Loader","groupOptions","options","o","buckets","bucket","useOptionMenu","idBase","isSelected","onPick","closeOnPick","highlightSelected","searchable","onSearchChange","disabled","focusRef","onClose","listboxId","optionId","useCallback","open","setOpen","useState","searchQuery","setSearchQueryState","setHighlightedIndex","searchInputRef","useRef","popoverRef","typeahead","onCloseRef","useMemo","q","matches","_a","k","findEnabled","start","delta","closeMenu","refocus","_b","useEffect","selIdx","openMenu","toggleMenu","setSearchQuery","query","pick","option","moveHighlight","cur","found","handleTypeahead","char","match","handleKeyDown","event","activeId"],"mappings":"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"}
@@ -2,11 +2,11 @@ import { jsxs as N, jsx as h } from "react/jsx-runtime";
2
2
  import { clsx as P } from "clsx";
3
3
  import { F as J } from "./FloatingPanel-C5c_eMQ0.js";
4
4
  import { b as j } from "./Icon-D5TxgfCc.js";
5
- import { L as X } from "./List-CwuAJDTi.js";
6
- import { L as Y } from "./ListItem-BWNIbyTh.js";
7
- import { L as Z } from "./Loader-De8_GqR1.js";
5
+ import { L as X } from "./List-2Y3ktTcF.js";
6
+ import { L as Y } from "./ListItem-2Lr5_NRY.js";
7
+ import { L as Z } from "./Loader-Bluu6z0-.js";
8
8
  import { T as C } from "./Typography-ChSuxgkc.js";
9
- import { a as B } from "./ConfigProvider-Bgu85MsI.js";
9
+ import { a as B } from "./ConfigProvider-D61cpCz-.js";
10
10
  import { useCallback as z, useState as A, useRef as T, useMemo as ee, useEffect as K } from "react";
11
11
  const re = "_popover_rf9kn_3", te = "_search_rf9kn_11", oe = "_searchIcon_rf9kn_20", se = "_searchInput_rf9kn_24", ae = "_listbox_rf9kn_40", ne = "_active_rf9kn_48", ie = "_noOptions_rf9kn_52", le = "_loading_rf9kn_58", ce = "_group_rf9kn_68", ue = "_groupLabel_rf9kn_80", fe = "_trailing_rf9kn_86", p = {
12
12
  popover: re,
@@ -284,4 +284,4 @@ export {
284
284
  ye as O,
285
285
  xe as u
286
286
  };
287
- //# sourceMappingURL=useOptionMenu-DeW68na-.js.map
287
+ //# sourceMappingURL=useOptionMenu-Dom1-bqm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useOptionMenu-DeW68na-.js","sources":["../src/components/OptionMenu/OptionMenu.tsx","../src/components/OptionMenu/useOptionMenu.ts"],"sourcesContent":["import type { KeyboardEvent, ReactNode, RefObject } from 'react'\nimport { clsx } from 'clsx'\nimport { useT } from '../../theme'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport { List, ListItem, type ListItemSize } from '../List'\nimport { Loader } from '../Loader'\nimport { Typography } from '../Typography'\nimport type { OptionMenuState, SelectOption } from './useOptionMenu'\nimport styles from './OptionMenu.module.css'\n\nexport interface OptionMenuProps {\n /** The state from `useOptionMenu`. */\n menu: OptionMenuState\n /** What the panel anchors under (and matches the width of) — also excluded from outside-click. */\n anchorRef: RefObject<HTMLElement | null>\n /** Row size. */\n size: ListItemSize\n /** Search box placeholder + accessible label. Defaults to the localized \"Search…\". */\n searchPlaceholder?: string\n /** Show a loader row instead of the options (server-side search in flight). */\n loading?: boolean\n /** Text next to the loader. Defaults to the localized \"Loading…\". */\n loadingText?: ReactNode\n /** Empty-result content — a node or `(query) => node`. Defaults to the localized \"No Options\". */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Tick the selected option(s). Defaults to `true`. */\n showSelectedTick?: boolean\n /** `aria-multiselectable` on the listbox. */\n multiselectable?: boolean\n /** Labels the listbox (the field label id). */\n labelledBy?: string\n /** Accessible label for the listbox when there's no visible label. */\n ariaLabel?: string\n /** Wraps the search box's key handling (e.g. MultiSelect's Backspace-removes-a-chip). */\n onSearchKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void\n /** Extra class on the panel. */\n className?: string\n}\n\n/**\n * The option popover shared by `Select`, `MultiSelect` and `PhoneField` (internal): a `FloatingPanel`\n * anchored under the field, an optional sticky search box (`role=\"combobox\"`, `aria-activedescendant`),\n * and a scrolling `role=\"listbox\"` of `ListItem` options — icon, label, the option's `trailing`, a tick\n * when selected, the keyboard highlight, disabled rows inert, `group`ed options under a labelled heading —\n * plus the loading and empty rows. All state\n * and keys live in `useOptionMenu`; this only renders it.\n */\nexport function OptionMenu({\n menu,\n anchorRef,\n size,\n searchPlaceholder,\n loading = false,\n loadingText,\n noOptionsText,\n showSelectedTick = true,\n multiselectable = false,\n labelledBy,\n ariaLabel,\n onSearchKeyDown,\n className,\n}: OptionMenuProps) {\n const t = useT()\n const searchPh = searchPlaceholder ?? t('common.search')\n const { filteredOptions, highlightedIndex } = menu\n\n const renderOption = ({ opt, index }: { opt: SelectOption; index: number }) => {\n const selected = menu.isSelected(opt)\n const tick = selected && showSelectedTick\n return (\n <ListItem\n key={opt.value}\n id={menu.optionId(index)}\n role=\"option\"\n tabIndex={-1}\n aria-selected={selected}\n aria-current={undefined}\n clickable\n selected={selected}\n disabled={opt.disabled}\n icon={opt.icon}\n className={clsx(index === highlightedIndex && styles.active)}\n trailing={\n opt.trailing != null || tick ? (\n <span className={styles.trailing}>\n {opt.trailing}\n {tick && <Icon name=\"TickCircle\" size=\"sm\" />}\n </span>\n ) : undefined\n }\n onMouseEnter={() => !opt.disabled && menu.setHighlightedIndex(index)}\n // keep focus where it is (trigger / search box) — a multi-select stays open and typing keeps\n // working; a single-select refocuses its trigger on close anyway\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => menu.pick(opt)}\n >\n {opt.label}\n </ListItem>\n )\n }\n\n // consecutive runs of the same `group` (the hook already gathered them) → a labelled role=\"group\"\n // each; ungrouped runs render as plain rows\n const renderRows = (rows: { opt: SelectOption; index: number }[]) => {\n if (!rows.some((r) => r.opt.group != null)) return rows.map(renderOption)\n const runs: { group: string | undefined; rows: typeof rows }[] = []\n for (const row of rows) {\n const last = runs[runs.length - 1]\n if (last && last.group === row.opt.group) last.rows.push(row)\n else runs.push({ group: row.opt.group, rows: [row] })\n }\n return runs.map((run, i) => {\n if (run.group == null) return run.rows.map(renderOption)\n const headingId = `${menu.listboxId}-group-${i}`\n return (\n <div key={`group-${i}`} role=\"group\" aria-labelledby={headingId} className={styles.group}>\n <Typography\n as=\"div\"\n id={headingId}\n role=\"presentation\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.groupLabel}\n >\n {run.group}\n </Typography>\n {run.rows.map(renderOption)}\n </div>\n )\n })\n }\n\n return (\n <FloatingPanel\n ref={menu.popoverRef}\n open={menu.open}\n triggerRef={anchorRef}\n onClose={menu.closeMenu}\n matchTriggerWidth\n className={clsx(styles.popover, className)}\n >\n {menu.searchable && (\n <div className={styles.search}>\n <Icon name=\"SearchNormal\" size=\"sm\" className={styles.searchIcon} aria-hidden=\"true\" />\n <input\n ref={menu.searchInputRef}\n className={styles.searchInput}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={menu.listboxId}\n aria-activedescendant={menu.activeId}\n aria-autocomplete=\"list\"\n aria-label={searchPh}\n placeholder={searchPh}\n value={menu.searchQuery}\n spellCheck={false}\n autoComplete=\"off\"\n onChange={(e) => menu.setSearchQuery(e.target.value)}\n onKeyDown={onSearchKeyDown ?? menu.handleKeyDown}\n />\n </div>\n )}\n\n {/* the listbox always carries its id (even when empty) so aria-controls never dangles */}\n <List\n role=\"listbox\"\n id={menu.listboxId}\n aria-labelledby={labelledBy}\n aria-label={labelledBy ? undefined : ariaLabel}\n aria-multiselectable={multiselectable || undefined}\n size={size}\n className={styles.listbox}\n // clear the mouse highlight when the pointer leaves the list (no lingering hover)\n onMouseLeave={() => menu.setHighlightedIndex(-1)}\n >\n {loading ? (\n <div className={styles.loading}>\n <Loader size=\"sm\" />\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {loadingText ?? t('common.loading')}\n </Typography>\n </div>\n ) : filteredOptions.length === 0 ? (\n <div className={styles.noOptions}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {noOptionsText == null\n ? t('select.noOptions')\n : typeof noOptionsText === 'function'\n ? noOptionsText(menu.searchQuery)\n : noOptionsText}\n </Typography>\n </div>\n ) : (\n renderRows(filteredOptions.map((opt, index) => ({ opt, index })))\n )}\n </List>\n </FloatingPanel>\n )\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type RefObject,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { IconName } from '../../icons/names'\n\n/** A single selectable option — shared by `Select`, `MultiSelect` and `PhoneField`. */\nexport interface SelectOption {\n /** The value committed when this option is chosen. */\n value: string\n /** Display + search text. */\n label: string\n /** Greys out and blocks selecting this option. */\n disabled?: boolean\n /** Leading icon — a known `IconName` (rendered as `<Icon>`) or any node. */\n icon?: IconName | ReactNode\n /**\n * Extra search terms matched alongside the label (case-insensitive, substring) — e.g. a currency's\n * code (`'USD'`) or a country's calling code (`'995'`). Never shown.\n */\n keywords?: readonly string[]\n /** Content on the right of the row, before the selected tick (e.g. a code or a count). */\n trailing?: ReactNode\n /**\n * Group heading. Options sharing a `group` are listed together under it (groups in order of first\n * appearance, options keeping their order within a group); options without one stay ungrouped.\n */\n group?: string\n}\n\n/**\n * Stable-group the options: each group gathered at its first appearance, order kept within a group. A\n * list with no `group` at all is returned untouched (the common case costs nothing).\n */\nexport function groupOptions<T extends SelectOption>(options: readonly T[]): readonly T[] {\n if (!options.some((o) => o.group != null)) return options\n const buckets = new Map<string | undefined, T[]>()\n for (const o of options) {\n const bucket = buckets.get(o.group)\n if (bucket) bucket.push(o)\n else buckets.set(o.group, [o])\n }\n return [...buckets.values()].flat()\n}\n\nexport interface UseOptionMenuOptions {\n /** Base for the listbox / option ids (`${idBase}-listbox`, `${idBase}-opt-${i}`). */\n idBase: string\n options: readonly SelectOption[]\n /** Whether an option is selected (drives the initial highlight when `highlightSelected`). */\n isSelected: (option: SelectOption) => boolean\n /** Called when an option is picked (Enter / Space / click). */\n onPick: (option: SelectOption) => void\n /** Close the menu after a pick (single-select) or keep it open (multi-select). Defaults to `true`. */\n closeOnPick?: boolean\n /** On open, highlight the selected option (single-select) instead of the first. Defaults to `true`. */\n highlightSelected?: boolean\n /** Show a search box that filters by label + keywords. */\n searchable?: boolean\n /** The consumer filters `options` itself (server-side search) — skip the local filter. */\n onSearchChange?: (query: string) => void\n disabled?: boolean\n /** The element focus returns to when the menu closes with `refocus` (the trigger / the input). */\n focusRef: RefObject<HTMLElement | null>\n /** Runs on every close (e.g. mark a form field touched). */\n onClose?: () => void\n}\n\n/**\n * The state + keyboard model behind every option popover (internal): open / close, the search query\n * and its label + keywords filter, the highlighted row (skipping disabled ones), type-ahead when not\n * searchable, and one `handleKeyDown` for the trigger and the search box — Arrow / Home / End move,\n * Enter / Space pick, Escape closes (refocusing), Tab closes and moves on. Render it with `OptionMenu`.\n */\nexport function useOptionMenu({\n idBase,\n options,\n isSelected,\n onPick,\n closeOnPick = true,\n highlightSelected = true,\n searchable = false,\n onSearchChange,\n disabled = false,\n focusRef,\n onClose,\n}: UseOptionMenuOptions) {\n const listboxId = `${idBase}-listbox`\n const optionId = useCallback((index: number) => `${idBase}-opt-${index}`, [idBase])\n\n const [open, setOpen] = useState(false)\n const [searchQuery, setSearchQueryState] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const searchInputRef = useRef<HTMLInputElement | null>(null)\n // the floating panel forwards its node here, for the focus-leaves-the-widget check on blur\n const popoverRef = useRef<HTMLDivElement | null>(null)\n const typeahead = useRef({ buffer: '', timer: 0 })\n // latest callbacks without re-creating the stable handlers\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n // local filter by label + keywords (skipped when the consumer owns the options — server search), then\n // grouped, so the flat index the keyboard walks is exactly the rendered order\n const filteredOptions = useMemo(() => {\n const q = searchQuery.trim().toLowerCase()\n const matches =\n !searchable || onSearchChange || !q\n ? options\n : options.filter(\n (o) =>\n o.label.toLowerCase().includes(q) ||\n o.keywords?.some((k) => k.toLowerCase().includes(q)),\n )\n return groupOptions(matches)\n }, [searchable, onSearchChange, searchQuery, options])\n\n const findEnabled = useCallback(\n (start: number, delta: number) => {\n let i = start\n while (i >= 0 && i < filteredOptions.length) {\n if (!filteredOptions[i].disabled) return i\n i += delta\n }\n return -1\n },\n [filteredOptions],\n )\n\n // single dismiss path: clears the search + type-ahead, notifies, optionally refocuses\n const closeMenu = useCallback(\n (refocus: boolean) => {\n setOpen(false)\n setSearchQueryState('')\n window.clearTimeout(typeahead.current.timer)\n typeahead.current.buffer = ''\n onCloseRef.current?.()\n if (refocus) focusRef.current?.focus()\n },\n [focusRef],\n )\n\n // on open: highlight the selected option (or the first enabled), focus the search box\n useEffect(() => {\n if (!open) return\n const selIdx = highlightSelected ? filteredOptions.findIndex(isSelected) : -1\n setHighlightedIndex(\n selIdx >= 0 && !filteredOptions[selIdx].disabled ? selIdx : findEnabled(0, 1),\n )\n if (searchable) requestAnimationFrame(() => searchInputRef.current?.focus())\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n // keep the highlighted option scrolled into view\n useEffect(() => {\n if (!open || highlightedIndex < 0) return\n document.getElementById(optionId(highlightedIndex))?.scrollIntoView?.({ block: 'nearest' })\n }, [open, highlightedIndex, optionId])\n\n // a new search → re-anchor the highlight to the first match\n useEffect(() => {\n if (open && searchable) setHighlightedIndex(findEnabled(0, 1))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchQuery])\n\n // the option count changed while open (async load / list shrink) → keep the highlight in range\n useEffect(() => {\n if (open) setHighlightedIndex((i) => (i < filteredOptions.length ? i : findEnabled(0, 1)))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filteredOptions.length])\n\n const openMenu = () => {\n if (!disabled) setOpen(true)\n }\n const toggleMenu = () => (open ? closeMenu(false) : openMenu())\n\n const setSearchQuery = (query: string) => {\n setSearchQueryState(query)\n onSearchChange?.(query)\n }\n\n const pick = (option: SelectOption | undefined) => {\n if (!option || option.disabled) return\n onPick(option)\n if (closeOnPick) closeMenu(true)\n }\n\n const moveHighlight = (delta: number) => {\n setHighlightedIndex((cur) => {\n const start = cur < 0 ? (delta > 0 ? 0 : filteredOptions.length - 1) : cur + delta\n const found = findEnabled(start, delta)\n return found === -1 ? cur : found\n })\n }\n\n // type-ahead (no search box): jump to the option whose label starts with the typed buffer\n const handleTypeahead = (char: string) => {\n const t = typeahead.current\n window.clearTimeout(t.timer)\n t.buffer += char.toLowerCase()\n t.timer = window.setTimeout(() => (t.buffer = ''), 500)\n const match = filteredOptions.findIndex(\n (o) => !o.disabled && o.label.toLowerCase().startsWith(t.buffer),\n )\n if (match >= 0) setHighlightedIndex(match)\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n open ? moveHighlight(1) : openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n open ? moveHighlight(-1) : openMenu()\n break\n case 'Enter':\n event.preventDefault()\n if (!open) openMenu()\n else pick(filteredOptions[highlightedIndex])\n break\n case ' ':\n // Space opens a closed menu; picks only when open without a search box (so search can type spaces)\n if (!open) {\n event.preventDefault()\n openMenu()\n } else if (!searchable) {\n event.preventDefault()\n pick(filteredOptions[highlightedIndex])\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation() // don't let FloatingPanel's own Escape also fire closeMenu\n closeMenu(true)\n }\n break\n case 'Tab':\n // refocus the trigger so Tab continues from the field's visual spot, not the portaled search\n // input's DOM position (end of <body>); no preventDefault — let Tab move on\n if (open) closeMenu(true)\n break\n case 'Home':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(0, 1))\n }\n break\n case 'End':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(filteredOptions.length - 1, -1))\n }\n break\n default:\n if (\n !searchable &&\n open &&\n event.key.length === 1 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n handleTypeahead(event.key)\n }\n }\n }\n\n const activeId = open && highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined\n\n return {\n open,\n openMenu,\n closeMenu,\n toggleMenu,\n searchable,\n searchQuery,\n setSearchQuery,\n filteredOptions,\n highlightedIndex,\n setHighlightedIndex,\n isSelected,\n pick,\n handleKeyDown,\n listboxId,\n optionId,\n activeId,\n searchInputRef,\n popoverRef,\n }\n}\n\n/** Everything `useOptionMenu` returns — pass it to `<OptionMenu menu={…} />`. */\nexport type OptionMenuState = ReturnType<typeof useOptionMenu>\n"],"names":["OptionMenu","menu","anchorRef","size","searchPlaceholder","loading","loadingText","noOptionsText","showSelectedTick","multiselectable","labelledBy","ariaLabel","onSearchKeyDown","className","useT","searchPh","filteredOptions","highlightedIndex","renderOption","opt","index","selected","tick","jsx","ListItem","clsx","styles","jsxs","Icon","e","renderRows","rows","r","runs","row","last","run","i","headingId","Typography","FloatingPanel","List","Loader","groupOptions","options","o","buckets","bucket","useOptionMenu","idBase","isSelected","onPick","closeOnPick","highlightSelected","searchable","onSearchChange","disabled","focusRef","onClose","listboxId","optionId","useCallback","open","setOpen","useState","searchQuery","setSearchQueryState","setHighlightedIndex","searchInputRef","useRef","popoverRef","typeahead","onCloseRef","useMemo","q","matches","_a","k","findEnabled","start","delta","closeMenu","refocus","_b","useEffect","selIdx","openMenu","toggleMenu","setSearchQuery","query","pick","option","moveHighlight","cur","found","handleTypeahead","char","t","match","handleKeyDown","event","activeId"],"mappings":"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"}
1
+ {"version":3,"file":"useOptionMenu-Dom1-bqm.js","sources":["../src/components/OptionMenu/OptionMenu.tsx","../src/components/OptionMenu/useOptionMenu.ts"],"sourcesContent":["import type { KeyboardEvent, ReactNode, RefObject } from 'react'\nimport { clsx } from 'clsx'\nimport { useT } from '../../theme'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport { List, ListItem, type ListItemSize } from '../List'\nimport { Loader } from '../Loader'\nimport { Typography } from '../Typography'\nimport type { OptionMenuState, SelectOption } from './useOptionMenu'\nimport styles from './OptionMenu.module.css'\n\nexport interface OptionMenuProps {\n /** The state from `useOptionMenu`. */\n menu: OptionMenuState\n /** What the panel anchors under (and matches the width of) — also excluded from outside-click. */\n anchorRef: RefObject<HTMLElement | null>\n /** Row size. */\n size: ListItemSize\n /** Search box placeholder + accessible label. Defaults to the localized \"Search…\". */\n searchPlaceholder?: string\n /** Show a loader row instead of the options (server-side search in flight). */\n loading?: boolean\n /** Text next to the loader. Defaults to the localized \"Loading…\". */\n loadingText?: ReactNode\n /** Empty-result content — a node or `(query) => node`. Defaults to the localized \"No Options\". */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Tick the selected option(s). Defaults to `true`. */\n showSelectedTick?: boolean\n /** `aria-multiselectable` on the listbox. */\n multiselectable?: boolean\n /** Labels the listbox (the field label id). */\n labelledBy?: string\n /** Accessible label for the listbox when there's no visible label. */\n ariaLabel?: string\n /** Wraps the search box's key handling (e.g. MultiSelect's Backspace-removes-a-chip). */\n onSearchKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void\n /** Extra class on the panel. */\n className?: string\n}\n\n/**\n * The option popover shared by `Select`, `MultiSelect` and `PhoneField` (internal): a `FloatingPanel`\n * anchored under the field, an optional sticky search box (`role=\"combobox\"`, `aria-activedescendant`),\n * and a scrolling `role=\"listbox\"` of `ListItem` options — icon, label, the option's `trailing`, a tick\n * when selected, the keyboard highlight, disabled rows inert, `group`ed options under a labelled heading —\n * plus the loading and empty rows. All state\n * and keys live in `useOptionMenu`; this only renders it.\n */\nexport function OptionMenu({\n menu,\n anchorRef,\n size,\n searchPlaceholder,\n loading = false,\n loadingText,\n noOptionsText,\n showSelectedTick = true,\n multiselectable = false,\n labelledBy,\n ariaLabel,\n onSearchKeyDown,\n className,\n}: OptionMenuProps) {\n const t = useT()\n const searchPh = searchPlaceholder ?? t('common.search')\n const { filteredOptions, highlightedIndex } = menu\n\n const renderOption = ({ opt, index }: { opt: SelectOption; index: number }) => {\n const selected = menu.isSelected(opt)\n const tick = selected && showSelectedTick\n return (\n <ListItem\n key={opt.value}\n id={menu.optionId(index)}\n role=\"option\"\n tabIndex={-1}\n aria-selected={selected}\n aria-current={undefined}\n clickable\n selected={selected}\n disabled={opt.disabled}\n icon={opt.icon}\n className={clsx(index === highlightedIndex && styles.active)}\n trailing={\n opt.trailing != null || tick ? (\n <span className={styles.trailing}>\n {opt.trailing}\n {tick && <Icon name=\"TickCircle\" size=\"sm\" />}\n </span>\n ) : undefined\n }\n onMouseEnter={() => !opt.disabled && menu.setHighlightedIndex(index)}\n // keep focus where it is (trigger / search box) — a multi-select stays open and typing keeps\n // working; a single-select refocuses its trigger on close anyway\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => menu.pick(opt)}\n >\n {opt.label}\n </ListItem>\n )\n }\n\n // consecutive runs of the same `group` (the hook already gathered them) → a labelled role=\"group\"\n // each; ungrouped runs render as plain rows\n const renderRows = (rows: { opt: SelectOption; index: number }[]) => {\n if (!rows.some((r) => r.opt.group != null)) return rows.map(renderOption)\n const runs: { group: string | undefined; rows: typeof rows }[] = []\n for (const row of rows) {\n const last = runs[runs.length - 1]\n if (last && last.group === row.opt.group) last.rows.push(row)\n else runs.push({ group: row.opt.group, rows: [row] })\n }\n return runs.map((run, i) => {\n if (run.group == null) return run.rows.map(renderOption)\n const headingId = `${menu.listboxId}-group-${i}`\n return (\n <div key={`group-${i}`} role=\"group\" aria-labelledby={headingId} className={styles.group}>\n <Typography\n as=\"div\"\n id={headingId}\n role=\"presentation\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.groupLabel}\n >\n {run.group}\n </Typography>\n {run.rows.map(renderOption)}\n </div>\n )\n })\n }\n\n return (\n <FloatingPanel\n ref={menu.popoverRef}\n open={menu.open}\n triggerRef={anchorRef}\n onClose={menu.closeMenu}\n matchTriggerWidth\n className={clsx(styles.popover, className)}\n >\n {menu.searchable && (\n <div className={styles.search}>\n <Icon name=\"SearchNormal\" size=\"sm\" className={styles.searchIcon} aria-hidden=\"true\" />\n <input\n ref={menu.searchInputRef}\n className={styles.searchInput}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={menu.listboxId}\n aria-activedescendant={menu.activeId}\n aria-autocomplete=\"list\"\n aria-label={searchPh}\n placeholder={searchPh}\n value={menu.searchQuery}\n spellCheck={false}\n autoComplete=\"off\"\n onChange={(e) => menu.setSearchQuery(e.target.value)}\n onKeyDown={onSearchKeyDown ?? menu.handleKeyDown}\n />\n </div>\n )}\n\n {/* the listbox always carries its id (even when empty) so aria-controls never dangles */}\n <List\n role=\"listbox\"\n id={menu.listboxId}\n aria-labelledby={labelledBy}\n aria-label={labelledBy ? undefined : ariaLabel}\n aria-multiselectable={multiselectable || undefined}\n size={size}\n className={styles.listbox}\n // clear the mouse highlight when the pointer leaves the list (no lingering hover)\n onMouseLeave={() => menu.setHighlightedIndex(-1)}\n >\n {loading ? (\n <div className={styles.loading}>\n <Loader size=\"sm\" />\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {loadingText ?? t('common.loading')}\n </Typography>\n </div>\n ) : filteredOptions.length === 0 ? (\n <div className={styles.noOptions}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {noOptionsText == null\n ? t('select.noOptions')\n : typeof noOptionsText === 'function'\n ? noOptionsText(menu.searchQuery)\n : noOptionsText}\n </Typography>\n </div>\n ) : (\n renderRows(filteredOptions.map((opt, index) => ({ opt, index })))\n )}\n </List>\n </FloatingPanel>\n )\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type RefObject,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { IconName } from '../../icons/names'\n\n/** A single selectable option — shared by `Select`, `MultiSelect` and `PhoneField`. */\nexport interface SelectOption {\n /** The value committed when this option is chosen. */\n value: string\n /** Display + search text. */\n label: string\n /** Greys out and blocks selecting this option. */\n disabled?: boolean\n /** Leading icon — a known `IconName` (rendered as `<Icon>`) or any node. */\n icon?: IconName | ReactNode\n /**\n * Extra search terms matched alongside the label (case-insensitive, substring) — e.g. a currency's\n * code (`'USD'`) or a country's calling code (`'995'`). Never shown.\n */\n keywords?: readonly string[]\n /** Content on the right of the row, before the selected tick (e.g. a code or a count). */\n trailing?: ReactNode\n /**\n * Group heading. Options sharing a `group` are listed together under it (groups in order of first\n * appearance, options keeping their order within a group); options without one stay ungrouped.\n */\n group?: string\n}\n\n/**\n * Stable-group the options: each group gathered at its first appearance, order kept within a group. A\n * list with no `group` at all is returned untouched (the common case costs nothing).\n */\nexport function groupOptions<T extends SelectOption>(options: readonly T[]): readonly T[] {\n if (!options.some((o) => o.group != null)) return options\n const buckets = new Map<string | undefined, T[]>()\n for (const o of options) {\n const bucket = buckets.get(o.group)\n if (bucket) bucket.push(o)\n else buckets.set(o.group, [o])\n }\n return [...buckets.values()].flat()\n}\n\nexport interface UseOptionMenuOptions {\n /** Base for the listbox / option ids (`${idBase}-listbox`, `${idBase}-opt-${i}`). */\n idBase: string\n options: readonly SelectOption[]\n /** Whether an option is selected (drives the initial highlight when `highlightSelected`). */\n isSelected: (option: SelectOption) => boolean\n /** Called when an option is picked (Enter / Space / click). */\n onPick: (option: SelectOption) => void\n /** Close the menu after a pick (single-select) or keep it open (multi-select). Defaults to `true`. */\n closeOnPick?: boolean\n /** On open, highlight the selected option (single-select) instead of the first. Defaults to `true`. */\n highlightSelected?: boolean\n /** Show a search box that filters by label + keywords. */\n searchable?: boolean\n /** The consumer filters `options` itself (server-side search) — skip the local filter. */\n onSearchChange?: (query: string) => void\n disabled?: boolean\n /** The element focus returns to when the menu closes with `refocus` (the trigger / the input). */\n focusRef: RefObject<HTMLElement | null>\n /** Runs on every close (e.g. mark a form field touched). */\n onClose?: () => void\n}\n\n/**\n * The state + keyboard model behind every option popover (internal): open / close, the search query\n * and its label + keywords filter, the highlighted row (skipping disabled ones), type-ahead when not\n * searchable, and one `handleKeyDown` for the trigger and the search box — Arrow / Home / End move,\n * Enter / Space pick, Escape closes (refocusing), Tab closes and moves on. Render it with `OptionMenu`.\n */\nexport function useOptionMenu({\n idBase,\n options,\n isSelected,\n onPick,\n closeOnPick = true,\n highlightSelected = true,\n searchable = false,\n onSearchChange,\n disabled = false,\n focusRef,\n onClose,\n}: UseOptionMenuOptions) {\n const listboxId = `${idBase}-listbox`\n const optionId = useCallback((index: number) => `${idBase}-opt-${index}`, [idBase])\n\n const [open, setOpen] = useState(false)\n const [searchQuery, setSearchQueryState] = useState('')\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const searchInputRef = useRef<HTMLInputElement | null>(null)\n // the floating panel forwards its node here, for the focus-leaves-the-widget check on blur\n const popoverRef = useRef<HTMLDivElement | null>(null)\n const typeahead = useRef({ buffer: '', timer: 0 })\n // latest callbacks without re-creating the stable handlers\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n // local filter by label + keywords (skipped when the consumer owns the options — server search), then\n // grouped, so the flat index the keyboard walks is exactly the rendered order\n const filteredOptions = useMemo(() => {\n const q = searchQuery.trim().toLowerCase()\n const matches =\n !searchable || onSearchChange || !q\n ? options\n : options.filter(\n (o) =>\n o.label.toLowerCase().includes(q) ||\n o.keywords?.some((k) => k.toLowerCase().includes(q)),\n )\n return groupOptions(matches)\n }, [searchable, onSearchChange, searchQuery, options])\n\n const findEnabled = useCallback(\n (start: number, delta: number) => {\n let i = start\n while (i >= 0 && i < filteredOptions.length) {\n if (!filteredOptions[i].disabled) return i\n i += delta\n }\n return -1\n },\n [filteredOptions],\n )\n\n // single dismiss path: clears the search + type-ahead, notifies, optionally refocuses\n const closeMenu = useCallback(\n (refocus: boolean) => {\n setOpen(false)\n setSearchQueryState('')\n window.clearTimeout(typeahead.current.timer)\n typeahead.current.buffer = ''\n onCloseRef.current?.()\n if (refocus) focusRef.current?.focus()\n },\n [focusRef],\n )\n\n // on open: highlight the selected option (or the first enabled), focus the search box\n useEffect(() => {\n if (!open) return\n const selIdx = highlightSelected ? filteredOptions.findIndex(isSelected) : -1\n setHighlightedIndex(\n selIdx >= 0 && !filteredOptions[selIdx].disabled ? selIdx : findEnabled(0, 1),\n )\n if (searchable) requestAnimationFrame(() => searchInputRef.current?.focus())\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n // keep the highlighted option scrolled into view\n useEffect(() => {\n if (!open || highlightedIndex < 0) return\n document.getElementById(optionId(highlightedIndex))?.scrollIntoView?.({ block: 'nearest' })\n }, [open, highlightedIndex, optionId])\n\n // a new search → re-anchor the highlight to the first match\n useEffect(() => {\n if (open && searchable) setHighlightedIndex(findEnabled(0, 1))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchQuery])\n\n // the option count changed while open (async load / list shrink) → keep the highlight in range\n useEffect(() => {\n if (open) setHighlightedIndex((i) => (i < filteredOptions.length ? i : findEnabled(0, 1)))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filteredOptions.length])\n\n const openMenu = () => {\n if (!disabled) setOpen(true)\n }\n const toggleMenu = () => (open ? closeMenu(false) : openMenu())\n\n const setSearchQuery = (query: string) => {\n setSearchQueryState(query)\n onSearchChange?.(query)\n }\n\n const pick = (option: SelectOption | undefined) => {\n if (!option || option.disabled) return\n onPick(option)\n if (closeOnPick) closeMenu(true)\n }\n\n const moveHighlight = (delta: number) => {\n setHighlightedIndex((cur) => {\n const start = cur < 0 ? (delta > 0 ? 0 : filteredOptions.length - 1) : cur + delta\n const found = findEnabled(start, delta)\n return found === -1 ? cur : found\n })\n }\n\n // type-ahead (no search box): jump to the option whose label starts with the typed buffer\n const handleTypeahead = (char: string) => {\n const t = typeahead.current\n window.clearTimeout(t.timer)\n t.buffer += char.toLowerCase()\n t.timer = window.setTimeout(() => (t.buffer = ''), 500)\n const match = filteredOptions.findIndex(\n (o) => !o.disabled && o.label.toLowerCase().startsWith(t.buffer),\n )\n if (match >= 0) setHighlightedIndex(match)\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n open ? moveHighlight(1) : openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n open ? moveHighlight(-1) : openMenu()\n break\n case 'Enter':\n event.preventDefault()\n if (!open) openMenu()\n else pick(filteredOptions[highlightedIndex])\n break\n case ' ':\n // Space opens a closed menu; picks only when open without a search box (so search can type spaces)\n if (!open) {\n event.preventDefault()\n openMenu()\n } else if (!searchable) {\n event.preventDefault()\n pick(filteredOptions[highlightedIndex])\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation() // don't let FloatingPanel's own Escape also fire closeMenu\n closeMenu(true)\n }\n break\n case 'Tab':\n // refocus the trigger so Tab continues from the field's visual spot, not the portaled search\n // input's DOM position (end of <body>); no preventDefault — let Tab move on\n if (open) closeMenu(true)\n break\n case 'Home':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(0, 1))\n }\n break\n case 'End':\n if (open) {\n event.preventDefault()\n setHighlightedIndex(findEnabled(filteredOptions.length - 1, -1))\n }\n break\n default:\n if (\n !searchable &&\n open &&\n event.key.length === 1 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n handleTypeahead(event.key)\n }\n }\n }\n\n const activeId = open && highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined\n\n return {\n open,\n openMenu,\n closeMenu,\n toggleMenu,\n searchable,\n searchQuery,\n setSearchQuery,\n filteredOptions,\n highlightedIndex,\n setHighlightedIndex,\n isSelected,\n pick,\n handleKeyDown,\n listboxId,\n optionId,\n activeId,\n searchInputRef,\n popoverRef,\n }\n}\n\n/** Everything `useOptionMenu` returns — pass it to `<OptionMenu menu={…} />`. */\nexport type OptionMenuState = ReturnType<typeof useOptionMenu>\n"],"names":["OptionMenu","menu","anchorRef","size","searchPlaceholder","loading","loadingText","noOptionsText","showSelectedTick","multiselectable","labelledBy","ariaLabel","onSearchKeyDown","className","useT","searchPh","filteredOptions","highlightedIndex","renderOption","opt","index","selected","tick","jsx","ListItem","clsx","styles","jsxs","Icon","e","renderRows","rows","r","runs","row","last","run","i","headingId","Typography","FloatingPanel","List","Loader","groupOptions","options","o","buckets","bucket","useOptionMenu","idBase","isSelected","onPick","closeOnPick","highlightSelected","searchable","onSearchChange","disabled","focusRef","onClose","listboxId","optionId","useCallback","open","setOpen","useState","searchQuery","setSearchQueryState","setHighlightedIndex","searchInputRef","useRef","popoverRef","typeahead","onCloseRef","useMemo","q","matches","_a","k","findEnabled","start","delta","closeMenu","refocus","_b","useEffect","selIdx","openMenu","toggleMenu","setSearchQuery","query","pick","option","moveHighlight","cur","found","handleTypeahead","char","t","match","handleKeyDown","event","activeId"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techzyapp/ui-library",
3
- "version": "1.0.41",
3
+ "version": "1.0.42",
4
4
  "description": "Techzy UI — reusable React component library for admin panels.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,109 +0,0 @@
1
- import { jsx as t, jsxs as m, Fragment as g } from "react/jsx-runtime";
2
- import { useNavigate as Q, useRouterState as y, Outlet as R } from "@tanstack/react-router";
3
- import { c as U } from "./errorMessage-C83fB2h5.js";
4
- import { A as b } from "./AuthGuard-CVklwDbj.js";
5
- import { a as k } from "./ConfigProvider-Bgu85MsI.js";
6
- import { A as B } from "./AuthLayout-q8pbCGdt.js";
7
- import { C as F } from "./Col-B51RlwWP.js";
8
- import { Q as G, E as I } from "./ErrorBoundary-ukRaS6uS.js";
9
- import { B as A } from "./Button-CjsnB8gX.js";
10
- import { T as L } from "./Toaster-Dput5iLU.js";
11
- import { R as K } from "./RootLayout-DIOquzrU.js";
12
- import { U as q } from "./UserCard-DYK6S-nr.js";
13
- import { L as w } from "./Loader-De8_GqR1.js";
14
- const D = "_pending_1jy0z_2", H = {
15
- pending: D
16
- }, nt = ({
17
- logo: d,
18
- logoTo: C,
19
- getUser: T,
20
- onLogout: S,
21
- authRouteId: E = "/_auth",
22
- loginPath: u = "/login",
23
- showUserCard: _ = !0,
24
- sidebarVariant: j,
25
- header: v,
26
- errorBoundary: a = !0,
27
- pending: l = !1,
28
- pendingFallback: x,
29
- unavailable: r,
30
- unavailableFallback: f
31
- }) => {
32
- const n = k(), O = Q(), W = y({
33
- select: (o) => o.matches.some((s) => s.routeId.startsWith(E))
34
- }), z = y({ select: (o) => {
35
- var s;
36
- return (s = o.location) == null ? void 0 : s.pathname;
37
- } }), i = () => {
38
- S(), O({ to: u });
39
- };
40
- if (l || r) {
41
- let o;
42
- if (l)
43
- o = x ?? /* @__PURE__ */ t("div", { className: H.pending, "aria-busy": "true", children: /* @__PURE__ */ t(w, { size: "lg" }) });
44
- else if (r) {
45
- const s = r.reason ?? (U(r.error) === 403 ? "forbidden" : "unreachable");
46
- if (f)
47
- o = f({
48
- error: r.error,
49
- reason: s,
50
- retry: r.onRetry,
51
- signOut: i
52
- });
53
- else {
54
- const c = s === "unreachable" ? r.onRetry : void 0, p = s === "forbidden";
55
- o = /* @__PURE__ */ t(
56
- B,
57
- {
58
- logo: d,
59
- icon: r.icon || void 0,
60
- color: r.color ?? "error",
61
- title: n(p ? "adminRoot.noAccessTitle" : "adminRoot.unreachableTitle"),
62
- subtitle: n(p ? "adminRoot.noAccessSubtitle" : "adminRoot.unreachableSubtitle"),
63
- children: /* @__PURE__ */ m(F, { gap: 16, children: [
64
- /* @__PURE__ */ t(G, { variant: "alert", error: r.error }),
65
- c ? /* @__PURE__ */ t(A, { fullWidth: !0, onClick: c, children: n("errorState.retry") }) : null,
66
- /* @__PURE__ */ t(A, { fullWidth: !0, variant: c ? "filled" : "contained", onClick: i, children: n("userCard.signOut") })
67
- ] })
68
- }
69
- );
70
- }
71
- }
72
- return /* @__PURE__ */ m(g, { children: [
73
- o,
74
- /* @__PURE__ */ t(L, {})
75
- ] });
76
- }
77
- const e = T(), h = a === !1 ? /* @__PURE__ */ t(R, {}) : /* @__PURE__ */ t(I, { ...a === !0 ? {} : a, resetKeys: [z], children: /* @__PURE__ */ t(R, {}) }), N = W ? h : /* @__PURE__ */ t(b, { isAuthenticated: e != null, redirectTo: u, children: /* @__PURE__ */ t(
78
- K,
79
- {
80
- logo: d,
81
- logoTo: C,
82
- sidebarVariant: j,
83
- toaster: !1,
84
- header: {
85
- user: e ? { name: e.name, email: e.email, avatar: e.avatar } : void 0,
86
- onLogout: i,
87
- ...v
88
- },
89
- sidebarFooter: _ && e ? /* @__PURE__ */ t(
90
- q,
91
- {
92
- name: e.name,
93
- email: e.email,
94
- avatar: e.avatar,
95
- onLogout: i
96
- }
97
- ) : void 0,
98
- children: h
99
- }
100
- ) });
101
- return /* @__PURE__ */ m(g, { children: [
102
- N,
103
- /* @__PURE__ */ t(L, {})
104
- ] });
105
- };
106
- export {
107
- nt as A
108
- };
109
- //# sourceMappingURL=AdminRoot-aOYQtzF0.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminRoot-aOYQtzF0.js","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Outlet, useNavigate, useRouterState, type LinkProps } from '@tanstack/react-router'\nimport {\n AuthLayout,\n Button,\n Col,\n ErrorBoundary,\n Loader,\n QueryError,\n RootLayout,\n UserCard,\n Toaster,\n type ErrorBoundaryProps,\n type IconName,\n type RootLayoutHeader,\n type RootLayoutProps,\n} from '../components'\nimport { getErrorStatus } from '../components/ErrorState/errorMessage'\nimport { useT, type ThemeColor } from '../theme'\nimport { AuthGuard } from '../auth/AuthGuard'\nimport styles from './AdminRoot.module.css'\n\n/** Why the session can't be used — see `AdminRootUnavailable.reason`. */\nexport type AdminRootUnavailableReason = 'forbidden' | 'unreachable'\n\n/** The `unavailable` state of `AdminRoot` — the session could not be checked, or may not be used here. */\nexport interface AdminRootUnavailable {\n /** What failed — passed to `QueryError` (message, trace id). */\n error: unknown\n /**\n * Why. `'forbidden'` = a valid session this panel may not use (no retry, only Sign Out).\n * `'unreachable'` = the check itself failed (Try Again + Sign Out). Defaults to `'forbidden'` when the\n * error carries HTTP status 403 (`error.status` or `error.response.status`), else `'unreachable'`.\n */\n reason?: AdminRootUnavailableReason\n /** Re-runs the session check. Shown as \"Try Again\" for `'unreachable'` only. */\n onRetry?: () => void\n /**\n * The `AuthLayout` icon. Default: none — apps differ here (one shows a tinted `CloudCross`, another keeps\n * every auth page icon-free), so it's the app's choice.\n */\n icon?: IconName | false\n /** Tint for `icon` (`AuthLayout`'s `color`). Default `'error'`. */\n color?: ThemeColor\n}\n\n/** What an `unavailableFallback` receives. */\nexport interface AdminRootUnavailableFallbackProps {\n /** The `unavailable.error`. */\n error: unknown\n /** The resolved reason (explicit, or inferred from a 403). */\n reason: AdminRootUnavailableReason\n /** `unavailable.onRetry`, when given — whatever the reason (the fallback decides whether to offer it). */\n retry?: () => void\n /** The shell's Sign Out: `onLogout()`, then navigate to `loginPath`. */\n signOut: () => void\n}\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /**\n * Where clicking the logo goes — the first menu page by default (see `RootLayout`'s `logoTo`); a path to\n * send it elsewhere, or `false` for a non-clickable logo.\n */\n logoTo?: RootLayoutProps['logoTo']\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /** Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. */\n loginPath?: string\n /** Show a `UserCard` in the sidebar footer. Default `true`. */\n showUserCard?: boolean\n /**\n * The sidebar's look, passed to `RootLayout` — `'floating'` or `'docked'` (flush to the edges). **Unset\n * (recommended)**, each user picks it in the header Settings drawer (saved), defaulting to the app-wide\n * `config.sidebar.variant` (`'floating'` when unset). **Set**, it pins the look and the drawer's Sidebar\n * section is hidden.\n */\n sidebarVariant?: RootLayoutProps['sidebarVariant']\n /**\n * Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). Flows through\n * unchanged — e.g. **`header.menu`** (`HeaderMenuItem[]`) adds items to the account menu above Sign out.\n */\n header?: RootLayoutHeader\n /**\n * Wrap the page content in an `ErrorBoundary` (reset on navigation), so a crashing page shows an\n * `ErrorState` inside the shell instead of a white screen. Default `true`; `false` opts out; an object\n * configures it (e.g. `{ onError: Sentry.captureException }` or a custom `fallback`). It only catches what\n * the router doesn't: TanStack Router catches a route's component / `loader` / `beforeLoad` errors in its own\n * per-route boundary, so page crashes need `createRouter({ defaultErrorComponent: PageError })`.\n */\n errorBoundary?: boolean | Omit<ErrorBoundaryProps, 'children' | 'resetKeys'>\n /**\n * The app is still finding out who is signed in (e.g. verifying a stored token or refreshing a cookie\n * session). While `true`, AdminRoot renders only `pendingFallback` — no shell, no public page, no\n * `AuthGuard`, and `getUser()` isn't read — so a signed-in admin is never redirected to sign-in before the\n * check resolves. Route `beforeLoad` guards (e.g. `authLayoutRoute`) still run in the router, independent\n * of this — they must tolerate the unknown state themselves. No minimum display time. Default `false`.\n */\n pending?: boolean\n /** What to show while `pending`. Default: a `Loader size=\"lg\"` centred in the full viewport. */\n pendingFallback?: ReactNode\n /**\n * The session could not be checked, or the server will not serve this account here. While set, AdminRoot\n * renders a standalone `AuthLayout` screen (the app's `logo`, a `QueryError`, Try Again / Sign Out) instead\n * of the shell or a public page — and never redirects. Sign Out calls `onLogout` then navigates to\n * `loginPath`, so **`onLogout` must clear whatever set `unavailable`** (or this screen shows again).\n * `pending` wins when both are set. `null` / `undefined` = not unavailable (the default).\n */\n unavailable?: AdminRootUnavailable | null\n /** Replaces the whole `unavailable` screen — for an app that needs its own wording or extra actions. */\n unavailableFallback?: (props: AdminRootUnavailableFallbackProps) => ReactNode\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout` + a sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath`). Logout clears the session and navigates to\n * `loginPath`. Mounts exactly one app-wide `<Toaster/>` (the inner `RootLayout` gets `toaster={false}`),\n * and wraps the page in an `ErrorBoundary` that resets on navigation (`errorBoundary`, default on).\n * While the app is still checking the session, pass `pending` (a full-screen loader instead of a premature\n * sign-in redirect); when the check failed or the server refuses this account, pass `unavailable` (a\n * standalone \"Cannot Reach the Server\" / \"No Access\" screen with Try Again / Sign Out). The `Toaster` stays\n * mounted in both.\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => {\n * const { status, error, retry } = useSession()\n * return (\n * <AdminRoot<AuthUser>\n * pending={status === 'loading'}\n * unavailable={status === 'unavailable' ? { error, onRetry: retry } : null}\n * logo={<Logo />}\n * getUser={getUser}\n * onLogout={logout}\n * />\n * )\n * },\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n logoTo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard = true,\n sidebarVariant,\n header,\n errorBoundary = true,\n pending = false,\n pendingFallback,\n unavailable,\n unavailableFallback,\n}: AdminRootProps<U>) => {\n const t = useT()\n const navigate = useNavigate()\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const pathname = useRouterState({ select: (s) => s.location?.pathname })\n const handleLogout = () => {\n onLogout()\n navigate({ to: loginPath as LinkProps['to'] })\n }\n\n // the session isn't known yet / can't be used — a standalone screen instead of the shell or a public\n // page (so no AuthGuard redirect, no sign-in flash). The Toaster stays, so a bootstrap toast isn't lost.\n if (pending || unavailable) {\n let gate: ReactNode\n if (pending) {\n gate = pendingFallback ?? (\n <div className={styles.pending} aria-busy=\"true\">\n <Loader size=\"lg\" />\n </div>\n )\n } else if (unavailable) {\n const reason: AdminRootUnavailableReason =\n unavailable.reason ??\n (getErrorStatus(unavailable.error) === 403 ? 'forbidden' : 'unreachable')\n if (unavailableFallback) {\n gate = unavailableFallback({\n error: unavailable.error,\n reason,\n retry: unavailable.onRetry,\n signOut: handleLogout,\n })\n } else {\n const retry = reason === 'unreachable' ? unavailable.onRetry : undefined\n const forbidden = reason === 'forbidden'\n gate = (\n <AuthLayout\n logo={logo}\n icon={unavailable.icon || undefined}\n color={unavailable.color ?? 'error'}\n title={t(forbidden ? 'adminRoot.noAccessTitle' : 'adminRoot.unreachableTitle')}\n subtitle={t(forbidden ? 'adminRoot.noAccessSubtitle' : 'adminRoot.unreachableSubtitle')}\n >\n <Col gap={16}>\n <QueryError variant=\"alert\" error={unavailable.error} />\n {retry ? (\n <Button fullWidth onClick={retry}>\n {t('errorState.retry')}\n </Button>\n ) : null}\n <Button fullWidth variant={retry ? 'filled' : 'contained'} onClick={handleLogout}>\n {t('userCard.signOut')}\n </Button>\n </Col>\n </AuthLayout>\n )\n }\n }\n return (\n <>\n {gate}\n <Toaster />\n </>\n )\n }\n\n const user = getUser()\n // the routed page, inside an ErrorBoundary that resets whenever the path changes\n const page =\n errorBoundary === false ? (\n <Outlet />\n ) : (\n <ErrorBoundary {...(errorBoundary === true ? {} : errorBoundary)} resetKeys={[pathname]}>\n <Outlet />\n </ErrorBoundary>\n )\n const content = isAuthRoute ? (\n page\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n logoTo={logoTo}\n sidebarVariant={sidebarVariant}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n sidebarFooter={\n showUserCard && user ? (\n <UserCard\n name={user.name}\n email={user.email}\n avatar={user.avatar}\n onLogout={handleLogout}\n />\n ) : undefined\n }\n >\n {page}\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n <Toaster />\n </>\n )\n}\n"],"names":["AdminRoot","logo","logoTo","getUser","onLogout","authRouteId","loginPath","showUserCard","sidebarVariant","header","errorBoundary","pending","pendingFallback","unavailable","unavailableFallback","t","useT","navigate","useNavigate","isAuthRoute","useRouterState","s","m","pathname","_a","handleLogout","gate","jsx","styles","Loader","reason","getErrorStatus","retry","forbidden","AuthLayout","jsxs","Col","QueryError","Button","Fragment","Toaster","user","page","Outlet","ErrorBoundary","content","AuthGuard","RootLayout","UserCard"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),n=require("@tanstack/react-router"),B=require("./errorMessage-C7N4KvUS.cjs"),W=require("./AuthGuard-kfOZviar.cjs"),z=require("./ConfigProvider-DELhJlqo.cjs"),F=require("./AuthLayout-exuNQicH.cjs"),G=require("./Col-BdQeyKEX.cjs"),x=require("./ErrorBoundary-DL194IyB.cjs"),R=require("./Button-ClVfHGBc.cjs"),f=require("./Toaster-fjyF8W3F.cjs"),N=require("./RootLayout-B_ZtI-L_.cjs"),U=require("./UserCard-B9bzkZph.cjs"),b=require("./Loader-Cywaf7ju.cjs"),k="_pending_1jy0z_2",I={pending:k},K=({logo:d,logoTo:y,getUser:q,onLogout:A,authRouteId:L="/_auth",loginPath:l="/login",showUserCard:C=!0,sidebarVariant:p,header:T,errorBoundary:c=!0,pending:h=!1,pendingFallback:S,unavailable:t,unavailableFallback:m})=>{const i=z.useT(),v=n.useNavigate(),E=n.useRouterState({select:o=>o.matches.some(s=>s.routeId.startsWith(L))}),O=n.useRouterState({select:o=>{var s;return(s=o.location)==null?void 0:s.pathname}}),u=()=>{A(),v({to:l})};if(h||t){let o;if(h)o=S??e.jsx("div",{className:I.pending,"aria-busy":"true",children:e.jsx(b.Loader,{size:"lg"})});else if(t){const s=t.reason??(B.getErrorStatus(t.error)===403?"forbidden":"unreachable");if(m)o=m({error:t.error,reason:s,retry:t.onRetry,signOut:u});else{const a=s==="unreachable"?t.onRetry:void 0,g=s==="forbidden";o=e.jsx(F.AuthLayout,{logo:d,icon:t.icon||void 0,color:t.color??"error",title:i(g?"adminRoot.noAccessTitle":"adminRoot.unreachableTitle"),subtitle:i(g?"adminRoot.noAccessSubtitle":"adminRoot.unreachableSubtitle"),children:e.jsxs(G.Col,{gap:16,children:[e.jsx(x.QueryError,{variant:"alert",error:t.error}),a?e.jsx(R.Button,{fullWidth:!0,onClick:a,children:i("errorState.retry")}):null,e.jsx(R.Button,{fullWidth:!0,variant:a?"filled":"contained",onClick:u,children:i("userCard.signOut")})]})})}}return e.jsxs(e.Fragment,{children:[o,e.jsx(f.Toaster,{})]})}const r=q(),j=c===!1?e.jsx(n.Outlet,{}):e.jsx(x.ErrorBoundary,{...c===!0?{}:c,resetKeys:[O],children:e.jsx(n.Outlet,{})}),_=E?j:e.jsx(W.AuthGuard,{isAuthenticated:r!=null,redirectTo:l,children:e.jsx(N.RootLayout,{logo:d,logoTo:y,sidebarVariant:p,toaster:!1,header:{user:r?{name:r.name,email:r.email,avatar:r.avatar}:void 0,onLogout:u,...T},sidebarFooter:C&&r?e.jsx(U.UserCard,{name:r.name,email:r.email,avatar:r.avatar,onLogout:u}):void 0,children:j})});return e.jsxs(e.Fragment,{children:[_,e.jsx(f.Toaster,{})]})};exports.AdminRoot=K;
2
- //# sourceMappingURL=AdminRoot-ajWIf94J.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminRoot-ajWIf94J.cjs","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Outlet, useNavigate, useRouterState, type LinkProps } from '@tanstack/react-router'\nimport {\n AuthLayout,\n Button,\n Col,\n ErrorBoundary,\n Loader,\n QueryError,\n RootLayout,\n UserCard,\n Toaster,\n type ErrorBoundaryProps,\n type IconName,\n type RootLayoutHeader,\n type RootLayoutProps,\n} from '../components'\nimport { getErrorStatus } from '../components/ErrorState/errorMessage'\nimport { useT, type ThemeColor } from '../theme'\nimport { AuthGuard } from '../auth/AuthGuard'\nimport styles from './AdminRoot.module.css'\n\n/** Why the session can't be used — see `AdminRootUnavailable.reason`. */\nexport type AdminRootUnavailableReason = 'forbidden' | 'unreachable'\n\n/** The `unavailable` state of `AdminRoot` — the session could not be checked, or may not be used here. */\nexport interface AdminRootUnavailable {\n /** What failed — passed to `QueryError` (message, trace id). */\n error: unknown\n /**\n * Why. `'forbidden'` = a valid session this panel may not use (no retry, only Sign Out).\n * `'unreachable'` = the check itself failed (Try Again + Sign Out). Defaults to `'forbidden'` when the\n * error carries HTTP status 403 (`error.status` or `error.response.status`), else `'unreachable'`.\n */\n reason?: AdminRootUnavailableReason\n /** Re-runs the session check. Shown as \"Try Again\" for `'unreachable'` only. */\n onRetry?: () => void\n /**\n * The `AuthLayout` icon. Default: none — apps differ here (one shows a tinted `CloudCross`, another keeps\n * every auth page icon-free), so it's the app's choice.\n */\n icon?: IconName | false\n /** Tint for `icon` (`AuthLayout`'s `color`). Default `'error'`. */\n color?: ThemeColor\n}\n\n/** What an `unavailableFallback` receives. */\nexport interface AdminRootUnavailableFallbackProps {\n /** The `unavailable.error`. */\n error: unknown\n /** The resolved reason (explicit, or inferred from a 403). */\n reason: AdminRootUnavailableReason\n /** `unavailable.onRetry`, when given — whatever the reason (the fallback decides whether to offer it). */\n retry?: () => void\n /** The shell's Sign Out: `onLogout()`, then navigate to `loginPath`. */\n signOut: () => void\n}\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /**\n * Where clicking the logo goes — the first menu page by default (see `RootLayout`'s `logoTo`); a path to\n * send it elsewhere, or `false` for a non-clickable logo.\n */\n logoTo?: RootLayoutProps['logoTo']\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /** Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. */\n loginPath?: string\n /** Show a `UserCard` in the sidebar footer. Default `true`. */\n showUserCard?: boolean\n /**\n * The sidebar's look, passed to `RootLayout` — `'floating'` or `'docked'` (flush to the edges). **Unset\n * (recommended)**, each user picks it in the header Settings drawer (saved), defaulting to the app-wide\n * `config.sidebar.variant` (`'floating'` when unset). **Set**, it pins the look and the drawer's Sidebar\n * section is hidden.\n */\n sidebarVariant?: RootLayoutProps['sidebarVariant']\n /**\n * Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). Flows through\n * unchanged — e.g. **`header.menu`** (`HeaderMenuItem[]`) adds items to the account menu above Sign out.\n */\n header?: RootLayoutHeader\n /**\n * Wrap the page content in an `ErrorBoundary` (reset on navigation), so a crashing page shows an\n * `ErrorState` inside the shell instead of a white screen. Default `true`; `false` opts out; an object\n * configures it (e.g. `{ onError: Sentry.captureException }` or a custom `fallback`). It only catches what\n * the router doesn't: TanStack Router catches a route's component / `loader` / `beforeLoad` errors in its own\n * per-route boundary, so page crashes need `createRouter({ defaultErrorComponent: PageError })`.\n */\n errorBoundary?: boolean | Omit<ErrorBoundaryProps, 'children' | 'resetKeys'>\n /**\n * The app is still finding out who is signed in (e.g. verifying a stored token or refreshing a cookie\n * session). While `true`, AdminRoot renders only `pendingFallback` — no shell, no public page, no\n * `AuthGuard`, and `getUser()` isn't read — so a signed-in admin is never redirected to sign-in before the\n * check resolves. Route `beforeLoad` guards (e.g. `authLayoutRoute`) still run in the router, independent\n * of this — they must tolerate the unknown state themselves. No minimum display time. Default `false`.\n */\n pending?: boolean\n /** What to show while `pending`. Default: a `Loader size=\"lg\"` centred in the full viewport. */\n pendingFallback?: ReactNode\n /**\n * The session could not be checked, or the server will not serve this account here. While set, AdminRoot\n * renders a standalone `AuthLayout` screen (the app's `logo`, a `QueryError`, Try Again / Sign Out) instead\n * of the shell or a public page — and never redirects. Sign Out calls `onLogout` then navigates to\n * `loginPath`, so **`onLogout` must clear whatever set `unavailable`** (or this screen shows again).\n * `pending` wins when both are set. `null` / `undefined` = not unavailable (the default).\n */\n unavailable?: AdminRootUnavailable | null\n /** Replaces the whole `unavailable` screen — for an app that needs its own wording or extra actions. */\n unavailableFallback?: (props: AdminRootUnavailableFallbackProps) => ReactNode\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout` + a sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath`). Logout clears the session and navigates to\n * `loginPath`. Mounts exactly one app-wide `<Toaster/>` (the inner `RootLayout` gets `toaster={false}`),\n * and wraps the page in an `ErrorBoundary` that resets on navigation (`errorBoundary`, default on).\n * While the app is still checking the session, pass `pending` (a full-screen loader instead of a premature\n * sign-in redirect); when the check failed or the server refuses this account, pass `unavailable` (a\n * standalone \"Cannot Reach the Server\" / \"No Access\" screen with Try Again / Sign Out). The `Toaster` stays\n * mounted in both.\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => {\n * const { status, error, retry } = useSession()\n * return (\n * <AdminRoot<AuthUser>\n * pending={status === 'loading'}\n * unavailable={status === 'unavailable' ? { error, onRetry: retry } : null}\n * logo={<Logo />}\n * getUser={getUser}\n * onLogout={logout}\n * />\n * )\n * },\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n logoTo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard = true,\n sidebarVariant,\n header,\n errorBoundary = true,\n pending = false,\n pendingFallback,\n unavailable,\n unavailableFallback,\n}: AdminRootProps<U>) => {\n const t = useT()\n const navigate = useNavigate()\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const pathname = useRouterState({ select: (s) => s.location?.pathname })\n const handleLogout = () => {\n onLogout()\n navigate({ to: loginPath as LinkProps['to'] })\n }\n\n // the session isn't known yet / can't be used — a standalone screen instead of the shell or a public\n // page (so no AuthGuard redirect, no sign-in flash). The Toaster stays, so a bootstrap toast isn't lost.\n if (pending || unavailable) {\n let gate: ReactNode\n if (pending) {\n gate = pendingFallback ?? (\n <div className={styles.pending} aria-busy=\"true\">\n <Loader size=\"lg\" />\n </div>\n )\n } else if (unavailable) {\n const reason: AdminRootUnavailableReason =\n unavailable.reason ??\n (getErrorStatus(unavailable.error) === 403 ? 'forbidden' : 'unreachable')\n if (unavailableFallback) {\n gate = unavailableFallback({\n error: unavailable.error,\n reason,\n retry: unavailable.onRetry,\n signOut: handleLogout,\n })\n } else {\n const retry = reason === 'unreachable' ? unavailable.onRetry : undefined\n const forbidden = reason === 'forbidden'\n gate = (\n <AuthLayout\n logo={logo}\n icon={unavailable.icon || undefined}\n color={unavailable.color ?? 'error'}\n title={t(forbidden ? 'adminRoot.noAccessTitle' : 'adminRoot.unreachableTitle')}\n subtitle={t(forbidden ? 'adminRoot.noAccessSubtitle' : 'adminRoot.unreachableSubtitle')}\n >\n <Col gap={16}>\n <QueryError variant=\"alert\" error={unavailable.error} />\n {retry ? (\n <Button fullWidth onClick={retry}>\n {t('errorState.retry')}\n </Button>\n ) : null}\n <Button fullWidth variant={retry ? 'filled' : 'contained'} onClick={handleLogout}>\n {t('userCard.signOut')}\n </Button>\n </Col>\n </AuthLayout>\n )\n }\n }\n return (\n <>\n {gate}\n <Toaster />\n </>\n )\n }\n\n const user = getUser()\n // the routed page, inside an ErrorBoundary that resets whenever the path changes\n const page =\n errorBoundary === false ? (\n <Outlet />\n ) : (\n <ErrorBoundary {...(errorBoundary === true ? {} : errorBoundary)} resetKeys={[pathname]}>\n <Outlet />\n </ErrorBoundary>\n )\n const content = isAuthRoute ? (\n page\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n logoTo={logoTo}\n sidebarVariant={sidebarVariant}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n sidebarFooter={\n showUserCard && user ? (\n <UserCard\n name={user.name}\n email={user.email}\n avatar={user.avatar}\n onLogout={handleLogout}\n />\n ) : undefined\n }\n >\n {page}\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n <Toaster />\n </>\n )\n}\n"],"names":["AdminRoot","logo","logoTo","getUser","onLogout","authRouteId","loginPath","showUserCard","sidebarVariant","header","errorBoundary","pending","pendingFallback","unavailable","unavailableFallback","t","useT","navigate","useNavigate","isAuthRoute","useRouterState","s","m","pathname","_a","handleLogout","gate","jsx","styles","Loader","reason","getErrorStatus","retry","forbidden","AuthLayout","jsxs","Col","QueryError","Button","Fragment","Toaster","user","page","Outlet","ErrorBoundary","content","AuthGuard","RootLayout","UserCard"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),x=require("react"),I=require("clsx"),l=require("./Icon-B6lz-V0A.cjs"),g=require("./IconButton-D3ZpI0XL.cjs"),C=require("./ConfigProvider-DELhJlqo.cjs"),N="_alert_13lvf_3",j="_filled_13lvf_19",h="_contained_13lvf_22",q="_outlined_13lvf_26",A="_text_13lvf_30",b="_icon_13lvf_35",z="_message_13lvf_44",E="_action_13lvf_50",T="_close_13lvf_57",s={alert:N,filled:j,contained:h,outlined:q,text:A,icon:b,message:z,action:E,close:T},w=new Set(l.ICON_NAMES),y={success:"TickCircle",error:"CloseCircle",warning:"Warning",info:"InfoCircle"},O=x.forwardRef(function({variant:i="filled",color:t="info",icon:n,action:c,onClose:o,closeLabel:a,className:_,style:f,children:d,...u},m){const v=C.useT(),r=n===!1?null:n==null?e.jsx(l.Icon,{name:y[t]??"InfoCircle"}):typeof n=="string"&&w.has(n)?e.jsx(l.Icon,{name:n}):n;return e.jsxs("div",{ref:m,role:"alert",className:I.clsx(s.alert,s[i],_),style:{"--tz-btn-rgb":`var(--tz-color-${t}-rgb)`,"--tz-btn-on":`var(--tz-color-${t}-contrast, #fff)`,...f},...u,children:[r!=null&&e.jsx("span",{className:s.icon,"aria-hidden":!0,children:r}),e.jsx("div",{className:s.message,children:d}),c!=null&&e.jsx("div",{className:s.action,children:c}),o&&e.jsx(g.IconButton,{variant:"text",color:t,size:"sm",className:s.close,"aria-label":a??v("common.close"),onClick:o,children:e.jsx(l.Icon,{name:"Close"})})]})});exports.Alert=O;
2
- //# sourceMappingURL=Alert-5tpyGb2M.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Alert-5tpyGb2M.cjs","sources":["../src/components/Alert/Alert.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Alert.module.css'\n\nexport type AlertVariant = 'contained' | 'filled' | 'outlined' | 'text'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Default leading icon per semantic color (other colors fall back to `InfoCircle`). */\nconst DEFAULT_ICON: Partial<Record<ThemeColor, IconName>> = {\n success: 'TickCircle',\n error: 'CloseCircle',\n warning: 'Warning',\n info: 'InfoCircle',\n}\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color' | 'title'> {\n /** Tint style. Defaults to `filled` (the soft tint). */\n variant?: AlertVariant\n /** Brand / semantic palette token that tints the alert. Defaults to `info`. */\n color?: ThemeColor\n /**\n * Leading icon — a known `IconName`, any node, or `false` to hide it. Defaults to the semantic icon\n * for `color` (success → `TickCircle`, error → `CloseCircle`, warning → `Warning`, info → `InfoCircle`).\n */\n icon?: IconName | ReactNode | false\n /** Trailing action (e.g. an `UNDO` button), placed before the close button. */\n action?: ReactNode\n /** When provided, a trailing × close button appears that calls this. */\n onClose?: () => void\n /** Accessible label for the close button. Defaults to `\"Close\"`. */\n closeLabel?: string\n /** Alert message. */\n children?: ReactNode\n}\n\n/**\n * A message banner — the library's inline feedback surface (info, success, warning, error). Tinted by\n * `color` via the shared `--tz-btn-rgb` pattern across the 4 standard `variant`s; a semantic leading\n * `icon` is auto-picked per color (override with `icon`, or `icon={false}` to drop it). An optional\n * `action` slot (e.g. an `UNDO` button) and an `onClose` × button trail the message. `role=\"alert\"`.\n */\nexport const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(\n {\n variant = 'filled',\n color = 'info',\n icon,\n action,\n onClose,\n closeLabel,\n className,\n style,\n children,\n ...props\n },\n ref,\n) {\n const t = useT()\n const renderedIcon =\n icon === false ? null : icon == null ? (\n <Icon name={DEFAULT_ICON[color] ?? 'InfoCircle'} />\n ) : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={clsx(styles.alert, styles[variant], className)}\n style={\n {\n '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`,\n '--tz-btn-on': `var(--tz-color-${color}-contrast, #fff)`,\n ...style,\n } as CSSProperties\n }\n {...props}\n >\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden>\n {renderedIcon}\n </span>\n )}\n <div className={styles.message}>{children}</div>\n {action != null && <div className={styles.action}>{action}</div>}\n {onClose && (\n <IconButton\n variant=\"text\"\n color={color}\n size=\"sm\"\n className={styles.close}\n aria-label={closeLabel ?? t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","DEFAULT_ICON","Alert","forwardRef","variant","color","icon","action","onClose","closeLabel","className","style","children","props","ref","t","useT","renderedIcon","jsx","Icon","jsxs","clsx","styles","IconButton"],"mappings":"2dAUMA,EAAgB,IAAI,IAAYC,YAAU,EAG1CC,EAAsD,CAC1D,QAAS,aACT,MAAO,cACP,QAAS,UACT,KAAM,YACR,EA4BaC,EAAQC,EAAAA,WAAuC,SAC1D,CACE,QAAAC,EAAU,SACV,MAAAC,EAAQ,OACR,KAAAC,EACA,OAAAC,EACA,QAAAC,EACA,WAAAC,EACA,UAAAC,EACA,MAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,MAAMC,EAAIC,EAAAA,KAAA,EACJC,EACJX,IAAS,GAAQ,KAAOA,GAAQ,KAC9BY,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAMlB,EAAaI,CAAK,GAAK,aAAc,EAC/C,OAAOC,GAAS,UAAYP,EAAc,IAAIO,CAAI,EACpDY,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAMb,CAAA,CAAkB,EAE9BA,EAGJ,OACEc,EAAAA,KAAC,MAAA,CACC,IAAAN,EACA,KAAK,QACL,UAAWO,EAAAA,KAAKC,EAAO,MAAOA,EAAOlB,CAAO,EAAGM,CAAS,EACxD,MACE,CACE,eAAgB,kBAAkBL,CAAK,QACvC,cAAe,kBAAkBA,CAAK,mBACtC,GAAGM,CAAA,EAGN,GAAGE,EAEH,SAAA,CAAAI,GAAgB,YACd,OAAA,CAAK,UAAWK,EAAO,KAAM,cAAW,GACtC,SAAAL,CAAA,CACH,EAEFC,EAAAA,IAAC,MAAA,CAAI,UAAWI,EAAO,QAAU,SAAAV,EAAS,EACzCL,GAAU,MAAQW,EAAAA,IAAC,OAAI,UAAWI,EAAO,OAAS,SAAAf,EAAO,EACzDC,GACCU,EAAAA,IAACK,EAAAA,WAAA,CACC,QAAQ,OACR,MAAAlB,EACA,KAAK,KACL,UAAWiB,EAAO,MAClB,aAAYb,GAAcM,EAAE,cAAc,EAC1C,QAASP,EAET,SAAAU,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAK,OAAA,CAAQ,CAAA,CAAA,CACrB,CAAA,CAAA,CAIR,CAAC"}
@@ -1,70 +0,0 @@
1
- import { jsx as e, jsxs as N } from "react/jsx-runtime";
2
- import { forwardRef as g } from "react";
3
- import { clsx as p } from "clsx";
4
- import { b as l, a as C } from "./Icon-D5TxgfCc.js";
5
- import { I } from "./IconButton-t1OhAMNc.js";
6
- import { a as x } from "./ConfigProvider-Bgu85MsI.js";
7
- const b = "_alert_13lvf_3", h = "_filled_13lvf_19", A = "_contained_13lvf_22", z = "_outlined_13lvf_26", E = "_text_13lvf_30", T = "_icon_13lvf_35", w = "_message_13lvf_44", y = "_action_13lvf_50", O = "_close_13lvf_57", n = {
8
- alert: b,
9
- filled: h,
10
- contained: A,
11
- outlined: z,
12
- text: E,
13
- icon: T,
14
- message: w,
15
- action: y,
16
- close: O
17
- }, S = new Set(C), j = {
18
- success: "TickCircle",
19
- error: "CloseCircle",
20
- warning: "Warning",
21
- info: "InfoCircle"
22
- }, R = g(function({
23
- variant: c = "filled",
24
- color: s = "info",
25
- icon: t,
26
- action: o,
27
- onClose: a,
28
- closeLabel: i,
29
- className: f,
30
- style: _,
31
- children: m,
32
- ...d
33
- }, v) {
34
- const u = x(), r = t === !1 ? null : t == null ? /* @__PURE__ */ e(l, { name: j[s] ?? "InfoCircle" }) : typeof t == "string" && S.has(t) ? /* @__PURE__ */ e(l, { name: t }) : t;
35
- return /* @__PURE__ */ N(
36
- "div",
37
- {
38
- ref: v,
39
- role: "alert",
40
- className: p(n.alert, n[c], f),
41
- style: {
42
- "--tz-btn-rgb": `var(--tz-color-${s}-rgb)`,
43
- "--tz-btn-on": `var(--tz-color-${s}-contrast, #fff)`,
44
- ..._
45
- },
46
- ...d,
47
- children: [
48
- r != null && /* @__PURE__ */ e("span", { className: n.icon, "aria-hidden": !0, children: r }),
49
- /* @__PURE__ */ e("div", { className: n.message, children: m }),
50
- o != null && /* @__PURE__ */ e("div", { className: n.action, children: o }),
51
- a && /* @__PURE__ */ e(
52
- I,
53
- {
54
- variant: "text",
55
- color: s,
56
- size: "sm",
57
- className: n.close,
58
- "aria-label": i ?? u("common.close"),
59
- onClick: a,
60
- children: /* @__PURE__ */ e(l, { name: "Close" })
61
- }
62
- )
63
- ]
64
- }
65
- );
66
- });
67
- export {
68
- R as A
69
- };
70
- //# sourceMappingURL=Alert-Dz0sNGpz.js.map