@alfadocs/ui-kit-debug 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. package/dist/_chunks/{actions-cell-renderer-BD-jruqA.js → actions-cell-renderer-ALEAGO3j.js} +6 -6
  2. package/dist/_chunks/{actions-cell-renderer-BD-jruqA.js.map → actions-cell-renderer-ALEAGO3j.js.map} +1 -1
  3. package/dist/_chunks/{agenda-tray-CYR-znfE.js → agenda-tray-BweO8pDo.js} +3 -3
  4. package/dist/_chunks/{agenda-tray-CYR-znfE.js.map → agenda-tray-BweO8pDo.js.map} +1 -1
  5. package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js → ai-consent-banner-OggpS5hW.js} +2 -2
  6. package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js.map → ai-consent-banner-OggpS5hW.js.map} +1 -1
  7. package/dist/_chunks/{ai-prompt-input-BgAubYKd.js → ai-prompt-input-DnbfEJnr.js} +2 -2
  8. package/dist/_chunks/{ai-prompt-input-BgAubYKd.js.map → ai-prompt-input-DnbfEJnr.js.map} +1 -1
  9. package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js → alia-sidebar-BWcWZivN.js} +7 -7
  10. package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js.map → alia-sidebar-BWcWZivN.js.map} +1 -1
  11. package/dist/_chunks/{anamnesis-card-BylMLHYj.js → anamnesis-card-NTi4LLzI.js} +2 -2
  12. package/dist/_chunks/{anamnesis-card-BylMLHYj.js.map → anamnesis-card-NTi4LLzI.js.map} +1 -1
  13. package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js → anamnesis-summary-rows-F-cCmFAn.js} +7 -7
  14. package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js.map → anamnesis-summary-rows-F-cCmFAn.js.map} +1 -1
  15. package/dist/_chunks/{appointment-timeline-DT1uFp8z.js → appointment-timeline-CMPvzlGZ.js} +4 -4
  16. package/dist/_chunks/{appointment-timeline-DT1uFp8z.js.map → appointment-timeline-CMPvzlGZ.js.map} +1 -1
  17. package/dist/_chunks/{appointment-tray-DvyVK7um.js → appointment-tray-3c_FLxXJ.js} +3 -3
  18. package/dist/_chunks/{appointment-tray-DvyVK7um.js.map → appointment-tray-3c_FLxXJ.js.map} +1 -1
  19. package/dist/_chunks/{audio-recorder-nVRN4PSK.js → audio-recorder-EWBCNIsd.js} +3 -3
  20. package/dist/_chunks/{audio-recorder-nVRN4PSK.js.map → audio-recorder-EWBCNIsd.js.map} +1 -1
  21. package/dist/_chunks/{bishop-score-BV1JAEMV.js → bishop-score-Cnu0xs-z.js} +2 -2
  22. package/dist/_chunks/{bishop-score-BV1JAEMV.js.map → bishop-score-Cnu0xs-z.js.map} +1 -1
  23. package/dist/_chunks/{bmi-calculator-CdR-RLFj.js → bmi-calculator-CcH6upht.js} +2 -2
  24. package/dist/_chunks/{bmi-calculator-CdR-RLFj.js.map → bmi-calculator-CcH6upht.js.map} +1 -1
  25. package/dist/_chunks/{booking-D84O6H2X.js → booking-CQMJUFG-.js} +5 -5
  26. package/dist/_chunks/{booking-D84O6H2X.js.map → booking-CQMJUFG-.js.map} +1 -1
  27. package/dist/_chunks/{button-group-Be_In68J.js → button-group-CaxRJsNG.js} +2 -2
  28. package/dist/_chunks/{button-group-Be_In68J.js.map → button-group-CaxRJsNG.js.map} +1 -1
  29. package/dist/_chunks/{button-BvNtqHAS.js → button-nJaPh_HC.js} +68 -38
  30. package/dist/_chunks/button-nJaPh_HC.js.map +1 -0
  31. package/dist/_chunks/{care-plan-card-CehAU7F_.js → care-plan-card-DQjVRDxO.js} +2 -2
  32. package/dist/_chunks/{care-plan-card-CehAU7F_.js.map → care-plan-card-DQjVRDxO.js.map} +1 -1
  33. package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js → care-plan-entry-card-CMpoeNkb.js} +2 -2
  34. package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js.map → care-plan-entry-card-CMpoeNkb.js.map} +1 -1
  35. package/dist/_chunks/{care-plan-header-_B0TTWT1.js → care-plan-header-CxYoq23f.js} +2 -2
  36. package/dist/_chunks/{care-plan-header-_B0TTWT1.js.map → care-plan-header-CxYoq23f.js.map} +1 -1
  37. package/dist/_chunks/{carousel.agent-pjORsMS8.js → carousel.agent-CLxdHEBP.js} +2 -2
  38. package/dist/_chunks/{carousel.agent-pjORsMS8.js.map → carousel.agent-CLxdHEBP.js.map} +1 -1
  39. package/dist/_chunks/{chart-Y-gso_Uz.js → chart-Bkr1Sh4o.js} +3 -3
  40. package/dist/_chunks/{chart-Y-gso_Uz.js.map → chart-Bkr1Sh4o.js.map} +1 -1
  41. package/dist/_chunks/{chat-input-BqI9GXQh.js → chat-input-BsB5Umpj.js} +2 -2
  42. package/dist/_chunks/{chat-input-BqI9GXQh.js.map → chat-input-BsB5Umpj.js.map} +1 -1
  43. package/dist/_chunks/{chat-message-DHNUbjXA.js → chat-message-DBQu10rs.js} +3 -3
  44. package/dist/_chunks/{chat-message-DHNUbjXA.js.map → chat-message-DBQu10rs.js.map} +1 -1
  45. package/dist/_chunks/{code-block-BONe9fJi.js → code-block-BIkpRLkl.js} +2 -2
  46. package/dist/_chunks/{code-block-BONe9fJi.js.map → code-block-BIkpRLkl.js.map} +1 -1
  47. package/dist/_chunks/{connection-status-NT8hUtYl.js → connection-status-DRZIcMqM.js} +3 -3
  48. package/dist/_chunks/{connection-status-NT8hUtYl.js.map → connection-status-DRZIcMqM.js.map} +1 -1
  49. package/dist/_chunks/{contact-profile-card-BxHiG8e6.js → contact-profile-card-CE9OJKcl.js} +2 -2
  50. package/dist/_chunks/{contact-profile-card-BxHiG8e6.js.map → contact-profile-card-CE9OJKcl.js.map} +1 -1
  51. package/dist/_chunks/{control-room-rail-DDyPDBji.js → control-room-rail-IH1eBjrK.js} +3 -3
  52. package/dist/_chunks/{control-room-rail-DDyPDBji.js.map → control-room-rail-IH1eBjrK.js.map} +1 -1
  53. package/dist/_chunks/{copy-field-B-DoMBH_.js → copy-field-fYKpl6aN.js} +2 -2
  54. package/dist/_chunks/{copy-field-B-DoMBH_.js.map → copy-field-fYKpl6aN.js.map} +1 -1
  55. package/dist/_chunks/{cycle-calculator-DJZYvNhw.js → cycle-calculator-DzgO1vzP.js} +2 -2
  56. package/dist/_chunks/{cycle-calculator-DJZYvNhw.js.map → cycle-calculator-DzgO1vzP.js.map} +1 -1
  57. package/dist/_chunks/{dashboard-grid-bd0QW2a8.js → dashboard-grid-BFtdHqfn.js} +2 -2
  58. package/dist/_chunks/{dashboard-grid-bd0QW2a8.js.map → dashboard-grid-BFtdHqfn.js.map} +1 -1
  59. package/dist/_chunks/{data-table-tabs-C8uDThT3.js → data-table-tabs-C1kRUzat.js} +3 -3
  60. package/dist/_chunks/{data-table-tabs-C8uDThT3.js.map → data-table-tabs-C1kRUzat.js.map} +1 -1
  61. package/dist/_chunks/{description-list-Ck7fKdt5.js → description-list-CjJqR8WK.js} +2 -2
  62. package/dist/_chunks/{description-list-Ck7fKdt5.js.map → description-list-CjJqR8WK.js.map} +1 -1
  63. package/dist/_chunks/{document-preview-Aae2yKvY.js → document-preview-oyx9RhCo.js} +2 -2
  64. package/dist/_chunks/{document-preview-Aae2yKvY.js.map → document-preview-oyx9RhCo.js.map} +1 -1
  65. package/dist/_chunks/{document-scanner-qNZLhH_r.js → document-scanner-C5Vrbu21.js} +2 -2
  66. package/dist/_chunks/{document-scanner-qNZLhH_r.js.map → document-scanner-C5Vrbu21.js.map} +1 -1
  67. package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js → due-date-calculator-wK8Tajzz.js} +2 -2
  68. package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js.map → due-date-calculator-wK8Tajzz.js.map} +1 -1
  69. package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js → editable-currency-cell-renderer-DYdzKpjL.js} +3 -3
  70. package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js.map → editable-currency-cell-renderer-DYdzKpjL.js.map} +1 -1
  71. package/dist/_chunks/{editor-overlay-DE-gxj9L.js → editor-overlay-DEc5yYwo.js} +2 -2
  72. package/dist/_chunks/{editor-overlay-DE-gxj9L.js.map → editor-overlay-DEc5yYwo.js.map} +1 -1
  73. package/dist/_chunks/{empty-state-Df0tM6Kn.js → empty-state-X0sVPfVo.js} +2 -2
  74. package/dist/_chunks/{empty-state-Df0tM6Kn.js.map → empty-state-X0sVPfVo.js.map} +1 -1
  75. package/dist/_chunks/{entity-summary-DBOI5di6.js → entity-summary-B_vO5Ur4.js} +3 -3
  76. package/dist/_chunks/{entity-summary-DBOI5di6.js.map → entity-summary-B_vO5Ur4.js.map} +1 -1
  77. package/dist/_chunks/{face-scheme-D7Pub04e.js → face-scheme-BfDi4YkW.js} +5 -5
  78. package/dist/_chunks/{face-scheme-D7Pub04e.js.map → face-scheme-BfDi4YkW.js.map} +1 -1
  79. package/dist/_chunks/{fetal-weight-jon6GIfQ.js → fetal-weight-Dqy0T1fP.js} +2 -2
  80. package/dist/_chunks/{fetal-weight-jon6GIfQ.js.map → fetal-weight-Dqy0T1fP.js.map} +1 -1
  81. package/dist/_chunks/{field-array-BQFX5OYi.js → field-array-BjkXZzSr.js} +3 -3
  82. package/dist/_chunks/{field-array-BQFX5OYi.js.map → field-array-BjkXZzSr.js.map} +1 -1
  83. package/dist/_chunks/{field-value-BbiDRyNh.js → field-value-DG8zaZvo.js} +4 -4
  84. package/dist/_chunks/{field-value-BbiDRyNh.js.map → field-value-DG8zaZvo.js.map} +1 -1
  85. package/dist/_chunks/{file-manager-CML_C6_h.js → file-manager-Cc_upjZX.js} +6 -6
  86. package/dist/_chunks/{file-manager-CML_C6_h.js.map → file-manager-Cc_upjZX.js.map} +1 -1
  87. package/dist/_chunks/{finished-terminal-BWNVh7Y8.js → finished-terminal-Br61Ip4e.js} +2 -2
  88. package/dist/_chunks/{finished-terminal-BWNVh7Y8.js.map → finished-terminal-Br61Ip4e.js.map} +1 -1
  89. package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js → fiscal-code-input-B_nYMSEM.js} +2 -2
  90. package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js.map → fiscal-code-input-B_nYMSEM.js.map} +1 -1
  91. package/dist/_chunks/{freemium-paywall-HG3pFvMp.js → freemium-paywall-DrXzYfv-.js} +2 -2
  92. package/dist/_chunks/{freemium-paywall-HG3pFvMp.js.map → freemium-paywall-DrXzYfv-.js.map} +1 -1
  93. package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js → gestational-age-calculator-C_uDAeP_.js} +2 -2
  94. package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js.map → gestational-age-calculator-C_uDAeP_.js.map} +1 -1
  95. package/dist/_chunks/{hcg-doubling-CC6TLtHd.js → hcg-doubling-BaXkJhT-.js} +2 -2
  96. package/dist/_chunks/{hcg-doubling-CC6TLtHd.js.map → hcg-doubling-BaXkJhT-.js.map} +1 -1
  97. package/dist/_chunks/{header-CimZS-J9.js → header-DUXRIPyM.js} +2 -2
  98. package/dist/_chunks/{header-CimZS-J9.js.map → header-DUXRIPyM.js.map} +1 -1
  99. package/dist/_chunks/{header-settings-C0zHLXJE.js → header-settings-CVC_davE.js} +4 -4
  100. package/dist/_chunks/{header-settings-C0zHLXJE.js.map → header-settings-CVC_davE.js.map} +1 -1
  101. package/dist/_chunks/{icon-button-9c9Gp41m.js → icon-button-DA2CAGHZ.js} +2 -2
  102. package/dist/_chunks/{icon-button-9c9Gp41m.js.map → icon-button-DA2CAGHZ.js.map} +1 -1
  103. package/dist/_chunks/{icon-button-group-DrvuWPGJ.js → icon-button-group-D6SVMteH.js} +2 -2
  104. package/dist/_chunks/{icon-button-group-DrvuWPGJ.js.map → icon-button-group-D6SVMteH.js.map} +1 -1
  105. package/dist/_chunks/{icon-picker-DXV3sDp1.js → icon-picker-ChzpCnZ-.js} +3 -3
  106. package/dist/_chunks/{icon-picker-DXV3sDp1.js.map → icon-picker-ChzpCnZ-.js.map} +1 -1
  107. package/dist/_chunks/{image-cropper-DWSnyLwW.js → image-cropper-C84NDTB7.js} +2 -2
  108. package/dist/_chunks/{image-cropper-DWSnyLwW.js.map → image-cropper-C84NDTB7.js.map} +1 -1
  109. package/dist/_chunks/{info-tip-C4mPSJbS.js → info-tip-C119cwQl.js} +2 -2
  110. package/dist/_chunks/{info-tip-C4mPSJbS.js.map → info-tip-C119cwQl.js.map} +1 -1
  111. package/dist/_chunks/{insert-result-98J1QEp7.js → insert-result-LCNTskNJ.js} +2 -2
  112. package/dist/_chunks/{insert-result-98J1QEp7.js.map → insert-result-LCNTskNJ.js.map} +1 -1
  113. package/dist/_chunks/{key-value-pair-DGkGlgCF.js → key-value-pair-BubG4fUa.js} +2 -2
  114. package/dist/_chunks/{key-value-pair-DGkGlgCF.js.map → key-value-pair-BubG4fUa.js.map} +1 -1
  115. package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js → link-cell-renderer-DH4JYpKU.js} +2 -2
  116. package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js.map → link-cell-renderer-DH4JYpKU.js.map} +1 -1
  117. package/dist/_chunks/{locale-picker-sI0HWgZy.js → locale-picker-BvbVjDQ-.js} +3 -3
  118. package/dist/_chunks/{locale-picker-sI0HWgZy.js.map → locale-picker-BvbVjDQ-.js.map} +1 -1
  119. package/dist/_chunks/{map-view-iwSDRW3t.js → map-view-CCAlC9IL.js} +2 -2
  120. package/dist/_chunks/{map-view-iwSDRW3t.js.map → map-view-CCAlC9IL.js.map} +1 -1
  121. package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js → marketplace-app-shell-Chfdia7m.js} +4 -4
  122. package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js.map → marketplace-app-shell-Chfdia7m.js.map} +1 -1
  123. package/dist/_chunks/{message-card-BCJ-Jgs6.js → message-card-D8GB4FdF.js} +3 -3
  124. package/dist/_chunks/{message-card-BCJ-Jgs6.js.map → message-card-D8GB4FdF.js.map} +1 -1
  125. package/dist/_chunks/{message-tray-DHtm_WaF.js → message-tray-CGIRQjx5.js} +4 -4
  126. package/dist/_chunks/{message-tray-DHtm_WaF.js.map → message-tray-CGIRQjx5.js.map} +1 -1
  127. package/dist/_chunks/{notes-panel-D6HKLLS-.js → notes-panel-DlnENphf.js} +3 -3
  128. package/dist/_chunks/{notes-panel-D6HKLLS-.js.map → notes-panel-DlnENphf.js.map} +1 -1
  129. package/dist/_chunks/{notification-card-CcMQn2RX.js → notification-card-CtrzoTUO.js} +3 -3
  130. package/dist/_chunks/{notification-card-CcMQn2RX.js.map → notification-card-CtrzoTUO.js.map} +1 -1
  131. package/dist/_chunks/{notification-tray-nr7dv-Q8.js → notification-tray-BiRzXHDf.js} +4 -4
  132. package/dist/_chunks/{notification-tray-nr7dv-Q8.js.map → notification-tray-BiRzXHDf.js.map} +1 -1
  133. package/dist/_chunks/{optical-prescription-DtzEqFQm.js → optical-prescription-Dj3Eh5Ok.js} +2 -2
  134. package/dist/_chunks/{optical-prescription-DtzEqFQm.js.map → optical-prescription-Dj3Eh5Ok.js.map} +1 -1
  135. package/dist/_chunks/{patient-details-rENrE_qY.js → patient-details-qnsqYBGQ.js} +5 -5
  136. package/dist/_chunks/{patient-details-rENrE_qY.js.map → patient-details-qnsqYBGQ.js.map} +1 -1
  137. package/dist/_chunks/{patient-search-NQemeJlL.js → patient-search-D5ufYoRc.js} +2 -2
  138. package/dist/_chunks/{patient-search-NQemeJlL.js.map → patient-search-D5ufYoRc.js.map} +1 -1
  139. package/dist/_chunks/{patient-summary-card-DQJgOOrA.js → patient-summary-card-CBfuDvJ5.js} +3 -3
  140. package/dist/_chunks/{patient-summary-card-DQJgOOrA.js.map → patient-summary-card-CBfuDvJ5.js.map} +1 -1
  141. package/dist/_chunks/{patient-table-BubxfOWL.js → patient-table-DwshfVsQ.js} +3 -3
  142. package/dist/_chunks/{patient-table-BubxfOWL.js.map → patient-table-DwshfVsQ.js.map} +1 -1
  143. package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js → payment-automation-upsell-BBIG7NFL.js} +2 -2
  144. package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js.map → payment-automation-upsell-BBIG7NFL.js.map} +1 -1
  145. package/dist/_chunks/{payment-request-card-CvhDzDNk.js → payment-request-card-BjjBMdsp.js} +3 -3
  146. package/dist/_chunks/{payment-request-card-CvhDzDNk.js.map → payment-request-card-BjjBMdsp.js.map} +1 -1
  147. package/dist/_chunks/{periodontal-chart-C0nNQKKK.js → periodontal-chart-BatZEFar.js} +2 -2
  148. package/dist/_chunks/{periodontal-chart-C0nNQKKK.js.map → periodontal-chart-BatZEFar.js.map} +1 -1
  149. package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js → periodontal-chart-card-BBpY_rBc.js} +2 -2
  150. package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js.map → periodontal-chart-card-BBpY_rBc.js.map} +1 -1
  151. package/dist/_chunks/{popover-Btj6N25H.js → popover-Cqcjx-Ny.js} +2 -2
  152. package/dist/_chunks/{popover-Btj6N25H.js.map → popover-Cqcjx-Ny.js.map} +1 -1
  153. package/dist/_chunks/{practice-results-CKoLD_x5.js → practice-results-BEsAdW-B.js} +719 -633
  154. package/dist/_chunks/practice-results-BEsAdW-B.js.map +1 -0
  155. package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js → pregnancy-dating-BVS_9YU2.js} +2 -2
  156. package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js.map → pregnancy-dating-BVS_9YU2.js.map} +1 -1
  157. package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js → pregnancy-weight-gain-CJwbs9W-.js} +2 -2
  158. package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js.map → pregnancy-weight-gain-CJwbs9W-.js.map} +1 -1
  159. package/dist/_chunks/{privacy-lock-SQYFRSuH.js → privacy-lock-CkAUo6Dz.js} +3 -3
  160. package/dist/_chunks/{privacy-lock-SQYFRSuH.js.map → privacy-lock-CkAUo6Dz.js.map} +1 -1
  161. package/dist/_chunks/{product-hub-panel-BjnD9pdl.js → product-hub-panel-BScCotGD.js} +3 -3
  162. package/dist/_chunks/{product-hub-panel-BjnD9pdl.js.map → product-hub-panel-BScCotGD.js.map} +1 -1
  163. package/dist/_chunks/{public-header.agent-DseNK2NQ.js → public-header.agent-kth2SdXn.js} +3 -3
  164. package/dist/_chunks/{public-header.agent-DseNK2NQ.js.map → public-header.agent-kth2SdXn.js.map} +1 -1
  165. package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js → radiograph-panel.agent-CiHwgISa.js} +4 -4
  166. package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js.map → radiograph-panel.agent-CiHwgISa.js.map} +1 -1
  167. package/dist/_chunks/{reviews-panel-Cd3SxJdW.js → reviews-panel-BKHEfqVQ.js} +4 -4
  168. package/dist/_chunks/{reviews-panel-Cd3SxJdW.js.map → reviews-panel-BKHEfqVQ.js.map} +1 -1
  169. package/dist/_chunks/{rich-text-editor-DGtn_4sb.js → rich-text-editor-DARnq_6N.js} +5 -5
  170. package/dist/_chunks/{rich-text-editor-DGtn_4sb.js.map → rich-text-editor-DARnq_6N.js.map} +1 -1
  171. package/dist/_chunks/{session-countdown-q4r5TlCo.js → session-countdown-QMsnRa1x.js} +2 -2
  172. package/dist/_chunks/{session-countdown-q4r5TlCo.js.map → session-countdown-QMsnRa1x.js.map} +1 -1
  173. package/dist/_chunks/{sheet-CD99CdXr.js → sheet-BSznOyJs.js} +2 -2
  174. package/dist/_chunks/{sheet-CD99CdXr.js.map → sheet-BSznOyJs.js.map} +1 -1
  175. package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js → sign-in-with-alfadocs-button-BLe_quy5.js} +2 -2
  176. package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js.map → sign-in-with-alfadocs-button-BLe_quy5.js.map} +1 -1
  177. package/dist/_chunks/{signature-request-C4UBfVRZ.js → signature-request-DXhpphlp.js} +4 -4
  178. package/dist/_chunks/{signature-request-C4UBfVRZ.js.map → signature-request-DXhpphlp.js.map} +1 -1
  179. package/dist/_chunks/{slot-grid-P_e9p5t5.js → slot-grid-BuZOKfcd.js} +4 -4
  180. package/dist/_chunks/{slot-grid-P_e9p5t5.js.map → slot-grid-BuZOKfcd.js.map} +1 -1
  181. package/dist/_chunks/{streaming-text-BuW7I0Zu.js → streaming-text-CvsjIQ7S.js} +2 -2
  182. package/dist/_chunks/{streaming-text-BuW7I0Zu.js.map → streaming-text-CvsjIQ7S.js.map} +1 -1
  183. package/dist/_chunks/{task-tray-BT288xoM.js → task-tray-CYG6rj2s.js} +3 -3
  184. package/dist/_chunks/{task-tray-BT288xoM.js.map → task-tray-CYG6rj2s.js.map} +1 -1
  185. package/dist/_chunks/{tasks-panel-BBkZuejF.js → tasks-panel-Do5SFp-j.js} +5 -5
  186. package/dist/_chunks/{tasks-panel-BBkZuejF.js.map → tasks-panel-Do5SFp-j.js.map} +1 -1
  187. package/dist/_chunks/{theme-toggle-Bi-CmV6M.js → theme-toggle-DuMhQNFS.js} +3 -3
  188. package/dist/_chunks/{theme-toggle-Bi-CmV6M.js.map → theme-toggle-DuMhQNFS.js.map} +1 -1
  189. package/dist/_chunks/{toast.agent-C44mtGrW.js → toast.agent-D1tdg6DS.js} +2 -2
  190. package/dist/_chunks/{toast.agent-C44mtGrW.js.map → toast.agent-D1tdg6DS.js.map} +1 -1
  191. package/dist/_chunks/{token-insert-menu-D8FgXl33.js → token-insert-menu-9Um0JinI.js} +2 -2
  192. package/dist/_chunks/{token-insert-menu-D8FgXl33.js.map → token-insert-menu-9Um0JinI.js.map} +1 -1
  193. package/dist/_chunks/{tool-rail-BF3F2Ihq.js → tool-rail-CHyUmulN.js} +2 -2
  194. package/dist/_chunks/{tool-rail-BF3F2Ihq.js.map → tool-rail-CHyUmulN.js.map} +1 -1
  195. package/dist/_chunks/{tooth-scheme-BPXE1_3N.js → tooth-scheme-WdyVymQ1.js} +3 -3
  196. package/dist/_chunks/{tooth-scheme-BPXE1_3N.js.map → tooth-scheme-WdyVymQ1.js.map} +1 -1
  197. package/dist/_chunks/{unit-converter-iDxlxKmm.js → unit-converter-BPumXMA6.js} +2 -2
  198. package/dist/_chunks/{unit-converter-iDxlxKmm.js.map → unit-converter-BPumXMA6.js.map} +1 -1
  199. package/dist/_chunks/{warning-stack-nczJf52p.js → warning-stack-DQz0Jyir.js} +3 -3
  200. package/dist/_chunks/{warning-stack-nczJf52p.js.map → warning-stack-DQz0Jyir.js.map} +1 -1
  201. package/dist/_chunks/{workflow-map-BVofnDYh.js → workflow-map-DE_ribRM.js} +5 -5
  202. package/dist/_chunks/{workflow-map-BVofnDYh.js.map → workflow-map-DE_ribRM.js.map} +1 -1
  203. package/dist/agent-catalog.json +2 -2
  204. package/dist/components/agenda-tray/index.js +1 -1
  205. package/dist/components/ai-consent-banner/index.js +1 -1
  206. package/dist/components/ai-prompt-input/index.js +1 -1
  207. package/dist/components/anamnesis-card/index.js +1 -1
  208. package/dist/components/appointment-card/index.js +1 -1
  209. package/dist/components/appointment-timeline/index.js +1 -1
  210. package/dist/components/audio-recorder/index.js +1 -1
  211. package/dist/components/bishop-score/index.js +1 -1
  212. package/dist/components/bmi-calculator/index.js +1 -1
  213. package/dist/components/booking/index.js +1 -1
  214. package/dist/components/button/button.d.ts +10 -0
  215. package/dist/components/button/button.d.ts.map +1 -1
  216. package/dist/components/button/index.js +2 -2
  217. package/dist/components/button-group/index.js +1 -1
  218. package/dist/components/care-plan-card/index.js +1 -1
  219. package/dist/components/care-plan-entry-card/index.js +1 -1
  220. package/dist/components/care-plan-header/index.js +1 -1
  221. package/dist/components/carousel/index.js +1 -1
  222. package/dist/components/chart/index.js +1 -1
  223. package/dist/components/chat-input/index.js +1 -1
  224. package/dist/components/chat-message/index.js +1 -1
  225. package/dist/components/connection-status/index.js +1 -1
  226. package/dist/components/contact-profile-card/index.js +1 -1
  227. package/dist/components/control-room-rail/index.js +1 -1
  228. package/dist/components/copy-field/index.js +1 -1
  229. package/dist/components/cycle-calculator/index.js +1 -1
  230. package/dist/components/dashboard-grid/index.js +1 -1
  231. package/dist/components/data-table/index.js +3 -3
  232. package/dist/components/data-table-tabs/index.js +1 -1
  233. package/dist/components/description-list/index.js +1 -1
  234. package/dist/components/document-preview/index.js +1 -1
  235. package/dist/components/document-scanner/index.js +1 -1
  236. package/dist/components/due-date-calculator/index.js +1 -1
  237. package/dist/components/editor-overlay/index.js +1 -1
  238. package/dist/components/empty-state/index.js +1 -1
  239. package/dist/components/entity-summary/index.js +1 -1
  240. package/dist/components/face-scheme/index.js +1 -1
  241. package/dist/components/fetal-weight/index.js +1 -1
  242. package/dist/components/field-array/index.js +1 -1
  243. package/dist/components/file-manager/index.js +1 -1
  244. package/dist/components/finished-terminal/index.js +1 -1
  245. package/dist/components/fiscal-code-input/index.js +1 -1
  246. package/dist/components/freemium-paywall/index.js +1 -1
  247. package/dist/components/gestational-age-calculator/index.js +1 -1
  248. package/dist/components/hcg-doubling/index.js +1 -1
  249. package/dist/components/header/index.js +1 -1
  250. package/dist/components/header-settings/index.js +1 -1
  251. package/dist/components/icon-button/index.js +1 -1
  252. package/dist/components/icon-button-group/index.js +1 -1
  253. package/dist/components/icon-picker/index.js +1 -1
  254. package/dist/components/image-cropper/index.js +1 -1
  255. package/dist/components/info-tip/index.js +1 -1
  256. package/dist/components/key-value-pair/index.js +1 -1
  257. package/dist/components/locale-picker/index.js +1 -1
  258. package/dist/components/map-view/index.js +1 -1
  259. package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
  260. package/dist/components/message-card/index.js +1 -1
  261. package/dist/components/message-tray/index.js +1 -1
  262. package/dist/components/notes-panel/index.js +1 -1
  263. package/dist/components/notification-card/index.js +1 -1
  264. package/dist/components/notification-tray/index.js +1 -1
  265. package/dist/components/optical-prescription/index.js +1 -1
  266. package/dist/components/patient-details/index.js +1 -1
  267. package/dist/components/patient-search/index.js +1 -1
  268. package/dist/components/patient-summary-card/index.js +1 -1
  269. package/dist/components/patient-table/index.js +1 -1
  270. package/dist/components/payment-card/index.js +1 -1
  271. package/dist/components/periodontal-chart/index.js +1 -1
  272. package/dist/components/periodontal-chart-card/index.js +1 -1
  273. package/dist/components/popover/index.js +1 -1
  274. package/dist/components/practice-results/index.js +1 -1
  275. package/dist/components/practice-results/practice-results.d.ts +47 -7
  276. package/dist/components/practice-results/practice-results.d.ts.map +1 -1
  277. package/dist/components/pregnancy-dating/index.js +1 -1
  278. package/dist/components/pregnancy-weight-gain/index.js +1 -1
  279. package/dist/components/privacy-lock/index.js +1 -1
  280. package/dist/components/product-hub-tray/index.js +1 -1
  281. package/dist/components/public-header/index.js +1 -1
  282. package/dist/components/public-header/public-header.d.ts +1 -1
  283. package/dist/components/radiograph-panel/index.js +1 -1
  284. package/dist/components/reviews-panel/index.js +1 -1
  285. package/dist/components/rich-text-editor/index.js +1 -1
  286. package/dist/components/session-countdown/index.js +1 -1
  287. package/dist/components/sheet/index.js +1 -1
  288. package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
  289. package/dist/components/slot-grid/index.js +1 -1
  290. package/dist/components/streaming-text/index.js +1 -1
  291. package/dist/components/task-tray/index.js +1 -1
  292. package/dist/components/tasks-panel/index.js +1 -1
  293. package/dist/components/theme-toggle/index.js +1 -1
  294. package/dist/components/toast/index.js +1 -1
  295. package/dist/components/token-insert-menu/index.js +1 -1
  296. package/dist/components/tool-rail/index.js +1 -1
  297. package/dist/components/tooth-scheme/index.js +1 -1
  298. package/dist/components/unit-converter/index.js +1 -1
  299. package/dist/components/warning-stack/index.js +1 -1
  300. package/dist/components/workflow/index.js +1 -1
  301. package/dist/i18n/locales/ar.d.ts +1 -0
  302. package/dist/i18n/locales/ar.d.ts.map +1 -1
  303. package/dist/i18n/locales/ar.js +2 -1
  304. package/dist/i18n/locales/ar.js.map +1 -1
  305. package/dist/i18n/locales/de.d.ts +1 -0
  306. package/dist/i18n/locales/de.d.ts.map +1 -1
  307. package/dist/i18n/locales/de.js +2 -1
  308. package/dist/i18n/locales/de.js.map +1 -1
  309. package/dist/i18n/locales/el.d.ts +1 -0
  310. package/dist/i18n/locales/el.d.ts.map +1 -1
  311. package/dist/i18n/locales/el.js +2 -1
  312. package/dist/i18n/locales/el.js.map +1 -1
  313. package/dist/i18n/locales/en.d.ts +1 -0
  314. package/dist/i18n/locales/en.d.ts.map +1 -1
  315. package/dist/i18n/locales/en.js +2 -1
  316. package/dist/i18n/locales/en.js.map +1 -1
  317. package/dist/i18n/locales/es.d.ts +1 -0
  318. package/dist/i18n/locales/es.d.ts.map +1 -1
  319. package/dist/i18n/locales/es.js +2 -1
  320. package/dist/i18n/locales/es.js.map +1 -1
  321. package/dist/i18n/locales/fr.d.ts +1 -0
  322. package/dist/i18n/locales/fr.d.ts.map +1 -1
  323. package/dist/i18n/locales/fr.js +2 -1
  324. package/dist/i18n/locales/fr.js.map +1 -1
  325. package/dist/i18n/locales/hi.d.ts +1 -0
  326. package/dist/i18n/locales/hi.d.ts.map +1 -1
  327. package/dist/i18n/locales/hi.js +2 -1
  328. package/dist/i18n/locales/hi.js.map +1 -1
  329. package/dist/i18n/locales/it.d.ts +1 -0
  330. package/dist/i18n/locales/it.d.ts.map +1 -1
  331. package/dist/i18n/locales/it.js +2 -1
  332. package/dist/i18n/locales/it.js.map +1 -1
  333. package/dist/i18n/locales/ja.d.ts +1 -0
  334. package/dist/i18n/locales/ja.d.ts.map +1 -1
  335. package/dist/i18n/locales/ja.js +2 -1
  336. package/dist/i18n/locales/ja.js.map +1 -1
  337. package/dist/i18n/locales/nl.d.ts +1 -0
  338. package/dist/i18n/locales/nl.d.ts.map +1 -1
  339. package/dist/i18n/locales/nl.js +2 -1
  340. package/dist/i18n/locales/nl.js.map +1 -1
  341. package/dist/i18n/locales/pl.d.ts +1 -0
  342. package/dist/i18n/locales/pl.d.ts.map +1 -1
  343. package/dist/i18n/locales/pl.js +2 -1
  344. package/dist/i18n/locales/pl.js.map +1 -1
  345. package/dist/i18n/locales/pt.d.ts +1 -0
  346. package/dist/i18n/locales/pt.d.ts.map +1 -1
  347. package/dist/i18n/locales/pt.js +2 -1
  348. package/dist/i18n/locales/pt.js.map +1 -1
  349. package/dist/i18n/locales/ro.d.ts +1 -0
  350. package/dist/i18n/locales/ro.d.ts.map +1 -1
  351. package/dist/i18n/locales/ro.js +2 -1
  352. package/dist/i18n/locales/ro.js.map +1 -1
  353. package/dist/i18n/locales/ru.d.ts +1 -0
  354. package/dist/i18n/locales/ru.d.ts.map +1 -1
  355. package/dist/i18n/locales/ru.js +2 -1
  356. package/dist/i18n/locales/ru.js.map +1 -1
  357. package/dist/i18n/locales/sq.d.ts +1 -0
  358. package/dist/i18n/locales/sq.d.ts.map +1 -1
  359. package/dist/i18n/locales/sq.js +2 -1
  360. package/dist/i18n/locales/sq.js.map +1 -1
  361. package/dist/i18n/locales/sv.d.ts +1 -0
  362. package/dist/i18n/locales/sv.d.ts.map +1 -1
  363. package/dist/i18n/locales/sv.js +2 -1
  364. package/dist/i18n/locales/sv.js.map +1 -1
  365. package/dist/i18n/locales/tr.d.ts +1 -0
  366. package/dist/i18n/locales/tr.d.ts.map +1 -1
  367. package/dist/i18n/locales/tr.js +2 -1
  368. package/dist/i18n/locales/tr.js.map +1 -1
  369. package/dist/i18n/locales/zh.d.ts +1 -0
  370. package/dist/i18n/locales/zh.d.ts.map +1 -1
  371. package/dist/i18n/locales/zh.js +2 -1
  372. package/dist/i18n/locales/zh.js.map +1 -1
  373. package/dist/index.js +96 -96
  374. package/dist/locales/ar.json +2 -1
  375. package/dist/locales/de.json +2 -1
  376. package/dist/locales/el.json +2 -1
  377. package/dist/locales/en.json +2 -1
  378. package/dist/locales/es.json +2 -1
  379. package/dist/locales/fr.json +2 -1
  380. package/dist/locales/hi.json +2 -1
  381. package/dist/locales/it.json +2 -1
  382. package/dist/locales/ja.json +2 -1
  383. package/dist/locales/nl.json +2 -1
  384. package/dist/locales/pl.json +2 -1
  385. package/dist/locales/pt.json +2 -1
  386. package/dist/locales/ro.json +2 -1
  387. package/dist/locales/ru.json +2 -1
  388. package/dist/locales/sq.json +2 -1
  389. package/dist/locales/sv.json +2 -1
  390. package/dist/locales/tr.json +2 -1
  391. package/dist/locales/zh.json +2 -1
  392. package/dist/patterns/alia-assistant/index.js +1 -1
  393. package/dist/patterns/anamnesis/index.js +1 -1
  394. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  395. package/dist/patterns/payment-automation-upsell/index.js +1 -1
  396. package/dist/patterns/signature-request/index.js +1 -1
  397. package/dist/tokens.css +1 -1
  398. package/package.json +1 -1
  399. package/dist/_chunks/button-BvNtqHAS.js.map +0 -1
  400. package/dist/_chunks/practice-results-CKoLD_x5.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"key-value-pair-DGkGlgCF.js","sources":["../../src/components/key-value-pair/key-value-pair.tsx"],"sourcesContent":["import { forwardRef, useState, useCallback, type HTMLAttributes } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Copy, Check } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* CVA — root wrapper */\n/* */\n/* The layout variants below describe the LOGICAL flow of label/value. */\n/* When an `icon` prop is supplied, the root flips to `flex-row` and */\n/* renders the icon at the leading edge regardless of the chosen */\n/* layout — the layout then governs the inner label/value stack. Cap- */\n/* height alignment is handled by `items-start` + a small `mt` offset */\n/* on the icon wrapper so a wrapping value doesn't push the icon */\n/* downward. */\n/* ------------------------------------------------------------------ */\n\nconst keyValuePairVariants = cva('ds:flex', {\n variants: {\n layout: {\n horizontal: 'ds:flex-row ds:items-center ds:gap-[var(--spacing-sm)]',\n vertical: 'ds:flex-col ds:gap-[var(--spacing-xs)]',\n },\n /** Internal — flips the root to a horizontal flex when an icon\n is present so the icon can sit at the leading edge of both\n horizontal and vertical inner stacks. `items-start` keeps the\n icon anchored to the label row even when the value wraps. */\n hasIcon: {\n true: 'ds:flex-row ds:items-start ds:gap-[var(--spacing-sm)]',\n false: '',\n },\n },\n defaultVariants: {\n layout: 'horizontal',\n hasIcon: false,\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* KeyValuePairProps */\n/* ------------------------------------------------------------------ */\n\nexport interface KeyValuePairProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<VariantProps<typeof keyValuePairVariants>, 'hasIcon'> {\n /** The label (term) */\n label: string;\n /** The value — accepts plain text, Badge, Tag, monospace code, any ReactNode */\n value: React.ReactNode;\n /** Layout direction */\n layout?: 'horizontal' | 'vertical';\n /** Render value in monospace font */\n mono?: boolean;\n /** Show a copy-to-clipboard IconButton beside the value */\n copyable?: boolean;\n /** The text to copy — defaults to `value` if value is a string */\n copyText?: string;\n /**\n * Optional decorative icon rendered at the leading edge of the pair.\n * Pass a `lucide-react` icon (or any single React element) for\n * visual consistency. The wrapper applies `aria-hidden=\"true\"` and\n * paints the icon with `var(--key-value-pair-icon-color)` (defaults\n * to `--muted-foreground`); consumers can recolour the slot via\n * that token without forking the component.\n *\n * Cap-height alignment with the label is automatic — the wrapper\n * uses `mt-0.5` so the glyph rides the label row, not the\n * geometric centre of a wrapping value.\n *\n * Type is `ReactElement` (not the broader `ReactNode`) so the\n * intent is clear at the call site: this slot is for a single\n * SVG/icon, not arbitrary fragments, strings, or numbers.\n */\n icon?: React.ReactElement | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* KeyValuePair */\n/* ------------------------------------------------------------------ */\n\nexport const KeyValuePair = forwardRef<HTMLDivElement, KeyValuePairProps>(\n (\n {\n label,\n value,\n layout = 'horizontal',\n mono = false,\n copyable = false,\n copyText,\n icon,\n className,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const [copied, setCopied] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n const textToCopy =\n copyText ?? (typeof value === 'string' ? value : undefined);\n\n const handleCopy = useCallback(async () => {\n if (!textToCopy) {\n if (import.meta.env.DEV) {\n console.warn(\n 'KeyValuePair: copyable is true but no copyText was provided and value is not a string. Copy no-op.',\n );\n }\n return;\n }\n\n try {\n await navigator.clipboard.writeText(textToCopy);\n setCopied(true);\n setAnnouncement(t('keyValuePair.copied'));\n setTimeout(() => {\n setCopied(false);\n setAnnouncement('');\n }, 2000);\n } catch {\n setAnnouncement(t('keyValuePair.notAvailable'));\n setTimeout(() => setAnnouncement(''), 3000);\n }\n }, [textToCopy, t]);\n\n const valueClasses = [\n 'type-body ds:text-foreground ds:min-w-0 ds:shrink ds:[unicode-bidi:isolate]',\n // `flex-1` lets the value absorb the remaining inline space\n // when the KVP root flexes the icon / label / value as direct\n // siblings (`hasIcon && layout === 'horizontal'`). Without it,\n // the value would shrink to its content width and the row\n // would leave inline-end whitespace. Vertical layout doesn't\n // need it because the value is below the label, not beside it.\n layout === 'horizontal' ? 'ds:flex-1' : '',\n mono ? 'ds:font-[family-name:var(--font-mono)]' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const hasIcon = icon !== undefined && icon !== null;\n\n // Inner stack — used ONLY for `layout=\"vertical\"` when an icon is\n // present (icon on the leading edge, label-on-top-of-value stacked\n // next to it). For `layout=\"horizontal\"` we render the icon /\n // label / value as direct flex children of the root — wrapping\n // them in a single `<div>` would break the KeyValueList subgrid\n // (the subgrid's 3 tracks would collapse to 2: the wrapper +\n // icon). See the conditional below.\n const innerStackClass =\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:min-w-0 ds:flex-1';\n\n const stack = (\n <>\n <span className=\"type-label ds:text-muted-foreground ds:shrink-0\">\n {label}\n <span className=\"ds:sr-only\">: </span>\n </span>\n <span className={valueClasses}>{value}</span>\n {copyable && (\n <IconButton\n icon={copied ? <Check /> : <Copy />}\n size=\"sm\"\n aria-label={t('keyValuePair.copy', { label })}\n onClick={handleCopy}\n intent=\"ghost\"\n className={\n layout === 'horizontal'\n ? 'ds:ms-auto ds:shrink-0'\n : 'ds:self-start'\n }\n />\n )}\n </>\n );\n\n return (\n <div\n ref={ref}\n className={keyValuePairVariants({ layout, hasIcon, className })}\n data-component=\"key-value-pair\"\n {...props}\n >\n {hasIcon ? (\n <>\n {/* Decorative icon wrapper. `aria-hidden` so SR users only\n hear \"<label>: <value>\" — the icon is brand polish,\n not semantic content.\n\n `translate-y` shifts the icon down by 2px visually so\n its centre lines up with the label's x-height centre.\n In a baseline-aligned subgrid row, the icon's margin-\n box bottom pins to the label's text baseline — that\n leaves the 16px SVG sitting visually 3-4px above the\n label's centre. `translate-y` adjusts only the paint\n position; the underlying baseline math still holds,\n so multi-line value cells (e.g. address + map link)\n stay correctly aligned with the FIRST line of the\n value. */}\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:shrink-0 ds:translate-y-0.5 ds:text-[color:var(--key-value-pair-icon-color)] ds:[&_svg]:size-4\"\n >\n {icon}\n </span>\n {/* `horizontal` layout: render label / value / copy as\n direct flex children of the root so each piece falls\n into its own track when this KVP is promoted to a\n subgrid row by `<KeyValueList>`. Wrapping them in a\n `<div>` here would collapse the subgrid's 3 tracks\n (icon | label | value) to 2 (icon | wrapper) and labels\n across rows would no longer share a column. The root's\n `flex flex-row` + `gap-sm` keeps the standalone visual\n identical.\n\n `vertical` layout still needs the wrapper because the\n stack is column-flow — label-on-top-of-value next to\n the icon. */}\n {layout === 'horizontal' ? (\n stack\n ) : (\n <div className={innerStackClass}>{stack}</div>\n )}\n </>\n ) : (\n stack\n )}\n <span role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {announcement}\n </span>\n </div>\n );\n },\n);\n\nKeyValuePair.displayName = 'KeyValuePair';\n\n/* ------------------------------------------------------------------ */\n/* KeyValueList — subgrid alignment for a column of KVP rows */\n/* */\n/* When several `<KeyValuePair>` rows live in the same card (practice */\n/* profile, settings panel, contact card, etc.), the per-row flex */\n/* layout means each row's label column has a different width. The */\n/* values end up zigzagged. Wrapping in `<KeyValueList>` puts all rows */\n/* into a single 3-column CSS subgrid (icon | label | value), so */\n/* labels share a column across rows and values start at the same */\n/* inline-start edge. */\n/* */\n/* Standalone `<KeyValuePair>` instances outside a `<KeyValueList>` */\n/* keep their existing per-row flex layout — no behaviour change for */\n/* consumers that didn't opt in. */\n/* ------------------------------------------------------------------ */\n\nexport interface KeyValueListProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Gap between rows. Maps to spacing tokens — defaults to `md`.\n * Smaller gaps suit dense settings panels; larger gaps suit\n * profile cards.\n */\n rowGap?: 'sm' | 'md' | 'lg';\n}\n\nconst rowGapClassMap: Record<\n NonNullable<KeyValueListProps['rowGap']>,\n string\n> = {\n sm: 'ds:gap-y-[var(--spacing-sm)]',\n md: 'ds:gap-y-[var(--spacing-md)]',\n lg: 'ds:gap-y-[var(--spacing-lg)]',\n};\n\nexport const KeyValueList = forwardRef<HTMLDivElement, KeyValueListProps>(\n ({ children, className, rowGap = 'md', ...props }, ref) => {\n // Three-column subgrid: icon | label | value.\n // - col 1: `auto` — width of the widest icon (or 0 if no rows have icons)\n // - col 2: `auto` — width of the widest label, shared across all rows\n // - col 3: `minmax(0, 1fr)` — value flexes; `minmax` prevents the\n // value from forcing the grid wider than its container when the\n // value contains a long unbroken string (e.g. an email or URL).\n //\n // Each child `<KeyValuePair>` (which renders as a `<div>` with a\n // `data-component=\"key-value-pair\"` marker) is promoted into a\n // subgrid row by the CSS below — the cell boundaries align across\n // every direct child.\n //\n // We render as `<div>` (not `<dl>`): axe enforces \"dl can only\n // contain dt/dd\" and the inner KVP renders as a `<div>`. The KVP's\n // own SR markup (label + `<span class=\"sr-only\">: </span>` + value)\n // already conveys term-value semantics — wrapping in a `<dl>`\n // doesn't add anything the screen reader doesn't already get.\n return (\n <div\n ref={ref}\n data-component=\"key-value-list\"\n className={[\n 'ds:grid ds:grid-cols-[auto_auto_minmax(0,1fr)]',\n 'ds:gap-x-[var(--spacing-md)]',\n rowGapClassMap[rowGap],\n // Each direct `data-component=\"key-value-pair\"` child becomes\n // a subgrid row spanning all three columns. The KVP's own\n // flex layout still works inside the cell (icon shrinks-0,\n // label shrinks-0, value flexes) — subgrid just aligns the\n // boundaries between siblings.\n 'ds:[&>[data-component=\"key-value-pair\"]]:grid',\n 'ds:[&>[data-component=\"key-value-pair\"]]:grid-cols-subgrid',\n 'ds:[&>[data-component=\"key-value-pair\"]]:col-span-3',\n 'ds:[&>[data-component=\"key-value-pair\"]]:items-baseline',\n // Unset the KVP's intra-row `gap-sm` so the subgrid inherits\n // the parent KeyValueList's `gap-x-md` for every track gap\n // (icon→label and label→value). `gap-0` here would override\n // the parent's gap and crowd the icon against the label;\n // `[gap:normal]` is the subgrid-spec way to defer to the\n // parent.\n 'ds:[&>[data-component=\"key-value-pair\"]]:[gap:normal]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {children}\n </div>\n );\n },\n);\n\nKeyValueList.displayName = 'KeyValueList';\n"],"names":["keyValuePairVariants","cva","KeyValuePair","forwardRef","label","value","layout","mono","copyable","copyText","icon","className","props","ref","t","useTranslation","copied","setCopied","useState","announcement","setAnnouncement","textToCopy","handleCopy","useCallback","valueClasses","hasIcon","innerStackClass","stack","jsxs","Fragment","jsx","IconButton","Check","Copy","rowGapClassMap","KeyValueList","children","rowGap"],"mappings":"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"}
1
+ {"version":3,"file":"key-value-pair-BubG4fUa.js","sources":["../../src/components/key-value-pair/key-value-pair.tsx"],"sourcesContent":["import { forwardRef, useState, useCallback, type HTMLAttributes } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Copy, Check } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* CVA — root wrapper */\n/* */\n/* The layout variants below describe the LOGICAL flow of label/value. */\n/* When an `icon` prop is supplied, the root flips to `flex-row` and */\n/* renders the icon at the leading edge regardless of the chosen */\n/* layout — the layout then governs the inner label/value stack. Cap- */\n/* height alignment is handled by `items-start` + a small `mt` offset */\n/* on the icon wrapper so a wrapping value doesn't push the icon */\n/* downward. */\n/* ------------------------------------------------------------------ */\n\nconst keyValuePairVariants = cva('ds:flex', {\n variants: {\n layout: {\n horizontal: 'ds:flex-row ds:items-center ds:gap-[var(--spacing-sm)]',\n vertical: 'ds:flex-col ds:gap-[var(--spacing-xs)]',\n },\n /** Internal — flips the root to a horizontal flex when an icon\n is present so the icon can sit at the leading edge of both\n horizontal and vertical inner stacks. `items-start` keeps the\n icon anchored to the label row even when the value wraps. */\n hasIcon: {\n true: 'ds:flex-row ds:items-start ds:gap-[var(--spacing-sm)]',\n false: '',\n },\n },\n defaultVariants: {\n layout: 'horizontal',\n hasIcon: false,\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* KeyValuePairProps */\n/* ------------------------------------------------------------------ */\n\nexport interface KeyValuePairProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<VariantProps<typeof keyValuePairVariants>, 'hasIcon'> {\n /** The label (term) */\n label: string;\n /** The value — accepts plain text, Badge, Tag, monospace code, any ReactNode */\n value: React.ReactNode;\n /** Layout direction */\n layout?: 'horizontal' | 'vertical';\n /** Render value in monospace font */\n mono?: boolean;\n /** Show a copy-to-clipboard IconButton beside the value */\n copyable?: boolean;\n /** The text to copy — defaults to `value` if value is a string */\n copyText?: string;\n /**\n * Optional decorative icon rendered at the leading edge of the pair.\n * Pass a `lucide-react` icon (or any single React element) for\n * visual consistency. The wrapper applies `aria-hidden=\"true\"` and\n * paints the icon with `var(--key-value-pair-icon-color)` (defaults\n * to `--muted-foreground`); consumers can recolour the slot via\n * that token without forking the component.\n *\n * Cap-height alignment with the label is automatic — the wrapper\n * uses `mt-0.5` so the glyph rides the label row, not the\n * geometric centre of a wrapping value.\n *\n * Type is `ReactElement` (not the broader `ReactNode`) so the\n * intent is clear at the call site: this slot is for a single\n * SVG/icon, not arbitrary fragments, strings, or numbers.\n */\n icon?: React.ReactElement | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* KeyValuePair */\n/* ------------------------------------------------------------------ */\n\nexport const KeyValuePair = forwardRef<HTMLDivElement, KeyValuePairProps>(\n (\n {\n label,\n value,\n layout = 'horizontal',\n mono = false,\n copyable = false,\n copyText,\n icon,\n className,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const [copied, setCopied] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n const textToCopy =\n copyText ?? (typeof value === 'string' ? value : undefined);\n\n const handleCopy = useCallback(async () => {\n if (!textToCopy) {\n if (import.meta.env.DEV) {\n console.warn(\n 'KeyValuePair: copyable is true but no copyText was provided and value is not a string. Copy no-op.',\n );\n }\n return;\n }\n\n try {\n await navigator.clipboard.writeText(textToCopy);\n setCopied(true);\n setAnnouncement(t('keyValuePair.copied'));\n setTimeout(() => {\n setCopied(false);\n setAnnouncement('');\n }, 2000);\n } catch {\n setAnnouncement(t('keyValuePair.notAvailable'));\n setTimeout(() => setAnnouncement(''), 3000);\n }\n }, [textToCopy, t]);\n\n const valueClasses = [\n 'type-body ds:text-foreground ds:min-w-0 ds:shrink ds:[unicode-bidi:isolate]',\n // `flex-1` lets the value absorb the remaining inline space\n // when the KVP root flexes the icon / label / value as direct\n // siblings (`hasIcon && layout === 'horizontal'`). Without it,\n // the value would shrink to its content width and the row\n // would leave inline-end whitespace. Vertical layout doesn't\n // need it because the value is below the label, not beside it.\n layout === 'horizontal' ? 'ds:flex-1' : '',\n mono ? 'ds:font-[family-name:var(--font-mono)]' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const hasIcon = icon !== undefined && icon !== null;\n\n // Inner stack — used ONLY for `layout=\"vertical\"` when an icon is\n // present (icon on the leading edge, label-on-top-of-value stacked\n // next to it). For `layout=\"horizontal\"` we render the icon /\n // label / value as direct flex children of the root — wrapping\n // them in a single `<div>` would break the KeyValueList subgrid\n // (the subgrid's 3 tracks would collapse to 2: the wrapper +\n // icon). See the conditional below.\n const innerStackClass =\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:min-w-0 ds:flex-1';\n\n const stack = (\n <>\n <span className=\"type-label ds:text-muted-foreground ds:shrink-0\">\n {label}\n <span className=\"ds:sr-only\">: </span>\n </span>\n <span className={valueClasses}>{value}</span>\n {copyable && (\n <IconButton\n icon={copied ? <Check /> : <Copy />}\n size=\"sm\"\n aria-label={t('keyValuePair.copy', { label })}\n onClick={handleCopy}\n intent=\"ghost\"\n className={\n layout === 'horizontal'\n ? 'ds:ms-auto ds:shrink-0'\n : 'ds:self-start'\n }\n />\n )}\n </>\n );\n\n return (\n <div\n ref={ref}\n className={keyValuePairVariants({ layout, hasIcon, className })}\n data-component=\"key-value-pair\"\n {...props}\n >\n {hasIcon ? (\n <>\n {/* Decorative icon wrapper. `aria-hidden` so SR users only\n hear \"<label>: <value>\" — the icon is brand polish,\n not semantic content.\n\n `translate-y` shifts the icon down by 2px visually so\n its centre lines up with the label's x-height centre.\n In a baseline-aligned subgrid row, the icon's margin-\n box bottom pins to the label's text baseline — that\n leaves the 16px SVG sitting visually 3-4px above the\n label's centre. `translate-y` adjusts only the paint\n position; the underlying baseline math still holds,\n so multi-line value cells (e.g. address + map link)\n stay correctly aligned with the FIRST line of the\n value. */}\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:shrink-0 ds:translate-y-0.5 ds:text-[color:var(--key-value-pair-icon-color)] ds:[&_svg]:size-4\"\n >\n {icon}\n </span>\n {/* `horizontal` layout: render label / value / copy as\n direct flex children of the root so each piece falls\n into its own track when this KVP is promoted to a\n subgrid row by `<KeyValueList>`. Wrapping them in a\n `<div>` here would collapse the subgrid's 3 tracks\n (icon | label | value) to 2 (icon | wrapper) and labels\n across rows would no longer share a column. The root's\n `flex flex-row` + `gap-sm` keeps the standalone visual\n identical.\n\n `vertical` layout still needs the wrapper because the\n stack is column-flow — label-on-top-of-value next to\n the icon. */}\n {layout === 'horizontal' ? (\n stack\n ) : (\n <div className={innerStackClass}>{stack}</div>\n )}\n </>\n ) : (\n stack\n )}\n <span role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {announcement}\n </span>\n </div>\n );\n },\n);\n\nKeyValuePair.displayName = 'KeyValuePair';\n\n/* ------------------------------------------------------------------ */\n/* KeyValueList — subgrid alignment for a column of KVP rows */\n/* */\n/* When several `<KeyValuePair>` rows live in the same card (practice */\n/* profile, settings panel, contact card, etc.), the per-row flex */\n/* layout means each row's label column has a different width. The */\n/* values end up zigzagged. Wrapping in `<KeyValueList>` puts all rows */\n/* into a single 3-column CSS subgrid (icon | label | value), so */\n/* labels share a column across rows and values start at the same */\n/* inline-start edge. */\n/* */\n/* Standalone `<KeyValuePair>` instances outside a `<KeyValueList>` */\n/* keep their existing per-row flex layout — no behaviour change for */\n/* consumers that didn't opt in. */\n/* ------------------------------------------------------------------ */\n\nexport interface KeyValueListProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Gap between rows. Maps to spacing tokens — defaults to `md`.\n * Smaller gaps suit dense settings panels; larger gaps suit\n * profile cards.\n */\n rowGap?: 'sm' | 'md' | 'lg';\n}\n\nconst rowGapClassMap: Record<\n NonNullable<KeyValueListProps['rowGap']>,\n string\n> = {\n sm: 'ds:gap-y-[var(--spacing-sm)]',\n md: 'ds:gap-y-[var(--spacing-md)]',\n lg: 'ds:gap-y-[var(--spacing-lg)]',\n};\n\nexport const KeyValueList = forwardRef<HTMLDivElement, KeyValueListProps>(\n ({ children, className, rowGap = 'md', ...props }, ref) => {\n // Three-column subgrid: icon | label | value.\n // - col 1: `auto` — width of the widest icon (or 0 if no rows have icons)\n // - col 2: `auto` — width of the widest label, shared across all rows\n // - col 3: `minmax(0, 1fr)` — value flexes; `minmax` prevents the\n // value from forcing the grid wider than its container when the\n // value contains a long unbroken string (e.g. an email or URL).\n //\n // Each child `<KeyValuePair>` (which renders as a `<div>` with a\n // `data-component=\"key-value-pair\"` marker) is promoted into a\n // subgrid row by the CSS below — the cell boundaries align across\n // every direct child.\n //\n // We render as `<div>` (not `<dl>`): axe enforces \"dl can only\n // contain dt/dd\" and the inner KVP renders as a `<div>`. The KVP's\n // own SR markup (label + `<span class=\"sr-only\">: </span>` + value)\n // already conveys term-value semantics — wrapping in a `<dl>`\n // doesn't add anything the screen reader doesn't already get.\n return (\n <div\n ref={ref}\n data-component=\"key-value-list\"\n className={[\n 'ds:grid ds:grid-cols-[auto_auto_minmax(0,1fr)]',\n 'ds:gap-x-[var(--spacing-md)]',\n rowGapClassMap[rowGap],\n // Each direct `data-component=\"key-value-pair\"` child becomes\n // a subgrid row spanning all three columns. The KVP's own\n // flex layout still works inside the cell (icon shrinks-0,\n // label shrinks-0, value flexes) — subgrid just aligns the\n // boundaries between siblings.\n 'ds:[&>[data-component=\"key-value-pair\"]]:grid',\n 'ds:[&>[data-component=\"key-value-pair\"]]:grid-cols-subgrid',\n 'ds:[&>[data-component=\"key-value-pair\"]]:col-span-3',\n 'ds:[&>[data-component=\"key-value-pair\"]]:items-baseline',\n // Unset the KVP's intra-row `gap-sm` so the subgrid inherits\n // the parent KeyValueList's `gap-x-md` for every track gap\n // (icon→label and label→value). `gap-0` here would override\n // the parent's gap and crowd the icon against the label;\n // `[gap:normal]` is the subgrid-spec way to defer to the\n // parent.\n 'ds:[&>[data-component=\"key-value-pair\"]]:[gap:normal]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {children}\n </div>\n );\n },\n);\n\nKeyValueList.displayName = 'KeyValueList';\n"],"names":["keyValuePairVariants","cva","KeyValuePair","forwardRef","label","value","layout","mono","copyable","copyText","icon","className","props","ref","t","useTranslation","copied","setCopied","useState","announcement","setAnnouncement","textToCopy","handleCopy","useCallback","valueClasses","hasIcon","innerStackClass","stack","jsxs","Fragment","jsx","IconButton","Check","Copy","rowGapClassMap","KeyValueList","children","rowGap"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { useGridFilter as A } from "ag-grid-react";
4
4
  import { D as H } from "./date-range-picker-CDrZ8Zh0.js";
5
5
  import { useTranslation as L } from "react-i18next";
6
6
  import { C as Q } from "./checkbox-BuZ1u__2.js";
7
- import { B as P } from "./button-BvNtqHAS.js";
7
+ import { B as P } from "./button-nJaPh_HC.js";
8
8
  import { M as W } from "./multi-select-DqL4o0qV.js";
9
9
  import { S as X } from "./scroll-area-BZOvUhwQ.js";
10
10
  import { A as $ } from "./autocomplete-BrONKN8l.js";
@@ -769,4 +769,4 @@ export {
769
769
  Ae as f,
770
770
  qe as g
771
771
  };
772
- //# sourceMappingURL=link-cell-renderer-D3IsW_2R.js.map
772
+ //# sourceMappingURL=link-cell-renderer-DH4JYpKU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-cell-renderer-D3IsW_2R.js","sources":["../../src/components/data-table/filters/date-range-filter.tsx","../../src/components/data-table/filters/select-filter.tsx","../../src/components/data-table/filters/typeahead-filter.tsx","../../src/components/data-table/filters/number-filter.tsx","../../src/components/data-table/cell-renderers/status-cell-renderer.tsx","../../src/components/data-table/cell-renderers/user-cell-renderer.tsx","../../src/components/data-table/cell-renderers/image-cell-renderer.tsx","../../src/components/data-table/cell-renderers/tag-list-cell-renderer.tsx","../../src/components/data-table/cell-renderers/date-cell-renderer.tsx","../../src/components/data-table/cell-renderers/currency-cell-renderer.tsx","../../src/components/data-table/cell-renderers/link-cell-renderer.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter } from 'ag-grid-community';\nimport { DateRangePicker } from '../../date-range-picker';\nimport type { DateRangeValue } from '../../date-range-picker';\n\n/**\n * Custom AG Grid filter component for date *ranges*. AG Grid Community's\n * built-in `agDateColumnFilter` only handles single-date comparison —\n * platform needs \"between X and Y\" for invoice / transaction lists.\n *\n * Wire on a colDef:\n * ```tsx\n * { field: 'date', filter: DateRangeFilter }\n * ```\n *\n * The filter model has shape `{ type: 'inRange', dateFrom, dateTo }` to\n * stay close to AG Grid's own date-filter convention so server-side\n * adapters can interpret it the same way.\n */\nexport interface DateRangeFilterModel {\n type: 'inRange';\n dateFrom: string | null;\n dateTo: string | null;\n}\n\n/**\n * `filterParams` a colDef may pass to `DateRangeFilter` /\n * `DateRangeFloatingFilter`.\n *\n * `commitMode` is forwarded to the wrapped `DateRangePicker`. Leave it unset\n * (picker default `'auto'`, commit-on-complete-range) for cheap client-side row\n * models; set `'apply'` for SERVER-side row models so each range edit defers to\n * one Apply and fires a single datasource round-trip instead of one per commit.\n */\nexport interface DateRangeFilterParams {\n placeholder?: string;\n commitMode?: 'auto' | 'apply';\n}\n\nfunction toIsoDate(d: Date | undefined): string | null {\n if (!d) return null;\n return d.toISOString().slice(0, 10);\n}\n\nfunction fromIsoDate(s: string | null | undefined): Date | undefined {\n if (!s) return undefined;\n const d = new Date(s);\n return Number.isNaN(d.getTime()) ? undefined : d;\n}\n\nexport function DateRangeFilter(\n props: CustomFilterProps<unknown, unknown, DateRangeFilterModel>,\n) {\n const { model, onModelChange, getValue, doesRowPassOtherFilter } = props;\n const filterParams =\n (props.colDef?.filterParams as DateRangeFilterParams | undefined) ?? {};\n // Picker UI state, seeded from the model and kept in sync when the model\n // changes externally — a programmatic default (e.g. \"this week\"), a server\n // restore, or an AG Grid reset. Mirrors `SelectFilter`'s `pending` sync.\n const [range, setRange] = useState<DateRangeValue>(() => ({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n }));\n useEffect(() => {\n setRange({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n });\n }, [model?.dateFrom, model?.dateTo]);\n\n // Tell AG Grid how to evaluate a row against the current model. AG Grid\n // calls this for each row; we read the cell value via `getValue(node)`\n // (a Date or ISO string), compare to the bounds. Bounds come from the\n // MODEL (the source of truth) — not the picker state — so a model set\n // programmatically applies even before the picker UI has mounted, exactly\n // as `SelectFilter` reads `model.values` directly.\n useGridFilter({\n doesFilterPass: (params) => {\n const from = fromIsoDate(model?.dateFrom);\n const to = fromIsoDate(model?.dateTo);\n if (!from && !to) return true;\n const cellValue = getValue(params.node) as\n | Date\n | string\n | null\n | undefined;\n if (!cellValue) return false;\n const cellDate =\n cellValue instanceof Date ? cellValue : fromIsoDate(String(cellValue));\n if (!cellDate) return false;\n if (from && cellDate < from) return false;\n if (to && cellDate > to) return false;\n // Respect other filters via the supplied callback if AG Grid uses\n // it (some grid setups call `doesRowPassOtherFilter` before us).\n void doesRowPassOtherFilter;\n return true;\n },\n });\n\n function apply(next: DateRangeValue) {\n setRange(next);\n if (!next.from && !next.to) {\n onModelChange(null);\n return;\n }\n onModelChange({\n type: 'inRange',\n dateFrom: toIsoDate(next.from),\n dateTo: toIsoDate(next.to),\n } satisfies DateRangeFilterModel);\n }\n\n return (\n <div\n data-component=\"date-range-filter\"\n className=\"ds:p-[var(--spacing-sm)] ds:min-w-[280px]\"\n >\n <DateRangePicker\n value={range}\n onChange={apply}\n commitMode={filterParams.commitMode}\n size=\"sm\"\n />\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `DateRangeFilter`.\n *\n * Renders the kit's `<DateRangePicker>` directly as the floating-filter\n * input — its built-in trigger button + calendar popover IS the filter\n * UI. Earlier versions wrapped the picker in a second `<Popover>`,\n * producing the \"click → empty popover with another trigger → click\n * again → calendar\" double-step that read as duplicated UI.\n */\nexport function DateRangeFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n DateRangeFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n // Let a colDef supply a short `filterParams.placeholder` for the in-row\n // trigger — the default \"Select date range\" is long for a narrow filter\n // column. (The label truncates cleanly either way; a short placeholder just\n // reads better.)\n const filterParams =\n (column?.getColDef?.()?.filterParams as\n | DateRangeFilterParams\n | undefined) ?? {};\n const [range, setRange] = useState<DateRangeValue>(() => ({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n }));\n // Reflect external model changes (a programmatic default, a parent-filter\n // edit, an AG Grid reset) in the in-row picker trigger.\n useEffect(() => {\n setRange({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n });\n }, [model?.dateFrom, model?.dateTo]);\n\n function apply(next: DateRangeValue) {\n setRange(next);\n if (!next.from && !next.to) {\n onModelChange(null);\n return;\n }\n onModelChange({\n type: 'inRange',\n dateFrom: toIsoDate(next.from),\n dateTo: toIsoDate(next.to),\n } satisfies DateRangeFilterModel);\n }\n\n return (\n <div data-component=\"date-range-floating-filter\" className=\"ds:w-full\">\n <DateRangePicker\n value={range}\n onChange={apply}\n commitMode={filterParams.commitMode}\n size=\"sm\"\n placeholder={filterParams.placeholder}\n />\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { GridApi, IFilter, IRowNode } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { Checkbox } from '../../checkbox';\nimport { Button } from '../../button';\nimport { MultiSelect } from '../../multi-select';\nimport { ScrollArea } from '../../scroll-area/scroll-area';\n\n/**\n * Custom AG Grid filter component — multi-select facet filter.\n *\n * The Community-friendly equivalent of AG Grid Enterprise's\n * `agSetColumnFilter`. Surfaces a checkbox list of every value the column\n * can take, so users tick to include / untick to exclude. Much faster than\n * the default `agTextColumnFilter` for closed enums (status, room,\n * operator).\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'status',\n * filter: SelectFilter,\n * filterParams: {\n * options: [\n * { value: 'open', label: 'Aperte' },\n * { value: 'paid', label: 'Pagate' },\n * ],\n * },\n * }\n * ```\n *\n * Model shape `{ type: 'set', values: Array<string | number> }` matches\n * AG Grid Enterprise's set-filter convention so server-side adapters can\n * read either implementation the same way.\n */\n\nexport interface SelectFilterOption {\n value: string | number;\n label: string;\n}\n\nexport interface SelectFilterModel {\n type: 'set';\n values: Array<string | number>;\n}\n\nexport interface SelectFilterParams {\n options?: SelectFilterOption[];\n placeholder?: string;\n}\n\ntype SelectFilterValue = string | number;\n\nfunction toValueKey(v: SelectFilterValue): string {\n return typeof v === 'number' ? `n:${v}` : `s:${v}`;\n}\n\n/** How a filter surface reads one row's value for its column. */\ntype SelectValueReader = (node: IRowNode) => unknown;\n\n/** Numeric collation, so a derived numeric column lists 1, 2, 3, 10 rather\n * than the lexicographic 1, 10, 2, 3. */\nconst LABEL_COLLATOR = new Intl.Collator(undefined, { numeric: true });\n\n/** Distinct values the column actually holds, label-sorted. `forEachNode`\n * walks the whole client-side row model, so the list does not shrink as\n * other columns filter rows out. */\nfunction collectColumnOptions(\n api: GridApi | undefined,\n readValue: SelectValueReader,\n): SelectFilterOption[] {\n if (!api) return [];\n const seen = new Map<string, SelectFilterOption>();\n api.forEachNode((node: IRowNode) => {\n const raw = readValue(node);\n if (raw === null || raw === undefined) return;\n const value =\n typeof raw === 'string' || typeof raw === 'number' ? raw : String(raw);\n const key = toValueKey(value);\n if (!seen.has(key)) seen.set(key, { value, label: String(value) });\n });\n return Array.from(seen.values()).sort((a, b) =>\n LABEL_COLLATOR.compare(String(a.label), String(b.label)),\n );\n}\n\nfunction sameOptions(\n a: SelectFilterOption[],\n b: SelectFilterOption[],\n): boolean {\n if (a.length !== b.length) return false;\n return a.every(\n (opt, i) =>\n toValueKey(opt.value) === toValueKey(b[i].value) &&\n opt.label === b[i].label,\n );\n}\n\n/**\n * The universe of choices for one Select-filtered column.\n *\n * An explicit `options` filterParam always wins — INCLUDING an empty one,\n * which means \"this column has no facets\", not \"derive them for me\". Omit\n * `options` entirely and the list is DERIVED from the values the column\n * actually holds, and re-derived as the row data changes, so both the popup\n * panel and its floating-filter twin offer the same, data-accurate choices.\n */\nfunction useSelectFilterOptions(\n api: GridApi | undefined,\n options: SelectFilterOption[] | undefined,\n readValue: SelectValueReader,\n): SelectFilterOption[] {\n const explicit = options;\n const hasExplicit = explicit !== undefined;\n const [derived, setDerived] = useState<SelectFilterOption[]>([]);\n\n // Latest-reader ref so a new `getValue` identity per grid render does not\n // tear down and rebuild the grid event subscription below.\n const readValueRef = useRef(readValue);\n useEffect(() => {\n readValueRef.current = readValue;\n });\n\n useEffect(() => {\n if (hasExplicit || !api) return;\n const recompute = () => {\n setDerived((prev) => {\n const next = collectColumnOptions(api, readValueRef.current);\n return sameOptions(prev, next) ? prev : next;\n });\n };\n recompute();\n api.addEventListener('modelUpdated', recompute);\n api.addEventListener('cellValueChanged', recompute);\n return () => {\n if (api.isDestroyed()) return;\n api.removeEventListener('modelUpdated', recompute);\n api.removeEventListener('cellValueChanged', recompute);\n };\n }, [api, hasExplicit]);\n\n return explicit ?? derived;\n}\n\nexport function SelectFilter(\n props: CustomFilterProps<unknown, unknown, SelectFilterModel> &\n SelectFilterParams,\n) {\n const { model, onModelChange, getValue, api, options, placeholder } = props;\n const { t } = useTranslation('ui');\n\n const readValue = useCallback<SelectValueReader>(\n (node) => getValue(node) as unknown,\n [getValue],\n );\n const derivedOptions = useSelectFilterOptions(api, options, readValue);\n\n // Working set — checkboxes mutate `pending` only; we commit to the\n // grid via `onModelChange` when the user clicks Apply (or clears).\n const initialSelected = useMemo<Set<string>>(() => {\n const set = new Set<string>();\n const incoming = model?.values ?? [];\n for (const v of incoming) set.add(toValueKey(v));\n return set;\n }, [model]);\n\n const [pending, setPending] = useState<Set<string>>(initialSelected);\n\n // Sync local `pending` if the model changes externally (e.g. when AG\n // Grid pushes a reset). `model` is the dependency — Set instances are\n // compared by reference in React, so the memo above is sufficient.\n useEffect(() => {\n setPending(initialSelected);\n }, [initialSelected]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n const active = model?.values;\n if (!active || active.length === 0) return true;\n const raw = getValue(params.node) as unknown;\n if (raw === null || raw === undefined) return false;\n const value: SelectFilterValue =\n typeof raw === 'string' || typeof raw === 'number' ? raw : String(raw);\n const key = toValueKey(value);\n return active.some((v) => toValueKey(v) === key);\n },\n });\n\n function toggle(optionKey: string) {\n setPending((prev) => {\n const next = new Set(prev);\n if (next.has(optionKey)) next.delete(optionKey);\n else next.add(optionKey);\n return next;\n });\n }\n\n function apply() {\n if (pending.size === 0) {\n onModelChange(null);\n return;\n }\n const values: SelectFilterValue[] = [];\n for (const opt of derivedOptions) {\n if (pending.has(toValueKey(opt.value))) values.push(opt.value);\n }\n // A ticked value can leave the data before Apply (the derived list is\n // live). Committing `values: []` would read as an active filter that\n // matches every row, so clear instead.\n if (values.length === 0) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: 'set', values });\n }\n\n function clear() {\n setPending(new Set());\n onModelChange(null);\n }\n\n const placeholderLabel = placeholder ?? t('dataTable.selectFilter.all');\n\n return (\n <div\n data-component=\"select-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[200px] ds:max-w-[260px]\"\n >\n <ScrollArea orientation=\"vertical\" className=\"ds:max-h-[240px]\">\n <div\n role=\"group\"\n aria-label={placeholderLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n {derivedOptions.length === 0 ? (\n <p className=\"ds:text-[length:var(--font-size-sm)] ds:text-[var(--muted-foreground)] ds:py-[var(--spacing-xs)]\">\n {t('dataTable.agGrid.noRowsToShow')}\n </p>\n ) : (\n derivedOptions.map((option) => {\n const key = toValueKey(option.value);\n return (\n <Checkbox\n key={key}\n size=\"sm\"\n label={option.label}\n checked={pending.has(key)}\n onCheckedChange={() => toggle(key)}\n />\n );\n })\n )}\n </div>\n </ScrollArea>\n <div className=\"ds:flex ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.selectFilter.clear')}\n </Button>\n <Button intent=\"primary\" size=\"sm\" onClick={apply} type=\"button\">\n {t('dataTable.selectFilter.apply')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `SelectFilter`.\n *\n * Renders the kit's `<MultiSelect>` directly as the floating-filter\n * input — its built-in trigger + checkbox dropdown IS the filter UI.\n * Earlier versions wrapped MultiSelect in another `<Popover>`,\n * producing the \"click trigger → empty popover with another trigger →\n * click → checkbox list\" double-step that read as duplicated UI.\n *\n * MultiSelect's options use `string` values; we string-convert the\n * model's `(string | number)[]` for the trigger and parse back on\n * apply. The grid model still tracks the original primitive types so\n * `doesFilterPass` keeps matching numeric columns correctly.\n *\n * Choices come from the same `useSelectFilterOptions` universe the popup\n * panel uses: an explicit `options` filterParam if the consumer declared\n * one, otherwise the column's own distinct values. Reading only\n * `filterParams.options` used to leave the trigger empty beside a working\n * panel whenever the consumer relied on derivation.\n */\nexport function SelectFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n SelectFilterModel\n >,\n) {\n const { model, onModelChange, column, api } = props;\n\n const colDef = column?.getColDef?.();\n const filterParams =\n (colDef?.filterParams as SelectFilterParams | undefined) ?? {};\n\n // The floating filter has no `getValue`; read through the grid instead.\n // A column with a `filterValueGetter` should declare `options` — the two\n // reads would otherwise disagree with the panel's.\n const readValue = useCallback<SelectValueReader>(\n (node) =>\n api && column\n ? (api.getCellValue<unknown>({\n rowNode: node,\n colKey: column,\n }) as unknown)\n : undefined,\n [api, column],\n );\n const availableOptions = useSelectFilterOptions(\n api,\n filterParams.options,\n readValue,\n );\n // Name the floating-filter trigger after its column so the per-column Select\n // filters are distinguishable to assistive tech — they otherwise all read as\n // the generic MultiSelect placeholder. An explicit `placeholder` wins.\n const accessibleLabel =\n filterParams.placeholder ??\n (typeof colDef?.headerName === 'string' ? colDef.headerName : undefined);\n\n // MultiSelect's `value` is `string[]`. SelectFilter's model carries\n // `(string | number)[]` so we string-convert in / out. Build a lookup\n // from the stringified key back to the original primitive so the\n // model retains the consumer's typing.\n const valueByKey = useMemo(() => {\n const map = new Map<string, SelectFilterValue>();\n for (const opt of availableOptions) map.set(String(opt.value), opt.value);\n return map;\n }, [availableOptions]);\n\n const selectOptions = useMemo(\n () =>\n availableOptions.map((opt) => ({\n value: String(opt.value),\n label: opt.label,\n })),\n [availableOptions],\n );\n\n const currentValue = useMemo(\n () => (model?.values ?? []).map((v) => String(v)),\n [model],\n );\n\n function handleChange(next: string[]) {\n if (next.length === 0) {\n onModelChange(null);\n return;\n }\n const values: SelectFilterValue[] = [];\n for (const k of next) {\n const original = valueByKey.get(k);\n if (original !== undefined) values.push(original);\n }\n // Same live-list guard as the panel's Apply: an empty set is a cleared\n // filter, never an active one that matches everything.\n if (values.length === 0) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: 'set', values });\n }\n\n return (\n <div data-component=\"select-floating-filter\" className=\"ds:w-full\">\n <MultiSelect\n size=\"sm\"\n options={selectOptions}\n value={currentValue}\n onChange={handleChange}\n placeholder={filterParams.placeholder}\n aria-label={accessibleLabel}\n allowClear\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter, IRowNode } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { Autocomplete } from '../../autocomplete';\nimport { Button } from '../../button';\nimport type { OptionShape } from '../../_shared/option';\n\n/**\n * Custom AG Grid filter component — single-select typeahead filter.\n *\n * Wraps the kit's existing `<Autocomplete>` so the user types to filter a\n * bounded-but-large set of values (e.g. patient names), picks one\n * suggestion, and the grid filters to rows matching that value exactly.\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'patient',\n * filter: TypeaheadFilter,\n * filterParams: {\n * options: PATIENTS.map(p => ({ value: p.name, label: p.name })),\n * },\n * }\n * ```\n *\n * Model shape `{ type: 'equals', value: string }` matches AG Grid's\n * text-filter `equals` convention so server-side adapters can read either\n * implementation the same way.\n */\n\nexport interface TypeaheadFilterOption {\n value: string;\n label: string;\n}\n\nexport interface TypeaheadFilterModel {\n type: 'equals';\n value: string;\n}\n\nexport interface TypeaheadFilterParams {\n options?: TypeaheadFilterOption[];\n loadOptions?: (\n input: string,\n opts: { signal: AbortSignal; locale: string },\n ) => Promise<TypeaheadFilterOption[]>;\n placeholder?: string;\n}\n\nfunction normalise(s: string): string {\n return s.trim().toLocaleLowerCase();\n}\n\nexport function TypeaheadFilter(\n props: CustomFilterProps<unknown, unknown, TypeaheadFilterModel> &\n TypeaheadFilterParams,\n) {\n const {\n model,\n onModelChange,\n getValue,\n api,\n column,\n options,\n loadOptions,\n placeholder,\n } = props;\n const { t } = useTranslation('ui');\n\n // Universe of choices. Prefer explicit `options`; fall back to the\n // column's distinct values when neither `options` nor `loadOptions` is\n // supplied. Same shape as SelectFilter's derivation so the two filters\n // present a consistent experience when consumers don't enumerate.\n const derivedOptions = useMemo<TypeaheadFilterOption[]>(() => {\n if (options && options.length > 0) return options;\n if (!api || !column) return [];\n const seen = new Map<string, TypeaheadFilterOption>();\n api.forEachNode((node: IRowNode) => {\n const raw = getValue(node) as unknown;\n if (raw === null || raw === undefined) return;\n const value = typeof raw === 'string' ? raw : String(raw);\n if (!seen.has(value)) {\n seen.set(value, { value, label: value });\n }\n });\n return Array.from(seen.values()).sort((a, b) =>\n a.label.localeCompare(b.label),\n );\n }, [options, api, column, getValue]);\n\n // Build the async `loadOptions` adapter that <Autocomplete> consumes.\n // Local-options path filters the snapshot synchronously and wraps it\n // in Promise.resolve(); explicit `loadOptions` is passed through.\n const adapterLoadOptions = useMemo(() => {\n return async (\n query: string,\n opts: { signal: AbortSignal; locale: string },\n ): Promise<OptionShape[]> => {\n if (loadOptions) {\n const result = await loadOptions(query, opts);\n return result.map((o) => ({ value: o.value, label: o.label }));\n }\n const q = normalise(query);\n const filtered = q\n ? derivedOptions.filter((o) => normalise(o.label).includes(q))\n : derivedOptions;\n return filtered\n .slice(0, 50)\n .map((o) => ({ value: o.value, label: o.label }));\n };\n }, [loadOptions, derivedOptions]);\n\n const [draft, setDraft] = useState<string>(model?.value ?? '');\n\n useEffect(() => {\n setDraft(model?.value ?? '');\n }, [model?.value]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n const target = model?.value;\n if (!target) return true;\n const raw = getValue(params.node) as unknown;\n if (raw === null || raw === undefined) return false;\n const value = typeof raw === 'string' ? raw : String(raw);\n return normalise(value) === normalise(target);\n },\n });\n\n function handleSelect(option: OptionShape) {\n // Autocomplete itself commits `option.label` to the input value; we\n // mirror that here so the displayed text matches what the user just\n // picked, even when label and value diverge (e.g. id vs name).\n setDraft(option.label);\n onModelChange({ type: 'equals', value: option.value });\n }\n\n function handleChange(next: string) {\n setDraft(next);\n // Clear the applied model when the user empties the input so the\n // grid stops filtering as soon as the field is blank.\n if (next === '' && model) onModelChange(null);\n }\n\n function clear() {\n setDraft('');\n onModelChange(null);\n }\n\n const placeholderLabel =\n placeholder ?? t('dataTable.typeaheadFilter.placeholder');\n\n return (\n <div\n data-component=\"typeahead-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[240px]\"\n >\n <Autocomplete\n size=\"sm\"\n value={draft}\n onChange={handleChange}\n onSelect={handleSelect}\n loadOptions={adapterLoadOptions}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n <div className=\"ds:flex ds:items-center ds:justify-end ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.typeaheadFilter.clear')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `TypeaheadFilter`.\n *\n * Renders the kit's `<Autocomplete>` directly as the floating-filter\n * input — its built-in text input + portaled dropdown IS the filter\n * UI. Earlier versions wrapped Autocomplete in a second `<Popover>`,\n * producing the \"click trigger → popover with another search input →\n * type → list appears\" double-step that read as duplicated UI.\n */\nexport function TypeaheadFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n TypeaheadFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n const { t } = useTranslation('ui');\n\n const filterParams =\n (column?.getColDef?.()?.filterParams as\n | TypeaheadFilterParams\n | undefined) ?? {};\n const availableOptions = filterParams.options ?? [];\n const loadOptions = filterParams.loadOptions;\n const placeholderLabel =\n filterParams.placeholder ?? t('dataTable.typeaheadFilter.placeholder');\n\n const adapterLoadOptions = useMemo(() => {\n return async (\n query: string,\n opts: { signal: AbortSignal; locale: string },\n ): Promise<OptionShape[]> => {\n if (loadOptions) {\n const result = await loadOptions(query, opts);\n return result.map((o) => ({ value: o.value, label: o.label }));\n }\n const q = normalise(query);\n const filtered = q\n ? availableOptions.filter((o) => normalise(o.label).includes(q))\n : availableOptions;\n return filtered\n .slice(0, 50)\n .map((o) => ({ value: o.value, label: o.label }));\n };\n }, [loadOptions, availableOptions]);\n\n // Track the input's display value separately from the applied model.\n // The user can type freely; we only apply when they pick an option\n // from the dropdown (committing a known value to the model). Clearing\n // the input clears the filter.\n const [draft, setDraft] = useState<string>(model?.value ?? '');\n useEffect(() => {\n setDraft(model?.value ?? '');\n }, [model?.value]);\n\n function handleSelect(option: OptionShape) {\n setDraft(option.label);\n onModelChange({ type: 'equals', value: option.value });\n }\n\n function handleChange(next: string) {\n setDraft(next);\n if (next === '' && model) onModelChange(null);\n }\n\n return (\n <div data-component=\"typeahead-floating-filter\" className=\"ds:w-full\">\n <Autocomplete\n size=\"sm\"\n value={draft}\n onChange={handleChange}\n onSelect={handleSelect}\n loadOptions={adapterLoadOptions}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { NumberInput } from '../../number-input';\nimport { Select } from '../../select';\nimport { Button } from '../../button';\n\n/**\n * Custom AG Grid filter component for numeric columns. AG Grid Community's\n * built-in `agNumberColumnFilter` paints a stock browser-skinned\n * `<input type=\"number\">` that does not match the kit's form language —\n * this wraps the DS `<NumberInput>` + `<Select>` so totals, prices,\n * quantities, etc. line up visually with neighbouring DS-styled cells.\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'total',\n * filter: NumberFilter,\n * floatingFilterComponent: NumberFloatingFilter,\n * filterParams: { defaultOperator: 'greaterThan', min: 0 },\n * }\n * ```\n *\n * The full-popover variant exposes the operator dropdown (equals,\n * greaterThan, inRange, blank, …); the floating-filter row is a single\n * compact input whose operator is fixed to `defaultOperator`. Both speak\n * the same `NumberFilterModel` so server-side adapters can read either.\n *\n * Model shape `{ type, filter, filterTo? }` matches AG Grid's own\n * `agNumberColumnFilter` vocabulary so adapters can interchange.\n */\n\nexport type NumberFilterOperator =\n | 'equals'\n | 'notEqual'\n | 'greaterThan'\n | 'greaterThanOrEqual'\n | 'lessThan'\n | 'lessThanOrEqual'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\nexport interface NumberFilterModel {\n type: NumberFilterOperator;\n filter: number;\n filterTo?: number;\n}\n\nexport interface NumberFilterParams {\n defaultOperator?: NumberFilterOperator;\n min?: number;\n max?: number;\n step?: number;\n placeholder?: string;\n}\n\nconst ALL_OPERATORS: NumberFilterOperator[] = [\n 'equals',\n 'notEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n 'lessThan',\n 'lessThanOrEqual',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\nfunction operatorTakesValue(op: NumberFilterOperator): boolean {\n return op !== 'blank' && op !== 'notBlank';\n}\n\nfunction operatorTakesRange(op: NumberFilterOperator): boolean {\n return op === 'inRange';\n}\n\nfunction evaluate(\n op: NumberFilterOperator,\n cell: number | null,\n primary: number | null,\n secondary: number | null,\n): boolean {\n if (op === 'blank') return cell === null;\n if (op === 'notBlank') return cell !== null;\n if (cell === null) return false;\n if (primary === null) return true;\n switch (op) {\n case 'equals':\n return cell === primary;\n case 'notEqual':\n return cell !== primary;\n case 'greaterThan':\n return cell > primary;\n case 'greaterThanOrEqual':\n return cell >= primary;\n case 'lessThan':\n return cell < primary;\n case 'lessThanOrEqual':\n return cell <= primary;\n case 'inRange': {\n if (secondary === null) return cell >= primary;\n const lo = Math.min(primary, secondary);\n const hi = Math.max(primary, secondary);\n return cell >= lo && cell <= hi;\n }\n default:\n return true;\n }\n}\n\nfunction coerceCell(raw: unknown): number | null {\n if (raw === null || raw === undefined || raw === '') return null;\n const n = typeof raw === 'number' ? raw : Number(raw);\n return Number.isNaN(n) ? null : n;\n}\n\nexport function NumberFilter(\n props: CustomFilterProps<unknown, unknown, NumberFilterModel> &\n NumberFilterParams,\n) {\n const {\n model,\n onModelChange,\n getValue,\n defaultOperator,\n min,\n max,\n step,\n placeholder,\n } = props;\n const { t } = useTranslation('ui');\n\n const initialOperator: NumberFilterOperator =\n model?.type ?? defaultOperator ?? 'equals';\n const [operator, setOperator] =\n useState<NumberFilterOperator>(initialOperator);\n const [primary, setPrimary] = useState<number | null>(model?.filter ?? null);\n const [secondary, setSecondary] = useState<number | null>(\n model?.filterTo ?? null,\n );\n\n // If AG Grid pushes an externally-cleared / reset model, mirror it in\n // local state so the UI stays consistent with the applied filter. The\n // cleared model arrives as null OR undefined (removed from a setFilterModel\n // map), so a loose check is load-bearing here.\n useEffect(() => {\n if (model == null) {\n setOperator(defaultOperator ?? 'equals');\n setPrimary(null);\n setSecondary(null);\n return;\n }\n setOperator(model.type);\n setPrimary(model.filter ?? null);\n setSecondary(model.filterTo ?? null);\n }, [model, defaultOperator]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n if (!model) return true;\n const cell = coerceCell(getValue(params.node));\n return evaluate(\n model.type,\n cell,\n model.filter ?? null,\n model.filterTo ?? null,\n );\n },\n });\n\n const operatorOptions = useMemo(\n () =>\n ALL_OPERATORS.map((op) => ({\n value: op,\n label: t(`dataTable.numberFilter.operators.${op}`),\n })),\n [t],\n );\n\n const placeholderLabel =\n placeholder ?? t('dataTable.numberFilter.placeholder');\n\n function apply() {\n if (!operatorTakesValue(operator)) {\n onModelChange({ type: operator, filter: 0 });\n return;\n }\n if (primary === null) {\n onModelChange(null);\n return;\n }\n if (operatorTakesRange(operator)) {\n onModelChange({\n type: operator,\n filter: primary,\n filterTo: secondary ?? undefined,\n });\n return;\n }\n onModelChange({ type: operator, filter: primary });\n }\n\n function clear() {\n setOperator(defaultOperator ?? 'equals');\n setPrimary(null);\n setSecondary(null);\n onModelChange(null);\n }\n\n const showValue = operatorTakesValue(operator);\n const showRange = operatorTakesRange(operator);\n\n return (\n <div\n data-component=\"number-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[240px]\"\n >\n <Select\n size=\"sm\"\n options={operatorOptions}\n value={operator}\n onValueChange={(next) => {\n if (next === '') return;\n setOperator(next as NumberFilterOperator);\n }}\n aria-label={t('dataTable.numberFilter.operators.equals')}\n />\n {showValue && !showRange && (\n <NumberInput\n size=\"sm\"\n value={primary}\n onChange={setPrimary}\n min={min}\n max={max}\n step={step}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n )}\n {showRange && (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <NumberInput\n size=\"sm\"\n value={primary}\n onChange={setPrimary}\n min={min}\n max={max}\n step={step}\n placeholder={t('dataTable.numberFilter.from')}\n aria-label={t('dataTable.numberFilter.from')}\n />\n <NumberInput\n size=\"sm\"\n value={secondary}\n onChange={setSecondary}\n min={min}\n max={max}\n step={step}\n placeholder={t('dataTable.numberFilter.to')}\n aria-label={t('dataTable.numberFilter.to')}\n />\n </div>\n )}\n <div className=\"ds:flex ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.numberFilter.clear')}\n </Button>\n <Button intent=\"primary\" size=\"sm\" onClick={apply} type=\"button\">\n {t('dataTable.numberFilter.apply')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `NumberFilter`.\n *\n * Renders the kit's `<NumberInput>` directly as the inline filter input\n * with a fixed operator (`defaultOperator`, or `'equals'`). The operator\n * dropdown lives only in the full popover — the floating-filter row is\n * deliberately compact, matching the way `agNumberColumnFilter` ships\n * with AG Grid Community.\n *\n * Debounced commit at 200 ms so each keystroke does not re-run the grid\n * filter. Empty input or invalid number commits `null` so the column\n * reverts to \"no filter\" rather than `filter: NaN`.\n */\nexport function NumberFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n NumberFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n const { t } = useTranslation('ui');\n\n const filterParams =\n (column?.getColDef?.()?.filterParams as NumberFilterParams | undefined) ??\n {};\n const operator: NumberFilterOperator =\n filterParams.defaultOperator ?? 'equals';\n const placeholderLabel =\n filterParams.placeholder ?? t('dataTable.numberFilter.placeholder');\n\n const [draft, setDraft] = useState<number | null>(model?.filter ?? null);\n\n // Sync local draft when the model is reset externally (e.g. a global\n // clear from the column-header menu's \"Clear\" button).\n useEffect(() => {\n setDraft(model?.filter ?? null);\n }, [model?.filter]);\n\n // Debounced commit. We don't pull a hook in for this — a single\n // useEffect + setTimeout is cheaper than the cost of importing one,\n // and AG Grid only re-renders this floating filter per keystroke.\n useEffect(() => {\n if (draft === (model?.filter ?? null)) return;\n const handle = setTimeout(() => {\n if (draft === null || Number.isNaN(draft)) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: operator, filter: draft });\n }, 200);\n return () => clearTimeout(handle);\n // `model` intentionally excluded — we only want to react to user\n // edits of `draft`. Model resets sync via the effect above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, operator]);\n\n return (\n <div data-component=\"number-floating-filter\" className=\"ds:w-full\">\n <NumberInput\n size=\"sm\"\n value={draft}\n onChange={setDraft}\n min={filterParams.min}\n max={filterParams.max}\n step={filterParams.step}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n </div>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Badge } from '../../badge/badge';\n\nexport type BadgeVariant = 'neutral' | 'info' | 'success' | 'warning' | 'error';\n\nexport interface StatusCellRendererParams {\n variantMap?: Record<string, BadgeVariant>;\n}\n\nexport function StatusCellRenderer(\n props: CustomCellRendererProps & StatusCellRendererParams,\n) {\n const { value, variantMap } = props;\n const variant: BadgeVariant = variantMap?.[value as string] ?? 'neutral';\n return (\n <Badge variant={variant} withDot size=\"sm\">\n {String(value ?? '')}\n </Badge>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Avatar } from '../../avatar/avatar';\n\nexport interface UserCellValue {\n name: string;\n src?: string;\n}\n\nexport function UserCellRenderer(\n props: CustomCellRendererProps<unknown, UserCellValue>,\n) {\n const { value } = props;\n if (!value) return null;\n return (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar name={value.name} src={value.src} size=\"sm\" />\n <span>{value.name}</span>\n </span>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Avatar } from '../../avatar/avatar';\n\nexport interface ImageCellRendererParams {\n /** Field name on the row whose value holds the image URL. */\n srcField: string;\n /** Optional field name holding alt text. Falls back to '' (decorative). */\n altField?: string;\n /**\n * Optional field name holding a name string. When the src URL is missing or\n * rejected, the cell falls back to `<Avatar name={fallback}>` so the cell\n * still has a visual.\n */\n fallbackField?: string;\n /** Visual size of the image. Matches `<Avatar>` sizes (sm=32, md=40, lg=48). */\n size?: 'sm' | 'md' | 'lg';\n /** Corner radius preset. `circle` matches `<Avatar>`. */\n shape?: 'square' | 'rounded' | 'circle';\n}\n\nconst SIZE_CLASS: Record<\n NonNullable<ImageCellRendererParams['size']>,\n string\n> = {\n sm: 'ds:size-8',\n md: 'ds:size-10',\n lg: 'ds:size-12',\n};\n\nconst SHAPE_CLASS: Record<\n NonNullable<ImageCellRendererParams['shape']>,\n string\n> = {\n square: 'ds:rounded-none',\n rounded: 'ds:rounded-[var(--radius-md)]',\n circle: 'ds:rounded-[var(--radius-full)]',\n};\n\nfunction readField(row: unknown, field: string): string | undefined {\n if (!row || typeof row !== 'object') return undefined;\n const value = (row as Record<string, unknown>)[field];\n return typeof value === 'string' ? value : undefined;\n}\n\n// Only accept http(s) and data: URLs. Reject `javascript:` / `vbscript:` /\n// any other smuggled scheme. Browsers won't execute non-image data: URLs in\n// `<img>`, but rejecting them in JS gives a single audit point.\nconst SAFE_SRC_RE = /^(?:https?:|data:image\\/)/i;\n\nfunction sanitizeSrc(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return undefined;\n return SAFE_SRC_RE.test(trimmed) ? trimmed : undefined;\n}\n\nexport function ImageCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ImageCellRendererParams,\n) {\n const {\n data,\n srcField,\n altField,\n fallbackField,\n size = 'md',\n shape = 'rounded',\n } = props;\n\n if (!data) return null;\n\n const rawSrc = readField(data, srcField);\n const src = sanitizeSrc(rawSrc);\n const alt = altField ? (readField(data, altField) ?? '') : '';\n const fallbackName = fallbackField\n ? readField(data, fallbackField)\n : undefined;\n\n if (!src) {\n if (fallbackName) {\n return <Avatar name={fallbackName} size={size} />;\n }\n return null;\n }\n\n return (\n <img\n src={src}\n alt={alt}\n loading=\"lazy\"\n decoding=\"async\"\n className={['ds:object-cover', SIZE_CLASS[size], SHAPE_CLASS[shape]].join(\n ' ',\n )}\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { Tag } from '../../tag/tag';\nimport { Tooltip } from '../../tooltip';\n\nexport interface TagListCellRendererParams {\n maxVisible?: number;\n}\n\nexport function TagListCellRenderer(\n props: CustomCellRendererProps<unknown, string[]> & TagListCellRendererParams,\n) {\n const { value, maxVisible = 3 } = props;\n const { t } = useTranslation();\n\n if (!Array.isArray(value) || value.length === 0) return null;\n\n const visible = value.slice(0, maxVisible);\n const overflow = value.length - maxVisible;\n\n return (\n <span className=\"ds:inline-flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {visible.map((tag) => (\n <Tag key={tag} label={tag} size=\"sm\" />\n ))}\n {overflow > 0 && (\n <Tooltip label={value.slice(maxVisible).join(', ')}>\n <Tag\n label={t('inputs.multiSelect.overflow', { count: overflow })}\n size=\"sm\"\n variant=\"neutral\"\n fill=\"outline\"\n />\n </Tooltip>\n )}\n </span>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Timestamp } from '../../timestamp';\n\nexport type DateCellFormat = 'date' | 'time' | 'datetime' | 'relative';\n\nexport interface DateCellRendererParams {\n /** Which preset to use. Default `'date'`. */\n format?: DateCellFormat;\n /** Escape hatch — overrides the preset entirely. */\n options?: Intl.DateTimeFormatOptions;\n}\n\nconst PRESETS: Record<\n Exclude<DateCellFormat, 'relative'>,\n Intl.DateTimeFormatOptions\n> = {\n date: { year: 'numeric', month: 'short', day: 'numeric' },\n time: { hour: '2-digit', minute: '2-digit' },\n datetime: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n },\n};\n\nexport function DateCellRenderer(\n props: CustomCellRendererProps & DateCellRendererParams,\n) {\n const { value, format = 'date', options } = props;\n if (value == null || value === '') return null;\n\n // `shape=\"bare\"` keeps the cell font inherited from --ag-font-size. Timestamp\n // still emits a proper `<time dateTime>` for assistive tech and feeds.\n if (format === 'relative' && !options) {\n return <Timestamp value={value as string | Date} shape=\"bare\" />;\n }\n\n return (\n <Timestamp\n value={value as string | Date}\n format=\"absolute\"\n shape=\"bare\"\n absoluteFormat={\n options ?? PRESETS[format === 'relative' ? 'date' : format]\n }\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface CurrencyCellRendererParams {\n /** ISO 4217 currency code. Default `'EUR'`. */\n currency?: string;\n /** Apply a destructive color token to negative amounts. */\n colorNegative?: boolean;\n /** Render the value with strikethrough — used for written-off balances. */\n strikethrough?: boolean;\n /** `Intl.NumberFormat` escape hatch. Merged on top of currency defaults. */\n options?: Intl.NumberFormatOptions;\n}\n\nfunction toNumber(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function CurrencyCellRenderer(\n props: CustomCellRendererProps & CurrencyCellRendererParams,\n) {\n const {\n value,\n currency = 'EUR',\n colorNegative,\n strikethrough,\n options,\n } = props;\n const { i18n } = useTranslation();\n const n = toNumber(value);\n if (n === null) return null;\n\n const locale = i18n.language || 'en';\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...options,\n }).format(n);\n\n const classNames = ['ds:tabular-nums'];\n if (colorNegative && n < 0)\n classNames.push('ds:text-[color:var(--destructive)]');\n if (strikethrough) classNames.push('line-through');\n\n return <span className={classNames.join(' ')}>{formatted}</span>;\n}\n","import type { MouseEvent } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\n\ntype Getter<T, TData> = T | ((data: TData) => T | undefined);\n\nexport interface LinkCellRendererParams<TData = unknown> {\n /** Anchor href — or a function that derives it from the row. */\n href?: Getter<string, TData>;\n /** Fallback / additional onClick. Prevents default when provided without href. */\n onClick?: (data: TData) => void;\n /** Small text rendered below the link — supports a row-aware function. */\n secondary?: Getter<string, TData>;\n}\n\nfunction resolve<T, TData>(\n source: Getter<T, TData> | undefined,\n data: TData,\n): T | undefined {\n if (typeof source === 'function') {\n return (source as (data: TData) => T | undefined)(data);\n }\n return source;\n}\n\nfunction safeHref(href: string): string {\n return /^(https?:\\/\\/|\\/|#|mailto:|tel:)/i.test(href) ? href : '#';\n}\n\nexport function LinkCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & LinkCellRendererParams<TData>,\n) {\n const { value, data, href, onClick, secondary } = props;\n if (!data) return null;\n\n const resolvedHref = resolve(href, data);\n const resolvedSecondary = resolve(secondary, data);\n const content = value == null || value === '' ? '' : String(value);\n\n const linkClasses = [\n 'ds:text-[color:var(--primary)]',\n 'ds:hover:underline',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:rounded-[var(--radius-sm)]',\n ].join(' ');\n\n const handleClick = (event: MouseEvent) => {\n if (!onClick) return;\n if (!resolvedHref) event.preventDefault();\n event.stopPropagation();\n onClick(data);\n };\n\n return (\n <span className=\"ds:flex ds:flex-col ds:leading-tight\">\n {resolvedHref ? (\n <a\n href={safeHref(resolvedHref)}\n onClick={handleClick}\n className={linkClasses}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={handleClick}\n className={[\n 'ds:appearance-none ds:bg-transparent ds:p-0 ds:text-start',\n linkClasses,\n ].join(' ')}\n >\n {content}\n </button>\n )}\n {resolvedSecondary ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {resolvedSecondary}\n </span>\n ) : null}\n </span>\n );\n}\n"],"names":["toIsoDate","d","fromIsoDate","s","DateRangeFilter","props","model","onModelChange","getValue","doesRowPassOtherFilter","filterParams","_a","range","setRange","useState","useEffect","useGridFilter","params","from","to","cellValue","cellDate","apply","next","jsx","DateRangePicker","DateRangeFloatingFilter","column","_b","toValueKey","v","LABEL_COLLATOR","collectColumnOptions","api","readValue","seen","node","raw","value","key","b","sameOptions","a","opt","i","useSelectFilterOptions","options","explicit","hasExplicit","derived","setDerived","readValueRef","useRef","recompute","prev","SelectFilter","placeholder","t","useTranslation","useCallback","derivedOptions","initialSelected","useMemo","set","incoming","pending","setPending","active","toggle","optionKey","values","clear","placeholderLabel","jsxs","ScrollArea","option","Checkbox","Button","SelectFloatingFilter","colDef","availableOptions","accessibleLabel","valueByKey","map","selectOptions","currentValue","handleChange","k","original","MultiSelect","normalise","TypeaheadFilter","loadOptions","adapterLoadOptions","query","opts","o","q","draft","setDraft","target","handleSelect","Autocomplete","TypeaheadFloatingFilter","ALL_OPERATORS","operatorTakesValue","op","operatorTakesRange","evaluate","cell","primary","secondary","lo","hi","coerceCell","n","NumberFilter","defaultOperator","min","max","step","initialOperator","operator","setOperator","setPrimary","setSecondary","operatorOptions","showValue","showRange","Select","NumberInput","NumberFloatingFilter","handle","StatusCellRenderer","variantMap","variant","Badge","UserCellRenderer","Avatar","SIZE_CLASS","SHAPE_CLASS","readField","row","field","SAFE_SRC_RE","sanitizeSrc","trimmed","ImageCellRenderer","data","srcField","altField","fallbackField","size","shape","rawSrc","src","alt","fallbackName","TagListCellRenderer","maxVisible","visible","overflow","tag","Tag","Tooltip","PRESETS","DateCellRenderer","format","Timestamp","toNumber","CurrencyCellRenderer","currency","colorNegative","strikethrough","i18n","locale","formatted","classNames","resolve","source","safeHref","href","LinkCellRenderer","onClick","resolvedHref","resolvedSecondary","content","linkClasses","handleClick","event"],"mappings":"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"}
1
+ {"version":3,"file":"link-cell-renderer-DH4JYpKU.js","sources":["../../src/components/data-table/filters/date-range-filter.tsx","../../src/components/data-table/filters/select-filter.tsx","../../src/components/data-table/filters/typeahead-filter.tsx","../../src/components/data-table/filters/number-filter.tsx","../../src/components/data-table/cell-renderers/status-cell-renderer.tsx","../../src/components/data-table/cell-renderers/user-cell-renderer.tsx","../../src/components/data-table/cell-renderers/image-cell-renderer.tsx","../../src/components/data-table/cell-renderers/tag-list-cell-renderer.tsx","../../src/components/data-table/cell-renderers/date-cell-renderer.tsx","../../src/components/data-table/cell-renderers/currency-cell-renderer.tsx","../../src/components/data-table/cell-renderers/link-cell-renderer.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter } from 'ag-grid-community';\nimport { DateRangePicker } from '../../date-range-picker';\nimport type { DateRangeValue } from '../../date-range-picker';\n\n/**\n * Custom AG Grid filter component for date *ranges*. AG Grid Community's\n * built-in `agDateColumnFilter` only handles single-date comparison —\n * platform needs \"between X and Y\" for invoice / transaction lists.\n *\n * Wire on a colDef:\n * ```tsx\n * { field: 'date', filter: DateRangeFilter }\n * ```\n *\n * The filter model has shape `{ type: 'inRange', dateFrom, dateTo }` to\n * stay close to AG Grid's own date-filter convention so server-side\n * adapters can interpret it the same way.\n */\nexport interface DateRangeFilterModel {\n type: 'inRange';\n dateFrom: string | null;\n dateTo: string | null;\n}\n\n/**\n * `filterParams` a colDef may pass to `DateRangeFilter` /\n * `DateRangeFloatingFilter`.\n *\n * `commitMode` is forwarded to the wrapped `DateRangePicker`. Leave it unset\n * (picker default `'auto'`, commit-on-complete-range) for cheap client-side row\n * models; set `'apply'` for SERVER-side row models so each range edit defers to\n * one Apply and fires a single datasource round-trip instead of one per commit.\n */\nexport interface DateRangeFilterParams {\n placeholder?: string;\n commitMode?: 'auto' | 'apply';\n}\n\nfunction toIsoDate(d: Date | undefined): string | null {\n if (!d) return null;\n return d.toISOString().slice(0, 10);\n}\n\nfunction fromIsoDate(s: string | null | undefined): Date | undefined {\n if (!s) return undefined;\n const d = new Date(s);\n return Number.isNaN(d.getTime()) ? undefined : d;\n}\n\nexport function DateRangeFilter(\n props: CustomFilterProps<unknown, unknown, DateRangeFilterModel>,\n) {\n const { model, onModelChange, getValue, doesRowPassOtherFilter } = props;\n const filterParams =\n (props.colDef?.filterParams as DateRangeFilterParams | undefined) ?? {};\n // Picker UI state, seeded from the model and kept in sync when the model\n // changes externally — a programmatic default (e.g. \"this week\"), a server\n // restore, or an AG Grid reset. Mirrors `SelectFilter`'s `pending` sync.\n const [range, setRange] = useState<DateRangeValue>(() => ({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n }));\n useEffect(() => {\n setRange({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n });\n }, [model?.dateFrom, model?.dateTo]);\n\n // Tell AG Grid how to evaluate a row against the current model. AG Grid\n // calls this for each row; we read the cell value via `getValue(node)`\n // (a Date or ISO string), compare to the bounds. Bounds come from the\n // MODEL (the source of truth) — not the picker state — so a model set\n // programmatically applies even before the picker UI has mounted, exactly\n // as `SelectFilter` reads `model.values` directly.\n useGridFilter({\n doesFilterPass: (params) => {\n const from = fromIsoDate(model?.dateFrom);\n const to = fromIsoDate(model?.dateTo);\n if (!from && !to) return true;\n const cellValue = getValue(params.node) as\n | Date\n | string\n | null\n | undefined;\n if (!cellValue) return false;\n const cellDate =\n cellValue instanceof Date ? cellValue : fromIsoDate(String(cellValue));\n if (!cellDate) return false;\n if (from && cellDate < from) return false;\n if (to && cellDate > to) return false;\n // Respect other filters via the supplied callback if AG Grid uses\n // it (some grid setups call `doesRowPassOtherFilter` before us).\n void doesRowPassOtherFilter;\n return true;\n },\n });\n\n function apply(next: DateRangeValue) {\n setRange(next);\n if (!next.from && !next.to) {\n onModelChange(null);\n return;\n }\n onModelChange({\n type: 'inRange',\n dateFrom: toIsoDate(next.from),\n dateTo: toIsoDate(next.to),\n } satisfies DateRangeFilterModel);\n }\n\n return (\n <div\n data-component=\"date-range-filter\"\n className=\"ds:p-[var(--spacing-sm)] ds:min-w-[280px]\"\n >\n <DateRangePicker\n value={range}\n onChange={apply}\n commitMode={filterParams.commitMode}\n size=\"sm\"\n />\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `DateRangeFilter`.\n *\n * Renders the kit's `<DateRangePicker>` directly as the floating-filter\n * input — its built-in trigger button + calendar popover IS the filter\n * UI. Earlier versions wrapped the picker in a second `<Popover>`,\n * producing the \"click → empty popover with another trigger → click\n * again → calendar\" double-step that read as duplicated UI.\n */\nexport function DateRangeFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n DateRangeFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n // Let a colDef supply a short `filterParams.placeholder` for the in-row\n // trigger — the default \"Select date range\" is long for a narrow filter\n // column. (The label truncates cleanly either way; a short placeholder just\n // reads better.)\n const filterParams =\n (column?.getColDef?.()?.filterParams as\n | DateRangeFilterParams\n | undefined) ?? {};\n const [range, setRange] = useState<DateRangeValue>(() => ({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n }));\n // Reflect external model changes (a programmatic default, a parent-filter\n // edit, an AG Grid reset) in the in-row picker trigger.\n useEffect(() => {\n setRange({\n from: fromIsoDate(model?.dateFrom),\n to: fromIsoDate(model?.dateTo),\n });\n }, [model?.dateFrom, model?.dateTo]);\n\n function apply(next: DateRangeValue) {\n setRange(next);\n if (!next.from && !next.to) {\n onModelChange(null);\n return;\n }\n onModelChange({\n type: 'inRange',\n dateFrom: toIsoDate(next.from),\n dateTo: toIsoDate(next.to),\n } satisfies DateRangeFilterModel);\n }\n\n return (\n <div data-component=\"date-range-floating-filter\" className=\"ds:w-full\">\n <DateRangePicker\n value={range}\n onChange={apply}\n commitMode={filterParams.commitMode}\n size=\"sm\"\n placeholder={filterParams.placeholder}\n />\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { GridApi, IFilter, IRowNode } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { Checkbox } from '../../checkbox';\nimport { Button } from '../../button';\nimport { MultiSelect } from '../../multi-select';\nimport { ScrollArea } from '../../scroll-area/scroll-area';\n\n/**\n * Custom AG Grid filter component — multi-select facet filter.\n *\n * The Community-friendly equivalent of AG Grid Enterprise's\n * `agSetColumnFilter`. Surfaces a checkbox list of every value the column\n * can take, so users tick to include / untick to exclude. Much faster than\n * the default `agTextColumnFilter` for closed enums (status, room,\n * operator).\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'status',\n * filter: SelectFilter,\n * filterParams: {\n * options: [\n * { value: 'open', label: 'Aperte' },\n * { value: 'paid', label: 'Pagate' },\n * ],\n * },\n * }\n * ```\n *\n * Model shape `{ type: 'set', values: Array<string | number> }` matches\n * AG Grid Enterprise's set-filter convention so server-side adapters can\n * read either implementation the same way.\n */\n\nexport interface SelectFilterOption {\n value: string | number;\n label: string;\n}\n\nexport interface SelectFilterModel {\n type: 'set';\n values: Array<string | number>;\n}\n\nexport interface SelectFilterParams {\n options?: SelectFilterOption[];\n placeholder?: string;\n}\n\ntype SelectFilterValue = string | number;\n\nfunction toValueKey(v: SelectFilterValue): string {\n return typeof v === 'number' ? `n:${v}` : `s:${v}`;\n}\n\n/** How a filter surface reads one row's value for its column. */\ntype SelectValueReader = (node: IRowNode) => unknown;\n\n/** Numeric collation, so a derived numeric column lists 1, 2, 3, 10 rather\n * than the lexicographic 1, 10, 2, 3. */\nconst LABEL_COLLATOR = new Intl.Collator(undefined, { numeric: true });\n\n/** Distinct values the column actually holds, label-sorted. `forEachNode`\n * walks the whole client-side row model, so the list does not shrink as\n * other columns filter rows out. */\nfunction collectColumnOptions(\n api: GridApi | undefined,\n readValue: SelectValueReader,\n): SelectFilterOption[] {\n if (!api) return [];\n const seen = new Map<string, SelectFilterOption>();\n api.forEachNode((node: IRowNode) => {\n const raw = readValue(node);\n if (raw === null || raw === undefined) return;\n const value =\n typeof raw === 'string' || typeof raw === 'number' ? raw : String(raw);\n const key = toValueKey(value);\n if (!seen.has(key)) seen.set(key, { value, label: String(value) });\n });\n return Array.from(seen.values()).sort((a, b) =>\n LABEL_COLLATOR.compare(String(a.label), String(b.label)),\n );\n}\n\nfunction sameOptions(\n a: SelectFilterOption[],\n b: SelectFilterOption[],\n): boolean {\n if (a.length !== b.length) return false;\n return a.every(\n (opt, i) =>\n toValueKey(opt.value) === toValueKey(b[i].value) &&\n opt.label === b[i].label,\n );\n}\n\n/**\n * The universe of choices for one Select-filtered column.\n *\n * An explicit `options` filterParam always wins — INCLUDING an empty one,\n * which means \"this column has no facets\", not \"derive them for me\". Omit\n * `options` entirely and the list is DERIVED from the values the column\n * actually holds, and re-derived as the row data changes, so both the popup\n * panel and its floating-filter twin offer the same, data-accurate choices.\n */\nfunction useSelectFilterOptions(\n api: GridApi | undefined,\n options: SelectFilterOption[] | undefined,\n readValue: SelectValueReader,\n): SelectFilterOption[] {\n const explicit = options;\n const hasExplicit = explicit !== undefined;\n const [derived, setDerived] = useState<SelectFilterOption[]>([]);\n\n // Latest-reader ref so a new `getValue` identity per grid render does not\n // tear down and rebuild the grid event subscription below.\n const readValueRef = useRef(readValue);\n useEffect(() => {\n readValueRef.current = readValue;\n });\n\n useEffect(() => {\n if (hasExplicit || !api) return;\n const recompute = () => {\n setDerived((prev) => {\n const next = collectColumnOptions(api, readValueRef.current);\n return sameOptions(prev, next) ? prev : next;\n });\n };\n recompute();\n api.addEventListener('modelUpdated', recompute);\n api.addEventListener('cellValueChanged', recompute);\n return () => {\n if (api.isDestroyed()) return;\n api.removeEventListener('modelUpdated', recompute);\n api.removeEventListener('cellValueChanged', recompute);\n };\n }, [api, hasExplicit]);\n\n return explicit ?? derived;\n}\n\nexport function SelectFilter(\n props: CustomFilterProps<unknown, unknown, SelectFilterModel> &\n SelectFilterParams,\n) {\n const { model, onModelChange, getValue, api, options, placeholder } = props;\n const { t } = useTranslation('ui');\n\n const readValue = useCallback<SelectValueReader>(\n (node) => getValue(node) as unknown,\n [getValue],\n );\n const derivedOptions = useSelectFilterOptions(api, options, readValue);\n\n // Working set — checkboxes mutate `pending` only; we commit to the\n // grid via `onModelChange` when the user clicks Apply (or clears).\n const initialSelected = useMemo<Set<string>>(() => {\n const set = new Set<string>();\n const incoming = model?.values ?? [];\n for (const v of incoming) set.add(toValueKey(v));\n return set;\n }, [model]);\n\n const [pending, setPending] = useState<Set<string>>(initialSelected);\n\n // Sync local `pending` if the model changes externally (e.g. when AG\n // Grid pushes a reset). `model` is the dependency — Set instances are\n // compared by reference in React, so the memo above is sufficient.\n useEffect(() => {\n setPending(initialSelected);\n }, [initialSelected]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n const active = model?.values;\n if (!active || active.length === 0) return true;\n const raw = getValue(params.node) as unknown;\n if (raw === null || raw === undefined) return false;\n const value: SelectFilterValue =\n typeof raw === 'string' || typeof raw === 'number' ? raw : String(raw);\n const key = toValueKey(value);\n return active.some((v) => toValueKey(v) === key);\n },\n });\n\n function toggle(optionKey: string) {\n setPending((prev) => {\n const next = new Set(prev);\n if (next.has(optionKey)) next.delete(optionKey);\n else next.add(optionKey);\n return next;\n });\n }\n\n function apply() {\n if (pending.size === 0) {\n onModelChange(null);\n return;\n }\n const values: SelectFilterValue[] = [];\n for (const opt of derivedOptions) {\n if (pending.has(toValueKey(opt.value))) values.push(opt.value);\n }\n // A ticked value can leave the data before Apply (the derived list is\n // live). Committing `values: []` would read as an active filter that\n // matches every row, so clear instead.\n if (values.length === 0) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: 'set', values });\n }\n\n function clear() {\n setPending(new Set());\n onModelChange(null);\n }\n\n const placeholderLabel = placeholder ?? t('dataTable.selectFilter.all');\n\n return (\n <div\n data-component=\"select-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[200px] ds:max-w-[260px]\"\n >\n <ScrollArea orientation=\"vertical\" className=\"ds:max-h-[240px]\">\n <div\n role=\"group\"\n aria-label={placeholderLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n {derivedOptions.length === 0 ? (\n <p className=\"ds:text-[length:var(--font-size-sm)] ds:text-[var(--muted-foreground)] ds:py-[var(--spacing-xs)]\">\n {t('dataTable.agGrid.noRowsToShow')}\n </p>\n ) : (\n derivedOptions.map((option) => {\n const key = toValueKey(option.value);\n return (\n <Checkbox\n key={key}\n size=\"sm\"\n label={option.label}\n checked={pending.has(key)}\n onCheckedChange={() => toggle(key)}\n />\n );\n })\n )}\n </div>\n </ScrollArea>\n <div className=\"ds:flex ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.selectFilter.clear')}\n </Button>\n <Button intent=\"primary\" size=\"sm\" onClick={apply} type=\"button\">\n {t('dataTable.selectFilter.apply')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `SelectFilter`.\n *\n * Renders the kit's `<MultiSelect>` directly as the floating-filter\n * input — its built-in trigger + checkbox dropdown IS the filter UI.\n * Earlier versions wrapped MultiSelect in another `<Popover>`,\n * producing the \"click trigger → empty popover with another trigger →\n * click → checkbox list\" double-step that read as duplicated UI.\n *\n * MultiSelect's options use `string` values; we string-convert the\n * model's `(string | number)[]` for the trigger and parse back on\n * apply. The grid model still tracks the original primitive types so\n * `doesFilterPass` keeps matching numeric columns correctly.\n *\n * Choices come from the same `useSelectFilterOptions` universe the popup\n * panel uses: an explicit `options` filterParam if the consumer declared\n * one, otherwise the column's own distinct values. Reading only\n * `filterParams.options` used to leave the trigger empty beside a working\n * panel whenever the consumer relied on derivation.\n */\nexport function SelectFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n SelectFilterModel\n >,\n) {\n const { model, onModelChange, column, api } = props;\n\n const colDef = column?.getColDef?.();\n const filterParams =\n (colDef?.filterParams as SelectFilterParams | undefined) ?? {};\n\n // The floating filter has no `getValue`; read through the grid instead.\n // A column with a `filterValueGetter` should declare `options` — the two\n // reads would otherwise disagree with the panel's.\n const readValue = useCallback<SelectValueReader>(\n (node) =>\n api && column\n ? (api.getCellValue<unknown>({\n rowNode: node,\n colKey: column,\n }) as unknown)\n : undefined,\n [api, column],\n );\n const availableOptions = useSelectFilterOptions(\n api,\n filterParams.options,\n readValue,\n );\n // Name the floating-filter trigger after its column so the per-column Select\n // filters are distinguishable to assistive tech — they otherwise all read as\n // the generic MultiSelect placeholder. An explicit `placeholder` wins.\n const accessibleLabel =\n filterParams.placeholder ??\n (typeof colDef?.headerName === 'string' ? colDef.headerName : undefined);\n\n // MultiSelect's `value` is `string[]`. SelectFilter's model carries\n // `(string | number)[]` so we string-convert in / out. Build a lookup\n // from the stringified key back to the original primitive so the\n // model retains the consumer's typing.\n const valueByKey = useMemo(() => {\n const map = new Map<string, SelectFilterValue>();\n for (const opt of availableOptions) map.set(String(opt.value), opt.value);\n return map;\n }, [availableOptions]);\n\n const selectOptions = useMemo(\n () =>\n availableOptions.map((opt) => ({\n value: String(opt.value),\n label: opt.label,\n })),\n [availableOptions],\n );\n\n const currentValue = useMemo(\n () => (model?.values ?? []).map((v) => String(v)),\n [model],\n );\n\n function handleChange(next: string[]) {\n if (next.length === 0) {\n onModelChange(null);\n return;\n }\n const values: SelectFilterValue[] = [];\n for (const k of next) {\n const original = valueByKey.get(k);\n if (original !== undefined) values.push(original);\n }\n // Same live-list guard as the panel's Apply: an empty set is a cleared\n // filter, never an active one that matches everything.\n if (values.length === 0) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: 'set', values });\n }\n\n return (\n <div data-component=\"select-floating-filter\" className=\"ds:w-full\">\n <MultiSelect\n size=\"sm\"\n options={selectOptions}\n value={currentValue}\n onChange={handleChange}\n placeholder={filterParams.placeholder}\n aria-label={accessibleLabel}\n allowClear\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter, IRowNode } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { Autocomplete } from '../../autocomplete';\nimport { Button } from '../../button';\nimport type { OptionShape } from '../../_shared/option';\n\n/**\n * Custom AG Grid filter component — single-select typeahead filter.\n *\n * Wraps the kit's existing `<Autocomplete>` so the user types to filter a\n * bounded-but-large set of values (e.g. patient names), picks one\n * suggestion, and the grid filters to rows matching that value exactly.\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'patient',\n * filter: TypeaheadFilter,\n * filterParams: {\n * options: PATIENTS.map(p => ({ value: p.name, label: p.name })),\n * },\n * }\n * ```\n *\n * Model shape `{ type: 'equals', value: string }` matches AG Grid's\n * text-filter `equals` convention so server-side adapters can read either\n * implementation the same way.\n */\n\nexport interface TypeaheadFilterOption {\n value: string;\n label: string;\n}\n\nexport interface TypeaheadFilterModel {\n type: 'equals';\n value: string;\n}\n\nexport interface TypeaheadFilterParams {\n options?: TypeaheadFilterOption[];\n loadOptions?: (\n input: string,\n opts: { signal: AbortSignal; locale: string },\n ) => Promise<TypeaheadFilterOption[]>;\n placeholder?: string;\n}\n\nfunction normalise(s: string): string {\n return s.trim().toLocaleLowerCase();\n}\n\nexport function TypeaheadFilter(\n props: CustomFilterProps<unknown, unknown, TypeaheadFilterModel> &\n TypeaheadFilterParams,\n) {\n const {\n model,\n onModelChange,\n getValue,\n api,\n column,\n options,\n loadOptions,\n placeholder,\n } = props;\n const { t } = useTranslation('ui');\n\n // Universe of choices. Prefer explicit `options`; fall back to the\n // column's distinct values when neither `options` nor `loadOptions` is\n // supplied. Same shape as SelectFilter's derivation so the two filters\n // present a consistent experience when consumers don't enumerate.\n const derivedOptions = useMemo<TypeaheadFilterOption[]>(() => {\n if (options && options.length > 0) return options;\n if (!api || !column) return [];\n const seen = new Map<string, TypeaheadFilterOption>();\n api.forEachNode((node: IRowNode) => {\n const raw = getValue(node) as unknown;\n if (raw === null || raw === undefined) return;\n const value = typeof raw === 'string' ? raw : String(raw);\n if (!seen.has(value)) {\n seen.set(value, { value, label: value });\n }\n });\n return Array.from(seen.values()).sort((a, b) =>\n a.label.localeCompare(b.label),\n );\n }, [options, api, column, getValue]);\n\n // Build the async `loadOptions` adapter that <Autocomplete> consumes.\n // Local-options path filters the snapshot synchronously and wraps it\n // in Promise.resolve(); explicit `loadOptions` is passed through.\n const adapterLoadOptions = useMemo(() => {\n return async (\n query: string,\n opts: { signal: AbortSignal; locale: string },\n ): Promise<OptionShape[]> => {\n if (loadOptions) {\n const result = await loadOptions(query, opts);\n return result.map((o) => ({ value: o.value, label: o.label }));\n }\n const q = normalise(query);\n const filtered = q\n ? derivedOptions.filter((o) => normalise(o.label).includes(q))\n : derivedOptions;\n return filtered\n .slice(0, 50)\n .map((o) => ({ value: o.value, label: o.label }));\n };\n }, [loadOptions, derivedOptions]);\n\n const [draft, setDraft] = useState<string>(model?.value ?? '');\n\n useEffect(() => {\n setDraft(model?.value ?? '');\n }, [model?.value]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n const target = model?.value;\n if (!target) return true;\n const raw = getValue(params.node) as unknown;\n if (raw === null || raw === undefined) return false;\n const value = typeof raw === 'string' ? raw : String(raw);\n return normalise(value) === normalise(target);\n },\n });\n\n function handleSelect(option: OptionShape) {\n // Autocomplete itself commits `option.label` to the input value; we\n // mirror that here so the displayed text matches what the user just\n // picked, even when label and value diverge (e.g. id vs name).\n setDraft(option.label);\n onModelChange({ type: 'equals', value: option.value });\n }\n\n function handleChange(next: string) {\n setDraft(next);\n // Clear the applied model when the user empties the input so the\n // grid stops filtering as soon as the field is blank.\n if (next === '' && model) onModelChange(null);\n }\n\n function clear() {\n setDraft('');\n onModelChange(null);\n }\n\n const placeholderLabel =\n placeholder ?? t('dataTable.typeaheadFilter.placeholder');\n\n return (\n <div\n data-component=\"typeahead-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[240px]\"\n >\n <Autocomplete\n size=\"sm\"\n value={draft}\n onChange={handleChange}\n onSelect={handleSelect}\n loadOptions={adapterLoadOptions}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n <div className=\"ds:flex ds:items-center ds:justify-end ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.typeaheadFilter.clear')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `TypeaheadFilter`.\n *\n * Renders the kit's `<Autocomplete>` directly as the floating-filter\n * input — its built-in text input + portaled dropdown IS the filter\n * UI. Earlier versions wrapped Autocomplete in a second `<Popover>`,\n * producing the \"click trigger → popover with another search input →\n * type → list appears\" double-step that read as duplicated UI.\n */\nexport function TypeaheadFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n TypeaheadFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n const { t } = useTranslation('ui');\n\n const filterParams =\n (column?.getColDef?.()?.filterParams as\n | TypeaheadFilterParams\n | undefined) ?? {};\n const availableOptions = filterParams.options ?? [];\n const loadOptions = filterParams.loadOptions;\n const placeholderLabel =\n filterParams.placeholder ?? t('dataTable.typeaheadFilter.placeholder');\n\n const adapterLoadOptions = useMemo(() => {\n return async (\n query: string,\n opts: { signal: AbortSignal; locale: string },\n ): Promise<OptionShape[]> => {\n if (loadOptions) {\n const result = await loadOptions(query, opts);\n return result.map((o) => ({ value: o.value, label: o.label }));\n }\n const q = normalise(query);\n const filtered = q\n ? availableOptions.filter((o) => normalise(o.label).includes(q))\n : availableOptions;\n return filtered\n .slice(0, 50)\n .map((o) => ({ value: o.value, label: o.label }));\n };\n }, [loadOptions, availableOptions]);\n\n // Track the input's display value separately from the applied model.\n // The user can type freely; we only apply when they pick an option\n // from the dropdown (committing a known value to the model). Clearing\n // the input clears the filter.\n const [draft, setDraft] = useState<string>(model?.value ?? '');\n useEffect(() => {\n setDraft(model?.value ?? '');\n }, [model?.value]);\n\n function handleSelect(option: OptionShape) {\n setDraft(option.label);\n onModelChange({ type: 'equals', value: option.value });\n }\n\n function handleChange(next: string) {\n setDraft(next);\n if (next === '' && model) onModelChange(null);\n }\n\n return (\n <div data-component=\"typeahead-floating-filter\" className=\"ds:w-full\">\n <Autocomplete\n size=\"sm\"\n value={draft}\n onChange={handleChange}\n onSelect={handleSelect}\n loadOptions={adapterLoadOptions}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport type {\n CustomFilterProps,\n CustomFloatingFilterProps,\n} from 'ag-grid-react';\nimport { useGridFilter } from 'ag-grid-react';\nimport type { IFilter } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { NumberInput } from '../../number-input';\nimport { Select } from '../../select';\nimport { Button } from '../../button';\n\n/**\n * Custom AG Grid filter component for numeric columns. AG Grid Community's\n * built-in `agNumberColumnFilter` paints a stock browser-skinned\n * `<input type=\"number\">` that does not match the kit's form language —\n * this wraps the DS `<NumberInput>` + `<Select>` so totals, prices,\n * quantities, etc. line up visually with neighbouring DS-styled cells.\n *\n * Wire on a colDef:\n * ```tsx\n * {\n * field: 'total',\n * filter: NumberFilter,\n * floatingFilterComponent: NumberFloatingFilter,\n * filterParams: { defaultOperator: 'greaterThan', min: 0 },\n * }\n * ```\n *\n * The full-popover variant exposes the operator dropdown (equals,\n * greaterThan, inRange, blank, …); the floating-filter row is a single\n * compact input whose operator is fixed to `defaultOperator`. Both speak\n * the same `NumberFilterModel` so server-side adapters can read either.\n *\n * Model shape `{ type, filter, filterTo? }` matches AG Grid's own\n * `agNumberColumnFilter` vocabulary so adapters can interchange.\n */\n\nexport type NumberFilterOperator =\n | 'equals'\n | 'notEqual'\n | 'greaterThan'\n | 'greaterThanOrEqual'\n | 'lessThan'\n | 'lessThanOrEqual'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\nexport interface NumberFilterModel {\n type: NumberFilterOperator;\n filter: number;\n filterTo?: number;\n}\n\nexport interface NumberFilterParams {\n defaultOperator?: NumberFilterOperator;\n min?: number;\n max?: number;\n step?: number;\n placeholder?: string;\n}\n\nconst ALL_OPERATORS: NumberFilterOperator[] = [\n 'equals',\n 'notEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n 'lessThan',\n 'lessThanOrEqual',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\nfunction operatorTakesValue(op: NumberFilterOperator): boolean {\n return op !== 'blank' && op !== 'notBlank';\n}\n\nfunction operatorTakesRange(op: NumberFilterOperator): boolean {\n return op === 'inRange';\n}\n\nfunction evaluate(\n op: NumberFilterOperator,\n cell: number | null,\n primary: number | null,\n secondary: number | null,\n): boolean {\n if (op === 'blank') return cell === null;\n if (op === 'notBlank') return cell !== null;\n if (cell === null) return false;\n if (primary === null) return true;\n switch (op) {\n case 'equals':\n return cell === primary;\n case 'notEqual':\n return cell !== primary;\n case 'greaterThan':\n return cell > primary;\n case 'greaterThanOrEqual':\n return cell >= primary;\n case 'lessThan':\n return cell < primary;\n case 'lessThanOrEqual':\n return cell <= primary;\n case 'inRange': {\n if (secondary === null) return cell >= primary;\n const lo = Math.min(primary, secondary);\n const hi = Math.max(primary, secondary);\n return cell >= lo && cell <= hi;\n }\n default:\n return true;\n }\n}\n\nfunction coerceCell(raw: unknown): number | null {\n if (raw === null || raw === undefined || raw === '') return null;\n const n = typeof raw === 'number' ? raw : Number(raw);\n return Number.isNaN(n) ? null : n;\n}\n\nexport function NumberFilter(\n props: CustomFilterProps<unknown, unknown, NumberFilterModel> &\n NumberFilterParams,\n) {\n const {\n model,\n onModelChange,\n getValue,\n defaultOperator,\n min,\n max,\n step,\n placeholder,\n } = props;\n const { t } = useTranslation('ui');\n\n const initialOperator: NumberFilterOperator =\n model?.type ?? defaultOperator ?? 'equals';\n const [operator, setOperator] =\n useState<NumberFilterOperator>(initialOperator);\n const [primary, setPrimary] = useState<number | null>(model?.filter ?? null);\n const [secondary, setSecondary] = useState<number | null>(\n model?.filterTo ?? null,\n );\n\n // If AG Grid pushes an externally-cleared / reset model, mirror it in\n // local state so the UI stays consistent with the applied filter. The\n // cleared model arrives as null OR undefined (removed from a setFilterModel\n // map), so a loose check is load-bearing here.\n useEffect(() => {\n if (model == null) {\n setOperator(defaultOperator ?? 'equals');\n setPrimary(null);\n setSecondary(null);\n return;\n }\n setOperator(model.type);\n setPrimary(model.filter ?? null);\n setSecondary(model.filterTo ?? null);\n }, [model, defaultOperator]);\n\n useGridFilter({\n doesFilterPass: (params) => {\n if (!model) return true;\n const cell = coerceCell(getValue(params.node));\n return evaluate(\n model.type,\n cell,\n model.filter ?? null,\n model.filterTo ?? null,\n );\n },\n });\n\n const operatorOptions = useMemo(\n () =>\n ALL_OPERATORS.map((op) => ({\n value: op,\n label: t(`dataTable.numberFilter.operators.${op}`),\n })),\n [t],\n );\n\n const placeholderLabel =\n placeholder ?? t('dataTable.numberFilter.placeholder');\n\n function apply() {\n if (!operatorTakesValue(operator)) {\n onModelChange({ type: operator, filter: 0 });\n return;\n }\n if (primary === null) {\n onModelChange(null);\n return;\n }\n if (operatorTakesRange(operator)) {\n onModelChange({\n type: operator,\n filter: primary,\n filterTo: secondary ?? undefined,\n });\n return;\n }\n onModelChange({ type: operator, filter: primary });\n }\n\n function clear() {\n setOperator(defaultOperator ?? 'equals');\n setPrimary(null);\n setSecondary(null);\n onModelChange(null);\n }\n\n const showValue = operatorTakesValue(operator);\n const showRange = operatorTakesRange(operator);\n\n return (\n <div\n data-component=\"number-filter\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)] ds:min-w-[240px]\"\n >\n <Select\n size=\"sm\"\n options={operatorOptions}\n value={operator}\n onValueChange={(next) => {\n if (next === '') return;\n setOperator(next as NumberFilterOperator);\n }}\n aria-label={t('dataTable.numberFilter.operators.equals')}\n />\n {showValue && !showRange && (\n <NumberInput\n size=\"sm\"\n value={primary}\n onChange={setPrimary}\n min={min}\n max={max}\n step={step}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n )}\n {showRange && (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <NumberInput\n size=\"sm\"\n value={primary}\n onChange={setPrimary}\n min={min}\n max={max}\n step={step}\n placeholder={t('dataTable.numberFilter.from')}\n aria-label={t('dataTable.numberFilter.from')}\n />\n <NumberInput\n size=\"sm\"\n value={secondary}\n onChange={setSecondary}\n min={min}\n max={max}\n step={step}\n placeholder={t('dataTable.numberFilter.to')}\n aria-label={t('dataTable.numberFilter.to')}\n />\n </div>\n )}\n <div className=\"ds:flex ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)] ds:border-t ds:border-[var(--border)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={clear} type=\"button\">\n {t('dataTable.numberFilter.clear')}\n </Button>\n <Button intent=\"primary\" size=\"sm\" onClick={apply} type=\"button\">\n {t('dataTable.numberFilter.apply')}\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Floating-filter companion for `NumberFilter`.\n *\n * Renders the kit's `<NumberInput>` directly as the inline filter input\n * with a fixed operator (`defaultOperator`, or `'equals'`). The operator\n * dropdown lives only in the full popover — the floating-filter row is\n * deliberately compact, matching the way `agNumberColumnFilter` ships\n * with AG Grid Community.\n *\n * Debounced commit at 200 ms so each keystroke does not re-run the grid\n * filter. Empty input or invalid number commits `null` so the column\n * reverts to \"no filter\" rather than `filter: NaN`.\n */\nexport function NumberFloatingFilter(\n props: CustomFloatingFilterProps<\n IFilter,\n unknown,\n unknown,\n NumberFilterModel\n >,\n) {\n const { model, onModelChange, column } = props;\n const { t } = useTranslation('ui');\n\n const filterParams =\n (column?.getColDef?.()?.filterParams as NumberFilterParams | undefined) ??\n {};\n const operator: NumberFilterOperator =\n filterParams.defaultOperator ?? 'equals';\n const placeholderLabel =\n filterParams.placeholder ?? t('dataTable.numberFilter.placeholder');\n\n const [draft, setDraft] = useState<number | null>(model?.filter ?? null);\n\n // Sync local draft when the model is reset externally (e.g. a global\n // clear from the column-header menu's \"Clear\" button).\n useEffect(() => {\n setDraft(model?.filter ?? null);\n }, [model?.filter]);\n\n // Debounced commit. We don't pull a hook in for this — a single\n // useEffect + setTimeout is cheaper than the cost of importing one,\n // and AG Grid only re-renders this floating filter per keystroke.\n useEffect(() => {\n if (draft === (model?.filter ?? null)) return;\n const handle = setTimeout(() => {\n if (draft === null || Number.isNaN(draft)) {\n onModelChange(null);\n return;\n }\n onModelChange({ type: operator, filter: draft });\n }, 200);\n return () => clearTimeout(handle);\n // `model` intentionally excluded — we only want to react to user\n // edits of `draft`. Model resets sync via the effect above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, operator]);\n\n return (\n <div data-component=\"number-floating-filter\" className=\"ds:w-full\">\n <NumberInput\n size=\"sm\"\n value={draft}\n onChange={setDraft}\n min={filterParams.min}\n max={filterParams.max}\n step={filterParams.step}\n placeholder={placeholderLabel}\n aria-label={placeholderLabel}\n />\n </div>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Badge } from '../../badge/badge';\n\nexport type BadgeVariant = 'neutral' | 'info' | 'success' | 'warning' | 'error';\n\nexport interface StatusCellRendererParams {\n variantMap?: Record<string, BadgeVariant>;\n}\n\nexport function StatusCellRenderer(\n props: CustomCellRendererProps & StatusCellRendererParams,\n) {\n const { value, variantMap } = props;\n const variant: BadgeVariant = variantMap?.[value as string] ?? 'neutral';\n return (\n <Badge variant={variant} withDot size=\"sm\">\n {String(value ?? '')}\n </Badge>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Avatar } from '../../avatar/avatar';\n\nexport interface UserCellValue {\n name: string;\n src?: string;\n}\n\nexport function UserCellRenderer(\n props: CustomCellRendererProps<unknown, UserCellValue>,\n) {\n const { value } = props;\n if (!value) return null;\n return (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar name={value.name} src={value.src} size=\"sm\" />\n <span>{value.name}</span>\n </span>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Avatar } from '../../avatar/avatar';\n\nexport interface ImageCellRendererParams {\n /** Field name on the row whose value holds the image URL. */\n srcField: string;\n /** Optional field name holding alt text. Falls back to '' (decorative). */\n altField?: string;\n /**\n * Optional field name holding a name string. When the src URL is missing or\n * rejected, the cell falls back to `<Avatar name={fallback}>` so the cell\n * still has a visual.\n */\n fallbackField?: string;\n /** Visual size of the image. Matches `<Avatar>` sizes (sm=32, md=40, lg=48). */\n size?: 'sm' | 'md' | 'lg';\n /** Corner radius preset. `circle` matches `<Avatar>`. */\n shape?: 'square' | 'rounded' | 'circle';\n}\n\nconst SIZE_CLASS: Record<\n NonNullable<ImageCellRendererParams['size']>,\n string\n> = {\n sm: 'ds:size-8',\n md: 'ds:size-10',\n lg: 'ds:size-12',\n};\n\nconst SHAPE_CLASS: Record<\n NonNullable<ImageCellRendererParams['shape']>,\n string\n> = {\n square: 'ds:rounded-none',\n rounded: 'ds:rounded-[var(--radius-md)]',\n circle: 'ds:rounded-[var(--radius-full)]',\n};\n\nfunction readField(row: unknown, field: string): string | undefined {\n if (!row || typeof row !== 'object') return undefined;\n const value = (row as Record<string, unknown>)[field];\n return typeof value === 'string' ? value : undefined;\n}\n\n// Only accept http(s) and data: URLs. Reject `javascript:` / `vbscript:` /\n// any other smuggled scheme. Browsers won't execute non-image data: URLs in\n// `<img>`, but rejecting them in JS gives a single audit point.\nconst SAFE_SRC_RE = /^(?:https?:|data:image\\/)/i;\n\nfunction sanitizeSrc(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return undefined;\n return SAFE_SRC_RE.test(trimmed) ? trimmed : undefined;\n}\n\nexport function ImageCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ImageCellRendererParams,\n) {\n const {\n data,\n srcField,\n altField,\n fallbackField,\n size = 'md',\n shape = 'rounded',\n } = props;\n\n if (!data) return null;\n\n const rawSrc = readField(data, srcField);\n const src = sanitizeSrc(rawSrc);\n const alt = altField ? (readField(data, altField) ?? '') : '';\n const fallbackName = fallbackField\n ? readField(data, fallbackField)\n : undefined;\n\n if (!src) {\n if (fallbackName) {\n return <Avatar name={fallbackName} size={size} />;\n }\n return null;\n }\n\n return (\n <img\n src={src}\n alt={alt}\n loading=\"lazy\"\n decoding=\"async\"\n className={['ds:object-cover', SIZE_CLASS[size], SHAPE_CLASS[shape]].join(\n ' ',\n )}\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { Tag } from '../../tag/tag';\nimport { Tooltip } from '../../tooltip';\n\nexport interface TagListCellRendererParams {\n maxVisible?: number;\n}\n\nexport function TagListCellRenderer(\n props: CustomCellRendererProps<unknown, string[]> & TagListCellRendererParams,\n) {\n const { value, maxVisible = 3 } = props;\n const { t } = useTranslation();\n\n if (!Array.isArray(value) || value.length === 0) return null;\n\n const visible = value.slice(0, maxVisible);\n const overflow = value.length - maxVisible;\n\n return (\n <span className=\"ds:inline-flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {visible.map((tag) => (\n <Tag key={tag} label={tag} size=\"sm\" />\n ))}\n {overflow > 0 && (\n <Tooltip label={value.slice(maxVisible).join(', ')}>\n <Tag\n label={t('inputs.multiSelect.overflow', { count: overflow })}\n size=\"sm\"\n variant=\"neutral\"\n fill=\"outline\"\n />\n </Tooltip>\n )}\n </span>\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Timestamp } from '../../timestamp';\n\nexport type DateCellFormat = 'date' | 'time' | 'datetime' | 'relative';\n\nexport interface DateCellRendererParams {\n /** Which preset to use. Default `'date'`. */\n format?: DateCellFormat;\n /** Escape hatch — overrides the preset entirely. */\n options?: Intl.DateTimeFormatOptions;\n}\n\nconst PRESETS: Record<\n Exclude<DateCellFormat, 'relative'>,\n Intl.DateTimeFormatOptions\n> = {\n date: { year: 'numeric', month: 'short', day: 'numeric' },\n time: { hour: '2-digit', minute: '2-digit' },\n datetime: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n },\n};\n\nexport function DateCellRenderer(\n props: CustomCellRendererProps & DateCellRendererParams,\n) {\n const { value, format = 'date', options } = props;\n if (value == null || value === '') return null;\n\n // `shape=\"bare\"` keeps the cell font inherited from --ag-font-size. Timestamp\n // still emits a proper `<time dateTime>` for assistive tech and feeds.\n if (format === 'relative' && !options) {\n return <Timestamp value={value as string | Date} shape=\"bare\" />;\n }\n\n return (\n <Timestamp\n value={value as string | Date}\n format=\"absolute\"\n shape=\"bare\"\n absoluteFormat={\n options ?? PRESETS[format === 'relative' ? 'date' : format]\n }\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface CurrencyCellRendererParams {\n /** ISO 4217 currency code. Default `'EUR'`. */\n currency?: string;\n /** Apply a destructive color token to negative amounts. */\n colorNegative?: boolean;\n /** Render the value with strikethrough — used for written-off balances. */\n strikethrough?: boolean;\n /** `Intl.NumberFormat` escape hatch. Merged on top of currency defaults. */\n options?: Intl.NumberFormatOptions;\n}\n\nfunction toNumber(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function CurrencyCellRenderer(\n props: CustomCellRendererProps & CurrencyCellRendererParams,\n) {\n const {\n value,\n currency = 'EUR',\n colorNegative,\n strikethrough,\n options,\n } = props;\n const { i18n } = useTranslation();\n const n = toNumber(value);\n if (n === null) return null;\n\n const locale = i18n.language || 'en';\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...options,\n }).format(n);\n\n const classNames = ['ds:tabular-nums'];\n if (colorNegative && n < 0)\n classNames.push('ds:text-[color:var(--destructive)]');\n if (strikethrough) classNames.push('line-through');\n\n return <span className={classNames.join(' ')}>{formatted}</span>;\n}\n","import type { MouseEvent } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\n\ntype Getter<T, TData> = T | ((data: TData) => T | undefined);\n\nexport interface LinkCellRendererParams<TData = unknown> {\n /** Anchor href — or a function that derives it from the row. */\n href?: Getter<string, TData>;\n /** Fallback / additional onClick. Prevents default when provided without href. */\n onClick?: (data: TData) => void;\n /** Small text rendered below the link — supports a row-aware function. */\n secondary?: Getter<string, TData>;\n}\n\nfunction resolve<T, TData>(\n source: Getter<T, TData> | undefined,\n data: TData,\n): T | undefined {\n if (typeof source === 'function') {\n return (source as (data: TData) => T | undefined)(data);\n }\n return source;\n}\n\nfunction safeHref(href: string): string {\n return /^(https?:\\/\\/|\\/|#|mailto:|tel:)/i.test(href) ? href : '#';\n}\n\nexport function LinkCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & LinkCellRendererParams<TData>,\n) {\n const { value, data, href, onClick, secondary } = props;\n if (!data) return null;\n\n const resolvedHref = resolve(href, data);\n const resolvedSecondary = resolve(secondary, data);\n const content = value == null || value === '' ? '' : String(value);\n\n const linkClasses = [\n 'ds:text-[color:var(--primary)]',\n 'ds:hover:underline',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:rounded-[var(--radius-sm)]',\n ].join(' ');\n\n const handleClick = (event: MouseEvent) => {\n if (!onClick) return;\n if (!resolvedHref) event.preventDefault();\n event.stopPropagation();\n onClick(data);\n };\n\n return (\n <span className=\"ds:flex ds:flex-col ds:leading-tight\">\n {resolvedHref ? (\n <a\n href={safeHref(resolvedHref)}\n onClick={handleClick}\n className={linkClasses}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={handleClick}\n className={[\n 'ds:appearance-none ds:bg-transparent ds:p-0 ds:text-start',\n linkClasses,\n ].join(' ')}\n >\n {content}\n </button>\n )}\n {resolvedSecondary ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {resolvedSecondary}\n </span>\n ) : null}\n </span>\n );\n}\n"],"names":["toIsoDate","d","fromIsoDate","s","DateRangeFilter","props","model","onModelChange","getValue","doesRowPassOtherFilter","filterParams","_a","range","setRange","useState","useEffect","useGridFilter","params","from","to","cellValue","cellDate","apply","next","jsx","DateRangePicker","DateRangeFloatingFilter","column","_b","toValueKey","v","LABEL_COLLATOR","collectColumnOptions","api","readValue","seen","node","raw","value","key","b","sameOptions","a","opt","i","useSelectFilterOptions","options","explicit","hasExplicit","derived","setDerived","readValueRef","useRef","recompute","prev","SelectFilter","placeholder","t","useTranslation","useCallback","derivedOptions","initialSelected","useMemo","set","incoming","pending","setPending","active","toggle","optionKey","values","clear","placeholderLabel","jsxs","ScrollArea","option","Checkbox","Button","SelectFloatingFilter","colDef","availableOptions","accessibleLabel","valueByKey","map","selectOptions","currentValue","handleChange","k","original","MultiSelect","normalise","TypeaheadFilter","loadOptions","adapterLoadOptions","query","opts","o","q","draft","setDraft","target","handleSelect","Autocomplete","TypeaheadFloatingFilter","ALL_OPERATORS","operatorTakesValue","op","operatorTakesRange","evaluate","cell","primary","secondary","lo","hi","coerceCell","n","NumberFilter","defaultOperator","min","max","step","initialOperator","operator","setOperator","setPrimary","setSecondary","operatorOptions","showValue","showRange","Select","NumberInput","NumberFloatingFilter","handle","StatusCellRenderer","variantMap","variant","Badge","UserCellRenderer","Avatar","SIZE_CLASS","SHAPE_CLASS","readField","row","field","SAFE_SRC_RE","sanitizeSrc","trimmed","ImageCellRenderer","data","srcField","altField","fallbackField","size","shape","rawSrc","src","alt","fallbackName","TagListCellRenderer","maxVisible","visible","overflow","tag","Tag","Tooltip","PRESETS","DateCellRenderer","format","Timestamp","toNumber","CurrencyCellRenderer","currency","colorNegative","strikethrough","i18n","locale","formatted","classNames","resolve","source","safeHref","href","LinkCellRenderer","onClick","resolvedHref","resolvedSecondary","content","linkClasses","handleClick","event"],"mappings":"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"}
@@ -3,8 +3,8 @@ import { forwardRef as I, createElement as Z, useId as ee, useState as B, useCal
3
3
  import { c as q } from "./index-D2ZczOXr.js";
4
4
  import { useTranslation as A } from "react-i18next";
5
5
  import { _ as y, R as oe } from "./index-4xgbg-sn.js";
6
- import { I as te } from "./icon-button-9c9Gp41m.js";
7
- import { P as L } from "./popover-Btj6N25H.js";
6
+ import { I as te } from "./icon-button-DA2CAGHZ.js";
7
+ import { P as L } from "./popover-Cqcjx-Ny.js";
8
8
  import { F as ne, f as ie, s as J, _ as re, a as le, b as ce, c as de, d as ue, e as ge, g as me, h as _e, i as fe, j as ve, k as pe, l as he, m as ye, n as be, o as Ne, p as Le, q as xe, r as Ce, t as Se, u as ke, v as we, w as Ee, x as Pe, y as Re, z as Ie, A as Te, B as Ae, C as De, D as je, E as Fe, G as Oe, H as ze, I as Ue, J as Ge, K as Me, L as He } from "./flag-view-udarpAot.js";
9
9
  import { c as Be, a as qe, d as Je } from "./input-surface-xyERuLU_.js";
10
10
  import { LOCALES_WITH_BUNDLES as D } from "../i18n/config.js";
@@ -828,4 +828,4 @@ export {
828
828
  P as b,
829
829
  x as c
830
830
  };
831
- //# sourceMappingURL=locale-picker-sI0HWgZy.js.map
831
+ //# sourceMappingURL=locale-picker-BvbVjDQ-.js.map