@alfadocs/ui-kit-debug 1.5.0 → 1.6.1

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 (419) 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-CGKof8QU.js → booking-CQMJUFG-.js} +556 -549
  26. package/dist/_chunks/booking-CQMJUFG-.js.map +1 -0
  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-profile-hero-Bdd0bFqC.js +187 -0
  154. package/dist/_chunks/practice-profile-hero-Bdd0bFqC.js.map +1 -0
  155. package/dist/_chunks/{practice-results-DWUZRm2x.js → practice-results-F_Rf7c4H.js} +224 -210
  156. package/dist/_chunks/practice-results-F_Rf7c4H.js.map +1 -0
  157. package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js → pregnancy-dating-BVS_9YU2.js} +2 -2
  158. package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js.map → pregnancy-dating-BVS_9YU2.js.map} +1 -1
  159. package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js → pregnancy-weight-gain-CJwbs9W-.js} +2 -2
  160. package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js.map → pregnancy-weight-gain-CJwbs9W-.js.map} +1 -1
  161. package/dist/_chunks/{privacy-lock-SQYFRSuH.js → privacy-lock-CkAUo6Dz.js} +3 -3
  162. package/dist/_chunks/{privacy-lock-SQYFRSuH.js.map → privacy-lock-CkAUo6Dz.js.map} +1 -1
  163. package/dist/_chunks/{product-hub-panel-BjnD9pdl.js → product-hub-panel-BScCotGD.js} +3 -3
  164. package/dist/_chunks/{product-hub-panel-BjnD9pdl.js.map → product-hub-panel-BScCotGD.js.map} +1 -1
  165. package/dist/_chunks/{public-header.agent-DseNK2NQ.js → public-header.agent-kth2SdXn.js} +3 -3
  166. package/dist/_chunks/{public-header.agent-DseNK2NQ.js.map → public-header.agent-kth2SdXn.js.map} +1 -1
  167. package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js → radiograph-panel.agent-CiHwgISa.js} +4 -4
  168. package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js.map → radiograph-panel.agent-CiHwgISa.js.map} +1 -1
  169. package/dist/_chunks/{reviews-panel-Cd3SxJdW.js → reviews-panel-BKHEfqVQ.js} +4 -4
  170. package/dist/_chunks/{reviews-panel-Cd3SxJdW.js.map → reviews-panel-BKHEfqVQ.js.map} +1 -1
  171. package/dist/_chunks/{rich-text-editor-DGtn_4sb.js → rich-text-editor-DARnq_6N.js} +5 -5
  172. package/dist/_chunks/{rich-text-editor-DGtn_4sb.js.map → rich-text-editor-DARnq_6N.js.map} +1 -1
  173. package/dist/_chunks/{session-countdown-q4r5TlCo.js → session-countdown-QMsnRa1x.js} +2 -2
  174. package/dist/_chunks/{session-countdown-q4r5TlCo.js.map → session-countdown-QMsnRa1x.js.map} +1 -1
  175. package/dist/_chunks/{sheet-CD99CdXr.js → sheet-BSznOyJs.js} +2 -2
  176. package/dist/_chunks/{sheet-CD99CdXr.js.map → sheet-BSznOyJs.js.map} +1 -1
  177. package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js → sign-in-with-alfadocs-button-BLe_quy5.js} +2 -2
  178. package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js.map → sign-in-with-alfadocs-button-BLe_quy5.js.map} +1 -1
  179. package/dist/_chunks/{signature-request-C4UBfVRZ.js → signature-request-DXhpphlp.js} +4 -4
  180. package/dist/_chunks/{signature-request-C4UBfVRZ.js.map → signature-request-DXhpphlp.js.map} +1 -1
  181. package/dist/_chunks/{slot-grid-P_e9p5t5.js → slot-grid-BuZOKfcd.js} +4 -4
  182. package/dist/_chunks/{slot-grid-P_e9p5t5.js.map → slot-grid-BuZOKfcd.js.map} +1 -1
  183. package/dist/_chunks/{streaming-text-BuW7I0Zu.js → streaming-text-CvsjIQ7S.js} +2 -2
  184. package/dist/_chunks/{streaming-text-BuW7I0Zu.js.map → streaming-text-CvsjIQ7S.js.map} +1 -1
  185. package/dist/_chunks/{task-tray-BT288xoM.js → task-tray-CYG6rj2s.js} +3 -3
  186. package/dist/_chunks/{task-tray-BT288xoM.js.map → task-tray-CYG6rj2s.js.map} +1 -1
  187. package/dist/_chunks/{tasks-panel-BBkZuejF.js → tasks-panel-Do5SFp-j.js} +5 -5
  188. package/dist/_chunks/{tasks-panel-BBkZuejF.js.map → tasks-panel-Do5SFp-j.js.map} +1 -1
  189. package/dist/_chunks/{theme-toggle-Bi-CmV6M.js → theme-toggle-DuMhQNFS.js} +3 -3
  190. package/dist/_chunks/{theme-toggle-Bi-CmV6M.js.map → theme-toggle-DuMhQNFS.js.map} +1 -1
  191. package/dist/_chunks/{toast.agent-C44mtGrW.js → toast.agent-D1tdg6DS.js} +2 -2
  192. package/dist/_chunks/{toast.agent-C44mtGrW.js.map → toast.agent-D1tdg6DS.js.map} +1 -1
  193. package/dist/_chunks/{token-insert-menu-D8FgXl33.js → token-insert-menu-9Um0JinI.js} +2 -2
  194. package/dist/_chunks/{token-insert-menu-D8FgXl33.js.map → token-insert-menu-9Um0JinI.js.map} +1 -1
  195. package/dist/_chunks/{tool-rail-BF3F2Ihq.js → tool-rail-CHyUmulN.js} +2 -2
  196. package/dist/_chunks/{tool-rail-BF3F2Ihq.js.map → tool-rail-CHyUmulN.js.map} +1 -1
  197. package/dist/_chunks/{tooth-scheme-BPXE1_3N.js → tooth-scheme-WdyVymQ1.js} +3 -3
  198. package/dist/_chunks/{tooth-scheme-BPXE1_3N.js.map → tooth-scheme-WdyVymQ1.js.map} +1 -1
  199. package/dist/_chunks/{unit-converter-iDxlxKmm.js → unit-converter-BPumXMA6.js} +2 -2
  200. package/dist/_chunks/{unit-converter-iDxlxKmm.js.map → unit-converter-BPumXMA6.js.map} +1 -1
  201. package/dist/_chunks/{warning-stack-nczJf52p.js → warning-stack-DQz0Jyir.js} +3 -3
  202. package/dist/_chunks/{warning-stack-nczJf52p.js.map → warning-stack-DQz0Jyir.js.map} +1 -1
  203. package/dist/_chunks/{workflow-map-BVofnDYh.js → workflow-map-DE_ribRM.js} +5 -5
  204. package/dist/_chunks/{workflow-map-BVofnDYh.js.map → workflow-map-DE_ribRM.js.map} +1 -1
  205. package/dist/agent-catalog.json +33 -36
  206. package/dist/agent-i18n/en.json +6 -5
  207. package/dist/components/agenda-tray/index.js +1 -1
  208. package/dist/components/ai-consent-banner/index.js +1 -1
  209. package/dist/components/ai-prompt-input/index.js +1 -1
  210. package/dist/components/anamnesis-card/index.js +1 -1
  211. package/dist/components/appointment-card/index.js +1 -1
  212. package/dist/components/appointment-timeline/index.js +1 -1
  213. package/dist/components/audio-recorder/index.js +1 -1
  214. package/dist/components/bishop-score/index.js +1 -1
  215. package/dist/components/bmi-calculator/index.js +1 -1
  216. package/dist/components/booking/booking-types.d.ts +9 -0
  217. package/dist/components/booking/booking-types.d.ts.map +1 -1
  218. package/dist/components/booking/booking.d.ts.map +1 -1
  219. package/dist/components/booking/index.js +1 -1
  220. package/dist/components/button/button.d.ts +10 -0
  221. package/dist/components/button/button.d.ts.map +1 -1
  222. package/dist/components/button/index.js +2 -2
  223. package/dist/components/button-group/index.js +1 -1
  224. package/dist/components/care-plan-card/index.js +1 -1
  225. package/dist/components/care-plan-entry-card/index.js +1 -1
  226. package/dist/components/care-plan-header/index.js +1 -1
  227. package/dist/components/carousel/index.js +1 -1
  228. package/dist/components/chart/index.js +1 -1
  229. package/dist/components/chat-input/index.js +1 -1
  230. package/dist/components/chat-message/index.js +1 -1
  231. package/dist/components/connection-status/index.js +1 -1
  232. package/dist/components/contact-profile-card/index.js +1 -1
  233. package/dist/components/control-room-rail/index.js +1 -1
  234. package/dist/components/copy-field/index.js +1 -1
  235. package/dist/components/cycle-calculator/index.js +1 -1
  236. package/dist/components/dashboard-grid/index.js +1 -1
  237. package/dist/components/data-table/index.js +3 -3
  238. package/dist/components/data-table-tabs/index.js +1 -1
  239. package/dist/components/description-list/index.js +1 -1
  240. package/dist/components/document-preview/index.js +1 -1
  241. package/dist/components/document-scanner/index.js +1 -1
  242. package/dist/components/due-date-calculator/index.js +1 -1
  243. package/dist/components/editor-overlay/index.js +1 -1
  244. package/dist/components/empty-state/index.js +1 -1
  245. package/dist/components/entity-summary/index.js +1 -1
  246. package/dist/components/face-scheme/index.js +1 -1
  247. package/dist/components/fetal-weight/index.js +1 -1
  248. package/dist/components/field-array/index.js +1 -1
  249. package/dist/components/file-manager/index.js +1 -1
  250. package/dist/components/finished-terminal/index.js +1 -1
  251. package/dist/components/fiscal-code-input/index.js +1 -1
  252. package/dist/components/freemium-paywall/index.js +1 -1
  253. package/dist/components/gestational-age-calculator/index.js +1 -1
  254. package/dist/components/hcg-doubling/index.js +1 -1
  255. package/dist/components/header/index.js +1 -1
  256. package/dist/components/header-settings/index.js +1 -1
  257. package/dist/components/icon-button/index.js +1 -1
  258. package/dist/components/icon-button-group/index.js +1 -1
  259. package/dist/components/icon-picker/index.js +1 -1
  260. package/dist/components/image-cropper/index.js +1 -1
  261. package/dist/components/index.d.ts +1 -0
  262. package/dist/components/index.d.ts.map +1 -1
  263. package/dist/components/info-tip/index.js +1 -1
  264. package/dist/components/key-value-pair/index.js +1 -1
  265. package/dist/components/locale-picker/index.js +1 -1
  266. package/dist/components/map-view/index.js +1 -1
  267. package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
  268. package/dist/components/message-card/index.js +1 -1
  269. package/dist/components/message-tray/index.js +1 -1
  270. package/dist/components/notes-panel/index.js +1 -1
  271. package/dist/components/notification-card/index.js +1 -1
  272. package/dist/components/notification-tray/index.js +1 -1
  273. package/dist/components/optical-prescription/index.js +1 -1
  274. package/dist/components/patient-details/index.js +1 -1
  275. package/dist/components/patient-search/index.js +1 -1
  276. package/dist/components/patient-summary-card/index.js +1 -1
  277. package/dist/components/patient-table/index.js +1 -1
  278. package/dist/components/payment-card/index.js +1 -1
  279. package/dist/components/periodontal-chart/index.js +1 -1
  280. package/dist/components/periodontal-chart-card/index.js +1 -1
  281. package/dist/components/popover/index.js +1 -1
  282. package/dist/components/practice-profile-hero/index.d.ts +4 -0
  283. package/dist/components/practice-profile-hero/index.d.ts.map +1 -0
  284. package/dist/components/practice-profile-hero/index.js +6 -0
  285. package/dist/components/practice-profile-hero/index.js.map +1 -0
  286. package/dist/components/practice-profile-hero/practice-profile-hero.agent.d.ts +4 -0
  287. package/dist/components/practice-profile-hero/practice-profile-hero.agent.d.ts.map +1 -0
  288. package/dist/components/practice-profile-hero/practice-profile-hero.d.ts +60 -0
  289. package/dist/components/practice-profile-hero/practice-profile-hero.d.ts.map +1 -0
  290. package/dist/components/practice-results/index.js +1 -1
  291. package/dist/components/practice-results/practice-results.d.ts +15 -1
  292. package/dist/components/practice-results/practice-results.d.ts.map +1 -1
  293. package/dist/components/pregnancy-dating/index.js +1 -1
  294. package/dist/components/pregnancy-weight-gain/index.js +1 -1
  295. package/dist/components/privacy-lock/index.js +1 -1
  296. package/dist/components/product-hub-tray/index.js +1 -1
  297. package/dist/components/public-header/index.js +1 -1
  298. package/dist/components/public-header/public-header.d.ts +1 -1
  299. package/dist/components/radiograph-panel/index.js +1 -1
  300. package/dist/components/reviews-panel/index.js +1 -1
  301. package/dist/components/rich-text-editor/index.js +1 -1
  302. package/dist/components/session-countdown/index.js +1 -1
  303. package/dist/components/sheet/index.js +1 -1
  304. package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
  305. package/dist/components/slot-grid/index.js +1 -1
  306. package/dist/components/streaming-text/index.js +1 -1
  307. package/dist/components/task-tray/index.js +1 -1
  308. package/dist/components/tasks-panel/index.js +1 -1
  309. package/dist/components/theme-toggle/index.js +1 -1
  310. package/dist/components/toast/index.js +1 -1
  311. package/dist/components/token-insert-menu/index.js +1 -1
  312. package/dist/components/tool-rail/index.js +1 -1
  313. package/dist/components/tooth-scheme/index.js +1 -1
  314. package/dist/components/unit-converter/index.js +1 -1
  315. package/dist/components/warning-stack/index.js +1 -1
  316. package/dist/components/workflow/index.js +1 -1
  317. package/dist/host-compat.css +1 -4
  318. package/dist/i18n/locales/ar.d.ts +1 -0
  319. package/dist/i18n/locales/ar.d.ts.map +1 -1
  320. package/dist/i18n/locales/ar.js +1 -0
  321. package/dist/i18n/locales/ar.js.map +1 -1
  322. package/dist/i18n/locales/de.d.ts +1 -0
  323. package/dist/i18n/locales/de.d.ts.map +1 -1
  324. package/dist/i18n/locales/de.js +1 -0
  325. package/dist/i18n/locales/de.js.map +1 -1
  326. package/dist/i18n/locales/el.d.ts +1 -0
  327. package/dist/i18n/locales/el.d.ts.map +1 -1
  328. package/dist/i18n/locales/el.js +1 -0
  329. package/dist/i18n/locales/el.js.map +1 -1
  330. package/dist/i18n/locales/en.d.ts +1 -0
  331. package/dist/i18n/locales/en.d.ts.map +1 -1
  332. package/dist/i18n/locales/en.js +1 -0
  333. package/dist/i18n/locales/en.js.map +1 -1
  334. package/dist/i18n/locales/es.d.ts +1 -0
  335. package/dist/i18n/locales/es.d.ts.map +1 -1
  336. package/dist/i18n/locales/es.js +1 -0
  337. package/dist/i18n/locales/es.js.map +1 -1
  338. package/dist/i18n/locales/fr.d.ts +1 -0
  339. package/dist/i18n/locales/fr.d.ts.map +1 -1
  340. package/dist/i18n/locales/fr.js +1 -0
  341. package/dist/i18n/locales/fr.js.map +1 -1
  342. package/dist/i18n/locales/hi.d.ts +1 -0
  343. package/dist/i18n/locales/hi.d.ts.map +1 -1
  344. package/dist/i18n/locales/hi.js +1 -0
  345. package/dist/i18n/locales/hi.js.map +1 -1
  346. package/dist/i18n/locales/it.d.ts +1 -0
  347. package/dist/i18n/locales/it.d.ts.map +1 -1
  348. package/dist/i18n/locales/it.js +1 -0
  349. package/dist/i18n/locales/it.js.map +1 -1
  350. package/dist/i18n/locales/ja.d.ts +1 -0
  351. package/dist/i18n/locales/ja.d.ts.map +1 -1
  352. package/dist/i18n/locales/ja.js +1 -0
  353. package/dist/i18n/locales/ja.js.map +1 -1
  354. package/dist/i18n/locales/nl.d.ts +1 -0
  355. package/dist/i18n/locales/nl.d.ts.map +1 -1
  356. package/dist/i18n/locales/nl.js +1 -0
  357. package/dist/i18n/locales/nl.js.map +1 -1
  358. package/dist/i18n/locales/pl.d.ts +1 -0
  359. package/dist/i18n/locales/pl.d.ts.map +1 -1
  360. package/dist/i18n/locales/pl.js +1 -0
  361. package/dist/i18n/locales/pl.js.map +1 -1
  362. package/dist/i18n/locales/pt.d.ts +1 -0
  363. package/dist/i18n/locales/pt.d.ts.map +1 -1
  364. package/dist/i18n/locales/pt.js +1 -0
  365. package/dist/i18n/locales/pt.js.map +1 -1
  366. package/dist/i18n/locales/ro.d.ts +1 -0
  367. package/dist/i18n/locales/ro.d.ts.map +1 -1
  368. package/dist/i18n/locales/ro.js +1 -0
  369. package/dist/i18n/locales/ro.js.map +1 -1
  370. package/dist/i18n/locales/ru.d.ts +1 -0
  371. package/dist/i18n/locales/ru.d.ts.map +1 -1
  372. package/dist/i18n/locales/ru.js +1 -0
  373. package/dist/i18n/locales/ru.js.map +1 -1
  374. package/dist/i18n/locales/sq.d.ts +1 -0
  375. package/dist/i18n/locales/sq.d.ts.map +1 -1
  376. package/dist/i18n/locales/sq.js +1 -0
  377. package/dist/i18n/locales/sq.js.map +1 -1
  378. package/dist/i18n/locales/sv.d.ts +1 -0
  379. package/dist/i18n/locales/sv.d.ts.map +1 -1
  380. package/dist/i18n/locales/sv.js +1 -0
  381. package/dist/i18n/locales/sv.js.map +1 -1
  382. package/dist/i18n/locales/tr.d.ts +1 -0
  383. package/dist/i18n/locales/tr.d.ts.map +1 -1
  384. package/dist/i18n/locales/tr.js +1 -0
  385. package/dist/i18n/locales/tr.js.map +1 -1
  386. package/dist/i18n/locales/zh.d.ts +1 -0
  387. package/dist/i18n/locales/zh.d.ts.map +1 -1
  388. package/dist/i18n/locales/zh.js +1 -0
  389. package/dist/i18n/locales/zh.js.map +1 -1
  390. package/dist/index.js +409 -406
  391. package/dist/index.js.map +1 -1
  392. package/dist/locales/ar.json +1 -0
  393. package/dist/locales/de.json +1 -0
  394. package/dist/locales/el.json +1 -0
  395. package/dist/locales/en.json +1 -0
  396. package/dist/locales/es.json +1 -0
  397. package/dist/locales/fr.json +1 -0
  398. package/dist/locales/hi.json +1 -0
  399. package/dist/locales/it.json +1 -0
  400. package/dist/locales/ja.json +1 -0
  401. package/dist/locales/nl.json +1 -0
  402. package/dist/locales/pl.json +1 -0
  403. package/dist/locales/pt.json +1 -0
  404. package/dist/locales/ro.json +1 -0
  405. package/dist/locales/ru.json +1 -0
  406. package/dist/locales/sq.json +1 -0
  407. package/dist/locales/sv.json +1 -0
  408. package/dist/locales/tr.json +1 -0
  409. package/dist/locales/zh.json +1 -0
  410. package/dist/patterns/alia-assistant/index.js +1 -1
  411. package/dist/patterns/anamnesis/index.js +1 -1
  412. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  413. package/dist/patterns/payment-automation-upsell/index.js +1 -1
  414. package/dist/patterns/signature-request/index.js +1 -1
  415. package/dist/tokens.css +1 -1
  416. package/package.json +5 -1
  417. package/dist/_chunks/booking-CGKof8QU.js.map +0 -1
  418. package/dist/_chunks/button-BvNtqHAS.js.map +0 -1
  419. package/dist/_chunks/practice-results-DWUZRm2x.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-tabs-C8uDThT3.js","sources":["../../src/components/data-table-tabs/data-table-tabs.agent.ts","../../src/components/data-table-tabs/use-data-table-filter-tabs.ts","../../src/components/data-table-tabs/data-table-tabs.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — DataTableTabs. */\n/* */\n/* Operations work against the curated `DataTableTabsHandle` (saved-filter */\n/* tab strip). Tab ids are opaque machine ids — labels are display-only. */\n/* See `src/docs/26-agent-readiness.mdx`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DataTableTabsHandle } from './data-table-tabs';\n\nexport const dataTableTabsAgent: AgentAdapter<DataTableTabsHandle> = {\n id: 'data-table-tabs',\n capabilities: ['select_single', 'view_change'],\n state: {\n activeTabId: {\n type: 'string | null',\n descriptionKey: 'ui.agent.dataTableTabs.state.activeTabId',\n description: 'Id of the currently-active saved-filter tab.',\n read: (handle) => handle.getActiveTabId(),\n },\n tabs: {\n type: 'Array<{ id, label }>',\n descriptionKey: 'ui.agent.dataTableTabs.state.tabs',\n description: 'The saved-filter tabs, in strip order (ids + labels).',\n read: (handle) =>\n handle.getTabs().map(({ id, label }) => ({ id, label })),\n },\n },\n actions: {\n select_tab: {\n // Applies a saved filter model — a view change, like apply_filter.\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to activate.' },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.selectTab',\n description:\n 'Activate a saved-filter tab: snapshots the outgoing tab, applies the incoming filter model to the table.',\n invoke: (handle, args: { id: string }) => {\n handle.selectTab(args.id);\n },\n },\n get_tabs: {\n safety: 'read',\n returns: 'Array<{ id: string, label: string }>',\n returnsSchema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n label: { type: 'string' },\n },\n required: ['id', 'label'],\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.getTabs',\n description: 'Return the saved-filter tabs (ids + labels) in order.',\n invoke: (handle) =>\n handle.getTabs().map(({ id, label }) => ({ id, label })),\n },\n add_tab: {\n safety: 'write',\n argsType: '{ label?: string }',\n argsSchema: {\n type: 'object',\n properties: {\n label: {\n type: 'string',\n description:\n 'Display name for the new tab. Defaults to a numbered name.',\n },\n },\n required: [],\n },\n idempotent: false,\n descriptionKey: 'ui.agent.dataTableTabs.actions.addTab',\n description:\n \"Add a new tab capturing the table's current filter model, and activate it. Returns the new tab id.\",\n returns: 'string',\n returnsSchema: { type: 'string' },\n invoke: (handle, args: { label?: string }) => handle.addTab(args.label),\n },\n rename_tab: {\n safety: 'write',\n argsType: '{ id: string, label: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to rename.' },\n label: { type: 'string', description: 'New display name.' },\n },\n required: ['id', 'label'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.renameTab',\n description:\n 'Rename a saved-filter tab. No-op on locked tabs and empty labels.',\n invoke: (handle, args: { id: string; label: string }) => {\n handle.renameTab(args.id, args.label);\n },\n },\n remove_tab: {\n // Removes a saved filter permanently — destructive, do not downgrade.\n safety: 'destructive',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to remove.' },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.removeTab',\n description:\n 'Remove a saved-filter tab (its saved filter is lost). No-op on locked tabs and the last remaining tab.',\n invoke: (handle, args: { id: string }) => {\n handle.removeTab(args.id);\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'data-table-tabs' },\n instanceId: { attr: 'data-component-id', sourceProp: 'id' },\n item: { attr: 'data-tab-id' },\n },\n};\n","/**\n * use-data-table-filter-tabs — headless sync engine for DataTableTabs.\n * ----------------------------------------------------------------------------\n * Owns the tabs array + active tab id and keeps the grid's AG Grid filter\n * model in lock-step with the active tab. The grid is a PROJECTION of the\n * active tab; the hook is the single owner of tab state.\n *\n * Four flows, all through `getTable()` resolved at call time (never held):\n *\n * 1. SUBSCRIBE-LATE — the grid api resolves after mount (ToolbarProvider\n * convention), so a mount effect polls a 50 ms interval until\n * `getTable()?.getRawApi()` resolves, then attaches a `filterChanged`\n * listener (FilterChips precedent — a one-shot `if (!api) return` would\n * bail permanently and never capture).\n * 2. CAPTURE — tabs are LIVE views: every user/host filter edit is written\n * into the active tab. The listener skips ONLY while `applyingRef` is set\n * (our own restore). It deliberately does NOT filter on\n * `event.source === 'api'`: external programmatic `setFilter` calls (page\n * warning actions, the data-table agent) are user intent and must land in\n * the active tab.\n * 3. RESTORE — activating a tab snapshots the outgoing tab defensively, then\n * applies the incoming model under the `applyingRef` guard and calls\n * `api.onFilterChanged()` so floating filters / chips / agents refresh\n * (ViewSwitcher precedent — `setFilterModel` alone doesn't re-run\n * listeners).\n * 4. INITIAL APPLY — when `applyOnActivate`, the active tab's model applies\n * once as soon as the api resolves (the patients FilteredView-proven\n * poll-then-set path; `firstDataRendered` gating is forbidden — zero-row\n * grids may never fire it).\n *\n * Persistence is opt-in via `persistKey` → `data-table-tabs:<persistKey>`\n * with a versioned envelope; the active tab id is deliberately NOT persisted\n * so a restored session lands on the first tab instead of silently\n * re-applying a stale aggressive filter.\n */\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { GridApi } from 'ag-grid-community';\nimport { useControllableState } from '../../hooks/use-controllable-state';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** One saved-filter tab. */\nexport interface SavedTab {\n /** Opaque machine-generated id — emitted as `data-tab-id`, never the label. */\n id: string;\n /** User-typed name; rendered text only — never used in DOM hooks or keys. */\n label: string;\n /** AG Grid filter model (`DataTableHandle.getFilter()` shape); `{}` = none. */\n filterModel: Record<string, unknown>;\n /** Captured quick-filter text — only present when `captureQuickFilter`. */\n quickFilter?: string;\n /** Locked tabs cannot be renamed or removed (e.g. an \"All\" tab). */\n locked?: boolean;\n}\n\n/**\n * The narrow grid seam the tabs ride on. Structural, and `getRawApi` is\n * deliberately typed against the un-parameterised `GridApi` so any\n * `DataTableHandle<TData>` (incl. `PatientTableHandle`) satisfies it —\n * `GridApi<TData>` is invariant, so pinning a row type here would reject\n * every concretely-typed handle.\n */\nexport interface DataTableTabsGridSeam {\n getFilter: () => Record<string, unknown>;\n setFilter: (model: Record<string, unknown>) => void;\n getRawApi: () => GridApi | undefined;\n}\n\nexport interface UseDataTableFilterTabsOptions {\n /** Resolve the grid seam at call time — `undefined` until grid-ready. */\n getTable: () => DataTableTabsGridSeam | null | undefined;\n tabs?: SavedTab[];\n defaultTabs?: SavedTab[];\n onTabsChange?: (tabs: SavedTab[]) => void;\n activeTabId?: string;\n defaultActiveTabId?: string;\n onActiveTabChange?: (id: string) => void;\n /** Opt-in localStorage persistence — disabled while `tabs` is controlled. */\n persistKey?: string;\n /** Capture/restore `quickFilterText` alongside the model. Default false. */\n captureQuickFilter?: boolean;\n /** Apply the active tab's model on mount + tab switch. Default true. */\n applyOnActivate?: boolean;\n /** Cap on the number of tabs. Default 8. */\n maxTabs?: number;\n /** Factory for a new tab; `index` is 1-based (used for the default name). */\n createTab?: (index: number) => SavedTab;\n /** Id factory — default `crypto.randomUUID()` with a counter fallback. */\n makeTabId?: () => string;\n}\n\nexport interface UseDataTableFilterTabsResult {\n tabs: SavedTab[];\n activeTabId: string;\n selectTab: (id: string) => void;\n addTab: (label?: string, filterModel?: Record<string, unknown>) => string;\n renameTab: (id: string, label: string) => void;\n removeTab: (id: string) => void;\n atCapacity: boolean;\n /** Synchronous snapshots for the imperative handle / agent adapter —\n * fresh immediately after a mutation, before React re-renders. */\n getTabsSnapshot: () => SavedTab[];\n getActiveTabIdSnapshot: () => string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nlet fallbackCounter = 0;\n\nfunction defaultMakeTabId(): string {\n try {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID();\n }\n } catch {\n /* noop — fall through to the counter */\n }\n fallbackCounter += 1;\n return `tab-${fallbackCounter}`;\n}\n\n/** Versioned persistence envelope — mirrors the col-state loader's guards. */\ninterface PersistEnvelope {\n v: 1;\n tabs: SavedTab[];\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) !== null\n );\n}\n\nfunction isValidEnvelope(value: unknown): value is PersistEnvelope {\n if (!isPlainObject(value) || value.v !== 1 || !Array.isArray(value.tabs)) {\n return false;\n }\n return (value.tabs as unknown[]).every(\n (tab) =>\n isPlainObject(tab) &&\n typeof tab.id === 'string' &&\n typeof tab.label === 'string' &&\n isPlainObject(tab.filterModel),\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\nexport function useDataTableFilterTabs(\n options: UseDataTableFilterTabsOptions,\n): UseDataTableFilterTabsResult {\n const {\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter = false,\n applyOnActivate = true,\n maxTabs = 8,\n createTab,\n makeTabId = defaultMakeTabId,\n } = options;\n\n const { t } = useTranslation();\n\n const isControlled = tabsProp !== undefined;\n if (import.meta.env.DEV && isControlled && persistKey) {\n // eslint-disable-next-line no-console\n console.warn(\n 'DataTableTabs: `persistKey` is ignored while `tabs` is controlled — persist from `onTabsChange` instead.',\n );\n }\n\n // Uncontrolled seed: defaultTabs, else one unfiltered tab.\n const seed = useMemo<SavedTab[]>(() => {\n if (defaultTabs && defaultTabs.length > 0) return defaultTabs;\n return [\n {\n id: 'default',\n label: t('dataTableTabs.newTabName', { number: 1 }),\n filterModel: {},\n },\n ];\n // The seed is computed once for the uncontrolled path; label language at\n // mount time is acceptable for a user-renameable default.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Persistence backs the UNCONTROLLED state only. The envelope validates on\n // load; any mismatch falls back to the seed. Read once, on mount.\n const persistedTabs = useMemo<SavedTab[] | null>(() => {\n if (!persistKey || isControlled || typeof window === 'undefined') {\n return null;\n }\n try {\n const raw = window.localStorage.getItem(`data-table-tabs:${persistKey}`);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n return isValidEnvelope(parsed) ? parsed.tabs : null;\n } catch {\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const [tabsState, setTabsState] = useControllableState<SavedTab[]>({\n value: tabsProp,\n defaultValue: persistedTabs ?? seed,\n onChange: onTabsChange,\n });\n const tabs = useMemo(() => tabsState ?? seed, [tabsState, seed]);\n\n // Mirror every uncontrolled tabs write into storage synchronously\n // (crash-safe — no effect lag). The ref also updates synchronously so\n // successive same-tick writes compose instead of both reading the\n // pre-render snapshot.\n const setTabs = useCallback(\n (update: (prev: SavedTab[]) => SavedTab[]) => {\n const next = update(tabsRef.current);\n tabsRef.current = next;\n setTabsState(next);\n if (persistKey && !isControlled) {\n try {\n const envelope: PersistEnvelope = { v: 1, tabs: next };\n window.localStorage.setItem(\n `data-table-tabs:${persistKey}`,\n JSON.stringify(envelope),\n );\n } catch {\n // localStorage may be unavailable in some environments\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [setTabsState, persistKey, isControlled],\n );\n\n const [activeIdState, setActiveIdState] = useControllableState<string>({\n value: activeTabIdProp,\n defaultValue: defaultActiveTabId ?? tabs[0]?.id ?? 'default',\n onChange: onActiveTabChange,\n });\n const activeTabId = activeIdState ?? tabs[0]?.id ?? 'default';\n\n /* -- refs mirroring the latest state for event handlers ------------ */\n const tabsRef = useRef(tabs);\n tabsRef.current = tabs;\n const activeIdRef = useRef(activeTabId);\n activeIdRef.current = activeTabId;\n /** True while the hook itself is writing the grid's filter model. */\n const applyingRef = useRef(false);\n const getTableRef = useRef(getTable);\n getTableRef.current = getTable;\n\n /* -- CAPTURE: write the live model into the active tab ------------- */\n const captureIntoActive = useCallback(() => {\n const seam = getTableRef.current();\n if (!seam) return;\n const model = seam.getFilter() ?? {};\n const quick = captureQuickFilter\n ? ((): string | undefined => {\n const raw = seam.getRawApi()?.getGridOption('quickFilterText');\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined;\n })()\n : undefined;\n setTabs((prev) =>\n prev.map((tab) =>\n tab.id === activeIdRef.current\n ? {\n ...tab,\n filterModel: model,\n ...(captureQuickFilter ? { quickFilter: quick } : {}),\n }\n : tab,\n ),\n );\n }, [captureQuickFilter, setTabs]);\n\n /* -- RESTORE: apply a tab's model to the grid ----------------------- */\n const applyTab = useCallback(\n (tab: SavedTab | undefined) => {\n if (!tab) return;\n const seam = getTableRef.current();\n if (!seam) return;\n applyingRef.current = true;\n try {\n seam.setFilter(tab.filterModel ?? {});\n const api = seam.getRawApi();\n if (captureQuickFilter) {\n api?.setGridOption('quickFilterText', tab.quickFilter ?? '');\n }\n // Re-run filtering + notify listeners (floating filters, chips, agent\n // state) — setFilterModel alone does not.\n api?.onFilterChanged();\n } finally {\n // AG Grid dispatches filterChanged synchronously, so a synchronous\n // clear is exact: a host setFilter one tick later is never swallowed.\n // If a grid path ever fires async, the stray capture writes back the\n // model we just applied — idempotent, harmless.\n applyingRef.current = false;\n }\n },\n [captureQuickFilter],\n );\n\n /* -- SUBSCRIBE-LATE + INITIAL APPLY --------------------------------- */\n useEffect(() => {\n let cleanup: (() => void) | undefined;\n const handler = () => {\n if (applyingRef.current) return;\n captureIntoActive();\n };\n const wire = (seam: DataTableTabsGridSeam) => {\n const api = seam.getRawApi();\n if (!api) return false;\n api.addEventListener('filterChanged', handler);\n cleanup = () => api.removeEventListener('filterChanged', handler);\n if (applyOnActivate) {\n const active = tabsRef.current.find(\n (tab) => tab.id === activeIdRef.current,\n );\n if (\n active &&\n (Object.keys(active.filterModel ?? {}).length > 0 ||\n (captureQuickFilter && active.quickFilter))\n ) {\n applyTab(active);\n }\n }\n return true;\n };\n const seam = getTableRef.current();\n if (seam && wire(seam)) return () => cleanup?.();\n // Grid not ready yet — poll until it is (never bail one-shot).\n const timer = window.setInterval(() => {\n const late = getTableRef.current();\n if (!late) return;\n if (wire(late)) window.clearInterval(timer);\n }, 50);\n return () => {\n window.clearInterval(timer);\n cleanup?.();\n };\n }, [applyOnActivate, applyTab, captureIntoActive, captureQuickFilter]);\n\n /* -- public reducers ------------------------------------------------ */\n\n const selectTab = useCallback(\n (id: string) => {\n if (id === activeIdRef.current) return;\n const next = tabsRef.current.find((tab) => tab.id === id);\n if (!next) return;\n // Defensive final snapshot of the outgoing tab — quickFilter has no\n // model event, so this is its only reliable capture point.\n captureIntoActive();\n setActiveIdState(id);\n activeIdRef.current = id;\n if (applyOnActivate) applyTab(next);\n },\n [applyOnActivate, applyTab, captureIntoActive, setActiveIdState],\n );\n\n const addTab = useCallback(\n (label?: string, filterModel?: Record<string, unknown>): string => {\n if (tabsRef.current.length >= maxTabs) return activeIdRef.current;\n const index = tabsRef.current.length + 1;\n const fresh: SavedTab = createTab\n ? createTab(index)\n : {\n id: makeTabId(),\n label: label ?? t('dataTableTabs.newTabName', { number: index }),\n // New tab = copy of the CURRENT live model, so the grid view does\n // not jump on add — the natural gesture is \"save my current\n // filter as a tab\".\n filterModel:\n filterModel ?? getTableRef.current()?.getFilter() ?? {},\n };\n setTabs((prev) => [...prev, fresh]);\n setActiveIdState(fresh.id);\n activeIdRef.current = fresh.id;\n return fresh.id;\n },\n [createTab, makeTabId, maxTabs, setActiveIdState, setTabs, t],\n );\n\n const renameTab = useCallback(\n (id: string, label: string) => {\n const trimmed = label.trim();\n if (!trimmed) return;\n setTabs((prev) =>\n prev.map((tab) =>\n tab.id === id && !tab.locked ? { ...tab, label: trimmed } : tab,\n ),\n );\n },\n [setTabs],\n );\n\n const removeTab = useCallback(\n (id: string) => {\n const current = tabsRef.current;\n const target = current.find((tab) => tab.id === id);\n if (!target || target.locked || current.length <= 1) return;\n const index = current.findIndex((tab) => tab.id === id);\n const next = current.filter((tab) => tab.id !== id);\n setTabs(() => next);\n if (activeIdRef.current === id) {\n // Activate the inline-start neighbour (else the next one) and apply\n // its model so the grid never shows a removed tab's filter.\n const neighbour = next[Math.max(0, index - 1)];\n if (neighbour) {\n setActiveIdState(neighbour.id);\n activeIdRef.current = neighbour.id;\n if (applyOnActivate) applyTab(neighbour);\n }\n }\n },\n [applyOnActivate, applyTab, setActiveIdState, setTabs],\n );\n\n const getTabsSnapshot = useCallback(() => tabsRef.current, []);\n const getActiveTabIdSnapshot = useCallback(() => activeIdRef.current, []);\n\n return {\n tabs,\n activeTabId,\n selectTab,\n addTab,\n renameTab,\n removeTab,\n atCapacity: tabs.length >= maxTabs,\n getTabsSnapshot,\n getActiveTabIdSnapshot,\n };\n}\n","/**\n * DataTableTabs — saved-filter folder tabs for any kit DataTable.\n * ----------------------------------------------------------------------------\n * A folder-tab strip attached above a table region. Each tab captures and\n * restores its own AG Grid filter model (tabs are LIVE views — any filter\n * edit rewrites the active tab); a \"+\" button saves the current filter as a\n * new tab; tabs rename via double-click / F2 and remove via Delete/Backspace\n * or the pointer-only ✕.\n *\n * ARIA: a real APG tablist built on Radix Tabs primitives with\n * `activationMode=\"manual\"` (arrow keys rove without applying filter models;\n * Enter/Space activates). Every trigger points at ONE stable hand-rolled\n * tabpanel that wraps `children` — the grid never remounts on tab switch and\n * no dangling ARIA refs exist. The \"+\" button and the rename editor are\n * SIBLINGS of the tablist (tablist purity).\n *\n * Grid wiring rides the narrow `DataTableTabsGridSeam` resolved at call time\n * (`getTable={() => tableRef.current}`) — see use-data-table-filter-tabs.ts\n * for the sync engine. Works against any `DataTableHandle`-shaped ref,\n * including `PatientTableHandle`.\n */\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\nimport { cva, cx, type VariantProps } from 'class-variance-authority';\nimport { Check, Plus, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { IconButton } from '../button/icon-button';\nimport { Popover } from '../popover';\nimport { TextInput } from '../text-input';\nimport { useDirection } from '../../hooks/use-direction';\nimport { useAgentRegistration } from '../../agent';\nimport { dataTableTabsAgent } from './data-table-tabs.agent';\nimport {\n useDataTableFilterTabs,\n type DataTableTabsGridSeam,\n type SavedTab,\n} from './use-data-table-filter-tabs';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nexport const dataTableTabsListVariants = cva(\n [\n // The strip scrolls horizontally when tabs overflow; focusable tabs inside\n // (with an inset focus ring, below) satisfy scrollable-region-focusable.\n // No baseline border and no leading padding: the first tab sits flush with\n // the table's inline-start edge and the active tab merges straight into the\n // grid header below — the table's own rounded top is the only edge drawn.\n 'ds:flex ds:items-end ds:gap-[var(--spacing-2xs)] ds:overflow-x-auto',\n 'ds:pe-[var(--spacing-2xs)]',\n ].join(' '),\n {\n variants: {\n size: {\n md: '',\n lg: '',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nexport const dataTableTabsTriggerVariants = cva(\n [\n // `group` so the pointer-only ✕ can reveal on hover/focus/active; `relative`\n // so that ✕ can be absolutely positioned in the trailing padding (below).\n 'ds:group ds:relative ds:inline-flex ds:items-center ds:justify-center',\n 'ds:whitespace-nowrap ds:select-none ds:cursor-pointer ds:shrink-0',\n // Logical top corners so the leading corner can be squared in either text\n // direction (see the first-tab override + the grid corner below). Inactive\n // tabs take a crisp white fill so they read clearly against a warm page\n // instead of dissolving into it; muted text keeps them clearly unselected.\n // (Focus ring is INSET — see FOCUS_RING — so the scroll container never\n // clips it and the flush-leading first tab keeps its ring.)\n 'ds:[border-start-start-radius:var(--radius-md)] ds:[border-start-end-radius:var(--radius-md)]',\n 'ds:bg-background ds:text-muted-foreground',\n // Match the grid header's eyebrow treatment (uppercase, tracked, medium):\n // the strip reads as one unit with the header below. `text-transform` is\n // display-only — the stored label keeps its case for the rename editor, and\n // uppercase is a no-op on caseless scripts (Arabic, CJK).\n 'ds:font-medium ds:uppercase ds:tracking-[var(--letter-spacing-uppercase)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-muted/40 ds:hover:text-foreground',\n // NOTE: the focus ring is applied by the component (see FOCUS_RING), gated\n // on keyboard modality — Radix focuses the trigger on click, which would\n // otherwise show a `:focus-visible` ring on a plain mouse selection.\n // Active = the table header surface (`--muted`): a 1px downward pull fuses\n // it into one continuous grey sheet with the grid header below. That fuse\n // (grey fill + foreground text) is the whole selection cue — no accent bar.\n 'ds:data-[state=active]:bg-muted ds:data-[state=active]:text-foreground',\n 'ds:data-[state=active]:z-[1]',\n 'ds:data-[state=active]:[margin-block-end:-1px]',\n 'ds:disabled:pointer-events-none ds:disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n size: {\n // Symmetric inline padding so the label centres and every tab matches,\n // removable or not; the ✕ lives in the trailing padding (absolute).\n md: 'ds:h-10 ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-2xs)]',\n lg: 'ds:h-12 ds:ps-[var(--spacing-lg)] ds:pe-[var(--spacing-lg)] ds:text-[length:var(--font-size-xs)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\n/**\n * Inset keyboard focus ring — applied only while the user is navigating by\n * keyboard (see `useKeyboardModality`). Inset (offset negated) so the scroll\n * container never clips it and the flush-leading first tab keeps its ring.\n */\nconst FOCUS_RING =\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:[outline-offset:calc(-1*var(--focus-ring-width))]';\n\n/**\n * True while the last input was a keyboard, false after any pointer press.\n * Radix Tabs programmatically focuses a trigger on click, which makes Chrome\n * match `:focus-visible` even for a mouse selection; gating the ring on real\n * keyboard use restores the intended behaviour without losing keyboard focus\n * visibility. Document-level listeners catch the Tab press that moves focus\n * INTO the tablist (its target is outside this component's subtree).\n */\nfunction useKeyboardModality(): boolean {\n const [keyboard, setKeyboard] = useState(false);\n useEffect(() => {\n // Functional updates return the same value when unchanged, so React bails\n // out of re-rendering except on an actual modality transition.\n const onKey = () => setKeyboard((k) => k || true);\n const onPointer = () => setKeyboard((k) => (k ? false : k));\n document.addEventListener('keydown', onKey, true);\n document.addEventListener('pointerdown', onPointer, true);\n return () => {\n document.removeEventListener('keydown', onKey, true);\n document.removeEventListener('pointerdown', onPointer, true);\n };\n }, []);\n return keyboard;\n}\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Curated imperative handle — also the agent-adapter surface. */\nexport interface DataTableTabsHandle {\n getTabs: () => SavedTab[];\n getActiveTabId: () => string | null;\n /** Snapshots the outgoing tab, applies the incoming tab's filter model. */\n selectTab: (id: string) => void;\n /** Default model = a copy of the current live model (grid view unchanged). */\n addTab: (label?: string, filterModel?: Record<string, unknown>) => string;\n /** No-op on locked tabs and empty/whitespace labels. */\n renameTab: (id: string, label: string) => void;\n /** No-op on locked tabs and the last remaining tab. */\n removeTab: (id: string) => void;\n}\n\nexport interface DataTableTabsProps extends VariantProps<\n typeof dataTableTabsTriggerVariants\n> {\n /**\n * Resolve the grid seam at call time — `undefined` until the grid is ready\n * (same convention as `ToolbarProvider.getApi`). Any `DataTableHandle`\n * satisfies it: `getTable={() => tableRef.current}`.\n */\n getTable: () => DataTableTabsGridSeam | null | undefined;\n /** Controlled tabs — pair with `onTabsChange`. */\n tabs?: SavedTab[];\n /** Uncontrolled seed. Default: one unfiltered tab. */\n defaultTabs?: SavedTab[];\n onTabsChange?: (tabs: SavedTab[]) => void;\n activeTabId?: string;\n defaultActiveTabId?: string;\n onActiveTabChange?: (id: string) => void;\n /**\n * Opt-in localStorage persistence under `data-table-tabs:<persistKey>`.\n * Ignored (with a DEV warning) while `tabs` is controlled. The active tab\n * id is deliberately not persisted.\n */\n persistKey?: string;\n /** Capture/restore the quick-filter text alongside the model. Default false. */\n captureQuickFilter?: boolean;\n /** Apply the active tab's model on mount + switch. Default true. */\n applyOnActivate?: boolean;\n /** Show the \"+\" button. Default true. */\n allowAdd?: boolean;\n /** Allow rename (double-click / F2 / popover editor). Default true. */\n allowRename?: boolean;\n /** Allow removal (Delete/Backspace / ✕). Default true. */\n allowRemove?: boolean;\n /** Tab cap — \"+\" disables at the cap. Default 8. */\n maxTabs?: number;\n /** Factory for new tabs; `index` is 1-based. */\n createTab?: (index: number) => SavedTab;\n /** Id factory — default `crypto.randomUUID()`. */\n makeTabId?: () => string;\n /** Open the rename editor on a freshly-added tab. Default true. */\n renameOnAdd?: boolean;\n /** `data-component-id` + agent instance id. */\n id?: string;\n className?: string;\n /** Accessible tablist name — defaults to the localised \"Saved views\". */\n 'aria-label'?: string;\n /** The table region — rendered inside the single stable tabpanel. */\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DataTableTabs = forwardRef<\n DataTableTabsHandle,\n DataTableTabsProps\n>(function DataTableTabs(\n {\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter = false,\n applyOnActivate = true,\n allowAdd = true,\n allowRename = true,\n allowRemove = true,\n maxTabs = 8,\n createTab,\n makeTabId,\n renameOnAdd = true,\n size = 'md',\n id,\n className,\n 'aria-label': ariaLabel,\n children,\n },\n ref,\n) {\n const { t } = useTranslation();\n const rootRef = useRef<HTMLDivElement>(null);\n const dir = useDirection(rootRef);\n const keyboardNav = useKeyboardModality();\n const baseId = useId();\n const panelId = `${baseId}-panel`;\n const hintId = `${baseId}-hint`;\n\n const {\n tabs,\n activeTabId,\n selectTab,\n addTab,\n renameTab,\n removeTab,\n atCapacity,\n getTabsSnapshot,\n getActiveTabIdSnapshot,\n } = useDataTableFilterTabs({\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter,\n applyOnActivate,\n maxTabs,\n createTab,\n makeTabId,\n });\n\n /* -- rename editor state -------------------------------------------- */\n const [renamingId, setRenamingId] = useState<string | null>(null);\n const renameInputRef = useRef<HTMLInputElement>(null);\n const renamingTab = tabs.find((tab) => tab.id === renamingId);\n\n /* -- announcements (sr-only live region) ----------------------------- */\n const [announcement, setAnnouncement] = useState('');\n useEffect(() => {\n if (!announcement) return;\n const timer = setTimeout(() => setAnnouncement(''), 3000);\n return () => clearTimeout(timer);\n }, [announcement]);\n\n /* -- focus management ------------------------------------------------ */\n const triggerRefs = useRef(new Map<string, HTMLButtonElement>());\n const focusTrigger = useCallback((tabId: string) => {\n // After a state flush — the trigger may have just (un)mounted.\n requestAnimationFrame(() => {\n triggerRefs.current.get(tabId)?.focus();\n });\n }, []);\n\n const canRename = useCallback(\n (tab: SavedTab) => allowRename && !tab.locked,\n [allowRename],\n );\n const canRemove = useCallback(\n (tab: SavedTab) => allowRemove && !tab.locked && tabs.length > 1,\n [allowRemove, tabs.length],\n );\n\n const openRename = useCallback(\n (tab: SavedTab) => {\n if (!canRename(tab)) return;\n setRenamingId(tab.id);\n },\n [canRename],\n );\n\n const commitRename = useCallback(() => {\n if (renamingId) {\n const value = renameInputRef.current?.value ?? '';\n if (value.trim()) {\n renameTab(renamingId, value);\n setAnnouncement(\n t('dataTableTabs.announce.renamed', { name: value.trim() }),\n );\n }\n }\n setRenamingId(null);\n }, [renamingId, renameTab, t]);\n\n const cancelRename = useCallback(() => setRenamingId(null), []);\n\n const handleAdd = useCallback(() => {\n // Mirror the hook's default naming — state hasn't flushed yet, so the\n // fresh tab isn't in `tabs` at announce time.\n const label = t('dataTableTabs.newTabName', { number: tabs.length + 1 });\n const newId = addTab();\n setAnnouncement(t('dataTableTabs.announce.added', { name: label }));\n if (renameOnAdd && allowRename) {\n // The rename popover autofocuses its input; focusing the trigger too\n // would steal focus from it — the editor's onCloseAutoFocus returns\n // focus to the trigger instead.\n setRenamingId(newId);\n } else {\n focusTrigger(newId);\n }\n }, [addTab, allowRename, focusTrigger, renameOnAdd, t, tabs.length]);\n\n const handleRemove = useCallback(\n (tab: SavedTab) => {\n if (!canRemove(tab)) return;\n const index = tabs.findIndex((candidate) => candidate.id === tab.id);\n const neighbour = tabs.filter((candidate) => candidate.id !== tab.id)[\n Math.max(0, index - 1)\n ];\n removeTab(tab.id);\n setAnnouncement(t('dataTableTabs.announce.removed', { name: tab.label }));\n if (neighbour) focusTrigger(neighbour.id);\n },\n [canRemove, focusTrigger, removeTab, t, tabs],\n );\n\n const handleTriggerKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, tab: SavedTab) => {\n // APG dismissible-tab pattern: Delete/Backspace removes; F2 renames.\n // The visual ✕ is pointer-only (aria-hidden) to avoid nested-interactive.\n if (event.key === 'Delete' || event.key === 'Backspace') {\n event.preventDefault();\n handleRemove(tab);\n } else if (event.key === 'F2') {\n event.preventDefault();\n openRename(tab);\n }\n },\n [handleRemove, openRename],\n );\n\n /* -- curated handle + agent registration ----------------------------- */\n // Latest-value refs so the stable handle object never closes over stale\n // callbacks (DataTable handle precedent — stable identity, live reads).\n // Reads go through the hook's synchronous snapshots, so a mutation is\n // visible to the very next handle call, before React re-renders.\n const selectTabRef = useRef(selectTab);\n selectTabRef.current = selectTab;\n const addTabRef = useRef(addTab);\n addTabRef.current = addTab;\n const renameTabRef = useRef(renameTab);\n renameTabRef.current = renameTab;\n const removeTabHandlerRef = useRef(handleRemove);\n removeTabHandlerRef.current = handleRemove;\n\n const handleRef = useRef<DataTableTabsHandle>({\n getTabs: () => getTabsSnapshot(),\n getActiveTabId: () => getActiveTabIdSnapshot() ?? null,\n selectTab: (tabId) => selectTabRef.current(tabId),\n addTab: (label, filterModel) => addTabRef.current(label, filterModel),\n renameTab: (tabId, label) => renameTabRef.current(tabId, label),\n removeTab: (tabId) => {\n const tab = getTabsSnapshot().find((candidate) => candidate.id === tabId);\n if (tab) removeTabHandlerRef.current(tab);\n },\n });\n\n useImperativeHandle(ref, () => handleRef.current, []);\n useAgentRegistration(dataTableTabsAgent, handleRef.current, id);\n\n /* -- render ----------------------------------------------------------- */\n const activeTriggerId = `${baseId}-tab-${activeTabId}`;\n\n return (\n <div\n ref={rootRef}\n data-component=\"data-table-tabs\"\n data-component-id={id}\n className={cx('ds:flex ds:min-w-0 ds:flex-col', className)}\n >\n <Popover.Root\n open={renamingId !== null}\n onOpenChange={(open) => {\n if (!open) cancelRename();\n }}\n >\n <TabsPrimitive.Root\n value={activeTabId}\n onValueChange={selectTab}\n orientation=\"horizontal\"\n activationMode=\"manual\"\n dir={dir}\n >\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-2xs)]\">\n <TabsPrimitive.List\n aria-label={ariaLabel ?? t('dataTableTabs.tablistLabel')}\n aria-describedby={hintId}\n className={cx(\n dataTableTabsListVariants({ size }),\n 'ds:min-w-0 ds:flex-initial',\n )}\n >\n {tabs.map((tab, index) => {\n const trigger = (\n <TabsPrimitive.Trigger\n key={tab.id}\n ref={(node) => {\n if (node) triggerRefs.current.set(tab.id, node);\n else triggerRefs.current.delete(tab.id);\n }}\n value={tab.id}\n id={`${baseId}-tab-${tab.id}`}\n aria-controls={panelId}\n data-tab-id={tab.id}\n className={cx(\n dataTableTabsTriggerVariants({ size }),\n // The leading tab sits flush in the panel's leading-top\n // corner: square that corner (and the grid's, below) so\n // the leading edge is one straight line with no cut-in.\n index === 0 && 'ds:[border-start-start-radius:0]',\n // Keyboard-only focus ring; in pointer mode suppress the\n // UA default outline that Radix's click-focus would show.\n keyboardNav\n ? FOCUS_RING\n : 'ds:focus-visible:outline-none',\n )}\n onKeyDown={(event) => handleTriggerKeyDown(event, tab)}\n onDoubleClick={() => openRename(tab)}\n >\n <span className=\"ds:max-w-[12rem] ds:truncate\">\n {tab.label}\n </span>\n {canRemove(tab) && (\n // Visual-only dismiss — pointer removal fires here;\n // keyboard removal is Delete/Backspace on the trigger.\n // No role/tabIndex: interactive content inside <button>\n // is invalid HTML (kit TabsTrigger precedent). Absolutely\n // positioned in the trailing padding and hidden until the\n // tab is hovered/focused or active, so it reserves no flow\n // space — every tab keeps the same symmetric padding\n // whether or not it can be removed, and labels never\n // reflow when it reveals.\n <span\n aria-hidden=\"true\"\n className={cx(\n 'ds:absolute ds:end-[var(--spacing-2xs)] ds:top-1/2 ds:-translate-y-1/2',\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:size-3.5 ds:rounded-[var(--radius-sm)]',\n 'ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none',\n 'ds:group-hover:opacity-100 ds:group-focus-visible:opacity-100',\n 'ds:group-data-[state=active]:opacity-100',\n 'ds:hover:bg-muted-foreground/20',\n )}\n onPointerDown={(event) => {\n event.stopPropagation();\n event.preventDefault();\n handleRemove(tab);\n }}\n >\n <X className=\"ds:size-3\" />\n </span>\n )}\n </TabsPrimitive.Trigger>\n );\n return renamingId === tab.id ? (\n <Popover.Anchor asChild key={tab.id}>\n {trigger}\n </Popover.Anchor>\n ) : (\n trigger\n );\n })}\n </TabsPrimitive.List>\n {allowAdd && (\n <IconButton\n intent=\"ghost\"\n size=\"sm\"\n icon={<Plus aria-hidden=\"true\" />}\n tooltip={\n atCapacity\n ? t('dataTableTabs.maxTabsReached')\n : t('dataTableTabs.addTab')\n }\n disabled={atCapacity}\n className=\"ds:mb-[var(--spacing-2xs)] ds:shrink-0\"\n onClick={handleAdd}\n />\n )}\n </div>\n\n {/* ONE stable tabpanel — the grid never remounts on tab switch.\n Square the nested AG-Grid wrapper's leading-top corner so it lines\n up flush under the leading tab instead of curving in beneath it.\n The selector no-ops for non-AG table regions. */}\n <div\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={activeTriggerId}\n className=\"ds:min-w-0 ds:[&_.ag-root-wrapper]:[border-start-start-radius:0]\"\n >\n {children}\n </div>\n </TabsPrimitive.Root>\n\n {/* Rename editor — sibling of the tablist, anchored to the renaming\n trigger via Popover.Anchor (never a Popover.Trigger on a tab). */}\n <Popover.Content\n side=\"bottom\"\n align=\"start\"\n aria-label={t('dataTableTabs.rename.title')}\n className=\"ds:w-64\"\n onCloseAutoFocus={(event) => {\n // Return focus to the (possibly freshly-added) tab trigger so\n // keyboard users don't land back on the \"+\" button.\n event.preventDefault();\n if (renamingTab) focusTrigger(renamingTab.id);\n else if (activeTabId) focusTrigger(activeTabId);\n }}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n renameInputRef.current?.focus();\n renameInputRef.current?.select();\n }}\n >\n <form\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]\"\n onSubmit={(event) => {\n event.preventDefault();\n commitRename();\n }}\n >\n <TextInput\n ref={renameInputRef}\n size=\"sm\"\n aria-label={t('dataTableTabs.rename.inputLabel')}\n defaultValue={renamingTab?.label ?? ''}\n maxLength={60}\n className=\"ds:min-w-0 ds:flex-1\"\n />\n <IconButton\n type=\"submit\"\n intent=\"ghost\"\n size=\"sm\"\n icon={<Check aria-hidden=\"true\" />}\n tooltip={t('dataTableTabs.rename.save')}\n />\n <IconButton\n type=\"button\"\n intent=\"ghost\"\n size=\"sm\"\n icon={<X aria-hidden=\"true\" />}\n tooltip={t('dataTableTabs.rename.cancel')}\n onClick={cancelRename}\n />\n </form>\n </Popover.Content>\n </Popover.Root>\n\n {/* Keyboard hint for the tablist (aria-describedby target). */}\n <span id={hintId} className=\"ds:sr-only\">\n {t('dataTableTabs.hint')}\n </span>\n {/* Live region for add/remove/rename announcements. */}\n <span role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {announcement}\n </span>\n </div>\n );\n});\n\nDataTableTabs.displayName = 'DataTableTabs';\n\nexport type { SavedTab, DataTableTabsGridSeam };\n"],"names":["dataTableTabsAgent","handle","id","label","args","fallbackCounter","defaultMakeTabId","isPlainObject","value","isValidEnvelope","tab","useDataTableFilterTabs","options","getTable","tabsProp","defaultTabs","onTabsChange","activeTabIdProp","defaultActiveTabId","onActiveTabChange","persistKey","captureQuickFilter","applyOnActivate","maxTabs","createTab","makeTabId","t","useTranslation","isControlled","seed","useMemo","persistedTabs","raw","parsed","tabsState","setTabsState","useControllableState","tabs","setTabs","useCallback","update","next","tabsRef","envelope","activeIdState","setActiveIdState","_a","activeTabId","_b","useRef","activeIdRef","applyingRef","getTableRef","captureIntoActive","seam","model","quick","prev","applyTab","api","useEffect","cleanup","handler","wire","active","timer","late","selectTab","addTab","filterModel","index","fresh","renameTab","trimmed","removeTab","current","target","neighbour","getTabsSnapshot","getActiveTabIdSnapshot","dataTableTabsListVariants","cva","dataTableTabsTriggerVariants","FOCUS_RING","useKeyboardModality","keyboard","setKeyboard","useState","onKey","k","onPointer","DataTableTabs","forwardRef","allowAdd","allowRename","allowRemove","renameOnAdd","size","className","ariaLabel","children","ref","rootRef","dir","useDirection","keyboardNav","baseId","useId","panelId","hintId","atCapacity","renamingId","setRenamingId","renameInputRef","renamingTab","announcement","setAnnouncement","triggerRefs","focusTrigger","tabId","canRename","canRemove","openRename","commitRename","cancelRename","handleAdd","newId","handleRemove","candidate","handleTriggerKeyDown","event","selectTabRef","addTabRef","renameTabRef","removeTabHandlerRef","handleRef","useImperativeHandle","useAgentRegistration","activeTriggerId","jsxs","cx","Popover","open","TabsPrimitive","jsx","trigger","node","X","IconButton","Plus","TextInput","Check"],"mappings":"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"}
1
+ {"version":3,"file":"data-table-tabs-C1kRUzat.js","sources":["../../src/components/data-table-tabs/data-table-tabs.agent.ts","../../src/components/data-table-tabs/use-data-table-filter-tabs.ts","../../src/components/data-table-tabs/data-table-tabs.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — DataTableTabs. */\n/* */\n/* Operations work against the curated `DataTableTabsHandle` (saved-filter */\n/* tab strip). Tab ids are opaque machine ids — labels are display-only. */\n/* See `src/docs/26-agent-readiness.mdx`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DataTableTabsHandle } from './data-table-tabs';\n\nexport const dataTableTabsAgent: AgentAdapter<DataTableTabsHandle> = {\n id: 'data-table-tabs',\n capabilities: ['select_single', 'view_change'],\n state: {\n activeTabId: {\n type: 'string | null',\n descriptionKey: 'ui.agent.dataTableTabs.state.activeTabId',\n description: 'Id of the currently-active saved-filter tab.',\n read: (handle) => handle.getActiveTabId(),\n },\n tabs: {\n type: 'Array<{ id, label }>',\n descriptionKey: 'ui.agent.dataTableTabs.state.tabs',\n description: 'The saved-filter tabs, in strip order (ids + labels).',\n read: (handle) =>\n handle.getTabs().map(({ id, label }) => ({ id, label })),\n },\n },\n actions: {\n select_tab: {\n // Applies a saved filter model — a view change, like apply_filter.\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to activate.' },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.selectTab',\n description:\n 'Activate a saved-filter tab: snapshots the outgoing tab, applies the incoming filter model to the table.',\n invoke: (handle, args: { id: string }) => {\n handle.selectTab(args.id);\n },\n },\n get_tabs: {\n safety: 'read',\n returns: 'Array<{ id: string, label: string }>',\n returnsSchema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n label: { type: 'string' },\n },\n required: ['id', 'label'],\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.getTabs',\n description: 'Return the saved-filter tabs (ids + labels) in order.',\n invoke: (handle) =>\n handle.getTabs().map(({ id, label }) => ({ id, label })),\n },\n add_tab: {\n safety: 'write',\n argsType: '{ label?: string }',\n argsSchema: {\n type: 'object',\n properties: {\n label: {\n type: 'string',\n description:\n 'Display name for the new tab. Defaults to a numbered name.',\n },\n },\n required: [],\n },\n idempotent: false,\n descriptionKey: 'ui.agent.dataTableTabs.actions.addTab',\n description:\n \"Add a new tab capturing the table's current filter model, and activate it. Returns the new tab id.\",\n returns: 'string',\n returnsSchema: { type: 'string' },\n invoke: (handle, args: { label?: string }) => handle.addTab(args.label),\n },\n rename_tab: {\n safety: 'write',\n argsType: '{ id: string, label: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to rename.' },\n label: { type: 'string', description: 'New display name.' },\n },\n required: ['id', 'label'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.renameTab',\n description:\n 'Rename a saved-filter tab. No-op on locked tabs and empty labels.',\n invoke: (handle, args: { id: string; label: string }) => {\n handle.renameTab(args.id, args.label);\n },\n },\n remove_tab: {\n // Removes a saved filter permanently — destructive, do not downgrade.\n safety: 'destructive',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Tab id to remove.' },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dataTableTabs.actions.removeTab',\n description:\n 'Remove a saved-filter tab (its saved filter is lost). No-op on locked tabs and the last remaining tab.',\n invoke: (handle, args: { id: string }) => {\n handle.removeTab(args.id);\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'data-table-tabs' },\n instanceId: { attr: 'data-component-id', sourceProp: 'id' },\n item: { attr: 'data-tab-id' },\n },\n};\n","/**\n * use-data-table-filter-tabs — headless sync engine for DataTableTabs.\n * ----------------------------------------------------------------------------\n * Owns the tabs array + active tab id and keeps the grid's AG Grid filter\n * model in lock-step with the active tab. The grid is a PROJECTION of the\n * active tab; the hook is the single owner of tab state.\n *\n * Four flows, all through `getTable()` resolved at call time (never held):\n *\n * 1. SUBSCRIBE-LATE — the grid api resolves after mount (ToolbarProvider\n * convention), so a mount effect polls a 50 ms interval until\n * `getTable()?.getRawApi()` resolves, then attaches a `filterChanged`\n * listener (FilterChips precedent — a one-shot `if (!api) return` would\n * bail permanently and never capture).\n * 2. CAPTURE — tabs are LIVE views: every user/host filter edit is written\n * into the active tab. The listener skips ONLY while `applyingRef` is set\n * (our own restore). It deliberately does NOT filter on\n * `event.source === 'api'`: external programmatic `setFilter` calls (page\n * warning actions, the data-table agent) are user intent and must land in\n * the active tab.\n * 3. RESTORE — activating a tab snapshots the outgoing tab defensively, then\n * applies the incoming model under the `applyingRef` guard and calls\n * `api.onFilterChanged()` so floating filters / chips / agents refresh\n * (ViewSwitcher precedent — `setFilterModel` alone doesn't re-run\n * listeners).\n * 4. INITIAL APPLY — when `applyOnActivate`, the active tab's model applies\n * once as soon as the api resolves (the patients FilteredView-proven\n * poll-then-set path; `firstDataRendered` gating is forbidden — zero-row\n * grids may never fire it).\n *\n * Persistence is opt-in via `persistKey` → `data-table-tabs:<persistKey>`\n * with a versioned envelope; the active tab id is deliberately NOT persisted\n * so a restored session lands on the first tab instead of silently\n * re-applying a stale aggressive filter.\n */\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { GridApi } from 'ag-grid-community';\nimport { useControllableState } from '../../hooks/use-controllable-state';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** One saved-filter tab. */\nexport interface SavedTab {\n /** Opaque machine-generated id — emitted as `data-tab-id`, never the label. */\n id: string;\n /** User-typed name; rendered text only — never used in DOM hooks or keys. */\n label: string;\n /** AG Grid filter model (`DataTableHandle.getFilter()` shape); `{}` = none. */\n filterModel: Record<string, unknown>;\n /** Captured quick-filter text — only present when `captureQuickFilter`. */\n quickFilter?: string;\n /** Locked tabs cannot be renamed or removed (e.g. an \"All\" tab). */\n locked?: boolean;\n}\n\n/**\n * The narrow grid seam the tabs ride on. Structural, and `getRawApi` is\n * deliberately typed against the un-parameterised `GridApi` so any\n * `DataTableHandle<TData>` (incl. `PatientTableHandle`) satisfies it —\n * `GridApi<TData>` is invariant, so pinning a row type here would reject\n * every concretely-typed handle.\n */\nexport interface DataTableTabsGridSeam {\n getFilter: () => Record<string, unknown>;\n setFilter: (model: Record<string, unknown>) => void;\n getRawApi: () => GridApi | undefined;\n}\n\nexport interface UseDataTableFilterTabsOptions {\n /** Resolve the grid seam at call time — `undefined` until grid-ready. */\n getTable: () => DataTableTabsGridSeam | null | undefined;\n tabs?: SavedTab[];\n defaultTabs?: SavedTab[];\n onTabsChange?: (tabs: SavedTab[]) => void;\n activeTabId?: string;\n defaultActiveTabId?: string;\n onActiveTabChange?: (id: string) => void;\n /** Opt-in localStorage persistence — disabled while `tabs` is controlled. */\n persistKey?: string;\n /** Capture/restore `quickFilterText` alongside the model. Default false. */\n captureQuickFilter?: boolean;\n /** Apply the active tab's model on mount + tab switch. Default true. */\n applyOnActivate?: boolean;\n /** Cap on the number of tabs. Default 8. */\n maxTabs?: number;\n /** Factory for a new tab; `index` is 1-based (used for the default name). */\n createTab?: (index: number) => SavedTab;\n /** Id factory — default `crypto.randomUUID()` with a counter fallback. */\n makeTabId?: () => string;\n}\n\nexport interface UseDataTableFilterTabsResult {\n tabs: SavedTab[];\n activeTabId: string;\n selectTab: (id: string) => void;\n addTab: (label?: string, filterModel?: Record<string, unknown>) => string;\n renameTab: (id: string, label: string) => void;\n removeTab: (id: string) => void;\n atCapacity: boolean;\n /** Synchronous snapshots for the imperative handle / agent adapter —\n * fresh immediately after a mutation, before React re-renders. */\n getTabsSnapshot: () => SavedTab[];\n getActiveTabIdSnapshot: () => string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nlet fallbackCounter = 0;\n\nfunction defaultMakeTabId(): string {\n try {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID();\n }\n } catch {\n /* noop — fall through to the counter */\n }\n fallbackCounter += 1;\n return `tab-${fallbackCounter}`;\n}\n\n/** Versioned persistence envelope — mirrors the col-state loader's guards. */\ninterface PersistEnvelope {\n v: 1;\n tabs: SavedTab[];\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) !== null\n );\n}\n\nfunction isValidEnvelope(value: unknown): value is PersistEnvelope {\n if (!isPlainObject(value) || value.v !== 1 || !Array.isArray(value.tabs)) {\n return false;\n }\n return (value.tabs as unknown[]).every(\n (tab) =>\n isPlainObject(tab) &&\n typeof tab.id === 'string' &&\n typeof tab.label === 'string' &&\n isPlainObject(tab.filterModel),\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\nexport function useDataTableFilterTabs(\n options: UseDataTableFilterTabsOptions,\n): UseDataTableFilterTabsResult {\n const {\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter = false,\n applyOnActivate = true,\n maxTabs = 8,\n createTab,\n makeTabId = defaultMakeTabId,\n } = options;\n\n const { t } = useTranslation();\n\n const isControlled = tabsProp !== undefined;\n if (import.meta.env.DEV && isControlled && persistKey) {\n // eslint-disable-next-line no-console\n console.warn(\n 'DataTableTabs: `persistKey` is ignored while `tabs` is controlled — persist from `onTabsChange` instead.',\n );\n }\n\n // Uncontrolled seed: defaultTabs, else one unfiltered tab.\n const seed = useMemo<SavedTab[]>(() => {\n if (defaultTabs && defaultTabs.length > 0) return defaultTabs;\n return [\n {\n id: 'default',\n label: t('dataTableTabs.newTabName', { number: 1 }),\n filterModel: {},\n },\n ];\n // The seed is computed once for the uncontrolled path; label language at\n // mount time is acceptable for a user-renameable default.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Persistence backs the UNCONTROLLED state only. The envelope validates on\n // load; any mismatch falls back to the seed. Read once, on mount.\n const persistedTabs = useMemo<SavedTab[] | null>(() => {\n if (!persistKey || isControlled || typeof window === 'undefined') {\n return null;\n }\n try {\n const raw = window.localStorage.getItem(`data-table-tabs:${persistKey}`);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n return isValidEnvelope(parsed) ? parsed.tabs : null;\n } catch {\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const [tabsState, setTabsState] = useControllableState<SavedTab[]>({\n value: tabsProp,\n defaultValue: persistedTabs ?? seed,\n onChange: onTabsChange,\n });\n const tabs = useMemo(() => tabsState ?? seed, [tabsState, seed]);\n\n // Mirror every uncontrolled tabs write into storage synchronously\n // (crash-safe — no effect lag). The ref also updates synchronously so\n // successive same-tick writes compose instead of both reading the\n // pre-render snapshot.\n const setTabs = useCallback(\n (update: (prev: SavedTab[]) => SavedTab[]) => {\n const next = update(tabsRef.current);\n tabsRef.current = next;\n setTabsState(next);\n if (persistKey && !isControlled) {\n try {\n const envelope: PersistEnvelope = { v: 1, tabs: next };\n window.localStorage.setItem(\n `data-table-tabs:${persistKey}`,\n JSON.stringify(envelope),\n );\n } catch {\n // localStorage may be unavailable in some environments\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [setTabsState, persistKey, isControlled],\n );\n\n const [activeIdState, setActiveIdState] = useControllableState<string>({\n value: activeTabIdProp,\n defaultValue: defaultActiveTabId ?? tabs[0]?.id ?? 'default',\n onChange: onActiveTabChange,\n });\n const activeTabId = activeIdState ?? tabs[0]?.id ?? 'default';\n\n /* -- refs mirroring the latest state for event handlers ------------ */\n const tabsRef = useRef(tabs);\n tabsRef.current = tabs;\n const activeIdRef = useRef(activeTabId);\n activeIdRef.current = activeTabId;\n /** True while the hook itself is writing the grid's filter model. */\n const applyingRef = useRef(false);\n const getTableRef = useRef(getTable);\n getTableRef.current = getTable;\n\n /* -- CAPTURE: write the live model into the active tab ------------- */\n const captureIntoActive = useCallback(() => {\n const seam = getTableRef.current();\n if (!seam) return;\n const model = seam.getFilter() ?? {};\n const quick = captureQuickFilter\n ? ((): string | undefined => {\n const raw = seam.getRawApi()?.getGridOption('quickFilterText');\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined;\n })()\n : undefined;\n setTabs((prev) =>\n prev.map((tab) =>\n tab.id === activeIdRef.current\n ? {\n ...tab,\n filterModel: model,\n ...(captureQuickFilter ? { quickFilter: quick } : {}),\n }\n : tab,\n ),\n );\n }, [captureQuickFilter, setTabs]);\n\n /* -- RESTORE: apply a tab's model to the grid ----------------------- */\n const applyTab = useCallback(\n (tab: SavedTab | undefined) => {\n if (!tab) return;\n const seam = getTableRef.current();\n if (!seam) return;\n applyingRef.current = true;\n try {\n seam.setFilter(tab.filterModel ?? {});\n const api = seam.getRawApi();\n if (captureQuickFilter) {\n api?.setGridOption('quickFilterText', tab.quickFilter ?? '');\n }\n // Re-run filtering + notify listeners (floating filters, chips, agent\n // state) — setFilterModel alone does not.\n api?.onFilterChanged();\n } finally {\n // AG Grid dispatches filterChanged synchronously, so a synchronous\n // clear is exact: a host setFilter one tick later is never swallowed.\n // If a grid path ever fires async, the stray capture writes back the\n // model we just applied — idempotent, harmless.\n applyingRef.current = false;\n }\n },\n [captureQuickFilter],\n );\n\n /* -- SUBSCRIBE-LATE + INITIAL APPLY --------------------------------- */\n useEffect(() => {\n let cleanup: (() => void) | undefined;\n const handler = () => {\n if (applyingRef.current) return;\n captureIntoActive();\n };\n const wire = (seam: DataTableTabsGridSeam) => {\n const api = seam.getRawApi();\n if (!api) return false;\n api.addEventListener('filterChanged', handler);\n cleanup = () => api.removeEventListener('filterChanged', handler);\n if (applyOnActivate) {\n const active = tabsRef.current.find(\n (tab) => tab.id === activeIdRef.current,\n );\n if (\n active &&\n (Object.keys(active.filterModel ?? {}).length > 0 ||\n (captureQuickFilter && active.quickFilter))\n ) {\n applyTab(active);\n }\n }\n return true;\n };\n const seam = getTableRef.current();\n if (seam && wire(seam)) return () => cleanup?.();\n // Grid not ready yet — poll until it is (never bail one-shot).\n const timer = window.setInterval(() => {\n const late = getTableRef.current();\n if (!late) return;\n if (wire(late)) window.clearInterval(timer);\n }, 50);\n return () => {\n window.clearInterval(timer);\n cleanup?.();\n };\n }, [applyOnActivate, applyTab, captureIntoActive, captureQuickFilter]);\n\n /* -- public reducers ------------------------------------------------ */\n\n const selectTab = useCallback(\n (id: string) => {\n if (id === activeIdRef.current) return;\n const next = tabsRef.current.find((tab) => tab.id === id);\n if (!next) return;\n // Defensive final snapshot of the outgoing tab — quickFilter has no\n // model event, so this is its only reliable capture point.\n captureIntoActive();\n setActiveIdState(id);\n activeIdRef.current = id;\n if (applyOnActivate) applyTab(next);\n },\n [applyOnActivate, applyTab, captureIntoActive, setActiveIdState],\n );\n\n const addTab = useCallback(\n (label?: string, filterModel?: Record<string, unknown>): string => {\n if (tabsRef.current.length >= maxTabs) return activeIdRef.current;\n const index = tabsRef.current.length + 1;\n const fresh: SavedTab = createTab\n ? createTab(index)\n : {\n id: makeTabId(),\n label: label ?? t('dataTableTabs.newTabName', { number: index }),\n // New tab = copy of the CURRENT live model, so the grid view does\n // not jump on add — the natural gesture is \"save my current\n // filter as a tab\".\n filterModel:\n filterModel ?? getTableRef.current()?.getFilter() ?? {},\n };\n setTabs((prev) => [...prev, fresh]);\n setActiveIdState(fresh.id);\n activeIdRef.current = fresh.id;\n return fresh.id;\n },\n [createTab, makeTabId, maxTabs, setActiveIdState, setTabs, t],\n );\n\n const renameTab = useCallback(\n (id: string, label: string) => {\n const trimmed = label.trim();\n if (!trimmed) return;\n setTabs((prev) =>\n prev.map((tab) =>\n tab.id === id && !tab.locked ? { ...tab, label: trimmed } : tab,\n ),\n );\n },\n [setTabs],\n );\n\n const removeTab = useCallback(\n (id: string) => {\n const current = tabsRef.current;\n const target = current.find((tab) => tab.id === id);\n if (!target || target.locked || current.length <= 1) return;\n const index = current.findIndex((tab) => tab.id === id);\n const next = current.filter((tab) => tab.id !== id);\n setTabs(() => next);\n if (activeIdRef.current === id) {\n // Activate the inline-start neighbour (else the next one) and apply\n // its model so the grid never shows a removed tab's filter.\n const neighbour = next[Math.max(0, index - 1)];\n if (neighbour) {\n setActiveIdState(neighbour.id);\n activeIdRef.current = neighbour.id;\n if (applyOnActivate) applyTab(neighbour);\n }\n }\n },\n [applyOnActivate, applyTab, setActiveIdState, setTabs],\n );\n\n const getTabsSnapshot = useCallback(() => tabsRef.current, []);\n const getActiveTabIdSnapshot = useCallback(() => activeIdRef.current, []);\n\n return {\n tabs,\n activeTabId,\n selectTab,\n addTab,\n renameTab,\n removeTab,\n atCapacity: tabs.length >= maxTabs,\n getTabsSnapshot,\n getActiveTabIdSnapshot,\n };\n}\n","/**\n * DataTableTabs — saved-filter folder tabs for any kit DataTable.\n * ----------------------------------------------------------------------------\n * A folder-tab strip attached above a table region. Each tab captures and\n * restores its own AG Grid filter model (tabs are LIVE views — any filter\n * edit rewrites the active tab); a \"+\" button saves the current filter as a\n * new tab; tabs rename via double-click / F2 and remove via Delete/Backspace\n * or the pointer-only ✕.\n *\n * ARIA: a real APG tablist built on Radix Tabs primitives with\n * `activationMode=\"manual\"` (arrow keys rove without applying filter models;\n * Enter/Space activates). Every trigger points at ONE stable hand-rolled\n * tabpanel that wraps `children` — the grid never remounts on tab switch and\n * no dangling ARIA refs exist. The \"+\" button and the rename editor are\n * SIBLINGS of the tablist (tablist purity).\n *\n * Grid wiring rides the narrow `DataTableTabsGridSeam` resolved at call time\n * (`getTable={() => tableRef.current}`) — see use-data-table-filter-tabs.ts\n * for the sync engine. Works against any `DataTableHandle`-shaped ref,\n * including `PatientTableHandle`.\n */\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\nimport { cva, cx, type VariantProps } from 'class-variance-authority';\nimport { Check, Plus, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { IconButton } from '../button/icon-button';\nimport { Popover } from '../popover';\nimport { TextInput } from '../text-input';\nimport { useDirection } from '../../hooks/use-direction';\nimport { useAgentRegistration } from '../../agent';\nimport { dataTableTabsAgent } from './data-table-tabs.agent';\nimport {\n useDataTableFilterTabs,\n type DataTableTabsGridSeam,\n type SavedTab,\n} from './use-data-table-filter-tabs';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nexport const dataTableTabsListVariants = cva(\n [\n // The strip scrolls horizontally when tabs overflow; focusable tabs inside\n // (with an inset focus ring, below) satisfy scrollable-region-focusable.\n // No baseline border and no leading padding: the first tab sits flush with\n // the table's inline-start edge and the active tab merges straight into the\n // grid header below — the table's own rounded top is the only edge drawn.\n 'ds:flex ds:items-end ds:gap-[var(--spacing-2xs)] ds:overflow-x-auto',\n 'ds:pe-[var(--spacing-2xs)]',\n ].join(' '),\n {\n variants: {\n size: {\n md: '',\n lg: '',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nexport const dataTableTabsTriggerVariants = cva(\n [\n // `group` so the pointer-only ✕ can reveal on hover/focus/active; `relative`\n // so that ✕ can be absolutely positioned in the trailing padding (below).\n 'ds:group ds:relative ds:inline-flex ds:items-center ds:justify-center',\n 'ds:whitespace-nowrap ds:select-none ds:cursor-pointer ds:shrink-0',\n // Logical top corners so the leading corner can be squared in either text\n // direction (see the first-tab override + the grid corner below). Inactive\n // tabs take a crisp white fill so they read clearly against a warm page\n // instead of dissolving into it; muted text keeps them clearly unselected.\n // (Focus ring is INSET — see FOCUS_RING — so the scroll container never\n // clips it and the flush-leading first tab keeps its ring.)\n 'ds:[border-start-start-radius:var(--radius-md)] ds:[border-start-end-radius:var(--radius-md)]',\n 'ds:bg-background ds:text-muted-foreground',\n // Match the grid header's eyebrow treatment (uppercase, tracked, medium):\n // the strip reads as one unit with the header below. `text-transform` is\n // display-only — the stored label keeps its case for the rename editor, and\n // uppercase is a no-op on caseless scripts (Arabic, CJK).\n 'ds:font-medium ds:uppercase ds:tracking-[var(--letter-spacing-uppercase)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-muted/40 ds:hover:text-foreground',\n // NOTE: the focus ring is applied by the component (see FOCUS_RING), gated\n // on keyboard modality — Radix focuses the trigger on click, which would\n // otherwise show a `:focus-visible` ring on a plain mouse selection.\n // Active = the table header surface (`--muted`): a 1px downward pull fuses\n // it into one continuous grey sheet with the grid header below. That fuse\n // (grey fill + foreground text) is the whole selection cue — no accent bar.\n 'ds:data-[state=active]:bg-muted ds:data-[state=active]:text-foreground',\n 'ds:data-[state=active]:z-[1]',\n 'ds:data-[state=active]:[margin-block-end:-1px]',\n 'ds:disabled:pointer-events-none ds:disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n size: {\n // Symmetric inline padding so the label centres and every tab matches,\n // removable or not; the ✕ lives in the trailing padding (absolute).\n md: 'ds:h-10 ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-2xs)]',\n lg: 'ds:h-12 ds:ps-[var(--spacing-lg)] ds:pe-[var(--spacing-lg)] ds:text-[length:var(--font-size-xs)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\n/**\n * Inset keyboard focus ring — applied only while the user is navigating by\n * keyboard (see `useKeyboardModality`). Inset (offset negated) so the scroll\n * container never clips it and the flush-leading first tab keeps its ring.\n */\nconst FOCUS_RING =\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:[outline-offset:calc(-1*var(--focus-ring-width))]';\n\n/**\n * True while the last input was a keyboard, false after any pointer press.\n * Radix Tabs programmatically focuses a trigger on click, which makes Chrome\n * match `:focus-visible` even for a mouse selection; gating the ring on real\n * keyboard use restores the intended behaviour without losing keyboard focus\n * visibility. Document-level listeners catch the Tab press that moves focus\n * INTO the tablist (its target is outside this component's subtree).\n */\nfunction useKeyboardModality(): boolean {\n const [keyboard, setKeyboard] = useState(false);\n useEffect(() => {\n // Functional updates return the same value when unchanged, so React bails\n // out of re-rendering except on an actual modality transition.\n const onKey = () => setKeyboard((k) => k || true);\n const onPointer = () => setKeyboard((k) => (k ? false : k));\n document.addEventListener('keydown', onKey, true);\n document.addEventListener('pointerdown', onPointer, true);\n return () => {\n document.removeEventListener('keydown', onKey, true);\n document.removeEventListener('pointerdown', onPointer, true);\n };\n }, []);\n return keyboard;\n}\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Curated imperative handle — also the agent-adapter surface. */\nexport interface DataTableTabsHandle {\n getTabs: () => SavedTab[];\n getActiveTabId: () => string | null;\n /** Snapshots the outgoing tab, applies the incoming tab's filter model. */\n selectTab: (id: string) => void;\n /** Default model = a copy of the current live model (grid view unchanged). */\n addTab: (label?: string, filterModel?: Record<string, unknown>) => string;\n /** No-op on locked tabs and empty/whitespace labels. */\n renameTab: (id: string, label: string) => void;\n /** No-op on locked tabs and the last remaining tab. */\n removeTab: (id: string) => void;\n}\n\nexport interface DataTableTabsProps extends VariantProps<\n typeof dataTableTabsTriggerVariants\n> {\n /**\n * Resolve the grid seam at call time — `undefined` until the grid is ready\n * (same convention as `ToolbarProvider.getApi`). Any `DataTableHandle`\n * satisfies it: `getTable={() => tableRef.current}`.\n */\n getTable: () => DataTableTabsGridSeam | null | undefined;\n /** Controlled tabs — pair with `onTabsChange`. */\n tabs?: SavedTab[];\n /** Uncontrolled seed. Default: one unfiltered tab. */\n defaultTabs?: SavedTab[];\n onTabsChange?: (tabs: SavedTab[]) => void;\n activeTabId?: string;\n defaultActiveTabId?: string;\n onActiveTabChange?: (id: string) => void;\n /**\n * Opt-in localStorage persistence under `data-table-tabs:<persistKey>`.\n * Ignored (with a DEV warning) while `tabs` is controlled. The active tab\n * id is deliberately not persisted.\n */\n persistKey?: string;\n /** Capture/restore the quick-filter text alongside the model. Default false. */\n captureQuickFilter?: boolean;\n /** Apply the active tab's model on mount + switch. Default true. */\n applyOnActivate?: boolean;\n /** Show the \"+\" button. Default true. */\n allowAdd?: boolean;\n /** Allow rename (double-click / F2 / popover editor). Default true. */\n allowRename?: boolean;\n /** Allow removal (Delete/Backspace / ✕). Default true. */\n allowRemove?: boolean;\n /** Tab cap — \"+\" disables at the cap. Default 8. */\n maxTabs?: number;\n /** Factory for new tabs; `index` is 1-based. */\n createTab?: (index: number) => SavedTab;\n /** Id factory — default `crypto.randomUUID()`. */\n makeTabId?: () => string;\n /** Open the rename editor on a freshly-added tab. Default true. */\n renameOnAdd?: boolean;\n /** `data-component-id` + agent instance id. */\n id?: string;\n className?: string;\n /** Accessible tablist name — defaults to the localised \"Saved views\". */\n 'aria-label'?: string;\n /** The table region — rendered inside the single stable tabpanel. */\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DataTableTabs = forwardRef<\n DataTableTabsHandle,\n DataTableTabsProps\n>(function DataTableTabs(\n {\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter = false,\n applyOnActivate = true,\n allowAdd = true,\n allowRename = true,\n allowRemove = true,\n maxTabs = 8,\n createTab,\n makeTabId,\n renameOnAdd = true,\n size = 'md',\n id,\n className,\n 'aria-label': ariaLabel,\n children,\n },\n ref,\n) {\n const { t } = useTranslation();\n const rootRef = useRef<HTMLDivElement>(null);\n const dir = useDirection(rootRef);\n const keyboardNav = useKeyboardModality();\n const baseId = useId();\n const panelId = `${baseId}-panel`;\n const hintId = `${baseId}-hint`;\n\n const {\n tabs,\n activeTabId,\n selectTab,\n addTab,\n renameTab,\n removeTab,\n atCapacity,\n getTabsSnapshot,\n getActiveTabIdSnapshot,\n } = useDataTableFilterTabs({\n getTable,\n tabs: tabsProp,\n defaultTabs,\n onTabsChange,\n activeTabId: activeTabIdProp,\n defaultActiveTabId,\n onActiveTabChange,\n persistKey,\n captureQuickFilter,\n applyOnActivate,\n maxTabs,\n createTab,\n makeTabId,\n });\n\n /* -- rename editor state -------------------------------------------- */\n const [renamingId, setRenamingId] = useState<string | null>(null);\n const renameInputRef = useRef<HTMLInputElement>(null);\n const renamingTab = tabs.find((tab) => tab.id === renamingId);\n\n /* -- announcements (sr-only live region) ----------------------------- */\n const [announcement, setAnnouncement] = useState('');\n useEffect(() => {\n if (!announcement) return;\n const timer = setTimeout(() => setAnnouncement(''), 3000);\n return () => clearTimeout(timer);\n }, [announcement]);\n\n /* -- focus management ------------------------------------------------ */\n const triggerRefs = useRef(new Map<string, HTMLButtonElement>());\n const focusTrigger = useCallback((tabId: string) => {\n // After a state flush — the trigger may have just (un)mounted.\n requestAnimationFrame(() => {\n triggerRefs.current.get(tabId)?.focus();\n });\n }, []);\n\n const canRename = useCallback(\n (tab: SavedTab) => allowRename && !tab.locked,\n [allowRename],\n );\n const canRemove = useCallback(\n (tab: SavedTab) => allowRemove && !tab.locked && tabs.length > 1,\n [allowRemove, tabs.length],\n );\n\n const openRename = useCallback(\n (tab: SavedTab) => {\n if (!canRename(tab)) return;\n setRenamingId(tab.id);\n },\n [canRename],\n );\n\n const commitRename = useCallback(() => {\n if (renamingId) {\n const value = renameInputRef.current?.value ?? '';\n if (value.trim()) {\n renameTab(renamingId, value);\n setAnnouncement(\n t('dataTableTabs.announce.renamed', { name: value.trim() }),\n );\n }\n }\n setRenamingId(null);\n }, [renamingId, renameTab, t]);\n\n const cancelRename = useCallback(() => setRenamingId(null), []);\n\n const handleAdd = useCallback(() => {\n // Mirror the hook's default naming — state hasn't flushed yet, so the\n // fresh tab isn't in `tabs` at announce time.\n const label = t('dataTableTabs.newTabName', { number: tabs.length + 1 });\n const newId = addTab();\n setAnnouncement(t('dataTableTabs.announce.added', { name: label }));\n if (renameOnAdd && allowRename) {\n // The rename popover autofocuses its input; focusing the trigger too\n // would steal focus from it — the editor's onCloseAutoFocus returns\n // focus to the trigger instead.\n setRenamingId(newId);\n } else {\n focusTrigger(newId);\n }\n }, [addTab, allowRename, focusTrigger, renameOnAdd, t, tabs.length]);\n\n const handleRemove = useCallback(\n (tab: SavedTab) => {\n if (!canRemove(tab)) return;\n const index = tabs.findIndex((candidate) => candidate.id === tab.id);\n const neighbour = tabs.filter((candidate) => candidate.id !== tab.id)[\n Math.max(0, index - 1)\n ];\n removeTab(tab.id);\n setAnnouncement(t('dataTableTabs.announce.removed', { name: tab.label }));\n if (neighbour) focusTrigger(neighbour.id);\n },\n [canRemove, focusTrigger, removeTab, t, tabs],\n );\n\n const handleTriggerKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, tab: SavedTab) => {\n // APG dismissible-tab pattern: Delete/Backspace removes; F2 renames.\n // The visual ✕ is pointer-only (aria-hidden) to avoid nested-interactive.\n if (event.key === 'Delete' || event.key === 'Backspace') {\n event.preventDefault();\n handleRemove(tab);\n } else if (event.key === 'F2') {\n event.preventDefault();\n openRename(tab);\n }\n },\n [handleRemove, openRename],\n );\n\n /* -- curated handle + agent registration ----------------------------- */\n // Latest-value refs so the stable handle object never closes over stale\n // callbacks (DataTable handle precedent — stable identity, live reads).\n // Reads go through the hook's synchronous snapshots, so a mutation is\n // visible to the very next handle call, before React re-renders.\n const selectTabRef = useRef(selectTab);\n selectTabRef.current = selectTab;\n const addTabRef = useRef(addTab);\n addTabRef.current = addTab;\n const renameTabRef = useRef(renameTab);\n renameTabRef.current = renameTab;\n const removeTabHandlerRef = useRef(handleRemove);\n removeTabHandlerRef.current = handleRemove;\n\n const handleRef = useRef<DataTableTabsHandle>({\n getTabs: () => getTabsSnapshot(),\n getActiveTabId: () => getActiveTabIdSnapshot() ?? null,\n selectTab: (tabId) => selectTabRef.current(tabId),\n addTab: (label, filterModel) => addTabRef.current(label, filterModel),\n renameTab: (tabId, label) => renameTabRef.current(tabId, label),\n removeTab: (tabId) => {\n const tab = getTabsSnapshot().find((candidate) => candidate.id === tabId);\n if (tab) removeTabHandlerRef.current(tab);\n },\n });\n\n useImperativeHandle(ref, () => handleRef.current, []);\n useAgentRegistration(dataTableTabsAgent, handleRef.current, id);\n\n /* -- render ----------------------------------------------------------- */\n const activeTriggerId = `${baseId}-tab-${activeTabId}`;\n\n return (\n <div\n ref={rootRef}\n data-component=\"data-table-tabs\"\n data-component-id={id}\n className={cx('ds:flex ds:min-w-0 ds:flex-col', className)}\n >\n <Popover.Root\n open={renamingId !== null}\n onOpenChange={(open) => {\n if (!open) cancelRename();\n }}\n >\n <TabsPrimitive.Root\n value={activeTabId}\n onValueChange={selectTab}\n orientation=\"horizontal\"\n activationMode=\"manual\"\n dir={dir}\n >\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-2xs)]\">\n <TabsPrimitive.List\n aria-label={ariaLabel ?? t('dataTableTabs.tablistLabel')}\n aria-describedby={hintId}\n className={cx(\n dataTableTabsListVariants({ size }),\n 'ds:min-w-0 ds:flex-initial',\n )}\n >\n {tabs.map((tab, index) => {\n const trigger = (\n <TabsPrimitive.Trigger\n key={tab.id}\n ref={(node) => {\n if (node) triggerRefs.current.set(tab.id, node);\n else triggerRefs.current.delete(tab.id);\n }}\n value={tab.id}\n id={`${baseId}-tab-${tab.id}`}\n aria-controls={panelId}\n data-tab-id={tab.id}\n className={cx(\n dataTableTabsTriggerVariants({ size }),\n // The leading tab sits flush in the panel's leading-top\n // corner: square that corner (and the grid's, below) so\n // the leading edge is one straight line with no cut-in.\n index === 0 && 'ds:[border-start-start-radius:0]',\n // Keyboard-only focus ring; in pointer mode suppress the\n // UA default outline that Radix's click-focus would show.\n keyboardNav\n ? FOCUS_RING\n : 'ds:focus-visible:outline-none',\n )}\n onKeyDown={(event) => handleTriggerKeyDown(event, tab)}\n onDoubleClick={() => openRename(tab)}\n >\n <span className=\"ds:max-w-[12rem] ds:truncate\">\n {tab.label}\n </span>\n {canRemove(tab) && (\n // Visual-only dismiss — pointer removal fires here;\n // keyboard removal is Delete/Backspace on the trigger.\n // No role/tabIndex: interactive content inside <button>\n // is invalid HTML (kit TabsTrigger precedent). Absolutely\n // positioned in the trailing padding and hidden until the\n // tab is hovered/focused or active, so it reserves no flow\n // space — every tab keeps the same symmetric padding\n // whether or not it can be removed, and labels never\n // reflow when it reveals.\n <span\n aria-hidden=\"true\"\n className={cx(\n 'ds:absolute ds:end-[var(--spacing-2xs)] ds:top-1/2 ds:-translate-y-1/2',\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:size-3.5 ds:rounded-[var(--radius-sm)]',\n 'ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none',\n 'ds:group-hover:opacity-100 ds:group-focus-visible:opacity-100',\n 'ds:group-data-[state=active]:opacity-100',\n 'ds:hover:bg-muted-foreground/20',\n )}\n onPointerDown={(event) => {\n event.stopPropagation();\n event.preventDefault();\n handleRemove(tab);\n }}\n >\n <X className=\"ds:size-3\" />\n </span>\n )}\n </TabsPrimitive.Trigger>\n );\n return renamingId === tab.id ? (\n <Popover.Anchor asChild key={tab.id}>\n {trigger}\n </Popover.Anchor>\n ) : (\n trigger\n );\n })}\n </TabsPrimitive.List>\n {allowAdd && (\n <IconButton\n intent=\"ghost\"\n size=\"sm\"\n icon={<Plus aria-hidden=\"true\" />}\n tooltip={\n atCapacity\n ? t('dataTableTabs.maxTabsReached')\n : t('dataTableTabs.addTab')\n }\n disabled={atCapacity}\n className=\"ds:mb-[var(--spacing-2xs)] ds:shrink-0\"\n onClick={handleAdd}\n />\n )}\n </div>\n\n {/* ONE stable tabpanel — the grid never remounts on tab switch.\n Square the nested AG-Grid wrapper's leading-top corner so it lines\n up flush under the leading tab instead of curving in beneath it.\n The selector no-ops for non-AG table regions. */}\n <div\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={activeTriggerId}\n className=\"ds:min-w-0 ds:[&_.ag-root-wrapper]:[border-start-start-radius:0]\"\n >\n {children}\n </div>\n </TabsPrimitive.Root>\n\n {/* Rename editor — sibling of the tablist, anchored to the renaming\n trigger via Popover.Anchor (never a Popover.Trigger on a tab). */}\n <Popover.Content\n side=\"bottom\"\n align=\"start\"\n aria-label={t('dataTableTabs.rename.title')}\n className=\"ds:w-64\"\n onCloseAutoFocus={(event) => {\n // Return focus to the (possibly freshly-added) tab trigger so\n // keyboard users don't land back on the \"+\" button.\n event.preventDefault();\n if (renamingTab) focusTrigger(renamingTab.id);\n else if (activeTabId) focusTrigger(activeTabId);\n }}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n renameInputRef.current?.focus();\n renameInputRef.current?.select();\n }}\n >\n <form\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]\"\n onSubmit={(event) => {\n event.preventDefault();\n commitRename();\n }}\n >\n <TextInput\n ref={renameInputRef}\n size=\"sm\"\n aria-label={t('dataTableTabs.rename.inputLabel')}\n defaultValue={renamingTab?.label ?? ''}\n maxLength={60}\n className=\"ds:min-w-0 ds:flex-1\"\n />\n <IconButton\n type=\"submit\"\n intent=\"ghost\"\n size=\"sm\"\n icon={<Check aria-hidden=\"true\" />}\n tooltip={t('dataTableTabs.rename.save')}\n />\n <IconButton\n type=\"button\"\n intent=\"ghost\"\n size=\"sm\"\n icon={<X aria-hidden=\"true\" />}\n tooltip={t('dataTableTabs.rename.cancel')}\n onClick={cancelRename}\n />\n </form>\n </Popover.Content>\n </Popover.Root>\n\n {/* Keyboard hint for the tablist (aria-describedby target). */}\n <span id={hintId} className=\"ds:sr-only\">\n {t('dataTableTabs.hint')}\n </span>\n {/* Live region for add/remove/rename announcements. */}\n <span role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {announcement}\n </span>\n </div>\n );\n});\n\nDataTableTabs.displayName = 'DataTableTabs';\n\nexport type { SavedTab, DataTableTabsGridSeam };\n"],"names":["dataTableTabsAgent","handle","id","label","args","fallbackCounter","defaultMakeTabId","isPlainObject","value","isValidEnvelope","tab","useDataTableFilterTabs","options","getTable","tabsProp","defaultTabs","onTabsChange","activeTabIdProp","defaultActiveTabId","onActiveTabChange","persistKey","captureQuickFilter","applyOnActivate","maxTabs","createTab","makeTabId","t","useTranslation","isControlled","seed","useMemo","persistedTabs","raw","parsed","tabsState","setTabsState","useControllableState","tabs","setTabs","useCallback","update","next","tabsRef","envelope","activeIdState","setActiveIdState","_a","activeTabId","_b","useRef","activeIdRef","applyingRef","getTableRef","captureIntoActive","seam","model","quick","prev","applyTab","api","useEffect","cleanup","handler","wire","active","timer","late","selectTab","addTab","filterModel","index","fresh","renameTab","trimmed","removeTab","current","target","neighbour","getTabsSnapshot","getActiveTabIdSnapshot","dataTableTabsListVariants","cva","dataTableTabsTriggerVariants","FOCUS_RING","useKeyboardModality","keyboard","setKeyboard","useState","onKey","k","onPointer","DataTableTabs","forwardRef","allowAdd","allowRename","allowRemove","renameOnAdd","size","className","ariaLabel","children","ref","rootRef","dir","useDirection","keyboardNav","baseId","useId","panelId","hintId","atCapacity","renamingId","setRenamingId","renameInputRef","renamingTab","announcement","setAnnouncement","triggerRefs","focusTrigger","tabId","canRename","canRemove","openRename","commitRename","cancelRename","handleAdd","newId","handleRemove","candidate","handleTriggerKeyDown","event","selectTabRef","addTabRef","renameTabRef","removeTabHandlerRef","handleRef","useImperativeHandle","useAgentRegistration","activeTriggerId","jsxs","cx","Popover","open","TabsPrimitive","jsx","trigger","node","X","IconButton","Plus","TextInput","Check"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as V } from "react/jsx-runtime";
2
2
  import { forwardRef as c, useMemo as x, Children as C, isValidElement as T, useContext as R, useState as b, useCallback as j, createContext as P } from "react";
3
3
  import { c as m } from "./index-D2ZczOXr.js";
4
4
  import { useTranslation as z } from "react-i18next";
5
- import { I as A } from "./icon-button-9c9Gp41m.js";
5
+ import { I as A } from "./icon-button-DA2CAGHZ.js";
6
6
  import { C as S } from "./check-DrFSN__t.js";
7
7
  import { C as B } from "./copy-vRpqqHtY.js";
8
8
  function E(s) {
@@ -316,4 +316,4 @@ const Z = Object.assign(k, {
316
316
  export {
317
317
  Z as D
318
318
  };
319
- //# sourceMappingURL=description-list-Ck7fKdt5.js.map
319
+ //# sourceMappingURL=description-list-CjJqR8WK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"description-list-Ck7fKdt5.js","sources":["../../src/components/description-list/description-list.tsx"],"sourcesContent":["import {\n Children,\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useMemo,\n useState,\n type CSSProperties,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Copy, Check } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* labelWidth → label / value track resolver */\n/* */\n/* The `inline` / `responsive` layouts render a two- or three-column */\n/* grid (icon? · label · value · copy?). The label column's width is */\n/* parameterised so consumers can pick the right behaviour for the */\n/* surrounding container: */\n/* */\n/* - `auto` (default): label sizes to its intrinsic content; the */\n/* value column takes the remainder. Long labels wrap word-by-word */\n/* in narrow contexts instead of being squeezed into a 1fr column */\n/* that can collapse below the longest word. */\n/* - `fixed`: legacy ⅓ / ⅔ ratio (label `minmax(0,1fr)`, value */\n/* `minmax(0,2fr)`). Use for wide forms where consistent alignment */\n/* across rows is more important than fitting the longest label. */\n/* - any CSS length / track size (`'8rem'`, `'min-content'`, …): */\n/* forces the label column to that width. */\n/* */\n/* The resolved values are surfaced as `--description-list-label-track` */\n/* and `--description-list-value-track` on the root `<dl>` so each Row */\n/* can compose them with the icon / copy auto columns it needs. */\n/* ------------------------------------------------------------------ */\n\ntype LabelWidthPreset = 'auto' | 'fixed';\nexport type DescriptionListLabelWidth = LabelWidthPreset | (string & {});\n\nfunction resolveLabelTrack(labelWidth: DescriptionListLabelWidth): string {\n // `auto` uses `fit-content(50%)` rather than the bare `auto` keyword.\n // CSS `auto` resolves to `minmax(min-content, max-content)`, which can't\n // shrink the term column below the dt's max-content in a narrow container\n // (the failure mode booking-website hit with long Italian medical labels\n // in a 320 px Carousel slide). `fit-content(50%)` clamps to\n // `max(min-content, min(50%-of-container, max-content))`:\n // - in narrow containers it caps at 50 % of the row width, leaving the\n // other half for the detail column; the dt wraps at word boundaries\n // via `overflow-wrap: break-word`.\n // - in wide containers it expands to the dt's max-content, so short\n // labels don't stretch unnecessarily.\n if (labelWidth === 'auto') return 'fit-content(50%)';\n if (labelWidth === 'fixed') return 'minmax(0,1fr)';\n return labelWidth;\n}\n\nfunction resolveValueTrack(labelWidth: DescriptionListLabelWidth): string {\n return labelWidth === 'fixed' ? 'minmax(0,2fr)' : 'minmax(0,1fr)';\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\ninterface DescriptionListContextShape {\n layout: 'inline' | 'stacked' | 'responsive';\n density: 'default' | 'compact';\n divider: 'none' | 'between' | 'bordered';\n /**\n * True when at least one direct child Row was rendered with a\n * non-null `icon` prop. Every Row in the list then reserves a\n * leading icon column (rendering a `size-4` empty placeholder\n * when this row has no icon) so the grid's `auto` column resolves\n * to the same width across all rows and sibling Rows align.\n */\n hasIcons: boolean;\n}\n\nconst DescriptionListContext = createContext<DescriptionListContextShape>({\n layout: 'inline',\n density: 'default',\n divider: 'none',\n hasIcons: false,\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — root <dl> */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListVariants = cva('ds:flex ds:flex-col', {\n variants: {\n layout: {\n inline: '',\n stacked: '',\n responsive: '',\n },\n density: {\n default: 'ds:gap-[var(--spacing-md)]',\n compact: 'ds:gap-[var(--spacing-sm)]',\n },\n divider: {\n none: '',\n between: '',\n bordered: '',\n },\n },\n defaultVariants: {\n layout: 'inline',\n density: 'default',\n divider: 'none',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — row <div> */\n/* */\n/* The grid template is selected per (layout × hasIcons × copyable). */\n/* Inline / responsive (above sm) layouts use a 2-, 3-, or 4-column */\n/* grid. Stacked layouts use flex-col when there are no icons, and a */\n/* 2- or 3-column grid when icons are present (so the icon can sit at */\n/* the leading edge of the dt/dd stack without breaking the dl/dt/dd */\n/* parent-child relationship the HTML5 spec requires). */\n/* */\n/* The icon column is `auto` — it resolves to the icon wrapper's */\n/* intrinsic box (`size-4` = 1rem), which matches the empty placeholder */\n/* rendered on rows without an icon. That keeps sibling rows aligned */\n/* even when only some rows carry an icon. */\n/* */\n/* The copy IconButton is pinned to the trailing column via */\n/* `[&>button]:col-start-N` so it does not wrap to an unrelated cell */\n/* when the row also contains multiple `<dd>` siblings. */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListRowVariants = cva('', {\n variants: {\n layout: {\n inline: '',\n stacked: '',\n responsive: '',\n },\n divider: {\n none: '',\n between:\n 'ds:[&:not(:last-child)]:border-b ds:[&:not(:last-child)]:border-[color:var(--border)] ds:[&:not(:last-child)]:pb-[var(--spacing-md)]',\n bordered:\n 'ds:border ds:border-[color:var(--border)] ds:rounded-[var(--radius-sm)] ds:p-[var(--spacing-sm)]',\n },\n copyable: {\n true: '',\n false: '',\n },\n hasIcons: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n /* ----- inline / no icons ----- */\n {\n layout: 'inline',\n hasIcons: false,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline',\n },\n {\n layout: 'inline',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>button]:col-start-3 ds:[&>button]:self-start',\n },\n /* ----- inline / with icons -----\n `items-baseline` aligns Term (`type-label` 14 px / 1.4 lh) and\n Detail (`type-body` 16 px / 1.6 lh) by their text baselines so\n their cap-heights line up — without it Detail's larger\n line-box pushed plain-text values visibly below the label.\n Per-cell overrides keep the icon at row-top (with the\n `mt-[5px]` cap-height nudge intact) and the copy button at\n row-start too. Chip cells (Badges / Tags inside the Detail\n column) baseline-align via their internal text baseline; the\n shift is sub-pixel and the chip rows remain visually anchored\n with the row's label. */\n {\n layout: 'inline',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start',\n },\n {\n layout: 'inline',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:[&>button]:col-start-4 ds:[&>button]:self-start',\n },\n /* ----- stacked / no icons / no copyable ----- */\n {\n layout: 'stacked',\n hasIcons: false,\n copyable: false,\n className: 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]',\n },\n /* ----- stacked / no icons / copyable — 2-col grid so the copy\n button sits in a trailing column instead of below dd ----- */\n {\n layout: 'stacked',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[minmax(0,1fr)_auto] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>button]:col-start-2 ds:[&>button]:row-span-full',\n },\n /* ----- stacked / with icons — explicit grid so dt/dd remain\n direct children of the row div while the icon sits at the\n leading edge of the column-2 stack. `labelWidth` does not\n apply here (single content column). ----- */\n {\n layout: 'stacked',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_minmax(0,1fr)] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>dt]:col-start-2 ds:[&>dd]:col-start-2 ds:[&>[data-dl-icon-slot]]:row-span-full',\n },\n {\n layout: 'stacked',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_minmax(0,1fr)_auto] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>dt]:col-start-2 ds:[&>dd]:col-start-2 ds:[&>[data-dl-icon-slot]]:row-span-full ds:[&>button]:col-start-3 ds:[&>button]:row-span-full',\n },\n /* ----- responsive / no icons (inline above sm, stacked below) ----- */\n {\n layout: 'responsive',\n hasIcons: false,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:max-sm:flex ds:max-sm:flex-col ds:max-sm:gap-[var(--spacing-xs)]',\n },\n {\n layout: 'responsive',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>button]:col-start-3 ds:[&>button]:self-start ds:max-sm:flex ds:max-sm:flex-col ds:max-sm:gap-[var(--spacing-xs)]',\n },\n /* ----- responsive / with icons ----- */\n {\n layout: 'responsive',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:max-sm:grid-cols-[auto_minmax(0,1fr)] ds:max-sm:gap-x-[var(--spacing-sm)] ds:max-sm:gap-y-[var(--spacing-xs)] ds:max-sm:[&>dt]:col-start-2 ds:max-sm:[&>dd]:col-start-2 ds:max-sm:[&>[data-dl-icon-slot]]:row-span-full',\n },\n {\n layout: 'responsive',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:[&>button]:col-start-4 ds:[&>button]:self-start ds:max-sm:grid-cols-[auto_minmax(0,1fr)_auto] ds:max-sm:gap-x-[var(--spacing-sm)] ds:max-sm:gap-y-[var(--spacing-xs)] ds:max-sm:[&>dt]:col-start-2 ds:max-sm:[&>dd]:col-start-2 ds:max-sm:[&>[data-dl-icon-slot]]:row-span-full ds:max-sm:[&>button]:col-start-3 ds:max-sm:[&>button]:row-span-full',\n },\n ],\n defaultVariants: {\n layout: 'inline',\n divider: 'none',\n copyable: false,\n hasIcons: false,\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\nexport interface DescriptionListProps extends React.HTMLAttributes<HTMLDListElement> {\n layout?: 'inline' | 'stacked' | 'responsive';\n density?: 'default' | 'compact';\n divider?: 'none' | 'between' | 'bordered';\n /**\n * Width of the term column in `inline` and `responsive` layouts.\n *\n * - `'auto'` (default): the term column sizes to its intrinsic content\n * per row, so labels wrap at word boundaries in narrow contexts (carousel\n * cards, sidebar panels) and the detail column takes the remaining inline\n * space. **Sibling rows do NOT share column widths under this preset** —\n * each row's columns size to its own content. Use this when intrinsic\n * per-row sizing matters more than vertical alignment of values.\n * - `'fixed'`: ⅓ / ⅔ split — term column is `minmax(0, 1fr)` and detail\n * column is `minmax(0, 2fr)`. Sibling rows share the same proportional\n * widths, so values align vertically across rows. Use this when shared\n * value-column alignment matters (the typical use case for a list of\n * contact rows, profile fields, or any tabular-feeling metadata).\n * - any CSS track size (`'8rem'`, `'min-content'`, `'40%'`, …): pins the\n * term column to that width and lets the detail column take the rest.\n *\n * Ignored when `layout=\"stacked\"` (single content column).\n */\n labelWidth?: DescriptionListLabelWidth;\n}\n\nexport interface DescriptionListRowProps extends React.HTMLAttributes<HTMLDivElement> {\n /** When true, shows a copy-to-clipboard button using KeyValuePair's established mechanism */\n copyable?: boolean;\n /** Text written to the clipboard when copyable=true */\n copyText?: string;\n /** Label used in the copy button's aria-label: \"Copy {copyLabel}\". Falls back to copyText. */\n copyLabel?: string;\n /**\n * Optional decorative icon rendered at the leading edge of the row.\n * Pass a `lucide-react` icon (or any single React element) for visual\n * consistency. The wrapper applies `aria-hidden=\"true\"` and paints\n * the icon with `var(--description-list-icon-color)` (defaults to\n * `--muted-foreground`); consumers can recolour the slot via that\n * token without forking the component.\n *\n * When any row in the list passes an `icon`, every row reserves a\n * leading icon column so values align across siblings — including\n * rows that did not pass an icon.\n *\n * Type is `ReactElement` (not the broader `ReactNode`) so the intent\n * is clear at the call site: this slot is for a single SVG/icon,\n * not arbitrary fragments, strings, or numbers.\n */\n icon?: React.ReactElement | null;\n}\n\nexport type DescriptionListTermProps = React.HTMLAttributes<HTMLElement>;\n\nexport interface DescriptionListDetailProps extends React.HTMLAttributes<HTMLElement> {\n /** Right-aligns numeric values via text-end */\n numeric?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Root — <dl> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListRoot = forwardRef<HTMLDListElement, DescriptionListProps>(\n (\n {\n layout = 'inline',\n density = 'default',\n divider = 'none',\n labelWidth = 'auto',\n className,\n children,\n style,\n ...props\n },\n ref,\n ) => {\n // Detect whether any direct child Row carries a non-null `icon` prop.\n // `Children.toArray` flattens nested arrays from `.map()` calls; fragments\n // (`<>…</>`) and deeper wrappers (HOCs, custom containers) are NOT\n // unwrapped. Consumers who hit that edge case can force the icon column\n // by passing `icon={<></>}` on at least one direct-child Row.\n const hasIcons = useMemo(\n () =>\n Children.toArray(children).some(\n (child) =>\n isValidElement(child) &&\n (child.props as { icon?: unknown }).icon != null,\n ),\n [children],\n );\n\n // Inline style — permitted per 23-constraints §Runtime-computed dimensions\n // (CSS custom property setter; the grid-template-columns rule that\n // consumes these variables lives in CVA on each Row).\n const gridStyle = useMemo<CSSProperties>(\n () =>\n ({\n ...style,\n '--description-list-label-track': resolveLabelTrack(labelWidth),\n '--description-list-value-track': resolveValueTrack(labelWidth),\n }) as CSSProperties,\n [style, labelWidth],\n );\n\n return (\n <DescriptionListContext.Provider\n value={{ layout, density, divider, hasIcons }}\n >\n <dl\n ref={ref}\n className={descriptionListVariants({\n layout,\n density,\n divider,\n className,\n })}\n data-component=\"description-list\"\n data-label-width={\n labelWidth === 'auto' || labelWidth === 'fixed'\n ? labelWidth\n : 'custom'\n }\n // eslint-disable-next-line react/forbid-dom-props -- 23-constraints §Runtime-computed dimensions: labelWidth resolves to a CSS track size set on `--description-list-label-track`. The grid-template-columns rule that consumes the variable lives in CVA on each Row.\n style={gridStyle}\n {...props}\n >\n {children}\n </dl>\n </DescriptionListContext.Provider>\n );\n },\n);\nDescriptionListRoot.displayName = 'DescriptionList';\n\n/* ------------------------------------------------------------------ */\n/* Row — <div> that groups a <dt> with its <dd>(s) */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListRow = forwardRef<HTMLDivElement, DescriptionListRowProps>(\n (\n {\n copyable = false,\n copyText,\n copyLabel,\n icon,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const { layout, divider, hasIcons } = useContext(DescriptionListContext);\n const { t } = useTranslation();\n const [copied, setCopied] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n const handleCopy = useCallback(async () => {\n if (!copyText) {\n if (import.meta.env.DEV) {\n console.warn(\n 'DescriptionList.Row: copyable=true but no copyText provided. Copy is a no-op.',\n );\n }\n return;\n }\n try {\n await navigator.clipboard.writeText(copyText);\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 }, [copyText, t]);\n\n const ariaLabel = t('keyValuePair.copy', {\n label: copyLabel ?? copyText ?? '',\n });\n\n return (\n <div\n ref={ref}\n className={descriptionListRowVariants({\n layout,\n divider,\n copyable,\n hasIcons,\n className,\n })}\n {...props}\n >\n {/* Icon slot — rendered on every row when the list has any icons\n so column-1 width is consistent across siblings. The wrapper\n is `size-4` regardless of whether it contains an SVG, so the\n grid's `auto` column resolves to the same 1rem width for\n both icon-bearing and icon-less rows. `aria-hidden` keeps SR\n announcements as \"term: definition\" without an interstitial\n icon role. */}\n {hasIcons && (\n <span\n data-dl-icon-slot\n aria-hidden=\"true\"\n // Cap-height alignment for the icon vs the label's first\n // line. The previous `mt-0.5` (2 px) left the icon\n // visibly above the label — `type-label` at 14 px /\n // 1.4 lh has its cap-height roughly 5 px below the row\n // top, so a 16 px icon centred at row+10 was painting\n // above the label's letter tops. `mt-[5px]` lands the\n // icon's visible glyph (after lucide's internal ~2 px\n // padding) right on the label cap-height.\n // `align-self` defers to the parent grid's\n // `items-start` so the icon stays anchored to the row's\n // first line — multi-line values (badge chips, wrapped\n // text) don't drag the icon down.\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:mt-[5px] ds:items-center ds:justify-center ds:[&_svg]:size-4 ds:text-[color:var(--description-list-icon-color)]\"\n >\n {icon}\n </span>\n )}\n {children}\n {copyable && (\n <IconButton\n icon={copied ? <Check /> : <Copy />}\n size=\"sm\"\n aria-label={ariaLabel}\n onClick={handleCopy}\n intent=\"ghost\"\n className=\"ds:self-start\"\n />\n )}\n {copyable && (\n <span role=\"status\" className=\"ds:sr-only\">\n {announcement}\n </span>\n )}\n </div>\n );\n },\n);\nDescriptionListRow.displayName = 'DescriptionList.Row';\n\n/* ------------------------------------------------------------------ */\n/* CVA — term <dt> */\n/* ------------------------------------------------------------------ */\n\n// Term / Detail use `overflow-wrap: break-word` (not `anywhere`) so natural-\n// language content wraps at word boundaries first. `anywhere` introduces a\n// soft-wrap opportunity at every character boundary, which combines with\n// `minmax(0, …)` grid tracks to break Italian / German labels mid-word in\n// narrow contexts (carousel cards, sidebar panels). `break-word` still breaks\n// genuinely unbreakable strings — URLs, hashes, long IDs — at the column\n// edge, so transaction IDs and email addresses don't push the layout wider.\nconst descriptionListTermVariants = cva(\n 'type-label ds:text-[color:var(--muted-foreground)] ds:text-start ds:[overflow-wrap:break-word] ds:[word-break:normal]',\n);\n\n/* ------------------------------------------------------------------ */\n/* CVA — detail <dd> */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListDetailVariants = cva(\n 'type-body ds:text-[color:var(--foreground)] ds:m-0 ds:[overflow-wrap:break-word] ds:[word-break:normal]',\n {\n variants: {\n numeric: {\n true: 'ds:text-end',\n false: 'ds:text-start',\n },\n },\n defaultVariants: {\n numeric: false,\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Term — <dt> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListTerm = forwardRef<HTMLElement, DescriptionListTermProps>(\n ({ className, ...props }, ref) => (\n <dt\n ref={ref as React.Ref<HTMLElement>}\n className={descriptionListTermVariants({ className })}\n {...props}\n />\n ),\n);\nDescriptionListTerm.displayName = 'DescriptionList.Term';\n\n/* ------------------------------------------------------------------ */\n/* Detail — <dd> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListDetail = forwardRef<\n HTMLElement,\n DescriptionListDetailProps\n>(({ numeric = false, className, ...props }, ref) => (\n <dd\n ref={ref as React.Ref<HTMLElement>}\n className={descriptionListDetailVariants({ numeric, className })}\n {...props}\n />\n));\nDescriptionListDetail.displayName = 'DescriptionList.Detail';\n\n/* ------------------------------------------------------------------ */\n/* Compound export */\n/* ------------------------------------------------------------------ */\n\nexport const DescriptionList = Object.assign(DescriptionListRoot, {\n Row: DescriptionListRow,\n Term: DescriptionListTerm,\n Detail: DescriptionListDetail,\n});\n"],"names":["resolveLabelTrack","labelWidth","resolveValueTrack","DescriptionListContext","createContext","descriptionListVariants","cva","descriptionListRowVariants","DescriptionListRoot","forwardRef","layout","density","divider","className","children","style","props","ref","hasIcons","useMemo","Children","child","isValidElement","gridStyle","jsx","DescriptionListRow","copyable","copyText","copyLabel","icon","useContext","t","useTranslation","copied","setCopied","useState","announcement","setAnnouncement","handleCopy","useCallback","ariaLabel","jsxs","IconButton","Check","Copy","descriptionListTermVariants","descriptionListDetailVariants","DescriptionListTerm","DescriptionListDetail","numeric","DescriptionList"],"mappings":"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"}
1
+ {"version":3,"file":"description-list-CjJqR8WK.js","sources":["../../src/components/description-list/description-list.tsx"],"sourcesContent":["import {\n Children,\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useMemo,\n useState,\n type CSSProperties,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Copy, Check } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* labelWidth → label / value track resolver */\n/* */\n/* The `inline` / `responsive` layouts render a two- or three-column */\n/* grid (icon? · label · value · copy?). The label column's width is */\n/* parameterised so consumers can pick the right behaviour for the */\n/* surrounding container: */\n/* */\n/* - `auto` (default): label sizes to its intrinsic content; the */\n/* value column takes the remainder. Long labels wrap word-by-word */\n/* in narrow contexts instead of being squeezed into a 1fr column */\n/* that can collapse below the longest word. */\n/* - `fixed`: legacy ⅓ / ⅔ ratio (label `minmax(0,1fr)`, value */\n/* `minmax(0,2fr)`). Use for wide forms where consistent alignment */\n/* across rows is more important than fitting the longest label. */\n/* - any CSS length / track size (`'8rem'`, `'min-content'`, …): */\n/* forces the label column to that width. */\n/* */\n/* The resolved values are surfaced as `--description-list-label-track` */\n/* and `--description-list-value-track` on the root `<dl>` so each Row */\n/* can compose them with the icon / copy auto columns it needs. */\n/* ------------------------------------------------------------------ */\n\ntype LabelWidthPreset = 'auto' | 'fixed';\nexport type DescriptionListLabelWidth = LabelWidthPreset | (string & {});\n\nfunction resolveLabelTrack(labelWidth: DescriptionListLabelWidth): string {\n // `auto` uses `fit-content(50%)` rather than the bare `auto` keyword.\n // CSS `auto` resolves to `minmax(min-content, max-content)`, which can't\n // shrink the term column below the dt's max-content in a narrow container\n // (the failure mode booking-website hit with long Italian medical labels\n // in a 320 px Carousel slide). `fit-content(50%)` clamps to\n // `max(min-content, min(50%-of-container, max-content))`:\n // - in narrow containers it caps at 50 % of the row width, leaving the\n // other half for the detail column; the dt wraps at word boundaries\n // via `overflow-wrap: break-word`.\n // - in wide containers it expands to the dt's max-content, so short\n // labels don't stretch unnecessarily.\n if (labelWidth === 'auto') return 'fit-content(50%)';\n if (labelWidth === 'fixed') return 'minmax(0,1fr)';\n return labelWidth;\n}\n\nfunction resolveValueTrack(labelWidth: DescriptionListLabelWidth): string {\n return labelWidth === 'fixed' ? 'minmax(0,2fr)' : 'minmax(0,1fr)';\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\ninterface DescriptionListContextShape {\n layout: 'inline' | 'stacked' | 'responsive';\n density: 'default' | 'compact';\n divider: 'none' | 'between' | 'bordered';\n /**\n * True when at least one direct child Row was rendered with a\n * non-null `icon` prop. Every Row in the list then reserves a\n * leading icon column (rendering a `size-4` empty placeholder\n * when this row has no icon) so the grid's `auto` column resolves\n * to the same width across all rows and sibling Rows align.\n */\n hasIcons: boolean;\n}\n\nconst DescriptionListContext = createContext<DescriptionListContextShape>({\n layout: 'inline',\n density: 'default',\n divider: 'none',\n hasIcons: false,\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — root <dl> */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListVariants = cva('ds:flex ds:flex-col', {\n variants: {\n layout: {\n inline: '',\n stacked: '',\n responsive: '',\n },\n density: {\n default: 'ds:gap-[var(--spacing-md)]',\n compact: 'ds:gap-[var(--spacing-sm)]',\n },\n divider: {\n none: '',\n between: '',\n bordered: '',\n },\n },\n defaultVariants: {\n layout: 'inline',\n density: 'default',\n divider: 'none',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — row <div> */\n/* */\n/* The grid template is selected per (layout × hasIcons × copyable). */\n/* Inline / responsive (above sm) layouts use a 2-, 3-, or 4-column */\n/* grid. Stacked layouts use flex-col when there are no icons, and a */\n/* 2- or 3-column grid when icons are present (so the icon can sit at */\n/* the leading edge of the dt/dd stack without breaking the dl/dt/dd */\n/* parent-child relationship the HTML5 spec requires). */\n/* */\n/* The icon column is `auto` — it resolves to the icon wrapper's */\n/* intrinsic box (`size-4` = 1rem), which matches the empty placeholder */\n/* rendered on rows without an icon. That keeps sibling rows aligned */\n/* even when only some rows carry an icon. */\n/* */\n/* The copy IconButton is pinned to the trailing column via */\n/* `[&>button]:col-start-N` so it does not wrap to an unrelated cell */\n/* when the row also contains multiple `<dd>` siblings. */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListRowVariants = cva('', {\n variants: {\n layout: {\n inline: '',\n stacked: '',\n responsive: '',\n },\n divider: {\n none: '',\n between:\n 'ds:[&:not(:last-child)]:border-b ds:[&:not(:last-child)]:border-[color:var(--border)] ds:[&:not(:last-child)]:pb-[var(--spacing-md)]',\n bordered:\n 'ds:border ds:border-[color:var(--border)] ds:rounded-[var(--radius-sm)] ds:p-[var(--spacing-sm)]',\n },\n copyable: {\n true: '',\n false: '',\n },\n hasIcons: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n /* ----- inline / no icons ----- */\n {\n layout: 'inline',\n hasIcons: false,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline',\n },\n {\n layout: 'inline',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>button]:col-start-3 ds:[&>button]:self-start',\n },\n /* ----- inline / with icons -----\n `items-baseline` aligns Term (`type-label` 14 px / 1.4 lh) and\n Detail (`type-body` 16 px / 1.6 lh) by their text baselines so\n their cap-heights line up — without it Detail's larger\n line-box pushed plain-text values visibly below the label.\n Per-cell overrides keep the icon at row-top (with the\n `mt-[5px]` cap-height nudge intact) and the copy button at\n row-start too. Chip cells (Badges / Tags inside the Detail\n column) baseline-align via their internal text baseline; the\n shift is sub-pixel and the chip rows remain visually anchored\n with the row's label. */\n {\n layout: 'inline',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start',\n },\n {\n layout: 'inline',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:[&>button]:col-start-4 ds:[&>button]:self-start',\n },\n /* ----- stacked / no icons / no copyable ----- */\n {\n layout: 'stacked',\n hasIcons: false,\n copyable: false,\n className: 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]',\n },\n /* ----- stacked / no icons / copyable — 2-col grid so the copy\n button sits in a trailing column instead of below dd ----- */\n {\n layout: 'stacked',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[minmax(0,1fr)_auto] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>button]:col-start-2 ds:[&>button]:row-span-full',\n },\n /* ----- stacked / with icons — explicit grid so dt/dd remain\n direct children of the row div while the icon sits at the\n leading edge of the column-2 stack. `labelWidth` does not\n apply here (single content column). ----- */\n {\n layout: 'stacked',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_minmax(0,1fr)] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>dt]:col-start-2 ds:[&>dd]:col-start-2 ds:[&>[data-dl-icon-slot]]:row-span-full',\n },\n {\n layout: 'stacked',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_minmax(0,1fr)_auto] ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-xs)] ds:items-start ds:[&>dt]:col-start-2 ds:[&>dd]:col-start-2 ds:[&>[data-dl-icon-slot]]:row-span-full ds:[&>button]:col-start-3 ds:[&>button]:row-span-full',\n },\n /* ----- responsive / no icons (inline above sm, stacked below) ----- */\n {\n layout: 'responsive',\n hasIcons: false,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:max-sm:flex ds:max-sm:flex-col ds:max-sm:gap-[var(--spacing-xs)]',\n },\n {\n layout: 'responsive',\n hasIcons: false,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>button]:col-start-3 ds:[&>button]:self-start ds:max-sm:flex ds:max-sm:flex-col ds:max-sm:gap-[var(--spacing-xs)]',\n },\n /* ----- responsive / with icons ----- */\n {\n layout: 'responsive',\n hasIcons: true,\n copyable: false,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:max-sm:grid-cols-[auto_minmax(0,1fr)] ds:max-sm:gap-x-[var(--spacing-sm)] ds:max-sm:gap-y-[var(--spacing-xs)] ds:max-sm:[&>dt]:col-start-2 ds:max-sm:[&>dd]:col-start-2 ds:max-sm:[&>[data-dl-icon-slot]]:row-span-full',\n },\n {\n layout: 'responsive',\n hasIcons: true,\n copyable: true,\n className:\n 'ds:grid ds:grid-cols-[auto_var(--description-list-label-track)_var(--description-list-value-track)_auto] ds:gap-[var(--spacing-md)] ds:items-baseline ds:[&>[data-dl-icon-slot]]:self-start ds:[&>button]:col-start-4 ds:[&>button]:self-start ds:max-sm:grid-cols-[auto_minmax(0,1fr)_auto] ds:max-sm:gap-x-[var(--spacing-sm)] ds:max-sm:gap-y-[var(--spacing-xs)] ds:max-sm:[&>dt]:col-start-2 ds:max-sm:[&>dd]:col-start-2 ds:max-sm:[&>[data-dl-icon-slot]]:row-span-full ds:max-sm:[&>button]:col-start-3 ds:max-sm:[&>button]:row-span-full',\n },\n ],\n defaultVariants: {\n layout: 'inline',\n divider: 'none',\n copyable: false,\n hasIcons: false,\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\nexport interface DescriptionListProps extends React.HTMLAttributes<HTMLDListElement> {\n layout?: 'inline' | 'stacked' | 'responsive';\n density?: 'default' | 'compact';\n divider?: 'none' | 'between' | 'bordered';\n /**\n * Width of the term column in `inline` and `responsive` layouts.\n *\n * - `'auto'` (default): the term column sizes to its intrinsic content\n * per row, so labels wrap at word boundaries in narrow contexts (carousel\n * cards, sidebar panels) and the detail column takes the remaining inline\n * space. **Sibling rows do NOT share column widths under this preset** —\n * each row's columns size to its own content. Use this when intrinsic\n * per-row sizing matters more than vertical alignment of values.\n * - `'fixed'`: ⅓ / ⅔ split — term column is `minmax(0, 1fr)` and detail\n * column is `minmax(0, 2fr)`. Sibling rows share the same proportional\n * widths, so values align vertically across rows. Use this when shared\n * value-column alignment matters (the typical use case for a list of\n * contact rows, profile fields, or any tabular-feeling metadata).\n * - any CSS track size (`'8rem'`, `'min-content'`, `'40%'`, …): pins the\n * term column to that width and lets the detail column take the rest.\n *\n * Ignored when `layout=\"stacked\"` (single content column).\n */\n labelWidth?: DescriptionListLabelWidth;\n}\n\nexport interface DescriptionListRowProps extends React.HTMLAttributes<HTMLDivElement> {\n /** When true, shows a copy-to-clipboard button using KeyValuePair's established mechanism */\n copyable?: boolean;\n /** Text written to the clipboard when copyable=true */\n copyText?: string;\n /** Label used in the copy button's aria-label: \"Copy {copyLabel}\". Falls back to copyText. */\n copyLabel?: string;\n /**\n * Optional decorative icon rendered at the leading edge of the row.\n * Pass a `lucide-react` icon (or any single React element) for visual\n * consistency. The wrapper applies `aria-hidden=\"true\"` and paints\n * the icon with `var(--description-list-icon-color)` (defaults to\n * `--muted-foreground`); consumers can recolour the slot via that\n * token without forking the component.\n *\n * When any row in the list passes an `icon`, every row reserves a\n * leading icon column so values align across siblings — including\n * rows that did not pass an icon.\n *\n * Type is `ReactElement` (not the broader `ReactNode`) so the intent\n * is clear at the call site: this slot is for a single SVG/icon,\n * not arbitrary fragments, strings, or numbers.\n */\n icon?: React.ReactElement | null;\n}\n\nexport type DescriptionListTermProps = React.HTMLAttributes<HTMLElement>;\n\nexport interface DescriptionListDetailProps extends React.HTMLAttributes<HTMLElement> {\n /** Right-aligns numeric values via text-end */\n numeric?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Root — <dl> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListRoot = forwardRef<HTMLDListElement, DescriptionListProps>(\n (\n {\n layout = 'inline',\n density = 'default',\n divider = 'none',\n labelWidth = 'auto',\n className,\n children,\n style,\n ...props\n },\n ref,\n ) => {\n // Detect whether any direct child Row carries a non-null `icon` prop.\n // `Children.toArray` flattens nested arrays from `.map()` calls; fragments\n // (`<>…</>`) and deeper wrappers (HOCs, custom containers) are NOT\n // unwrapped. Consumers who hit that edge case can force the icon column\n // by passing `icon={<></>}` on at least one direct-child Row.\n const hasIcons = useMemo(\n () =>\n Children.toArray(children).some(\n (child) =>\n isValidElement(child) &&\n (child.props as { icon?: unknown }).icon != null,\n ),\n [children],\n );\n\n // Inline style — permitted per 23-constraints §Runtime-computed dimensions\n // (CSS custom property setter; the grid-template-columns rule that\n // consumes these variables lives in CVA on each Row).\n const gridStyle = useMemo<CSSProperties>(\n () =>\n ({\n ...style,\n '--description-list-label-track': resolveLabelTrack(labelWidth),\n '--description-list-value-track': resolveValueTrack(labelWidth),\n }) as CSSProperties,\n [style, labelWidth],\n );\n\n return (\n <DescriptionListContext.Provider\n value={{ layout, density, divider, hasIcons }}\n >\n <dl\n ref={ref}\n className={descriptionListVariants({\n layout,\n density,\n divider,\n className,\n })}\n data-component=\"description-list\"\n data-label-width={\n labelWidth === 'auto' || labelWidth === 'fixed'\n ? labelWidth\n : 'custom'\n }\n // eslint-disable-next-line react/forbid-dom-props -- 23-constraints §Runtime-computed dimensions: labelWidth resolves to a CSS track size set on `--description-list-label-track`. The grid-template-columns rule that consumes the variable lives in CVA on each Row.\n style={gridStyle}\n {...props}\n >\n {children}\n </dl>\n </DescriptionListContext.Provider>\n );\n },\n);\nDescriptionListRoot.displayName = 'DescriptionList';\n\n/* ------------------------------------------------------------------ */\n/* Row — <div> that groups a <dt> with its <dd>(s) */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListRow = forwardRef<HTMLDivElement, DescriptionListRowProps>(\n (\n {\n copyable = false,\n copyText,\n copyLabel,\n icon,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const { layout, divider, hasIcons } = useContext(DescriptionListContext);\n const { t } = useTranslation();\n const [copied, setCopied] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n const handleCopy = useCallback(async () => {\n if (!copyText) {\n if (import.meta.env.DEV) {\n console.warn(\n 'DescriptionList.Row: copyable=true but no copyText provided. Copy is a no-op.',\n );\n }\n return;\n }\n try {\n await navigator.clipboard.writeText(copyText);\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 }, [copyText, t]);\n\n const ariaLabel = t('keyValuePair.copy', {\n label: copyLabel ?? copyText ?? '',\n });\n\n return (\n <div\n ref={ref}\n className={descriptionListRowVariants({\n layout,\n divider,\n copyable,\n hasIcons,\n className,\n })}\n {...props}\n >\n {/* Icon slot — rendered on every row when the list has any icons\n so column-1 width is consistent across siblings. The wrapper\n is `size-4` regardless of whether it contains an SVG, so the\n grid's `auto` column resolves to the same 1rem width for\n both icon-bearing and icon-less rows. `aria-hidden` keeps SR\n announcements as \"term: definition\" without an interstitial\n icon role. */}\n {hasIcons && (\n <span\n data-dl-icon-slot\n aria-hidden=\"true\"\n // Cap-height alignment for the icon vs the label's first\n // line. The previous `mt-0.5` (2 px) left the icon\n // visibly above the label — `type-label` at 14 px /\n // 1.4 lh has its cap-height roughly 5 px below the row\n // top, so a 16 px icon centred at row+10 was painting\n // above the label's letter tops. `mt-[5px]` lands the\n // icon's visible glyph (after lucide's internal ~2 px\n // padding) right on the label cap-height.\n // `align-self` defers to the parent grid's\n // `items-start` so the icon stays anchored to the row's\n // first line — multi-line values (badge chips, wrapped\n // text) don't drag the icon down.\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:mt-[5px] ds:items-center ds:justify-center ds:[&_svg]:size-4 ds:text-[color:var(--description-list-icon-color)]\"\n >\n {icon}\n </span>\n )}\n {children}\n {copyable && (\n <IconButton\n icon={copied ? <Check /> : <Copy />}\n size=\"sm\"\n aria-label={ariaLabel}\n onClick={handleCopy}\n intent=\"ghost\"\n className=\"ds:self-start\"\n />\n )}\n {copyable && (\n <span role=\"status\" className=\"ds:sr-only\">\n {announcement}\n </span>\n )}\n </div>\n );\n },\n);\nDescriptionListRow.displayName = 'DescriptionList.Row';\n\n/* ------------------------------------------------------------------ */\n/* CVA — term <dt> */\n/* ------------------------------------------------------------------ */\n\n// Term / Detail use `overflow-wrap: break-word` (not `anywhere`) so natural-\n// language content wraps at word boundaries first. `anywhere` introduces a\n// soft-wrap opportunity at every character boundary, which combines with\n// `minmax(0, …)` grid tracks to break Italian / German labels mid-word in\n// narrow contexts (carousel cards, sidebar panels). `break-word` still breaks\n// genuinely unbreakable strings — URLs, hashes, long IDs — at the column\n// edge, so transaction IDs and email addresses don't push the layout wider.\nconst descriptionListTermVariants = cva(\n 'type-label ds:text-[color:var(--muted-foreground)] ds:text-start ds:[overflow-wrap:break-word] ds:[word-break:normal]',\n);\n\n/* ------------------------------------------------------------------ */\n/* CVA — detail <dd> */\n/* ------------------------------------------------------------------ */\n\nconst descriptionListDetailVariants = cva(\n 'type-body ds:text-[color:var(--foreground)] ds:m-0 ds:[overflow-wrap:break-word] ds:[word-break:normal]',\n {\n variants: {\n numeric: {\n true: 'ds:text-end',\n false: 'ds:text-start',\n },\n },\n defaultVariants: {\n numeric: false,\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Term — <dt> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListTerm = forwardRef<HTMLElement, DescriptionListTermProps>(\n ({ className, ...props }, ref) => (\n <dt\n ref={ref as React.Ref<HTMLElement>}\n className={descriptionListTermVariants({ className })}\n {...props}\n />\n ),\n);\nDescriptionListTerm.displayName = 'DescriptionList.Term';\n\n/* ------------------------------------------------------------------ */\n/* Detail — <dd> */\n/* ------------------------------------------------------------------ */\n\nconst DescriptionListDetail = forwardRef<\n HTMLElement,\n DescriptionListDetailProps\n>(({ numeric = false, className, ...props }, ref) => (\n <dd\n ref={ref as React.Ref<HTMLElement>}\n className={descriptionListDetailVariants({ numeric, className })}\n {...props}\n />\n));\nDescriptionListDetail.displayName = 'DescriptionList.Detail';\n\n/* ------------------------------------------------------------------ */\n/* Compound export */\n/* ------------------------------------------------------------------ */\n\nexport const DescriptionList = Object.assign(DescriptionListRoot, {\n Row: DescriptionListRow,\n Term: DescriptionListTerm,\n Detail: DescriptionListDetail,\n});\n"],"names":["resolveLabelTrack","labelWidth","resolveValueTrack","DescriptionListContext","createContext","descriptionListVariants","cva","descriptionListRowVariants","DescriptionListRoot","forwardRef","layout","density","divider","className","children","style","props","ref","hasIcons","useMemo","Children","child","isValidElement","gridStyle","jsx","DescriptionListRow","copyable","copyText","copyLabel","icon","useContext","t","useTranslation","copied","setCopied","useState","announcement","setAnnouncement","handleCopy","useCallback","ariaLabel","jsxs","IconButton","Check","Copy","descriptionListTermVariants","descriptionListDetailVariants","DescriptionListTerm","DescriptionListDetail","numeric","DescriptionList"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { c as $ } from "./index-D2ZczOXr.js";
4
4
  import { useTranslation as U } from "react-i18next";
5
5
  import { B as b } from "./badge-sTusUqZD.js";
6
6
  import { C as B } from "./card-DPmk26CL.js";
7
- import { E as G } from "./empty-state-Df0tM6Kn.js";
7
+ import { E as G } from "./empty-state-X0sVPfVo.js";
8
8
  import { P as Y } from "./panel-header-D313n_9-.js";
9
9
  import { P as J } from "./pdf-viewer-DUIsV9s5.js";
10
10
  import { T as O, b as Q, c as X, a as Z } from "./tabs-CBb2AidH.js";
@@ -287,4 +287,4 @@ export {
287
287
  ue as D,
288
288
  de as d
289
289
  };
290
- //# sourceMappingURL=document-preview-Aae2yKvY.js.map
290
+ //# sourceMappingURL=document-preview-oyx9RhCo.js.map