@techzyapp/ui-library 1.0.32 → 1.0.33

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 (416) hide show
  1. package/dist/AdminRoot-CwUHa2us.js +107 -0
  2. package/dist/AdminRoot-CwUHa2us.js.map +1 -0
  3. package/dist/AdminRoot-cjP_Ad4r.cjs +2 -0
  4. package/dist/AdminRoot-cjP_Ad4r.cjs.map +1 -0
  5. package/dist/{Alert-B9l1VhIr.cjs → Alert-CfjDmLR8.cjs} +2 -2
  6. package/dist/{Alert-B9l1VhIr.cjs.map → Alert-CfjDmLR8.cjs.map} +1 -1
  7. package/dist/{Alert-B7w9xD2p.js → Alert-LJDrtkJy.js} +3 -3
  8. package/dist/{Alert-B7w9xD2p.js.map → Alert-LJDrtkJy.js.map} +1 -1
  9. package/dist/{Breadcrumbs-B1JMwCjO.cjs → Breadcrumbs-COb2zmDk.cjs} +2 -2
  10. package/dist/{Breadcrumbs-B1JMwCjO.cjs.map → Breadcrumbs-COb2zmDk.cjs.map} +1 -1
  11. package/dist/{Breadcrumbs-Cl1CgKkk.js → Breadcrumbs-DYeVrOns.js} +3 -3
  12. package/dist/{Breadcrumbs-Cl1CgKkk.js.map → Breadcrumbs-DYeVrOns.js.map} +1 -1
  13. package/dist/{Button-BZq1mIUH.cjs → Button-BD5wpg-t.cjs} +2 -2
  14. package/dist/{Button-BZq1mIUH.cjs.map → Button-BD5wpg-t.cjs.map} +1 -1
  15. package/dist/{Button-BJ5Xd10u.js → Button-PBZnkRNn.js} +2 -2
  16. package/dist/{Button-BJ5Xd10u.js.map → Button-PBZnkRNn.js.map} +1 -1
  17. package/dist/{Calendar-r-dDXWEp.cjs → Calendar-842vjtdN.cjs} +2 -2
  18. package/dist/{Calendar-r-dDXWEp.cjs.map → Calendar-842vjtdN.cjs.map} +1 -1
  19. package/dist/{Calendar-rRPnaU9M.js → Calendar-Bb5Ekbpr.js} +3 -3
  20. package/dist/{Calendar-rRPnaU9M.js.map → Calendar-Bb5Ekbpr.js.map} +1 -1
  21. package/dist/{Card-Cr3D2bzJ.js → Card-CV_rHego.js} +2 -2
  22. package/dist/{Card-Cr3D2bzJ.js.map → Card-CV_rHego.js.map} +1 -1
  23. package/dist/{Card-KsczbH5c.cjs → Card-DL7XnkOA.cjs} +2 -2
  24. package/dist/{Card-KsczbH5c.cjs.map → Card-DL7XnkOA.cjs.map} +1 -1
  25. package/dist/{Chip-BZ3I4Lbe.cjs → Chip-CLPIPC9a.cjs} +2 -2
  26. package/dist/{Chip-BZ3I4Lbe.cjs.map → Chip-CLPIPC9a.cjs.map} +1 -1
  27. package/dist/{Chip-DEp1zWh1.js → Chip-DdOUVF0Z.js} +2 -2
  28. package/dist/{Chip-DEp1zWh1.js.map → Chip-DdOUVF0Z.js.map} +1 -1
  29. package/dist/{CodeBlock-CMHqvoBJ.js → CodeBlock-B35NXZzd.js} +3 -3
  30. package/dist/{CodeBlock-CMHqvoBJ.js.map → CodeBlock-B35NXZzd.js.map} +1 -1
  31. package/dist/{CodeBlock-DIkyeG4S.cjs → CodeBlock-C0dbyxcl.cjs} +2 -2
  32. package/dist/{CodeBlock-DIkyeG4S.cjs.map → CodeBlock-C0dbyxcl.cjs.map} +1 -1
  33. package/dist/{ColorPicker-5SMyU5oh.js → ColorPicker-6UraVYFy.js} +3 -3
  34. package/dist/{ColorPicker-5SMyU5oh.js.map → ColorPicker-6UraVYFy.js.map} +1 -1
  35. package/dist/{ColorPicker-B1riGs1z.cjs → ColorPicker-DmLGKaYF.cjs} +2 -2
  36. package/dist/{ColorPicker-B1riGs1z.cjs.map → ColorPicker-DmLGKaYF.cjs.map} +1 -1
  37. package/dist/{ColorPickerPanel-4Y6oXL7v.js → ColorPickerPanel-DZ-W_wOI.js} +2 -2
  38. package/dist/{ColorPickerPanel-4Y6oXL7v.js.map → ColorPickerPanel-DZ-W_wOI.js.map} +1 -1
  39. package/dist/{ColorPickerPanel-CzBlh0zw.cjs → ColorPickerPanel-WuxwwfCI.cjs} +2 -2
  40. package/dist/{ColorPickerPanel-CzBlh0zw.cjs.map → ColorPickerPanel-WuxwwfCI.cjs.map} +1 -1
  41. package/dist/{ColorRamp-Qc8ZtPDh.js → ColorRamp-CSqzzHZx.js} +2 -2
  42. package/dist/{ColorRamp-Qc8ZtPDh.js.map → ColorRamp-CSqzzHZx.js.map} +1 -1
  43. package/dist/{ColorRamp-D_h-hp7n.cjs → ColorRamp-D_9gsqJl.cjs} +2 -2
  44. package/dist/{ColorRamp-D_h-hp7n.cjs.map → ColorRamp-D_9gsqJl.cjs.map} +1 -1
  45. package/dist/{ConfigProvider-CzAQf_d_.cjs → ConfigProvider-CVLHPXQm.cjs} +2 -2
  46. package/dist/ConfigProvider-CVLHPXQm.cjs.map +1 -0
  47. package/dist/{ConfigProvider-D2svpXFu.js → ConfigProvider-tvLbKiqu.js} +2 -2
  48. package/dist/ConfigProvider-tvLbKiqu.js.map +1 -0
  49. package/dist/{CopyButton-DUtx2-Gi.cjs → CopyButton-0w4OToIy.cjs} +2 -2
  50. package/dist/{CopyButton-DUtx2-Gi.cjs.map → CopyButton-0w4OToIy.cjs.map} +1 -1
  51. package/dist/{CopyButton-BNcW9-KU.js → CopyButton-B_mYxcXV.js} +3 -3
  52. package/dist/{CopyButton-BNcW9-KU.js.map → CopyButton-B_mYxcXV.js.map} +1 -1
  53. package/dist/{DatePicker-D2PyGdec.js → DatePicker-Bt-M87zX.js} +4 -4
  54. package/dist/{DatePicker-D2PyGdec.js.map → DatePicker-Bt-M87zX.js.map} +1 -1
  55. package/dist/{DatePicker-D_PqDvKt.cjs → DatePicker-D1uFIm3M.cjs} +2 -2
  56. package/dist/{DatePicker-D_PqDvKt.cjs.map → DatePicker-D1uFIm3M.cjs.map} +1 -1
  57. package/dist/{DateTimePicker-C3Kq5hKE.cjs → DateTimePicker-DPt-LDVJ.cjs} +2 -2
  58. package/dist/{DateTimePicker-C3Kq5hKE.cjs.map → DateTimePicker-DPt-LDVJ.cjs.map} +1 -1
  59. package/dist/{DateTimePicker-DdXFzqO_.js → DateTimePicker-zJUc9crs.js} +7 -7
  60. package/dist/{DateTimePicker-DdXFzqO_.js.map → DateTimePicker-zJUc9crs.js.map} +1 -1
  61. package/dist/{DescriptionList-DxRgKNEJ.js → DescriptionList-BLx9NfAW.js} +4 -4
  62. package/dist/{DescriptionList-DxRgKNEJ.js.map → DescriptionList-BLx9NfAW.js.map} +1 -1
  63. package/dist/{DescriptionList-C7AOcw_2.cjs → DescriptionList-CPCbzU9b.cjs} +2 -2
  64. package/dist/{DescriptionList-C7AOcw_2.cjs.map → DescriptionList-CPCbzU9b.cjs.map} +1 -1
  65. package/dist/{EmptyState-CvpKSYY4.js → EmptyState-BEVEGcLx.js} +2 -2
  66. package/dist/{EmptyState-CvpKSYY4.js.map → EmptyState-BEVEGcLx.js.map} +1 -1
  67. package/dist/{EmptyState-ECc6e_En.cjs → EmptyState-C54C0Qwc.cjs} +2 -2
  68. package/dist/{EmptyState-ECc6e_En.cjs.map → EmptyState-C54C0Qwc.cjs.map} +1 -1
  69. package/dist/ErrorBoundary-8iu-mR5Y.cjs +2 -0
  70. package/dist/ErrorBoundary-8iu-mR5Y.cjs.map +1 -0
  71. package/dist/ErrorBoundary-BSJL381Y.js +49 -0
  72. package/dist/ErrorBoundary-BSJL381Y.js.map +1 -0
  73. package/dist/ErrorState-BXMjBWav.cjs +4 -0
  74. package/dist/ErrorState-BXMjBWav.cjs.map +1 -0
  75. package/dist/ErrorState-DKhZ4aJh.js +142 -0
  76. package/dist/ErrorState-DKhZ4aJh.js.map +1 -0
  77. package/dist/{FileCard-Bjqsgi7S.cjs → FileCard-B3dfdTVN.cjs} +2 -2
  78. package/dist/{FileCard-Bjqsgi7S.cjs.map → FileCard-B3dfdTVN.cjs.map} +1 -1
  79. package/dist/{FileCard-D4t0-ms2.js → FileCard-R_sB8Qbx.js} +3 -3
  80. package/dist/{FileCard-D4t0-ms2.js.map → FileCard-R_sB8Qbx.js.map} +1 -1
  81. package/dist/{FileUploader-DWM8WrY6.cjs → FileUploader-4UMy0urx.cjs} +2 -2
  82. package/dist/{FileUploader-DWM8WrY6.cjs.map → FileUploader-4UMy0urx.cjs.map} +1 -1
  83. package/dist/{FileUploader-DdcvZoUb.js → FileUploader-B55atuxq.js} +5 -5
  84. package/dist/{FileUploader-DdcvZoUb.js.map → FileUploader-B55atuxq.js.map} +1 -1
  85. package/dist/{Flag-D5rqScYG.cjs → Flag-CFvJHC0u.cjs} +2 -2
  86. package/dist/{Flag-D5rqScYG.cjs.map → Flag-CFvJHC0u.cjs.map} +1 -1
  87. package/dist/{Flag-BLEBMdb-.js → Flag-D7fmMqqy.js} +2 -2
  88. package/dist/{Flag-BLEBMdb-.js.map → Flag-D7fmMqqy.js.map} +1 -1
  89. package/dist/{FullscreenToggle-DZnKK1Lj.js → FullscreenToggle-CXmPqxJv.js} +3 -3
  90. package/dist/{FullscreenToggle-DZnKK1Lj.js.map → FullscreenToggle-CXmPqxJv.js.map} +1 -1
  91. package/dist/{FullscreenToggle-CZoc5pYg.cjs → FullscreenToggle-D7tUPCNI.cjs} +2 -2
  92. package/dist/{FullscreenToggle-CZoc5pYg.cjs.map → FullscreenToggle-D7tUPCNI.cjs.map} +1 -1
  93. package/dist/{IconButton-V8tjArlt.cjs → IconButton-BVrO9TBP.cjs} +2 -2
  94. package/dist/{IconButton-V8tjArlt.cjs.map → IconButton-BVrO9TBP.cjs.map} +1 -1
  95. package/dist/{IconButton-CqFgam3J.js → IconButton-sC_E_TXd.js} +2 -2
  96. package/dist/{IconButton-CqFgam3J.js.map → IconButton-sC_E_TXd.js.map} +1 -1
  97. package/dist/{Loader-Bsz0BkGr.js → Loader-ChrouvaR.js} +2 -2
  98. package/dist/{Loader-Bsz0BkGr.js.map → Loader-ChrouvaR.js.map} +1 -1
  99. package/dist/{Loader-CqRaCdzF.cjs → Loader-DNCEHqZb.cjs} +2 -2
  100. package/dist/{Loader-CqRaCdzF.cjs.map → Loader-DNCEHqZb.cjs.map} +1 -1
  101. package/dist/{LocationPicker-BRGNcTd_.cjs → LocationPicker-CJ6bCJC4.cjs} +2 -2
  102. package/dist/{LocationPicker-BRGNcTd_.cjs.map → LocationPicker-CJ6bCJC4.cjs.map} +1 -1
  103. package/dist/{LocationPicker-DtMDpPFZ.js → LocationPicker-DxiQ27k6.js} +6 -6
  104. package/dist/{LocationPicker-DtMDpPFZ.js.map → LocationPicker-DxiQ27k6.js.map} +1 -1
  105. package/dist/{Modal-CcrqM4kn.cjs → Modal-BL_XihC8.cjs} +2 -2
  106. package/dist/{Modal-CcrqM4kn.cjs.map → Modal-BL_XihC8.cjs.map} +1 -1
  107. package/dist/{Modal-DCee1a9m.js → Modal-Do8pzyMl.js} +3 -3
  108. package/dist/{Modal-DCee1a9m.js.map → Modal-Do8pzyMl.js.map} +1 -1
  109. package/dist/{MultiSelect-JQ6iKHyI.js → MultiSelect-BfsEdXNa.js} +4 -4
  110. package/dist/{MultiSelect-JQ6iKHyI.js.map → MultiSelect-BfsEdXNa.js.map} +1 -1
  111. package/dist/{MultiSelect-BJ-qMpA5.cjs → MultiSelect-WS5YNGRD.cjs} +2 -2
  112. package/dist/{MultiSelect-BJ-qMpA5.cjs.map → MultiSelect-WS5YNGRD.cjs.map} +1 -1
  113. package/dist/{NumberField-mZjwZB8E.cjs → NumberField-CxiEfRAi.cjs} +2 -2
  114. package/dist/{NumberField-mZjwZB8E.cjs.map → NumberField-CxiEfRAi.cjs.map} +1 -1
  115. package/dist/{NumberField-Bf-vDNLy.js → NumberField-P68n6q5m.js} +3 -3
  116. package/dist/{NumberField-Bf-vDNLy.js.map → NumberField-P68n6q5m.js.map} +1 -1
  117. package/dist/{OtpField-DaAIBp6C.js → OtpField-DjTJH4Kh.js} +2 -2
  118. package/dist/{OtpField-DaAIBp6C.js.map → OtpField-DjTJH4Kh.js.map} +1 -1
  119. package/dist/{OtpField-TdjMkgQi.cjs → OtpField-XieJfl1y.cjs} +2 -2
  120. package/dist/{OtpField-TdjMkgQi.cjs.map → OtpField-XieJfl1y.cjs.map} +1 -1
  121. package/dist/PageError-ClR7k0Zb.js +69 -0
  122. package/dist/PageError-ClR7k0Zb.js.map +1 -0
  123. package/dist/PageError-D7_Q8wz8.cjs +2 -0
  124. package/dist/PageError-D7_Q8wz8.cjs.map +1 -0
  125. package/dist/{PageLayout-BoHvt2cT.cjs → PageLayout-DTG83hLL.cjs} +2 -2
  126. package/dist/{PageLayout-BoHvt2cT.cjs.map → PageLayout-DTG83hLL.cjs.map} +1 -1
  127. package/dist/{PageLayout-Bwv8Oohb.js → PageLayout-XQ_aQTf5.js} +2 -2
  128. package/dist/{PageLayout-Bwv8Oohb.js.map → PageLayout-XQ_aQTf5.js.map} +1 -1
  129. package/dist/PageNotFound-CpwHMTxG.js +24 -0
  130. package/dist/PageNotFound-CpwHMTxG.js.map +1 -0
  131. package/dist/PageNotFound-D3wJ4Job.cjs +2 -0
  132. package/dist/PageNotFound-D3wJ4Job.cjs.map +1 -0
  133. package/dist/{Pagination-DzkTjEZL.cjs → Pagination-BF8cmQMi.cjs} +2 -2
  134. package/dist/{Pagination-DzkTjEZL.cjs.map → Pagination-BF8cmQMi.cjs.map} +1 -1
  135. package/dist/{Pagination-C0xr3D-g.js → Pagination-Df-F9i2o.js} +2 -2
  136. package/dist/{Pagination-C0xr3D-g.js.map → Pagination-Df-F9i2o.js.map} +1 -1
  137. package/dist/{PaletteField-CQV2dll0.cjs → PaletteField-BFRPv7AC.cjs} +2 -2
  138. package/dist/{PaletteField-CQV2dll0.cjs.map → PaletteField-BFRPv7AC.cjs.map} +1 -1
  139. package/dist/{PaletteField-CQv6MBKe.js → PaletteField-DUu4jz1c.js} +3 -3
  140. package/dist/{PaletteField-CQv6MBKe.js.map → PaletteField-DUu4jz1c.js.map} +1 -1
  141. package/dist/{PhoneField-Bqj5-33G.js → PhoneField-CXIQX_hR.js} +4 -4
  142. package/dist/{PhoneField-Bqj5-33G.js.map → PhoneField-CXIQX_hR.js.map} +1 -1
  143. package/dist/{PhoneField-Dzdm5hfY.cjs → PhoneField-O5syyH7u.cjs} +2 -2
  144. package/dist/{PhoneField-Dzdm5hfY.cjs.map → PhoneField-O5syyH7u.cjs.map} +1 -1
  145. package/dist/{Popconfirm-CYkwGTh-.js → Popconfirm-D4J7tlk_.js} +3 -3
  146. package/dist/{Popconfirm-CYkwGTh-.js.map → Popconfirm-D4J7tlk_.js.map} +1 -1
  147. package/dist/{Popconfirm-DS6tCxV0.cjs → Popconfirm-bEoOPmZY.cjs} +2 -2
  148. package/dist/{Popconfirm-DS6tCxV0.cjs.map → Popconfirm-bEoOPmZY.cjs.map} +1 -1
  149. package/dist/{Progress-DZUtn3Sh.js → Progress-BxvqmmGS.js} +2 -2
  150. package/dist/{Progress-DZUtn3Sh.js.map → Progress-BxvqmmGS.js.map} +1 -1
  151. package/dist/{Progress-lf9vIKIk.cjs → Progress-CqXX0rRp.cjs} +2 -2
  152. package/dist/{Progress-lf9vIKIk.cjs.map → Progress-CqXX0rRp.cjs.map} +1 -1
  153. package/dist/{RemoveDialog-DaWh4xmW.js → RemoveDialog-DH3eNUxC.js} +5 -5
  154. package/dist/{RemoveDialog-DaWh4xmW.js.map → RemoveDialog-DH3eNUxC.js.map} +1 -1
  155. package/dist/{RemoveDialog-Csfhv9ve.cjs → RemoveDialog-FrieNcjL.cjs} +2 -2
  156. package/dist/{RemoveDialog-Csfhv9ve.cjs.map → RemoveDialog-FrieNcjL.cjs.map} +1 -1
  157. package/dist/{RichTextEditor-BLEDQq2H.js → RichTextEditor-6frB2C5G.js} +7 -7
  158. package/dist/{RichTextEditor-BLEDQq2H.js.map → RichTextEditor-6frB2C5G.js.map} +1 -1
  159. package/dist/{RichTextEditor-Eo8uLXlI.cjs → RichTextEditor-B-C4NPDk.cjs} +2 -2
  160. package/dist/{RichTextEditor-Eo8uLXlI.cjs.map → RichTextEditor-B-C4NPDk.cjs.map} +1 -1
  161. package/dist/{RootLayout-D-ZlsTXF.js → RootLayout-C7n79JjM.js} +219 -202
  162. package/dist/RootLayout-C7n79JjM.js.map +1 -0
  163. package/dist/RootLayout-CtkpgPGV.cjs +2 -0
  164. package/dist/RootLayout-CtkpgPGV.cjs.map +1 -0
  165. package/dist/{Select-CH3mF6y1.cjs → Select-Bjq_p8_e.cjs} +2 -2
  166. package/dist/{Select-CH3mF6y1.cjs.map → Select-Bjq_p8_e.cjs.map} +1 -1
  167. package/dist/{Select-C0UBQXhg.js → Select-DO3zDQYV.js} +3 -3
  168. package/dist/{Select-C0UBQXhg.js.map → Select-DO3zDQYV.js.map} +1 -1
  169. package/dist/{Sidebar-6wu2fuPT.cjs → Sidebar-2oH285Xs.cjs} +2 -2
  170. package/dist/{Sidebar-6wu2fuPT.cjs.map → Sidebar-2oH285Xs.cjs.map} +1 -1
  171. package/dist/{Sidebar--rOPtrqa.js → Sidebar-CKbSWc5q.js} +3 -3
  172. package/dist/{Sidebar--rOPtrqa.js.map → Sidebar-CKbSWc5q.js.map} +1 -1
  173. package/dist/{SpeedDial-BIodC6td.js → SpeedDial-BZK-z_r9.js} +2 -2
  174. package/dist/{SpeedDial-BIodC6td.js.map → SpeedDial-BZK-z_r9.js.map} +1 -1
  175. package/dist/{SpeedDial-BtxXH6Ij.cjs → SpeedDial-KGf8b4Gq.cjs} +2 -2
  176. package/dist/{SpeedDial-BtxXH6Ij.cjs.map → SpeedDial-KGf8b4Gq.cjs.map} +1 -1
  177. package/dist/{Stepper-CPBPTxbP.js → Stepper-BI3pjWf_.js} +2 -2
  178. package/dist/{Stepper-CPBPTxbP.js.map → Stepper-BI3pjWf_.js.map} +1 -1
  179. package/dist/{Stepper-B38I8PBS.cjs → Stepper-s9Vah5R2.cjs} +2 -2
  180. package/dist/{Stepper-B38I8PBS.cjs.map → Stepper-s9Vah5R2.cjs.map} +1 -1
  181. package/dist/Table-CLjLsYYS.cjs +2 -0
  182. package/dist/Table-CLjLsYYS.cjs.map +1 -0
  183. package/dist/{Table-BV-dr36o.js → Table-PsNnKn_j.js} +153 -152
  184. package/dist/Table-PsNnKn_j.js.map +1 -0
  185. package/dist/{Tabs-RjyUkLTB.js → Tabs-B2WzlRXI.js} +2 -2
  186. package/dist/{Tabs-RjyUkLTB.js.map → Tabs-B2WzlRXI.js.map} +1 -1
  187. package/dist/{Tabs-DIs8iFA-.cjs → Tabs-DQoNP0QT.cjs} +2 -2
  188. package/dist/{Tabs-DIs8iFA-.cjs.map → Tabs-DQoNP0QT.cjs.map} +1 -1
  189. package/dist/{TagsField-CJ10-kFr.cjs → TagsField-CLfAAz4N.cjs} +2 -2
  190. package/dist/{TagsField-CJ10-kFr.cjs.map → TagsField-CLfAAz4N.cjs.map} +1 -1
  191. package/dist/{TagsField-B3MtFiFs.js → TagsField-pdvQU4zh.js} +4 -4
  192. package/dist/{TagsField-B3MtFiFs.js.map → TagsField-pdvQU4zh.js.map} +1 -1
  193. package/dist/{TextField-D_hzd5Gf.cjs → TextField-CgPfN-4d.cjs} +2 -2
  194. package/dist/{TextField-D_hzd5Gf.cjs.map → TextField-CgPfN-4d.cjs.map} +1 -1
  195. package/dist/{TextField-CInaL0FR.js → TextField-LONfx4jy.js} +3 -3
  196. package/dist/{TextField-CInaL0FR.js.map → TextField-LONfx4jy.js.map} +1 -1
  197. package/dist/{ThemeToggle-DkhhlH_r.cjs → ThemeToggle-9RBaRALj.cjs} +2 -2
  198. package/dist/{ThemeToggle-DkhhlH_r.cjs.map → ThemeToggle-9RBaRALj.cjs.map} +1 -1
  199. package/dist/{ThemeToggle-CWfuK0tZ.js → ThemeToggle-DTkFppOd.js} +3 -3
  200. package/dist/{ThemeToggle-CWfuK0tZ.js.map → ThemeToggle-DTkFppOd.js.map} +1 -1
  201. package/dist/{TimeColumns-fD6dosYP.js → TimeColumns-B7af5Cbj.js} +2 -2
  202. package/dist/{TimeColumns-fD6dosYP.js.map → TimeColumns-B7af5Cbj.js.map} +1 -1
  203. package/dist/{TimeColumns-t3Pn01v5.cjs → TimeColumns-CJ13uf3K.cjs} +2 -2
  204. package/dist/{TimeColumns-t3Pn01v5.cjs.map → TimeColumns-CJ13uf3K.cjs.map} +1 -1
  205. package/dist/{TimePicker-DypTHDW0.js → TimePicker-BitZ7wv-.js} +5 -5
  206. package/dist/{TimePicker-DypTHDW0.js.map → TimePicker-BitZ7wv-.js.map} +1 -1
  207. package/dist/{TimePicker-DOwQF7sX.cjs → TimePicker-Dshko7IJ.cjs} +2 -2
  208. package/dist/{TimePicker-DOwQF7sX.cjs.map → TimePicker-Dshko7IJ.cjs.map} +1 -1
  209. package/dist/{Toaster-DdUOwi7L.cjs → Toaster-8ynQTcc0.cjs} +2 -2
  210. package/dist/{Toaster-DdUOwi7L.cjs.map → Toaster-8ynQTcc0.cjs.map} +1 -1
  211. package/dist/{Toaster-BwNAKDMc.js → Toaster-CYVETXVZ.js} +2 -2
  212. package/dist/{Toaster-BwNAKDMc.js.map → Toaster-CYVETXVZ.js.map} +1 -1
  213. package/dist/{TranslatedFields-D9FQlxiQ.cjs → TranslatedFields-BKI3jrNd.cjs} +2 -2
  214. package/dist/{TranslatedFields-D9FQlxiQ.cjs.map → TranslatedFields-BKI3jrNd.cjs.map} +1 -1
  215. package/dist/{TranslatedFields-C_-qPixE.js → TranslatedFields-dmb-0Yn7.js} +5 -5
  216. package/dist/{TranslatedFields-C_-qPixE.js.map → TranslatedFields-dmb-0Yn7.js.map} +1 -1
  217. package/dist/{UserCard-C-q2s2Cw.cjs → UserCard-ah6K1y0H.cjs} +2 -2
  218. package/dist/{UserCard-C-q2s2Cw.cjs.map → UserCard-ah6K1y0H.cjs.map} +1 -1
  219. package/dist/{UserCard-CwWv0HXD.js → UserCard-pEJZqiDF.js} +3 -3
  220. package/dist/{UserCard-CwWv0HXD.js.map → UserCard-pEJZqiDF.js.map} +1 -1
  221. package/dist/app/AdminRoot.d.cts +75 -4
  222. package/dist/app/AdminRoot.d.ts +75 -4
  223. package/dist/components/Alert/index.cjs +1 -1
  224. package/dist/components/Alert/index.js +1 -1
  225. package/dist/components/Breadcrumbs/index.cjs +1 -1
  226. package/dist/components/Breadcrumbs/index.js +1 -1
  227. package/dist/components/Button/index.cjs +1 -1
  228. package/dist/components/Button/index.js +1 -1
  229. package/dist/components/Card/index.cjs +1 -1
  230. package/dist/components/Card/index.js +1 -1
  231. package/dist/components/Chip/index.cjs +1 -1
  232. package/dist/components/Chip/index.js +1 -1
  233. package/dist/components/CodeBlock/index.cjs +1 -1
  234. package/dist/components/CodeBlock/index.js +1 -1
  235. package/dist/components/ColorPicker/index.cjs +1 -1
  236. package/dist/components/ColorPicker/index.js +1 -1
  237. package/dist/components/ColorRamp/index.cjs +1 -1
  238. package/dist/components/ColorRamp/index.js +1 -1
  239. package/dist/components/CopyButton/index.cjs +1 -1
  240. package/dist/components/CopyButton/index.js +1 -1
  241. package/dist/components/DatePicker/index.cjs +1 -1
  242. package/dist/components/DatePicker/index.js +1 -1
  243. package/dist/components/DateTimePicker/index.cjs +1 -1
  244. package/dist/components/DateTimePicker/index.js +1 -1
  245. package/dist/components/DescriptionList/index.cjs +1 -1
  246. package/dist/components/DescriptionList/index.js +1 -1
  247. package/dist/components/EmptyState/index.cjs +1 -1
  248. package/dist/components/EmptyState/index.js +1 -1
  249. package/dist/components/ErrorState/ErrorBoundary.d.cts +3 -3
  250. package/dist/components/ErrorState/ErrorBoundary.d.ts +3 -3
  251. package/dist/components/ErrorState/ErrorState.d.cts +37 -9
  252. package/dist/components/ErrorState/ErrorState.d.ts +37 -9
  253. package/dist/components/ErrorState/errorMessage.d.cts +35 -3
  254. package/dist/components/ErrorState/errorMessage.d.ts +35 -3
  255. package/dist/components/ErrorState/index.cjs +1 -1
  256. package/dist/components/ErrorState/index.d.cts +2 -2
  257. package/dist/components/ErrorState/index.d.ts +2 -2
  258. package/dist/components/ErrorState/index.js +15 -10
  259. package/dist/components/ErrorState/index.js.map +1 -1
  260. package/dist/components/FileCard/index.cjs +1 -1
  261. package/dist/components/FileCard/index.js +1 -1
  262. package/dist/components/FileUploader/index.cjs +1 -1
  263. package/dist/components/FileUploader/index.js +1 -1
  264. package/dist/components/Flag/index.cjs +1 -1
  265. package/dist/components/Flag/index.js +1 -1
  266. package/dist/components/FullscreenToggle/index.cjs +1 -1
  267. package/dist/components/FullscreenToggle/index.js +1 -1
  268. package/dist/components/IconButton/index.cjs +1 -1
  269. package/dist/components/IconButton/index.js +1 -1
  270. package/dist/components/Loader/index.cjs +1 -1
  271. package/dist/components/Loader/index.js +1 -1
  272. package/dist/components/LocationPicker/index.cjs +1 -1
  273. package/dist/components/LocationPicker/index.js +1 -1
  274. package/dist/components/Modal/index.cjs +1 -1
  275. package/dist/components/Modal/index.js +1 -1
  276. package/dist/components/MultiSelect/MultiSelect.d.cts +1 -1
  277. package/dist/components/MultiSelect/MultiSelect.d.ts +1 -1
  278. package/dist/components/MultiSelect/index.cjs +1 -1
  279. package/dist/components/MultiSelect/index.js +1 -1
  280. package/dist/components/NumberField/index.cjs +1 -1
  281. package/dist/components/NumberField/index.js +1 -1
  282. package/dist/components/OptionMenu/OptionMenu.d.cts +1 -1
  283. package/dist/components/OptionMenu/OptionMenu.d.ts +1 -1
  284. package/dist/components/OtpField/index.cjs +1 -1
  285. package/dist/components/OtpField/index.js +1 -1
  286. package/dist/components/PageError/PageError.d.cts +53 -0
  287. package/dist/components/PageError/PageError.d.ts +53 -0
  288. package/dist/components/PageError/index.cjs +2 -0
  289. package/dist/components/PageError/index.cjs.map +1 -0
  290. package/dist/components/PageError/index.d.cts +2 -0
  291. package/dist/components/PageError/index.d.ts +2 -0
  292. package/dist/components/PageError/index.js +6 -0
  293. package/dist/components/PageError/index.js.map +1 -0
  294. package/dist/components/PageLayout/index.cjs +1 -1
  295. package/dist/components/PageLayout/index.js +1 -1
  296. package/dist/components/PageNotFound/index.cjs +1 -1
  297. package/dist/components/PageNotFound/index.js +1 -1
  298. package/dist/components/PageNotFound/useHomeTo.d.cts +10 -0
  299. package/dist/components/PageNotFound/useHomeTo.d.ts +10 -0
  300. package/dist/components/Pagination/index.cjs +1 -1
  301. package/dist/components/Pagination/index.js +1 -1
  302. package/dist/components/PaletteField/index.cjs +1 -1
  303. package/dist/components/PaletteField/index.js +1 -1
  304. package/dist/components/PhoneField/index.cjs +1 -1
  305. package/dist/components/PhoneField/index.js +1 -1
  306. package/dist/components/Popconfirm/index.cjs +1 -1
  307. package/dist/components/Popconfirm/index.js +1 -1
  308. package/dist/components/Progress/index.cjs +1 -1
  309. package/dist/components/Progress/index.js +1 -1
  310. package/dist/components/RemoveDialog/index.cjs +1 -1
  311. package/dist/components/RemoveDialog/index.js +1 -1
  312. package/dist/components/RichTextEditor/index.cjs +1 -1
  313. package/dist/components/RichTextEditor/index.js +1 -1
  314. package/dist/components/RootLayout/index.cjs +1 -1
  315. package/dist/components/RootLayout/index.js +1 -1
  316. package/dist/components/Select/Select.d.cts +1 -1
  317. package/dist/components/Select/Select.d.ts +1 -1
  318. package/dist/components/Select/index.cjs +1 -1
  319. package/dist/components/Select/index.js +1 -1
  320. package/dist/components/Sidebar/index.cjs +1 -1
  321. package/dist/components/Sidebar/index.js +1 -1
  322. package/dist/components/SpeedDial/index.cjs +1 -1
  323. package/dist/components/SpeedDial/index.js +1 -1
  324. package/dist/components/Stepper/index.cjs +1 -1
  325. package/dist/components/Stepper/index.js +1 -1
  326. package/dist/components/Table/Table.d.cts +1 -1
  327. package/dist/components/Table/Table.d.ts +1 -1
  328. package/dist/components/Table/index.cjs +1 -1
  329. package/dist/components/Table/index.js +1 -1
  330. package/dist/components/Tabs/index.cjs +1 -1
  331. package/dist/components/Tabs/index.js +1 -1
  332. package/dist/components/TagsField/TagsField.d.cts +1 -1
  333. package/dist/components/TagsField/TagsField.d.ts +1 -1
  334. package/dist/components/TagsField/index.cjs +1 -1
  335. package/dist/components/TagsField/index.js +1 -1
  336. package/dist/components/TextField/TextField.d.cts +1 -1
  337. package/dist/components/TextField/TextField.d.ts +1 -1
  338. package/dist/components/TextField/index.cjs +1 -1
  339. package/dist/components/TextField/index.js +1 -1
  340. package/dist/components/ThemeToggle/index.cjs +1 -1
  341. package/dist/components/ThemeToggle/index.js +1 -1
  342. package/dist/components/TimePicker/index.cjs +1 -1
  343. package/dist/components/TimePicker/index.js +1 -1
  344. package/dist/components/Toast/index.cjs +1 -1
  345. package/dist/components/Toast/index.js +1 -1
  346. package/dist/components/TranslatedFields/index.cjs +1 -1
  347. package/dist/components/TranslatedFields/index.js +1 -1
  348. package/dist/components/UserCard/UserCard.d.cts +1 -1
  349. package/dist/components/UserCard/UserCard.d.ts +1 -1
  350. package/dist/components/UserCard/index.cjs +1 -1
  351. package/dist/components/UserCard/index.js +1 -1
  352. package/dist/components/index.d.cts +1 -0
  353. package/dist/components/index.d.ts +1 -0
  354. package/dist/entries/app.cjs +1 -1
  355. package/dist/entries/app.d.cts +1 -1
  356. package/dist/entries/app.d.ts +1 -1
  357. package/dist/entries/app.js +1 -1
  358. package/dist/entries/components.cjs +1 -1
  359. package/dist/entries/components.js +166 -159
  360. package/dist/entries/components.js.map +1 -1
  361. package/dist/entries/i18n.cjs +1 -1
  362. package/dist/entries/i18n.js +2 -2
  363. package/dist/entries/theme.cjs +1 -1
  364. package/dist/entries/theme.js +1 -1
  365. package/dist/errorMessage-C7N4KvUS.cjs +2 -0
  366. package/dist/errorMessage-C7N4KvUS.cjs.map +1 -0
  367. package/dist/errorMessage-C83fB2h5.js +98 -0
  368. package/dist/errorMessage-C83fB2h5.js.map +1 -0
  369. package/dist/i18n/messages.d.cts +15 -1
  370. package/dist/i18n/messages.d.ts +15 -1
  371. package/dist/index.cjs +1 -1
  372. package/dist/index.css +1 -1
  373. package/dist/index.js +212 -205
  374. package/dist/index.js.map +1 -1
  375. package/dist/{messages-BOJsnD0O.js → messages-C1eTrGJy.js} +128 -79
  376. package/dist/messages-C1eTrGJy.js.map +1 -0
  377. package/dist/messages-DCr7iFmv.cjs +36 -0
  378. package/dist/messages-DCr7iFmv.cjs.map +1 -0
  379. package/dist/theme/ConfigProvider.d.cts +17 -3
  380. package/dist/theme/ConfigProvider.d.ts +17 -3
  381. package/dist/useHomeTo-Cr6Usr_D.cjs +2 -0
  382. package/dist/useHomeTo-Cr6Usr_D.cjs.map +1 -0
  383. package/dist/useHomeTo-yTXajO22.js +25 -0
  384. package/dist/useHomeTo-yTXajO22.js.map +1 -0
  385. package/dist/{useOptionMenu-8hjCTNL4.cjs → useOptionMenu-DHGSbQmS.cjs} +2 -2
  386. package/dist/{useOptionMenu-8hjCTNL4.cjs.map → useOptionMenu-DHGSbQmS.cjs.map} +1 -1
  387. package/dist/{useOptionMenu-C1wOZ9NT.js → useOptionMenu-DK0ixg-p.js} +3 -3
  388. package/dist/{useOptionMenu-C1wOZ9NT.js.map → useOptionMenu-DK0ixg-p.js.map} +1 -1
  389. package/package.json +1 -1
  390. package/dist/AdminRoot-B9A4Hoz0.js +0 -57
  391. package/dist/AdminRoot-B9A4Hoz0.js.map +0 -1
  392. package/dist/AdminRoot-BVUEWczU.cjs +0 -2
  393. package/dist/AdminRoot-BVUEWczU.cjs.map +0 -1
  394. package/dist/ConfigProvider-CzAQf_d_.cjs.map +0 -1
  395. package/dist/ConfigProvider-D2svpXFu.js.map +0 -1
  396. package/dist/ErrorBoundary-CJx5E9wJ.js +0 -163
  397. package/dist/ErrorBoundary-CJx5E9wJ.js.map +0 -1
  398. package/dist/ErrorBoundary-DbKRtdgS.cjs +0 -2
  399. package/dist/ErrorBoundary-DbKRtdgS.cjs.map +0 -1
  400. package/dist/PageNotFound-CMt8vnky.js +0 -39
  401. package/dist/PageNotFound-CMt8vnky.js.map +0 -1
  402. package/dist/PageNotFound-DDm6nwQh.cjs +0 -2
  403. package/dist/PageNotFound-DDm6nwQh.cjs.map +0 -1
  404. package/dist/QueryError-Dl8yzdxw.js +0 -19
  405. package/dist/QueryError-Dl8yzdxw.js.map +0 -1
  406. package/dist/QueryError-RF7Mh5zg.cjs +0 -2
  407. package/dist/QueryError-RF7Mh5zg.cjs.map +0 -1
  408. package/dist/RootLayout-BvyeNM9_.cjs +0 -2
  409. package/dist/RootLayout-BvyeNM9_.cjs.map +0 -1
  410. package/dist/RootLayout-D-ZlsTXF.js.map +0 -1
  411. package/dist/Table-1RVWzyS6.cjs +0 -2
  412. package/dist/Table-1RVWzyS6.cjs.map +0 -1
  413. package/dist/Table-BV-dr36o.js.map +0 -1
  414. package/dist/messages-BOJsnD0O.js.map +0 -1
  415. package/dist/messages-ejfYfHwL.cjs +0 -36
  416. package/dist/messages-ejfYfHwL.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PhoneField-Dzdm5hfY.cjs","sources":["../src/components/PhoneField/phone.ts","../src/components/PhoneField/PhoneField.tsx"],"sourcesContent":["import type * as PhoneLibModule from 'libphonenumber-js'\nimport type { CountryCode } from 'libphonenumber-js'\nimport { optionalPeer } from '../../hooks/useOptionalPeer'\n\n/**\n * `libphonenumber-js` is an optional peer, loaded **lazily** (see `optionalPeer`) — never imported\n * statically, so apps that don't install it still build + run when they import the barrel. PhoneField\n * waits for it on mount; the helpers below run only once it's loaded (`lib()`).\n */\nexport const phonePeer = optionalPeer<typeof PhoneLibModule>(\n 'libphonenumber-js',\n 'PhoneField',\n () => import('libphonenumber-js'),\n)\nconst lib = () => phonePeer.get()!\n\n/** An ISO-3166 alpha-2 country code, as `libphonenumber-js` knows it (`'GE'`, `'US'`, …). */\nexport type PhoneCountry = CountryCode\n/** How the number is shown in the input while typing (the value is always E.164). */\nexport type PhoneFormat = 'national' | 'international'\n\nlet allCountries: readonly PhoneCountry[] | undefined\n/** Every country `libphonenumber-js` has metadata for (once loaded). */\nexport function getPhoneCountries(): readonly PhoneCountry[] {\n return (allCountries ??= lib().getCountries())\n}\n\n/** The country's calling code without the `+` — `'GE'` → `'995'`. */\nexport const callingCodeOf = (country: PhoneCountry): string => lib().getCountryCallingCode(country)\n\n/**\n * `true` for a complete, valid number (E.164 or any parseable international form). Use it in a schema:\n * `phone: z.string().refine(isValidPhone, 'Enter a valid phone number')`. Needs `libphonenumber-js`\n * loaded — it is once any PhoneField has mounted; before that it starts the load and returns `false`.\n */\nexport function isValidPhone(value: unknown): boolean {\n const loaded = phonePeer.get()\n // not loaded yet (no PhoneField mounted so far) → start loading and report \"not valid\" for now\n if (!loaded) {\n void phonePeer.load()\n return false\n }\n return typeof value === 'string' && value.trim() !== '' && loaded.isValidPhoneNumber(value)\n}\n\n/** A flag emoji from the two regional-indicator letters — no image assets (Windows shows the letters). */\nexport function flagEmoji(country: string): string {\n return String.fromCodePoint(\n ...[...country.toUpperCase()].map((c) => 0x1f1e6 + c.charCodeAt(0) - 65),\n )\n}\n\nconst displayNamesCache = new Map<string, Intl.DisplayNames | null>()\n/** The country's name in `locale` via `Intl.DisplayNames` (no catalog to ship); falls back to the code. */\nexport function countryName(country: string, locale: string): string {\n if (!displayNamesCache.has(locale)) {\n try {\n displayNamesCache.set(locale, new Intl.DisplayNames([locale], { type: 'region' }))\n } catch {\n displayNamesCache.set(locale, null)\n }\n }\n try {\n return displayNamesCache.get(locale)?.of(country) ?? country\n } catch {\n return country\n }\n}\n\n// the main country for a calling code shared by several (a partial \"+44…\" parses as Guernsey otherwise)\nconst MAIN_FOR_CODE: Record<string, PhoneCountry> = {\n '1': 'US',\n '7': 'RU',\n '39': 'IT',\n '44': 'GB',\n '47': 'NO',\n '61': 'AU',\n '212': 'MA',\n '262': 'RE',\n '290': 'SH',\n '358': 'FI',\n '590': 'GP',\n '599': 'CW',\n}\n// base UI language → its usual country, for the default when the locale carries no region\nconst LANGUAGE_COUNTRY: Record<string, PhoneCountry> = {\n ka: 'GE',\n en: 'US',\n es: 'ES',\n de: 'DE',\n it: 'IT',\n fr: 'FR',\n ru: 'RU',\n}\n\n/** The default country: the locale's region → its language's usual country → the browser's region → US. */\nexport function detectCountry(locale: string, allowed: readonly PhoneCountry[]): PhoneCountry {\n const [base, region] = locale.split('-')\n const browser =\n typeof navigator !== 'undefined' ? navigator.language?.split('-')[1]?.toUpperCase() : undefined\n const candidates = [region?.toUpperCase(), LANGUAGE_COUNTRY[base?.toLowerCase()], browser, 'US']\n return (candidates.find((c) => c && allowed.includes(c as PhoneCountry)) ??\n allowed[0]) as PhoneCountry\n}\n\n/** The result of reading what's in the input. */\nexport interface PhoneReading {\n /** The canonical value — `'+995555123456'`, or `''` when empty. */\n e164: string\n /** The country the number belongs to (may switch when a `+code` is typed). */\n country: PhoneCountry\n /** The national significant number — digits only, no trunk `0`. */\n national: string\n /** A complete, valid number. */\n valid: boolean\n /** What the input should show (formatted as you type). */\n display: string\n}\n\nconst digitsOf = (s: string) => s.replace(/\\D/g, '')\n\n/** Which allowed country a `+code…` number belongs to — keep the current one when it shares the code. */\nfunction countryForCode(\n code: string,\n current: PhoneCountry,\n detected: PhoneCountry | undefined,\n allowed: readonly PhoneCountry[],\n): PhoneCountry {\n if (callingCodeOf(current) === code) return current\n const pick = [detected, MAIN_FOR_CODE[code], ...allowed.filter((c) => callingCodeOf(c) === code)]\n return (pick.find((c) => c && allowed.includes(c)) as PhoneCountry | undefined) ?? current\n}\n\n/** Read raw input text → the canonical value + the formatted display, as the user types. */\nexport function readPhoneInput(\n raw: string,\n country: PhoneCountry,\n format: PhoneFormat,\n allowed: readonly PhoneCountry[],\n): PhoneReading {\n const text = raw.trimStart()\n const digits = digitsOf(text)\n if (!digits) {\n return {\n e164: '',\n country,\n national: '',\n valid: false,\n display: text.startsWith('+') ? '+' : '',\n }\n }\n\n // an explicit \"+code…\" (typed or pasted) — the calling code decides the country\n if (text.startsWith('+')) {\n const typer = new (lib().AsYouType)()\n const display = typer.input(`+${digits}`)\n const code = typer.getCallingCode()\n const parsed = lib().parsePhoneNumberFromString(`+${digits}`)\n const next = code\n ? countryForCode(code, country, parsed?.country ?? typer.getCountry(), allowed)\n : country\n const e164 = `+${digits}`\n return {\n e164,\n country: next,\n national: code ? digits.slice(code.length) : '',\n valid: lib().isValidPhoneNumber(e164),\n display,\n }\n }\n\n // national digits under the selected country (a leading trunk \"0\" is dropped from the value)\n const code = callingCodeOf(country)\n const parsed = lib().parsePhoneNumberFromString(digits, country)\n const national = parsed?.nationalNumber ?? digits.replace(/^0+/, '')\n const e164 = national ? `+${code}${national}` : ''\n const display =\n format === 'international'\n ? new (lib().AsYouType)(country).input(`+${code}${national}`)\n : new (lib().AsYouType)(country).input(digits)\n return {\n e164,\n country,\n national,\n valid: e164 !== '' && lib().isValidPhoneNumber(e164),\n display,\n }\n}\n\n/** Derive the country + display from an E.164 value (initial / external value changes). */\nexport function phoneFromValue(\n value: string,\n fallback: PhoneCountry,\n format: PhoneFormat,\n allowed: readonly PhoneCountry[],\n): { country: PhoneCountry; display: string } {\n if (!value) return { country: fallback, display: '' }\n const parsed = lib().parsePhoneNumberFromString(value)\n if (parsed) {\n const country = countryForCode(parsed.countryCallingCode, fallback, parsed.country, allowed)\n return {\n country,\n display: format === 'national' ? parsed.formatNational() : parsed.formatInternational(),\n }\n }\n const reading = readPhoneInput(value, fallback, 'international', allowed)\n const display =\n format === 'national' && reading.national\n ? new (lib().AsYouType)(reading.country).input(reading.national)\n : reading.display\n return { country: reading.country, display }\n}\n\n/** Caret index in `display` right after its `n`-th digit — keeps the caret put while reformatting. */\nexport function caretAfterDigits(display: string, n: number): number {\n if (n <= 0) return display.startsWith('+') ? 1 : 0\n let seen = 0\n for (let i = 0; i < display.length; i++) {\n if (/\\d/.test(display[i])) seen++\n if (seen === n) return i + 1\n }\n return display.length\n}\n","import {\n forwardRef,\n useCallback,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type CSSProperties,\n type FocusEvent,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useLanguage, useT } from '../../theme'\nimport { useOptionalPeer } from '../../hooks/useOptionalPeer'\nimport { useFormContext } from '../../form/formContext'\nimport { Icon } from '../Icon'\nimport { TextField } from '../TextField'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu, type SelectOption } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport fieldStyles from '../TextField/TextField.module.css'\nimport {\n callingCodeOf,\n getPhoneCountries,\n caretAfterDigits,\n countryName,\n detectCountry,\n flagEmoji,\n phoneFromValue,\n phonePeer,\n readPhoneInput,\n type PhoneCountry,\n type PhoneFormat,\n} from './phone'\nimport styles from './PhoneField.module.css'\n\nexport type PhoneFieldSize = 'sm' | 'md' | 'lg'\n\n/** Extra details handed to `onChange` alongside the E.164 value. */\nexport interface PhoneFieldChangeMeta {\n /** The number's country (ISO alpha-2). */\n country: PhoneCountry\n /** The national significant number — digits only, no trunk `0`. */\n national: string\n /** A complete, valid number for that country. */\n valid: boolean\n}\n\nexport interface PhoneFieldProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'value' | 'defaultValue' | 'onChange' | 'type' | 'size' | 'color'\n> {\n /** The number in **E.164** (`'+995555123456'`) — the only form the field emits. `''` when empty. */\n value?: string\n /** Initial E.164 value for uncontrolled use. */\n defaultValue?: string\n /** Fires with the E.164 value (`''` when cleared) and `{ country, national, valid }`. */\n onChange?: (value: string, meta: PhoneFieldChangeMeta) => void\n /** The country to start with. Defaults to one derived from the UI language / browser locale. */\n defaultCountry?: PhoneCountry\n /** Restrict the selectable countries (e.g. only where you operate). Defaults to all. */\n countries?: readonly PhoneCountry[]\n /** Countries pinned to the top of the list, in this order. */\n preferredCountries?: readonly PhoneCountry[]\n /**\n * How the number reads while typing — `national` (default: `555 12 34 56`, the calling code lives in\n * the country button) or `international` (`+995 555 12 34 56`). The value is E.164 either way.\n */\n format?: PhoneFormat\n /** Field label. */\n label?: ReactNode\n /** Helper / validation text under the field. */\n helperText?: ReactNode\n /** Error state (red border + helper). */\n error?: boolean\n /** Shows a required asterisk. */\n required?: boolean\n /** `sm` / `md` / `lg` — control height + type. Defaults to `md`. */\n size?: PhoneFieldSize\n /** Stretch to the container. Defaults to `true`. */\n fullWidth?: boolean\n}\n\n/** The field itself — rendered once `libphonenumber-js` has loaded. */\nconst PhoneFieldInner = forwardRef<HTMLInputElement, PhoneFieldProps>(function PhoneFieldInner(\n {\n value,\n defaultValue,\n onChange,\n defaultCountry,\n countries: countriesProp,\n preferredCountries = [],\n format = 'national',\n label,\n helperText,\n error,\n required,\n size = 'md',\n fullWidth = true,\n name,\n disabled = false,\n id: idProp,\n className,\n style,\n onBlur,\n placeholder,\n ...props\n },\n ref,\n) {\n const t = useT()\n const { language } = useLanguage()\n const countries = countriesProp ?? getPhoneCountries()\n const reactId = useId()\n const id = idProp ?? reactId\n const helperId = `${id}-helper`\n\n // ── value: controlled / form-bound / uncontrolled — always E.164 ──\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const [internal, setInternal] = useState(defaultValue ?? '')\n const currentValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string | undefined) ?? '')\n : internal\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const fallbackCountry = useMemo<PhoneCountry>(\n () =>\n defaultCountry && countries.includes(defaultCountry)\n ? defaultCountry\n : detectCountry(language, countries),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [defaultCountry, language, countries.join()],\n )\n\n const [country, setCountry] = useState<PhoneCountry>(\n () => phoneFromValue(currentValue, fallbackCountry, format, countries).country,\n )\n const [display, setDisplay] = useState(\n () => phoneFromValue(currentValue, fallbackCountry, format, countries).display,\n )\n\n // re-derive the display when the value changes from OUTSIDE (a reset / a controlled update) — the\n // values we emit ourselves are skipped, so formatting never fights the user mid-typing\n const lastEmitted = useRef(currentValue)\n if (lastEmitted.current !== currentValue) {\n lastEmitted.current = currentValue\n const next = phoneFromValue(currentValue, country, format, countries)\n setCountry(next.country)\n setDisplay(next.display)\n }\n\n // caret restore after reformatting\n const innerRef = useRef<HTMLInputElement | null>(null)\n const setInputRef = useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLInputElement | null }).current = node\n },\n [ref],\n )\n const pendingCaret = useRef<number | null>(null)\n useLayoutEffect(() => {\n const pos = pendingCaret.current\n if (pos == null) return\n pendingCaret.current = null\n innerRef.current?.setSelectionRange(pos, pos)\n })\n\n const emit = (reading: ReturnType<typeof readPhoneInput>) => {\n lastEmitted.current = reading.e164\n setDisplay(reading.display)\n if (reading.country !== country) setCountry(reading.country)\n if (value === undefined && !isFormBound) setInternal(reading.e164)\n if (isFormBound) form!.setValue(name!, reading.e164)\n onChange?.(reading.e164, {\n country: reading.country,\n national: reading.national,\n valid: reading.valid,\n })\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const el = event.target\n let raw = el.value\n const caret = el.selectionStart ?? raw.length\n let digitsBefore = raw.slice(0, caret).replace(/\\D/g, '').length\n // backspace over a formatting char (space / paren / dash) would be re-added by the formatter —\n // treat it as deleting the digit before it instead\n const prevDigits = display.replace(/\\D/g, '')\n if (raw.length < display.length && raw.replace(/\\D/g, '') === prevDigits && digitsBefore > 0) {\n let seen = 0\n let cut = -1\n for (let i = 0; i < raw.length; i++) {\n if (/\\d/.test(raw[i]) && ++seen === digitsBefore) {\n cut = i\n break\n }\n }\n if (cut >= 0) raw = raw.slice(0, cut) + raw.slice(cut + 1)\n digitsBefore -= 1\n }\n const reading = readPhoneInput(raw, country, format, countries)\n pendingCaret.current =\n caret >= el.value.length\n ? reading.display.length\n : caretAfterDigits(reading.display, digitsBefore)\n emit(reading)\n }\n\n // ── country picker — the shared option menu (search matches name, ISO code, calling code) ──\n const controlRef = useRef<HTMLDivElement | null>(null)\n const countryOptions = useMemo<SelectOption[]>(() => {\n const toOption = (c: PhoneCountry): SelectOption => {\n const dial = callingCodeOf(c)\n return {\n value: c,\n label: countryName(c, language),\n icon: (\n <span className={styles.flag} aria-hidden=\"true\">\n {flagEmoji(c)}\n </span>\n ),\n keywords: [c, dial, `+${dial}`],\n trailing: <span className={styles.dial}>+{dial}</span>,\n }\n }\n // preferred countries first (in the given order), then the rest A→Z by their localized name —\n // as two groups (\"Suggested\" / \"All Countries\") when there are preferred ones\n const pinned = preferredCountries.filter((c) => countries.includes(c)).map(toOption)\n const rest = countries\n .filter((c) => !preferredCountries.includes(c))\n .map(toOption)\n .sort((a, b) => a.label.localeCompare(b.label, language))\n if (pinned.length === 0) return rest\n return [\n ...pinned.map((o) => ({ ...o, group: t('phoneField.suggested') })),\n ...rest.map((o) => ({ ...o, group: t('phoneField.allCountries') })),\n ]\n }, [countries, preferredCountries, language, t])\n\n const pickCountry = (next: PhoneCountry) => {\n // keep the typed national digits, re-read under the new calling code\n const national = readPhoneInput(display, country, format, countries).national\n setCountry(next)\n emit({ ...readPhoneInput(national, next, format, countries), country: next })\n }\n\n const menu = useOptionMenu({\n idBase: `${id}-country`,\n options: countryOptions,\n isSelected: (o) => o.value === country,\n onPick: (o) => pickCountry(o.value as PhoneCountry),\n searchable: true,\n disabled,\n // after a pick / Esc, typing continues in the number\n focusRef: innerRef,\n })\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n bound?.onBlur(event)\n onBlur?.(event)\n }\n\n const describedBy = resolvedHelperText != null ? helperId : undefined\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const code = callingCodeOf(country)\n const name_ = countryName(country, language)\n\n return (\n <div\n className={clsx(\n fieldStyles.field,\n fieldStyles[size],\n fullWidth && fieldStyles.fullWidth,\n resolvedError && fieldStyles.error,\n disabled && fieldStyles.disabled,\n styles.phoneField,\n className,\n )}\n style={style as CSSProperties}\n >\n {label != null && (\n <label htmlFor={id} className={fieldStyles.label}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={fieldStyles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div ref={controlRef} className={clsx(fieldStyles.control, styles.control)}>\n <button\n type=\"button\"\n className={styles.country}\n aria-haspopup=\"listbox\"\n aria-expanded={menu.open}\n aria-controls={menu.open ? menu.listboxId : undefined}\n aria-label={`${t('phoneField.country')}: ${name_} (+${code})`}\n disabled={disabled}\n onClick={menu.toggleMenu}\n onKeyDown={(e) => {\n // ↓ / ↑ open the list (Enter / Space already click the button)\n if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !menu.open) {\n e.preventDefault()\n menu.openMenu()\n }\n }}\n >\n <span className={styles.flag} aria-hidden=\"true\">\n {flagEmoji(country)}\n </span>\n {format === 'national' && <span className={styles.code}>+{code}</span>}\n {/* the same chevron as Select / MultiSelect (ArrowDown4, sized per field size: sm 16 · md 14 · lg 12) */}\n <Icon\n name=\"ArrowDown4\"\n className={clsx(styles.chevron, menu.open && styles.chevronOpen)}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </button>\n <input\n ref={setInputRef}\n id={id}\n name={name}\n type=\"tel\"\n inputMode=\"tel\"\n autoComplete=\"tel\"\n className={fieldStyles.input}\n value={display}\n placeholder={placeholder}\n onChange={handleChange}\n onBlur={handleBlur}\n disabled={disabled}\n aria-invalid={resolvedError || undefined}\n aria-describedby={describedBy}\n {...props}\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={controlRef}\n size={size}\n searchPlaceholder={t('phoneField.search')}\n ariaLabel={t('phoneField.country')}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={fieldStyles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n\n/**\n * A phone-number field: a **country button** (flag + `+code`, opening a searchable, localized country\n * list) inside the input frame, and the number **formatted as you type** for that country. The value is\n * always **E.164** (`'+995555123456'`) — one canonical form for the backend. Typing or pasting `+44…`\n * switches the country by its calling code. `onChange(value, { country, national, valid })`; binds to a\n * `<Form>` by `name` (the form value is the E.164 string — validate with `isValidPhone`). Country names\n * come from `Intl.DisplayNames` in the active UI language; flags are emoji. Needs the optional peer\n * **`libphonenumber-js`** (formatting, parsing, validation metadata), loaded lazily on first mount — until\n * it's ready (or if it isn't installed) a disabled look-alike field renders. Reuses the `TextField` look.\n */\nexport const PhoneField = forwardRef<HTMLInputElement, PhoneFieldProps>(\n function PhoneField(props, ref) {\n const { module } = useOptionalPeer(phonePeer)\n if (module) return <PhoneFieldInner ref={ref} {...props} />\n // loading (a tick, first mount only) or the peer is missing: the same frame, disabled — never bound\n // to a <Form> (no `name`) so it can't write a value\n const {\n label,\n helperText,\n error,\n required,\n size,\n fullWidth = true,\n className,\n style,\n placeholder,\n } = props\n return (\n <TextField\n ref={ref}\n type=\"tel\"\n label={label}\n helperText={helperText}\n error={error}\n required={required}\n size={size}\n fullWidth={fullWidth}\n className={className}\n style={style}\n placeholder={placeholder}\n value={props.value ?? props.defaultValue ?? ''}\n readOnly\n disabled\n />\n )\n },\n)\n"],"names":["phonePeer","optionalPeer","lib","allCountries","getPhoneCountries","callingCodeOf","country","isValidPhone","value","loaded","flagEmoji","c","displayNamesCache","countryName","locale","_a","MAIN_FOR_CODE","LANGUAGE_COUNTRY","detectCountry","allowed","base","region","browser","_b","digitsOf","s","countryForCode","code","current","detected","readPhoneInput","raw","format","text","digits","typer","display","parsed","next","e164","national","phoneFromValue","fallback","reading","caretAfterDigits","n","seen","i","PhoneFieldInner","forwardRef","defaultValue","onChange","defaultCountry","countriesProp","preferredCountries","label","helperText","error","required","size","fullWidth","name","disabled","idProp","className","style","onBlur","placeholder","props","ref","t","useT","language","useLanguage","countries","reactId","useId","id","helperId","form","useFormContext","isFormBound","bound","internal","setInternal","useState","currentValue","resolvedError","resolvedHelperText","fallbackCountry","useMemo","setCountry","setDisplay","lastEmitted","useRef","innerRef","setInputRef","useCallback","node","pendingCaret","useLayoutEffect","pos","emit","handleChange","event","el","caret","digitsBefore","prevDigits","cut","controlRef","countryOptions","toOption","dial","jsx","styles","jsxs","pinned","rest","a","b","o","pickCountry","menu","useOptionMenu","handleBlur","describedBy","chevronPx","name_","clsx","fieldStyles","Typography","e","Icon","OptionMenu","PhoneField","module","useOptionalPeer","TextField"],"mappings":"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"}
1
+ {"version":3,"file":"PhoneField-O5syyH7u.cjs","sources":["../src/components/PhoneField/phone.ts","../src/components/PhoneField/PhoneField.tsx"],"sourcesContent":["import type * as PhoneLibModule from 'libphonenumber-js'\nimport type { CountryCode } from 'libphonenumber-js'\nimport { optionalPeer } from '../../hooks/useOptionalPeer'\n\n/**\n * `libphonenumber-js` is an optional peer, loaded **lazily** (see `optionalPeer`) — never imported\n * statically, so apps that don't install it still build + run when they import the barrel. PhoneField\n * waits for it on mount; the helpers below run only once it's loaded (`lib()`).\n */\nexport const phonePeer = optionalPeer<typeof PhoneLibModule>(\n 'libphonenumber-js',\n 'PhoneField',\n () => import('libphonenumber-js'),\n)\nconst lib = () => phonePeer.get()!\n\n/** An ISO-3166 alpha-2 country code, as `libphonenumber-js` knows it (`'GE'`, `'US'`, …). */\nexport type PhoneCountry = CountryCode\n/** How the number is shown in the input while typing (the value is always E.164). */\nexport type PhoneFormat = 'national' | 'international'\n\nlet allCountries: readonly PhoneCountry[] | undefined\n/** Every country `libphonenumber-js` has metadata for (once loaded). */\nexport function getPhoneCountries(): readonly PhoneCountry[] {\n return (allCountries ??= lib().getCountries())\n}\n\n/** The country's calling code without the `+` — `'GE'` → `'995'`. */\nexport const callingCodeOf = (country: PhoneCountry): string => lib().getCountryCallingCode(country)\n\n/**\n * `true` for a complete, valid number (E.164 or any parseable international form). Use it in a schema:\n * `phone: z.string().refine(isValidPhone, 'Enter a valid phone number')`. Needs `libphonenumber-js`\n * loaded — it is once any PhoneField has mounted; before that it starts the load and returns `false`.\n */\nexport function isValidPhone(value: unknown): boolean {\n const loaded = phonePeer.get()\n // not loaded yet (no PhoneField mounted so far) → start loading and report \"not valid\" for now\n if (!loaded) {\n void phonePeer.load()\n return false\n }\n return typeof value === 'string' && value.trim() !== '' && loaded.isValidPhoneNumber(value)\n}\n\n/** A flag emoji from the two regional-indicator letters — no image assets (Windows shows the letters). */\nexport function flagEmoji(country: string): string {\n return String.fromCodePoint(\n ...[...country.toUpperCase()].map((c) => 0x1f1e6 + c.charCodeAt(0) - 65),\n )\n}\n\nconst displayNamesCache = new Map<string, Intl.DisplayNames | null>()\n/** The country's name in `locale` via `Intl.DisplayNames` (no catalog to ship); falls back to the code. */\nexport function countryName(country: string, locale: string): string {\n if (!displayNamesCache.has(locale)) {\n try {\n displayNamesCache.set(locale, new Intl.DisplayNames([locale], { type: 'region' }))\n } catch {\n displayNamesCache.set(locale, null)\n }\n }\n try {\n return displayNamesCache.get(locale)?.of(country) ?? country\n } catch {\n return country\n }\n}\n\n// the main country for a calling code shared by several (a partial \"+44…\" parses as Guernsey otherwise)\nconst MAIN_FOR_CODE: Record<string, PhoneCountry> = {\n '1': 'US',\n '7': 'RU',\n '39': 'IT',\n '44': 'GB',\n '47': 'NO',\n '61': 'AU',\n '212': 'MA',\n '262': 'RE',\n '290': 'SH',\n '358': 'FI',\n '590': 'GP',\n '599': 'CW',\n}\n// base UI language → its usual country, for the default when the locale carries no region\nconst LANGUAGE_COUNTRY: Record<string, PhoneCountry> = {\n ka: 'GE',\n en: 'US',\n es: 'ES',\n de: 'DE',\n it: 'IT',\n fr: 'FR',\n ru: 'RU',\n}\n\n/** The default country: the locale's region → its language's usual country → the browser's region → US. */\nexport function detectCountry(locale: string, allowed: readonly PhoneCountry[]): PhoneCountry {\n const [base, region] = locale.split('-')\n const browser =\n typeof navigator !== 'undefined' ? navigator.language?.split('-')[1]?.toUpperCase() : undefined\n const candidates = [region?.toUpperCase(), LANGUAGE_COUNTRY[base?.toLowerCase()], browser, 'US']\n return (candidates.find((c) => c && allowed.includes(c as PhoneCountry)) ??\n allowed[0]) as PhoneCountry\n}\n\n/** The result of reading what's in the input. */\nexport interface PhoneReading {\n /** The canonical value — `'+995555123456'`, or `''` when empty. */\n e164: string\n /** The country the number belongs to (may switch when a `+code` is typed). */\n country: PhoneCountry\n /** The national significant number — digits only, no trunk `0`. */\n national: string\n /** A complete, valid number. */\n valid: boolean\n /** What the input should show (formatted as you type). */\n display: string\n}\n\nconst digitsOf = (s: string) => s.replace(/\\D/g, '')\n\n/** Which allowed country a `+code…` number belongs to — keep the current one when it shares the code. */\nfunction countryForCode(\n code: string,\n current: PhoneCountry,\n detected: PhoneCountry | undefined,\n allowed: readonly PhoneCountry[],\n): PhoneCountry {\n if (callingCodeOf(current) === code) return current\n const pick = [detected, MAIN_FOR_CODE[code], ...allowed.filter((c) => callingCodeOf(c) === code)]\n return (pick.find((c) => c && allowed.includes(c)) as PhoneCountry | undefined) ?? current\n}\n\n/** Read raw input text → the canonical value + the formatted display, as the user types. */\nexport function readPhoneInput(\n raw: string,\n country: PhoneCountry,\n format: PhoneFormat,\n allowed: readonly PhoneCountry[],\n): PhoneReading {\n const text = raw.trimStart()\n const digits = digitsOf(text)\n if (!digits) {\n return {\n e164: '',\n country,\n national: '',\n valid: false,\n display: text.startsWith('+') ? '+' : '',\n }\n }\n\n // an explicit \"+code…\" (typed or pasted) — the calling code decides the country\n if (text.startsWith('+')) {\n const typer = new (lib().AsYouType)()\n const display = typer.input(`+${digits}`)\n const code = typer.getCallingCode()\n const parsed = lib().parsePhoneNumberFromString(`+${digits}`)\n const next = code\n ? countryForCode(code, country, parsed?.country ?? typer.getCountry(), allowed)\n : country\n const e164 = `+${digits}`\n return {\n e164,\n country: next,\n national: code ? digits.slice(code.length) : '',\n valid: lib().isValidPhoneNumber(e164),\n display,\n }\n }\n\n // national digits under the selected country (a leading trunk \"0\" is dropped from the value)\n const code = callingCodeOf(country)\n const parsed = lib().parsePhoneNumberFromString(digits, country)\n const national = parsed?.nationalNumber ?? digits.replace(/^0+/, '')\n const e164 = national ? `+${code}${national}` : ''\n const display =\n format === 'international'\n ? new (lib().AsYouType)(country).input(`+${code}${national}`)\n : new (lib().AsYouType)(country).input(digits)\n return {\n e164,\n country,\n national,\n valid: e164 !== '' && lib().isValidPhoneNumber(e164),\n display,\n }\n}\n\n/** Derive the country + display from an E.164 value (initial / external value changes). */\nexport function phoneFromValue(\n value: string,\n fallback: PhoneCountry,\n format: PhoneFormat,\n allowed: readonly PhoneCountry[],\n): { country: PhoneCountry; display: string } {\n if (!value) return { country: fallback, display: '' }\n const parsed = lib().parsePhoneNumberFromString(value)\n if (parsed) {\n const country = countryForCode(parsed.countryCallingCode, fallback, parsed.country, allowed)\n return {\n country,\n display: format === 'national' ? parsed.formatNational() : parsed.formatInternational(),\n }\n }\n const reading = readPhoneInput(value, fallback, 'international', allowed)\n const display =\n format === 'national' && reading.national\n ? new (lib().AsYouType)(reading.country).input(reading.national)\n : reading.display\n return { country: reading.country, display }\n}\n\n/** Caret index in `display` right after its `n`-th digit — keeps the caret put while reformatting. */\nexport function caretAfterDigits(display: string, n: number): number {\n if (n <= 0) return display.startsWith('+') ? 1 : 0\n let seen = 0\n for (let i = 0; i < display.length; i++) {\n if (/\\d/.test(display[i])) seen++\n if (seen === n) return i + 1\n }\n return display.length\n}\n","import {\n forwardRef,\n useCallback,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type CSSProperties,\n type FocusEvent,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useLanguage, useT } from '../../theme'\nimport { useOptionalPeer } from '../../hooks/useOptionalPeer'\nimport { useFormContext } from '../../form/formContext'\nimport { Icon } from '../Icon'\nimport { TextField } from '../TextField'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu, type SelectOption } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport fieldStyles from '../TextField/TextField.module.css'\nimport {\n callingCodeOf,\n getPhoneCountries,\n caretAfterDigits,\n countryName,\n detectCountry,\n flagEmoji,\n phoneFromValue,\n phonePeer,\n readPhoneInput,\n type PhoneCountry,\n type PhoneFormat,\n} from './phone'\nimport styles from './PhoneField.module.css'\n\nexport type PhoneFieldSize = 'sm' | 'md' | 'lg'\n\n/** Extra details handed to `onChange` alongside the E.164 value. */\nexport interface PhoneFieldChangeMeta {\n /** The number's country (ISO alpha-2). */\n country: PhoneCountry\n /** The national significant number — digits only, no trunk `0`. */\n national: string\n /** A complete, valid number for that country. */\n valid: boolean\n}\n\nexport interface PhoneFieldProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'value' | 'defaultValue' | 'onChange' | 'type' | 'size' | 'color'\n> {\n /** The number in **E.164** (`'+995555123456'`) — the only form the field emits. `''` when empty. */\n value?: string\n /** Initial E.164 value for uncontrolled use. */\n defaultValue?: string\n /** Fires with the E.164 value (`''` when cleared) and `{ country, national, valid }`. */\n onChange?: (value: string, meta: PhoneFieldChangeMeta) => void\n /** The country to start with. Defaults to one derived from the UI language / browser locale. */\n defaultCountry?: PhoneCountry\n /** Restrict the selectable countries (e.g. only where you operate). Defaults to all. */\n countries?: readonly PhoneCountry[]\n /** Countries pinned to the top of the list, in this order. */\n preferredCountries?: readonly PhoneCountry[]\n /**\n * How the number reads while typing — `national` (default: `555 12 34 56`, the calling code lives in\n * the country button) or `international` (`+995 555 12 34 56`). The value is E.164 either way.\n */\n format?: PhoneFormat\n /** Field label. */\n label?: ReactNode\n /** Helper / validation text under the field. */\n helperText?: ReactNode\n /** Error state (red border + helper). */\n error?: boolean\n /** Shows a required asterisk. */\n required?: boolean\n /** `sm` / `md` / `lg` — control height + type. Defaults to `md`. */\n size?: PhoneFieldSize\n /** Stretch to the container. Defaults to `true`. */\n fullWidth?: boolean\n}\n\n/** The field itself — rendered once `libphonenumber-js` has loaded. */\nconst PhoneFieldInner = forwardRef<HTMLInputElement, PhoneFieldProps>(function PhoneFieldInner(\n {\n value,\n defaultValue,\n onChange,\n defaultCountry,\n countries: countriesProp,\n preferredCountries = [],\n format = 'national',\n label,\n helperText,\n error,\n required,\n size = 'md',\n fullWidth = true,\n name,\n disabled = false,\n id: idProp,\n className,\n style,\n onBlur,\n placeholder,\n ...props\n },\n ref,\n) {\n const t = useT()\n const { language } = useLanguage()\n const countries = countriesProp ?? getPhoneCountries()\n const reactId = useId()\n const id = idProp ?? reactId\n const helperId = `${id}-helper`\n\n // ── value: controlled / form-bound / uncontrolled — always E.164 ──\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const [internal, setInternal] = useState(defaultValue ?? '')\n const currentValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string | undefined) ?? '')\n : internal\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const fallbackCountry = useMemo<PhoneCountry>(\n () =>\n defaultCountry && countries.includes(defaultCountry)\n ? defaultCountry\n : detectCountry(language, countries),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [defaultCountry, language, countries.join()],\n )\n\n const [country, setCountry] = useState<PhoneCountry>(\n () => phoneFromValue(currentValue, fallbackCountry, format, countries).country,\n )\n const [display, setDisplay] = useState(\n () => phoneFromValue(currentValue, fallbackCountry, format, countries).display,\n )\n\n // re-derive the display when the value changes from OUTSIDE (a reset / a controlled update) — the\n // values we emit ourselves are skipped, so formatting never fights the user mid-typing\n const lastEmitted = useRef(currentValue)\n if (lastEmitted.current !== currentValue) {\n lastEmitted.current = currentValue\n const next = phoneFromValue(currentValue, country, format, countries)\n setCountry(next.country)\n setDisplay(next.display)\n }\n\n // caret restore after reformatting\n const innerRef = useRef<HTMLInputElement | null>(null)\n const setInputRef = useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLInputElement | null }).current = node\n },\n [ref],\n )\n const pendingCaret = useRef<number | null>(null)\n useLayoutEffect(() => {\n const pos = pendingCaret.current\n if (pos == null) return\n pendingCaret.current = null\n innerRef.current?.setSelectionRange(pos, pos)\n })\n\n const emit = (reading: ReturnType<typeof readPhoneInput>) => {\n lastEmitted.current = reading.e164\n setDisplay(reading.display)\n if (reading.country !== country) setCountry(reading.country)\n if (value === undefined && !isFormBound) setInternal(reading.e164)\n if (isFormBound) form!.setValue(name!, reading.e164)\n onChange?.(reading.e164, {\n country: reading.country,\n national: reading.national,\n valid: reading.valid,\n })\n }\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const el = event.target\n let raw = el.value\n const caret = el.selectionStart ?? raw.length\n let digitsBefore = raw.slice(0, caret).replace(/\\D/g, '').length\n // backspace over a formatting char (space / paren / dash) would be re-added by the formatter —\n // treat it as deleting the digit before it instead\n const prevDigits = display.replace(/\\D/g, '')\n if (raw.length < display.length && raw.replace(/\\D/g, '') === prevDigits && digitsBefore > 0) {\n let seen = 0\n let cut = -1\n for (let i = 0; i < raw.length; i++) {\n if (/\\d/.test(raw[i]) && ++seen === digitsBefore) {\n cut = i\n break\n }\n }\n if (cut >= 0) raw = raw.slice(0, cut) + raw.slice(cut + 1)\n digitsBefore -= 1\n }\n const reading = readPhoneInput(raw, country, format, countries)\n pendingCaret.current =\n caret >= el.value.length\n ? reading.display.length\n : caretAfterDigits(reading.display, digitsBefore)\n emit(reading)\n }\n\n // ── country picker — the shared option menu (search matches name, ISO code, calling code) ──\n const controlRef = useRef<HTMLDivElement | null>(null)\n const countryOptions = useMemo<SelectOption[]>(() => {\n const toOption = (c: PhoneCountry): SelectOption => {\n const dial = callingCodeOf(c)\n return {\n value: c,\n label: countryName(c, language),\n icon: (\n <span className={styles.flag} aria-hidden=\"true\">\n {flagEmoji(c)}\n </span>\n ),\n keywords: [c, dial, `+${dial}`],\n trailing: <span className={styles.dial}>+{dial}</span>,\n }\n }\n // preferred countries first (in the given order), then the rest A→Z by their localized name —\n // as two groups (\"Suggested\" / \"All Countries\") when there are preferred ones\n const pinned = preferredCountries.filter((c) => countries.includes(c)).map(toOption)\n const rest = countries\n .filter((c) => !preferredCountries.includes(c))\n .map(toOption)\n .sort((a, b) => a.label.localeCompare(b.label, language))\n if (pinned.length === 0) return rest\n return [\n ...pinned.map((o) => ({ ...o, group: t('phoneField.suggested') })),\n ...rest.map((o) => ({ ...o, group: t('phoneField.allCountries') })),\n ]\n }, [countries, preferredCountries, language, t])\n\n const pickCountry = (next: PhoneCountry) => {\n // keep the typed national digits, re-read under the new calling code\n const national = readPhoneInput(display, country, format, countries).national\n setCountry(next)\n emit({ ...readPhoneInput(national, next, format, countries), country: next })\n }\n\n const menu = useOptionMenu({\n idBase: `${id}-country`,\n options: countryOptions,\n isSelected: (o) => o.value === country,\n onPick: (o) => pickCountry(o.value as PhoneCountry),\n searchable: true,\n disabled,\n // after a pick / Esc, typing continues in the number\n focusRef: innerRef,\n })\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n bound?.onBlur(event)\n onBlur?.(event)\n }\n\n const describedBy = resolvedHelperText != null ? helperId : undefined\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const code = callingCodeOf(country)\n const name_ = countryName(country, language)\n\n return (\n <div\n className={clsx(\n fieldStyles.field,\n fieldStyles[size],\n fullWidth && fieldStyles.fullWidth,\n resolvedError && fieldStyles.error,\n disabled && fieldStyles.disabled,\n styles.phoneField,\n className,\n )}\n style={style as CSSProperties}\n >\n {label != null && (\n <label htmlFor={id} className={fieldStyles.label}>\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={fieldStyles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div ref={controlRef} className={clsx(fieldStyles.control, styles.control)}>\n <button\n type=\"button\"\n className={styles.country}\n aria-haspopup=\"listbox\"\n aria-expanded={menu.open}\n aria-controls={menu.open ? menu.listboxId : undefined}\n aria-label={`${t('phoneField.country')}: ${name_} (+${code})`}\n disabled={disabled}\n onClick={menu.toggleMenu}\n onKeyDown={(e) => {\n // ↓ / ↑ open the list (Enter / Space already click the button)\n if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !menu.open) {\n e.preventDefault()\n menu.openMenu()\n }\n }}\n >\n <span className={styles.flag} aria-hidden=\"true\">\n {flagEmoji(country)}\n </span>\n {format === 'national' && <span className={styles.code}>+{code}</span>}\n {/* the same chevron as Select / MultiSelect (ArrowDown4, sized per field size: sm 16 · md 14 · lg 12) */}\n <Icon\n name=\"ArrowDown4\"\n className={clsx(styles.chevron, menu.open && styles.chevronOpen)}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </button>\n <input\n ref={setInputRef}\n id={id}\n name={name}\n type=\"tel\"\n inputMode=\"tel\"\n autoComplete=\"tel\"\n className={fieldStyles.input}\n value={display}\n placeholder={placeholder}\n onChange={handleChange}\n onBlur={handleBlur}\n disabled={disabled}\n aria-invalid={resolvedError || undefined}\n aria-describedby={describedBy}\n {...props}\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={controlRef}\n size={size}\n searchPlaceholder={t('phoneField.search')}\n ariaLabel={t('phoneField.country')}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={fieldStyles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n\n/**\n * A phone-number field: a **country button** (flag + `+code`, opening a searchable, localized country\n * list) inside the input frame, and the number **formatted as you type** for that country. The value is\n * always **E.164** (`'+995555123456'`) — one canonical form for the backend. Typing or pasting `+44…`\n * switches the country by its calling code. `onChange(value, { country, national, valid })`; binds to a\n * `<Form>` by `name` (the form value is the E.164 string — validate with `isValidPhone`). Country names\n * come from `Intl.DisplayNames` in the active UI language; flags are emoji. Needs the optional peer\n * **`libphonenumber-js`** (formatting, parsing, validation metadata), loaded lazily on first mount — until\n * it's ready (or if it isn't installed) a disabled look-alike field renders. Reuses the `TextField` look.\n */\nexport const PhoneField = forwardRef<HTMLInputElement, PhoneFieldProps>(\n function PhoneField(props, ref) {\n const { module } = useOptionalPeer(phonePeer)\n if (module) return <PhoneFieldInner ref={ref} {...props} />\n // loading (a tick, first mount only) or the peer is missing: the same frame, disabled — never bound\n // to a <Form> (no `name`) so it can't write a value\n const {\n label,\n helperText,\n error,\n required,\n size,\n fullWidth = true,\n className,\n style,\n placeholder,\n } = props\n return (\n <TextField\n ref={ref}\n type=\"tel\"\n label={label}\n helperText={helperText}\n error={error}\n required={required}\n size={size}\n fullWidth={fullWidth}\n className={className}\n style={style}\n placeholder={placeholder}\n value={props.value ?? props.defaultValue ?? ''}\n readOnly\n disabled\n />\n )\n },\n)\n"],"names":["phonePeer","optionalPeer","lib","allCountries","getPhoneCountries","callingCodeOf","country","isValidPhone","value","loaded","flagEmoji","c","displayNamesCache","countryName","locale","_a","MAIN_FOR_CODE","LANGUAGE_COUNTRY","detectCountry","allowed","base","region","browser","_b","digitsOf","s","countryForCode","code","current","detected","readPhoneInput","raw","format","text","digits","typer","display","parsed","next","e164","national","phoneFromValue","fallback","reading","caretAfterDigits","n","seen","i","PhoneFieldInner","forwardRef","defaultValue","onChange","defaultCountry","countriesProp","preferredCountries","label","helperText","error","required","size","fullWidth","name","disabled","idProp","className","style","onBlur","placeholder","props","ref","t","useT","language","useLanguage","countries","reactId","useId","id","helperId","form","useFormContext","isFormBound","bound","internal","setInternal","useState","currentValue","resolvedError","resolvedHelperText","fallbackCountry","useMemo","setCountry","setDisplay","lastEmitted","useRef","innerRef","setInputRef","useCallback","node","pendingCaret","useLayoutEffect","pos","emit","handleChange","event","el","caret","digitsBefore","prevDigits","cut","controlRef","countryOptions","toOption","dial","jsx","styles","jsxs","pinned","rest","a","b","o","pickCountry","menu","useOptionMenu","handleBlur","describedBy","chevronPx","name_","clsx","fieldStyles","Typography","e","Icon","OptionMenu","PhoneField","module","useOptionalPeer","TextField"],"mappings":"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"}
@@ -2,10 +2,10 @@ import { jsx as o, jsxs as i, Fragment as J } from "react/jsx-runtime";
2
2
  import { useId as K, useRef as A, useState as R, useEffect as Q, cloneElement as U } from "react";
3
3
  import { clsx as V } from "clsx";
4
4
  import { a as W } from "./names-BR1uJs0-.js";
5
- import { B as S } from "./Button-BJ5Xd10u.js";
5
+ import { B as S } from "./Button-PBZnkRNn.js";
6
6
  import { F as X } from "./FloatingPanel-C5c_eMQ0.js";
7
7
  import { I as Y } from "./Icon-CGQ5yGSZ.js";
8
- import { a as Z } from "./ConfigProvider-D2svpXFu.js";
8
+ import { a as Z } from "./ConfigProvider-tvLbKiqu.js";
9
9
  const tt = "_popconfirm_ztpne_5", et = "_body_ztpne_12", nt = "_icon_ztpne_21", rt = "_text_ztpne_33", ot = "_title_ztpne_43", st = "_description_ztpne_50", it = "_footer_ztpne_58", n = {
10
10
  popconfirm: tt,
11
11
  body: et,
@@ -110,4 +110,4 @@ function yt({
110
110
  export {
111
111
  yt as P
112
112
  };
113
- //# sourceMappingURL=Popconfirm-CYkwGTh-.js.map
113
+ //# sourceMappingURL=Popconfirm-D4J7tlk_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popconfirm-CYkwGTh-.js","sources":["../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Button } from '../Button'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport type { PopoverAlign } from '../Popover'\nimport styles from './Popconfirm.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface PopconfirmProps {\n /** The question — \"Delete this item?\". Labels the dialog. */\n title: ReactNode\n /** Optional muted line under the title (the consequence). Describes the dialog. */\n description?: ReactNode\n /**\n * Runs on confirm. Return a Promise to keep the popover open with the confirm button **loading** until\n * it settles — it closes on success and **stays open on rejection** (show your own toast).\n */\n // `unknown` (not `void | Promise`) so `() => toast.success(…)` — which returns an id — still fits\n onConfirm: () => unknown\n /** Runs on Cancel, `Escape` or an outside click. */\n onCancel?: () => void\n /** Confirm button label. Defaults to the localized \"Confirm\". */\n confirmLabel?: ReactNode\n /** Cancel button label. Defaults to the localized \"Cancel\". */\n cancelLabel?: ReactNode\n /** Tints the confirm button and the icon. Defaults to `error` (a destructive action). */\n color?: ThemeColor\n /** Leading icon — a known `IconName`, any node, or `false`. Defaults to `Danger` in the `color`. */\n icon?: IconName | ReactNode | false\n /** Horizontal alignment to the trigger (`start` default, `end` for a trigger near the right edge). */\n align?: PopoverAlign\n /** Controlled open state. */\n open?: boolean\n /** Fires with the next open state. */\n onOpenChange?: (open: boolean) => void\n /** Clicking the trigger does nothing (no popover). */\n disabled?: boolean\n /** Panel width (px number or CSS width). Defaults to `300px`. */\n width?: number | string\n /** Class on the floating panel. */\n className?: string\n /** Style on the floating panel. */\n style?: CSSProperties\n /** The trigger — usually a `Button` / `IconButton`. Cloned to wire the click + ARIA. */\n children: ReactElement\n}\n\n/**\n * An **inline confirm** for quick, low-risk actions (a row's delete / archive) — a small anchored popover\n * with a question, an optional description and **Cancel** / **Confirm**, where a `RemoveDialog` modal\n * would be too heavy and a bare `onClick` too dangerous. Wraps its trigger (`children`), which it clones\n * to toggle the panel. Built on the shared `FloatingPanel` (portaled, flips, clamps to the viewport,\n * dismisses on outside click / `Escape` = cancel). A11y: `role=\"alertdialog\"` labelled by the title and\n * described by the description, focus trapped and **placed on Cancel** (never the destructive button —\n * the `RemoveDialog` rule), focus returns to the trigger. An async `onConfirm` shows a loading confirm\n * button (Cancel + dismiss locked meanwhile), closes on success, stays open on failure. The icon sits in a\n * tinted box, the buttons (`sm`; confirm `contained` in `color`, default `error`) in a Card-style footer. Use `RemoveDialog` for high-risk, context-heavy deletes.\n */\nexport function Popconfirm({\n title,\n description,\n onConfirm,\n onCancel,\n confirmLabel,\n cancelLabel,\n color = 'error',\n icon = 'Danger',\n align = 'start',\n open,\n onOpenChange,\n disabled = false,\n width = 300,\n className,\n style,\n children,\n}: PopconfirmProps) {\n const t = useT()\n const id = useId()\n const panelId = `${id}-panel`\n const titleId = `${id}-title`\n const descId = `${id}-desc`\n const triggerRef = useRef<HTMLElement | null>(null)\n const cancelRef = useRef<HTMLButtonElement | null>(null)\n const [busy, setBusy] = useState(false)\n\n const isControlled = open !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlled ? open : internalOpen\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next)\n onOpenChange?.(next)\n }\n\n // focus Cancel once the panel is positioned + visible (a hidden element can't take focus)\n useEffect(() => {\n if (!isOpen) return\n const raf = requestAnimationFrame(() => cancelRef.current?.focus())\n return () => cancelAnimationFrame(raf)\n }, [isOpen])\n\n const close = (refocus: boolean) => {\n setOpen(false)\n if (refocus) triggerRef.current?.focus()\n }\n\n const cancel = (refocus = true) => {\n if (busy) return\n onCancel?.()\n close(refocus)\n }\n\n const confirm = async () => {\n const result = onConfirm()\n // any thenable counts as async (not just native Promises)\n if (!result || typeof (result as PromiseLike<unknown>).then !== 'function') {\n close(true)\n return\n }\n setBusy(true)\n try {\n await result\n setBusy(false)\n close(true)\n } catch {\n // stays open so the user can retry or cancel; surfacing the error (a toast) is the consumer's job\n setBusy(false)\n }\n }\n\n const triggerProps = children.props as {\n onClick?: (event: ReactMouseEvent) => void\n ref?: Ref<HTMLElement>\n }\n const originalRef = triggerProps.ref\n const trigger = cloneElement(children as ReactElement<Record<string, unknown>>, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node\n if (typeof originalRef === 'function') originalRef(node)\n else if (originalRef) (originalRef as { current: HTMLElement | null }).current = node\n },\n onClick: (event: ReactMouseEvent) => {\n triggerProps.onClick?.(event)\n if (disabled || busy) return\n if (isOpen) cancel(false)\n else setOpen(true)\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? panelId : undefined,\n })\n\n const renderedIcon =\n icon === false ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <>\n {trigger}\n <FloatingPanel\n open={isOpen}\n triggerRef={triggerRef}\n align={align}\n onClose={(refocus) => cancel(refocus)}\n id={panelId}\n role=\"alertdialog\"\n ariaLabelledBy={titleId}\n ariaDescribedBy={description != null ? descId : undefined}\n trapFocus\n width={width}\n className={clsx(styles.popconfirm, className)}\n style={{ '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`, ...style } as CSSProperties}\n >\n <div className={styles.body}>\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden=\"true\">\n {renderedIcon}\n </span>\n )}\n <div className={styles.text}>\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n {description != null && (\n <div id={descId} className={styles.description}>\n {description}\n </div>\n )}\n </div>\n </div>\n <div className={styles.footer}>\n <Button ref={cancelRef} variant=\"text\" size=\"sm\" onClick={() => cancel()} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button variant=\"contained\" color={color} size=\"sm\" loading={busy} onClick={confirm}>\n {confirmLabel ?? t('common.confirm')}\n </Button>\n </div>\n </FloatingPanel>\n </>\n )\n}\n"],"names":["ICON_NAME_SET","ICON_NAMES","Popconfirm","title","description","onConfirm","onCancel","confirmLabel","cancelLabel","color","icon","align","open","onOpenChange","disabled","width","className","style","children","t","useT","id","useId","panelId","titleId","descId","triggerRef","useRef","cancelRef","busy","setBusy","useState","isControlled","internalOpen","setInternalOpen","isOpen","setOpen","next","useEffect","raf","_a","close","refocus","cancel","confirm","result","triggerProps","originalRef","trigger","cloneElement","node","event","renderedIcon","jsx","Icon","jsxs","Fragment","FloatingPanel","clsx","styles","Button"],"mappings":"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"}
1
+ {"version":3,"file":"Popconfirm-D4J7tlk_.js","sources":["../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Button } from '../Button'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport type { PopoverAlign } from '../Popover'\nimport styles from './Popconfirm.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface PopconfirmProps {\n /** The question — \"Delete this item?\". Labels the dialog. */\n title: ReactNode\n /** Optional muted line under the title (the consequence). Describes the dialog. */\n description?: ReactNode\n /**\n * Runs on confirm. Return a Promise to keep the popover open with the confirm button **loading** until\n * it settles — it closes on success and **stays open on rejection** (show your own toast).\n */\n // `unknown` (not `void | Promise`) so `() => toast.success(…)` — which returns an id — still fits\n onConfirm: () => unknown\n /** Runs on Cancel, `Escape` or an outside click. */\n onCancel?: () => void\n /** Confirm button label. Defaults to the localized \"Confirm\". */\n confirmLabel?: ReactNode\n /** Cancel button label. Defaults to the localized \"Cancel\". */\n cancelLabel?: ReactNode\n /** Tints the confirm button and the icon. Defaults to `error` (a destructive action). */\n color?: ThemeColor\n /** Leading icon — a known `IconName`, any node, or `false`. Defaults to `Danger` in the `color`. */\n icon?: IconName | ReactNode | false\n /** Horizontal alignment to the trigger (`start` default, `end` for a trigger near the right edge). */\n align?: PopoverAlign\n /** Controlled open state. */\n open?: boolean\n /** Fires with the next open state. */\n onOpenChange?: (open: boolean) => void\n /** Clicking the trigger does nothing (no popover). */\n disabled?: boolean\n /** Panel width (px number or CSS width). Defaults to `300px`. */\n width?: number | string\n /** Class on the floating panel. */\n className?: string\n /** Style on the floating panel. */\n style?: CSSProperties\n /** The trigger — usually a `Button` / `IconButton`. Cloned to wire the click + ARIA. */\n children: ReactElement\n}\n\n/**\n * An **inline confirm** for quick, low-risk actions (a row's delete / archive) — a small anchored popover\n * with a question, an optional description and **Cancel** / **Confirm**, where a `RemoveDialog` modal\n * would be too heavy and a bare `onClick` too dangerous. Wraps its trigger (`children`), which it clones\n * to toggle the panel. Built on the shared `FloatingPanel` (portaled, flips, clamps to the viewport,\n * dismisses on outside click / `Escape` = cancel). A11y: `role=\"alertdialog\"` labelled by the title and\n * described by the description, focus trapped and **placed on Cancel** (never the destructive button —\n * the `RemoveDialog` rule), focus returns to the trigger. An async `onConfirm` shows a loading confirm\n * button (Cancel + dismiss locked meanwhile), closes on success, stays open on failure. The icon sits in a\n * tinted box, the buttons (`sm`; confirm `contained` in `color`, default `error`) in a Card-style footer. Use `RemoveDialog` for high-risk, context-heavy deletes.\n */\nexport function Popconfirm({\n title,\n description,\n onConfirm,\n onCancel,\n confirmLabel,\n cancelLabel,\n color = 'error',\n icon = 'Danger',\n align = 'start',\n open,\n onOpenChange,\n disabled = false,\n width = 300,\n className,\n style,\n children,\n}: PopconfirmProps) {\n const t = useT()\n const id = useId()\n const panelId = `${id}-panel`\n const titleId = `${id}-title`\n const descId = `${id}-desc`\n const triggerRef = useRef<HTMLElement | null>(null)\n const cancelRef = useRef<HTMLButtonElement | null>(null)\n const [busy, setBusy] = useState(false)\n\n const isControlled = open !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlled ? open : internalOpen\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next)\n onOpenChange?.(next)\n }\n\n // focus Cancel once the panel is positioned + visible (a hidden element can't take focus)\n useEffect(() => {\n if (!isOpen) return\n const raf = requestAnimationFrame(() => cancelRef.current?.focus())\n return () => cancelAnimationFrame(raf)\n }, [isOpen])\n\n const close = (refocus: boolean) => {\n setOpen(false)\n if (refocus) triggerRef.current?.focus()\n }\n\n const cancel = (refocus = true) => {\n if (busy) return\n onCancel?.()\n close(refocus)\n }\n\n const confirm = async () => {\n const result = onConfirm()\n // any thenable counts as async (not just native Promises)\n if (!result || typeof (result as PromiseLike<unknown>).then !== 'function') {\n close(true)\n return\n }\n setBusy(true)\n try {\n await result\n setBusy(false)\n close(true)\n } catch {\n // stays open so the user can retry or cancel; surfacing the error (a toast) is the consumer's job\n setBusy(false)\n }\n }\n\n const triggerProps = children.props as {\n onClick?: (event: ReactMouseEvent) => void\n ref?: Ref<HTMLElement>\n }\n const originalRef = triggerProps.ref\n const trigger = cloneElement(children as ReactElement<Record<string, unknown>>, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node\n if (typeof originalRef === 'function') originalRef(node)\n else if (originalRef) (originalRef as { current: HTMLElement | null }).current = node\n },\n onClick: (event: ReactMouseEvent) => {\n triggerProps.onClick?.(event)\n if (disabled || busy) return\n if (isOpen) cancel(false)\n else setOpen(true)\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? panelId : undefined,\n })\n\n const renderedIcon =\n icon === false ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <>\n {trigger}\n <FloatingPanel\n open={isOpen}\n triggerRef={triggerRef}\n align={align}\n onClose={(refocus) => cancel(refocus)}\n id={panelId}\n role=\"alertdialog\"\n ariaLabelledBy={titleId}\n ariaDescribedBy={description != null ? descId : undefined}\n trapFocus\n width={width}\n className={clsx(styles.popconfirm, className)}\n style={{ '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`, ...style } as CSSProperties}\n >\n <div className={styles.body}>\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden=\"true\">\n {renderedIcon}\n </span>\n )}\n <div className={styles.text}>\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n {description != null && (\n <div id={descId} className={styles.description}>\n {description}\n </div>\n )}\n </div>\n </div>\n <div className={styles.footer}>\n <Button ref={cancelRef} variant=\"text\" size=\"sm\" onClick={() => cancel()} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button variant=\"contained\" color={color} size=\"sm\" loading={busy} onClick={confirm}>\n {confirmLabel ?? t('common.confirm')}\n </Button>\n </div>\n </FloatingPanel>\n </>\n )\n}\n"],"names":["ICON_NAME_SET","ICON_NAMES","Popconfirm","title","description","onConfirm","onCancel","confirmLabel","cancelLabel","color","icon","align","open","onOpenChange","disabled","width","className","style","children","t","useT","id","useId","panelId","titleId","descId","triggerRef","useRef","cancelRef","busy","setBusy","useState","isControlled","internalOpen","setInternalOpen","isOpen","setOpen","next","useEffect","raf","_a","close","refocus","cancel","confirm","result","triggerProps","originalRef","trigger","cloneElement","node","event","renderedIcon","jsx","Icon","jsxs","Fragment","FloatingPanel","clsx","styles","Button"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";const t=require("react/jsx-runtime"),n=require("react"),G=require("clsx"),H=require("./names-YOCJ4B5J.cjs"),R=require("./Button-BZq1mIUH.cjs"),J=require("./FloatingPanel-tGCG2nhA.cjs"),K=require("./Icon-BUP5_kRs.cjs"),Q=require("./ConfigProvider-CzAQf_d_.cjs"),U="_popconfirm_ztpne_5",V="_body_ztpne_12",W="_icon_ztpne_21",X="_text_ztpne_33",Y="_title_ztpne_43",Z="_description_ztpne_50",ee="_footer_ztpne_58",r={popconfirm:U,body:V,icon:W,text:X,title:Y,description:Z,footer:ee},te=new Set(H.ICON_NAMES);function se({title:E,description:u,onConfirm:S,onCancel:f,confirmLabel:k,cancelLabel:A,color:j="error",icon:c="Danger",align:P="start",open:v,onOpenChange:d,disabled:$=!1,width:w=300,className:D,style:M,children:b}){const z=Q.useT(),p=n.useId(),N=`${p}-panel`,g=`${p}-title`,h=`${p}-desc`,m=n.useRef(null),I=n.useRef(null),[i,_]=n.useState(!1),q=v!==void 0,[O,T]=n.useState(!1),o=q?v:O,B=e=>{q||T(e),d==null||d(e)};n.useEffect(()=>{if(!o)return;const e=requestAnimationFrame(()=>{var s;return(s=I.current)==null?void 0:s.focus()});return()=>cancelAnimationFrame(e)},[o]);const x=e=>{var s;B(!1),e&&((s=m.current)==null||s.focus())},y=(e=!0)=>{i||(f==null||f(),x(e))},C=async()=>{const e=S();if(!e||typeof e.then!="function"){x(!0);return}_(!0);try{await e,_(!1),x(!0)}catch{_(!1)}},l=b.props,a=l.ref,L=n.cloneElement(b,{ref:e=>{m.current=e,typeof a=="function"?a(e):a&&(a.current=e)},onClick:e=>{var s;(s=l.onClick)==null||s.call(l,e),!($||i)&&(o?y(!1):B(!0))},"aria-haspopup":"dialog","aria-expanded":o,"aria-controls":o?N:void 0}),F=c===!1?null:typeof c=="string"&&te.has(c)?t.jsx(K.Icon,{name:c}):c;return t.jsxs(t.Fragment,{children:[L,t.jsxs(J.FloatingPanel,{open:o,triggerRef:m,align:P,onClose:e=>y(e),id:N,role:"alertdialog",ariaLabelledBy:g,ariaDescribedBy:u!=null?h:void 0,trapFocus:!0,width:w,className:G.clsx(r.popconfirm,D),style:{"--tz-btn-rgb":`var(--tz-color-${j}-rgb)`,...M},children:[t.jsxs("div",{className:r.body,children:[F!=null&&t.jsx("span",{className:r.icon,"aria-hidden":"true",children:F}),t.jsxs("div",{className:r.text,children:[t.jsx("div",{id:g,className:r.title,children:E}),u!=null&&t.jsx("div",{id:h,className:r.description,children:u})]})]}),t.jsxs("div",{className:r.footer,children:[t.jsx(R.Button,{ref:I,variant:"text",size:"sm",onClick:()=>y(),disabled:i,children:A??z("common.cancel")}),t.jsx(R.Button,{variant:"contained",color:j,size:"sm",loading:i,onClick:C,children:k??z("common.confirm")})]})]})]})}exports.Popconfirm=se;
2
- //# sourceMappingURL=Popconfirm-DS6tCxV0.cjs.map
1
+ "use strict";const t=require("react/jsx-runtime"),n=require("react"),G=require("clsx"),H=require("./names-YOCJ4B5J.cjs"),R=require("./Button-BD5wpg-t.cjs"),J=require("./FloatingPanel-tGCG2nhA.cjs"),K=require("./Icon-BUP5_kRs.cjs"),Q=require("./ConfigProvider-CVLHPXQm.cjs"),U="_popconfirm_ztpne_5",V="_body_ztpne_12",W="_icon_ztpne_21",X="_text_ztpne_33",Y="_title_ztpne_43",Z="_description_ztpne_50",ee="_footer_ztpne_58",r={popconfirm:U,body:V,icon:W,text:X,title:Y,description:Z,footer:ee},te=new Set(H.ICON_NAMES);function se({title:E,description:u,onConfirm:S,onCancel:f,confirmLabel:k,cancelLabel:A,color:j="error",icon:c="Danger",align:P="start",open:v,onOpenChange:d,disabled:$=!1,width:w=300,className:D,style:M,children:b}){const z=Q.useT(),p=n.useId(),N=`${p}-panel`,g=`${p}-title`,h=`${p}-desc`,m=n.useRef(null),I=n.useRef(null),[i,_]=n.useState(!1),q=v!==void 0,[O,T]=n.useState(!1),o=q?v:O,B=e=>{q||T(e),d==null||d(e)};n.useEffect(()=>{if(!o)return;const e=requestAnimationFrame(()=>{var s;return(s=I.current)==null?void 0:s.focus()});return()=>cancelAnimationFrame(e)},[o]);const x=e=>{var s;B(!1),e&&((s=m.current)==null||s.focus())},y=(e=!0)=>{i||(f==null||f(),x(e))},C=async()=>{const e=S();if(!e||typeof e.then!="function"){x(!0);return}_(!0);try{await e,_(!1),x(!0)}catch{_(!1)}},l=b.props,a=l.ref,L=n.cloneElement(b,{ref:e=>{m.current=e,typeof a=="function"?a(e):a&&(a.current=e)},onClick:e=>{var s;(s=l.onClick)==null||s.call(l,e),!($||i)&&(o?y(!1):B(!0))},"aria-haspopup":"dialog","aria-expanded":o,"aria-controls":o?N:void 0}),F=c===!1?null:typeof c=="string"&&te.has(c)?t.jsx(K.Icon,{name:c}):c;return t.jsxs(t.Fragment,{children:[L,t.jsxs(J.FloatingPanel,{open:o,triggerRef:m,align:P,onClose:e=>y(e),id:N,role:"alertdialog",ariaLabelledBy:g,ariaDescribedBy:u!=null?h:void 0,trapFocus:!0,width:w,className:G.clsx(r.popconfirm,D),style:{"--tz-btn-rgb":`var(--tz-color-${j}-rgb)`,...M},children:[t.jsxs("div",{className:r.body,children:[F!=null&&t.jsx("span",{className:r.icon,"aria-hidden":"true",children:F}),t.jsxs("div",{className:r.text,children:[t.jsx("div",{id:g,className:r.title,children:E}),u!=null&&t.jsx("div",{id:h,className:r.description,children:u})]})]}),t.jsxs("div",{className:r.footer,children:[t.jsx(R.Button,{ref:I,variant:"text",size:"sm",onClick:()=>y(),disabled:i,children:A??z("common.cancel")}),t.jsx(R.Button,{variant:"contained",color:j,size:"sm",loading:i,onClick:C,children:k??z("common.confirm")})]})]})]})}exports.Popconfirm=se;
2
+ //# sourceMappingURL=Popconfirm-bEoOPmZY.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popconfirm-DS6tCxV0.cjs","sources":["../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Button } from '../Button'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport type { PopoverAlign } from '../Popover'\nimport styles from './Popconfirm.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface PopconfirmProps {\n /** The question — \"Delete this item?\". Labels the dialog. */\n title: ReactNode\n /** Optional muted line under the title (the consequence). Describes the dialog. */\n description?: ReactNode\n /**\n * Runs on confirm. Return a Promise to keep the popover open with the confirm button **loading** until\n * it settles — it closes on success and **stays open on rejection** (show your own toast).\n */\n // `unknown` (not `void | Promise`) so `() => toast.success(…)` — which returns an id — still fits\n onConfirm: () => unknown\n /** Runs on Cancel, `Escape` or an outside click. */\n onCancel?: () => void\n /** Confirm button label. Defaults to the localized \"Confirm\". */\n confirmLabel?: ReactNode\n /** Cancel button label. Defaults to the localized \"Cancel\". */\n cancelLabel?: ReactNode\n /** Tints the confirm button and the icon. Defaults to `error` (a destructive action). */\n color?: ThemeColor\n /** Leading icon — a known `IconName`, any node, or `false`. Defaults to `Danger` in the `color`. */\n icon?: IconName | ReactNode | false\n /** Horizontal alignment to the trigger (`start` default, `end` for a trigger near the right edge). */\n align?: PopoverAlign\n /** Controlled open state. */\n open?: boolean\n /** Fires with the next open state. */\n onOpenChange?: (open: boolean) => void\n /** Clicking the trigger does nothing (no popover). */\n disabled?: boolean\n /** Panel width (px number or CSS width). Defaults to `300px`. */\n width?: number | string\n /** Class on the floating panel. */\n className?: string\n /** Style on the floating panel. */\n style?: CSSProperties\n /** The trigger — usually a `Button` / `IconButton`. Cloned to wire the click + ARIA. */\n children: ReactElement\n}\n\n/**\n * An **inline confirm** for quick, low-risk actions (a row's delete / archive) — a small anchored popover\n * with a question, an optional description and **Cancel** / **Confirm**, where a `RemoveDialog` modal\n * would be too heavy and a bare `onClick` too dangerous. Wraps its trigger (`children`), which it clones\n * to toggle the panel. Built on the shared `FloatingPanel` (portaled, flips, clamps to the viewport,\n * dismisses on outside click / `Escape` = cancel). A11y: `role=\"alertdialog\"` labelled by the title and\n * described by the description, focus trapped and **placed on Cancel** (never the destructive button —\n * the `RemoveDialog` rule), focus returns to the trigger. An async `onConfirm` shows a loading confirm\n * button (Cancel + dismiss locked meanwhile), closes on success, stays open on failure. The icon sits in a\n * tinted box, the buttons (`sm`; confirm `contained` in `color`, default `error`) in a Card-style footer. Use `RemoveDialog` for high-risk, context-heavy deletes.\n */\nexport function Popconfirm({\n title,\n description,\n onConfirm,\n onCancel,\n confirmLabel,\n cancelLabel,\n color = 'error',\n icon = 'Danger',\n align = 'start',\n open,\n onOpenChange,\n disabled = false,\n width = 300,\n className,\n style,\n children,\n}: PopconfirmProps) {\n const t = useT()\n const id = useId()\n const panelId = `${id}-panel`\n const titleId = `${id}-title`\n const descId = `${id}-desc`\n const triggerRef = useRef<HTMLElement | null>(null)\n const cancelRef = useRef<HTMLButtonElement | null>(null)\n const [busy, setBusy] = useState(false)\n\n const isControlled = open !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlled ? open : internalOpen\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next)\n onOpenChange?.(next)\n }\n\n // focus Cancel once the panel is positioned + visible (a hidden element can't take focus)\n useEffect(() => {\n if (!isOpen) return\n const raf = requestAnimationFrame(() => cancelRef.current?.focus())\n return () => cancelAnimationFrame(raf)\n }, [isOpen])\n\n const close = (refocus: boolean) => {\n setOpen(false)\n if (refocus) triggerRef.current?.focus()\n }\n\n const cancel = (refocus = true) => {\n if (busy) return\n onCancel?.()\n close(refocus)\n }\n\n const confirm = async () => {\n const result = onConfirm()\n // any thenable counts as async (not just native Promises)\n if (!result || typeof (result as PromiseLike<unknown>).then !== 'function') {\n close(true)\n return\n }\n setBusy(true)\n try {\n await result\n setBusy(false)\n close(true)\n } catch {\n // stays open so the user can retry or cancel; surfacing the error (a toast) is the consumer's job\n setBusy(false)\n }\n }\n\n const triggerProps = children.props as {\n onClick?: (event: ReactMouseEvent) => void\n ref?: Ref<HTMLElement>\n }\n const originalRef = triggerProps.ref\n const trigger = cloneElement(children as ReactElement<Record<string, unknown>>, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node\n if (typeof originalRef === 'function') originalRef(node)\n else if (originalRef) (originalRef as { current: HTMLElement | null }).current = node\n },\n onClick: (event: ReactMouseEvent) => {\n triggerProps.onClick?.(event)\n if (disabled || busy) return\n if (isOpen) cancel(false)\n else setOpen(true)\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? panelId : undefined,\n })\n\n const renderedIcon =\n icon === false ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <>\n {trigger}\n <FloatingPanel\n open={isOpen}\n triggerRef={triggerRef}\n align={align}\n onClose={(refocus) => cancel(refocus)}\n id={panelId}\n role=\"alertdialog\"\n ariaLabelledBy={titleId}\n ariaDescribedBy={description != null ? descId : undefined}\n trapFocus\n width={width}\n className={clsx(styles.popconfirm, className)}\n style={{ '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`, ...style } as CSSProperties}\n >\n <div className={styles.body}>\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden=\"true\">\n {renderedIcon}\n </span>\n )}\n <div className={styles.text}>\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n {description != null && (\n <div id={descId} className={styles.description}>\n {description}\n </div>\n )}\n </div>\n </div>\n <div className={styles.footer}>\n <Button ref={cancelRef} variant=\"text\" size=\"sm\" onClick={() => cancel()} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button variant=\"contained\" color={color} size=\"sm\" loading={busy} onClick={confirm}>\n {confirmLabel ?? t('common.confirm')}\n </Button>\n </div>\n </FloatingPanel>\n </>\n )\n}\n"],"names":["ICON_NAME_SET","ICON_NAMES","Popconfirm","title","description","onConfirm","onCancel","confirmLabel","cancelLabel","color","icon","align","open","onOpenChange","disabled","width","className","style","children","t","useT","id","useId","panelId","titleId","descId","triggerRef","useRef","cancelRef","busy","setBusy","useState","isControlled","internalOpen","setInternalOpen","isOpen","setOpen","next","useEffect","raf","_a","close","refocus","cancel","confirm","result","triggerProps","originalRef","trigger","cloneElement","node","event","renderedIcon","jsx","Icon","jsxs","Fragment","FloatingPanel","clsx","styles","Button"],"mappings":"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"}
1
+ {"version":3,"file":"Popconfirm-bEoOPmZY.cjs","sources":["../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Button } from '../Button'\nimport { FloatingPanel } from '../FloatingPanel/FloatingPanel'\nimport { Icon } from '../Icon'\nimport type { PopoverAlign } from '../Popover'\nimport styles from './Popconfirm.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface PopconfirmProps {\n /** The question — \"Delete this item?\". Labels the dialog. */\n title: ReactNode\n /** Optional muted line under the title (the consequence). Describes the dialog. */\n description?: ReactNode\n /**\n * Runs on confirm. Return a Promise to keep the popover open with the confirm button **loading** until\n * it settles — it closes on success and **stays open on rejection** (show your own toast).\n */\n // `unknown` (not `void | Promise`) so `() => toast.success(…)` — which returns an id — still fits\n onConfirm: () => unknown\n /** Runs on Cancel, `Escape` or an outside click. */\n onCancel?: () => void\n /** Confirm button label. Defaults to the localized \"Confirm\". */\n confirmLabel?: ReactNode\n /** Cancel button label. Defaults to the localized \"Cancel\". */\n cancelLabel?: ReactNode\n /** Tints the confirm button and the icon. Defaults to `error` (a destructive action). */\n color?: ThemeColor\n /** Leading icon — a known `IconName`, any node, or `false`. Defaults to `Danger` in the `color`. */\n icon?: IconName | ReactNode | false\n /** Horizontal alignment to the trigger (`start` default, `end` for a trigger near the right edge). */\n align?: PopoverAlign\n /** Controlled open state. */\n open?: boolean\n /** Fires with the next open state. */\n onOpenChange?: (open: boolean) => void\n /** Clicking the trigger does nothing (no popover). */\n disabled?: boolean\n /** Panel width (px number or CSS width). Defaults to `300px`. */\n width?: number | string\n /** Class on the floating panel. */\n className?: string\n /** Style on the floating panel. */\n style?: CSSProperties\n /** The trigger — usually a `Button` / `IconButton`. Cloned to wire the click + ARIA. */\n children: ReactElement\n}\n\n/**\n * An **inline confirm** for quick, low-risk actions (a row's delete / archive) — a small anchored popover\n * with a question, an optional description and **Cancel** / **Confirm**, where a `RemoveDialog` modal\n * would be too heavy and a bare `onClick` too dangerous. Wraps its trigger (`children`), which it clones\n * to toggle the panel. Built on the shared `FloatingPanel` (portaled, flips, clamps to the viewport,\n * dismisses on outside click / `Escape` = cancel). A11y: `role=\"alertdialog\"` labelled by the title and\n * described by the description, focus trapped and **placed on Cancel** (never the destructive button —\n * the `RemoveDialog` rule), focus returns to the trigger. An async `onConfirm` shows a loading confirm\n * button (Cancel + dismiss locked meanwhile), closes on success, stays open on failure. The icon sits in a\n * tinted box, the buttons (`sm`; confirm `contained` in `color`, default `error`) in a Card-style footer. Use `RemoveDialog` for high-risk, context-heavy deletes.\n */\nexport function Popconfirm({\n title,\n description,\n onConfirm,\n onCancel,\n confirmLabel,\n cancelLabel,\n color = 'error',\n icon = 'Danger',\n align = 'start',\n open,\n onOpenChange,\n disabled = false,\n width = 300,\n className,\n style,\n children,\n}: PopconfirmProps) {\n const t = useT()\n const id = useId()\n const panelId = `${id}-panel`\n const titleId = `${id}-title`\n const descId = `${id}-desc`\n const triggerRef = useRef<HTMLElement | null>(null)\n const cancelRef = useRef<HTMLButtonElement | null>(null)\n const [busy, setBusy] = useState(false)\n\n const isControlled = open !== undefined\n const [internalOpen, setInternalOpen] = useState(false)\n const isOpen = isControlled ? open : internalOpen\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next)\n onOpenChange?.(next)\n }\n\n // focus Cancel once the panel is positioned + visible (a hidden element can't take focus)\n useEffect(() => {\n if (!isOpen) return\n const raf = requestAnimationFrame(() => cancelRef.current?.focus())\n return () => cancelAnimationFrame(raf)\n }, [isOpen])\n\n const close = (refocus: boolean) => {\n setOpen(false)\n if (refocus) triggerRef.current?.focus()\n }\n\n const cancel = (refocus = true) => {\n if (busy) return\n onCancel?.()\n close(refocus)\n }\n\n const confirm = async () => {\n const result = onConfirm()\n // any thenable counts as async (not just native Promises)\n if (!result || typeof (result as PromiseLike<unknown>).then !== 'function') {\n close(true)\n return\n }\n setBusy(true)\n try {\n await result\n setBusy(false)\n close(true)\n } catch {\n // stays open so the user can retry or cancel; surfacing the error (a toast) is the consumer's job\n setBusy(false)\n }\n }\n\n const triggerProps = children.props as {\n onClick?: (event: ReactMouseEvent) => void\n ref?: Ref<HTMLElement>\n }\n const originalRef = triggerProps.ref\n const trigger = cloneElement(children as ReactElement<Record<string, unknown>>, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node\n if (typeof originalRef === 'function') originalRef(node)\n else if (originalRef) (originalRef as { current: HTMLElement | null }).current = node\n },\n onClick: (event: ReactMouseEvent) => {\n triggerProps.onClick?.(event)\n if (disabled || busy) return\n if (isOpen) cancel(false)\n else setOpen(true)\n },\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? panelId : undefined,\n })\n\n const renderedIcon =\n icon === false ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <>\n {trigger}\n <FloatingPanel\n open={isOpen}\n triggerRef={triggerRef}\n align={align}\n onClose={(refocus) => cancel(refocus)}\n id={panelId}\n role=\"alertdialog\"\n ariaLabelledBy={titleId}\n ariaDescribedBy={description != null ? descId : undefined}\n trapFocus\n width={width}\n className={clsx(styles.popconfirm, className)}\n style={{ '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`, ...style } as CSSProperties}\n >\n <div className={styles.body}>\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden=\"true\">\n {renderedIcon}\n </span>\n )}\n <div className={styles.text}>\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n {description != null && (\n <div id={descId} className={styles.description}>\n {description}\n </div>\n )}\n </div>\n </div>\n <div className={styles.footer}>\n <Button ref={cancelRef} variant=\"text\" size=\"sm\" onClick={() => cancel()} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button variant=\"contained\" color={color} size=\"sm\" loading={busy} onClick={confirm}>\n {confirmLabel ?? t('common.confirm')}\n </Button>\n </div>\n </FloatingPanel>\n </>\n )\n}\n"],"names":["ICON_NAME_SET","ICON_NAMES","Popconfirm","title","description","onConfirm","onCancel","confirmLabel","cancelLabel","color","icon","align","open","onOpenChange","disabled","width","className","style","children","t","useT","id","useId","panelId","titleId","descId","triggerRef","useRef","cancelRef","busy","setBusy","useState","isControlled","internalOpen","setInternalOpen","isOpen","setOpen","next","useEffect","raf","_a","close","refocus","cancel","confirm","result","triggerProps","originalRef","trigger","cloneElement","node","event","renderedIcon","jsx","Icon","jsxs","Fragment","FloatingPanel","clsx","styles","Button"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsxs as s, jsx as a } from "react/jsx-runtime";
2
2
  import { forwardRef as I, useId as L } from "react";
3
3
  import { clsx as l } from "clsx";
4
- import { a as B } from "./ConfigProvider-D2svpXFu.js";
4
+ import { a as B } from "./ConfigProvider-tvLbKiqu.js";
5
5
  const C = "_root_1uzzo_4", D = "_caption_1uzzo_11", R = "_value_1uzzo_16", S = "_linear_1uzzo_23", q = "_sm_1uzzo_28", A = "_md_1uzzo_31", E = "_lg_1uzzo_34", G = "_header_1uzzo_38", H = "_track_1uzzo_45", J = "_buffer_1uzzo_52", K = "_fill_1uzzo_53", O = "_striped_1uzzo_69", Q = "_animated_1uzzo_82", U = "_indeterminate_1uzzo_95", W = "_circular_1uzzo_109", X = "_ring_1uzzo_128", Y = "_svg_1uzzo_136", Z = "_ringTrack_1uzzo_144", nn = "_ringFill_1uzzo_145", rn = "_ringValue_1uzzo_159", an = "_spinning_1uzzo_165", n = {
6
6
  root: C,
7
7
  caption: D,
@@ -116,4 +116,4 @@ const C = "_root_1uzzo_4", D = "_caption_1uzzo_11", R = "_value_1uzzo_16", S = "
116
116
  export {
117
117
  sn as P
118
118
  };
119
- //# sourceMappingURL=Progress-DZUtn3Sh.js.map
119
+ //# sourceMappingURL=Progress-BxvqmmGS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Progress-DZUtn3Sh.js","sources":["../src/components/Progress/Progress.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Progress.module.css'\n\nexport type ProgressVariant = 'linear' | 'circular'\nexport type ProgressSize = 'sm' | 'md' | 'lg'\n\n/** Percentages (0–100) at which the color switches automatically — quota UX. */\nexport interface ProgressThresholds {\n /** From this percentage on, the bar turns `warning`. */\n warning?: number\n /** From this percentage on, the bar turns `error`. */\n error?: number\n}\n\nexport interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {\n /** Current value, `0`–`max`. Omit it for an **indeterminate** progress (a moving bar / spinning arc). */\n value?: number\n /** The value that means \"done\". Defaults to `100`. */\n max?: number\n /** `linear` (default) — a bar; `circular` — a ring. */\n variant?: ProgressVariant\n /** Linear: bar thickness 4 / 6 / 8 px. Circular: ring 32 / 48 / 64 px. Defaults to `md`. */\n size?: ProgressSize\n /** Theme color of the fill. Defaults to `accent`. */\n color?: ThemeColor\n /** A caption — above the bar (left) for linear, under the ring for circular. Labels the progressbar. */\n label?: ReactNode\n /**\n * Show the value: `true` → the percentage (\"42%\"); a function → your own text, e.g.\n * `(v, max) => `${v} GB of ${max} GB``. Linear: right of the caption; circular: inside the ring.\n */\n showValue?: boolean | ((value: number, max: number) => ReactNode)\n /** A second, lighter bar behind the fill (buffered / pending amount), `0`–`max`. Linear only. */\n buffer?: number\n /** Diagonal stripes on the fill. Linear only. */\n striped?: boolean\n /** Animate the stripes (implies `striped`). Linear only. Off under `prefers-reduced-motion`. */\n animated?: boolean\n /** Switch the color automatically by percentage (e.g. `{ warning: 80, error: 95 }` for a quota). */\n thresholds?: ProgressThresholds\n}\n\nconst clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n))\n\n/**\n * A progress indicator — **linear** (a bar) or **circular** (a ring) — for uploads, wizard steps, quotas and\n * background jobs. Determinate with `value` / `max`, or **indeterminate** without `value` (a moving bar / a\n * spinning arc). An optional caption (`label`) and value readout (`showValue` — the percentage or your own\n * formatter), a lighter `buffer` bar, `striped` / `animated` fills, and `thresholds` that turn the fill\n * `warning` / `error` as it fills up. Tinted by `color` through the shared `--tz-btn-rgb` pattern; the track is\n * `primary-shade200`, the bar is pill-rounded (so the global `square` shape flattens it). A11y:\n * `role=\"progressbar\"` with `aria-valuemin/max/now` + `aria-valuetext`, labelled by the caption (or a\n * localized \"Progress\"); indeterminate drops `aria-valuenow` and sets `aria-busy`. Motion stops under\n * `prefers-reduced-motion`. Token-only. `forwardRef` to the root `<div>`.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(function Progress(\n {\n value,\n max = 100,\n variant = 'linear',\n size = 'md',\n color = 'accent',\n label,\n showValue = false,\n buffer,\n striped = false,\n animated = false,\n thresholds,\n className,\n style,\n ...props\n },\n ref,\n) {\n const t = useT()\n const labelId = useId()\n const indeterminate = value == null\n const safeMax = max > 0 ? max : 100\n const current = indeterminate ? 0 : clamp(value, 0, safeMax)\n const pct = (current / safeMax) * 100\n const bufferPct = buffer == null ? undefined : (clamp(buffer, 0, safeMax) / safeMax) * 100\n\n // quota UX: the fill turns warning / error as it crosses the thresholds (error wins)\n const resolvedColor: ThemeColor =\n !indeterminate && thresholds?.error != null && pct >= thresholds.error\n ? 'error'\n : !indeterminate && thresholds?.warning != null && pct >= thresholds.warning\n ? 'warning'\n : color\n\n const valueText = indeterminate\n ? undefined\n : typeof showValue === 'function'\n ? showValue(current, safeMax)\n : showValue\n ? `${Math.round(pct)}%`\n : undefined\n const ariaValueText = indeterminate\n ? t('common.loading')\n : typeof valueText === 'string'\n ? valueText\n : `${Math.round(pct)}%`\n\n const a11y = {\n role: 'progressbar',\n 'aria-valuemin': 0,\n 'aria-valuemax': safeMax,\n 'aria-valuenow': indeterminate ? undefined : current,\n 'aria-valuetext': ariaValueText,\n 'aria-busy': indeterminate || undefined,\n ...(label != null ? { 'aria-labelledby': labelId } : { 'aria-label': t('progress.label') }),\n } as const\n\n const rootStyle = {\n '--tz-btn-rgb': `var(--tz-color-${resolvedColor}-rgb)`,\n ...style,\n } as CSSProperties\n\n if (variant === 'circular') {\n // pathLength=100 makes the dash math a plain percentage\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.circular, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n <div className={clsx(styles.ring, indeterminate && styles.spinning)} {...a11y}>\n <svg viewBox=\"0 0 36 36\" className={styles.svg} aria-hidden=\"true\">\n <circle className={styles.ringTrack} cx=\"18\" cy=\"18\" r=\"15.5\" pathLength={100} />\n <circle\n className={styles.ringFill}\n cx=\"18\"\n cy=\"18\"\n r=\"15.5\"\n pathLength={100}\n strokeDasharray={indeterminate ? '28 72' : `${pct} ${100 - pct}`}\n />\n </svg>\n {valueText != null && <span className={styles.ringValue}>{valueText}</span>}\n </div>\n {label != null && (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n )}\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.linear, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n {(label != null || valueText != null) && (\n <div className={styles.header}>\n {label != null ? (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n ) : (\n <span />\n )}\n {valueText != null && <span className={styles.value}>{valueText}</span>}\n </div>\n )}\n <div className={clsx(styles.track, indeterminate && styles.indeterminate)} {...a11y}>\n {bufferPct != null && !indeterminate && (\n <div className={styles.buffer} style={{ width: `${bufferPct}%` }} />\n )}\n <div\n className={clsx(\n styles.fill,\n (striped || animated) && styles.striped,\n animated && styles.animated,\n )}\n style={indeterminate ? undefined : { width: `${pct}%` }}\n />\n </div>\n </div>\n )\n})\n"],"names":["clamp","n","lo","hi","Progress","forwardRef","value","max","variant","size","color","label","showValue","buffer","striped","animated","thresholds","className","style","props","ref","t","useT","labelId","useId","indeterminate","safeMax","current","pct","bufferPct","resolvedColor","valueText","ariaValueText","a11y","rootStyle","jsxs","clsx","styles","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Progress-BxvqmmGS.js","sources":["../src/components/Progress/Progress.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Progress.module.css'\n\nexport type ProgressVariant = 'linear' | 'circular'\nexport type ProgressSize = 'sm' | 'md' | 'lg'\n\n/** Percentages (0–100) at which the color switches automatically — quota UX. */\nexport interface ProgressThresholds {\n /** From this percentage on, the bar turns `warning`. */\n warning?: number\n /** From this percentage on, the bar turns `error`. */\n error?: number\n}\n\nexport interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {\n /** Current value, `0`–`max`. Omit it for an **indeterminate** progress (a moving bar / spinning arc). */\n value?: number\n /** The value that means \"done\". Defaults to `100`. */\n max?: number\n /** `linear` (default) — a bar; `circular` — a ring. */\n variant?: ProgressVariant\n /** Linear: bar thickness 4 / 6 / 8 px. Circular: ring 32 / 48 / 64 px. Defaults to `md`. */\n size?: ProgressSize\n /** Theme color of the fill. Defaults to `accent`. */\n color?: ThemeColor\n /** A caption — above the bar (left) for linear, under the ring for circular. Labels the progressbar. */\n label?: ReactNode\n /**\n * Show the value: `true` → the percentage (\"42%\"); a function → your own text, e.g.\n * `(v, max) => `${v} GB of ${max} GB``. Linear: right of the caption; circular: inside the ring.\n */\n showValue?: boolean | ((value: number, max: number) => ReactNode)\n /** A second, lighter bar behind the fill (buffered / pending amount), `0`–`max`. Linear only. */\n buffer?: number\n /** Diagonal stripes on the fill. Linear only. */\n striped?: boolean\n /** Animate the stripes (implies `striped`). Linear only. Off under `prefers-reduced-motion`. */\n animated?: boolean\n /** Switch the color automatically by percentage (e.g. `{ warning: 80, error: 95 }` for a quota). */\n thresholds?: ProgressThresholds\n}\n\nconst clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n))\n\n/**\n * A progress indicator — **linear** (a bar) or **circular** (a ring) — for uploads, wizard steps, quotas and\n * background jobs. Determinate with `value` / `max`, or **indeterminate** without `value` (a moving bar / a\n * spinning arc). An optional caption (`label`) and value readout (`showValue` — the percentage or your own\n * formatter), a lighter `buffer` bar, `striped` / `animated` fills, and `thresholds` that turn the fill\n * `warning` / `error` as it fills up. Tinted by `color` through the shared `--tz-btn-rgb` pattern; the track is\n * `primary-shade200`, the bar is pill-rounded (so the global `square` shape flattens it). A11y:\n * `role=\"progressbar\"` with `aria-valuemin/max/now` + `aria-valuetext`, labelled by the caption (or a\n * localized \"Progress\"); indeterminate drops `aria-valuenow` and sets `aria-busy`. Motion stops under\n * `prefers-reduced-motion`. Token-only. `forwardRef` to the root `<div>`.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(function Progress(\n {\n value,\n max = 100,\n variant = 'linear',\n size = 'md',\n color = 'accent',\n label,\n showValue = false,\n buffer,\n striped = false,\n animated = false,\n thresholds,\n className,\n style,\n ...props\n },\n ref,\n) {\n const t = useT()\n const labelId = useId()\n const indeterminate = value == null\n const safeMax = max > 0 ? max : 100\n const current = indeterminate ? 0 : clamp(value, 0, safeMax)\n const pct = (current / safeMax) * 100\n const bufferPct = buffer == null ? undefined : (clamp(buffer, 0, safeMax) / safeMax) * 100\n\n // quota UX: the fill turns warning / error as it crosses the thresholds (error wins)\n const resolvedColor: ThemeColor =\n !indeterminate && thresholds?.error != null && pct >= thresholds.error\n ? 'error'\n : !indeterminate && thresholds?.warning != null && pct >= thresholds.warning\n ? 'warning'\n : color\n\n const valueText = indeterminate\n ? undefined\n : typeof showValue === 'function'\n ? showValue(current, safeMax)\n : showValue\n ? `${Math.round(pct)}%`\n : undefined\n const ariaValueText = indeterminate\n ? t('common.loading')\n : typeof valueText === 'string'\n ? valueText\n : `${Math.round(pct)}%`\n\n const a11y = {\n role: 'progressbar',\n 'aria-valuemin': 0,\n 'aria-valuemax': safeMax,\n 'aria-valuenow': indeterminate ? undefined : current,\n 'aria-valuetext': ariaValueText,\n 'aria-busy': indeterminate || undefined,\n ...(label != null ? { 'aria-labelledby': labelId } : { 'aria-label': t('progress.label') }),\n } as const\n\n const rootStyle = {\n '--tz-btn-rgb': `var(--tz-color-${resolvedColor}-rgb)`,\n ...style,\n } as CSSProperties\n\n if (variant === 'circular') {\n // pathLength=100 makes the dash math a plain percentage\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.circular, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n <div className={clsx(styles.ring, indeterminate && styles.spinning)} {...a11y}>\n <svg viewBox=\"0 0 36 36\" className={styles.svg} aria-hidden=\"true\">\n <circle className={styles.ringTrack} cx=\"18\" cy=\"18\" r=\"15.5\" pathLength={100} />\n <circle\n className={styles.ringFill}\n cx=\"18\"\n cy=\"18\"\n r=\"15.5\"\n pathLength={100}\n strokeDasharray={indeterminate ? '28 72' : `${pct} ${100 - pct}`}\n />\n </svg>\n {valueText != null && <span className={styles.ringValue}>{valueText}</span>}\n </div>\n {label != null && (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n )}\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.linear, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n {(label != null || valueText != null) && (\n <div className={styles.header}>\n {label != null ? (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n ) : (\n <span />\n )}\n {valueText != null && <span className={styles.value}>{valueText}</span>}\n </div>\n )}\n <div className={clsx(styles.track, indeterminate && styles.indeterminate)} {...a11y}>\n {bufferPct != null && !indeterminate && (\n <div className={styles.buffer} style={{ width: `${bufferPct}%` }} />\n )}\n <div\n className={clsx(\n styles.fill,\n (striped || animated) && styles.striped,\n animated && styles.animated,\n )}\n style={indeterminate ? undefined : { width: `${pct}%` }}\n />\n </div>\n </div>\n )\n})\n"],"names":["clamp","n","lo","hi","Progress","forwardRef","value","max","variant","size","color","label","showValue","buffer","striped","animated","thresholds","className","style","props","ref","t","useT","labelId","useId","indeterminate","safeMax","current","pct","bufferPct","resolvedColor","valueText","ariaValueText","a11y","rootStyle","jsxs","clsx","styles","jsx"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";const r=require("react/jsx-runtime"),w=require("react"),o=require("clsx"),h=require("./ConfigProvider-CzAQf_d_.cjs"),C="_root_1uzzo_4",I="_caption_1uzzo_11",L="_value_1uzzo_16",R="_linear_1uzzo_23",B="_sm_1uzzo_28",D="_md_1uzzo_31",S="_lg_1uzzo_34",A="_header_1uzzo_38",E="_track_1uzzo_45",G="_buffer_1uzzo_52",H="_fill_1uzzo_53",J="_striped_1uzzo_69",K="_animated_1uzzo_82",O="_indeterminate_1uzzo_95",Q="_circular_1uzzo_109",U="_ring_1uzzo_128",W="_svg_1uzzo_136",X="_ringTrack_1uzzo_144",Y="_ringFill_1uzzo_145",Z="_ringValue_1uzzo_159",nn="_spinning_1uzzo_165",n={root:C,caption:I,value:L,linear:R,sm:B,md:D,lg:S,header:A,track:E,buffer:G,fill:H,striped:J,animated:K,"pg-stripes":"_pg-stripes_1uzzo_1",indeterminate:O,"pg-sweep":"_pg-sweep_1uzzo_1",circular:Q,ring:U,svg:W,ringTrack:X,ringFill:Y,ringValue:Z,spinning:nn,"pg-spin":"_pg-spin_1uzzo_1"},T=(d,l,u)=>Math.min(u,Math.max(l,d)),rn=w.forwardRef(function({value:l,max:u=100,variant:$="linear",size:p="md",color:M="accent",label:c,showValue:_=!1,buffer:m,striped:P=!1,animated:v=!1,thresholds:i,className:x,style:q,...f},j){const y=h.useT(),g=w.useId(),s=l==null,t=u>0?u:100,z=s?0:T(l,0,t),a=z/t*100,N=m==null?void 0:T(m,0,t)/t*100,F=!s&&(i==null?void 0:i.error)!=null&&a>=i.error?"error":!s&&(i==null?void 0:i.warning)!=null&&a>=i.warning?"warning":M,e=s?void 0:typeof _=="function"?_(z,t):_?`${Math.round(a)}%`:void 0,V=s?y("common.loading"):typeof e=="string"?e:`${Math.round(a)}%`,b={role:"progressbar","aria-valuemin":0,"aria-valuemax":t,"aria-valuenow":s?void 0:z,"aria-valuetext":V,"aria-busy":s||void 0,...c!=null?{"aria-labelledby":g}:{"aria-label":y("progress.label")}},k={"--tz-btn-rgb":`var(--tz-color-${F}-rgb)`,...q};return $==="circular"?r.jsxs("div",{ref:j,className:o.clsx(n.root,n.circular,n[p],x),style:k,...f,children:[r.jsxs("div",{className:o.clsx(n.ring,s&&n.spinning),...b,children:[r.jsxs("svg",{viewBox:"0 0 36 36",className:n.svg,"aria-hidden":"true",children:[r.jsx("circle",{className:n.ringTrack,cx:"18",cy:"18",r:"15.5",pathLength:100}),r.jsx("circle",{className:n.ringFill,cx:"18",cy:"18",r:"15.5",pathLength:100,strokeDasharray:s?"28 72":`${a} ${100-a}`})]}),e!=null&&r.jsx("span",{className:n.ringValue,children:e})]}),c!=null&&r.jsx("span",{id:g,className:n.caption,children:c})]}):r.jsxs("div",{ref:j,className:o.clsx(n.root,n.linear,n[p],x),style:k,...f,children:[(c!=null||e!=null)&&r.jsxs("div",{className:n.header,children:[c!=null?r.jsx("span",{id:g,className:n.caption,children:c}):r.jsx("span",{}),e!=null&&r.jsx("span",{className:n.value,children:e})]}),r.jsxs("div",{className:o.clsx(n.track,s&&n.indeterminate),...b,children:[N!=null&&!s&&r.jsx("div",{className:n.buffer,style:{width:`${N}%`}}),r.jsx("div",{className:o.clsx(n.fill,(P||v)&&n.striped,v&&n.animated),style:s?void 0:{width:`${a}%`}})]})]})});exports.Progress=rn;
2
- //# sourceMappingURL=Progress-lf9vIKIk.cjs.map
1
+ "use strict";const r=require("react/jsx-runtime"),w=require("react"),o=require("clsx"),h=require("./ConfigProvider-CVLHPXQm.cjs"),C="_root_1uzzo_4",I="_caption_1uzzo_11",L="_value_1uzzo_16",R="_linear_1uzzo_23",B="_sm_1uzzo_28",D="_md_1uzzo_31",S="_lg_1uzzo_34",A="_header_1uzzo_38",E="_track_1uzzo_45",G="_buffer_1uzzo_52",H="_fill_1uzzo_53",J="_striped_1uzzo_69",K="_animated_1uzzo_82",O="_indeterminate_1uzzo_95",Q="_circular_1uzzo_109",U="_ring_1uzzo_128",W="_svg_1uzzo_136",X="_ringTrack_1uzzo_144",Y="_ringFill_1uzzo_145",Z="_ringValue_1uzzo_159",nn="_spinning_1uzzo_165",n={root:C,caption:I,value:L,linear:R,sm:B,md:D,lg:S,header:A,track:E,buffer:G,fill:H,striped:J,animated:K,"pg-stripes":"_pg-stripes_1uzzo_1",indeterminate:O,"pg-sweep":"_pg-sweep_1uzzo_1",circular:Q,ring:U,svg:W,ringTrack:X,ringFill:Y,ringValue:Z,spinning:nn,"pg-spin":"_pg-spin_1uzzo_1"},T=(d,l,u)=>Math.min(u,Math.max(l,d)),rn=w.forwardRef(function({value:l,max:u=100,variant:$="linear",size:p="md",color:M="accent",label:c,showValue:_=!1,buffer:m,striped:P=!1,animated:v=!1,thresholds:i,className:x,style:q,...f},j){const y=h.useT(),g=w.useId(),s=l==null,t=u>0?u:100,z=s?0:T(l,0,t),a=z/t*100,N=m==null?void 0:T(m,0,t)/t*100,F=!s&&(i==null?void 0:i.error)!=null&&a>=i.error?"error":!s&&(i==null?void 0:i.warning)!=null&&a>=i.warning?"warning":M,e=s?void 0:typeof _=="function"?_(z,t):_?`${Math.round(a)}%`:void 0,V=s?y("common.loading"):typeof e=="string"?e:`${Math.round(a)}%`,b={role:"progressbar","aria-valuemin":0,"aria-valuemax":t,"aria-valuenow":s?void 0:z,"aria-valuetext":V,"aria-busy":s||void 0,...c!=null?{"aria-labelledby":g}:{"aria-label":y("progress.label")}},k={"--tz-btn-rgb":`var(--tz-color-${F}-rgb)`,...q};return $==="circular"?r.jsxs("div",{ref:j,className:o.clsx(n.root,n.circular,n[p],x),style:k,...f,children:[r.jsxs("div",{className:o.clsx(n.ring,s&&n.spinning),...b,children:[r.jsxs("svg",{viewBox:"0 0 36 36",className:n.svg,"aria-hidden":"true",children:[r.jsx("circle",{className:n.ringTrack,cx:"18",cy:"18",r:"15.5",pathLength:100}),r.jsx("circle",{className:n.ringFill,cx:"18",cy:"18",r:"15.5",pathLength:100,strokeDasharray:s?"28 72":`${a} ${100-a}`})]}),e!=null&&r.jsx("span",{className:n.ringValue,children:e})]}),c!=null&&r.jsx("span",{id:g,className:n.caption,children:c})]}):r.jsxs("div",{ref:j,className:o.clsx(n.root,n.linear,n[p],x),style:k,...f,children:[(c!=null||e!=null)&&r.jsxs("div",{className:n.header,children:[c!=null?r.jsx("span",{id:g,className:n.caption,children:c}):r.jsx("span",{}),e!=null&&r.jsx("span",{className:n.value,children:e})]}),r.jsxs("div",{className:o.clsx(n.track,s&&n.indeterminate),...b,children:[N!=null&&!s&&r.jsx("div",{className:n.buffer,style:{width:`${N}%`}}),r.jsx("div",{className:o.clsx(n.fill,(P||v)&&n.striped,v&&n.animated),style:s?void 0:{width:`${a}%`}})]})]})});exports.Progress=rn;
2
+ //# sourceMappingURL=Progress-CqXX0rRp.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Progress-lf9vIKIk.cjs","sources":["../src/components/Progress/Progress.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Progress.module.css'\n\nexport type ProgressVariant = 'linear' | 'circular'\nexport type ProgressSize = 'sm' | 'md' | 'lg'\n\n/** Percentages (0–100) at which the color switches automatically — quota UX. */\nexport interface ProgressThresholds {\n /** From this percentage on, the bar turns `warning`. */\n warning?: number\n /** From this percentage on, the bar turns `error`. */\n error?: number\n}\n\nexport interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {\n /** Current value, `0`–`max`. Omit it for an **indeterminate** progress (a moving bar / spinning arc). */\n value?: number\n /** The value that means \"done\". Defaults to `100`. */\n max?: number\n /** `linear` (default) — a bar; `circular` — a ring. */\n variant?: ProgressVariant\n /** Linear: bar thickness 4 / 6 / 8 px. Circular: ring 32 / 48 / 64 px. Defaults to `md`. */\n size?: ProgressSize\n /** Theme color of the fill. Defaults to `accent`. */\n color?: ThemeColor\n /** A caption — above the bar (left) for linear, under the ring for circular. Labels the progressbar. */\n label?: ReactNode\n /**\n * Show the value: `true` → the percentage (\"42%\"); a function → your own text, e.g.\n * `(v, max) => `${v} GB of ${max} GB``. Linear: right of the caption; circular: inside the ring.\n */\n showValue?: boolean | ((value: number, max: number) => ReactNode)\n /** A second, lighter bar behind the fill (buffered / pending amount), `0`–`max`. Linear only. */\n buffer?: number\n /** Diagonal stripes on the fill. Linear only. */\n striped?: boolean\n /** Animate the stripes (implies `striped`). Linear only. Off under `prefers-reduced-motion`. */\n animated?: boolean\n /** Switch the color automatically by percentage (e.g. `{ warning: 80, error: 95 }` for a quota). */\n thresholds?: ProgressThresholds\n}\n\nconst clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n))\n\n/**\n * A progress indicator — **linear** (a bar) or **circular** (a ring) — for uploads, wizard steps, quotas and\n * background jobs. Determinate with `value` / `max`, or **indeterminate** without `value` (a moving bar / a\n * spinning arc). An optional caption (`label`) and value readout (`showValue` — the percentage or your own\n * formatter), a lighter `buffer` bar, `striped` / `animated` fills, and `thresholds` that turn the fill\n * `warning` / `error` as it fills up. Tinted by `color` through the shared `--tz-btn-rgb` pattern; the track is\n * `primary-shade200`, the bar is pill-rounded (so the global `square` shape flattens it). A11y:\n * `role=\"progressbar\"` with `aria-valuemin/max/now` + `aria-valuetext`, labelled by the caption (or a\n * localized \"Progress\"); indeterminate drops `aria-valuenow` and sets `aria-busy`. Motion stops under\n * `prefers-reduced-motion`. Token-only. `forwardRef` to the root `<div>`.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(function Progress(\n {\n value,\n max = 100,\n variant = 'linear',\n size = 'md',\n color = 'accent',\n label,\n showValue = false,\n buffer,\n striped = false,\n animated = false,\n thresholds,\n className,\n style,\n ...props\n },\n ref,\n) {\n const t = useT()\n const labelId = useId()\n const indeterminate = value == null\n const safeMax = max > 0 ? max : 100\n const current = indeterminate ? 0 : clamp(value, 0, safeMax)\n const pct = (current / safeMax) * 100\n const bufferPct = buffer == null ? undefined : (clamp(buffer, 0, safeMax) / safeMax) * 100\n\n // quota UX: the fill turns warning / error as it crosses the thresholds (error wins)\n const resolvedColor: ThemeColor =\n !indeterminate && thresholds?.error != null && pct >= thresholds.error\n ? 'error'\n : !indeterminate && thresholds?.warning != null && pct >= thresholds.warning\n ? 'warning'\n : color\n\n const valueText = indeterminate\n ? undefined\n : typeof showValue === 'function'\n ? showValue(current, safeMax)\n : showValue\n ? `${Math.round(pct)}%`\n : undefined\n const ariaValueText = indeterminate\n ? t('common.loading')\n : typeof valueText === 'string'\n ? valueText\n : `${Math.round(pct)}%`\n\n const a11y = {\n role: 'progressbar',\n 'aria-valuemin': 0,\n 'aria-valuemax': safeMax,\n 'aria-valuenow': indeterminate ? undefined : current,\n 'aria-valuetext': ariaValueText,\n 'aria-busy': indeterminate || undefined,\n ...(label != null ? { 'aria-labelledby': labelId } : { 'aria-label': t('progress.label') }),\n } as const\n\n const rootStyle = {\n '--tz-btn-rgb': `var(--tz-color-${resolvedColor}-rgb)`,\n ...style,\n } as CSSProperties\n\n if (variant === 'circular') {\n // pathLength=100 makes the dash math a plain percentage\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.circular, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n <div className={clsx(styles.ring, indeterminate && styles.spinning)} {...a11y}>\n <svg viewBox=\"0 0 36 36\" className={styles.svg} aria-hidden=\"true\">\n <circle className={styles.ringTrack} cx=\"18\" cy=\"18\" r=\"15.5\" pathLength={100} />\n <circle\n className={styles.ringFill}\n cx=\"18\"\n cy=\"18\"\n r=\"15.5\"\n pathLength={100}\n strokeDasharray={indeterminate ? '28 72' : `${pct} ${100 - pct}`}\n />\n </svg>\n {valueText != null && <span className={styles.ringValue}>{valueText}</span>}\n </div>\n {label != null && (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n )}\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.linear, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n {(label != null || valueText != null) && (\n <div className={styles.header}>\n {label != null ? (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n ) : (\n <span />\n )}\n {valueText != null && <span className={styles.value}>{valueText}</span>}\n </div>\n )}\n <div className={clsx(styles.track, indeterminate && styles.indeterminate)} {...a11y}>\n {bufferPct != null && !indeterminate && (\n <div className={styles.buffer} style={{ width: `${bufferPct}%` }} />\n )}\n <div\n className={clsx(\n styles.fill,\n (striped || animated) && styles.striped,\n animated && styles.animated,\n )}\n style={indeterminate ? undefined : { width: `${pct}%` }}\n />\n </div>\n </div>\n )\n})\n"],"names":["clamp","n","lo","hi","Progress","forwardRef","value","max","variant","size","color","label","showValue","buffer","striped","animated","thresholds","className","style","props","ref","t","useT","labelId","useId","indeterminate","safeMax","current","pct","bufferPct","resolvedColor","valueText","ariaValueText","a11y","rootStyle","jsxs","clsx","styles","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Progress-CqXX0rRp.cjs","sources":["../src/components/Progress/Progress.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Progress.module.css'\n\nexport type ProgressVariant = 'linear' | 'circular'\nexport type ProgressSize = 'sm' | 'md' | 'lg'\n\n/** Percentages (0–100) at which the color switches automatically — quota UX. */\nexport interface ProgressThresholds {\n /** From this percentage on, the bar turns `warning`. */\n warning?: number\n /** From this percentage on, the bar turns `error`. */\n error?: number\n}\n\nexport interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {\n /** Current value, `0`–`max`. Omit it for an **indeterminate** progress (a moving bar / spinning arc). */\n value?: number\n /** The value that means \"done\". Defaults to `100`. */\n max?: number\n /** `linear` (default) — a bar; `circular` — a ring. */\n variant?: ProgressVariant\n /** Linear: bar thickness 4 / 6 / 8 px. Circular: ring 32 / 48 / 64 px. Defaults to `md`. */\n size?: ProgressSize\n /** Theme color of the fill. Defaults to `accent`. */\n color?: ThemeColor\n /** A caption — above the bar (left) for linear, under the ring for circular. Labels the progressbar. */\n label?: ReactNode\n /**\n * Show the value: `true` → the percentage (\"42%\"); a function → your own text, e.g.\n * `(v, max) => `${v} GB of ${max} GB``. Linear: right of the caption; circular: inside the ring.\n */\n showValue?: boolean | ((value: number, max: number) => ReactNode)\n /** A second, lighter bar behind the fill (buffered / pending amount), `0`–`max`. Linear only. */\n buffer?: number\n /** Diagonal stripes on the fill. Linear only. */\n striped?: boolean\n /** Animate the stripes (implies `striped`). Linear only. Off under `prefers-reduced-motion`. */\n animated?: boolean\n /** Switch the color automatically by percentage (e.g. `{ warning: 80, error: 95 }` for a quota). */\n thresholds?: ProgressThresholds\n}\n\nconst clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n))\n\n/**\n * A progress indicator — **linear** (a bar) or **circular** (a ring) — for uploads, wizard steps, quotas and\n * background jobs. Determinate with `value` / `max`, or **indeterminate** without `value` (a moving bar / a\n * spinning arc). An optional caption (`label`) and value readout (`showValue` — the percentage or your own\n * formatter), a lighter `buffer` bar, `striped` / `animated` fills, and `thresholds` that turn the fill\n * `warning` / `error` as it fills up. Tinted by `color` through the shared `--tz-btn-rgb` pattern; the track is\n * `primary-shade200`, the bar is pill-rounded (so the global `square` shape flattens it). A11y:\n * `role=\"progressbar\"` with `aria-valuemin/max/now` + `aria-valuetext`, labelled by the caption (or a\n * localized \"Progress\"); indeterminate drops `aria-valuenow` and sets `aria-busy`. Motion stops under\n * `prefers-reduced-motion`. Token-only. `forwardRef` to the root `<div>`.\n */\nexport const Progress = forwardRef<HTMLDivElement, ProgressProps>(function Progress(\n {\n value,\n max = 100,\n variant = 'linear',\n size = 'md',\n color = 'accent',\n label,\n showValue = false,\n buffer,\n striped = false,\n animated = false,\n thresholds,\n className,\n style,\n ...props\n },\n ref,\n) {\n const t = useT()\n const labelId = useId()\n const indeterminate = value == null\n const safeMax = max > 0 ? max : 100\n const current = indeterminate ? 0 : clamp(value, 0, safeMax)\n const pct = (current / safeMax) * 100\n const bufferPct = buffer == null ? undefined : (clamp(buffer, 0, safeMax) / safeMax) * 100\n\n // quota UX: the fill turns warning / error as it crosses the thresholds (error wins)\n const resolvedColor: ThemeColor =\n !indeterminate && thresholds?.error != null && pct >= thresholds.error\n ? 'error'\n : !indeterminate && thresholds?.warning != null && pct >= thresholds.warning\n ? 'warning'\n : color\n\n const valueText = indeterminate\n ? undefined\n : typeof showValue === 'function'\n ? showValue(current, safeMax)\n : showValue\n ? `${Math.round(pct)}%`\n : undefined\n const ariaValueText = indeterminate\n ? t('common.loading')\n : typeof valueText === 'string'\n ? valueText\n : `${Math.round(pct)}%`\n\n const a11y = {\n role: 'progressbar',\n 'aria-valuemin': 0,\n 'aria-valuemax': safeMax,\n 'aria-valuenow': indeterminate ? undefined : current,\n 'aria-valuetext': ariaValueText,\n 'aria-busy': indeterminate || undefined,\n ...(label != null ? { 'aria-labelledby': labelId } : { 'aria-label': t('progress.label') }),\n } as const\n\n const rootStyle = {\n '--tz-btn-rgb': `var(--tz-color-${resolvedColor}-rgb)`,\n ...style,\n } as CSSProperties\n\n if (variant === 'circular') {\n // pathLength=100 makes the dash math a plain percentage\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.circular, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n <div className={clsx(styles.ring, indeterminate && styles.spinning)} {...a11y}>\n <svg viewBox=\"0 0 36 36\" className={styles.svg} aria-hidden=\"true\">\n <circle className={styles.ringTrack} cx=\"18\" cy=\"18\" r=\"15.5\" pathLength={100} />\n <circle\n className={styles.ringFill}\n cx=\"18\"\n cy=\"18\"\n r=\"15.5\"\n pathLength={100}\n strokeDasharray={indeterminate ? '28 72' : `${pct} ${100 - pct}`}\n />\n </svg>\n {valueText != null && <span className={styles.ringValue}>{valueText}</span>}\n </div>\n {label != null && (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n )}\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles.linear, styles[size], className)}\n style={rootStyle}\n {...props}\n >\n {(label != null || valueText != null) && (\n <div className={styles.header}>\n {label != null ? (\n <span id={labelId} className={styles.caption}>\n {label}\n </span>\n ) : (\n <span />\n )}\n {valueText != null && <span className={styles.value}>{valueText}</span>}\n </div>\n )}\n <div className={clsx(styles.track, indeterminate && styles.indeterminate)} {...a11y}>\n {bufferPct != null && !indeterminate && (\n <div className={styles.buffer} style={{ width: `${bufferPct}%` }} />\n )}\n <div\n className={clsx(\n styles.fill,\n (striped || animated) && styles.striped,\n animated && styles.animated,\n )}\n style={indeterminate ? undefined : { width: `${pct}%` }}\n />\n </div>\n </div>\n )\n})\n"],"names":["clamp","n","lo","hi","Progress","forwardRef","value","max","variant","size","color","label","showValue","buffer","striped","animated","thresholds","className","style","props","ref","t","useT","labelId","useId","indeterminate","safeMax","current","pct","bufferPct","resolvedColor","valueText","ariaValueText","a11y","rootStyle","jsxs","clsx","styles","jsx"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import { jsx as o, jsxs as l, Fragment as T } from "react/jsx-runtime";
2
2
  import { forwardRef as I, useState as _, useRef as R, useId as E } from "react";
3
3
  import { B as O } from "./Blockquote-Ma-2naET.js";
4
- import { B as v } from "./Button-BJ5Xd10u.js";
4
+ import { B as v } from "./Button-PBZnkRNn.js";
5
5
  import { C as S } from "./Code-DaEpXHfF.js";
6
6
  import { I as B } from "./Icon-CGQ5yGSZ.js";
7
- import { M as j } from "./Modal-DCee1a9m.js";
8
- import { T as F } from "./TextField-CInaL0FR.js";
7
+ import { M as j } from "./Modal-Do8pzyMl.js";
8
+ import { T as F } from "./TextField-LONfx4jy.js";
9
9
  import { T as L } from "./Typography-CJv5AnRP.js";
10
- import { a as k } from "./ConfigProvider-D2svpXFu.js";
10
+ import { a as k } from "./ConfigProvider-tvLbKiqu.js";
11
11
  const M = "_modalBody_1nqut_5", K = "_body_1nqut_4", P = "_iconBox_1nqut_20", A = "_confirm_1nqut_37", G = "_phrase_1nqut_45", a = {
12
12
  modalBody: M,
13
13
  body: K,
@@ -106,4 +106,4 @@ function H({ text: u }) {
106
106
  export {
107
107
  eo as R
108
108
  };
109
- //# sourceMappingURL=RemoveDialog-DaWh4xmW.js.map
109
+ //# sourceMappingURL=RemoveDialog-DH3eNUxC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RemoveDialog-DaWh4xmW.js","sources":["../src/components/RemoveDialog/RemoveDialog.tsx"],"sourcesContent":["import { forwardRef, useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport { useT } from '../../theme'\nimport { Blockquote } from '../Blockquote'\nimport { Button } from '../Button'\nimport { Code } from '../Code'\nimport { Icon } from '../Icon'\nimport { Modal } from '../Modal'\nimport { TextField } from '../TextField'\nimport { Typography } from '../Typography'\nimport styles from './RemoveDialog.module.css'\n\nexport interface RemoveDialogProps {\n /** Whether the dialog is open. */\n open: boolean\n /** Called on Cancel, the × button, backdrop, or Escape (ignored while a confirm is in flight). */\n onClose: () => void\n /**\n * The destructive action. May be async — while its promise is pending the Delete button shows a\n * loader and the dialog locks (no dismiss); on success the dialog **auto-closes**, on rejection it\n * stays open so the user can retry (surface the error yourself, e.g. a toast).\n */\n onConfirm: () => void | Promise<void>\n /** Header title. Defaults to `\"Remove\"`. */\n title?: ReactNode\n /** Body prompt shown under the icon. Defaults to `\"Are you sure you want to delete?\"`. */\n message?: ReactNode\n /** Confirm (destructive) button label. Defaults to `\"Delete\"`. */\n confirmLabel?: string\n /** Cancel button label. Defaults to `\"Cancel\"`. */\n cancelLabel?: string\n /** External loading override — combined with the internal async-confirm state. */\n loading?: boolean\n /**\n * **Type-to-confirm** for high-risk deletes: the user must type this exact text (e.g. `\"remove user\"`)\n * into a field before Delete enables. Case-sensitive; surrounding whitespace is ignored. The field is\n * focused on open, cleared on every open, and Enter confirms once it matches.\n */\n confirmText?: string\n}\n\n/**\n * A ready-made delete confirmation — a thin convenience wrapper over `Modal` for the ubiquitous\n * \"Are you sure you want to delete?\" prompt. Hardcodes the destructive flavor (a `Trash` glyph in a\n * soft error circle + an `error` Delete button); just wire `open` / `onClose` / `onConfirm`. An async\n * `onConfirm` drives the button loader and locks dismissal, then auto-closes on success. `confirmText`\n * adds **type-to-confirm**: Delete stays disabled until the user types that exact text. Built on\n * `Modal`, so it inherits the portal, scroll-lock, focus-trap, and backdrop/Escape dismissal.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <RemoveDialog open={isOpen} onClose={close} onConfirm={() => deleteItem(id)} />\n */\nexport const RemoveDialog = forwardRef<HTMLDivElement, RemoveDialogProps>(function RemoveDialog(\n {\n open,\n onClose,\n onConfirm,\n title,\n message,\n confirmLabel,\n cancelLabel,\n loading = false,\n confirmText,\n },\n ref,\n) {\n const t = useT()\n const [submitting, setSubmitting] = useState(false)\n const busy = loading || submitting\n\n // type-to-confirm — cleared every time the dialog opens (\"adjust state on prop change\", no effect)\n const [typed, setTyped] = useState('')\n const wasOpen = useRef(open)\n if (wasOpen.current !== open) {\n wasOpen.current = open\n if (open) setTyped('')\n }\n const matches = confirmText == null || typed.trim() === confirmText.trim()\n const promptId = useId()\n\n // dismissal is blocked while the confirm is running (so the delete can't be abandoned mid-flight)\n const handleClose = () => {\n if (!busy) onClose()\n }\n\n const handleConfirm = async () => {\n if (!matches || busy) return\n try {\n setSubmitting(true)\n await onConfirm()\n onClose() // auto-close on success\n } catch {\n // keep the dialog open on failure so the user can retry; the consumer surfaces the error\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <Modal\n ref={ref}\n open={open}\n onClose={handleClose}\n size=\"sm\"\n bodyClassName={styles.modalBody}\n title={title ?? t('removeDialog.title')}\n showCloseButton={!busy}\n closeOnBackdrop={!busy}\n closeOnEscape={!busy}\n footer={\n <>\n <Button variant=\"text\" size=\"sm\" onClick={handleClose} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button\n color=\"error\"\n variant=\"filled\"\n size=\"sm\"\n onClick={handleConfirm}\n loading={busy}\n disabled={!matches}\n >\n {confirmLabel ?? t('common.delete')}\n </Button>\n </>\n }\n >\n <div className={styles.body}>\n <div className={styles.iconBox} aria-hidden>\n <Icon name=\"Trash\" />\n </div>\n <Typography align=\"center\">{message ?? t('removeDialog.message')}</Typography>\n {confirmText != null && (\n <div className={styles.confirm}>\n {/* the instruction, as an error-tinted quote — it also names the field (aria-labelledby) */}\n <Blockquote id={promptId} size=\"sm\" color=\"error\">\n <TypeToConfirmLabel text={confirmText} />\n </Blockquote>\n <TextField\n aria-labelledby={promptId}\n placeholder={confirmText}\n value={typed}\n onChange={(event) => setTyped(event.target.value)}\n onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n void handleConfirm()\n }\n }}\n // a green tick once the phrase matches — the field confirms itself before Delete does\n adornment={typed && matches ? <Icon name=\"TickCircle\" color=\"success\" /> : undefined}\n adornmentPosition=\"right\"\n disabled={busy}\n size=\"sm\"\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n </div>\n )}\n </div>\n </Modal>\n )\n})\n\n/** \"Type {text} to confirm\" with the text set as inline `Code`, so the exact phrase stands out. */\nfunction TypeToConfirmLabel({ text }: { text: string }) {\n const t = useT()\n // translate with a sentinel in place of {text}, then split around it to slot the Code element in\n const SENTINEL = '\\u0000'\n const [before, after = ''] = t('removeDialog.typeToConfirm', { text: SENTINEL }).split(SENTINEL)\n return (\n <>\n {before}\n <Code size=\"sm\" color=\"error\" className={styles.phrase}>\n {text}\n </Code>\n {after}\n </>\n )\n}\n"],"names":["RemoveDialog","forwardRef","open","onClose","onConfirm","title","message","confirmLabel","cancelLabel","loading","confirmText","ref","t","useT","submitting","setSubmitting","useState","busy","typed","setTyped","wasOpen","useRef","matches","promptId","useId","handleClose","handleConfirm","jsx","Modal","styles","jsxs","Fragment","Button","Icon","Typography","Blockquote","TypeToConfirmLabel","TextField","event","text","SENTINEL","before","after","Code"],"mappings":"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"}
1
+ {"version":3,"file":"RemoveDialog-DH3eNUxC.js","sources":["../src/components/RemoveDialog/RemoveDialog.tsx"],"sourcesContent":["import { forwardRef, useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport { useT } from '../../theme'\nimport { Blockquote } from '../Blockquote'\nimport { Button } from '../Button'\nimport { Code } from '../Code'\nimport { Icon } from '../Icon'\nimport { Modal } from '../Modal'\nimport { TextField } from '../TextField'\nimport { Typography } from '../Typography'\nimport styles from './RemoveDialog.module.css'\n\nexport interface RemoveDialogProps {\n /** Whether the dialog is open. */\n open: boolean\n /** Called on Cancel, the × button, backdrop, or Escape (ignored while a confirm is in flight). */\n onClose: () => void\n /**\n * The destructive action. May be async — while its promise is pending the Delete button shows a\n * loader and the dialog locks (no dismiss); on success the dialog **auto-closes**, on rejection it\n * stays open so the user can retry (surface the error yourself, e.g. a toast).\n */\n onConfirm: () => void | Promise<void>\n /** Header title. Defaults to `\"Remove\"`. */\n title?: ReactNode\n /** Body prompt shown under the icon. Defaults to `\"Are you sure you want to delete?\"`. */\n message?: ReactNode\n /** Confirm (destructive) button label. Defaults to `\"Delete\"`. */\n confirmLabel?: string\n /** Cancel button label. Defaults to `\"Cancel\"`. */\n cancelLabel?: string\n /** External loading override — combined with the internal async-confirm state. */\n loading?: boolean\n /**\n * **Type-to-confirm** for high-risk deletes: the user must type this exact text (e.g. `\"remove user\"`)\n * into a field before Delete enables. Case-sensitive; surrounding whitespace is ignored. The field is\n * focused on open, cleared on every open, and Enter confirms once it matches.\n */\n confirmText?: string\n}\n\n/**\n * A ready-made delete confirmation — a thin convenience wrapper over `Modal` for the ubiquitous\n * \"Are you sure you want to delete?\" prompt. Hardcodes the destructive flavor (a `Trash` glyph in a\n * soft error circle + an `error` Delete button); just wire `open` / `onClose` / `onConfirm`. An async\n * `onConfirm` drives the button loader and locks dismissal, then auto-closes on success. `confirmText`\n * adds **type-to-confirm**: Delete stays disabled until the user types that exact text. Built on\n * `Modal`, so it inherits the portal, scroll-lock, focus-trap, and backdrop/Escape dismissal.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <RemoveDialog open={isOpen} onClose={close} onConfirm={() => deleteItem(id)} />\n */\nexport const RemoveDialog = forwardRef<HTMLDivElement, RemoveDialogProps>(function RemoveDialog(\n {\n open,\n onClose,\n onConfirm,\n title,\n message,\n confirmLabel,\n cancelLabel,\n loading = false,\n confirmText,\n },\n ref,\n) {\n const t = useT()\n const [submitting, setSubmitting] = useState(false)\n const busy = loading || submitting\n\n // type-to-confirm — cleared every time the dialog opens (\"adjust state on prop change\", no effect)\n const [typed, setTyped] = useState('')\n const wasOpen = useRef(open)\n if (wasOpen.current !== open) {\n wasOpen.current = open\n if (open) setTyped('')\n }\n const matches = confirmText == null || typed.trim() === confirmText.trim()\n const promptId = useId()\n\n // dismissal is blocked while the confirm is running (so the delete can't be abandoned mid-flight)\n const handleClose = () => {\n if (!busy) onClose()\n }\n\n const handleConfirm = async () => {\n if (!matches || busy) return\n try {\n setSubmitting(true)\n await onConfirm()\n onClose() // auto-close on success\n } catch {\n // keep the dialog open on failure so the user can retry; the consumer surfaces the error\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <Modal\n ref={ref}\n open={open}\n onClose={handleClose}\n size=\"sm\"\n bodyClassName={styles.modalBody}\n title={title ?? t('removeDialog.title')}\n showCloseButton={!busy}\n closeOnBackdrop={!busy}\n closeOnEscape={!busy}\n footer={\n <>\n <Button variant=\"text\" size=\"sm\" onClick={handleClose} disabled={busy}>\n {cancelLabel ?? t('common.cancel')}\n </Button>\n <Button\n color=\"error\"\n variant=\"filled\"\n size=\"sm\"\n onClick={handleConfirm}\n loading={busy}\n disabled={!matches}\n >\n {confirmLabel ?? t('common.delete')}\n </Button>\n </>\n }\n >\n <div className={styles.body}>\n <div className={styles.iconBox} aria-hidden>\n <Icon name=\"Trash\" />\n </div>\n <Typography align=\"center\">{message ?? t('removeDialog.message')}</Typography>\n {confirmText != null && (\n <div className={styles.confirm}>\n {/* the instruction, as an error-tinted quote — it also names the field (aria-labelledby) */}\n <Blockquote id={promptId} size=\"sm\" color=\"error\">\n <TypeToConfirmLabel text={confirmText} />\n </Blockquote>\n <TextField\n aria-labelledby={promptId}\n placeholder={confirmText}\n value={typed}\n onChange={(event) => setTyped(event.target.value)}\n onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n void handleConfirm()\n }\n }}\n // a green tick once the phrase matches — the field confirms itself before Delete does\n adornment={typed && matches ? <Icon name=\"TickCircle\" color=\"success\" /> : undefined}\n adornmentPosition=\"right\"\n disabled={busy}\n size=\"sm\"\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n </div>\n )}\n </div>\n </Modal>\n )\n})\n\n/** \"Type {text} to confirm\" with the text set as inline `Code`, so the exact phrase stands out. */\nfunction TypeToConfirmLabel({ text }: { text: string }) {\n const t = useT()\n // translate with a sentinel in place of {text}, then split around it to slot the Code element in\n const SENTINEL = '\\u0000'\n const [before, after = ''] = t('removeDialog.typeToConfirm', { text: SENTINEL }).split(SENTINEL)\n return (\n <>\n {before}\n <Code size=\"sm\" color=\"error\" className={styles.phrase}>\n {text}\n </Code>\n {after}\n </>\n )\n}\n"],"names":["RemoveDialog","forwardRef","open","onClose","onConfirm","title","message","confirmLabel","cancelLabel","loading","confirmText","ref","t","useT","submitting","setSubmitting","useState","busy","typed","setTyped","wasOpen","useRef","matches","promptId","useId","handleClose","handleConfirm","jsx","Modal","styles","jsxs","Fragment","Button","Icon","Typography","Blockquote","TypeToConfirmLabel","TextField","event","text","SENTINEL","before","after","Code"],"mappings":";;;;;;;;;;;;;;;;GAoDaA,KAAeC,EAA8C,SACxE;AAAA,EACE,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,aAAAC;AACF,GACAC,GACA;AACA,QAAMC,IAAIC,EAAA,GACJ,CAACC,GAAYC,CAAa,IAAIC,EAAS,EAAK,GAC5CC,IAAOR,KAAWK,GAGlB,CAACI,GAAOC,CAAQ,IAAIH,EAAS,EAAE,GAC/BI,IAAUC,EAAOnB,CAAI;AAC3B,EAAIkB,EAAQ,YAAYlB,MACtBkB,EAAQ,UAAUlB,GACdA,OAAe,EAAE;AAEvB,QAAMoB,IAAUZ,KAAe,QAAQQ,EAAM,KAAA,MAAWR,EAAY,KAAA,GAC9Da,IAAWC,EAAA,GAGXC,IAAc,MAAM;AACxB,IAAKR,KAAMd,EAAA;AAAA,EACb,GAEMuB,IAAgB,YAAY;AAChC,QAAI,GAACJ,KAAWL;AAChB,UAAI;AACF,QAAAF,EAAc,EAAI,GAClB,MAAMX,EAAA,GACND,EAAA;AAAA,MACF,QAAQ;AAAA,MAER,UAAA;AACE,QAAAY,EAAc,EAAK;AAAA,MACrB;AAAA,EACF;AAEA,SACE,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAjB;AAAA,MACA,MAAAT;AAAA,MACA,SAASuB;AAAA,MACT,MAAK;AAAA,MACL,eAAeI,EAAO;AAAA,MACtB,OAAOxB,KAASO,EAAE,oBAAoB;AAAA,MACtC,iBAAiB,CAACK;AAAA,MAClB,iBAAiB,CAACA;AAAA,MAClB,eAAe,CAACA;AAAA,MAChB,QACE,gBAAAa,EAAAC,GAAA,EACE,UAAA;AAAA,QAAA,gBAAAJ,EAACK,GAAA,EAAO,SAAQ,QAAO,MAAK,MAAK,SAASP,GAAa,UAAUR,GAC9D,UAAAT,KAAeI,EAAE,eAAe,GACnC;AAAA,QACA,gBAAAe;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAASN;AAAA,YACT,SAAST;AAAA,YACT,UAAU,CAACK;AAAA,YAEV,UAAAf,KAAgBK,EAAE,eAAe;AAAA,UAAA;AAAA,QAAA;AAAA,MACpC,GACF;AAAA,MAGF,UAAA,gBAAAkB,EAAC,OAAA,EAAI,WAAWD,EAAO,MACrB,UAAA;AAAA,QAAA,gBAAAF,EAAC,OAAA,EAAI,WAAWE,EAAO,SAAS,eAAW,IACzC,UAAA,gBAAAF,EAACM,GAAA,EAAK,MAAK,QAAA,CAAQ,EAAA,CACrB;AAAA,0BACCC,GAAA,EAAW,OAAM,UAAU,UAAA5B,KAAWM,EAAE,sBAAsB,GAAE;AAAA,QAChEF,KAAe,QACd,gBAAAoB,EAAC,OAAA,EAAI,WAAWD,EAAO,SAErB,UAAA;AAAA,UAAA,gBAAAF,EAACQ,GAAA,EAAW,IAAIZ,GAAU,MAAK,MAAK,OAAM,SACxC,UAAA,gBAAAI,EAACS,GAAA,EAAmB,MAAM1B,EAAA,CAAa,GACzC;AAAA,UACA,gBAAAiB;AAAA,YAACU;AAAA,YAAA;AAAA,cACC,mBAAiBd;AAAA,cACjB,aAAab;AAAA,cACb,OAAOQ;AAAA,cACP,UAAU,CAACoB,MAAUnB,EAASmB,EAAM,OAAO,KAAK;AAAA,cAChD,WAAW,CAACA,MAA2C;AACrD,gBAAIA,EAAM,QAAQ,YAChBA,EAAM,eAAA,GACDZ,EAAA;AAAA,cAET;AAAA,cAEA,WAAWR,KAASI,IAAU,gBAAAK,EAACM,KAAK,MAAK,cAAa,OAAM,UAAA,CAAU,IAAK;AAAA,cAC3E,mBAAkB;AAAA,cAClB,UAAUhB;AAAA,cACV,MAAK;AAAA,cACL,cAAa;AAAA,cACb,gBAAe;AAAA,cACf,aAAY;AAAA,cACZ,YAAY;AAAA,YAAA;AAAA,UAAA;AAAA,QACd,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;AAGD,SAASmB,EAAmB,EAAE,MAAAG,KAA0B;AACtD,QAAM,IAAI1B,EAAA,GAEJ2B,IAAW,MACX,CAACC,GAAQC,IAAQ,EAAE,IAAI,EAAE,8BAA8B,EAAE,MAAMF,EAAA,CAAU,EAAE,MAAMA,CAAQ;AAC/F,SACE,gBAAAV,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAU;AAAA,IACD,gBAAAd,EAACgB,KAAK,MAAK,MAAK,OAAM,SAAQ,WAAWd,EAAO,QAC7C,UAAAU,EAAA,CACH;AAAA,IACCG;AAAA,EAAA,GACH;AAEJ;"}