@techzyapp/ui-library 1.0.44 → 1.0.45

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 (377) hide show
  1. package/dist/{AdminRoot-9KE3ll-D.js → AdminRoot-BZ1v5vN9.js} +7 -7
  2. package/dist/{AdminRoot-9KE3ll-D.js.map → AdminRoot-BZ1v5vN9.js.map} +1 -1
  3. package/dist/{AdminRoot-BMzHo0n7.cjs → AdminRoot-DJ4-UMAB.cjs} +2 -2
  4. package/dist/{AdminRoot-BMzHo0n7.cjs.map → AdminRoot-DJ4-UMAB.cjs.map} +1 -1
  5. package/dist/{Alert-BFfzpPNd.js → Alert-BU7GlQna.js} +3 -3
  6. package/dist/{Alert-BFfzpPNd.js.map → Alert-BU7GlQna.js.map} +1 -1
  7. package/dist/{Alert-DS8TzpIS.cjs → Alert-CVQOjuEq.cjs} +2 -2
  8. package/dist/{Alert-DS8TzpIS.cjs.map → Alert-CVQOjuEq.cjs.map} +1 -1
  9. package/dist/{Breadcrumbs-CloqFpp1.js → Breadcrumbs-BMz_YVPa.js} +3 -3
  10. package/dist/{Breadcrumbs-CloqFpp1.js.map → Breadcrumbs-BMz_YVPa.js.map} +1 -1
  11. package/dist/{Breadcrumbs-N2-sZWW5.cjs → Breadcrumbs-BbC0o4JE.cjs} +2 -2
  12. package/dist/{Breadcrumbs-N2-sZWW5.cjs.map → Breadcrumbs-BbC0o4JE.cjs.map} +1 -1
  13. package/dist/{Button-5LQtDA9d.js → Button-C415LPw_.js} +2 -2
  14. package/dist/{Button-5LQtDA9d.js.map → Button-C415LPw_.js.map} +1 -1
  15. package/dist/{Button-Bxztlybi.cjs → Button-mBZOvgyZ.cjs} +2 -2
  16. package/dist/{Button-Bxztlybi.cjs.map → Button-mBZOvgyZ.cjs.map} +1 -1
  17. package/dist/{Calendar-BIKo_aus.js → Calendar-B0f6h9-A.js} +3 -3
  18. package/dist/{Calendar-BIKo_aus.js.map → Calendar-B0f6h9-A.js.map} +1 -1
  19. package/dist/{Calendar-CsBgaKZ-.cjs → Calendar-hO051hfk.cjs} +2 -2
  20. package/dist/{Calendar-CsBgaKZ-.cjs.map → Calendar-hO051hfk.cjs.map} +1 -1
  21. package/dist/{Card-Csn3FaMl.cjs → Card-BdNr5row.cjs} +2 -2
  22. package/dist/{Card-Csn3FaMl.cjs.map → Card-BdNr5row.cjs.map} +1 -1
  23. package/dist/{Card-DMwQ7rMk.js → Card-ssUNaOF_.js} +3 -3
  24. package/dist/{Card-DMwQ7rMk.js.map → Card-ssUNaOF_.js.map} +1 -1
  25. package/dist/{Chip-BdCZ44I8.cjs → Chip-BpJN4rzY.cjs} +2 -2
  26. package/dist/{Chip-BdCZ44I8.cjs.map → Chip-BpJN4rzY.cjs.map} +1 -1
  27. package/dist/{Chip-C7IkFuM1.js → Chip-C0x-6g2h.js} +2 -2
  28. package/dist/{Chip-C7IkFuM1.js.map → Chip-C0x-6g2h.js.map} +1 -1
  29. package/dist/{CodeBlock-C10JN6DR.js → CodeBlock-DKnWINdV.js} +3 -3
  30. package/dist/{CodeBlock-C10JN6DR.js.map → CodeBlock-DKnWINdV.js.map} +1 -1
  31. package/dist/{CodeBlock-BnXxxqAW.cjs → CodeBlock-DTrzN95i.cjs} +2 -2
  32. package/dist/{CodeBlock-BnXxxqAW.cjs.map → CodeBlock-DTrzN95i.cjs.map} +1 -1
  33. package/dist/{ColorPicker-z8_-77LO.js → ColorPicker-Bidev2DJ.js} +3 -3
  34. package/dist/{ColorPicker-z8_-77LO.js.map → ColorPicker-Bidev2DJ.js.map} +1 -1
  35. package/dist/{ColorPicker-CVddGc-n.cjs → ColorPicker-Doaegll4.cjs} +2 -2
  36. package/dist/{ColorPicker-CVddGc-n.cjs.map → ColorPicker-Doaegll4.cjs.map} +1 -1
  37. package/dist/{ColorPickerPanel-DJY6-EqO.cjs → ColorPickerPanel-048Fj7wv.cjs} +2 -2
  38. package/dist/{ColorPickerPanel-DJY6-EqO.cjs.map → ColorPickerPanel-048Fj7wv.cjs.map} +1 -1
  39. package/dist/{ColorPickerPanel-y4A2LLLf.js → ColorPickerPanel-DThSuUoz.js} +2 -2
  40. package/dist/{ColorPickerPanel-y4A2LLLf.js.map → ColorPickerPanel-DThSuUoz.js.map} +1 -1
  41. package/dist/{ColorRamp-DvRsdOWy.cjs → ColorRamp-CGw4D9bf.cjs} +2 -2
  42. package/dist/{ColorRamp-DvRsdOWy.cjs.map → ColorRamp-CGw4D9bf.cjs.map} +1 -1
  43. package/dist/{ColorRamp-Dvit8yoP.js → ColorRamp-Reb0q69d.js} +2 -2
  44. package/dist/{ColorRamp-Dvit8yoP.js.map → ColorRamp-Reb0q69d.js.map} +1 -1
  45. package/dist/{ConfigProvider-Cf-awvZs.cjs → ConfigProvider-DBU6rOIA.cjs} +2 -2
  46. package/dist/{ConfigProvider-Cf-awvZs.cjs.map → ConfigProvider-DBU6rOIA.cjs.map} +1 -1
  47. package/dist/{ConfigProvider-CYgmMH4j.js → ConfigProvider-DVDGtCUc.js} +2 -2
  48. package/dist/{ConfigProvider-CYgmMH4j.js.map → ConfigProvider-DVDGtCUc.js.map} +1 -1
  49. package/dist/{CopyButton-BOp7waEt.cjs → CopyButton-Cnab62vt.cjs} +2 -2
  50. package/dist/{CopyButton-BOp7waEt.cjs.map → CopyButton-Cnab62vt.cjs.map} +1 -1
  51. package/dist/{CopyButton-_iMBE4q_.js → CopyButton-Dm8-V4ku.js} +3 -3
  52. package/dist/{CopyButton-_iMBE4q_.js.map → CopyButton-Dm8-V4ku.js.map} +1 -1
  53. package/dist/{DatePicker-X5hZVSW6.js → DatePicker-C4MTCmDn.js} +4 -4
  54. package/dist/{DatePicker-X5hZVSW6.js.map → DatePicker-C4MTCmDn.js.map} +1 -1
  55. package/dist/{DatePicker-UQwpH-rw.cjs → DatePicker-CaGeW_-j.cjs} +2 -2
  56. package/dist/{DatePicker-UQwpH-rw.cjs.map → DatePicker-CaGeW_-j.cjs.map} +1 -1
  57. package/dist/{DateTimePicker-Ch1kUHEb.js → DateTimePicker-B0CjHKPV.js} +7 -7
  58. package/dist/{DateTimePicker-Ch1kUHEb.js.map → DateTimePicker-B0CjHKPV.js.map} +1 -1
  59. package/dist/{DateTimePicker-ClTZGMON.cjs → DateTimePicker-DXKaAYey.cjs} +2 -2
  60. package/dist/{DateTimePicker-ClTZGMON.cjs.map → DateTimePicker-DXKaAYey.cjs.map} +1 -1
  61. package/dist/{DescriptionList-IVAvgpEL.cjs → DescriptionList-BSDwobDc.cjs} +2 -2
  62. package/dist/{DescriptionList-IVAvgpEL.cjs.map → DescriptionList-BSDwobDc.cjs.map} +1 -1
  63. package/dist/{DescriptionList-Cque-iYk.js → DescriptionList-BkUS5egS.js} +4 -4
  64. package/dist/{DescriptionList-Cque-iYk.js.map → DescriptionList-BkUS5egS.js.map} +1 -1
  65. package/dist/{EmptyState-C84B-E8a.cjs → EmptyState-CkkFHKrh.cjs} +2 -2
  66. package/dist/{EmptyState-C84B-E8a.cjs.map → EmptyState-CkkFHKrh.cjs.map} +1 -1
  67. package/dist/{EmptyState-Yts_p-jZ.js → EmptyState-DXoaPC7o.js} +2 -2
  68. package/dist/{EmptyState-Yts_p-jZ.js.map → EmptyState-DXoaPC7o.js.map} +1 -1
  69. package/dist/{ErrorBoundary-BgMOPle0.js → ErrorBoundary-CSP_Ctg6.js} +3 -3
  70. package/dist/{ErrorBoundary-BgMOPle0.js.map → ErrorBoundary-CSP_Ctg6.js.map} +1 -1
  71. package/dist/{ErrorBoundary-DtYswKp3.cjs → ErrorBoundary-tZjKtO28.cjs} +2 -2
  72. package/dist/{ErrorBoundary-DtYswKp3.cjs.map → ErrorBoundary-tZjKtO28.cjs.map} +1 -1
  73. package/dist/{ErrorState-Aa8LVjkl.cjs → ErrorState-JH4JdrTI.cjs} +2 -2
  74. package/dist/{ErrorState-Aa8LVjkl.cjs.map → ErrorState-JH4JdrTI.cjs.map} +1 -1
  75. package/dist/{ErrorState-BE9Rcmht.js → ErrorState-WYsly5-i.js} +7 -7
  76. package/dist/{ErrorState-BE9Rcmht.js.map → ErrorState-WYsly5-i.js.map} +1 -1
  77. package/dist/{FileCard-Chfx0QdF.cjs → FileCard-BIfPqeek.cjs} +2 -2
  78. package/dist/{FileCard-Chfx0QdF.cjs.map → FileCard-BIfPqeek.cjs.map} +1 -1
  79. package/dist/{FileCard-m3i_8yKR.js → FileCard-D4TB3qGG.js} +3 -3
  80. package/dist/{FileCard-m3i_8yKR.js.map → FileCard-D4TB3qGG.js.map} +1 -1
  81. package/dist/FileUploader-DPVF76Ha.js +701 -0
  82. package/dist/FileUploader-DPVF76Ha.js.map +1 -0
  83. package/dist/FileUploader-YE_DfTNC.cjs +2 -0
  84. package/dist/FileUploader-YE_DfTNC.cjs.map +1 -0
  85. package/dist/{Flag-BvZB3295.cjs → Flag-B6OhgwZr.cjs} +2 -2
  86. package/dist/{Flag-BvZB3295.cjs.map → Flag-B6OhgwZr.cjs.map} +1 -1
  87. package/dist/{Flag-C1HwnZXJ.js → Flag-Q3vI7cgt.js} +2 -2
  88. package/dist/{Flag-C1HwnZXJ.js.map → Flag-Q3vI7cgt.js.map} +1 -1
  89. package/dist/{FullscreenToggle-B4ynXdCP.js → FullscreenToggle-CxwGPLdd.js} +3 -3
  90. package/dist/{FullscreenToggle-B4ynXdCP.js.map → FullscreenToggle-CxwGPLdd.js.map} +1 -1
  91. package/dist/{FullscreenToggle-CEFZQ5OC.cjs → FullscreenToggle-ipX55Nj4.cjs} +2 -2
  92. package/dist/{FullscreenToggle-CEFZQ5OC.cjs.map → FullscreenToggle-ipX55Nj4.cjs.map} +1 -1
  93. package/dist/{IconButton-wW1o4HHw.cjs → IconButton-U_sr2Ahy.cjs} +2 -2
  94. package/dist/{IconButton-wW1o4HHw.cjs.map → IconButton-U_sr2Ahy.cjs.map} +1 -1
  95. package/dist/{IconButton-EaExCXRq.js → IconButton-re6xITGO.js} +2 -2
  96. package/dist/{IconButton-EaExCXRq.js.map → IconButton-re6xITGO.js.map} +1 -1
  97. package/dist/ImageEditor-1n50vo_v.cjs +64 -0
  98. package/dist/ImageEditor-1n50vo_v.cjs.map +1 -0
  99. package/dist/{ImageEditor-DTFQZ6ON.js → ImageEditor-BwrG1fk7.js} +968 -948
  100. package/dist/ImageEditor-BwrG1fk7.js.map +1 -0
  101. package/dist/{Loader-D_Foo6Hj.js → Loader-7v1QBvHY.js} +2 -2
  102. package/dist/{Loader-D_Foo6Hj.js.map → Loader-7v1QBvHY.js.map} +1 -1
  103. package/dist/{Loader-DNR2_YHm.cjs → Loader-BE3SQr7W.cjs} +2 -2
  104. package/dist/{Loader-DNR2_YHm.cjs.map → Loader-BE3SQr7W.cjs.map} +1 -1
  105. package/dist/{LocationPicker-DGbnbTW9.js → LocationPicker-BvKtZFq0.js} +6 -6
  106. package/dist/{LocationPicker-DGbnbTW9.js.map → LocationPicker-BvKtZFq0.js.map} +1 -1
  107. package/dist/{LocationPicker-CdO37PKg.cjs → LocationPicker-CVJ4jVn2.cjs} +2 -2
  108. package/dist/{LocationPicker-CdO37PKg.cjs.map → LocationPicker-CVJ4jVn2.cjs.map} +1 -1
  109. package/dist/{Modal-Du-uVpYw.cjs → Modal-CxODxl81.cjs} +2 -2
  110. package/dist/{Modal-Du-uVpYw.cjs.map → Modal-CxODxl81.cjs.map} +1 -1
  111. package/dist/{Modal-1rIBMvKH.js → Modal-DpoiMMM3.js} +3 -3
  112. package/dist/{Modal-1rIBMvKH.js.map → Modal-DpoiMMM3.js.map} +1 -1
  113. package/dist/{MultiSelect-lAAaD0uL.cjs → MultiSelect-2GouMRTl.cjs} +2 -2
  114. package/dist/{MultiSelect-lAAaD0uL.cjs.map → MultiSelect-2GouMRTl.cjs.map} +1 -1
  115. package/dist/{MultiSelect-BoqunsM9.js → MultiSelect-B7KwEhL5.js} +4 -4
  116. package/dist/{MultiSelect-BoqunsM9.js.map → MultiSelect-B7KwEhL5.js.map} +1 -1
  117. package/dist/{NumberField-DHFGNQjZ.js → NumberField-ThojS4K3.js} +3 -3
  118. package/dist/{NumberField-DHFGNQjZ.js.map → NumberField-ThojS4K3.js.map} +1 -1
  119. package/dist/{NumberField-CyUA6eob.cjs → NumberField-o2z2QNK1.cjs} +2 -2
  120. package/dist/{NumberField-CyUA6eob.cjs.map → NumberField-o2z2QNK1.cjs.map} +1 -1
  121. package/dist/{OtpField-CIy5OtXI.cjs → OtpField-BhZq44vV.cjs} +2 -2
  122. package/dist/{OtpField-CIy5OtXI.cjs.map → OtpField-BhZq44vV.cjs.map} +1 -1
  123. package/dist/{OtpField-pL9nj4AW.js → OtpField-C3MlMZ2F.js} +2 -2
  124. package/dist/{OtpField-pL9nj4AW.js.map → OtpField-C3MlMZ2F.js.map} +1 -1
  125. package/dist/{PageError-C5SO0mVJ.js → PageError-63Gk6fVC.js} +5 -5
  126. package/dist/{PageError-C5SO0mVJ.js.map → PageError-63Gk6fVC.js.map} +1 -1
  127. package/dist/{PageError-DbokLmOY.cjs → PageError-CCKWbrc5.cjs} +2 -2
  128. package/dist/{PageError-DbokLmOY.cjs.map → PageError-CCKWbrc5.cjs.map} +1 -1
  129. package/dist/{PageLayout-Du-D6Pd4.js → PageLayout-BekkDBtT.js} +4 -4
  130. package/dist/{PageLayout-Du-D6Pd4.js.map → PageLayout-BekkDBtT.js.map} +1 -1
  131. package/dist/{PageLayout-B7ZDiNq8.cjs → PageLayout-CDPUYu6A.cjs} +2 -2
  132. package/dist/{PageLayout-B7ZDiNq8.cjs.map → PageLayout-CDPUYu6A.cjs.map} +1 -1
  133. package/dist/{PageNotFound-DSkoMfed.js → PageNotFound-BD3zX3cd.js} +5 -5
  134. package/dist/{PageNotFound-DSkoMfed.js.map → PageNotFound-BD3zX3cd.js.map} +1 -1
  135. package/dist/{PageNotFound-DfNwdtgJ.cjs → PageNotFound-CTR6htwa.cjs} +2 -2
  136. package/dist/{PageNotFound-DfNwdtgJ.cjs.map → PageNotFound-CTR6htwa.cjs.map} +1 -1
  137. package/dist/{Pagination-DO2Os4an.cjs → Pagination-BJvLUjQ0.cjs} +2 -2
  138. package/dist/{Pagination-DO2Os4an.cjs.map → Pagination-BJvLUjQ0.cjs.map} +1 -1
  139. package/dist/{Pagination-BH8ACaAC.js → Pagination-qKjISBJ9.js} +2 -2
  140. package/dist/{Pagination-BH8ACaAC.js.map → Pagination-qKjISBJ9.js.map} +1 -1
  141. package/dist/{PaletteField-BfvcJvGM.cjs → PaletteField-CDS9CJW9.cjs} +2 -2
  142. package/dist/{PaletteField-BfvcJvGM.cjs.map → PaletteField-CDS9CJW9.cjs.map} +1 -1
  143. package/dist/{PaletteField-BFb0PQ-S.js → PaletteField-y8KpR4Ap.js} +3 -3
  144. package/dist/{PaletteField-BFb0PQ-S.js.map → PaletteField-y8KpR4Ap.js.map} +1 -1
  145. package/dist/{PhoneField-C-wOm7g5.cjs → PhoneField-Df3J6Hhg.cjs} +2 -2
  146. package/dist/{PhoneField-C-wOm7g5.cjs.map → PhoneField-Df3J6Hhg.cjs.map} +1 -1
  147. package/dist/{PhoneField-DFhGWgbK.js → PhoneField-OjsuevPx.js} +4 -4
  148. package/dist/{PhoneField-DFhGWgbK.js.map → PhoneField-OjsuevPx.js.map} +1 -1
  149. package/dist/{Popconfirm-_53vtMI0.cjs → Popconfirm-BKzJ_EZy.cjs} +2 -2
  150. package/dist/{Popconfirm-_53vtMI0.cjs.map → Popconfirm-BKzJ_EZy.cjs.map} +1 -1
  151. package/dist/{Popconfirm-o5da44ra.js → Popconfirm-aCyniPnH.js} +3 -3
  152. package/dist/{Popconfirm-o5da44ra.js.map → Popconfirm-aCyniPnH.js.map} +1 -1
  153. package/dist/{Progress-BSinoQ8t.cjs → Progress-DWOoLd8u.cjs} +2 -2
  154. package/dist/{Progress-BSinoQ8t.cjs.map → Progress-DWOoLd8u.cjs.map} +1 -1
  155. package/dist/{Progress-CHzNwegP.js → Progress-DzxbkcaD.js} +2 -2
  156. package/dist/{Progress-CHzNwegP.js.map → Progress-DzxbkcaD.js.map} +1 -1
  157. package/dist/{QrCode-tNNnsbHM.cjs → QrCode-C8uAPiHq.cjs} +2 -2
  158. package/dist/{QrCode-tNNnsbHM.cjs.map → QrCode-C8uAPiHq.cjs.map} +1 -1
  159. package/dist/{QrCode-C3hAfNP6.js → QrCode-DaJYqBc1.js} +2 -2
  160. package/dist/{QrCode-C3hAfNP6.js.map → QrCode-DaJYqBc1.js.map} +1 -1
  161. package/dist/{RemoveDialog-Hi_gV-8A.cjs → RemoveDialog-BnOtR6-q.cjs} +2 -2
  162. package/dist/{RemoveDialog-Hi_gV-8A.cjs.map → RemoveDialog-BnOtR6-q.cjs.map} +1 -1
  163. package/dist/{RemoveDialog-CXy-PY-G.js → RemoveDialog-MhEU5Zl3.js} +5 -5
  164. package/dist/{RemoveDialog-CXy-PY-G.js.map → RemoveDialog-MhEU5Zl3.js.map} +1 -1
  165. package/dist/RichTextEditor-Cnrnvv1f.cjs +2 -0
  166. package/dist/RichTextEditor-Cnrnvv1f.cjs.map +1 -0
  167. package/dist/RichTextEditor-zkoxujnO.js +1148 -0
  168. package/dist/RichTextEditor-zkoxujnO.js.map +1 -0
  169. package/dist/{RootLayout-CjT5uHlt.js → RootLayout-C4r9i5Go.js} +15 -15
  170. package/dist/{RootLayout-CjT5uHlt.js.map → RootLayout-C4r9i5Go.js.map} +1 -1
  171. package/dist/{RootLayout-iSGY4MsS.cjs → RootLayout-Z9PuRfsa.cjs} +2 -2
  172. package/dist/{RootLayout-iSGY4MsS.cjs.map → RootLayout-Z9PuRfsa.cjs.map} +1 -1
  173. package/dist/{Select-DVoL547R.cjs → Select-CylqFHce.cjs} +2 -2
  174. package/dist/{Select-DVoL547R.cjs.map → Select-CylqFHce.cjs.map} +1 -1
  175. package/dist/{Select-DuLDLnnb.js → Select-jT94L1vq.js} +3 -3
  176. package/dist/{Select-DuLDLnnb.js.map → Select-jT94L1vq.js.map} +1 -1
  177. package/dist/{Sidebar-DvQmuBNK.js → Sidebar-B1O2RsbR.js} +3 -3
  178. package/dist/{Sidebar-DvQmuBNK.js.map → Sidebar-B1O2RsbR.js.map} +1 -1
  179. package/dist/{Sidebar-DRQo4zAF.cjs → Sidebar-Bcm0fgVm.cjs} +2 -2
  180. package/dist/{Sidebar-DRQo4zAF.cjs.map → Sidebar-Bcm0fgVm.cjs.map} +1 -1
  181. package/dist/{Slider-DxnCQRSH.cjs → Slider-CV7ug0WF.cjs} +2 -2
  182. package/dist/{Slider-DxnCQRSH.cjs.map → Slider-CV7ug0WF.cjs.map} +1 -1
  183. package/dist/{Slider-D-QjclQJ.js → Slider-DC-ugZwT.js} +2 -2
  184. package/dist/{Slider-D-QjclQJ.js.map → Slider-DC-ugZwT.js.map} +1 -1
  185. package/dist/{SpeedDial-BBQ9y6lm.js → SpeedDial-C6yiMUe8.js} +2 -2
  186. package/dist/{SpeedDial-BBQ9y6lm.js.map → SpeedDial-C6yiMUe8.js.map} +1 -1
  187. package/dist/{SpeedDial-37OMwj9C.cjs → SpeedDial-DOgm2DDX.cjs} +2 -2
  188. package/dist/{SpeedDial-37OMwj9C.cjs.map → SpeedDial-DOgm2DDX.cjs.map} +1 -1
  189. package/dist/{Stepper-CU5Y0kfj.js → Stepper-BZdYGpBN.js} +2 -2
  190. package/dist/{Stepper-CU5Y0kfj.js.map → Stepper-BZdYGpBN.js.map} +1 -1
  191. package/dist/{Stepper-WqkfGPnQ.cjs → Stepper-DqM86TGV.cjs} +2 -2
  192. package/dist/{Stepper-WqkfGPnQ.cjs.map → Stepper-DqM86TGV.cjs.map} +1 -1
  193. package/dist/{Table-BnlvrRMr.cjs → Table-BgaCwRDQ.cjs} +2 -2
  194. package/dist/{Table-BnlvrRMr.cjs.map → Table-BgaCwRDQ.cjs.map} +1 -1
  195. package/dist/{Table-BECUUZtf.js → Table-FZlVWoYi.js} +16 -16
  196. package/dist/{Table-BECUUZtf.js.map → Table-FZlVWoYi.js.map} +1 -1
  197. package/dist/{Tabs-BXAHddi7.js → Tabs-BqQPkorY.js} +2 -2
  198. package/dist/{Tabs-BXAHddi7.js.map → Tabs-BqQPkorY.js.map} +1 -1
  199. package/dist/{Tabs-DiL1vNW3.cjs → Tabs-kGeyFhJ6.cjs} +2 -2
  200. package/dist/{Tabs-DiL1vNW3.cjs.map → Tabs-kGeyFhJ6.cjs.map} +1 -1
  201. package/dist/{TagsField-BsV_6dff.cjs → TagsField-B_sjp48X.cjs} +2 -2
  202. package/dist/{TagsField-BsV_6dff.cjs.map → TagsField-B_sjp48X.cjs.map} +1 -1
  203. package/dist/{TagsField-C1SgykAj.js → TagsField-ByTx9JXK.js} +4 -4
  204. package/dist/{TagsField-C1SgykAj.js.map → TagsField-ByTx9JXK.js.map} +1 -1
  205. package/dist/{TextField-DUv689u2.cjs → TextField-CBYJIfau.cjs} +2 -2
  206. package/dist/{TextField-DUv689u2.cjs.map → TextField-CBYJIfau.cjs.map} +1 -1
  207. package/dist/{TextField-oZI7thoU.js → TextField-CyKIx-d-.js} +3 -3
  208. package/dist/{TextField-oZI7thoU.js.map → TextField-CyKIx-d-.js.map} +1 -1
  209. package/dist/{ThemeToggle-xn3roH0u.cjs → ThemeToggle-D2dIqiBa.cjs} +2 -2
  210. package/dist/{ThemeToggle-xn3roH0u.cjs.map → ThemeToggle-D2dIqiBa.cjs.map} +1 -1
  211. package/dist/{ThemeToggle-5uHCUsX7.js → ThemeToggle-Dg6IishB.js} +3 -3
  212. package/dist/{ThemeToggle-5uHCUsX7.js.map → ThemeToggle-Dg6IishB.js.map} +1 -1
  213. package/dist/{TimeColumns-lO33mhX7.js → TimeColumns-Cx8J5qzW.js} +2 -2
  214. package/dist/{TimeColumns-lO33mhX7.js.map → TimeColumns-Cx8J5qzW.js.map} +1 -1
  215. package/dist/{TimeColumns-By23LHZw.cjs → TimeColumns-DVmK_T_P.cjs} +2 -2
  216. package/dist/{TimeColumns-By23LHZw.cjs.map → TimeColumns-DVmK_T_P.cjs.map} +1 -1
  217. package/dist/{TimePicker-BHFNH8LR.cjs → TimePicker-0nZOPRKp.cjs} +2 -2
  218. package/dist/{TimePicker-BHFNH8LR.cjs.map → TimePicker-0nZOPRKp.cjs.map} +1 -1
  219. package/dist/{TimePicker-Dl5p833O.js → TimePicker-sAhtvqQ4.js} +5 -5
  220. package/dist/{TimePicker-Dl5p833O.js.map → TimePicker-sAhtvqQ4.js.map} +1 -1
  221. package/dist/{Toaster-BPBFZiTr.js → Toaster-BOW9rzLq.js} +3 -3
  222. package/dist/{Toaster-BPBFZiTr.js.map → Toaster-BOW9rzLq.js.map} +1 -1
  223. package/dist/{Toaster-D4T89N1S.cjs → Toaster-DYGo92ke.cjs} +2 -2
  224. package/dist/{Toaster-D4T89N1S.cjs.map → Toaster-DYGo92ke.cjs.map} +1 -1
  225. package/dist/{TranslatedFields-LdeJeHEp.cjs → TranslatedFields-C_DuLotV.cjs} +2 -2
  226. package/dist/{TranslatedFields-LdeJeHEp.cjs.map → TranslatedFields-C_DuLotV.cjs.map} +1 -1
  227. package/dist/{TranslatedFields-Clsr84XC.js → TranslatedFields-CcE0td9p.js} +5 -5
  228. package/dist/{TranslatedFields-Clsr84XC.js.map → TranslatedFields-CcE0td9p.js.map} +1 -1
  229. package/dist/{UserCard-CQOiWppq.cjs → UserCard-DLVptkLr.cjs} +2 -2
  230. package/dist/{UserCard-CQOiWppq.cjs.map → UserCard-DLVptkLr.cjs.map} +1 -1
  231. package/dist/{UserCard-Cr75RwZb.js → UserCard-DeONbaKj.js} +3 -3
  232. package/dist/{UserCard-Cr75RwZb.js.map → UserCard-DeONbaKj.js.map} +1 -1
  233. package/dist/components/Alert/index.cjs +1 -1
  234. package/dist/components/Alert/index.js +1 -1
  235. package/dist/components/Breadcrumbs/index.cjs +1 -1
  236. package/dist/components/Breadcrumbs/index.js +1 -1
  237. package/dist/components/Button/index.cjs +1 -1
  238. package/dist/components/Button/index.js +1 -1
  239. package/dist/components/Card/index.cjs +1 -1
  240. package/dist/components/Card/index.js +1 -1
  241. package/dist/components/Chip/index.cjs +1 -1
  242. package/dist/components/Chip/index.js +1 -1
  243. package/dist/components/CodeBlock/index.cjs +1 -1
  244. package/dist/components/CodeBlock/index.js +1 -1
  245. package/dist/components/ColorPicker/index.cjs +1 -1
  246. package/dist/components/ColorPicker/index.js +1 -1
  247. package/dist/components/ColorRamp/index.cjs +1 -1
  248. package/dist/components/ColorRamp/index.js +1 -1
  249. package/dist/components/CopyButton/index.cjs +1 -1
  250. package/dist/components/CopyButton/index.js +1 -1
  251. package/dist/components/DatePicker/index.cjs +1 -1
  252. package/dist/components/DatePicker/index.js +1 -1
  253. package/dist/components/DateTimePicker/index.cjs +1 -1
  254. package/dist/components/DateTimePicker/index.js +1 -1
  255. package/dist/components/DescriptionList/index.cjs +1 -1
  256. package/dist/components/DescriptionList/index.js +1 -1
  257. package/dist/components/EmptyState/index.cjs +1 -1
  258. package/dist/components/EmptyState/index.js +1 -1
  259. package/dist/components/ErrorState/index.cjs +1 -1
  260. package/dist/components/ErrorState/index.js +2 -2
  261. package/dist/components/FileCard/index.cjs +1 -1
  262. package/dist/components/FileCard/index.js +1 -1
  263. package/dist/components/FileUploader/index.cjs +1 -1
  264. package/dist/components/FileUploader/index.js +1 -1
  265. package/dist/components/Flag/index.cjs +1 -1
  266. package/dist/components/Flag/index.js +1 -1
  267. package/dist/components/FullscreenToggle/index.cjs +1 -1
  268. package/dist/components/FullscreenToggle/index.js +1 -1
  269. package/dist/components/IconButton/index.cjs +1 -1
  270. package/dist/components/IconButton/index.js +1 -1
  271. package/dist/components/ImageEditor/index.cjs +1 -1
  272. package/dist/components/ImageEditor/index.js +1 -1
  273. package/dist/components/Loader/index.cjs +1 -1
  274. package/dist/components/Loader/index.js +1 -1
  275. package/dist/components/LocationPicker/index.cjs +1 -1
  276. package/dist/components/LocationPicker/index.js +1 -1
  277. package/dist/components/Modal/index.cjs +1 -1
  278. package/dist/components/Modal/index.js +1 -1
  279. package/dist/components/MultiSelect/index.cjs +1 -1
  280. package/dist/components/MultiSelect/index.js +1 -1
  281. package/dist/components/NumberField/index.cjs +1 -1
  282. package/dist/components/NumberField/index.js +1 -1
  283. package/dist/components/OtpField/index.cjs +1 -1
  284. package/dist/components/OtpField/index.js +1 -1
  285. package/dist/components/PageError/index.cjs +1 -1
  286. package/dist/components/PageError/index.js +1 -1
  287. package/dist/components/PageLayout/index.cjs +1 -1
  288. package/dist/components/PageLayout/index.js +1 -1
  289. package/dist/components/PageNotFound/index.cjs +1 -1
  290. package/dist/components/PageNotFound/index.js +1 -1
  291. package/dist/components/Pagination/index.cjs +1 -1
  292. package/dist/components/Pagination/index.js +1 -1
  293. package/dist/components/PaletteField/index.cjs +1 -1
  294. package/dist/components/PaletteField/index.js +1 -1
  295. package/dist/components/PhoneField/index.cjs +1 -1
  296. package/dist/components/PhoneField/index.js +1 -1
  297. package/dist/components/Popconfirm/index.cjs +1 -1
  298. package/dist/components/Popconfirm/index.js +1 -1
  299. package/dist/components/Progress/index.cjs +1 -1
  300. package/dist/components/Progress/index.js +1 -1
  301. package/dist/components/QrCode/index.cjs +1 -1
  302. package/dist/components/QrCode/index.js +1 -1
  303. package/dist/components/RemoveDialog/index.cjs +1 -1
  304. package/dist/components/RemoveDialog/index.js +1 -1
  305. package/dist/components/RichTextEditor/index.cjs +1 -1
  306. package/dist/components/RichTextEditor/index.js +1 -1
  307. package/dist/components/RichTextEditor/nodes/ImageNode.d.cts +17 -5
  308. package/dist/components/RichTextEditor/nodes/ImageNode.d.ts +17 -5
  309. package/dist/components/RootLayout/index.cjs +1 -1
  310. package/dist/components/RootLayout/index.js +1 -1
  311. package/dist/components/Select/index.cjs +1 -1
  312. package/dist/components/Select/index.js +1 -1
  313. package/dist/components/Sidebar/index.cjs +1 -1
  314. package/dist/components/Sidebar/index.js +1 -1
  315. package/dist/components/Slider/index.cjs +1 -1
  316. package/dist/components/Slider/index.js +1 -1
  317. package/dist/components/SpeedDial/index.cjs +1 -1
  318. package/dist/components/SpeedDial/index.js +1 -1
  319. package/dist/components/Stepper/index.cjs +1 -1
  320. package/dist/components/Stepper/index.js +1 -1
  321. package/dist/components/Table/index.cjs +1 -1
  322. package/dist/components/Table/index.js +1 -1
  323. package/dist/components/Tabs/index.cjs +1 -1
  324. package/dist/components/Tabs/index.js +1 -1
  325. package/dist/components/TagsField/index.cjs +1 -1
  326. package/dist/components/TagsField/index.js +1 -1
  327. package/dist/components/TextField/index.cjs +1 -1
  328. package/dist/components/TextField/index.js +1 -1
  329. package/dist/components/ThemeToggle/index.cjs +1 -1
  330. package/dist/components/ThemeToggle/index.js +1 -1
  331. package/dist/components/TimePicker/index.cjs +1 -1
  332. package/dist/components/TimePicker/index.js +1 -1
  333. package/dist/components/Toast/index.cjs +1 -1
  334. package/dist/components/Toast/index.js +1 -1
  335. package/dist/components/TranslatedFields/index.cjs +1 -1
  336. package/dist/components/TranslatedFields/index.js +1 -1
  337. package/dist/components/UserCard/index.cjs +1 -1
  338. package/dist/components/UserCard/index.js +1 -1
  339. package/dist/entries/app.cjs +1 -1
  340. package/dist/entries/app.js +1 -1
  341. package/dist/entries/components.cjs +1 -1
  342. package/dist/entries/components.js +53 -53
  343. package/dist/entries/i18n.cjs +1 -1
  344. package/dist/entries/i18n.js +2 -2
  345. package/dist/entries/theme.cjs +1 -1
  346. package/dist/entries/theme.js +1 -1
  347. package/dist/i18n/messages.d.cts +5 -0
  348. package/dist/i18n/messages.d.ts +5 -0
  349. package/dist/index.cjs +1 -1
  350. package/dist/index.css +1 -1
  351. package/dist/index.js +56 -56
  352. package/dist/{messages-BZYBZ3GR.js → messages-DeQuvGln.js} +47 -12
  353. package/dist/messages-DeQuvGln.js.map +1 -0
  354. package/dist/{messages-CTHjpVJq.cjs → messages-dL9MkVze.cjs} +9 -9
  355. package/dist/messages-dL9MkVze.cjs.map +1 -0
  356. package/dist/{useHomeTo-Biyc-Un8.js → useHomeTo-BL3e8Sc6.js} +2 -2
  357. package/dist/{useHomeTo-Biyc-Un8.js.map → useHomeTo-BL3e8Sc6.js.map} +1 -1
  358. package/dist/{useHomeTo-D7wcH6aw.cjs → useHomeTo-W1PDW5CU.cjs} +2 -2
  359. package/dist/{useHomeTo-D7wcH6aw.cjs.map → useHomeTo-W1PDW5CU.cjs.map} +1 -1
  360. package/dist/{useOptionMenu-BTt8t9SM.js → useOptionMenu-BkKiZ6Ax.js} +3 -3
  361. package/dist/{useOptionMenu-BTt8t9SM.js.map → useOptionMenu-BkKiZ6Ax.js.map} +1 -1
  362. package/dist/{useOptionMenu-B40OOVsO.cjs → useOptionMenu-CVl7VHXl.cjs} +2 -2
  363. package/dist/{useOptionMenu-B40OOVsO.cjs.map → useOptionMenu-CVl7VHXl.cjs.map} +1 -1
  364. package/package.json +1 -1
  365. package/dist/FileUploader-B27Y4rak.js +0 -706
  366. package/dist/FileUploader-B27Y4rak.js.map +0 -1
  367. package/dist/FileUploader-DkvFO0N_.cjs +0 -2
  368. package/dist/FileUploader-DkvFO0N_.cjs.map +0 -1
  369. package/dist/ImageEditor-DTFQZ6ON.js.map +0 -1
  370. package/dist/ImageEditor-D_HKfDbx.cjs +0 -60
  371. package/dist/ImageEditor-D_HKfDbx.cjs.map +0 -1
  372. package/dist/RichTextEditor-BhVE1q4U.cjs +0 -2
  373. package/dist/RichTextEditor-BhVE1q4U.cjs.map +0 -1
  374. package/dist/RichTextEditor-DQz9jGD3.js +0 -1011
  375. package/dist/RichTextEditor-DQz9jGD3.js.map +0 -1
  376. package/dist/messages-BZYBZ3GR.js.map +0 -1
  377. package/dist/messages-CTHjpVJq.cjs.map +0 -1
@@ -1,2 +1,2 @@
1
- "use strict";const t=require("react/jsx-runtime"),c=require("react"),N=require("clsx"),j=require("./Icon-CBg21lKA.cjs"),C=require("./IconButton-wW1o4HHw.cjs"),X=require("./Overlay-CywFQfjm.cjs"),Y=require("./ConfigProvider-Cf-awvZs.cjs"),Z="_overlay_1lotx_3",$="_modal_1lotx_25",ee="_sm_1lotx_48",te="_md_1lotx_51",ne="_lg_1lotx_54",le="_fullScreen_1lotx_57",se="_header_1lotx_74",oe="_headerDivided_1lotx_83",ce="_headerMain_1lotx_86",ae="_icon_1lotx_93",re="_headerText_1lotx_96",ie="_title_1lotx_103",de="_subtitle_1lotx_115",ue="_close_1lotx_127",fe="_body_1lotx_132",xe="_footer_1lotx_143",n={overlay:Z,modal:$,sm:ee,md:te,lg:ne,fullScreen:le,header:se,headerDivided:oe,headerMain:ce,icon:ae,headerText:re,title:ie,subtitle:de,close:ue,body:fe,footer:xe},_e=new Set(j.ICON_NAMES),O='a[href]:not([tabindex="-1"]), button:not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), input:not(:disabled):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])',me='input:not([type="hidden"]):not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), [contenteditable]:not([contenteditable="false"]):not([tabindex="-1"])';function k(E){const s=Array.from(E);for(const o of s){const u=o instanceof HTMLInputElement&&o.type==="radio"&&!o.checked?s.find(r=>r instanceof HTMLInputElement&&r.type==="radio"&&r.name===o.name&&r.checked)??o:o;if(u.focus({preventScroll:!0}),document.activeElement===u)return!0}return!1}const be=c.forwardRef(function({open:s,onClose:o,size:u="md",scrollBehavior:r="outside",placement:S="center",title:i,description:f,icon:x,color:L="accent",footer:b,bodyClassName:B,showCloseButton:D=!0,closeOnBackdrop:F=!0,closeOnEscape:H=!0,ariaLabel:K,className:P,style:z,children:h,...w},m){const U=Y.useT(),v=c.useRef(null),M=c.useRef(null),T=c.useRef(null),q=c.useId(),R=c.useId(),g=c.useRef(null),p=c.useRef(!1);s!==p.current&&(p.current=s,s&&typeof document<"u"&&(g.current=document.activeElement)),c.useEffect(()=>{var a,_;if(!s)return;const e=v.current,l=g.current;return e!=null&&e.contains(document.activeElement)||k(((a=M.current)==null?void 0:a.querySelectorAll(me))??[])||k(((_=T.current)==null?void 0:_.querySelectorAll(O))??[])||e==null||e.focus({preventScroll:!0}),()=>{var d;l!=null&&l.isConnected&&((d=l.focus)==null||d.call(l))}},[s]);const G=e=>{v.current=e,typeof m=="function"?m(e):m&&(m.current=e)},J=e=>{if(e.key!=="Tab")return;const l=v.current;if(!l)return;const a=[...l.querySelectorAll(O)].filter(A=>A.offsetParent!==null||A===document.activeElement);if(a.length===0){e.preventDefault(),l.focus();return}const _=a[0],d=a[a.length-1],I=document.activeElement;e.shiftKey&&(I===_||I===l)?(e.preventDefault(),d.focus()):!e.shiftKey&&I===d&&(e.preventDefault(),_.focus())};if(!s)return null;const Q=S!=="center",y=x==null?null:typeof x=="string"&&_e.has(x)?t.jsx(j.Icon,{name:x}):x,V=i!=null||f!=null||y!=null||D,W=h!=null||b!=null;return t.jsx(X.Overlay,{open:s,onClose:o,closeOnBackdrop:F,closeOnEscape:H,onKeyDown:J,className:n.overlay,"data-size":u,"data-placement":S,"data-scroll":Q?"inside":r,children:t.jsxs("div",{ref:G,className:N.clsx(n.modal,n[u],P),role:"dialog","aria-modal":"true","aria-labelledby":i!=null?q:void 0,"aria-label":i==null?K:void 0,"aria-describedby":f!=null?R:void 0,tabIndex:-1,style:z,...w,children:[V&&t.jsxs("div",{className:N.clsx(n.header,W&&n.headerDivided),children:[t.jsxs("div",{className:n.headerMain,children:[y!=null&&t.jsx(C.IconButton,{variant:"filled",size:"sm",color:L,nonClickable:!0,"aria-hidden":!0,className:n.icon,children:y}),(i!=null||f!=null)&&t.jsxs("div",{className:n.headerText,children:[i!=null&&t.jsx("div",{id:q,className:n.title,children:i}),f!=null&&t.jsx("div",{id:R,className:n.subtitle,children:f})]})]}),D&&t.jsx(C.IconButton,{variant:"filled",color:"primary",size:"sm",className:n.close,"aria-label":U("common.close"),onClick:o,children:t.jsx(j.Icon,{name:"Close"})})]}),h!=null&&t.jsx("div",{ref:M,className:N.clsx(n.body,B),children:h}),b!=null&&t.jsx("div",{ref:T,className:n.footer,children:b})]})})});exports.Modal=be;
2
- //# sourceMappingURL=Modal-Du-uVpYw.cjs.map
1
+ "use strict";const t=require("react/jsx-runtime"),c=require("react"),N=require("clsx"),j=require("./Icon-CBg21lKA.cjs"),C=require("./IconButton-U_sr2Ahy.cjs"),X=require("./Overlay-CywFQfjm.cjs"),Y=require("./ConfigProvider-DBU6rOIA.cjs"),Z="_overlay_1lotx_3",$="_modal_1lotx_25",ee="_sm_1lotx_48",te="_md_1lotx_51",ne="_lg_1lotx_54",le="_fullScreen_1lotx_57",se="_header_1lotx_74",oe="_headerDivided_1lotx_83",ce="_headerMain_1lotx_86",ae="_icon_1lotx_93",re="_headerText_1lotx_96",ie="_title_1lotx_103",de="_subtitle_1lotx_115",ue="_close_1lotx_127",fe="_body_1lotx_132",xe="_footer_1lotx_143",n={overlay:Z,modal:$,sm:ee,md:te,lg:ne,fullScreen:le,header:se,headerDivided:oe,headerMain:ce,icon:ae,headerText:re,title:ie,subtitle:de,close:ue,body:fe,footer:xe},_e=new Set(j.ICON_NAMES),O='a[href]:not([tabindex="-1"]), button:not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), input:not(:disabled):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])',me='input:not([type="hidden"]):not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), [contenteditable]:not([contenteditable="false"]):not([tabindex="-1"])';function k(E){const s=Array.from(E);for(const o of s){const u=o instanceof HTMLInputElement&&o.type==="radio"&&!o.checked?s.find(r=>r instanceof HTMLInputElement&&r.type==="radio"&&r.name===o.name&&r.checked)??o:o;if(u.focus({preventScroll:!0}),document.activeElement===u)return!0}return!1}const be=c.forwardRef(function({open:s,onClose:o,size:u="md",scrollBehavior:r="outside",placement:S="center",title:i,description:f,icon:x,color:L="accent",footer:b,bodyClassName:B,showCloseButton:D=!0,closeOnBackdrop:F=!0,closeOnEscape:H=!0,ariaLabel:K,className:P,style:z,children:h,...w},m){const U=Y.useT(),v=c.useRef(null),M=c.useRef(null),T=c.useRef(null),q=c.useId(),R=c.useId(),g=c.useRef(null),p=c.useRef(!1);s!==p.current&&(p.current=s,s&&typeof document<"u"&&(g.current=document.activeElement)),c.useEffect(()=>{var a,_;if(!s)return;const e=v.current,l=g.current;return e!=null&&e.contains(document.activeElement)||k(((a=M.current)==null?void 0:a.querySelectorAll(me))??[])||k(((_=T.current)==null?void 0:_.querySelectorAll(O))??[])||e==null||e.focus({preventScroll:!0}),()=>{var d;l!=null&&l.isConnected&&((d=l.focus)==null||d.call(l))}},[s]);const G=e=>{v.current=e,typeof m=="function"?m(e):m&&(m.current=e)},J=e=>{if(e.key!=="Tab")return;const l=v.current;if(!l)return;const a=[...l.querySelectorAll(O)].filter(A=>A.offsetParent!==null||A===document.activeElement);if(a.length===0){e.preventDefault(),l.focus();return}const _=a[0],d=a[a.length-1],I=document.activeElement;e.shiftKey&&(I===_||I===l)?(e.preventDefault(),d.focus()):!e.shiftKey&&I===d&&(e.preventDefault(),_.focus())};if(!s)return null;const Q=S!=="center",y=x==null?null:typeof x=="string"&&_e.has(x)?t.jsx(j.Icon,{name:x}):x,V=i!=null||f!=null||y!=null||D,W=h!=null||b!=null;return t.jsx(X.Overlay,{open:s,onClose:o,closeOnBackdrop:F,closeOnEscape:H,onKeyDown:J,className:n.overlay,"data-size":u,"data-placement":S,"data-scroll":Q?"inside":r,children:t.jsxs("div",{ref:G,className:N.clsx(n.modal,n[u],P),role:"dialog","aria-modal":"true","aria-labelledby":i!=null?q:void 0,"aria-label":i==null?K:void 0,"aria-describedby":f!=null?R:void 0,tabIndex:-1,style:z,...w,children:[V&&t.jsxs("div",{className:N.clsx(n.header,W&&n.headerDivided),children:[t.jsxs("div",{className:n.headerMain,children:[y!=null&&t.jsx(C.IconButton,{variant:"filled",size:"sm",color:L,nonClickable:!0,"aria-hidden":!0,className:n.icon,children:y}),(i!=null||f!=null)&&t.jsxs("div",{className:n.headerText,children:[i!=null&&t.jsx("div",{id:q,className:n.title,children:i}),f!=null&&t.jsx("div",{id:R,className:n.subtitle,children:f})]})]}),D&&t.jsx(C.IconButton,{variant:"filled",color:"primary",size:"sm",className:n.close,"aria-label":U("common.close"),onClick:o,children:t.jsx(j.Icon,{name:"Close"})})]}),h!=null&&t.jsx("div",{ref:M,className:N.clsx(n.body,B),children:h}),b!=null&&t.jsx("div",{ref:T,className:n.footer,children:b})]})})});exports.Modal=be;
2
+ //# sourceMappingURL=Modal-CxODxl81.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal-Du-uVpYw.cjs","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { Overlay } from '../Overlay/Overlay'\nimport styles from './Modal.module.css'\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'fullScreen'\nexport type ModalScrollBehavior = 'inside' | 'outside'\nexport type ModalPlacement = 'center' | 'left' | 'right'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Focusable descendants used by the focus trap + initial focus. */\n// every clause excludes tabindex=\"-1\" so decorative/programmatic-only nodes (e.g. the header's\n// `nonClickable aria-hidden` IconButton) don't count as trap boundaries or initial-focus targets\nconst FOCUSABLE =\n 'a[href]:not([tabindex=\"-1\"]), button:not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), input:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [tabindex]:not([tabindex=\"-1\"])'\n\n/** Body FIELDS — where a form modal's initial focus lands (buttons / links in content don't count). */\nconst FIELD =\n 'input:not([type=\"hidden\"]):not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [contenteditable]:not([contenteditable=\"false\"]):not([tabindex=\"-1\"])'\n\n/**\n * Focus the first candidate that actually takes focus (a field inside a hidden tab panel won't). A radio\n * lands on its group's checked option, as Tab would.\n */\nfunction focusFirst(candidates: ArrayLike<HTMLElement>): boolean {\n const list = Array.from(candidates)\n for (const candidate of list) {\n const el =\n candidate instanceof HTMLInputElement && candidate.type === 'radio' && !candidate.checked\n ? (list.find(\n (other) =>\n other instanceof HTMLInputElement &&\n other.type === 'radio' &&\n other.name === candidate.name &&\n other.checked,\n ) ?? candidate)\n : candidate\n el.focus({ preventScroll: true })\n if (document.activeElement === el) return true\n }\n return false\n}\n\nexport interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'color'> {\n /** Whether the modal is open — gates the portal and drives the enter animation. */\n open: boolean\n /** Called when a dismiss is requested (close button, backdrop click, or Escape). */\n onClose: () => void\n /** Preset max-width: `sm` 400 · `md` 520 · `lg` 760 px, or `fullScreen` (fills the viewport). Defaults to `md`. */\n size?: ModalSize\n /**\n * Where overflow scrolls when the content is taller than the viewport: `outside` (default — the\n * whole dialog grows and the overlay/page scrolls) or `inside` (the body scrolls while the header +\n * footer stay pinned). Ignored for side-drawer placements (`left`/`right`), which always scroll inside.\n */\n scrollBehavior?: ModalScrollBehavior\n /**\n * Where the dialog sits: `center` (default — the standard centered modal), or `left` / `right` to\n * make it a **full-height side drawer** (sheet) that slides in from that edge. A drawer takes its\n * width from `size`, fills the viewport height, and always scrolls its body inside (header + footer\n * stay pinned).\n */\n placement?: ModalPlacement\n /** Header title. When set, labels the dialog (`aria-labelledby`). */\n title?: ReactNode\n /** Muted description line under the title (e.g. a confirm prompt). */\n description?: ReactNode\n /** Leading header icon shown in a tinted box (like `Card`) — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Theme color that tints the leading icon box. Defaults to `accent`. */\n color?: ThemeColor\n /** Footer slot — right-aligned actions over a top divider (e.g. Cancel / Confirm buttons). */\n footer?: ReactNode\n /** Extra class on the scrollable body element — to tune its padding / layout (e.g. a compact confirm). */\n bodyClassName?: string\n /** Show the header × close button. Defaults to `true`. */\n showCloseButton?: boolean\n /** Close when the backdrop (outside the dialog) is clicked. Defaults to `true`. */\n closeOnBackdrop?: boolean\n /** Close when Escape is pressed. Defaults to `true`. */\n closeOnEscape?: boolean\n /** Accessible label — used when there's no `title`. */\n ariaLabel?: string\n /** Dialog body. */\n children?: ReactNode\n}\n\n/**\n * A centered, backdrop-dimmed overlay dialog. Portaled to `<body>`, it locks page scroll while open,\n * traps Tab focus inside, restores focus to the previously-focused element on close, and dismisses on\n * close button / backdrop click / Escape (each toggleable). Sizes are `sm`/`md`/`lg` (max-width caps)\n * or `fullScreen`; `scrollBehavior` picks inside-body vs. whole-dialog scrolling. `placement` turns it\n * into a full-height side drawer (`left`/`right`) that slides in from the edge. The header mirrors\n * `Card` — an optional tinted `icon` box + `title` + `description`. Controlled by `open` + `onClose`.\n * The forwarded ref points at the dialog element.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <Modal open={isOpen} onClose={close} title=\"Edit\" footer={<Button onClick={close}>Done</Button>}>\n * …\n * </Modal>\n */\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(function Modal(\n {\n open,\n onClose,\n size = 'md',\n scrollBehavior = 'outside',\n placement = 'center',\n title,\n description,\n icon,\n color = 'accent',\n footer,\n bodyClassName,\n showCloseButton = true,\n closeOnBackdrop = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n style,\n children,\n ...props\n },\n forwardedRef,\n) {\n const t = useT()\n const panelRef = useRef<HTMLDivElement | null>(null)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n const titleId = useId()\n const descId = useId()\n\n // portal + scrim + scroll-lock + fade-in + backdrop-dismiss are handled by the shared `<Overlay>`\n\n // the element focused before opening — read during the render that opens the modal, because an\n // `autoFocus` element inside moves focus on mount, before any effect could see the opener\n const openerRef = useRef<HTMLElement | null>(null)\n const wasOpenRef = useRef(false)\n if (open !== wasOpenRef.current) {\n wasOpenRef.current = open\n if (open && typeof document !== 'undefined') {\n openerRef.current = document.activeElement as HTMLElement | null\n }\n }\n\n // focus management on open — an explicit `autoFocus` inside wins; else the first body FIELD (form\n // modals land on their first input), else the first footer action (a confirm dialog lands on\n // Cancel/Confirm, a sheet on its Close), else the dialog panel itself. Never \"any control in the\n // body\": a copy / icon / link button deep in content isn't where focus should start (it would also\n // pop that button's tooltip). The Tab trap still reaches every control. Restore on close.\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n const opener = openerRef.current\n if (!panel?.contains(document.activeElement)) {\n // preventScroll so opening an `outside`-scroll modal doesn't jump the overlay to a below-fold control\n const placed =\n focusFirst(bodyRef.current?.querySelectorAll<HTMLElement>(FIELD) ?? []) ||\n focusFirst(footerRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])\n if (!placed) panel?.focus({ preventScroll: true })\n }\n // only restore if the element is still mounted (it may have unmounted while the modal was open)\n return () => {\n if (opener?.isConnected) opener.focus?.()\n }\n }, [open])\n\n // merge the panel ref (positioning/focus) with the forwarded ref (consumer access)\n const setPanelRef = (node: HTMLDivElement | null) => {\n panelRef.current = node\n if (typeof forwardedRef === 'function') forwardedRef(node)\n else if (forwardedRef) forwardedRef.current = node\n }\n\n // trap Tab within the dialog so focus can't strand on the locked page behind it (Escape + backdrop\n // dismissal live in `<Overlay>`; this fires after the overlay's own handler)\n const handleTabTrap = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab') return\n const panel = panelRef.current\n if (!panel) return\n const focusables = [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)].filter(\n (el) => el.offsetParent !== null || el === document.activeElement,\n )\n if (focusables.length === 0) {\n event.preventDefault()\n panel.focus()\n return\n }\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n const active = document.activeElement\n if (event.shiftKey && (active === first || active === panel)) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && active === last) {\n event.preventDefault()\n first.focus()\n }\n }\n\n if (!open) return null\n\n // a side drawer (left/right) is always full-height with the body scrolling inside (header/footer pinned)\n const isDrawer = placement !== 'center'\n\n const renderedIcon =\n icon == null ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n const hasHeader = title != null || description != null || renderedIcon != null || showCloseButton\n // a divider sets the header apart from the body/footer, like Card\n const headerDivided = children != null || footer != null\n\n return (\n <Overlay\n open={open}\n onClose={onClose}\n closeOnBackdrop={closeOnBackdrop}\n closeOnEscape={closeOnEscape}\n onKeyDown={handleTabTrap}\n className={styles.overlay}\n data-size={size}\n data-placement={placement}\n data-scroll={isDrawer ? 'inside' : scrollBehavior}\n >\n <div\n ref={setPanelRef}\n className={clsx(styles.modal, styles[size], className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title != null ? titleId : undefined}\n aria-label={title == null ? ariaLabel : undefined}\n aria-describedby={description != null ? descId : undefined}\n tabIndex={-1}\n style={style as CSSProperties}\n {...props}\n >\n {hasHeader && (\n <div className={clsx(styles.header, headerDivided && styles.headerDivided)}>\n <div className={styles.headerMain}>\n {renderedIcon != null && (\n <IconButton\n variant=\"filled\"\n size=\"sm\"\n color={color}\n nonClickable\n aria-hidden\n className={styles.icon}\n >\n {renderedIcon}\n </IconButton>\n )}\n {(title != null || description != null) && (\n <div className={styles.headerText}>\n {title != null && (\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n )}\n {description != null && (\n <div id={descId} className={styles.subtitle}>\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n {showCloseButton && (\n <IconButton\n variant=\"filled\"\n color=\"primary\"\n size=\"sm\"\n className={styles.close}\n aria-label={t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )}\n {children != null && (\n <div ref={bodyRef} className={clsx(styles.body, bodyClassName)}>\n {children}\n </div>\n )}\n {footer != null && (\n <div ref={footerRef} className={styles.footer}>\n {footer}\n </div>\n )}\n </div>\n </Overlay>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","FOCUSABLE","FIELD","focusFirst","candidates","list","candidate","el","other","Modal","forwardRef","open","onClose","size","scrollBehavior","placement","title","description","icon","color","footer","bodyClassName","showCloseButton","closeOnBackdrop","closeOnEscape","ariaLabel","className","style","children","props","forwardedRef","t","useT","panelRef","useRef","bodyRef","footerRef","titleId","useId","descId","openerRef","wasOpenRef","useEffect","panel","opener","_a","_b","setPanelRef","node","handleTabTrap","event","focusables","first","last","active","isDrawer","renderedIcon","jsx","Icon","hasHeader","headerDivided","Overlay","styles","jsxs","clsx","IconButton"],"mappings":"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"}
1
+ {"version":3,"file":"Modal-CxODxl81.cjs","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { Overlay } from '../Overlay/Overlay'\nimport styles from './Modal.module.css'\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'fullScreen'\nexport type ModalScrollBehavior = 'inside' | 'outside'\nexport type ModalPlacement = 'center' | 'left' | 'right'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Focusable descendants used by the focus trap + initial focus. */\n// every clause excludes tabindex=\"-1\" so decorative/programmatic-only nodes (e.g. the header's\n// `nonClickable aria-hidden` IconButton) don't count as trap boundaries or initial-focus targets\nconst FOCUSABLE =\n 'a[href]:not([tabindex=\"-1\"]), button:not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), input:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [tabindex]:not([tabindex=\"-1\"])'\n\n/** Body FIELDS — where a form modal's initial focus lands (buttons / links in content don't count). */\nconst FIELD =\n 'input:not([type=\"hidden\"]):not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [contenteditable]:not([contenteditable=\"false\"]):not([tabindex=\"-1\"])'\n\n/**\n * Focus the first candidate that actually takes focus (a field inside a hidden tab panel won't). A radio\n * lands on its group's checked option, as Tab would.\n */\nfunction focusFirst(candidates: ArrayLike<HTMLElement>): boolean {\n const list = Array.from(candidates)\n for (const candidate of list) {\n const el =\n candidate instanceof HTMLInputElement && candidate.type === 'radio' && !candidate.checked\n ? (list.find(\n (other) =>\n other instanceof HTMLInputElement &&\n other.type === 'radio' &&\n other.name === candidate.name &&\n other.checked,\n ) ?? candidate)\n : candidate\n el.focus({ preventScroll: true })\n if (document.activeElement === el) return true\n }\n return false\n}\n\nexport interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'color'> {\n /** Whether the modal is open — gates the portal and drives the enter animation. */\n open: boolean\n /** Called when a dismiss is requested (close button, backdrop click, or Escape). */\n onClose: () => void\n /** Preset max-width: `sm` 400 · `md` 520 · `lg` 760 px, or `fullScreen` (fills the viewport). Defaults to `md`. */\n size?: ModalSize\n /**\n * Where overflow scrolls when the content is taller than the viewport: `outside` (default — the\n * whole dialog grows and the overlay/page scrolls) or `inside` (the body scrolls while the header +\n * footer stay pinned). Ignored for side-drawer placements (`left`/`right`), which always scroll inside.\n */\n scrollBehavior?: ModalScrollBehavior\n /**\n * Where the dialog sits: `center` (default — the standard centered modal), or `left` / `right` to\n * make it a **full-height side drawer** (sheet) that slides in from that edge. A drawer takes its\n * width from `size`, fills the viewport height, and always scrolls its body inside (header + footer\n * stay pinned).\n */\n placement?: ModalPlacement\n /** Header title. When set, labels the dialog (`aria-labelledby`). */\n title?: ReactNode\n /** Muted description line under the title (e.g. a confirm prompt). */\n description?: ReactNode\n /** Leading header icon shown in a tinted box (like `Card`) — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Theme color that tints the leading icon box. Defaults to `accent`. */\n color?: ThemeColor\n /** Footer slot — right-aligned actions over a top divider (e.g. Cancel / Confirm buttons). */\n footer?: ReactNode\n /** Extra class on the scrollable body element — to tune its padding / layout (e.g. a compact confirm). */\n bodyClassName?: string\n /** Show the header × close button. Defaults to `true`. */\n showCloseButton?: boolean\n /** Close when the backdrop (outside the dialog) is clicked. Defaults to `true`. */\n closeOnBackdrop?: boolean\n /** Close when Escape is pressed. Defaults to `true`. */\n closeOnEscape?: boolean\n /** Accessible label — used when there's no `title`. */\n ariaLabel?: string\n /** Dialog body. */\n children?: ReactNode\n}\n\n/**\n * A centered, backdrop-dimmed overlay dialog. Portaled to `<body>`, it locks page scroll while open,\n * traps Tab focus inside, restores focus to the previously-focused element on close, and dismisses on\n * close button / backdrop click / Escape (each toggleable). Sizes are `sm`/`md`/`lg` (max-width caps)\n * or `fullScreen`; `scrollBehavior` picks inside-body vs. whole-dialog scrolling. `placement` turns it\n * into a full-height side drawer (`left`/`right`) that slides in from the edge. The header mirrors\n * `Card` — an optional tinted `icon` box + `title` + `description`. Controlled by `open` + `onClose`.\n * The forwarded ref points at the dialog element.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <Modal open={isOpen} onClose={close} title=\"Edit\" footer={<Button onClick={close}>Done</Button>}>\n * …\n * </Modal>\n */\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(function Modal(\n {\n open,\n onClose,\n size = 'md',\n scrollBehavior = 'outside',\n placement = 'center',\n title,\n description,\n icon,\n color = 'accent',\n footer,\n bodyClassName,\n showCloseButton = true,\n closeOnBackdrop = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n style,\n children,\n ...props\n },\n forwardedRef,\n) {\n const t = useT()\n const panelRef = useRef<HTMLDivElement | null>(null)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n const titleId = useId()\n const descId = useId()\n\n // portal + scrim + scroll-lock + fade-in + backdrop-dismiss are handled by the shared `<Overlay>`\n\n // the element focused before opening — read during the render that opens the modal, because an\n // `autoFocus` element inside moves focus on mount, before any effect could see the opener\n const openerRef = useRef<HTMLElement | null>(null)\n const wasOpenRef = useRef(false)\n if (open !== wasOpenRef.current) {\n wasOpenRef.current = open\n if (open && typeof document !== 'undefined') {\n openerRef.current = document.activeElement as HTMLElement | null\n }\n }\n\n // focus management on open — an explicit `autoFocus` inside wins; else the first body FIELD (form\n // modals land on their first input), else the first footer action (a confirm dialog lands on\n // Cancel/Confirm, a sheet on its Close), else the dialog panel itself. Never \"any control in the\n // body\": a copy / icon / link button deep in content isn't where focus should start (it would also\n // pop that button's tooltip). The Tab trap still reaches every control. Restore on close.\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n const opener = openerRef.current\n if (!panel?.contains(document.activeElement)) {\n // preventScroll so opening an `outside`-scroll modal doesn't jump the overlay to a below-fold control\n const placed =\n focusFirst(bodyRef.current?.querySelectorAll<HTMLElement>(FIELD) ?? []) ||\n focusFirst(footerRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])\n if (!placed) panel?.focus({ preventScroll: true })\n }\n // only restore if the element is still mounted (it may have unmounted while the modal was open)\n return () => {\n if (opener?.isConnected) opener.focus?.()\n }\n }, [open])\n\n // merge the panel ref (positioning/focus) with the forwarded ref (consumer access)\n const setPanelRef = (node: HTMLDivElement | null) => {\n panelRef.current = node\n if (typeof forwardedRef === 'function') forwardedRef(node)\n else if (forwardedRef) forwardedRef.current = node\n }\n\n // trap Tab within the dialog so focus can't strand on the locked page behind it (Escape + backdrop\n // dismissal live in `<Overlay>`; this fires after the overlay's own handler)\n const handleTabTrap = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab') return\n const panel = panelRef.current\n if (!panel) return\n const focusables = [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)].filter(\n (el) => el.offsetParent !== null || el === document.activeElement,\n )\n if (focusables.length === 0) {\n event.preventDefault()\n panel.focus()\n return\n }\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n const active = document.activeElement\n if (event.shiftKey && (active === first || active === panel)) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && active === last) {\n event.preventDefault()\n first.focus()\n }\n }\n\n if (!open) return null\n\n // a side drawer (left/right) is always full-height with the body scrolling inside (header/footer pinned)\n const isDrawer = placement !== 'center'\n\n const renderedIcon =\n icon == null ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n const hasHeader = title != null || description != null || renderedIcon != null || showCloseButton\n // a divider sets the header apart from the body/footer, like Card\n const headerDivided = children != null || footer != null\n\n return (\n <Overlay\n open={open}\n onClose={onClose}\n closeOnBackdrop={closeOnBackdrop}\n closeOnEscape={closeOnEscape}\n onKeyDown={handleTabTrap}\n className={styles.overlay}\n data-size={size}\n data-placement={placement}\n data-scroll={isDrawer ? 'inside' : scrollBehavior}\n >\n <div\n ref={setPanelRef}\n className={clsx(styles.modal, styles[size], className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title != null ? titleId : undefined}\n aria-label={title == null ? ariaLabel : undefined}\n aria-describedby={description != null ? descId : undefined}\n tabIndex={-1}\n style={style as CSSProperties}\n {...props}\n >\n {hasHeader && (\n <div className={clsx(styles.header, headerDivided && styles.headerDivided)}>\n <div className={styles.headerMain}>\n {renderedIcon != null && (\n <IconButton\n variant=\"filled\"\n size=\"sm\"\n color={color}\n nonClickable\n aria-hidden\n className={styles.icon}\n >\n {renderedIcon}\n </IconButton>\n )}\n {(title != null || description != null) && (\n <div className={styles.headerText}>\n {title != null && (\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n )}\n {description != null && (\n <div id={descId} className={styles.subtitle}>\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n {showCloseButton && (\n <IconButton\n variant=\"filled\"\n color=\"primary\"\n size=\"sm\"\n className={styles.close}\n aria-label={t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )}\n {children != null && (\n <div ref={bodyRef} className={clsx(styles.body, bodyClassName)}>\n {children}\n </div>\n )}\n {footer != null && (\n <div ref={footerRef} className={styles.footer}>\n {footer}\n </div>\n )}\n </div>\n </Overlay>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","FOCUSABLE","FIELD","focusFirst","candidates","list","candidate","el","other","Modal","forwardRef","open","onClose","size","scrollBehavior","placement","title","description","icon","color","footer","bodyClassName","showCloseButton","closeOnBackdrop","closeOnEscape","ariaLabel","className","style","children","props","forwardedRef","t","useT","panelRef","useRef","bodyRef","footerRef","titleId","useId","descId","openerRef","wasOpenRef","useEffect","panel","opener","_a","_b","setPanelRef","node","handleTabTrap","event","focusables","first","last","active","isDrawer","renderedIcon","jsx","Icon","hasHeader","headerDivided","Overlay","styles","jsxs","clsx","IconButton"],"mappings":"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"}
@@ -2,9 +2,9 @@ import { jsx as a, jsxs as x } from "react/jsx-runtime";
2
2
  import { forwardRef as Z, useRef as _, useId as R, useEffect as $ } from "react";
3
3
  import { clsx as E } from "clsx";
4
4
  import { b as L, a as ee } from "./Icon-B7DJn8Tw.js";
5
- import { I as q } from "./IconButton-EaExCXRq.js";
5
+ import { I as q } from "./IconButton-re6xITGO.js";
6
6
  import { O as te } from "./Overlay-DiL0ZARH.js";
7
- import { a as ne } from "./ConfigProvider-CYgmMH4j.js";
7
+ import { a as ne } from "./ConfigProvider-DVDGtCUc.js";
8
8
  const le = "_overlay_1lotx_3", oe = "_modal_1lotx_25", ae = "_sm_1lotx_48", se = "_md_1lotx_51", ce = "_lg_1lotx_54", re = "_fullScreen_1lotx_57", ie = "_header_1lotx_74", de = "_headerDivided_1lotx_83", ue = "_headerMain_1lotx_86", fe = "_icon_1lotx_93", me = "_headerText_1lotx_96", _e = "_title_1lotx_103", be = "_subtitle_1lotx_115", xe = "_close_1lotx_127", he = "_body_1lotx_132", ve = "_footer_1lotx_143", t = {
9
9
  overlay: le,
10
10
  modal: oe,
@@ -151,4 +151,4 @@ const ge = Z(function({
151
151
  export {
152
152
  ge as M
153
153
  };
154
- //# sourceMappingURL=Modal-1rIBMvKH.js.map
154
+ //# sourceMappingURL=Modal-DpoiMMM3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal-1rIBMvKH.js","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { Overlay } from '../Overlay/Overlay'\nimport styles from './Modal.module.css'\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'fullScreen'\nexport type ModalScrollBehavior = 'inside' | 'outside'\nexport type ModalPlacement = 'center' | 'left' | 'right'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Focusable descendants used by the focus trap + initial focus. */\n// every clause excludes tabindex=\"-1\" so decorative/programmatic-only nodes (e.g. the header's\n// `nonClickable aria-hidden` IconButton) don't count as trap boundaries or initial-focus targets\nconst FOCUSABLE =\n 'a[href]:not([tabindex=\"-1\"]), button:not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), input:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [tabindex]:not([tabindex=\"-1\"])'\n\n/** Body FIELDS — where a form modal's initial focus lands (buttons / links in content don't count). */\nconst FIELD =\n 'input:not([type=\"hidden\"]):not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [contenteditable]:not([contenteditable=\"false\"]):not([tabindex=\"-1\"])'\n\n/**\n * Focus the first candidate that actually takes focus (a field inside a hidden tab panel won't). A radio\n * lands on its group's checked option, as Tab would.\n */\nfunction focusFirst(candidates: ArrayLike<HTMLElement>): boolean {\n const list = Array.from(candidates)\n for (const candidate of list) {\n const el =\n candidate instanceof HTMLInputElement && candidate.type === 'radio' && !candidate.checked\n ? (list.find(\n (other) =>\n other instanceof HTMLInputElement &&\n other.type === 'radio' &&\n other.name === candidate.name &&\n other.checked,\n ) ?? candidate)\n : candidate\n el.focus({ preventScroll: true })\n if (document.activeElement === el) return true\n }\n return false\n}\n\nexport interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'color'> {\n /** Whether the modal is open — gates the portal and drives the enter animation. */\n open: boolean\n /** Called when a dismiss is requested (close button, backdrop click, or Escape). */\n onClose: () => void\n /** Preset max-width: `sm` 400 · `md` 520 · `lg` 760 px, or `fullScreen` (fills the viewport). Defaults to `md`. */\n size?: ModalSize\n /**\n * Where overflow scrolls when the content is taller than the viewport: `outside` (default — the\n * whole dialog grows and the overlay/page scrolls) or `inside` (the body scrolls while the header +\n * footer stay pinned). Ignored for side-drawer placements (`left`/`right`), which always scroll inside.\n */\n scrollBehavior?: ModalScrollBehavior\n /**\n * Where the dialog sits: `center` (default — the standard centered modal), or `left` / `right` to\n * make it a **full-height side drawer** (sheet) that slides in from that edge. A drawer takes its\n * width from `size`, fills the viewport height, and always scrolls its body inside (header + footer\n * stay pinned).\n */\n placement?: ModalPlacement\n /** Header title. When set, labels the dialog (`aria-labelledby`). */\n title?: ReactNode\n /** Muted description line under the title (e.g. a confirm prompt). */\n description?: ReactNode\n /** Leading header icon shown in a tinted box (like `Card`) — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Theme color that tints the leading icon box. Defaults to `accent`. */\n color?: ThemeColor\n /** Footer slot — right-aligned actions over a top divider (e.g. Cancel / Confirm buttons). */\n footer?: ReactNode\n /** Extra class on the scrollable body element — to tune its padding / layout (e.g. a compact confirm). */\n bodyClassName?: string\n /** Show the header × close button. Defaults to `true`. */\n showCloseButton?: boolean\n /** Close when the backdrop (outside the dialog) is clicked. Defaults to `true`. */\n closeOnBackdrop?: boolean\n /** Close when Escape is pressed. Defaults to `true`. */\n closeOnEscape?: boolean\n /** Accessible label — used when there's no `title`. */\n ariaLabel?: string\n /** Dialog body. */\n children?: ReactNode\n}\n\n/**\n * A centered, backdrop-dimmed overlay dialog. Portaled to `<body>`, it locks page scroll while open,\n * traps Tab focus inside, restores focus to the previously-focused element on close, and dismisses on\n * close button / backdrop click / Escape (each toggleable). Sizes are `sm`/`md`/`lg` (max-width caps)\n * or `fullScreen`; `scrollBehavior` picks inside-body vs. whole-dialog scrolling. `placement` turns it\n * into a full-height side drawer (`left`/`right`) that slides in from the edge. The header mirrors\n * `Card` — an optional tinted `icon` box + `title` + `description`. Controlled by `open` + `onClose`.\n * The forwarded ref points at the dialog element.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <Modal open={isOpen} onClose={close} title=\"Edit\" footer={<Button onClick={close}>Done</Button>}>\n * …\n * </Modal>\n */\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(function Modal(\n {\n open,\n onClose,\n size = 'md',\n scrollBehavior = 'outside',\n placement = 'center',\n title,\n description,\n icon,\n color = 'accent',\n footer,\n bodyClassName,\n showCloseButton = true,\n closeOnBackdrop = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n style,\n children,\n ...props\n },\n forwardedRef,\n) {\n const t = useT()\n const panelRef = useRef<HTMLDivElement | null>(null)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n const titleId = useId()\n const descId = useId()\n\n // portal + scrim + scroll-lock + fade-in + backdrop-dismiss are handled by the shared `<Overlay>`\n\n // the element focused before opening — read during the render that opens the modal, because an\n // `autoFocus` element inside moves focus on mount, before any effect could see the opener\n const openerRef = useRef<HTMLElement | null>(null)\n const wasOpenRef = useRef(false)\n if (open !== wasOpenRef.current) {\n wasOpenRef.current = open\n if (open && typeof document !== 'undefined') {\n openerRef.current = document.activeElement as HTMLElement | null\n }\n }\n\n // focus management on open — an explicit `autoFocus` inside wins; else the first body FIELD (form\n // modals land on their first input), else the first footer action (a confirm dialog lands on\n // Cancel/Confirm, a sheet on its Close), else the dialog panel itself. Never \"any control in the\n // body\": a copy / icon / link button deep in content isn't where focus should start (it would also\n // pop that button's tooltip). The Tab trap still reaches every control. Restore on close.\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n const opener = openerRef.current\n if (!panel?.contains(document.activeElement)) {\n // preventScroll so opening an `outside`-scroll modal doesn't jump the overlay to a below-fold control\n const placed =\n focusFirst(bodyRef.current?.querySelectorAll<HTMLElement>(FIELD) ?? []) ||\n focusFirst(footerRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])\n if (!placed) panel?.focus({ preventScroll: true })\n }\n // only restore if the element is still mounted (it may have unmounted while the modal was open)\n return () => {\n if (opener?.isConnected) opener.focus?.()\n }\n }, [open])\n\n // merge the panel ref (positioning/focus) with the forwarded ref (consumer access)\n const setPanelRef = (node: HTMLDivElement | null) => {\n panelRef.current = node\n if (typeof forwardedRef === 'function') forwardedRef(node)\n else if (forwardedRef) forwardedRef.current = node\n }\n\n // trap Tab within the dialog so focus can't strand on the locked page behind it (Escape + backdrop\n // dismissal live in `<Overlay>`; this fires after the overlay's own handler)\n const handleTabTrap = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab') return\n const panel = panelRef.current\n if (!panel) return\n const focusables = [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)].filter(\n (el) => el.offsetParent !== null || el === document.activeElement,\n )\n if (focusables.length === 0) {\n event.preventDefault()\n panel.focus()\n return\n }\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n const active = document.activeElement\n if (event.shiftKey && (active === first || active === panel)) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && active === last) {\n event.preventDefault()\n first.focus()\n }\n }\n\n if (!open) return null\n\n // a side drawer (left/right) is always full-height with the body scrolling inside (header/footer pinned)\n const isDrawer = placement !== 'center'\n\n const renderedIcon =\n icon == null ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n const hasHeader = title != null || description != null || renderedIcon != null || showCloseButton\n // a divider sets the header apart from the body/footer, like Card\n const headerDivided = children != null || footer != null\n\n return (\n <Overlay\n open={open}\n onClose={onClose}\n closeOnBackdrop={closeOnBackdrop}\n closeOnEscape={closeOnEscape}\n onKeyDown={handleTabTrap}\n className={styles.overlay}\n data-size={size}\n data-placement={placement}\n data-scroll={isDrawer ? 'inside' : scrollBehavior}\n >\n <div\n ref={setPanelRef}\n className={clsx(styles.modal, styles[size], className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title != null ? titleId : undefined}\n aria-label={title == null ? ariaLabel : undefined}\n aria-describedby={description != null ? descId : undefined}\n tabIndex={-1}\n style={style as CSSProperties}\n {...props}\n >\n {hasHeader && (\n <div className={clsx(styles.header, headerDivided && styles.headerDivided)}>\n <div className={styles.headerMain}>\n {renderedIcon != null && (\n <IconButton\n variant=\"filled\"\n size=\"sm\"\n color={color}\n nonClickable\n aria-hidden\n className={styles.icon}\n >\n {renderedIcon}\n </IconButton>\n )}\n {(title != null || description != null) && (\n <div className={styles.headerText}>\n {title != null && (\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n )}\n {description != null && (\n <div id={descId} className={styles.subtitle}>\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n {showCloseButton && (\n <IconButton\n variant=\"filled\"\n color=\"primary\"\n size=\"sm\"\n className={styles.close}\n aria-label={t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )}\n {children != null && (\n <div ref={bodyRef} className={clsx(styles.body, bodyClassName)}>\n {children}\n </div>\n )}\n {footer != null && (\n <div ref={footerRef} className={styles.footer}>\n {footer}\n </div>\n )}\n </div>\n </Overlay>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","FOCUSABLE","FIELD","focusFirst","candidates","list","candidate","el","other","Modal","forwardRef","open","onClose","size","scrollBehavior","placement","title","description","icon","color","footer","bodyClassName","showCloseButton","closeOnBackdrop","closeOnEscape","ariaLabel","className","style","children","props","forwardedRef","t","useT","panelRef","useRef","bodyRef","footerRef","titleId","useId","descId","openerRef","wasOpenRef","useEffect","panel","opener","_a","_b","setPanelRef","node","handleTabTrap","event","focusables","first","last","active","isDrawer","renderedIcon","jsx","Icon","hasHeader","headerDivided","Overlay","styles","jsxs","clsx","IconButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;GAsBMA,KAAgB,IAAI,IAAYC,EAAU,GAK1CC,IACJ,kPAGIC,KACJ;AAMF,SAASC,EAAWC,GAA6C;AAC/D,QAAMC,IAAO,MAAM,KAAKD,CAAU;AAClC,aAAWE,KAAaD,GAAM;AAC5B,UAAME,IACJD,aAAqB,oBAAoBA,EAAU,SAAS,WAAW,CAACA,EAAU,UAC7ED,EAAK;AAAA,MACJ,CAACG,MACCA,aAAiB,oBACjBA,EAAM,SAAS,WACfA,EAAM,SAASF,EAAU,QACzBE,EAAM;AAAA,IAAA,KACLF,IACLA;AAEN,QADAC,EAAG,MAAM,EAAE,eAAe,GAAA,CAAM,GAC5B,SAAS,kBAAkBA,EAAI,QAAO;AAAA,EAC5C;AACA,SAAO;AACT;AA6DO,MAAME,KAAQC,EAAuC,SAC1D;AAAA,EACE,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,gBAAAC,IAAiB;AAAA,EACjB,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC,IAAkB;AAAA,EAClB,iBAAAC,IAAkB;AAAA,EAClB,eAAAC,IAAgB;AAAA,EAChB,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAIC,GAAA,GACJC,IAAWC,EAA8B,IAAI,GAC7CC,IAAUD,EAA8B,IAAI,GAC5CE,IAAYF,EAA8B,IAAI,GAC9CG,IAAUC,EAAA,GACVC,IAASD,EAAA,GAMTE,IAAYN,EAA2B,IAAI,GAC3CO,IAAaP,EAAO,EAAK;AAC/B,EAAIvB,MAAS8B,EAAW,YACtBA,EAAW,UAAU9B,GACjBA,KAAQ,OAAO,WAAa,QAC9B6B,EAAU,UAAU,SAAS,iBASjCE,EAAU,MAAM;;AACd,QAAI,CAAC/B,EAAM;AACX,UAAMgC,IAAQV,EAAS,SACjBW,IAASJ,EAAU;AACzB,WAAKG,KAAA,QAAAA,EAAO,SAAS,SAAS,kBAG1BxC,IAAW0C,IAAAV,EAAQ,YAAR,gBAAAU,EAAiB,iBAA8B3C,QAAU,CAAA,CAAE,KACtEC,IAAW2C,IAAAV,EAAU,YAAV,gBAAAU,EAAmB,iBAA8B7C,OAAc,EAAE,KACjE0C,KAAA,QAAAA,EAAO,MAAM,EAAE,eAAe,OAGtC,MAAM;;AACX,MAAIC,KAAA,QAAAA,EAAQ,iBAAaC,IAAAD,EAAO,UAAP,QAAAC,EAAA,KAAAD;AAAA,IAC3B;AAAA,EACF,GAAG,CAACjC,CAAI,CAAC;AAGT,QAAMoC,IAAc,CAACC,MAAgC;AACnD,IAAAf,EAAS,UAAUe,GACf,OAAOlB,KAAiB,aAAYA,EAAakB,CAAI,IAChDlB,QAA2B,UAAUkB;AAAA,EAChD,GAIMC,IAAgB,CAACC,MAAyC;AAC9D,QAAIA,EAAM,QAAQ,MAAO;AACzB,UAAMP,IAAQV,EAAS;AACvB,QAAI,CAACU,EAAO;AACZ,UAAMQ,IAAa,CAAC,GAAGR,EAAM,iBAA8B1C,CAAS,CAAC,EAAE;AAAA,MACrE,CAACM,MAAOA,EAAG,iBAAiB,QAAQA,MAAO,SAAS;AAAA,IAAA;AAEtD,QAAI4C,EAAW,WAAW,GAAG;AAC3B,MAAAD,EAAM,eAAA,GACNP,EAAM,MAAA;AACN;AAAA,IACF;AACA,UAAMS,IAAQD,EAAW,CAAC,GACpBE,IAAOF,EAAWA,EAAW,SAAS,CAAC,GACvCG,IAAS,SAAS;AACxB,IAAIJ,EAAM,aAAaI,MAAWF,KAASE,MAAWX,MACpDO,EAAM,eAAA,GACNG,EAAK,MAAA,KACI,CAACH,EAAM,YAAYI,MAAWD,MACvCH,EAAM,eAAA,GACNE,EAAM,MAAA;AAAA,EAEV;AAEA,MAAI,CAACzC,EAAM,QAAO;AAGlB,QAAM4C,IAAWxC,MAAc,UAEzByC,IACJtC,KAAQ,OAAO,OAAO,OAAOA,KAAS,YAAYnB,GAAc,IAAImB,CAAI,IACtE,gBAAAuC,EAACC,GAAA,EAAK,MAAMxC,GAAkB,IAE9BA,GAGEyC,IAAY3C,KAAS,QAAQC,KAAe,QAAQuC,KAAgB,QAAQlC,GAE5EsC,IAAgBhC,KAAY,QAAQR,KAAU;AAEpD,SACE,gBAAAqC;AAAA,IAACI;AAAA,IAAA;AAAA,MACC,MAAAlD;AAAA,MACA,SAAAC;AAAA,MACA,iBAAAW;AAAA,MACA,eAAAC;AAAA,MACA,WAAWyB;AAAA,MACX,WAAWa,EAAO;AAAA,MAClB,aAAWjD;AAAA,MACX,kBAAgBE;AAAA,MAChB,eAAawC,IAAW,WAAWzC;AAAA,MAEnC,UAAA,gBAAAiD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKhB;AAAA,UACL,WAAWiB,EAAKF,EAAO,OAAOA,EAAOjD,CAAI,GAAGa,CAAS;AAAA,UACrD,MAAK;AAAA,UACL,cAAW;AAAA,UACX,mBAAiBV,KAAS,OAAOqB,IAAU;AAAA,UAC3C,cAAYrB,KAAS,OAAOS,IAAY;AAAA,UACxC,oBAAkBR,KAAe,OAAOsB,IAAS;AAAA,UACjD,UAAU;AAAA,UACV,OAAAZ;AAAA,UACC,GAAGE;AAAA,UAEH,UAAA;AAAA,YAAA8B,KACC,gBAAAI,EAAC,SAAI,WAAWC,EAAKF,EAAO,QAAQF,KAAiBE,EAAO,aAAa,GACvE,UAAA;AAAA,cAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,YACpB,UAAA;AAAA,gBAAAN,KAAgB,QACf,gBAAAC;AAAA,kBAACQ;AAAA,kBAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,OAAA9C;AAAA,oBACA,cAAY;AAAA,oBACZ,eAAW;AAAA,oBACX,WAAW2C,EAAO;AAAA,oBAEjB,UAAAN;AAAA,kBAAA;AAAA,gBAAA;AAAA,iBAGHxC,KAAS,QAAQC,KAAe,2BAC/B,OAAA,EAAI,WAAW6C,EAAO,YACpB,UAAA;AAAA,kBAAA9C,KAAS,0BACP,OAAA,EAAI,IAAIqB,GAAS,WAAWyB,EAAO,OACjC,UAAA9C,EAAA,CACH;AAAA,kBAEDC,KAAe,QACd,gBAAAwC,EAAC,OAAA,EAAI,IAAIlB,GAAQ,WAAWuB,EAAO,UAChC,UAAA7C,EAAA,CACH;AAAA,gBAAA,EAAA,CAEJ;AAAA,cAAA,GAEJ;AAAA,cACCK,KACC,gBAAAmC;AAAA,gBAACQ;AAAA,gBAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,OAAM;AAAA,kBACN,MAAK;AAAA,kBACL,WAAWH,EAAO;AAAA,kBAClB,cAAY/B,EAAE,cAAc;AAAA,kBAC5B,SAASnB;AAAA,kBAET,UAAA,gBAAA6C,EAACC,GAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,gBAAA;AAAA,cAAA;AAAA,YACrB,GAEJ;AAAA,YAED9B,KAAY,QACX,gBAAA6B,EAAC,OAAA,EAAI,KAAKtB,GAAS,WAAW6B,EAAKF,EAAO,MAAMzC,CAAa,GAC1D,UAAAO,EAAA,CACH;AAAA,YAEDR,KAAU,QACT,gBAAAqC,EAAC,OAAA,EAAI,KAAKrB,GAAW,WAAW0B,EAAO,QACpC,UAAA1C,EAAA,CACH;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGN,CAAC;"}
1
+ {"version":3,"file":"Modal-DpoiMMM3.js","sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { Overlay } from '../Overlay/Overlay'\nimport styles from './Modal.module.css'\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'fullScreen'\nexport type ModalScrollBehavior = 'inside' | 'outside'\nexport type ModalPlacement = 'center' | 'left' | 'right'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Focusable descendants used by the focus trap + initial focus. */\n// every clause excludes tabindex=\"-1\" so decorative/programmatic-only nodes (e.g. the header's\n// `nonClickable aria-hidden` IconButton) don't count as trap boundaries or initial-focus targets\nconst FOCUSABLE =\n 'a[href]:not([tabindex=\"-1\"]), button:not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), input:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [tabindex]:not([tabindex=\"-1\"])'\n\n/** Body FIELDS — where a form modal's initial focus lands (buttons / links in content don't count). */\nconst FIELD =\n 'input:not([type=\"hidden\"]):not(:disabled):not([tabindex=\"-1\"]), textarea:not(:disabled):not([tabindex=\"-1\"]), select:not(:disabled):not([tabindex=\"-1\"]), [contenteditable]:not([contenteditable=\"false\"]):not([tabindex=\"-1\"])'\n\n/**\n * Focus the first candidate that actually takes focus (a field inside a hidden tab panel won't). A radio\n * lands on its group's checked option, as Tab would.\n */\nfunction focusFirst(candidates: ArrayLike<HTMLElement>): boolean {\n const list = Array.from(candidates)\n for (const candidate of list) {\n const el =\n candidate instanceof HTMLInputElement && candidate.type === 'radio' && !candidate.checked\n ? (list.find(\n (other) =>\n other instanceof HTMLInputElement &&\n other.type === 'radio' &&\n other.name === candidate.name &&\n other.checked,\n ) ?? candidate)\n : candidate\n el.focus({ preventScroll: true })\n if (document.activeElement === el) return true\n }\n return false\n}\n\nexport interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'color'> {\n /** Whether the modal is open — gates the portal and drives the enter animation. */\n open: boolean\n /** Called when a dismiss is requested (close button, backdrop click, or Escape). */\n onClose: () => void\n /** Preset max-width: `sm` 400 · `md` 520 · `lg` 760 px, or `fullScreen` (fills the viewport). Defaults to `md`. */\n size?: ModalSize\n /**\n * Where overflow scrolls when the content is taller than the viewport: `outside` (default — the\n * whole dialog grows and the overlay/page scrolls) or `inside` (the body scrolls while the header +\n * footer stay pinned). Ignored for side-drawer placements (`left`/`right`), which always scroll inside.\n */\n scrollBehavior?: ModalScrollBehavior\n /**\n * Where the dialog sits: `center` (default — the standard centered modal), or `left` / `right` to\n * make it a **full-height side drawer** (sheet) that slides in from that edge. A drawer takes its\n * width from `size`, fills the viewport height, and always scrolls its body inside (header + footer\n * stay pinned).\n */\n placement?: ModalPlacement\n /** Header title. When set, labels the dialog (`aria-labelledby`). */\n title?: ReactNode\n /** Muted description line under the title (e.g. a confirm prompt). */\n description?: ReactNode\n /** Leading header icon shown in a tinted box (like `Card`) — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Theme color that tints the leading icon box. Defaults to `accent`. */\n color?: ThemeColor\n /** Footer slot — right-aligned actions over a top divider (e.g. Cancel / Confirm buttons). */\n footer?: ReactNode\n /** Extra class on the scrollable body element — to tune its padding / layout (e.g. a compact confirm). */\n bodyClassName?: string\n /** Show the header × close button. Defaults to `true`. */\n showCloseButton?: boolean\n /** Close when the backdrop (outside the dialog) is clicked. Defaults to `true`. */\n closeOnBackdrop?: boolean\n /** Close when Escape is pressed. Defaults to `true`. */\n closeOnEscape?: boolean\n /** Accessible label — used when there's no `title`. */\n ariaLabel?: string\n /** Dialog body. */\n children?: ReactNode\n}\n\n/**\n * A centered, backdrop-dimmed overlay dialog. Portaled to `<body>`, it locks page scroll while open,\n * traps Tab focus inside, restores focus to the previously-focused element on close, and dismisses on\n * close button / backdrop click / Escape (each toggleable). Sizes are `sm`/`md`/`lg` (max-width caps)\n * or `fullScreen`; `scrollBehavior` picks inside-body vs. whole-dialog scrolling. `placement` turns it\n * into a full-height side drawer (`left`/`right`) that slides in from the edge. The header mirrors\n * `Card` — an optional tinted `icon` box + `title` + `description`. Controlled by `open` + `onClose`.\n * The forwarded ref points at the dialog element.\n *\n * @example\n * const { isOpen, open, close } = useDisclosure()\n * <Modal open={isOpen} onClose={close} title=\"Edit\" footer={<Button onClick={close}>Done</Button>}>\n * …\n * </Modal>\n */\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(function Modal(\n {\n open,\n onClose,\n size = 'md',\n scrollBehavior = 'outside',\n placement = 'center',\n title,\n description,\n icon,\n color = 'accent',\n footer,\n bodyClassName,\n showCloseButton = true,\n closeOnBackdrop = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n style,\n children,\n ...props\n },\n forwardedRef,\n) {\n const t = useT()\n const panelRef = useRef<HTMLDivElement | null>(null)\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const footerRef = useRef<HTMLDivElement | null>(null)\n const titleId = useId()\n const descId = useId()\n\n // portal + scrim + scroll-lock + fade-in + backdrop-dismiss are handled by the shared `<Overlay>`\n\n // the element focused before opening — read during the render that opens the modal, because an\n // `autoFocus` element inside moves focus on mount, before any effect could see the opener\n const openerRef = useRef<HTMLElement | null>(null)\n const wasOpenRef = useRef(false)\n if (open !== wasOpenRef.current) {\n wasOpenRef.current = open\n if (open && typeof document !== 'undefined') {\n openerRef.current = document.activeElement as HTMLElement | null\n }\n }\n\n // focus management on open — an explicit `autoFocus` inside wins; else the first body FIELD (form\n // modals land on their first input), else the first footer action (a confirm dialog lands on\n // Cancel/Confirm, a sheet on its Close), else the dialog panel itself. Never \"any control in the\n // body\": a copy / icon / link button deep in content isn't where focus should start (it would also\n // pop that button's tooltip). The Tab trap still reaches every control. Restore on close.\n useEffect(() => {\n if (!open) return\n const panel = panelRef.current\n const opener = openerRef.current\n if (!panel?.contains(document.activeElement)) {\n // preventScroll so opening an `outside`-scroll modal doesn't jump the overlay to a below-fold control\n const placed =\n focusFirst(bodyRef.current?.querySelectorAll<HTMLElement>(FIELD) ?? []) ||\n focusFirst(footerRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? [])\n if (!placed) panel?.focus({ preventScroll: true })\n }\n // only restore if the element is still mounted (it may have unmounted while the modal was open)\n return () => {\n if (opener?.isConnected) opener.focus?.()\n }\n }, [open])\n\n // merge the panel ref (positioning/focus) with the forwarded ref (consumer access)\n const setPanelRef = (node: HTMLDivElement | null) => {\n panelRef.current = node\n if (typeof forwardedRef === 'function') forwardedRef(node)\n else if (forwardedRef) forwardedRef.current = node\n }\n\n // trap Tab within the dialog so focus can't strand on the locked page behind it (Escape + backdrop\n // dismissal live in `<Overlay>`; this fires after the overlay's own handler)\n const handleTabTrap = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab') return\n const panel = panelRef.current\n if (!panel) return\n const focusables = [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)].filter(\n (el) => el.offsetParent !== null || el === document.activeElement,\n )\n if (focusables.length === 0) {\n event.preventDefault()\n panel.focus()\n return\n }\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n const active = document.activeElement\n if (event.shiftKey && (active === first || active === panel)) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && active === last) {\n event.preventDefault()\n first.focus()\n }\n }\n\n if (!open) return null\n\n // a side drawer (left/right) is always full-height with the body scrolling inside (header/footer pinned)\n const isDrawer = placement !== 'center'\n\n const renderedIcon =\n icon == null ? null : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n const hasHeader = title != null || description != null || renderedIcon != null || showCloseButton\n // a divider sets the header apart from the body/footer, like Card\n const headerDivided = children != null || footer != null\n\n return (\n <Overlay\n open={open}\n onClose={onClose}\n closeOnBackdrop={closeOnBackdrop}\n closeOnEscape={closeOnEscape}\n onKeyDown={handleTabTrap}\n className={styles.overlay}\n data-size={size}\n data-placement={placement}\n data-scroll={isDrawer ? 'inside' : scrollBehavior}\n >\n <div\n ref={setPanelRef}\n className={clsx(styles.modal, styles[size], className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title != null ? titleId : undefined}\n aria-label={title == null ? ariaLabel : undefined}\n aria-describedby={description != null ? descId : undefined}\n tabIndex={-1}\n style={style as CSSProperties}\n {...props}\n >\n {hasHeader && (\n <div className={clsx(styles.header, headerDivided && styles.headerDivided)}>\n <div className={styles.headerMain}>\n {renderedIcon != null && (\n <IconButton\n variant=\"filled\"\n size=\"sm\"\n color={color}\n nonClickable\n aria-hidden\n className={styles.icon}\n >\n {renderedIcon}\n </IconButton>\n )}\n {(title != null || description != null) && (\n <div className={styles.headerText}>\n {title != null && (\n <div id={titleId} className={styles.title}>\n {title}\n </div>\n )}\n {description != null && (\n <div id={descId} className={styles.subtitle}>\n {description}\n </div>\n )}\n </div>\n )}\n </div>\n {showCloseButton && (\n <IconButton\n variant=\"filled\"\n color=\"primary\"\n size=\"sm\"\n className={styles.close}\n aria-label={t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )}\n {children != null && (\n <div ref={bodyRef} className={clsx(styles.body, bodyClassName)}>\n {children}\n </div>\n )}\n {footer != null && (\n <div ref={footerRef} className={styles.footer}>\n {footer}\n </div>\n )}\n </div>\n </Overlay>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","FOCUSABLE","FIELD","focusFirst","candidates","list","candidate","el","other","Modal","forwardRef","open","onClose","size","scrollBehavior","placement","title","description","icon","color","footer","bodyClassName","showCloseButton","closeOnBackdrop","closeOnEscape","ariaLabel","className","style","children","props","forwardedRef","t","useT","panelRef","useRef","bodyRef","footerRef","titleId","useId","descId","openerRef","wasOpenRef","useEffect","panel","opener","_a","_b","setPanelRef","node","handleTabTrap","event","focusables","first","last","active","isDrawer","renderedIcon","jsx","Icon","hasHeader","headerDivided","Overlay","styles","jsxs","clsx","IconButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;GAsBMA,KAAgB,IAAI,IAAYC,EAAU,GAK1CC,IACJ,kPAGIC,KACJ;AAMF,SAASC,EAAWC,GAA6C;AAC/D,QAAMC,IAAO,MAAM,KAAKD,CAAU;AAClC,aAAWE,KAAaD,GAAM;AAC5B,UAAME,IACJD,aAAqB,oBAAoBA,EAAU,SAAS,WAAW,CAACA,EAAU,UAC7ED,EAAK;AAAA,MACJ,CAACG,MACCA,aAAiB,oBACjBA,EAAM,SAAS,WACfA,EAAM,SAASF,EAAU,QACzBE,EAAM;AAAA,IAAA,KACLF,IACLA;AAEN,QADAC,EAAG,MAAM,EAAE,eAAe,GAAA,CAAM,GAC5B,SAAS,kBAAkBA,EAAI,QAAO;AAAA,EAC5C;AACA,SAAO;AACT;AA6DO,MAAME,KAAQC,EAAuC,SAC1D;AAAA,EACE,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,gBAAAC,IAAiB;AAAA,EACjB,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC,IAAkB;AAAA,EAClB,iBAAAC,IAAkB;AAAA,EAClB,eAAAC,IAAgB;AAAA,EAChB,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAIC,GAAA,GACJC,IAAWC,EAA8B,IAAI,GAC7CC,IAAUD,EAA8B,IAAI,GAC5CE,IAAYF,EAA8B,IAAI,GAC9CG,IAAUC,EAAA,GACVC,IAASD,EAAA,GAMTE,IAAYN,EAA2B,IAAI,GAC3CO,IAAaP,EAAO,EAAK;AAC/B,EAAIvB,MAAS8B,EAAW,YACtBA,EAAW,UAAU9B,GACjBA,KAAQ,OAAO,WAAa,QAC9B6B,EAAU,UAAU,SAAS,iBASjCE,EAAU,MAAM;;AACd,QAAI,CAAC/B,EAAM;AACX,UAAMgC,IAAQV,EAAS,SACjBW,IAASJ,EAAU;AACzB,WAAKG,KAAA,QAAAA,EAAO,SAAS,SAAS,kBAG1BxC,IAAW0C,IAAAV,EAAQ,YAAR,gBAAAU,EAAiB,iBAA8B3C,QAAU,CAAA,CAAE,KACtEC,IAAW2C,IAAAV,EAAU,YAAV,gBAAAU,EAAmB,iBAA8B7C,OAAc,EAAE,KACjE0C,KAAA,QAAAA,EAAO,MAAM,EAAE,eAAe,OAGtC,MAAM;;AACX,MAAIC,KAAA,QAAAA,EAAQ,iBAAaC,IAAAD,EAAO,UAAP,QAAAC,EAAA,KAAAD;AAAA,IAC3B;AAAA,EACF,GAAG,CAACjC,CAAI,CAAC;AAGT,QAAMoC,IAAc,CAACC,MAAgC;AACnD,IAAAf,EAAS,UAAUe,GACf,OAAOlB,KAAiB,aAAYA,EAAakB,CAAI,IAChDlB,QAA2B,UAAUkB;AAAA,EAChD,GAIMC,IAAgB,CAACC,MAAyC;AAC9D,QAAIA,EAAM,QAAQ,MAAO;AACzB,UAAMP,IAAQV,EAAS;AACvB,QAAI,CAACU,EAAO;AACZ,UAAMQ,IAAa,CAAC,GAAGR,EAAM,iBAA8B1C,CAAS,CAAC,EAAE;AAAA,MACrE,CAACM,MAAOA,EAAG,iBAAiB,QAAQA,MAAO,SAAS;AAAA,IAAA;AAEtD,QAAI4C,EAAW,WAAW,GAAG;AAC3B,MAAAD,EAAM,eAAA,GACNP,EAAM,MAAA;AACN;AAAA,IACF;AACA,UAAMS,IAAQD,EAAW,CAAC,GACpBE,IAAOF,EAAWA,EAAW,SAAS,CAAC,GACvCG,IAAS,SAAS;AACxB,IAAIJ,EAAM,aAAaI,MAAWF,KAASE,MAAWX,MACpDO,EAAM,eAAA,GACNG,EAAK,MAAA,KACI,CAACH,EAAM,YAAYI,MAAWD,MACvCH,EAAM,eAAA,GACNE,EAAM,MAAA;AAAA,EAEV;AAEA,MAAI,CAACzC,EAAM,QAAO;AAGlB,QAAM4C,IAAWxC,MAAc,UAEzByC,IACJtC,KAAQ,OAAO,OAAO,OAAOA,KAAS,YAAYnB,GAAc,IAAImB,CAAI,IACtE,gBAAAuC,EAACC,GAAA,EAAK,MAAMxC,GAAkB,IAE9BA,GAGEyC,IAAY3C,KAAS,QAAQC,KAAe,QAAQuC,KAAgB,QAAQlC,GAE5EsC,IAAgBhC,KAAY,QAAQR,KAAU;AAEpD,SACE,gBAAAqC;AAAA,IAACI;AAAA,IAAA;AAAA,MACC,MAAAlD;AAAA,MACA,SAAAC;AAAA,MACA,iBAAAW;AAAA,MACA,eAAAC;AAAA,MACA,WAAWyB;AAAA,MACX,WAAWa,EAAO;AAAA,MAClB,aAAWjD;AAAA,MACX,kBAAgBE;AAAA,MAChB,eAAawC,IAAW,WAAWzC;AAAA,MAEnC,UAAA,gBAAAiD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKhB;AAAA,UACL,WAAWiB,EAAKF,EAAO,OAAOA,EAAOjD,CAAI,GAAGa,CAAS;AAAA,UACrD,MAAK;AAAA,UACL,cAAW;AAAA,UACX,mBAAiBV,KAAS,OAAOqB,IAAU;AAAA,UAC3C,cAAYrB,KAAS,OAAOS,IAAY;AAAA,UACxC,oBAAkBR,KAAe,OAAOsB,IAAS;AAAA,UACjD,UAAU;AAAA,UACV,OAAAZ;AAAA,UACC,GAAGE;AAAA,UAEH,UAAA;AAAA,YAAA8B,KACC,gBAAAI,EAAC,SAAI,WAAWC,EAAKF,EAAO,QAAQF,KAAiBE,EAAO,aAAa,GACvE,UAAA;AAAA,cAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,YACpB,UAAA;AAAA,gBAAAN,KAAgB,QACf,gBAAAC;AAAA,kBAACQ;AAAA,kBAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,OAAA9C;AAAA,oBACA,cAAY;AAAA,oBACZ,eAAW;AAAA,oBACX,WAAW2C,EAAO;AAAA,oBAEjB,UAAAN;AAAA,kBAAA;AAAA,gBAAA;AAAA,iBAGHxC,KAAS,QAAQC,KAAe,2BAC/B,OAAA,EAAI,WAAW6C,EAAO,YACpB,UAAA;AAAA,kBAAA9C,KAAS,0BACP,OAAA,EAAI,IAAIqB,GAAS,WAAWyB,EAAO,OACjC,UAAA9C,EAAA,CACH;AAAA,kBAEDC,KAAe,QACd,gBAAAwC,EAAC,OAAA,EAAI,IAAIlB,GAAQ,WAAWuB,EAAO,UAChC,UAAA7C,EAAA,CACH;AAAA,gBAAA,EAAA,CAEJ;AAAA,cAAA,GAEJ;AAAA,cACCK,KACC,gBAAAmC;AAAA,gBAACQ;AAAA,gBAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,OAAM;AAAA,kBACN,MAAK;AAAA,kBACL,WAAWH,EAAO;AAAA,kBAClB,cAAY/B,EAAE,cAAc;AAAA,kBAC5B,SAASnB;AAAA,kBAET,UAAA,gBAAA6C,EAACC,GAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,gBAAA;AAAA,cAAA;AAAA,YACrB,GAEJ;AAAA,YAED9B,KAAY,QACX,gBAAA6B,EAAC,OAAA,EAAI,KAAKtB,GAAS,WAAW6B,EAAKF,EAAO,MAAMzC,CAAa,GAC1D,UAAAO,EAAA,CACH;AAAA,YAEDR,KAAU,QACT,gBAAAqC,EAAC,OAAA,EAAI,KAAKrB,GAAW,WAAW0B,EAAO,QACpC,UAAA1C,EAAA,CACH;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGN,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";const s=require("react/jsx-runtime"),d=require("react"),C=require("clsx"),ie=require("./formContext-bTWrqdEV.cjs"),ae=require("./Chip-BdCZ44I8.cjs"),K=require("./Icon-CBg21lKA.cjs"),O=require("./useOptionMenu-B40OOVsO.cjs"),W=require("./Typography-d97DdbNd.cjs"),de=require("./ConfigProvider-Cf-awvZs.cjs"),ue="_field_1lirs_1",_e="_fullWidth_1lirs_7",he="_label_1lirs_12",pe="_required_1lirs_21",fe="_control_1lirs_27",ve="_filled_1lirs_47",me="_open_1lirs_51",xe="_error_1lirs_56",ye="_disabled_1lirs_64",be="_chips_1lirs_31",ge="_value_1lirs_84",je="_valueLabel_1lirs_91",qe="_placeholder_1lirs_96",Ie="_clear_1lirs_100",Ne="_chevron_1lirs_119",Se="_sm_1lirs_129",Te="_md_1lirs_133",we="_lg_1lirs_137",Ce="_helper_1lirs_142",r={field:ue,fullWidth:_e,label:he,required:pe,control:fe,filled:ve,open:me,error:xe,disabled:ye,chips:be,value:ge,valueLabel:je,placeholder:qe,clear:Ie,chevron:Ne,sm:Se,md:Te,lg:we,helper:Ce},De=d.forwardRef(function({label:h,options:D,size:u="md",error:A,helperText:F,required:R=!1,fullWidth:$=!0,disabled:c=!1,value:b,defaultValue:E,onChange:g,placeholder:H,color:Q="primary",clearable:U=!0,searchable:j=!1,searchPlaceholder:G,onSearchChange:J,loading:X=!1,loadingText:Y,noOptionsText:Z,name:i,id:z,className:ee,style:le},_){const re=d.useId(),p=z??re,q=`${p}-label`,k=`${p}-helper`,I=de.useT(),f=ie.useFormContext(),v=!!(f&&i),o=v?f.field(i):void 0,se=b!==void 0?b:v?f.values[i]??[]:void 0,B=b!==void 0||v,[oe,ne]=d.useState(E??[]),n=B?se:oe,N=A??(o==null?void 0:o.error)??!1,S=F??(o==null?void 0:o.helperText),T=e=>{B||ne(e),v&&f.setValue(i,e),g==null||g(e)},a=d.useRef(null),m=d.useRef(void 0);m.current=o?()=>o.onBlur({}):void 0;const te=d.useCallback(e=>{a.current=e,typeof _=="function"?_(e):_&&(_.current=e)},[_]),M=e=>T(n.filter(l=>l!==e)),t=O.useOptionMenu({idBase:p,options:D,isSelected:e=>n.includes(e.value),onPick:e=>T(n.includes(e.value)?n.filter(l=>l!==e.value):[...n,e.value]),closeOnPick:!1,highlightSelected:!1,searchable:j,onSearchChange:J,disabled:c,focusRef:a,onClose:()=>{var e;return(e=m.current)==null?void 0:e.call(m)}}),{open:x}=t,L=e=>{if(e.key==="Backspace"&&x&&(!j||t.searchQuery==="")&&n.length>0){e.preventDefault(),M(n[n.length-1]);return}t.handleKeyDown(e)},ce=e=>{var y,V;const l=e.relatedTarget;l&&((y=t.popoverRef.current)!=null&&y.contains(l)||(V=a.current)!=null&&V.contains(l))||o==null||o.onBlur(e)},P=u==="sm"?16:u==="md"?14:12,w=n.length>0;return s.jsxs("div",{className:C.clsx(r.field,r[u],$&&r.fullWidth,N&&r.error,c&&r.disabled,ee),style:le,children:[h!=null&&s.jsxs("span",{id:q,className:r.label,onClick:()=>{var e;return!c&&((e=a.current)==null?void 0:e.focus())},children:[s.jsx(W.Typography,{as:"span",variant:"bodySmall",color:"muted",children:h}),R&&s.jsx("span",{className:r.required,"aria-hidden":"true",children:"*"})]}),s.jsxs("div",{ref:te,id:p,...i?{name:i}:{},role:"combobox",tabIndex:c?-1:0,"aria-haspopup":"listbox","aria-expanded":x,"aria-controls":x?t.listboxId:void 0,"aria-activedescendant":j?void 0:t.activeId,"aria-labelledby":h!=null?q:void 0,"aria-disabled":c||void 0,"aria-required":R||void 0,"aria-invalid":N||void 0,"aria-describedby":S!=null?k:void 0,className:C.clsx(r.control,x&&r.open,w&&r.filled),onClick:t.toggleMenu,onKeyDown:L,onBlur:ce,children:[w?s.jsx("span",{className:r.chips,children:n.map(e=>{const l=D.find(y=>y.value===e);return s.jsx(ae.Chip,{size:u,color:Q,disabled:c,onDelete:()=>M(e),deleteLabel:I("fileUploader.remove",{name:(l==null?void 0:l.label)??e}),deleteTabIndex:-1,children:(l==null?void 0:l.label)??e},e)})}):s.jsx("span",{className:C.clsx(r.value,r.placeholder),children:s.jsx("span",{className:r.valueLabel,children:H??I("select.placeholder")})}),U&&w&&!c&&s.jsx("button",{type:"button",className:r.clear,"aria-label":I("multiSelect.clearAll"),tabIndex:-1,onMouseDown:e=>e.preventDefault(),onClick:e=>{var l;e.stopPropagation(),T([]),(l=a.current)==null||l.focus()},children:s.jsx(K.Icon,{name:"CloseCircle",size:"sm"})}),s.jsx(K.Icon,{name:"ArrowDown4",className:r.chevron,style:{width:P,height:P},"aria-hidden":"true"})]}),s.jsx(O.OptionMenu,{menu:t,anchorRef:a,size:u,searchPlaceholder:G,loading:X,loadingText:Y,noOptionsText:Z,multiselectable:!0,labelledBy:h!=null?q:void 0,onSearchKeyDown:L}),S!=null&&s.jsx(W.Typography,{as:"span",id:k,variant:"bodySmall",color:N?"error":"muted",className:r.helper,children:S})]})});exports.MultiSelect=De;
2
- //# sourceMappingURL=MultiSelect-lAAaD0uL.cjs.map
1
+ "use strict";const s=require("react/jsx-runtime"),d=require("react"),C=require("clsx"),ie=require("./formContext-bTWrqdEV.cjs"),ae=require("./Chip-BpJN4rzY.cjs"),K=require("./Icon-CBg21lKA.cjs"),O=require("./useOptionMenu-CVl7VHXl.cjs"),W=require("./Typography-d97DdbNd.cjs"),de=require("./ConfigProvider-DBU6rOIA.cjs"),ue="_field_1lirs_1",_e="_fullWidth_1lirs_7",he="_label_1lirs_12",pe="_required_1lirs_21",fe="_control_1lirs_27",ve="_filled_1lirs_47",me="_open_1lirs_51",xe="_error_1lirs_56",ye="_disabled_1lirs_64",be="_chips_1lirs_31",ge="_value_1lirs_84",je="_valueLabel_1lirs_91",qe="_placeholder_1lirs_96",Ie="_clear_1lirs_100",Ne="_chevron_1lirs_119",Se="_sm_1lirs_129",Te="_md_1lirs_133",we="_lg_1lirs_137",Ce="_helper_1lirs_142",r={field:ue,fullWidth:_e,label:he,required:pe,control:fe,filled:ve,open:me,error:xe,disabled:ye,chips:be,value:ge,valueLabel:je,placeholder:qe,clear:Ie,chevron:Ne,sm:Se,md:Te,lg:we,helper:Ce},De=d.forwardRef(function({label:h,options:D,size:u="md",error:A,helperText:F,required:R=!1,fullWidth:$=!0,disabled:c=!1,value:b,defaultValue:E,onChange:g,placeholder:H,color:Q="primary",clearable:U=!0,searchable:j=!1,searchPlaceholder:G,onSearchChange:J,loading:X=!1,loadingText:Y,noOptionsText:Z,name:i,id:z,className:ee,style:le},_){const re=d.useId(),p=z??re,q=`${p}-label`,k=`${p}-helper`,I=de.useT(),f=ie.useFormContext(),v=!!(f&&i),o=v?f.field(i):void 0,se=b!==void 0?b:v?f.values[i]??[]:void 0,B=b!==void 0||v,[oe,ne]=d.useState(E??[]),n=B?se:oe,N=A??(o==null?void 0:o.error)??!1,S=F??(o==null?void 0:o.helperText),T=e=>{B||ne(e),v&&f.setValue(i,e),g==null||g(e)},a=d.useRef(null),m=d.useRef(void 0);m.current=o?()=>o.onBlur({}):void 0;const te=d.useCallback(e=>{a.current=e,typeof _=="function"?_(e):_&&(_.current=e)},[_]),M=e=>T(n.filter(l=>l!==e)),t=O.useOptionMenu({idBase:p,options:D,isSelected:e=>n.includes(e.value),onPick:e=>T(n.includes(e.value)?n.filter(l=>l!==e.value):[...n,e.value]),closeOnPick:!1,highlightSelected:!1,searchable:j,onSearchChange:J,disabled:c,focusRef:a,onClose:()=>{var e;return(e=m.current)==null?void 0:e.call(m)}}),{open:x}=t,L=e=>{if(e.key==="Backspace"&&x&&(!j||t.searchQuery==="")&&n.length>0){e.preventDefault(),M(n[n.length-1]);return}t.handleKeyDown(e)},ce=e=>{var y,V;const l=e.relatedTarget;l&&((y=t.popoverRef.current)!=null&&y.contains(l)||(V=a.current)!=null&&V.contains(l))||o==null||o.onBlur(e)},P=u==="sm"?16:u==="md"?14:12,w=n.length>0;return s.jsxs("div",{className:C.clsx(r.field,r[u],$&&r.fullWidth,N&&r.error,c&&r.disabled,ee),style:le,children:[h!=null&&s.jsxs("span",{id:q,className:r.label,onClick:()=>{var e;return!c&&((e=a.current)==null?void 0:e.focus())},children:[s.jsx(W.Typography,{as:"span",variant:"bodySmall",color:"muted",children:h}),R&&s.jsx("span",{className:r.required,"aria-hidden":"true",children:"*"})]}),s.jsxs("div",{ref:te,id:p,...i?{name:i}:{},role:"combobox",tabIndex:c?-1:0,"aria-haspopup":"listbox","aria-expanded":x,"aria-controls":x?t.listboxId:void 0,"aria-activedescendant":j?void 0:t.activeId,"aria-labelledby":h!=null?q:void 0,"aria-disabled":c||void 0,"aria-required":R||void 0,"aria-invalid":N||void 0,"aria-describedby":S!=null?k:void 0,className:C.clsx(r.control,x&&r.open,w&&r.filled),onClick:t.toggleMenu,onKeyDown:L,onBlur:ce,children:[w?s.jsx("span",{className:r.chips,children:n.map(e=>{const l=D.find(y=>y.value===e);return s.jsx(ae.Chip,{size:u,color:Q,disabled:c,onDelete:()=>M(e),deleteLabel:I("fileUploader.remove",{name:(l==null?void 0:l.label)??e}),deleteTabIndex:-1,children:(l==null?void 0:l.label)??e},e)})}):s.jsx("span",{className:C.clsx(r.value,r.placeholder),children:s.jsx("span",{className:r.valueLabel,children:H??I("select.placeholder")})}),U&&w&&!c&&s.jsx("button",{type:"button",className:r.clear,"aria-label":I("multiSelect.clearAll"),tabIndex:-1,onMouseDown:e=>e.preventDefault(),onClick:e=>{var l;e.stopPropagation(),T([]),(l=a.current)==null||l.focus()},children:s.jsx(K.Icon,{name:"CloseCircle",size:"sm"})}),s.jsx(K.Icon,{name:"ArrowDown4",className:r.chevron,style:{width:P,height:P},"aria-hidden":"true"})]}),s.jsx(O.OptionMenu,{menu:t,anchorRef:a,size:u,searchPlaceholder:G,loading:X,loadingText:Y,noOptionsText:Z,multiselectable:!0,labelledBy:h!=null?q:void 0,onSearchKeyDown:L}),S!=null&&s.jsx(W.Typography,{as:"span",id:k,variant:"bodySmall",color:N?"error":"muted",className:r.helper,children:S})]})});exports.MultiSelect=De;
2
+ //# sourceMappingURL=MultiSelect-2GouMRTl.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelect-lAAaD0uL.cjs","sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useFormContext } from '../../form/formContext'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Chip } from '../Chip'\nimport { Icon } from '../Icon'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport type { SelectOption, SelectSize } from '../Select'\nimport styles from './MultiSelect.module.css'\n\nexport interface MultiSelectProps {\n /** Label rendered above the field. */\n label?: ReactNode\n /** The selectable options. */\n options: SelectOption[]\n /** Preset size — control height, font, chips and option density. */\n size?: SelectSize\n /** Marks the field invalid: red border/ring + the `helperText` in the error color. */\n error?: boolean\n /** Helper / validation text under the field. Adopts the error color while `error`. */\n helperText?: ReactNode\n /** Adds a red asterisk after the label. */\n required?: boolean\n /** Stretches the field to fill its container width. Defaults to `true`. */\n fullWidth?: boolean\n /** Disables the field. */\n disabled?: boolean\n /** Controlled value — the chosen options' `value`s. */\n value?: string[]\n /** Initial value for uncontrolled use. */\n defaultValue?: string[]\n /** Fires with the next array of selected values. */\n onChange?: (value: string[]) => void\n /** Text shown in the trigger when nothing is selected. Defaults to `\"Select…\"`. */\n placeholder?: string\n /** Theme palette token tinting the selected chips. Defaults to `primary`. */\n color?: ThemeColor\n /** Shows a clear (×) button in the trigger when anything is selected. Defaults to `true`. */\n clearable?: boolean\n /** Adds a search box inside the popover that filters options by label. */\n searchable?: boolean\n /** Placeholder for the search box. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string\n /**\n * Fires with the search query as the user types. **Providing this switches off the built-in\n * local filtering** — you own `options` (e.g. fetch them from a server for the current query).\n */\n onSearchChange?: (query: string) => void\n /** Shows a loading indicator in the popover (e.g. while fetching server-side search results). */\n loading?: boolean\n /** Text shown next to the loader while `loading`. Defaults to `\"Loading…\"`. */\n loadingText?: ReactNode\n /**\n * Shown in the popover when no option matches. Defaults to `\"No Options\"`. Pass a function\n * `(query) => node` to vary the message by the current search text — e.g. a \"Type to search\" hint\n * while it's empty vs a \"No results\" message after typing.\n */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Form field name — auto-binds to a surrounding `<Form>` (value is a `string[]`). */\n name?: string\n /** Id for the trigger (label association). */\n id?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A labeled multi-select — the `string[]` sibling of `Select`. The trigger shows the chosen options\n * as deletable `Chip`s (wrapping, growing like `TagsField`) or a placeholder; clicking it opens the\n * same `Dropdown`-style popover (portaled, flips, scroll-locked, trigger-width, animated — shared via\n * `useFloatingPanel`). Options render as `ListItem`s in a `role=\"listbox\"` `aria-multiselectable`\n * list; selecting **toggles** an option and keeps the popover open, the chosen ones showing a tick.\n * Full keyboard support (Arrow/Home/End, Enter/Space to toggle, Escape to close, type-ahead) and\n * ARIA. Optionally `searchable` + `clearable`; pass `onSearchChange` to drive the search\n * **server-side** (you own `options` — local filtering is skipped) with a `loading` indicator.\n * Controlled (`value` + `onChange`) or uncontrolled\n * (`defaultValue`), and binds to a surrounding `<Form>` by `name` (value = `string[]`; validate with\n * e.g. `z.array(z.string()).min(1, 'Pick at least one')`). Token-only styling.\n */\nexport const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(function MultiSelect(\n {\n label,\n options,\n size = 'md',\n error,\n helperText,\n required = false,\n fullWidth = true,\n disabled = false,\n value,\n defaultValue,\n onChange,\n placeholder,\n color = 'primary',\n clearable = true,\n searchable = false,\n searchPlaceholder,\n onSearchChange,\n loading = false,\n loadingText,\n noOptionsText,\n name,\n id: idProp,\n className,\n style,\n },\n ref,\n) {\n const reactId = useId()\n const id = idProp ?? reactId\n const labelId = `${id}-label`\n const helperId = `${id}-helper`\n\n // ── value (controlled / form-bound / uncontrolled) — always a string[] ─────────────────────────\n // Read the RAW form value (field().value String-coerces, which would flatten the array).\n const t = useT()\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const externalValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string[] | undefined) ?? [])\n : undefined\n const isControlled = value !== undefined || isFormBound\n const [internal, setInternal] = useState<string[]>(defaultValue ?? [])\n const selectedValues = isControlled ? externalValue! : internal\n\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const commit = (next: string[]) => {\n if (!isControlled) setInternal(next)\n if (isFormBound) form!.setValue(name!, next)\n onChange?.(next)\n }\n\n // ── the option popover (state + keys shared with Select / PhoneField) — stays open on pick ─────\n const triggerRef = useRef<HTMLDivElement | null>(null)\n const fieldBlur = useRef<(() => void) | undefined>(undefined)\n fieldBlur.current = bound ? () => bound.onBlur({} as FocusEvent<HTMLInputElement>) : undefined\n\n const setTriggerRef = useCallback(\n (node: HTMLDivElement | null) => {\n triggerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node\n },\n [ref],\n )\n\n const removeValue = (v: string) => commit(selectedValues.filter((x) => x !== v))\n\n const menu = useOptionMenu({\n idBase: id,\n options,\n isSelected: (o) => selectedValues.includes(o.value),\n onPick: (o) =>\n commit(\n selectedValues.includes(o.value)\n ? selectedValues.filter((v) => v !== o.value)\n : [...selectedValues, o.value],\n ),\n closeOnPick: false,\n highlightSelected: false,\n searchable,\n onSearchChange,\n disabled,\n focusRef: triggerRef,\n onClose: () => fieldBlur.current?.(),\n })\n const { open } = menu\n\n // Backspace removes the last chip while the search box is empty (or there's none); else the shared keys\n const handleKeyDown = (event: ReactKeyboardEvent) => {\n if (\n event.key === 'Backspace' &&\n open &&\n (!searchable || menu.searchQuery === '') &&\n selectedValues.length > 0\n ) {\n event.preventDefault()\n removeValue(selectedValues[selectedValues.length - 1])\n return\n }\n menu.handleKeyDown(event)\n }\n\n const handleTriggerBlur = (event: FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget as Node | null\n if (next && (menu.popoverRef.current?.contains(next) || triggerRef.current?.contains(next)))\n return\n bound?.onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // chevron size per field size: sm 16 · md 14 · lg 12\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const hasValue = selectedValues.length > 0\n\n return (\n <div\n className={clsx(\n styles.field,\n styles[size],\n fullWidth && styles.fullWidth,\n resolvedError && styles.error,\n disabled && styles.disabled,\n className,\n )}\n style={style}\n >\n {label != null && (\n <span\n id={labelId}\n className={styles.label}\n onClick={() => !disabled && triggerRef.current?.focus()}\n >\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={styles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div\n ref={setTriggerRef}\n id={id}\n {...(name ? { name } : {})}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? menu.listboxId : undefined}\n aria-activedescendant={searchable ? undefined : menu.activeId}\n aria-labelledby={label != null ? labelId : undefined}\n aria-disabled={disabled || undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedError || undefined}\n aria-describedby={resolvedHelperText != null ? helperId : undefined}\n className={clsx(styles.control, open && styles.open, hasValue && styles.filled)}\n onClick={menu.toggleMenu}\n onKeyDown={handleKeyDown}\n onBlur={handleTriggerBlur}\n >\n {hasValue ? (\n <span className={styles.chips}>\n {selectedValues.map((v) => {\n const opt = options.find((o) => o.value === v)\n return (\n <Chip\n key={v}\n size={size}\n color={color}\n disabled={disabled}\n onDelete={() => removeValue(v)}\n deleteLabel={t('fileUploader.remove', { name: opt?.label ?? v })}\n // the combobox owns keyboard focus — keep chip deletes out of the tab order\n deleteTabIndex={-1}\n >\n {opt?.label ?? v}\n </Chip>\n )\n })}\n </span>\n ) : (\n <span className={clsx(styles.value, styles.placeholder)}>\n <span className={styles.valueLabel}>{placeholder ?? t('select.placeholder')}</span>\n </span>\n )}\n\n {clearable && hasValue && !disabled && (\n <button\n type=\"button\"\n className={styles.clear}\n aria-label={t('multiSelect.clearAll')}\n tabIndex={-1}\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.stopPropagation()\n commit([])\n triggerRef.current?.focus()\n }}\n >\n <Icon name=\"CloseCircle\" size=\"sm\" />\n </button>\n )}\n\n <Icon\n name=\"ArrowDown4\"\n className={styles.chevron}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={triggerRef}\n size={size}\n searchPlaceholder={searchPlaceholder}\n loading={loading}\n loadingText={loadingText}\n noOptionsText={noOptionsText}\n multiselectable\n labelledBy={label != null ? labelId : undefined}\n onSearchKeyDown={handleKeyDown}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={styles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n"],"names":["MultiSelect","forwardRef","label","options","size","error","helperText","required","fullWidth","disabled","value","defaultValue","onChange","placeholder","color","clearable","searchable","searchPlaceholder","onSearchChange","loading","loadingText","noOptionsText","name","idProp","className","style","ref","reactId","useId","id","labelId","helperId","t","useT","form","useFormContext","isFormBound","bound","externalValue","isControlled","internal","setInternal","useState","selectedValues","resolvedError","resolvedHelperText","commit","next","triggerRef","useRef","fieldBlur","setTriggerRef","useCallback","node","removeValue","v","x","menu","useOptionMenu","o","_a","open","handleKeyDown","event","handleTriggerBlur","_b","chevronPx","hasValue","jsxs","clsx","styles","jsx","Typography","opt","Chip","Icon","OptionMenu"],"mappings":"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"}
1
+ {"version":3,"file":"MultiSelect-2GouMRTl.cjs","sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useFormContext } from '../../form/formContext'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Chip } from '../Chip'\nimport { Icon } from '../Icon'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport type { SelectOption, SelectSize } from '../Select'\nimport styles from './MultiSelect.module.css'\n\nexport interface MultiSelectProps {\n /** Label rendered above the field. */\n label?: ReactNode\n /** The selectable options. */\n options: SelectOption[]\n /** Preset size — control height, font, chips and option density. */\n size?: SelectSize\n /** Marks the field invalid: red border/ring + the `helperText` in the error color. */\n error?: boolean\n /** Helper / validation text under the field. Adopts the error color while `error`. */\n helperText?: ReactNode\n /** Adds a red asterisk after the label. */\n required?: boolean\n /** Stretches the field to fill its container width. Defaults to `true`. */\n fullWidth?: boolean\n /** Disables the field. */\n disabled?: boolean\n /** Controlled value — the chosen options' `value`s. */\n value?: string[]\n /** Initial value for uncontrolled use. */\n defaultValue?: string[]\n /** Fires with the next array of selected values. */\n onChange?: (value: string[]) => void\n /** Text shown in the trigger when nothing is selected. Defaults to `\"Select…\"`. */\n placeholder?: string\n /** Theme palette token tinting the selected chips. Defaults to `primary`. */\n color?: ThemeColor\n /** Shows a clear (×) button in the trigger when anything is selected. Defaults to `true`. */\n clearable?: boolean\n /** Adds a search box inside the popover that filters options by label. */\n searchable?: boolean\n /** Placeholder for the search box. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string\n /**\n * Fires with the search query as the user types. **Providing this switches off the built-in\n * local filtering** — you own `options` (e.g. fetch them from a server for the current query).\n */\n onSearchChange?: (query: string) => void\n /** Shows a loading indicator in the popover (e.g. while fetching server-side search results). */\n loading?: boolean\n /** Text shown next to the loader while `loading`. Defaults to `\"Loading…\"`. */\n loadingText?: ReactNode\n /**\n * Shown in the popover when no option matches. Defaults to `\"No Options\"`. Pass a function\n * `(query) => node` to vary the message by the current search text — e.g. a \"Type to search\" hint\n * while it's empty vs a \"No results\" message after typing.\n */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Form field name — auto-binds to a surrounding `<Form>` (value is a `string[]`). */\n name?: string\n /** Id for the trigger (label association). */\n id?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A labeled multi-select — the `string[]` sibling of `Select`. The trigger shows the chosen options\n * as deletable `Chip`s (wrapping, growing like `TagsField`) or a placeholder; clicking it opens the\n * same `Dropdown`-style popover (portaled, flips, scroll-locked, trigger-width, animated — shared via\n * `useFloatingPanel`). Options render as `ListItem`s in a `role=\"listbox\"` `aria-multiselectable`\n * list; selecting **toggles** an option and keeps the popover open, the chosen ones showing a tick.\n * Full keyboard support (Arrow/Home/End, Enter/Space to toggle, Escape to close, type-ahead) and\n * ARIA. Optionally `searchable` + `clearable`; pass `onSearchChange` to drive the search\n * **server-side** (you own `options` — local filtering is skipped) with a `loading` indicator.\n * Controlled (`value` + `onChange`) or uncontrolled\n * (`defaultValue`), and binds to a surrounding `<Form>` by `name` (value = `string[]`; validate with\n * e.g. `z.array(z.string()).min(1, 'Pick at least one')`). Token-only styling.\n */\nexport const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(function MultiSelect(\n {\n label,\n options,\n size = 'md',\n error,\n helperText,\n required = false,\n fullWidth = true,\n disabled = false,\n value,\n defaultValue,\n onChange,\n placeholder,\n color = 'primary',\n clearable = true,\n searchable = false,\n searchPlaceholder,\n onSearchChange,\n loading = false,\n loadingText,\n noOptionsText,\n name,\n id: idProp,\n className,\n style,\n },\n ref,\n) {\n const reactId = useId()\n const id = idProp ?? reactId\n const labelId = `${id}-label`\n const helperId = `${id}-helper`\n\n // ── value (controlled / form-bound / uncontrolled) — always a string[] ─────────────────────────\n // Read the RAW form value (field().value String-coerces, which would flatten the array).\n const t = useT()\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const externalValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string[] | undefined) ?? [])\n : undefined\n const isControlled = value !== undefined || isFormBound\n const [internal, setInternal] = useState<string[]>(defaultValue ?? [])\n const selectedValues = isControlled ? externalValue! : internal\n\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const commit = (next: string[]) => {\n if (!isControlled) setInternal(next)\n if (isFormBound) form!.setValue(name!, next)\n onChange?.(next)\n }\n\n // ── the option popover (state + keys shared with Select / PhoneField) — stays open on pick ─────\n const triggerRef = useRef<HTMLDivElement | null>(null)\n const fieldBlur = useRef<(() => void) | undefined>(undefined)\n fieldBlur.current = bound ? () => bound.onBlur({} as FocusEvent<HTMLInputElement>) : undefined\n\n const setTriggerRef = useCallback(\n (node: HTMLDivElement | null) => {\n triggerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node\n },\n [ref],\n )\n\n const removeValue = (v: string) => commit(selectedValues.filter((x) => x !== v))\n\n const menu = useOptionMenu({\n idBase: id,\n options,\n isSelected: (o) => selectedValues.includes(o.value),\n onPick: (o) =>\n commit(\n selectedValues.includes(o.value)\n ? selectedValues.filter((v) => v !== o.value)\n : [...selectedValues, o.value],\n ),\n closeOnPick: false,\n highlightSelected: false,\n searchable,\n onSearchChange,\n disabled,\n focusRef: triggerRef,\n onClose: () => fieldBlur.current?.(),\n })\n const { open } = menu\n\n // Backspace removes the last chip while the search box is empty (or there's none); else the shared keys\n const handleKeyDown = (event: ReactKeyboardEvent) => {\n if (\n event.key === 'Backspace' &&\n open &&\n (!searchable || menu.searchQuery === '') &&\n selectedValues.length > 0\n ) {\n event.preventDefault()\n removeValue(selectedValues[selectedValues.length - 1])\n return\n }\n menu.handleKeyDown(event)\n }\n\n const handleTriggerBlur = (event: FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget as Node | null\n if (next && (menu.popoverRef.current?.contains(next) || triggerRef.current?.contains(next)))\n return\n bound?.onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // chevron size per field size: sm 16 · md 14 · lg 12\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const hasValue = selectedValues.length > 0\n\n return (\n <div\n className={clsx(\n styles.field,\n styles[size],\n fullWidth && styles.fullWidth,\n resolvedError && styles.error,\n disabled && styles.disabled,\n className,\n )}\n style={style}\n >\n {label != null && (\n <span\n id={labelId}\n className={styles.label}\n onClick={() => !disabled && triggerRef.current?.focus()}\n >\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={styles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div\n ref={setTriggerRef}\n id={id}\n {...(name ? { name } : {})}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? menu.listboxId : undefined}\n aria-activedescendant={searchable ? undefined : menu.activeId}\n aria-labelledby={label != null ? labelId : undefined}\n aria-disabled={disabled || undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedError || undefined}\n aria-describedby={resolvedHelperText != null ? helperId : undefined}\n className={clsx(styles.control, open && styles.open, hasValue && styles.filled)}\n onClick={menu.toggleMenu}\n onKeyDown={handleKeyDown}\n onBlur={handleTriggerBlur}\n >\n {hasValue ? (\n <span className={styles.chips}>\n {selectedValues.map((v) => {\n const opt = options.find((o) => o.value === v)\n return (\n <Chip\n key={v}\n size={size}\n color={color}\n disabled={disabled}\n onDelete={() => removeValue(v)}\n deleteLabel={t('fileUploader.remove', { name: opt?.label ?? v })}\n // the combobox owns keyboard focus — keep chip deletes out of the tab order\n deleteTabIndex={-1}\n >\n {opt?.label ?? v}\n </Chip>\n )\n })}\n </span>\n ) : (\n <span className={clsx(styles.value, styles.placeholder)}>\n <span className={styles.valueLabel}>{placeholder ?? t('select.placeholder')}</span>\n </span>\n )}\n\n {clearable && hasValue && !disabled && (\n <button\n type=\"button\"\n className={styles.clear}\n aria-label={t('multiSelect.clearAll')}\n tabIndex={-1}\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.stopPropagation()\n commit([])\n triggerRef.current?.focus()\n }}\n >\n <Icon name=\"CloseCircle\" size=\"sm\" />\n </button>\n )}\n\n <Icon\n name=\"ArrowDown4\"\n className={styles.chevron}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={triggerRef}\n size={size}\n searchPlaceholder={searchPlaceholder}\n loading={loading}\n loadingText={loadingText}\n noOptionsText={noOptionsText}\n multiselectable\n labelledBy={label != null ? labelId : undefined}\n onSearchKeyDown={handleKeyDown}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={styles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n"],"names":["MultiSelect","forwardRef","label","options","size","error","helperText","required","fullWidth","disabled","value","defaultValue","onChange","placeholder","color","clearable","searchable","searchPlaceholder","onSearchChange","loading","loadingText","noOptionsText","name","idProp","className","style","ref","reactId","useId","id","labelId","helperId","t","useT","form","useFormContext","isFormBound","bound","externalValue","isControlled","internal","setInternal","useState","selectedValues","resolvedError","resolvedHelperText","commit","next","triggerRef","useRef","fieldBlur","setTriggerRef","useCallback","node","removeValue","v","x","menu","useOptionMenu","o","_a","open","handleKeyDown","event","handleTriggerBlur","_b","chevronPx","hasValue","jsxs","clsx","styles","jsx","Typography","opt","Chip","Icon","OptionMenu"],"mappings":"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"}
@@ -2,11 +2,11 @@ import { jsxs as k, jsx as s } from "react/jsx-runtime";
2
2
  import { forwardRef as ie, useId as ce, useState as de, useRef as P, useCallback as ue } from "react";
3
3
  import { clsx as B } from "clsx";
4
4
  import { u as _e } from "./formContext-B7ln1Miy.js";
5
- import { C as pe } from "./Chip-C7IkFuM1.js";
5
+ import { C as pe } from "./Chip-C0x-6g2h.js";
6
6
  import { b as W } from "./Icon-B7DJn8Tw.js";
7
- import { u as me, O as fe } from "./useOptionMenu-BTt8t9SM.js";
7
+ import { u as me, O as fe } from "./useOptionMenu-BkKiZ6Ax.js";
8
8
  import { T as j } from "./Typography-ChSuxgkc.js";
9
- import { a as he } from "./ConfigProvider-CYgmMH4j.js";
9
+ import { a as he } from "./ConfigProvider-DVDGtCUc.js";
10
10
  const ve = "_field_1lirs_1", be = "_fullWidth_1lirs_7", ye = "_label_1lirs_12", ge = "_required_1lirs_21", xe = "_control_1lirs_27", Ie = "_filled_1lirs_47", Ne = "_open_1lirs_51", we = "_error_1lirs_56", De = "_disabled_1lirs_64", Se = "_chips_1lirs_31", Te = "_value_1lirs_84", ke = "_valueLabel_1lirs_91", Be = "_placeholder_1lirs_96", Ce = "_clear_1lirs_100", Me = "_chevron_1lirs_119", Re = "_sm_1lirs_129", Le = "_md_1lirs_133", Ve = "_lg_1lirs_137", qe = "_helper_1lirs_142", r = {
11
11
  field: ve,
12
12
  fullWidth: be,
@@ -216,4 +216,4 @@ const ve = "_field_1lirs_1", be = "_fullWidth_1lirs_7", ye = "_label_1lirs_12",
216
216
  export {
217
217
  Qe as M
218
218
  };
219
- //# sourceMappingURL=MultiSelect-BoqunsM9.js.map
219
+ //# sourceMappingURL=MultiSelect-B7KwEhL5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelect-BoqunsM9.js","sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useFormContext } from '../../form/formContext'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Chip } from '../Chip'\nimport { Icon } from '../Icon'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport type { SelectOption, SelectSize } from '../Select'\nimport styles from './MultiSelect.module.css'\n\nexport interface MultiSelectProps {\n /** Label rendered above the field. */\n label?: ReactNode\n /** The selectable options. */\n options: SelectOption[]\n /** Preset size — control height, font, chips and option density. */\n size?: SelectSize\n /** Marks the field invalid: red border/ring + the `helperText` in the error color. */\n error?: boolean\n /** Helper / validation text under the field. Adopts the error color while `error`. */\n helperText?: ReactNode\n /** Adds a red asterisk after the label. */\n required?: boolean\n /** Stretches the field to fill its container width. Defaults to `true`. */\n fullWidth?: boolean\n /** Disables the field. */\n disabled?: boolean\n /** Controlled value — the chosen options' `value`s. */\n value?: string[]\n /** Initial value for uncontrolled use. */\n defaultValue?: string[]\n /** Fires with the next array of selected values. */\n onChange?: (value: string[]) => void\n /** Text shown in the trigger when nothing is selected. Defaults to `\"Select…\"`. */\n placeholder?: string\n /** Theme palette token tinting the selected chips. Defaults to `primary`. */\n color?: ThemeColor\n /** Shows a clear (×) button in the trigger when anything is selected. Defaults to `true`. */\n clearable?: boolean\n /** Adds a search box inside the popover that filters options by label. */\n searchable?: boolean\n /** Placeholder for the search box. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string\n /**\n * Fires with the search query as the user types. **Providing this switches off the built-in\n * local filtering** — you own `options` (e.g. fetch them from a server for the current query).\n */\n onSearchChange?: (query: string) => void\n /** Shows a loading indicator in the popover (e.g. while fetching server-side search results). */\n loading?: boolean\n /** Text shown next to the loader while `loading`. Defaults to `\"Loading…\"`. */\n loadingText?: ReactNode\n /**\n * Shown in the popover when no option matches. Defaults to `\"No Options\"`. Pass a function\n * `(query) => node` to vary the message by the current search text — e.g. a \"Type to search\" hint\n * while it's empty vs a \"No results\" message after typing.\n */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Form field name — auto-binds to a surrounding `<Form>` (value is a `string[]`). */\n name?: string\n /** Id for the trigger (label association). */\n id?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A labeled multi-select — the `string[]` sibling of `Select`. The trigger shows the chosen options\n * as deletable `Chip`s (wrapping, growing like `TagsField`) or a placeholder; clicking it opens the\n * same `Dropdown`-style popover (portaled, flips, scroll-locked, trigger-width, animated — shared via\n * `useFloatingPanel`). Options render as `ListItem`s in a `role=\"listbox\"` `aria-multiselectable`\n * list; selecting **toggles** an option and keeps the popover open, the chosen ones showing a tick.\n * Full keyboard support (Arrow/Home/End, Enter/Space to toggle, Escape to close, type-ahead) and\n * ARIA. Optionally `searchable` + `clearable`; pass `onSearchChange` to drive the search\n * **server-side** (you own `options` — local filtering is skipped) with a `loading` indicator.\n * Controlled (`value` + `onChange`) or uncontrolled\n * (`defaultValue`), and binds to a surrounding `<Form>` by `name` (value = `string[]`; validate with\n * e.g. `z.array(z.string()).min(1, 'Pick at least one')`). Token-only styling.\n */\nexport const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(function MultiSelect(\n {\n label,\n options,\n size = 'md',\n error,\n helperText,\n required = false,\n fullWidth = true,\n disabled = false,\n value,\n defaultValue,\n onChange,\n placeholder,\n color = 'primary',\n clearable = true,\n searchable = false,\n searchPlaceholder,\n onSearchChange,\n loading = false,\n loadingText,\n noOptionsText,\n name,\n id: idProp,\n className,\n style,\n },\n ref,\n) {\n const reactId = useId()\n const id = idProp ?? reactId\n const labelId = `${id}-label`\n const helperId = `${id}-helper`\n\n // ── value (controlled / form-bound / uncontrolled) — always a string[] ─────────────────────────\n // Read the RAW form value (field().value String-coerces, which would flatten the array).\n const t = useT()\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const externalValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string[] | undefined) ?? [])\n : undefined\n const isControlled = value !== undefined || isFormBound\n const [internal, setInternal] = useState<string[]>(defaultValue ?? [])\n const selectedValues = isControlled ? externalValue! : internal\n\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const commit = (next: string[]) => {\n if (!isControlled) setInternal(next)\n if (isFormBound) form!.setValue(name!, next)\n onChange?.(next)\n }\n\n // ── the option popover (state + keys shared with Select / PhoneField) — stays open on pick ─────\n const triggerRef = useRef<HTMLDivElement | null>(null)\n const fieldBlur = useRef<(() => void) | undefined>(undefined)\n fieldBlur.current = bound ? () => bound.onBlur({} as FocusEvent<HTMLInputElement>) : undefined\n\n const setTriggerRef = useCallback(\n (node: HTMLDivElement | null) => {\n triggerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node\n },\n [ref],\n )\n\n const removeValue = (v: string) => commit(selectedValues.filter((x) => x !== v))\n\n const menu = useOptionMenu({\n idBase: id,\n options,\n isSelected: (o) => selectedValues.includes(o.value),\n onPick: (o) =>\n commit(\n selectedValues.includes(o.value)\n ? selectedValues.filter((v) => v !== o.value)\n : [...selectedValues, o.value],\n ),\n closeOnPick: false,\n highlightSelected: false,\n searchable,\n onSearchChange,\n disabled,\n focusRef: triggerRef,\n onClose: () => fieldBlur.current?.(),\n })\n const { open } = menu\n\n // Backspace removes the last chip while the search box is empty (or there's none); else the shared keys\n const handleKeyDown = (event: ReactKeyboardEvent) => {\n if (\n event.key === 'Backspace' &&\n open &&\n (!searchable || menu.searchQuery === '') &&\n selectedValues.length > 0\n ) {\n event.preventDefault()\n removeValue(selectedValues[selectedValues.length - 1])\n return\n }\n menu.handleKeyDown(event)\n }\n\n const handleTriggerBlur = (event: FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget as Node | null\n if (next && (menu.popoverRef.current?.contains(next) || triggerRef.current?.contains(next)))\n return\n bound?.onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // chevron size per field size: sm 16 · md 14 · lg 12\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const hasValue = selectedValues.length > 0\n\n return (\n <div\n className={clsx(\n styles.field,\n styles[size],\n fullWidth && styles.fullWidth,\n resolvedError && styles.error,\n disabled && styles.disabled,\n className,\n )}\n style={style}\n >\n {label != null && (\n <span\n id={labelId}\n className={styles.label}\n onClick={() => !disabled && triggerRef.current?.focus()}\n >\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={styles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div\n ref={setTriggerRef}\n id={id}\n {...(name ? { name } : {})}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? menu.listboxId : undefined}\n aria-activedescendant={searchable ? undefined : menu.activeId}\n aria-labelledby={label != null ? labelId : undefined}\n aria-disabled={disabled || undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedError || undefined}\n aria-describedby={resolvedHelperText != null ? helperId : undefined}\n className={clsx(styles.control, open && styles.open, hasValue && styles.filled)}\n onClick={menu.toggleMenu}\n onKeyDown={handleKeyDown}\n onBlur={handleTriggerBlur}\n >\n {hasValue ? (\n <span className={styles.chips}>\n {selectedValues.map((v) => {\n const opt = options.find((o) => o.value === v)\n return (\n <Chip\n key={v}\n size={size}\n color={color}\n disabled={disabled}\n onDelete={() => removeValue(v)}\n deleteLabel={t('fileUploader.remove', { name: opt?.label ?? v })}\n // the combobox owns keyboard focus — keep chip deletes out of the tab order\n deleteTabIndex={-1}\n >\n {opt?.label ?? v}\n </Chip>\n )\n })}\n </span>\n ) : (\n <span className={clsx(styles.value, styles.placeholder)}>\n <span className={styles.valueLabel}>{placeholder ?? t('select.placeholder')}</span>\n </span>\n )}\n\n {clearable && hasValue && !disabled && (\n <button\n type=\"button\"\n className={styles.clear}\n aria-label={t('multiSelect.clearAll')}\n tabIndex={-1}\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.stopPropagation()\n commit([])\n triggerRef.current?.focus()\n }}\n >\n <Icon name=\"CloseCircle\" size=\"sm\" />\n </button>\n )}\n\n <Icon\n name=\"ArrowDown4\"\n className={styles.chevron}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={triggerRef}\n size={size}\n searchPlaceholder={searchPlaceholder}\n loading={loading}\n loadingText={loadingText}\n noOptionsText={noOptionsText}\n multiselectable\n labelledBy={label != null ? labelId : undefined}\n onSearchKeyDown={handleKeyDown}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={styles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n"],"names":["MultiSelect","forwardRef","label","options","size","error","helperText","required","fullWidth","disabled","value","defaultValue","onChange","placeholder","color","clearable","searchable","searchPlaceholder","onSearchChange","loading","loadingText","noOptionsText","name","idProp","className","style","ref","reactId","useId","id","labelId","helperId","t","useT","form","useFormContext","isFormBound","bound","externalValue","isControlled","internal","setInternal","useState","selectedValues","resolvedError","resolvedHelperText","commit","next","triggerRef","useRef","fieldBlur","setTriggerRef","useCallback","node","removeValue","v","x","menu","useOptionMenu","o","_a","open","handleKeyDown","event","handleTriggerBlur","_b","chevronPx","hasValue","jsxs","clsx","styles","jsx","Typography","opt","Chip","Icon","OptionMenu"],"mappings":"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"}
1
+ {"version":3,"file":"MultiSelect-B7KwEhL5.js","sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { useFormContext } from '../../form/formContext'\nimport { useT, type ThemeColor } from '../../theme'\nimport { Chip } from '../Chip'\nimport { Icon } from '../Icon'\nimport { OptionMenu } from '../OptionMenu/OptionMenu'\nimport { useOptionMenu } from '../OptionMenu/useOptionMenu'\nimport { Typography } from '../Typography'\nimport type { SelectOption, SelectSize } from '../Select'\nimport styles from './MultiSelect.module.css'\n\nexport interface MultiSelectProps {\n /** Label rendered above the field. */\n label?: ReactNode\n /** The selectable options. */\n options: SelectOption[]\n /** Preset size — control height, font, chips and option density. */\n size?: SelectSize\n /** Marks the field invalid: red border/ring + the `helperText` in the error color. */\n error?: boolean\n /** Helper / validation text under the field. Adopts the error color while `error`. */\n helperText?: ReactNode\n /** Adds a red asterisk after the label. */\n required?: boolean\n /** Stretches the field to fill its container width. Defaults to `true`. */\n fullWidth?: boolean\n /** Disables the field. */\n disabled?: boolean\n /** Controlled value — the chosen options' `value`s. */\n value?: string[]\n /** Initial value for uncontrolled use. */\n defaultValue?: string[]\n /** Fires with the next array of selected values. */\n onChange?: (value: string[]) => void\n /** Text shown in the trigger when nothing is selected. Defaults to `\"Select…\"`. */\n placeholder?: string\n /** Theme palette token tinting the selected chips. Defaults to `primary`. */\n color?: ThemeColor\n /** Shows a clear (×) button in the trigger when anything is selected. Defaults to `true`. */\n clearable?: boolean\n /** Adds a search box inside the popover that filters options by label. */\n searchable?: boolean\n /** Placeholder for the search box. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string\n /**\n * Fires with the search query as the user types. **Providing this switches off the built-in\n * local filtering** — you own `options` (e.g. fetch them from a server for the current query).\n */\n onSearchChange?: (query: string) => void\n /** Shows a loading indicator in the popover (e.g. while fetching server-side search results). */\n loading?: boolean\n /** Text shown next to the loader while `loading`. Defaults to `\"Loading…\"`. */\n loadingText?: ReactNode\n /**\n * Shown in the popover when no option matches. Defaults to `\"No Options\"`. Pass a function\n * `(query) => node` to vary the message by the current search text — e.g. a \"Type to search\" hint\n * while it's empty vs a \"No results\" message after typing.\n */\n noOptionsText?: ReactNode | ((query: string) => ReactNode)\n /** Form field name — auto-binds to a surrounding `<Form>` (value is a `string[]`). */\n name?: string\n /** Id for the trigger (label association). */\n id?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A labeled multi-select — the `string[]` sibling of `Select`. The trigger shows the chosen options\n * as deletable `Chip`s (wrapping, growing like `TagsField`) or a placeholder; clicking it opens the\n * same `Dropdown`-style popover (portaled, flips, scroll-locked, trigger-width, animated — shared via\n * `useFloatingPanel`). Options render as `ListItem`s in a `role=\"listbox\"` `aria-multiselectable`\n * list; selecting **toggles** an option and keeps the popover open, the chosen ones showing a tick.\n * Full keyboard support (Arrow/Home/End, Enter/Space to toggle, Escape to close, type-ahead) and\n * ARIA. Optionally `searchable` + `clearable`; pass `onSearchChange` to drive the search\n * **server-side** (you own `options` — local filtering is skipped) with a `loading` indicator.\n * Controlled (`value` + `onChange`) or uncontrolled\n * (`defaultValue`), and binds to a surrounding `<Form>` by `name` (value = `string[]`; validate with\n * e.g. `z.array(z.string()).min(1, 'Pick at least one')`). Token-only styling.\n */\nexport const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(function MultiSelect(\n {\n label,\n options,\n size = 'md',\n error,\n helperText,\n required = false,\n fullWidth = true,\n disabled = false,\n value,\n defaultValue,\n onChange,\n placeholder,\n color = 'primary',\n clearable = true,\n searchable = false,\n searchPlaceholder,\n onSearchChange,\n loading = false,\n loadingText,\n noOptionsText,\n name,\n id: idProp,\n className,\n style,\n },\n ref,\n) {\n const reactId = useId()\n const id = idProp ?? reactId\n const labelId = `${id}-label`\n const helperId = `${id}-helper`\n\n // ── value (controlled / form-bound / uncontrolled) — always a string[] ─────────────────────────\n // Read the RAW form value (field().value String-coerces, which would flatten the array).\n const t = useT()\n const form = useFormContext()\n const isFormBound = Boolean(form && name)\n const bound = isFormBound ? form!.field(name!) : undefined\n const externalValue =\n value !== undefined\n ? value\n : isFormBound\n ? ((form!.values[name!] as string[] | undefined) ?? [])\n : undefined\n const isControlled = value !== undefined || isFormBound\n const [internal, setInternal] = useState<string[]>(defaultValue ?? [])\n const selectedValues = isControlled ? externalValue! : internal\n\n const resolvedError = error ?? bound?.error ?? false\n const resolvedHelperText = helperText ?? bound?.helperText\n\n const commit = (next: string[]) => {\n if (!isControlled) setInternal(next)\n if (isFormBound) form!.setValue(name!, next)\n onChange?.(next)\n }\n\n // ── the option popover (state + keys shared with Select / PhoneField) — stays open on pick ─────\n const triggerRef = useRef<HTMLDivElement | null>(null)\n const fieldBlur = useRef<(() => void) | undefined>(undefined)\n fieldBlur.current = bound ? () => bound.onBlur({} as FocusEvent<HTMLInputElement>) : undefined\n\n const setTriggerRef = useCallback(\n (node: HTMLDivElement | null) => {\n triggerRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node\n },\n [ref],\n )\n\n const removeValue = (v: string) => commit(selectedValues.filter((x) => x !== v))\n\n const menu = useOptionMenu({\n idBase: id,\n options,\n isSelected: (o) => selectedValues.includes(o.value),\n onPick: (o) =>\n commit(\n selectedValues.includes(o.value)\n ? selectedValues.filter((v) => v !== o.value)\n : [...selectedValues, o.value],\n ),\n closeOnPick: false,\n highlightSelected: false,\n searchable,\n onSearchChange,\n disabled,\n focusRef: triggerRef,\n onClose: () => fieldBlur.current?.(),\n })\n const { open } = menu\n\n // Backspace removes the last chip while the search box is empty (or there's none); else the shared keys\n const handleKeyDown = (event: ReactKeyboardEvent) => {\n if (\n event.key === 'Backspace' &&\n open &&\n (!searchable || menu.searchQuery === '') &&\n selectedValues.length > 0\n ) {\n event.preventDefault()\n removeValue(selectedValues[selectedValues.length - 1])\n return\n }\n menu.handleKeyDown(event)\n }\n\n const handleTriggerBlur = (event: FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget as Node | null\n if (next && (menu.popoverRef.current?.contains(next) || triggerRef.current?.contains(next)))\n return\n bound?.onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // chevron size per field size: sm 16 · md 14 · lg 12\n const chevronPx = size === 'sm' ? 16 : size === 'md' ? 14 : 12\n const hasValue = selectedValues.length > 0\n\n return (\n <div\n className={clsx(\n styles.field,\n styles[size],\n fullWidth && styles.fullWidth,\n resolvedError && styles.error,\n disabled && styles.disabled,\n className,\n )}\n style={style}\n >\n {label != null && (\n <span\n id={labelId}\n className={styles.label}\n onClick={() => !disabled && triggerRef.current?.focus()}\n >\n <Typography as=\"span\" variant=\"bodySmall\" color=\"muted\">\n {label}\n </Typography>\n {required && (\n <span className={styles.required} aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div\n ref={setTriggerRef}\n id={id}\n {...(name ? { name } : {})}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? menu.listboxId : undefined}\n aria-activedescendant={searchable ? undefined : menu.activeId}\n aria-labelledby={label != null ? labelId : undefined}\n aria-disabled={disabled || undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedError || undefined}\n aria-describedby={resolvedHelperText != null ? helperId : undefined}\n className={clsx(styles.control, open && styles.open, hasValue && styles.filled)}\n onClick={menu.toggleMenu}\n onKeyDown={handleKeyDown}\n onBlur={handleTriggerBlur}\n >\n {hasValue ? (\n <span className={styles.chips}>\n {selectedValues.map((v) => {\n const opt = options.find((o) => o.value === v)\n return (\n <Chip\n key={v}\n size={size}\n color={color}\n disabled={disabled}\n onDelete={() => removeValue(v)}\n deleteLabel={t('fileUploader.remove', { name: opt?.label ?? v })}\n // the combobox owns keyboard focus — keep chip deletes out of the tab order\n deleteTabIndex={-1}\n >\n {opt?.label ?? v}\n </Chip>\n )\n })}\n </span>\n ) : (\n <span className={clsx(styles.value, styles.placeholder)}>\n <span className={styles.valueLabel}>{placeholder ?? t('select.placeholder')}</span>\n </span>\n )}\n\n {clearable && hasValue && !disabled && (\n <button\n type=\"button\"\n className={styles.clear}\n aria-label={t('multiSelect.clearAll')}\n tabIndex={-1}\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.stopPropagation()\n commit([])\n triggerRef.current?.focus()\n }}\n >\n <Icon name=\"CloseCircle\" size=\"sm\" />\n </button>\n )}\n\n <Icon\n name=\"ArrowDown4\"\n className={styles.chevron}\n style={{ width: chevronPx, height: chevronPx }}\n aria-hidden=\"true\"\n />\n </div>\n\n <OptionMenu\n menu={menu}\n anchorRef={triggerRef}\n size={size}\n searchPlaceholder={searchPlaceholder}\n loading={loading}\n loadingText={loadingText}\n noOptionsText={noOptionsText}\n multiselectable\n labelledBy={label != null ? labelId : undefined}\n onSearchKeyDown={handleKeyDown}\n />\n\n {resolvedHelperText != null && (\n <Typography\n as=\"span\"\n id={helperId}\n variant=\"bodySmall\"\n color={resolvedError ? 'error' : 'muted'}\n className={styles.helper}\n >\n {resolvedHelperText}\n </Typography>\n )}\n </div>\n )\n})\n"],"names":["MultiSelect","forwardRef","label","options","size","error","helperText","required","fullWidth","disabled","value","defaultValue","onChange","placeholder","color","clearable","searchable","searchPlaceholder","onSearchChange","loading","loadingText","noOptionsText","name","idProp","className","style","ref","reactId","useId","id","labelId","helperId","t","useT","form","useFormContext","isFormBound","bound","externalValue","isControlled","internal","setInternal","useState","selectedValues","resolvedError","resolvedHelperText","commit","next","triggerRef","useRef","fieldBlur","setTriggerRef","useCallback","node","removeValue","v","x","menu","useOptionMenu","o","_a","open","handleKeyDown","event","handleTriggerBlur","_b","chevronPx","hasValue","jsxs","clsx","styles","jsx","Typography","opt","Chip","Icon","OptionMenu"],"mappings":"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"}
@@ -3,10 +3,10 @@ import { forwardRef as ye, useId as be, useState as J, useEffect as Ie, useRef a
3
3
  import { clsx as O } from "clsx";
4
4
  import { u as Fe } from "./formContext-B7ln1Miy.js";
5
5
  import { b as Q } from "./Icon-B7DJn8Tw.js";
6
- import { I as X } from "./IconButton-EaExCXRq.js";
6
+ import { I as X } from "./IconButton-re6xITGO.js";
7
7
  import { T as Y } from "./Typography-ChSuxgkc.js";
8
8
  import { f as r } from "./TextField.module-6gYcR9TL.js";
9
- import { a as Me } from "./ConfigProvider-CYgmMH4j.js";
9
+ import { a as Me } from "./ConfigProvider-DVDGtCUc.js";
10
10
  const Z = /^-?\d*\.?\d*$/;
11
11
  function V(t) {
12
12
  if (t === "" || t === "-" || t === "." || t === "-.") return null;
@@ -180,4 +180,4 @@ const We = ye(function({
180
180
  export {
181
181
  We as N
182
182
  };
183
- //# sourceMappingURL=NumberField-DHFGNQjZ.js.map
183
+ //# sourceMappingURL=NumberField-ThojS4K3.js.map