@alfadocs/ui-kit-debug 1.94.0 → 1.95.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 (277) hide show
  1. package/dist/_chunks/{actions-cell-renderer-B1yaOfQM.js → actions-cell-renderer-BVn3vDTg.js} +3 -3
  2. package/dist/_chunks/{actions-cell-renderer-B1yaOfQM.js.map → actions-cell-renderer-BVn3vDTg.js.map} +1 -1
  3. package/dist/_chunks/{anamnesis-summary-rows-IMohuz0D.js → anamnesis-summary-rows-krsCC-F4.js} +5 -5
  4. package/dist/_chunks/{anamnesis-summary-rows-IMohuz0D.js.map → anamnesis-summary-rows-krsCC-F4.js.map} +1 -1
  5. package/dist/_chunks/{appointment-card-Bstc1p7a.js → appointment-card-Csx4544A.js} +2 -2
  6. package/dist/_chunks/{appointment-card-Bstc1p7a.js.map → appointment-card-Csx4544A.js.map} +1 -1
  7. package/dist/_chunks/{appointment-peek-C0kKqnFk.js → appointment-peek-CcDCWb-F.js} +2 -2
  8. package/dist/_chunks/{appointment-peek-C0kKqnFk.js.map → appointment-peek-CcDCWb-F.js.map} +1 -1
  9. package/dist/_chunks/{appointment-timeline-rbt9AwHO.js → appointment-timeline-DW6FN6u8.js} +3 -3
  10. package/dist/_chunks/{appointment-timeline-rbt9AwHO.js.map → appointment-timeline-DW6FN6u8.js.map} +1 -1
  11. package/dist/_chunks/{appointment-tray-6zd8RLIL.js → appointment-tray-CZfXwHWz.js} +2 -2
  12. package/dist/_chunks/{appointment-tray-6zd8RLIL.js.map → appointment-tray-CZfXwHWz.js.map} +1 -1
  13. package/dist/_chunks/{balance-badge-cell-vZxbOFgP.js → balance-badge-cell-DbgEQsou.js} +3 -3
  14. package/dist/_chunks/{balance-badge-cell-vZxbOFgP.js.map → balance-badge-cell-DbgEQsou.js.map} +1 -1
  15. package/dist/_chunks/{button-group-ZVb1Q-w4.js → button-group-CUnNnt8a.js} +2 -2
  16. package/dist/_chunks/{button-group-ZVb1Q-w4.js.map → button-group-CUnNnt8a.js.map} +1 -1
  17. package/dist/_chunks/{calendar-appointment-editor-dialog-CsVWoRcP.js → calendar-appointment-editor-dialog-D3tQ8N34.js} +12 -12
  18. package/dist/_chunks/{calendar-appointment-editor-dialog-CsVWoRcP.js.map → calendar-appointment-editor-dialog-D3tQ8N34.js.map} +1 -1
  19. package/dist/_chunks/{care-plan-card-DD9rEWYN.js → care-plan-card-YWKV8Kjq.js} +2 -2
  20. package/dist/_chunks/{care-plan-card-DD9rEWYN.js.map → care-plan-card-YWKV8Kjq.js.map} +1 -1
  21. package/dist/_chunks/{care-plan-entry-card-4VaY2c96.js → care-plan-entry-card-CApivtMW.js} +2 -2
  22. package/dist/_chunks/{care-plan-entry-card-4VaY2c96.js.map → care-plan-entry-card-CApivtMW.js.map} +1 -1
  23. package/dist/_chunks/{care-plan-header-CXUJQt8Q.js → care-plan-header-BBh0X7EO.js} +2 -2
  24. package/dist/_chunks/{care-plan-header-CXUJQt8Q.js.map → care-plan-header-BBh0X7EO.js.map} +1 -1
  25. package/dist/_chunks/chart-bddVIElM.js +1550 -0
  26. package/dist/_chunks/chart-bddVIElM.js.map +1 -0
  27. package/dist/_chunks/{dashboard-grid-DwJ_HV3d.js → dashboard-grid-DrOkTtya.js} +2 -2
  28. package/dist/_chunks/{dashboard-grid-DwJ_HV3d.js.map → dashboard-grid-DrOkTtya.js.map} +1 -1
  29. package/dist/_chunks/{data-table-C_nnpJ-Q.js → data-table-Bh9_IEj4.js} +3 -3
  30. package/dist/_chunks/{data-table-C_nnpJ-Q.js.map → data-table-Bh9_IEj4.js.map} +1 -1
  31. package/dist/_chunks/{date-time-picker-n-yrlMJq.js → date-time-picker-cwsWiB4q.js} +2 -2
  32. package/dist/_chunks/{date-time-picker-n-yrlMJq.js.map → date-time-picker-cwsWiB4q.js.map} +1 -1
  33. package/dist/_chunks/{document-preview-ytR1FcWA.js → document-preview-CL1xsnLS.js} +2 -2
  34. package/dist/_chunks/{document-preview-ytR1FcWA.js.map → document-preview-CL1xsnLS.js.map} +1 -1
  35. package/dist/_chunks/{dropdown-menu-D1we7oAY.js → dropdown-menu-CqxBthww.js} +2 -2
  36. package/dist/_chunks/{dropdown-menu-D1we7oAY.js.map → dropdown-menu-CqxBthww.js.map} +1 -1
  37. package/dist/_chunks/{editable-currency-cell-renderer-rWYiF4EI.js → editable-currency-cell-renderer-BQYL5GjP.js} +2 -2
  38. package/dist/_chunks/{editable-currency-cell-renderer-rWYiF4EI.js.map → editable-currency-cell-renderer-BQYL5GjP.js.map} +1 -1
  39. package/dist/_chunks/{face-scheme-BKSE98bo.js → face-scheme-DyHc3zPt.js} +4 -4
  40. package/dist/_chunks/{face-scheme-BKSE98bo.js.map → face-scheme-DyHc3zPt.js.map} +1 -1
  41. package/dist/_chunks/{file-manager-CAIbuaSs.js → file-manager-Cgf2yc10.js} +4 -4
  42. package/dist/_chunks/{file-manager-CAIbuaSs.js.map → file-manager-Cgf2yc10.js.map} +1 -1
  43. package/dist/_chunks/{hcg-doubling-K41Wy7LB.js → hcg-doubling-DQe1ptNB.js} +2 -2
  44. package/dist/_chunks/{hcg-doubling-K41Wy7LB.js.map → hcg-doubling-DQe1ptNB.js.map} +1 -1
  45. package/dist/_chunks/{header-settings-BeA2fnol.js → header-settings-DittkpqU.js} +2 -2
  46. package/dist/_chunks/{header-settings-BeA2fnol.js.map → header-settings-DittkpqU.js.map} +1 -1
  47. package/dist/_chunks/{heatmap-DdF8qTTV.js → heatmap-9Ql8Ny9d.js} +2 -2
  48. package/dist/_chunks/{heatmap-DdF8qTTV.js.map → heatmap-9Ql8Ny9d.js.map} +1 -1
  49. package/dist/_chunks/{icon-button-group-CRKFR48b.js → icon-button-group-mXvYDaba.js} +2 -2
  50. package/dist/_chunks/{icon-button-group-CRKFR48b.js.map → icon-button-group-mXvYDaba.js.map} +1 -1
  51. package/dist/_chunks/{marketplace-app-shell-CJQtx3sv.js → marketplace-app-shell-C8nHixB8.js} +4 -4
  52. package/dist/_chunks/{marketplace-app-shell-CJQtx3sv.js.map → marketplace-app-shell-C8nHixB8.js.map} +1 -1
  53. package/dist/_chunks/{message-tray-Cllf-v0G.js → message-tray-18_TrLCy.js} +2 -2
  54. package/dist/_chunks/{message-tray-Cllf-v0G.js.map → message-tray-18_TrLCy.js.map} +1 -1
  55. package/dist/_chunks/{muscle-scheme-B7qMW0ho.js → muscle-scheme-CznhrQlo.js} +2 -2
  56. package/dist/_chunks/{muscle-scheme-B7qMW0ho.js.map → muscle-scheme-CznhrQlo.js.map} +1 -1
  57. package/dist/_chunks/{notes-panel-ib7I3aNf.js → notes-panel-D6YhNGHU.js} +2 -2
  58. package/dist/_chunks/{notes-panel-ib7I3aNf.js.map → notes-panel-D6YhNGHU.js.map} +1 -1
  59. package/dist/_chunks/{notification-tray-0OkA2duS.js → notification-tray-CQK3lw87.js} +2 -2
  60. package/dist/_chunks/{notification-tray-0OkA2duS.js.map → notification-tray-CQK3lw87.js.map} +1 -1
  61. package/dist/_chunks/{patient-details-DTlpBYHJ.js → patient-details-DQQpgx4A.js} +2 -2
  62. package/dist/_chunks/{patient-details-DTlpBYHJ.js.map → patient-details-DQQpgx4A.js.map} +1 -1
  63. package/dist/_chunks/{patient-field-row-DWTKV1hF.js → patient-field-row-Cb5jUd5Q.js} +2 -2
  64. package/dist/_chunks/{patient-field-row-DWTKV1hF.js.map → patient-field-row-Cb5jUd5Q.js.map} +1 -1
  65. package/dist/_chunks/{patient-search-Ca9j5cWb.js → patient-search-Cp2efqHs.js} +2 -2
  66. package/dist/_chunks/{patient-search-Ca9j5cWb.js.map → patient-search-Cp2efqHs.js.map} +1 -1
  67. package/dist/_chunks/{patient-summary-card-C61AR4Tn.js → patient-summary-card-BvMI0eMu.js} +2 -2
  68. package/dist/_chunks/{patient-summary-card-C61AR4Tn.js.map → patient-summary-card-BvMI0eMu.js.map} +1 -1
  69. package/dist/_chunks/{practice-results-BWX9y6mS.js → practice-results-ZOVlrb43.js} +3 -3
  70. package/dist/_chunks/practice-results-ZOVlrb43.js.map +1 -0
  71. package/dist/_chunks/{product-hub-panel-bHi7lkVD.js → product-hub-panel-CqRJlmb7.js} +2 -2
  72. package/dist/_chunks/{product-hub-panel-bHi7lkVD.js.map → product-hub-panel-CqRJlmb7.js.map} +1 -1
  73. package/dist/_chunks/{public-footer-IoRWoAMz.js → public-footer-BiPiU_lk.js} +2 -2
  74. package/dist/_chunks/{public-footer-IoRWoAMz.js.map → public-footer-BiPiU_lk.js.map} +1 -1
  75. package/dist/_chunks/{reserved.agent-XU88crNW.js → reserved.agent-BvwjDyne.js} +2 -2
  76. package/dist/_chunks/{reserved.agent-XU88crNW.js.map → reserved.agent-BvwjDyne.js.map} +1 -1
  77. package/dist/_chunks/{rich-text-editor-BfEu57dk.js → rich-text-editor-iw2tJLKA.js} +2 -2
  78. package/dist/_chunks/{rich-text-editor-BfEu57dk.js.map → rich-text-editor-iw2tJLKA.js.map} +1 -1
  79. package/dist/_chunks/{separator-CYU_bGFn.js → separator-Bdc9bqoJ.js} +18 -19
  80. package/dist/_chunks/separator-Bdc9bqoJ.js.map +1 -0
  81. package/dist/_chunks/{signature-request-BVGeF0qB.js → signature-request-CLtMgQKi.js} +3 -3
  82. package/dist/_chunks/{signature-request-BVGeF0qB.js.map → signature-request-CLtMgQKi.js.map} +1 -1
  83. package/dist/_chunks/{signed-out-frame-CgRXOUzi.js → signed-out-frame-CRwVTCjY.js} +2 -2
  84. package/dist/_chunks/{signed-out-frame-CgRXOUzi.js.map → signed-out-frame-CRwVTCjY.js.map} +1 -1
  85. package/dist/_chunks/{slot-grid-B-IAFX3C.js → slot-grid-BhjaLJ0o.js} +229 -214
  86. package/dist/_chunks/{slot-grid-B-IAFX3C.js.map → slot-grid-BhjaLJ0o.js.map} +1 -1
  87. package/dist/_chunks/{tab-bar-BEODTG6k.js → tab-bar-C_pggqVr.js} +2 -2
  88. package/dist/_chunks/{tab-bar-BEODTG6k.js.map → tab-bar-C_pggqVr.js.map} +1 -1
  89. package/dist/_chunks/{tabs-BmxQu-TJ.js → tabs-DYHgRVSJ.js} +2 -2
  90. package/dist/_chunks/{tabs-BmxQu-TJ.js.map → tabs-DYHgRVSJ.js.map} +1 -1
  91. package/dist/_chunks/{task-editor-BZeSBxwU.js → task-editor-BlGdXR9F.js} +3 -3
  92. package/dist/_chunks/{task-editor-BZeSBxwU.js.map → task-editor-BlGdXR9F.js.map} +1 -1
  93. package/dist/_chunks/{tasks-panel-BTCYGLGA.js → tasks-panel-Q0CiEAff.js} +2 -2
  94. package/dist/_chunks/{tasks-panel-BTCYGLGA.js.map → tasks-panel-Q0CiEAff.js.map} +1 -1
  95. package/dist/_chunks/{theme-toggle-DKpzb0-M.js → theme-toggle-jZRbAidE.js} +3 -3
  96. package/dist/_chunks/{theme-toggle-DKpzb0-M.js.map → theme-toggle-jZRbAidE.js.map} +1 -1
  97. package/dist/_chunks/time-picker-DSt-ns5F.js +914 -0
  98. package/dist/_chunks/time-picker-DSt-ns5F.js.map +1 -0
  99. package/dist/_chunks/{token-insert-menu-DtAnBd0x.js → token-insert-menu-Dl3x2ekR.js} +2 -2
  100. package/dist/_chunks/{token-insert-menu-DtAnBd0x.js.map → token-insert-menu-Dl3x2ekR.js.map} +1 -1
  101. package/dist/_chunks/{tooth-scheme-COJJkdsi.js → tooth-scheme-Bd7xECuj.js} +2 -2
  102. package/dist/_chunks/{tooth-scheme-COJJkdsi.js.map → tooth-scheme-Bd7xECuj.js.map} +1 -1
  103. package/dist/_chunks/{use-appointment-details-read-B6uhmNdV.js → use-appointment-details-read-CpXRSfPI.js} +5 -5
  104. package/dist/_chunks/{use-appointment-details-read-B6uhmNdV.js.map → use-appointment-details-read-CpXRSfPI.js.map} +1 -1
  105. package/dist/_chunks/{workflow-map-BcfOwsSB.js → workflow-map-BWJhlZbC.js} +2 -2
  106. package/dist/_chunks/{workflow-map-BcfOwsSB.js.map → workflow-map-BWJhlZbC.js.map} +1 -1
  107. package/dist/_chunks/{workflow-status-Dc_CyEz5.js → workflow-status-HQ6ziE46.js} +2 -2
  108. package/dist/_chunks/{workflow-status-Dc_CyEz5.js.map → workflow-status-HQ6ziE46.js.map} +1 -1
  109. package/dist/_chunks/{workflow-webhook-action-B_nBJ_ht.js → workflow-webhook-action-Uhyfr6_6.js} +2 -2
  110. package/dist/_chunks/{workflow-webhook-action-B_nBJ_ht.js.map → workflow-webhook-action-Uhyfr6_6.js.map} +1 -1
  111. package/dist/agent-catalog.json +12 -4
  112. package/dist/agent-i18n/en.json +2 -2
  113. package/dist/apexcharts.css +4 -1
  114. package/dist/components/appointment-card/index.js +2 -2
  115. package/dist/components/appointment-details-panel/index.js +1 -1
  116. package/dist/components/appointment-peek/index.js +1 -1
  117. package/dist/components/appointment-timeline/index.js +1 -1
  118. package/dist/components/booking/index.js +1 -1
  119. package/dist/components/button-group/index.js +1 -1
  120. package/dist/components/care-plan-card/index.js +1 -1
  121. package/dist/components/care-plan-entry-card/index.js +1 -1
  122. package/dist/components/care-plan-header/index.js +1 -1
  123. package/dist/components/chart/chart-axis-scale.d.ts +21 -0
  124. package/dist/components/chart/chart-axis-scale.d.ts.map +1 -0
  125. package/dist/components/chart/chart.agent.d.ts.map +1 -1
  126. package/dist/components/chart/chart.d.ts +55 -0
  127. package/dist/components/chart/chart.d.ts.map +1 -1
  128. package/dist/components/chart/index.d.ts +1 -1
  129. package/dist/components/chart/index.d.ts.map +1 -1
  130. package/dist/components/chart/index.js +1 -1
  131. package/dist/components/dashboard-grid/index.js +1 -1
  132. package/dist/components/data-table/index.js +3 -3
  133. package/dist/components/date-time-picker/index.js +1 -1
  134. package/dist/components/document-preview/index.js +1 -1
  135. package/dist/components/dropdown-menu/index.js +1 -1
  136. package/dist/components/face-scheme/index.js +1 -1
  137. package/dist/components/file-manager/index.js +1 -1
  138. package/dist/components/hcg-doubling/index.js +1 -1
  139. package/dist/components/header-settings/index.js +1 -1
  140. package/dist/components/heatmap/index.js +1 -1
  141. package/dist/components/icon-button-group/index.js +1 -1
  142. package/dist/components/message-tray/index.js +1 -1
  143. package/dist/components/muscle-scheme/index.js +1 -1
  144. package/dist/components/notes-panel/index.js +1 -1
  145. package/dist/components/notification-tray/index.js +1 -1
  146. package/dist/components/patient-details/index.js +1 -1
  147. package/dist/components/patient-search/index.js +1 -1
  148. package/dist/components/patient-summary-card/index.js +1 -1
  149. package/dist/components/patient-table/index.js +1 -1
  150. package/dist/components/practice-results/index.js +1 -1
  151. package/dist/components/product-hub-tray/index.js +1 -1
  152. package/dist/components/public-footer/index.js +1 -1
  153. package/dist/components/rich-text-editor/index.js +1 -1
  154. package/dist/components/separator/index.js +1 -1
  155. package/dist/components/separator/separator.d.ts.map +1 -1
  156. package/dist/components/skeleton-scheme/index.js +1 -1
  157. package/dist/components/slot-grid/index.js +1 -1
  158. package/dist/components/slot-grid/slot-grid.d.ts.map +1 -1
  159. package/dist/components/tab-bar/index.js +1 -1
  160. package/dist/components/tabs/index.js +1 -1
  161. package/dist/components/task-editor/index.js +1 -1
  162. package/dist/components/tasks-panel/index.js +1 -1
  163. package/dist/components/theme-toggle/index.js +1 -1
  164. package/dist/components/time-picker/index.js +1 -1
  165. package/dist/components/time-picker/time-picker.d.ts +15 -8
  166. package/dist/components/time-picker/time-picker.d.ts.map +1 -1
  167. package/dist/components/token-insert-menu/index.js +1 -1
  168. package/dist/components/tooth-scheme/index.js +1 -1
  169. package/dist/components/workflow/index.js +1 -1
  170. package/dist/components/workflow-status/index.js +1 -1
  171. package/dist/core.css +1 -1
  172. package/dist/host-compat.css +4 -1
  173. package/dist/i18n/locales/ar.d.ts +4 -1
  174. package/dist/i18n/locales/ar.d.ts.map +1 -1
  175. package/dist/i18n/locales/ar.js +6 -3
  176. package/dist/i18n/locales/ar.js.map +1 -1
  177. package/dist/i18n/locales/de.d.ts +5 -2
  178. package/dist/i18n/locales/de.d.ts.map +1 -1
  179. package/dist/i18n/locales/de.js +7 -4
  180. package/dist/i18n/locales/de.js.map +1 -1
  181. package/dist/i18n/locales/el.d.ts +5 -2
  182. package/dist/i18n/locales/el.d.ts.map +1 -1
  183. package/dist/i18n/locales/el.js +7 -4
  184. package/dist/i18n/locales/el.js.map +1 -1
  185. package/dist/i18n/locales/en.d.ts +5 -2
  186. package/dist/i18n/locales/en.d.ts.map +1 -1
  187. package/dist/i18n/locales/en.js +6 -3
  188. package/dist/i18n/locales/en.js.map +1 -1
  189. package/dist/i18n/locales/es.d.ts +5 -2
  190. package/dist/i18n/locales/es.d.ts.map +1 -1
  191. package/dist/i18n/locales/es.js +7 -4
  192. package/dist/i18n/locales/es.js.map +1 -1
  193. package/dist/i18n/locales/fr.d.ts +4 -1
  194. package/dist/i18n/locales/fr.d.ts.map +1 -1
  195. package/dist/i18n/locales/fr.js +6 -3
  196. package/dist/i18n/locales/fr.js.map +1 -1
  197. package/dist/i18n/locales/hi.d.ts +5 -2
  198. package/dist/i18n/locales/hi.d.ts.map +1 -1
  199. package/dist/i18n/locales/hi.js +7 -4
  200. package/dist/i18n/locales/hi.js.map +1 -1
  201. package/dist/i18n/locales/it.d.ts +5 -2
  202. package/dist/i18n/locales/it.d.ts.map +1 -1
  203. package/dist/i18n/locales/it.js +7 -4
  204. package/dist/i18n/locales/it.js.map +1 -1
  205. package/dist/i18n/locales/ja.d.ts +5 -2
  206. package/dist/i18n/locales/ja.d.ts.map +1 -1
  207. package/dist/i18n/locales/ja.js +7 -4
  208. package/dist/i18n/locales/ja.js.map +1 -1
  209. package/dist/i18n/locales/nl.d.ts +5 -2
  210. package/dist/i18n/locales/nl.d.ts.map +1 -1
  211. package/dist/i18n/locales/nl.js +7 -4
  212. package/dist/i18n/locales/nl.js.map +1 -1
  213. package/dist/i18n/locales/pl.d.ts +5 -2
  214. package/dist/i18n/locales/pl.d.ts.map +1 -1
  215. package/dist/i18n/locales/pl.js +7 -4
  216. package/dist/i18n/locales/pl.js.map +1 -1
  217. package/dist/i18n/locales/pt.d.ts +4 -1
  218. package/dist/i18n/locales/pt.d.ts.map +1 -1
  219. package/dist/i18n/locales/pt.js +6 -3
  220. package/dist/i18n/locales/pt.js.map +1 -1
  221. package/dist/i18n/locales/ro.d.ts +5 -2
  222. package/dist/i18n/locales/ro.d.ts.map +1 -1
  223. package/dist/i18n/locales/ro.js +7 -4
  224. package/dist/i18n/locales/ro.js.map +1 -1
  225. package/dist/i18n/locales/ru.d.ts +5 -2
  226. package/dist/i18n/locales/ru.d.ts.map +1 -1
  227. package/dist/i18n/locales/ru.js +7 -4
  228. package/dist/i18n/locales/ru.js.map +1 -1
  229. package/dist/i18n/locales/sq.d.ts +5 -2
  230. package/dist/i18n/locales/sq.d.ts.map +1 -1
  231. package/dist/i18n/locales/sq.js +7 -4
  232. package/dist/i18n/locales/sq.js.map +1 -1
  233. package/dist/i18n/locales/sv.d.ts +5 -2
  234. package/dist/i18n/locales/sv.d.ts.map +1 -1
  235. package/dist/i18n/locales/sv.js +7 -4
  236. package/dist/i18n/locales/sv.js.map +1 -1
  237. package/dist/i18n/locales/tr.d.ts +5 -2
  238. package/dist/i18n/locales/tr.d.ts.map +1 -1
  239. package/dist/i18n/locales/tr.js +7 -4
  240. package/dist/i18n/locales/tr.js.map +1 -1
  241. package/dist/i18n/locales/zh.d.ts +5 -2
  242. package/dist/i18n/locales/zh.d.ts.map +1 -1
  243. package/dist/i18n/locales/zh.js +7 -4
  244. package/dist/i18n/locales/zh.js.map +1 -1
  245. package/dist/index.js +53 -53
  246. package/dist/locales/ar.json +6 -3
  247. package/dist/locales/de.json +7 -4
  248. package/dist/locales/el.json +7 -4
  249. package/dist/locales/en.json +6 -3
  250. package/dist/locales/es.json +7 -4
  251. package/dist/locales/fr.json +6 -3
  252. package/dist/locales/hi.json +7 -4
  253. package/dist/locales/it.json +7 -4
  254. package/dist/locales/ja.json +7 -4
  255. package/dist/locales/nl.json +7 -4
  256. package/dist/locales/pl.json +7 -4
  257. package/dist/locales/pt.json +6 -3
  258. package/dist/locales/ro.json +7 -4
  259. package/dist/locales/ru.json +7 -4
  260. package/dist/locales/sq.json +7 -4
  261. package/dist/locales/sv.json +7 -4
  262. package/dist/locales/tr.json +7 -4
  263. package/dist/locales/zh.json +7 -4
  264. package/dist/patterns/anamnesis/index.js +1 -1
  265. package/dist/patterns/calendar/index.js +1 -1
  266. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  267. package/dist/patterns/signature-request/index.js +1 -1
  268. package/dist/patterns/signed-out-frame/index.js +1 -1
  269. package/dist/patterns/workflow-webhook-action/index.js +1 -1
  270. package/dist/tokens.css +4 -1
  271. package/package.json +1 -1
  272. package/dist/_chunks/chart-D4huJSru.js +0 -1340
  273. package/dist/_chunks/chart-D4huJSru.js.map +0 -1
  274. package/dist/_chunks/practice-results-BWX9y6mS.js.map +0 -1
  275. package/dist/_chunks/separator-CYU_bGFn.js.map +0 -1
  276. package/dist/_chunks/time-picker-DVfyAR81.js +0 -871
  277. package/dist/_chunks/time-picker-DVfyAR81.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-menu-D1we7oAY.js","sources":["../../src/components/dropdown-menu/dropdown-menu.agent.ts","../../src/components/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { DropdownMenuHandle } from './dropdown-menu';\n\n// The handle cannot run an arbitrary item (Radix owns item activation), so\n// there is no 'pick' capability. It CAN drive settings rows: a ChoiceSub or\n// SwitchItem given a `name` registers with its Root, and set_value /\n// set_checked call that row's own onValueChange / onCheckedChange, exactly\n// as a click would. Rows mount with the menu, so a closed menu opens for the\n// moment and closes again.\nexport const dropdownMenuAgent: AgentAdapter<DropdownMenuHandle> = {\n id: 'dropdown-menu',\n capabilities: ['open', 'close', 'set_value'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dropdownMenu.state.isOpen',\n description: 'True when the menu is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n settings: {\n type: 'Array<{ setting: string; kind: \"choice\" | \"switch\"; value?: string; options?: string[]; checked?: boolean; disabled: boolean }>',\n descriptionKey: 'ui.agent.dropdownMenu.state.settings',\n description:\n \"The menu's named settings rows and their current values: choice rows with the selected value and every option's value, switch rows with whether they are on. Rows are listed only while the menu is open; open it first to read them.\",\n read: (handle) => handle.getSettings(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.open',\n description: 'Open the menu.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.close',\n description: 'Close the menu.',\n invoke: (handle) => {\n handle.close();\n },\n },\n set_value: {\n safety: 'write',\n argsType: '{ setting: string; value: string }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n value: {\n type: 'string',\n description: \"One of the row's option values.\",\n },\n },\n required: ['setting', 'value'],\n },\n idempotent: true,\n errors: [\n 'No choice row with that name in this menu',\n 'The value is not one of the options, or it or the row is disabled',\n ],\n examples: [\n {\n args: { setting: 'slotDensity', value: 'comfortable' },\n note: 'Calendar display settings: switch to comfortable rows.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setValue',\n description:\n 'Pick an option on a named choice row (ChoiceSub), as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; value: string }) =>\n handle.setValue(args.setting, args.value),\n },\n set_checked: {\n safety: 'write',\n argsType: '{ setting: string; checked: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n checked: { type: 'boolean' },\n },\n required: ['setting', 'checked'],\n },\n idempotent: true,\n errors: [\n 'No switch row with that name in this menu',\n 'The row is disabled',\n ],\n examples: [\n {\n args: { setting: 'zebraRows', checked: true },\n note: 'Calendar display settings: turn zebra rows on.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setChecked',\n description:\n 'Turn a named switch row (SwitchItem) on or off, as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; checked: boolean }) =>\n handle.setChecked(args.setting, args.checked),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dropdown-menu' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on DropdownMenu.Root.',\n },\n item: {\n attr: 'data-setting',\n sourceProp: 'name',\n description:\n 'On a ChoiceSub or SwitchItem row given a name: the setting that set_value / set_checked address.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\nimport { Separator as DsSeparator } from '../separator/separator';\nimport { Kbd, type KbdNamedKey } from '../kbd/kbd';\nimport { useDocumentDirection } from '../_shared/use-direction';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport { PopupRegion } from '../_shared/popup-region';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { dropdownMenuAgent } from './dropdown-menu.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst contentVariants = cva(\n [\n 'ds:z-[var(--z-dropdown)]',\n // Roomier panel: wider floor, larger radius, deeper float and a\n // breath more padding so menus read as elevated surfaces rather\n // than flat lists hugging their trigger.\n 'ds:min-w-[14rem]',\n 'ds:rounded-[var(--radius-lg)]',\n // Border kept (transparent) so the forced-colors override below can\n // repaint a visible edge in HCM. In normal modes the soft drop-shadow\n // carries the edge cue; the heavy `--border` (grey-800 since WCAG\n // 1.4.11 bump in 67fef8c) made the menu read as a charcoal box.\n 'ds:border ds:border-transparent',\n 'ds:bg-[var(--popover)] ds:text-[color:var(--popover-foreground)]',\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:p-[var(--spacing-sm)]',\n // Never taller than the room Radix measures beside the trigger: a long\n // menu scrolls instead of running off the screen. Submenus portal out,\n // so the scroll never clips them. Radix sets the same variable on\n // Content and SubContent.\n 'ds:max-h-[var(--radix-dropdown-menu-content-available-height)] ds:overflow-y-auto',\n // Motion — gated on --animation-duration via Tailwind's animate-in\n // preset. motion-reduce disables via the no-preference query.\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:fade-in ds:data-[state=closed]:fade-out',\n 'ds:data-[state=open]:zoom-in-95 ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[state=open]:slide-in-from-top-1',\n 'ds:motion-reduce:animate-none',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n);\n\nconst itemClasses = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n 'ds:cursor-pointer ds:select-none ds:outline-none',\n // Radix highlights on hover and on keyboard focus alike.\n MENU_ROW_HIGHLIGHT.highlighted,\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n // Disabled\n 'ds:data-[disabled]:opacity-50 ds:data-[disabled]:cursor-not-allowed',\n 'ds:data-[disabled]:pointer-events-none',\n ].join(' '),\n);\n\nconst labelClasses = cva(\n [\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-2xs)]',\n // Quiet sentence-case caption — the shouty uppercase eyebrow made\n // every menu read as a form. Groups should lean on separators first\n // and reach for a Label only when the grouping is genuinely unclear.\n 'ds:text-[length:var(--font-size-xs)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:text-[color:var(--muted-foreground)]',\n 'ds:select-none',\n ].join(' '),\n);\n\nconst indicatorSlotClasses =\n 'ds:inline-flex ds:items-center ds:justify-center ds:size-4 ds:shrink-0';\n\n/* ------------------------------------------------------------------ */\n/* Root / Trigger / Portal */\n/* ------------------------------------------------------------------ */\n\n/** A named settings row (a ChoiceSub or SwitchItem given a `name`) and\n * its current state, as an agent reads it. Values only, never labels. */\nexport interface DropdownMenuSetting {\n setting: string;\n kind: 'choice' | 'switch';\n /** ChoiceSub: the selected value and every option's value. */\n value?: string;\n options?: string[];\n /** SwitchItem: whether it is on. */\n checked?: boolean;\n disabled: boolean;\n}\n\n// Curated agent-readiness handle — see dropdown-menu.agent.ts.\nexport interface DropdownMenuHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n /** The named settings rows, while the menu is open (closed: none). */\n getSettings: () => DropdownMenuSetting[];\n /** Pick `value` on the named ChoiceSub. A closed menu opens for the\n * moment and closes again. Rejects on an unknown row, value or a\n * disabled one. */\n setValue: (setting: string, value: string) => Promise<void>;\n /** Turn the named SwitchItem on or off, as `setValue` does. */\n setChecked: (setting: string, checked: boolean) => Promise<void>;\n}\n\n/* A named row registers with its Root so the handle can drive it. */\ntype SettingRow =\n | {\n kind: 'choice';\n read: () => {\n value: string;\n options: ReadonlyArray<{ value: string; disabled?: boolean }>;\n disabled: boolean;\n closeOnSelect: boolean;\n };\n pick: (value: string) => void;\n }\n | {\n kind: 'switch';\n read: () => { checked: boolean; disabled: boolean };\n pick: (checked: boolean) => void;\n };\n\ntype RegisterSettingRow = (name: string, row: SettingRow) => () => void;\n\nconst SettingRowsContext = createContext<RegisterSettingRow | undefined>(\n undefined,\n);\n\nconst nextFrame = () =>\n new Promise<void>((resolve) => {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => resolve());\n } else {\n setTimeout(resolve, 16);\n }\n });\n\nexport interface DropdownMenuRootProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Root\n> {\n /** Opaque instance id — forwarded to DropdownMenu.Content as `data-component-id`. */\n id?: string;\n}\n\nconst DropdownMenuIdContext = createContext<string | undefined>(undefined);\n\nconst Root = ({\n dir,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}: DropdownMenuRootProps) => {\n const autoDir = useDocumentDirection();\n const [openRaw, setOpen] = useControllableState<boolean>({\n value: openProp,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const open = openRaw ?? false;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const rowsRef = useRef(new Map<string, SettingRow>());\n // Counts explicit open/close calls on the handle.\n const openRequestsRef = useRef(0);\n const registerRow = useMemo<RegisterSettingRow>(\n () => (name, row) => {\n rowsRef.current.set(name, row);\n return () => {\n if (rowsRef.current.get(name) === row) rowsRef.current.delete(name);\n };\n },\n [],\n );\n\n const handle = useMemo<DropdownMenuHandle>(() => {\n /* Rows mount with the menu. A closed menu opens for the moment, waits\n for the row to register, and closes again once the change lands. */\n // open/close update the ref at once, not a render later, so a set\n // right after an explicit open() sees the menu as open and leaves it so.\n const show = (next: boolean) => {\n openRef.current = next;\n setOpen(next);\n };\n const withRow = async <K extends SettingRow['kind']>(\n setting: string,\n kind: K,\n apply: (row: Extract<SettingRow, { kind: K }>) => void,\n ) => {\n const opened = !openRef.current;\n if (opened) show(true);\n const requests = openRequestsRef.current;\n try {\n // A row mounts a render or two after the menu opens.\n let row = rowsRef.current.get(setting);\n for (let frame = 0; !row && frame < 30; frame += 1) {\n await nextFrame();\n row = rowsRef.current.get(setting);\n }\n if (!row || row.kind !== kind) {\n throw new Error(`No ${kind} setting named \"${setting}\" in this menu`);\n }\n apply(row as Extract<SettingRow, { kind: K }>);\n } finally {\n // Close only a menu this call opened, and nobody asked for since.\n if (opened && openRequestsRef.current === requests) show(false);\n }\n };\n return {\n getIsOpen: () => openRef.current,\n open: () => {\n openRequestsRef.current += 1;\n show(true);\n },\n close: () => {\n openRequestsRef.current += 1;\n show(false);\n },\n getSettings: () =>\n [...rowsRef.current].map(([setting, row]) => {\n if (row.kind === 'choice') {\n const { value, options, disabled } = row.read();\n return {\n setting,\n kind: 'choice' as const,\n value,\n options: options.map((option) => option.value),\n disabled,\n };\n }\n const { checked, disabled } = row.read();\n return { setting, kind: 'switch' as const, checked, disabled };\n }),\n setValue: (setting, value) =>\n withRow(setting, 'choice', (row) => {\n const { options, disabled, closeOnSelect } = row.read();\n const option = options.find((o) => o.value === value);\n if (disabled || !option || option.disabled) {\n throw new Error(\n `\"${value}\" is not an option that \"${setting}\" can take now`,\n );\n }\n row.pick(value);\n // As a click on the option would.\n if (closeOnSelect) show(false);\n }),\n setChecked: (setting, checked) =>\n withRow(setting, 'switch', (row) => {\n if (row.read().disabled) {\n throw new Error(`\"${setting}\" is disabled`);\n }\n row.pick(checked);\n }),\n };\n }, [setOpen]);\n useAgentRegistration(dropdownMenuAgent, handle, id);\n\n return (\n <DropdownMenuIdContext.Provider value={id}>\n <SettingRowsContext.Provider value={registerRow}>\n <RadixDropdownMenu.Root\n dir={dir ?? autoDir}\n open={open}\n onOpenChange={setOpen}\n {...props}\n />\n </SettingRowsContext.Provider>\n </DropdownMenuIdContext.Provider>\n );\n};\nRoot.displayName = 'DropdownMenu.Root';\n\nconst Trigger = RadixDropdownMenu.Trigger;\nconst Portal = RadixDropdownMenu.Portal;\nconst RadixGroup = RadixDropdownMenu.Group;\nconst RadixRadioGroup = RadixDropdownMenu.RadioGroup;\n\n/* ------------------------------------------------------------------ */\n/* Content */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuContentProps\n extends\n ComponentPropsWithoutRef<typeof RadixDropdownMenu.Content>,\n VariantProps<typeof contentVariants> {}\n\nconst Content = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Content>,\n DropdownMenuContentProps\n>(({ className, sideOffset = 8, ...props }, ref) => {\n const instanceId = useContext(DropdownMenuIdContext);\n return (\n <RadixDropdownMenu.Portal>\n {/* A region named after the trigger, so axe `region` passes while open. */}\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.Content\n ref={popupRef}\n sideOffset={sideOffset}\n className={contentVariants({ className })}\n data-component=\"dropdown-menu\"\n data-component-id={instanceId}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n );\n});\nContent.displayName = 'DropdownMenu.Content';\n\n/* ------------------------------------------------------------------ */\n/* Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Item\n> {\n startIcon?: ReactNode;\n endIcon?: ReactNode;\n description?: ReactNode;\n /** Convenience — renders a DS <Kbd keys={…}> on the inline-end. */\n shortcut?: Array<KbdNamedKey | string>;\n}\n\nconst Item = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n className,\n startIcon,\n endIcon,\n description,\n shortcut,\n children,\n ...props\n },\n ref,\n ) => (\n <RadixDropdownMenu.Item\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:flex ds:flex-col ds:min-w-0\">\n <span className=\"ds:truncate\">{children}</span>\n {description ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {description}\n </span>\n ) : null}\n </span>\n {shortcut ? (\n <span className=\"ds:ms-auto\">\n <Kbd keys={shortcut} size=\"sm\" />\n </span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:ms-auto ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {endIcon}\n </span>\n ) : null}\n </RadixDropdownMenu.Item>\n ),\n);\nItem.displayName = 'DropdownMenu.Item';\n\n/* ------------------------------------------------------------------ */\n/* CheckboxItem */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuCheckboxItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n>;\n\nconst CheckboxItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n <span className={indicatorSlotClasses}>\n <RadixDropdownMenu.ItemIndicator>\n <Check aria-hidden className=\"ds:size-4\" />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.CheckboxItem>\n));\nCheckboxItem.displayName = 'DropdownMenu.CheckboxItem';\n\n/* Registers a named row with its Root for as long as it is mounted. The\n row object is rebuilt each render; the Root reads it through a ref, so\n it always sees the latest value and callback. */\nfunction useSettingRow(name: string | undefined, row: SettingRow): void {\n const register = useContext(SettingRowsContext);\n const latest = useRef(row);\n useLayoutEffect(() => {\n latest.current = row;\n });\n useEffect(() => {\n if (!name || !register) return undefined;\n const proxy: SettingRow =\n latest.current.kind === 'choice'\n ? {\n kind: 'choice',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'choice' }>\n ).read(),\n pick: (value) =>\n (latest.current as Extract<SettingRow, { kind: 'choice' }>).pick(\n value,\n ),\n }\n : {\n kind: 'switch',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'switch' }>\n ).read(),\n pick: (checked) =>\n (latest.current as Extract<SettingRow, { kind: 'switch' }>).pick(\n checked,\n ),\n };\n return register(name, proxy);\n }, [name, register]);\n}\n\n/* ------------------------------------------------------------------ */\n/* SwitchItem */\n/* */\n/* A persistent on/off toggle row (menuitemcheckbox semantics) whose */\n/* indicator is a trailing switch glyph instead of a tick — for */\n/* settings that live inside a menu (e.g. accessible mode). Selecting */\n/* keeps the menu open so the user sees the toggle land. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuSwitchItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n> {\n /** Names the row for agents (the menu's `set_checked` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n}\n\n// Mirrors the kit Switch's `sm` metrics (track h-4 w-7, thumb size-3)\n// and its primary checked fill so the two switch affordances stay kin.\n// The muted-foreground border keeps the OFF state perceivable — without\n// it the muted track sits at ~1.2:1 on the popover (WCAG 1.4.11).\nconst switchTrackClasses = [\n 'ds:ms-auto ds:inline-flex ds:items-center ds:shrink-0',\n 'ds:h-4 ds:w-7 ds:p-[2px]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:bg-[color:var(--muted)]',\n 'ds:[[data-state=checked]_&]:bg-[color:var(--primary)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--primary)]',\n // Thumb slides via justify swap — logical-direction safe, no\n // transform to fight under prefers-reduced-motion.\n 'ds:justify-start ds:[[data-state=checked]_&]:justify-end',\n 'ds:forced-colors:border-[CanvasText]',\n // HCM strips fills — paint the checked track with the system\n // selection colour so state isn't conveyed by thumb position alone.\n 'ds:forced-colors:[[data-state=checked]_&]:bg-[SelectedItem]',\n].join(' ');\n\nconst switchThumbClasses = [\n 'ds:block ds:size-3',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[color:var(--background)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-transparent',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\nconst SwitchItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuSwitchItemProps\n>(({ className, children, onSelect, name, ...props }, ref) => {\n const { checked, onCheckedChange, disabled } = props;\n useSettingRow(name, {\n kind: 'switch',\n read: () => ({ checked: checked === true, disabled: disabled === true }),\n // What a click does, and only when it would change something: the\n // consumer's onSelect, then the new state.\n pick: (next) => {\n if (next === (checked === true)) return;\n onSelect?.(new Event('menu.itemSelect', { cancelable: true }));\n onCheckedChange?.(next);\n },\n });\n return (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n data-setting={name}\n onSelect={(event) => {\n // Keep-open is unconditional — prevent first so a throwing consumer\n // handler can't close the menu as a side effect.\n event.preventDefault();\n onSelect?.(event);\n }}\n {...props}\n >\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <span aria-hidden=\"true\" className={switchTrackClasses}>\n <span className={switchThumbClasses} />\n </span>\n </RadixDropdownMenu.CheckboxItem>\n );\n});\nSwitchItem.displayName = 'DropdownMenu.SwitchItem';\n\n/* ------------------------------------------------------------------ */\n/* RadioGroup / RadioItem */\n/* ------------------------------------------------------------------ */\n\nconst RadioGroup = RadixRadioGroup;\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.RadioItem\n>;\n\nconst RadioItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.RadioItem>,\n DropdownMenuRadioItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.RadioItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {/* Real radio affordance: an always-visible ring with a filled dot\n when selected — a tick reads as a checkbox, not a single choice.\n The ring colours via the item's own data-state so the unchecked\n options still advertise that they are part of a radio set. */}\n <span className={indicatorSlotClasses} aria-hidden=\"true\">\n <span\n className={[\n 'ds:inline-flex ds:size-4 ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--accent)]',\n // Accent on the lit row would vanish, so ring and dot take its ink.\n 'ds:not-forced-colors:[[data-highlighted][data-state=checked]_&]:border-[color:var(--accent-foreground)]',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' ')}\n >\n <RadixDropdownMenu.ItemIndicator>\n <span\n className={[\n 'ds:block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--accent)]',\n 'ds:not-forced-colors:group-data-[highlighted]/menu-row:bg-[color:var(--accent-foreground)]',\n 'ds:forced-colors:bg-[CanvasText]',\n ].join(' ')}\n />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.RadioItem>\n));\nRadioItem.displayName = 'DropdownMenu.RadioItem';\n\n/* ------------------------------------------------------------------ */\n/* Label */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Label\n>;\n\nconst Label = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Label>,\n DropdownMenuLabelProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Label\n ref={ref}\n className={labelClasses({ className })}\n {...props}\n />\n));\nLabel.displayName = 'DropdownMenu.Label';\n\n/* ------------------------------------------------------------------ */\n/* Separator */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Separator\n>;\n\nconst MenuSeparator = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Separator ref={ref} asChild {...props}>\n <DsSeparator\n className={['ds:my-[calc(var(--spacing-xs)/2)]', className ?? '']\n .filter(Boolean)\n .join(' ')}\n />\n </RadixDropdownMenu.Separator>\n));\nMenuSeparator.displayName = 'DropdownMenu.Separator';\n\n/* ------------------------------------------------------------------ */\n/* Shortcut — thin wrapper over DS Kbd for the right side of an Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuShortcutProps {\n keys: Array<KbdNamedKey | string>;\n separator?: 'none' | 'plus' | 'then';\n}\n\nconst Shortcut = forwardRef<HTMLSpanElement, DropdownMenuShortcutProps>(\n ({ keys, separator = 'none' }, ref) => (\n <span ref={ref} className=\"ds:ms-auto ds:ps-[var(--spacing-sm)]\">\n <Kbd keys={keys} separator={separator} size=\"sm\" />\n </span>\n ),\n);\nShortcut.displayName = 'DropdownMenu.Shortcut';\n\n/* ------------------------------------------------------------------ */\n/* Sub-menu */\n/* ------------------------------------------------------------------ */\n\nconst Sub = RadixDropdownMenu.Sub;\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubTrigger\n> {\n startIcon?: ReactNode;\n}\n\nconst SubTrigger = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(({ className, startIcon, children, ...props }, ref) => (\n <RadixDropdownMenu.SubTrigger\n ref={ref}\n // Stays lit while focus is in its submenu, so the path is visible.\n className={itemClasses({\n className: [MENU_ROW_HIGHLIGHT.open, className].filter(Boolean).join(' '),\n })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <ChevronRight\n aria-hidden\n className=\"ds:ms-auto ds:size-4 ds:shrink-0 ds:rtl:-scale-x-100\"\n />\n </RadixDropdownMenu.SubTrigger>\n));\nSubTrigger.displayName = 'DropdownMenu.SubTrigger';\n\nexport type DropdownMenuSubContentProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubContent\n>;\n\nconst SubContent = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubContent>,\n DropdownMenuSubContentProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Portal>\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.SubContent\n ref={popupRef}\n sideOffset={8}\n data-component=\"dropdown-menu-sub-content\"\n className={contentVariants({ className })}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n));\nSubContent.displayName = 'DropdownMenu.SubContent';\n\n/* ------------------------------------------------------------------ */\n/* ChoiceSub */\n/* */\n/* One setting with a few exclusive options, as a single menu row that */\n/* names the setting and shows its current value (\"Row density · */\n/* Compact ›\"). The row opens a submenu of radio items. It replaces the */\n/* \"label + Select\" row inside popovers: no Select ever opens inside a */\n/* menu, and the whole settings menu stays keyboard-native. Picking an */\n/* option keeps the menu open by default, like SwitchItem, so the user */\n/* sees the value land and can adjust the next setting. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuChoiceOption<T extends string = string> {\n value: T;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface DropdownMenuChoiceSubProps<T extends string = string> {\n /** The setting's name, shown at the start of the row. */\n label: ReactNode;\n /** The selected option's value; its label shows at the end of the row. */\n value: T;\n onValueChange: (value: T) => void;\n options: ReadonlyArray<DropdownMenuChoiceOption<T>>;\n startIcon?: ReactNode;\n disabled?: boolean;\n /** Close the whole menu after a pick. @default false */\n closeOnSelect?: boolean;\n /** Names the row for agents (the menu's `set_value` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n className?: string;\n}\n\nfunction ChoiceSub<T extends string>({\n label,\n value,\n onValueChange,\n options,\n startIcon,\n disabled,\n closeOnSelect = false,\n name,\n className,\n}: DropdownMenuChoiceSubProps<T>) {\n const current = options.find((option) => option.value === value);\n useSettingRow(name, {\n kind: 'choice',\n read: () => ({\n value,\n options,\n disabled: disabled === true,\n closeOnSelect,\n }),\n pick: (next) => onValueChange(next as T),\n });\n return (\n <Sub>\n <SubTrigger\n startIcon={startIcon}\n disabled={disabled}\n className={className}\n data-component=\"dropdown-menu-choice\"\n data-value={value}\n data-setting={name}\n >\n <span className=\"ds:flex ds:min-w-0 ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <span className=\"ds:truncate\">{label}</span>\n {current ? (\n <span className=\"ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:[[data-highlighted]_&]:text-current\">\n {current.label}\n </span>\n ) : null}\n </span>\n </SubTrigger>\n <SubContent>\n <RadioGroup\n value={value}\n onValueChange={(next) => onValueChange(next as T)}\n >\n {options.map((option) => (\n <RadioItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={\n closeOnSelect ? undefined : (event) => event.preventDefault()\n }\n >\n {option.label}\n </RadioItem>\n ))}\n </RadioGroup>\n </SubContent>\n </Sub>\n );\n}\nChoiceSub.displayName = 'DropdownMenu.ChoiceSub';\n\n/* ------------------------------------------------------------------ */\n/* Assembled namespace export */\n/* ------------------------------------------------------------------ */\n\nexport const DropdownMenu = {\n Root,\n Trigger,\n Portal,\n Content,\n Group: RadixGroup,\n Item,\n CheckboxItem,\n SwitchItem,\n RadioGroup,\n RadioItem,\n Label,\n Separator: MenuSeparator,\n Shortcut,\n Sub,\n SubTrigger,\n SubContent,\n ChoiceSub,\n};\n"],"names":["dropdownMenuAgent","handle","args","contentVariants","cva","itemClasses","MENU_ROW_HIGHLIGHT","labelClasses","indicatorSlotClasses","SettingRowsContext","createContext","nextFrame","resolve","DropdownMenuIdContext","Root","dir","id","openProp","defaultOpen","onOpenChange","props","autoDir","useDocumentDirection","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","rowsRef","openRequestsRef","registerRow","useMemo","name","row","show","next","withRow","setting","kind","apply","opened","requests","frame","value","options","disabled","option","checked","closeOnSelect","o","useAgentRegistration","jsx","RadixDropdownMenu","Trigger","Portal","RadixGroup","RadixRadioGroup","Content","forwardRef","className","sideOffset","ref","instanceId","useContext","PopupRegion","popupRef","Item","startIcon","endIcon","description","shortcut","children","jsxs","Kbd","CheckboxItem","Check","useSettingRow","register","latest","useLayoutEffect","proxy","switchTrackClasses","switchThumbClasses","SwitchItem","onSelect","onCheckedChange","event","RadioGroup","RadioItem","Label","MenuSeparator","DsSeparator","Shortcut","keys","separator","Sub","SubTrigger","ChevronRight","SubContent","ChoiceSub","label","onValueChange","current","DropdownMenu"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-menu-CqxBthww.js","sources":["../../src/components/dropdown-menu/dropdown-menu.agent.ts","../../src/components/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { DropdownMenuHandle } from './dropdown-menu';\n\n// The handle cannot run an arbitrary item (Radix owns item activation), so\n// there is no 'pick' capability. It CAN drive settings rows: a ChoiceSub or\n// SwitchItem given a `name` registers with its Root, and set_value /\n// set_checked call that row's own onValueChange / onCheckedChange, exactly\n// as a click would. Rows mount with the menu, so a closed menu opens for the\n// moment and closes again.\nexport const dropdownMenuAgent: AgentAdapter<DropdownMenuHandle> = {\n id: 'dropdown-menu',\n capabilities: ['open', 'close', 'set_value'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dropdownMenu.state.isOpen',\n description: 'True when the menu is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n settings: {\n type: 'Array<{ setting: string; kind: \"choice\" | \"switch\"; value?: string; options?: string[]; checked?: boolean; disabled: boolean }>',\n descriptionKey: 'ui.agent.dropdownMenu.state.settings',\n description:\n \"The menu's named settings rows and their current values: choice rows with the selected value and every option's value, switch rows with whether they are on. Rows are listed only while the menu is open; open it first to read them.\",\n read: (handle) => handle.getSettings(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.open',\n description: 'Open the menu.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.close',\n description: 'Close the menu.',\n invoke: (handle) => {\n handle.close();\n },\n },\n set_value: {\n safety: 'write',\n argsType: '{ setting: string; value: string }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n value: {\n type: 'string',\n description: \"One of the row's option values.\",\n },\n },\n required: ['setting', 'value'],\n },\n idempotent: true,\n errors: [\n 'No choice row with that name in this menu',\n 'The value is not one of the options, or it or the row is disabled',\n ],\n examples: [\n {\n args: { setting: 'slotDensity', value: 'comfortable' },\n note: 'Calendar display settings: switch to comfortable rows.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setValue',\n description:\n 'Pick an option on a named choice row (ChoiceSub), as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; value: string }) =>\n handle.setValue(args.setting, args.value),\n },\n set_checked: {\n safety: 'write',\n argsType: '{ setting: string; checked: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n checked: { type: 'boolean' },\n },\n required: ['setting', 'checked'],\n },\n idempotent: true,\n errors: [\n 'No switch row with that name in this menu',\n 'The row is disabled',\n ],\n examples: [\n {\n args: { setting: 'zebraRows', checked: true },\n note: 'Calendar display settings: turn zebra rows on.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setChecked',\n description:\n 'Turn a named switch row (SwitchItem) on or off, as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; checked: boolean }) =>\n handle.setChecked(args.setting, args.checked),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dropdown-menu' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on DropdownMenu.Root.',\n },\n item: {\n attr: 'data-setting',\n sourceProp: 'name',\n description:\n 'On a ChoiceSub or SwitchItem row given a name: the setting that set_value / set_checked address.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\nimport { Separator as DsSeparator } from '../separator/separator';\nimport { Kbd, type KbdNamedKey } from '../kbd/kbd';\nimport { useDocumentDirection } from '../_shared/use-direction';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport { PopupRegion } from '../_shared/popup-region';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { dropdownMenuAgent } from './dropdown-menu.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst contentVariants = cva(\n [\n 'ds:z-[var(--z-dropdown)]',\n // Roomier panel: wider floor, larger radius, deeper float and a\n // breath more padding so menus read as elevated surfaces rather\n // than flat lists hugging their trigger.\n 'ds:min-w-[14rem]',\n 'ds:rounded-[var(--radius-lg)]',\n // Border kept (transparent) so the forced-colors override below can\n // repaint a visible edge in HCM. In normal modes the soft drop-shadow\n // carries the edge cue; the heavy `--border` (grey-800 since WCAG\n // 1.4.11 bump in 67fef8c) made the menu read as a charcoal box.\n 'ds:border ds:border-transparent',\n 'ds:bg-[var(--popover)] ds:text-[color:var(--popover-foreground)]',\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:p-[var(--spacing-sm)]',\n // Never taller than the room Radix measures beside the trigger: a long\n // menu scrolls instead of running off the screen. Submenus portal out,\n // so the scroll never clips them. Radix sets the same variable on\n // Content and SubContent.\n 'ds:max-h-[var(--radix-dropdown-menu-content-available-height)] ds:overflow-y-auto',\n // Motion — gated on --animation-duration via Tailwind's animate-in\n // preset. motion-reduce disables via the no-preference query.\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:fade-in ds:data-[state=closed]:fade-out',\n 'ds:data-[state=open]:zoom-in-95 ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[state=open]:slide-in-from-top-1',\n 'ds:motion-reduce:animate-none',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n);\n\nconst itemClasses = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n 'ds:cursor-pointer ds:select-none ds:outline-none',\n // Radix highlights on hover and on keyboard focus alike.\n MENU_ROW_HIGHLIGHT.highlighted,\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n // Disabled\n 'ds:data-[disabled]:opacity-50 ds:data-[disabled]:cursor-not-allowed',\n 'ds:data-[disabled]:pointer-events-none',\n ].join(' '),\n);\n\nconst labelClasses = cva(\n [\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-2xs)]',\n // Quiet sentence-case caption — the shouty uppercase eyebrow made\n // every menu read as a form. Groups should lean on separators first\n // and reach for a Label only when the grouping is genuinely unclear.\n 'ds:text-[length:var(--font-size-xs)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:text-[color:var(--muted-foreground)]',\n 'ds:select-none',\n ].join(' '),\n);\n\nconst indicatorSlotClasses =\n 'ds:inline-flex ds:items-center ds:justify-center ds:size-4 ds:shrink-0';\n\n/* ------------------------------------------------------------------ */\n/* Root / Trigger / Portal */\n/* ------------------------------------------------------------------ */\n\n/** A named settings row (a ChoiceSub or SwitchItem given a `name`) and\n * its current state, as an agent reads it. Values only, never labels. */\nexport interface DropdownMenuSetting {\n setting: string;\n kind: 'choice' | 'switch';\n /** ChoiceSub: the selected value and every option's value. */\n value?: string;\n options?: string[];\n /** SwitchItem: whether it is on. */\n checked?: boolean;\n disabled: boolean;\n}\n\n// Curated agent-readiness handle — see dropdown-menu.agent.ts.\nexport interface DropdownMenuHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n /** The named settings rows, while the menu is open (closed: none). */\n getSettings: () => DropdownMenuSetting[];\n /** Pick `value` on the named ChoiceSub. A closed menu opens for the\n * moment and closes again. Rejects on an unknown row, value or a\n * disabled one. */\n setValue: (setting: string, value: string) => Promise<void>;\n /** Turn the named SwitchItem on or off, as `setValue` does. */\n setChecked: (setting: string, checked: boolean) => Promise<void>;\n}\n\n/* A named row registers with its Root so the handle can drive it. */\ntype SettingRow =\n | {\n kind: 'choice';\n read: () => {\n value: string;\n options: ReadonlyArray<{ value: string; disabled?: boolean }>;\n disabled: boolean;\n closeOnSelect: boolean;\n };\n pick: (value: string) => void;\n }\n | {\n kind: 'switch';\n read: () => { checked: boolean; disabled: boolean };\n pick: (checked: boolean) => void;\n };\n\ntype RegisterSettingRow = (name: string, row: SettingRow) => () => void;\n\nconst SettingRowsContext = createContext<RegisterSettingRow | undefined>(\n undefined,\n);\n\nconst nextFrame = () =>\n new Promise<void>((resolve) => {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => resolve());\n } else {\n setTimeout(resolve, 16);\n }\n });\n\nexport interface DropdownMenuRootProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Root\n> {\n /** Opaque instance id — forwarded to DropdownMenu.Content as `data-component-id`. */\n id?: string;\n}\n\nconst DropdownMenuIdContext = createContext<string | undefined>(undefined);\n\nconst Root = ({\n dir,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}: DropdownMenuRootProps) => {\n const autoDir = useDocumentDirection();\n const [openRaw, setOpen] = useControllableState<boolean>({\n value: openProp,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const open = openRaw ?? false;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const rowsRef = useRef(new Map<string, SettingRow>());\n // Counts explicit open/close calls on the handle.\n const openRequestsRef = useRef(0);\n const registerRow = useMemo<RegisterSettingRow>(\n () => (name, row) => {\n rowsRef.current.set(name, row);\n return () => {\n if (rowsRef.current.get(name) === row) rowsRef.current.delete(name);\n };\n },\n [],\n );\n\n const handle = useMemo<DropdownMenuHandle>(() => {\n /* Rows mount with the menu. A closed menu opens for the moment, waits\n for the row to register, and closes again once the change lands. */\n // open/close update the ref at once, not a render later, so a set\n // right after an explicit open() sees the menu as open and leaves it so.\n const show = (next: boolean) => {\n openRef.current = next;\n setOpen(next);\n };\n const withRow = async <K extends SettingRow['kind']>(\n setting: string,\n kind: K,\n apply: (row: Extract<SettingRow, { kind: K }>) => void,\n ) => {\n const opened = !openRef.current;\n if (opened) show(true);\n const requests = openRequestsRef.current;\n try {\n // A row mounts a render or two after the menu opens.\n let row = rowsRef.current.get(setting);\n for (let frame = 0; !row && frame < 30; frame += 1) {\n await nextFrame();\n row = rowsRef.current.get(setting);\n }\n if (!row || row.kind !== kind) {\n throw new Error(`No ${kind} setting named \"${setting}\" in this menu`);\n }\n apply(row as Extract<SettingRow, { kind: K }>);\n } finally {\n // Close only a menu this call opened, and nobody asked for since.\n if (opened && openRequestsRef.current === requests) show(false);\n }\n };\n return {\n getIsOpen: () => openRef.current,\n open: () => {\n openRequestsRef.current += 1;\n show(true);\n },\n close: () => {\n openRequestsRef.current += 1;\n show(false);\n },\n getSettings: () =>\n [...rowsRef.current].map(([setting, row]) => {\n if (row.kind === 'choice') {\n const { value, options, disabled } = row.read();\n return {\n setting,\n kind: 'choice' as const,\n value,\n options: options.map((option) => option.value),\n disabled,\n };\n }\n const { checked, disabled } = row.read();\n return { setting, kind: 'switch' as const, checked, disabled };\n }),\n setValue: (setting, value) =>\n withRow(setting, 'choice', (row) => {\n const { options, disabled, closeOnSelect } = row.read();\n const option = options.find((o) => o.value === value);\n if (disabled || !option || option.disabled) {\n throw new Error(\n `\"${value}\" is not an option that \"${setting}\" can take now`,\n );\n }\n row.pick(value);\n // As a click on the option would.\n if (closeOnSelect) show(false);\n }),\n setChecked: (setting, checked) =>\n withRow(setting, 'switch', (row) => {\n if (row.read().disabled) {\n throw new Error(`\"${setting}\" is disabled`);\n }\n row.pick(checked);\n }),\n };\n }, [setOpen]);\n useAgentRegistration(dropdownMenuAgent, handle, id);\n\n return (\n <DropdownMenuIdContext.Provider value={id}>\n <SettingRowsContext.Provider value={registerRow}>\n <RadixDropdownMenu.Root\n dir={dir ?? autoDir}\n open={open}\n onOpenChange={setOpen}\n {...props}\n />\n </SettingRowsContext.Provider>\n </DropdownMenuIdContext.Provider>\n );\n};\nRoot.displayName = 'DropdownMenu.Root';\n\nconst Trigger = RadixDropdownMenu.Trigger;\nconst Portal = RadixDropdownMenu.Portal;\nconst RadixGroup = RadixDropdownMenu.Group;\nconst RadixRadioGroup = RadixDropdownMenu.RadioGroup;\n\n/* ------------------------------------------------------------------ */\n/* Content */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuContentProps\n extends\n ComponentPropsWithoutRef<typeof RadixDropdownMenu.Content>,\n VariantProps<typeof contentVariants> {}\n\nconst Content = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Content>,\n DropdownMenuContentProps\n>(({ className, sideOffset = 8, ...props }, ref) => {\n const instanceId = useContext(DropdownMenuIdContext);\n return (\n <RadixDropdownMenu.Portal>\n {/* A region named after the trigger, so axe `region` passes while open. */}\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.Content\n ref={popupRef}\n sideOffset={sideOffset}\n className={contentVariants({ className })}\n data-component=\"dropdown-menu\"\n data-component-id={instanceId}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n );\n});\nContent.displayName = 'DropdownMenu.Content';\n\n/* ------------------------------------------------------------------ */\n/* Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Item\n> {\n startIcon?: ReactNode;\n endIcon?: ReactNode;\n description?: ReactNode;\n /** Convenience — renders a DS <Kbd keys={…}> on the inline-end. */\n shortcut?: Array<KbdNamedKey | string>;\n}\n\nconst Item = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n className,\n startIcon,\n endIcon,\n description,\n shortcut,\n children,\n ...props\n },\n ref,\n ) => (\n <RadixDropdownMenu.Item\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:flex ds:flex-col ds:min-w-0\">\n <span className=\"ds:truncate\">{children}</span>\n {description ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {description}\n </span>\n ) : null}\n </span>\n {shortcut ? (\n <span className=\"ds:ms-auto\">\n <Kbd keys={shortcut} size=\"sm\" />\n </span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:ms-auto ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {endIcon}\n </span>\n ) : null}\n </RadixDropdownMenu.Item>\n ),\n);\nItem.displayName = 'DropdownMenu.Item';\n\n/* ------------------------------------------------------------------ */\n/* CheckboxItem */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuCheckboxItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n>;\n\nconst CheckboxItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n <span className={indicatorSlotClasses}>\n <RadixDropdownMenu.ItemIndicator>\n <Check aria-hidden className=\"ds:size-4\" />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.CheckboxItem>\n));\nCheckboxItem.displayName = 'DropdownMenu.CheckboxItem';\n\n/* Registers a named row with its Root for as long as it is mounted. The\n row object is rebuilt each render; the Root reads it through a ref, so\n it always sees the latest value and callback. */\nfunction useSettingRow(name: string | undefined, row: SettingRow): void {\n const register = useContext(SettingRowsContext);\n const latest = useRef(row);\n useLayoutEffect(() => {\n latest.current = row;\n });\n useEffect(() => {\n if (!name || !register) return undefined;\n const proxy: SettingRow =\n latest.current.kind === 'choice'\n ? {\n kind: 'choice',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'choice' }>\n ).read(),\n pick: (value) =>\n (latest.current as Extract<SettingRow, { kind: 'choice' }>).pick(\n value,\n ),\n }\n : {\n kind: 'switch',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'switch' }>\n ).read(),\n pick: (checked) =>\n (latest.current as Extract<SettingRow, { kind: 'switch' }>).pick(\n checked,\n ),\n };\n return register(name, proxy);\n }, [name, register]);\n}\n\n/* ------------------------------------------------------------------ */\n/* SwitchItem */\n/* */\n/* A persistent on/off toggle row (menuitemcheckbox semantics) whose */\n/* indicator is a trailing switch glyph instead of a tick — for */\n/* settings that live inside a menu (e.g. accessible mode). Selecting */\n/* keeps the menu open so the user sees the toggle land. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuSwitchItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n> {\n /** Names the row for agents (the menu's `set_checked` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n}\n\n// Mirrors the kit Switch's `sm` metrics (track h-4 w-7, thumb size-3)\n// and its primary checked fill so the two switch affordances stay kin.\n// The muted-foreground border keeps the OFF state perceivable — without\n// it the muted track sits at ~1.2:1 on the popover (WCAG 1.4.11).\nconst switchTrackClasses = [\n 'ds:ms-auto ds:inline-flex ds:items-center ds:shrink-0',\n 'ds:h-4 ds:w-7 ds:p-[2px]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:bg-[color:var(--muted)]',\n 'ds:[[data-state=checked]_&]:bg-[color:var(--primary)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--primary)]',\n // Thumb slides via justify swap — logical-direction safe, no\n // transform to fight under prefers-reduced-motion.\n 'ds:justify-start ds:[[data-state=checked]_&]:justify-end',\n 'ds:forced-colors:border-[CanvasText]',\n // HCM strips fills — paint the checked track with the system\n // selection colour so state isn't conveyed by thumb position alone.\n 'ds:forced-colors:[[data-state=checked]_&]:bg-[SelectedItem]',\n].join(' ');\n\nconst switchThumbClasses = [\n 'ds:block ds:size-3',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[color:var(--background)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-transparent',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\nconst SwitchItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuSwitchItemProps\n>(({ className, children, onSelect, name, ...props }, ref) => {\n const { checked, onCheckedChange, disabled } = props;\n useSettingRow(name, {\n kind: 'switch',\n read: () => ({ checked: checked === true, disabled: disabled === true }),\n // What a click does, and only when it would change something: the\n // consumer's onSelect, then the new state.\n pick: (next) => {\n if (next === (checked === true)) return;\n onSelect?.(new Event('menu.itemSelect', { cancelable: true }));\n onCheckedChange?.(next);\n },\n });\n return (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n data-setting={name}\n onSelect={(event) => {\n // Keep-open is unconditional — prevent first so a throwing consumer\n // handler can't close the menu as a side effect.\n event.preventDefault();\n onSelect?.(event);\n }}\n {...props}\n >\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <span aria-hidden=\"true\" className={switchTrackClasses}>\n <span className={switchThumbClasses} />\n </span>\n </RadixDropdownMenu.CheckboxItem>\n );\n});\nSwitchItem.displayName = 'DropdownMenu.SwitchItem';\n\n/* ------------------------------------------------------------------ */\n/* RadioGroup / RadioItem */\n/* ------------------------------------------------------------------ */\n\nconst RadioGroup = RadixRadioGroup;\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.RadioItem\n>;\n\nconst RadioItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.RadioItem>,\n DropdownMenuRadioItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.RadioItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {/* Real radio affordance: an always-visible ring with a filled dot\n when selected — a tick reads as a checkbox, not a single choice.\n The ring colours via the item's own data-state so the unchecked\n options still advertise that they are part of a radio set. */}\n <span className={indicatorSlotClasses} aria-hidden=\"true\">\n <span\n className={[\n 'ds:inline-flex ds:size-4 ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--accent)]',\n // Accent on the lit row would vanish, so ring and dot take its ink.\n 'ds:not-forced-colors:[[data-highlighted][data-state=checked]_&]:border-[color:var(--accent-foreground)]',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' ')}\n >\n <RadixDropdownMenu.ItemIndicator>\n <span\n className={[\n 'ds:block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--accent)]',\n 'ds:not-forced-colors:group-data-[highlighted]/menu-row:bg-[color:var(--accent-foreground)]',\n 'ds:forced-colors:bg-[CanvasText]',\n ].join(' ')}\n />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.RadioItem>\n));\nRadioItem.displayName = 'DropdownMenu.RadioItem';\n\n/* ------------------------------------------------------------------ */\n/* Label */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Label\n>;\n\nconst Label = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Label>,\n DropdownMenuLabelProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Label\n ref={ref}\n className={labelClasses({ className })}\n {...props}\n />\n));\nLabel.displayName = 'DropdownMenu.Label';\n\n/* ------------------------------------------------------------------ */\n/* Separator */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Separator\n>;\n\nconst MenuSeparator = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Separator ref={ref} asChild {...props}>\n <DsSeparator\n className={['ds:my-[calc(var(--spacing-xs)/2)]', className ?? '']\n .filter(Boolean)\n .join(' ')}\n />\n </RadixDropdownMenu.Separator>\n));\nMenuSeparator.displayName = 'DropdownMenu.Separator';\n\n/* ------------------------------------------------------------------ */\n/* Shortcut — thin wrapper over DS Kbd for the right side of an Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuShortcutProps {\n keys: Array<KbdNamedKey | string>;\n separator?: 'none' | 'plus' | 'then';\n}\n\nconst Shortcut = forwardRef<HTMLSpanElement, DropdownMenuShortcutProps>(\n ({ keys, separator = 'none' }, ref) => (\n <span ref={ref} className=\"ds:ms-auto ds:ps-[var(--spacing-sm)]\">\n <Kbd keys={keys} separator={separator} size=\"sm\" />\n </span>\n ),\n);\nShortcut.displayName = 'DropdownMenu.Shortcut';\n\n/* ------------------------------------------------------------------ */\n/* Sub-menu */\n/* ------------------------------------------------------------------ */\n\nconst Sub = RadixDropdownMenu.Sub;\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubTrigger\n> {\n startIcon?: ReactNode;\n}\n\nconst SubTrigger = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(({ className, startIcon, children, ...props }, ref) => (\n <RadixDropdownMenu.SubTrigger\n ref={ref}\n // Stays lit while focus is in its submenu, so the path is visible.\n className={itemClasses({\n className: [MENU_ROW_HIGHLIGHT.open, className].filter(Boolean).join(' '),\n })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <ChevronRight\n aria-hidden\n className=\"ds:ms-auto ds:size-4 ds:shrink-0 ds:rtl:-scale-x-100\"\n />\n </RadixDropdownMenu.SubTrigger>\n));\nSubTrigger.displayName = 'DropdownMenu.SubTrigger';\n\nexport type DropdownMenuSubContentProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubContent\n>;\n\nconst SubContent = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubContent>,\n DropdownMenuSubContentProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Portal>\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.SubContent\n ref={popupRef}\n sideOffset={8}\n data-component=\"dropdown-menu-sub-content\"\n className={contentVariants({ className })}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n));\nSubContent.displayName = 'DropdownMenu.SubContent';\n\n/* ------------------------------------------------------------------ */\n/* ChoiceSub */\n/* */\n/* One setting with a few exclusive options, as a single menu row that */\n/* names the setting and shows its current value (\"Row density · */\n/* Compact ›\"). The row opens a submenu of radio items. It replaces the */\n/* \"label + Select\" row inside popovers: no Select ever opens inside a */\n/* menu, and the whole settings menu stays keyboard-native. Picking an */\n/* option keeps the menu open by default, like SwitchItem, so the user */\n/* sees the value land and can adjust the next setting. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuChoiceOption<T extends string = string> {\n value: T;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface DropdownMenuChoiceSubProps<T extends string = string> {\n /** The setting's name, shown at the start of the row. */\n label: ReactNode;\n /** The selected option's value; its label shows at the end of the row. */\n value: T;\n onValueChange: (value: T) => void;\n options: ReadonlyArray<DropdownMenuChoiceOption<T>>;\n startIcon?: ReactNode;\n disabled?: boolean;\n /** Close the whole menu after a pick. @default false */\n closeOnSelect?: boolean;\n /** Names the row for agents (the menu's `set_value` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n className?: string;\n}\n\nfunction ChoiceSub<T extends string>({\n label,\n value,\n onValueChange,\n options,\n startIcon,\n disabled,\n closeOnSelect = false,\n name,\n className,\n}: DropdownMenuChoiceSubProps<T>) {\n const current = options.find((option) => option.value === value);\n useSettingRow(name, {\n kind: 'choice',\n read: () => ({\n value,\n options,\n disabled: disabled === true,\n closeOnSelect,\n }),\n pick: (next) => onValueChange(next as T),\n });\n return (\n <Sub>\n <SubTrigger\n startIcon={startIcon}\n disabled={disabled}\n className={className}\n data-component=\"dropdown-menu-choice\"\n data-value={value}\n data-setting={name}\n >\n <span className=\"ds:flex ds:min-w-0 ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <span className=\"ds:truncate\">{label}</span>\n {current ? (\n <span className=\"ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:[[data-highlighted]_&]:text-current\">\n {current.label}\n </span>\n ) : null}\n </span>\n </SubTrigger>\n <SubContent>\n <RadioGroup\n value={value}\n onValueChange={(next) => onValueChange(next as T)}\n >\n {options.map((option) => (\n <RadioItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={\n closeOnSelect ? undefined : (event) => event.preventDefault()\n }\n >\n {option.label}\n </RadioItem>\n ))}\n </RadioGroup>\n </SubContent>\n </Sub>\n );\n}\nChoiceSub.displayName = 'DropdownMenu.ChoiceSub';\n\n/* ------------------------------------------------------------------ */\n/* Assembled namespace export */\n/* ------------------------------------------------------------------ */\n\nexport const DropdownMenu = {\n Root,\n Trigger,\n Portal,\n Content,\n Group: RadixGroup,\n Item,\n CheckboxItem,\n SwitchItem,\n RadioGroup,\n RadioItem,\n Label,\n Separator: MenuSeparator,\n Shortcut,\n Sub,\n SubTrigger,\n SubContent,\n ChoiceSub,\n};\n"],"names":["dropdownMenuAgent","handle","args","contentVariants","cva","itemClasses","MENU_ROW_HIGHLIGHT","labelClasses","indicatorSlotClasses","SettingRowsContext","createContext","nextFrame","resolve","DropdownMenuIdContext","Root","dir","id","openProp","defaultOpen","onOpenChange","props","autoDir","useDocumentDirection","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","rowsRef","openRequestsRef","registerRow","useMemo","name","row","show","next","withRow","setting","kind","apply","opened","requests","frame","value","options","disabled","option","checked","closeOnSelect","o","useAgentRegistration","jsx","RadixDropdownMenu","Trigger","Portal","RadixGroup","RadixRadioGroup","Content","forwardRef","className","sideOffset","ref","instanceId","useContext","PopupRegion","popupRef","Item","startIcon","endIcon","description","shortcut","children","jsxs","Kbd","CheckboxItem","Check","useSettingRow","register","latest","useLayoutEffect","proxy","switchTrackClasses","switchThumbClasses","SwitchItem","onSelect","onCheckedChange","event","RadioGroup","RadioItem","Label","MenuSeparator","DsSeparator","Shortcut","keys","separator","Sub","SubTrigger","ChevronRight","SubContent","ChoiceSub","label","onValueChange","current","DropdownMenu"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { jsx as i, jsxs as L } from "react/jsx-runtime";
3
3
  import { T as P } from "./tag-DOZGz0fT.js";
4
4
  import { useTranslation as x } from "react-i18next";
5
5
  import { I as S } from "./icon-button-S8_weU3g.js";
6
- import { I as V } from "./icon-button-group-CRKFR48b.js";
6
+ import { I as V } from "./icon-button-group-mXvYDaba.js";
7
7
  import { A as $, a as H } from "./arrow-up-BYvcvTkB.js";
8
8
  import { S as G } from "./square-check-big-dj0o8yA3.js";
9
9
  import { S as O } from "./square-DASBRZ0U.js";
@@ -409,4 +409,4 @@ export {
409
409
  ge as r,
410
410
  me as u
411
411
  };
412
- //# sourceMappingURL=editable-currency-cell-renderer-rWYiF4EI.js.map
412
+ //# sourceMappingURL=editable-currency-cell-renderer-BQYL5GjP.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editable-currency-cell-renderer-rWYiF4EI.js","sources":["../../src/components/data-table/hooks/use-total-row.ts","../../src/components/data-table/cell-renderers/tooth-cell-renderer.tsx","../../src/components/data-table/cell-renderers/currency-cell-renderer.tsx","../../src/components/data-table/cell-renderers/reorder-cell-renderer.tsx","../../src/components/data-table/cell-renderers/toggle-cell-renderer.tsx","../../src/components/data-table/cell-renderers/color-dot-cell-renderer.tsx","../../src/components/data-table/cell-renderers/balance-cell-renderer.tsx","../../src/components/data-table/cell-renderers/editable-text-cell-renderer.tsx","../../src/components/data-table/cell-renderers/editable-currency-cell-renderer.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\n/**\n * Compute a pinned total row from a dataset and a list of numeric fields.\n *\n * The returned object is structurally a `TData` with non-summed fields left\n * `undefined` — plug it into `pinnedBottomRowData={[totalRow]}`. Cell renderers\n * in the non-summed columns receive `undefined`, so they should render nothing\n * (all of the DS cell renderers short-circuit on `null`/`undefined`).\n *\n * Pass an optional `labelField` + `labelValue` to show a static caption such\n * as \"Total\" in the first column of the pinned row.\n */\nexport function useTotalRow<TData>(\n rowData: TData[] | undefined,\n sumFields: Array<keyof TData & string>,\n options?: {\n labelField?: keyof TData & string;\n labelValue?: string;\n },\n): TData {\n return useMemo(() => {\n const row: Record<string, unknown> = {};\n\n for (const field of sumFields) {\n let total = 0;\n for (const r of rowData ?? []) {\n const raw = (r as Record<string, unknown>)[field];\n const n = typeof raw === 'number' ? raw : Number(raw);\n if (Number.isFinite(n)) total += n;\n }\n row[field] = total;\n }\n\n if (options?.labelField && options.labelValue !== undefined) {\n row[options.labelField] = options.labelValue;\n }\n\n return row as TData;\n }, [rowData, sumFields, options?.labelField, options?.labelValue]);\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Tag } from '../../tag/tag';\n\n// Tooth glyph — lucide ships no dental icon, so this is a small inline tooth\n// (a crown narrowing to two roots) tinted with `currentColor`, so it inherits\n// the Tag's text colour. Decorative; the FDI numbers are the accessible label.\nfunction ToothIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className=\"ds:size-3.5\"\n >\n <path d=\"M12 5.5c-1.074 -1.426 -2.45 -2.2 -4 -2c-2.5 .323 -3.7 2.5 -3.5 5c.1 1.5 .5 3 .5 4.5c0 1.5 .5 3.5 1 5c.3 .9 .5 2 1.5 2s1.3 -1.5 1.5 -2.5c.2 -1 .5 -2 1.5 -2s1.3 1 1.5 2c.2 1 .5 2.5 1.5 2.5s1.2 -1.1 1.5 -2c.5 -1.5 1 -3.5 1 -5c0 -1.5 .4 -3 .5 -4.5c.2 -2.5 -1 -4.677 -3.5 -5c-1.55 -.2 -2.926 .574 -4 2z\" />\n </svg>\n );\n}\n\nexport interface ToothCellRendererParams {\n /** Max inline size of the chip before its label truncates (with a tooltip). */\n maxInlineSize?: string;\n}\n\n/**\n * Renders an array of tooth ids (FDI notation) as a single outlined Tag — the\n * teeth comma-separated and prefixed with a tooth glyph, so dentition reads at\n * a glance instead of as bare numbers.\n */\nexport function ToothCellRenderer(\n props: CustomCellRendererProps<unknown, string[]> & ToothCellRendererParams,\n) {\n const { value, maxInlineSize = '8rem' } = props;\n if (!Array.isArray(value) || value.length === 0) return null;\n\n return (\n <Tag\n label={value.join(', ')}\n size=\"sm\"\n fill=\"outline\"\n leading={<ToothIcon />}\n maxInlineSize={maxInlineSize}\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface CurrencyCellRendererParams {\n /** ISO 4217 currency code. Default `'EUR'`. */\n currency?: string;\n /** Apply a destructive color token to negative amounts. */\n colorNegative?: boolean;\n /** Render the value with strikethrough — used for written-off balances. */\n strikethrough?: boolean;\n /** `Intl.NumberFormat` escape hatch. Merged on top of currency defaults. */\n options?: Intl.NumberFormatOptions;\n}\n\nfunction toNumber(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function CurrencyCellRenderer(\n props: CustomCellRendererProps & CurrencyCellRendererParams,\n) {\n const {\n value,\n currency = 'EUR',\n colorNegative,\n strikethrough,\n options,\n } = props;\n const { i18n } = useTranslation('ui');\n const n = toNumber(value);\n if (n === null) return null;\n\n const locale = i18n.language || 'en';\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...options,\n }).format(n);\n\n const classNames = ['ds:tabular-nums'];\n if (colorNegative && n < 0)\n classNames.push('ds:text-[color:var(--destructive)]');\n if (strikethrough) classNames.push('line-through');\n\n return <span className={classNames.join(' ')}>{formatted}</span>;\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { ArrowUp, ArrowDown } from 'lucide-react';\nimport { IconButton } from '../../button/icon-button';\nimport { IconButtonGroup } from '../../icon-button-group';\n\n/**\n * Keyboard-accessible row-reorder cell. AG Grid's native row dragging is\n * mouse/touch only; this renderer adds move-up / move-down buttons so the order\n * is reachable by keyboard too (the missing accessible half of the\n * \"drag-sortable column\" primitive). The consumer owns `rowData` order and\n * reorders it in `onMove` — the same controlled contract as the editable cells.\n */\nexport interface ReorderCellRendererParams<TData = unknown> {\n /** Move the row one step in the given direction (consumer reorders rowData). */\n onMove: (data: TData, direction: 'up' | 'down') => void;\n /** Accessible name for the move-up button (defaults to a kit string). */\n moveUpLabel?: string;\n /** Accessible name for the move-down button (defaults to a kit string). */\n moveDownLabel?: string;\n /** Button intent (default `ghost`). */\n intent?: 'ghost' | 'outline';\n /** Render the two buttons as a connected `IconButtonGroup` (default true). */\n group?: boolean;\n /**\n * Disable move-up on the first displayed row and move-down on the last\n * (default true). Turn off when the grid is filtered/sorted and the ends are\n * not meaningful.\n */\n disableAtEnds?: boolean;\n}\n\n/**\n * Pixel width a reorder column needs for the two `sm` IconButtons (32px each)\n * plus the data-table cell's inline padding so the controls never clip. Mirrors\n * {@link actionsColumnWidth}.\n */\nexport function reorderColumnWidth(): number {\n const SM_BUTTON = 32;\n const CELL_INSET = 26;\n return SM_BUTTON * 2 + CELL_INSET;\n}\n\nexport function ReorderCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ReorderCellRendererParams<TData>,\n) {\n const {\n data,\n node,\n api,\n onMove,\n moveUpLabel,\n moveDownLabel,\n intent = 'ghost',\n group = true,\n disableAtEnds = true,\n } = props;\n const { t } = useTranslation('ui');\n if (!data) return null;\n\n const rowIndex = node.rowIndex ?? -1;\n const lastIndex = api.getDisplayedRowCount() - 1;\n const atFirst = disableAtEnds && rowIndex <= 0;\n const atLast = disableAtEnds && rowIndex >= lastIndex;\n\n const upLabel = moveUpLabel ?? t('dataTable.moveUp', 'Move up');\n const downLabel = moveDownLabel ?? t('dataTable.moveDown', 'Move down');\n\n // An ARRAY of IconButtons (not a Fragment): IconButtonGroup inspects its\n // direct children and rejects anything that isn't a DS IconButton.\n const buttons = [\n <IconButton\n key=\"up\"\n size=\"sm\"\n intent={intent}\n icon={<ArrowUp aria-hidden className=\"ds:size-4\" />}\n tooltip={upLabel}\n aria-label={upLabel}\n disabled={atFirst}\n onClick={(event) => {\n event.stopPropagation();\n onMove(data, 'up');\n }}\n />,\n <IconButton\n key=\"down\"\n size=\"sm\"\n intent={intent}\n icon={<ArrowDown aria-hidden className=\"ds:size-4\" />}\n tooltip={downLabel}\n aria-label={downLabel}\n disabled={atLast}\n onClick={(event) => {\n event.stopPropagation();\n onMove(data, 'down');\n }}\n />,\n ];\n\n return group ? (\n <IconButtonGroup\n aria-label={t('dataTable.reorder', 'Reorder row')}\n size=\"sm\"\n >\n {buttons}\n </IconButtonGroup>\n ) : (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {buttons}\n </span>\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { SquareCheckBig, Square } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface ToggleCellRendererParams<TData = unknown> {\n /**\n * Fires with the row and the new target value. May return a `Promise` —\n * if it rejects, the consumer is expected to revert the underlying value\n * and flash the row with `data-table-row-error` (return that row class\n * from `getRowClass`). Use `onError` below to be notified inside this\n * renderer.\n */\n onToggle: (data: TData, newValue: boolean) => void | Promise<void>;\n /**\n * Optional reject hook. Fires when the `onToggle` promise rejects, with\n * the row and the error. The button auto-disables during the in-flight\n * promise and re-enables on either settle.\n */\n onError?: (data: TData, error: unknown) => void;\n /** Icon shown when the current value is truthy. */\n trueIcon?: ReactNode;\n /** Icon shown when the current value is falsy. */\n falseIcon?: ReactNode;\n /** Extra classes applied to the \"on\" icon — defaults to success token. */\n trueClass?: string;\n /** Extra classes applied to the \"off\" icon. */\n falseClass?: string;\n /** Accessible label. Falls back to the default on/off announcements. */\n label?: string;\n}\n\nexport function ToggleCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData, boolean> &\n ToggleCellRendererParams<TData>,\n) {\n const {\n value,\n data,\n onToggle,\n onError,\n trueIcon,\n falseIcon,\n trueClass = 'ds:text-[color:var(--success)]',\n falseClass = 'ds:text-[color:var(--muted-foreground)]',\n label,\n } = props;\n const { t } = useTranslation('ui');\n const [pending, setPending] = useState(false);\n if (!data) return null;\n\n const isOn = Boolean(value);\n const icon = isOn\n ? (trueIcon ?? <SquareCheckBig aria-hidden className=\"ds:size-4\" />)\n : (falseIcon ?? <Square aria-hidden className=\"ds:size-4\" />);\n const stateClass = isOn ? trueClass : falseClass;\n const resolvedLabel =\n label ?? (isOn ? t('inputs.switch.on') : t('inputs.switch.off'));\n\n async function handleClick(event: React.MouseEvent) {\n event.stopPropagation();\n if (pending || !data) return;\n const next = !isOn;\n const result = onToggle(data, next);\n if (result && typeof (result as Promise<void>).then === 'function') {\n setPending(true);\n try {\n await result;\n } catch (err) {\n onError?.(data, err);\n } finally {\n setPending(false);\n }\n }\n }\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n aria-busy={pending}\n aria-label={resolvedLabel}\n disabled={pending}\n onClick={handleClick}\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:appearance-none ds:bg-transparent ds:p-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:disabled:opacity-50',\n stateClass,\n ].join(' ')}\n >\n {icon}\n </button>\n );\n}\n","import { useRef } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useIsomorphicLayoutEffect } from '../../../hooks/use-isomorphic-layout-effect';\n\nexport interface ColorDotCellRendererParams {\n /** Field name on the row whose value holds the hex color. */\n colorField: string;\n /** Visual size of the dot. */\n size?: 'sm' | 'md' | 'lg';\n /** Optional label shown next to the dot. */\n labelField?: string;\n}\n\nconst SIZE_CLASS: Record<\n NonNullable<ColorDotCellRendererParams['size']>,\n string\n> = {\n sm: 'ds:size-[var(--icon-size-sm)]',\n md: 'ds:size-[var(--icon-size-md)]',\n lg: 'ds:size-[var(--icon-size-lg)]',\n};\n\nfunction readField(row: unknown, field: string): string | undefined {\n if (!row || typeof row !== 'object') return undefined;\n const value = (row as Record<string, unknown>)[field];\n return typeof value === 'string' ? value : undefined;\n}\n\n// Only accept trusted CSS color forms. Anything outside this allow-list\n// (including smuggled `url()` or extra declarations) is dropped so the\n// CSS custom-property writer can't be used to inject styles.\nconst HEX_RE = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB_RE = /^rgba?\\(\\s*[\\d.\\s,%/]+\\)$/i;\nconst HSL_RE = /^hsla?\\(\\s*[\\d.\\s,%/]+\\)$/i;\nconst CSS_VAR_RE = /^var\\(--[a-z0-9-]+(?:,\\s*[^)]+)?\\)$/i;\n\nfunction sanitizeColor(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const v = raw.trim();\n if (\n HEX_RE.test(v) ||\n RGB_RE.test(v) ||\n HSL_RE.test(v) ||\n CSS_VAR_RE.test(v)\n ) {\n return v;\n }\n return undefined;\n}\n\nexport function ColorDotCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ColorDotCellRendererParams,\n) {\n const { data, colorField, size = 'md', labelField } = props;\n const dotRef = useRef<HTMLSpanElement | null>(null);\n const rawColor = data ? readField(data, colorField) : undefined;\n const color = sanitizeColor(rawColor);\n const label = data && labelField ? readField(data, labelField) : undefined;\n\n // Apply the dynamic color via a CSS custom property on the element.\n // Keeps hex/rgb literals out of JSX (constraint #2 and #4). The data\n // itself drives the color — constraints only forbid hardcoded colors\n // in component source, not in consumer row data.\n useIsomorphicLayoutEffect(() => {\n const el = dotRef.current;\n if (!el) return;\n if (color) {\n el.style.setProperty('--data-table-dot-color', color);\n } else {\n el.style.removeProperty('--data-table-dot-color');\n }\n }, [color]);\n\n if (!color) return null;\n\n return (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <span\n ref={dotRef}\n aria-hidden=\"true\"\n className={[\n 'ds:inline-block ds:shrink-0 ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--data-table-dot-color)]',\n 'ds:border ds:border-[color:var(--border)]',\n SIZE_CLASS[size],\n ].join(' ')}\n />\n {label ? <span>{label}</span> : null}\n </span>\n );\n}\n","import type { ColDef } from 'ag-grid-community';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface BalanceLine {\n /** User-visible label for this line. */\n label: string;\n /** Field name on the row whose numeric value is rendered. */\n valueField: string;\n /** `'currency'` renders via Intl, `'percent'` appends `%`, `'number'` raw. Default `'number'`. */\n format?: 'currency' | 'percent' | 'number';\n}\n\nexport interface BalanceCellRendererParams {\n lines: BalanceLine[];\n /** ISO 4217 code, used by `currency`-formatted lines. Default `'EUR'`. */\n currency?: string;\n /** Apply destructive color to negative values. */\n highlightNegative?: boolean;\n}\n\nfunction readNumber(row: unknown, field: string): number | null {\n if (!row || typeof row !== 'object') return null;\n const raw = (row as Record<string, unknown>)[field];\n const n = typeof raw === 'number' ? raw : Number(raw);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Renders a compact set of label / value pairs inside a single AG Grid cell.\n *\n * Layout is **horizontal** with middle-dot separators so the cell fits\n * inside the default AG Grid row height without spilling into the row\n * below. Use the SALDI / Listini patterns (Totale · Incassato · Da Incassare)\n * as the canonical example.\n *\n * If a consumer's content wraps (long localized labels, narrow columns)\n * they can opt into row auto-growth by spreading\n * {@link balanceCellRendererColDefDefaults} onto the column definition.\n */\nexport function BalanceCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & BalanceCellRendererParams,\n) {\n const { data, lines, currency = 'EUR', highlightNegative } = props;\n const { i18n } = useTranslation('ui');\n if (!data) return null;\n\n const locale = i18n.language || 'en';\n\n const formatLine = (\n line: BalanceLine,\n ): { label: string; formatted: string; negative: boolean } | null => {\n const n = readNumber(data, line.valueField);\n if (n === null) return null;\n\n let formatted: string;\n switch (line.format ?? 'number') {\n case 'currency':\n formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(n);\n break;\n case 'percent':\n formatted = new Intl.NumberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: 1,\n }).format(n / 100);\n break;\n default:\n formatted = new Intl.NumberFormat(locale).format(n);\n }\n\n return {\n label: line.label,\n formatted,\n negative: Boolean(highlightNegative) && n < 0,\n };\n };\n\n const rendered = lines\n .map(formatLine)\n .filter(\n (x): x is { label: string; formatted: string; negative: boolean } =>\n x !== null,\n );\n if (rendered.length === 0) return null;\n\n return (\n <div\n className={[\n 'ds:flex',\n 'ds:flex-wrap',\n 'ds:items-center',\n 'ds:gap-x-[var(--spacing-sm)]',\n 'ds:gap-y-0',\n 'type-meta',\n 'ds:leading-tight',\n ].join(' ')}\n >\n {rendered.map((item, idx) => (\n <span\n key={`${item.label}-${idx}`}\n className=\"ds:inline-flex ds:items-baseline ds:gap-x-[var(--spacing-xs)]\"\n >\n {idx > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:me-[var(--spacing-xs)] ds:text-[color:var(--muted-foreground)]\"\n >\n ·\n </span>\n ) : null}\n <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {item.label}\n </span>\n <span\n className={[\n 'ds:tabular-nums',\n 'ds:font-medium',\n item.negative ? 'ds:text-[color:var(--destructive)]' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {item.formatted}\n </span>\n </span>\n ))}\n </div>\n );\n}\n\n/**\n * Column-definition defaults consumers can spread onto a `ColDef` when they\n * want the renderer's wrapped / multi-line behaviour to grow the row.\n *\n * The default compact horizontal layout is engineered to fit the standard\n * AG Grid row height, so this opt-in is only needed when a long label set\n * wraps across two or more lines and the consumer would rather grow the\n * row than wrap silently.\n *\n * AG Grid does NOT auto-grow row height to fit a tall cell unless\n * `autoHeight` and `wrapText` are set on the colDef itself — a cell\n * renderer can't impose that from inside.\n *\n * @example\n * ```ts\n * {\n * headerName: 'Saldi',\n * cellRenderer: BalanceCellRenderer,\n * cellRendererParams: { lines, currency: 'EUR' },\n * ...balanceCellRendererColDefDefaults,\n * }\n * ```\n */\nexport const balanceCellRendererColDefDefaults: Readonly<\n Pick<ColDef, 'autoHeight' | 'wrapText'>\n> = {\n autoHeight: true,\n wrapText: true,\n};\n","import { useEffect, useRef, useState } from 'react';\nimport type { CustomCellEditorProps } from 'ag-grid-react';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_HEIGHT,\n INPUT_SURFACE_PADDING_X,\n INPUT_SURFACE_TEXT,\n} from '../../_shared/input-surface';\n\n/**\n * Inline text editor that visually matches `<TextInput size=\"sm\">`. Use as\n * `cellEditor` on a colDef with `editable: true`. The cell renderer (default\n * or custom) takes over again once editing stops.\n *\n * AG Grid commits on Enter or Tab or blur; cancels on Escape. The consumer\n * receives the committed value via `onCellValueChanged`.\n */\nexport function EditableTextCellRenderer<TData = unknown>(\n props: CustomCellEditorProps<TData, string>,\n) {\n const { initialValue, onValueChange, stopEditing, column } = props;\n const [value, setValue] = useState<string>(initialValue ?? '');\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Focus + select on mount so typing replaces the current value.\n useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.select();\n }, []);\n\n // The current value is pushed to AG Grid via `onValueChange` on every\n // keystroke — AG Grid commits the most recent value when editing stops.\n // No `useGridCellEditor` hook needed for that contract.\n\n // Thread the column header into the input's accessible name so screen\n // readers announce \"Edit text, {column}\" instead of an unlabelled input.\n // AG Grid doesn't auto-wire the column header to cell editors.\n const headerName =\n (column?.getColDef?.()?.headerName as string | undefined) ?? undefined;\n\n return (\n <input\n ref={inputRef}\n type=\"text\"\n value={value}\n aria-label={headerName}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n onValueChange(next);\n }}\n onKeyDown={(e) => {\n // Escape cancels, Enter/Tab commit — AG Grid handles both, but we\n // explicitly stop editing on Enter so the consumer sees the commit\n // immediately rather than waiting for the next focus blur.\n if (e.key === 'Enter') {\n e.preventDefault();\n stopEditing();\n }\n }}\n className={[\n 'ds:block ds:w-full ds:appearance-none',\n // Input surface chrome: rounded border + bg + focus halo.\n INPUT_SURFACE_CHROME,\n // Use the `md` height (`--min-target-size`) so the input\n // auto-lifts to 48px under `.theme-accessible` to satisfy\n // WCAG 2.5.5 target size.\n INPUT_SURFACE_HEIGHT.md,\n INPUT_SURFACE_TEXT.sm,\n INPUT_SURFACE_PADDING_X.sm,\n ].join(' ')}\n />\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport type { CustomCellEditorProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_HEIGHT,\n INPUT_SURFACE_PADDING_X,\n INPUT_SURFACE_TEXT,\n} from '../../_shared/input-surface';\n\nexport interface EditableCurrencyCellEditorParams {\n /** ISO 4217 currency code (e.g. `EUR`, `USD`). Defaults to `EUR`. */\n currency?: string;\n /** Decimal places allowed in the editor. Defaults to 2 (cents precision). */\n decimals?: number;\n /** Minimum allowed value — values below this are clamped on commit. */\n min?: number;\n /** Maximum allowed value — values above this are clamped on commit. */\n max?: number;\n}\n\n/**\n * Inline numeric editor that visually matches `<TextInput size=\"sm\">`. Use as\n * `cellEditor` on a colDef with `editable: true`. The display formatting is\n * still the renderer's job — once editing stops, the cell hands back to\n * `CurrencyCellRenderer` (or whichever renderer the colDef declares).\n *\n * Stores a Number, not a string, so consumers receive `row.amount = 12.5`\n * not `\"12.5\"`. Strips locale separators on each change so commas/dots in\n * any language convert to a clean numeric value.\n */\nexport function EditableCurrencyCellRenderer<TData = unknown>(\n props: CustomCellEditorProps<TData, number> &\n EditableCurrencyCellEditorParams,\n) {\n const {\n initialValue,\n onValueChange,\n stopEditing,\n column,\n decimals = 2,\n min,\n max,\n } = props;\n const { i18n } = useTranslation('ui');\n const inputRef = useRef<HTMLInputElement | null>(null);\n // Thread the column header into the input's accessible name — see\n // editable-text-cell-renderer.tsx for the rationale.\n const headerName =\n (column?.getColDef?.()?.headerName as string | undefined) ?? undefined;\n\n // Local string state so the user can type intermediate values like \"12.\"\n // before the trailing zero arrives. We commit a Number to AG Grid on each\n // change for consumers that watch row state live; the final commit fires\n // when editing stops.\n const [draft, setDraft] = useState<string>(() => {\n if (initialValue == null || Number.isNaN(initialValue)) return '';\n return String(initialValue);\n });\n\n useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.select();\n }, []);\n\n function parseDraft(input: string): number | null {\n if (input.trim().length === 0) return null;\n // Accept either the user's locale decimal separator or a `.`. Strip\n // grouping characters (locale thousands separators, plus spaces).\n const lang = i18n.language || 'en';\n const partsFmt = new Intl.NumberFormat(lang).formatToParts(12345.6);\n const groupChar = partsFmt.find((p) => p.type === 'group')?.value ?? '';\n const decimalChar =\n partsFmt.find((p) => p.type === 'decimal')?.value ?? '.';\n const cleaned = input\n .replace(new RegExp(`\\\\${groupChar}`, 'g'), '')\n .replace(decimalChar, '.')\n .replace(/[^\\d.-]/g, '');\n const n = Number(cleaned);\n return Number.isFinite(n) ? n : null;\n }\n\n function commit(input: string) {\n const parsed = parseDraft(input);\n if (parsed == null) {\n onValueChange(null);\n return;\n }\n // Clamp first, then round to the declared precision so we never\n // persist floating-point dust from string parsing.\n let clamped = parsed;\n if (typeof min === 'number') clamped = Math.max(min, clamped);\n if (typeof max === 'number') clamped = Math.min(max, clamped);\n const factor = 10 ** decimals;\n onValueChange(Math.round(clamped * factor) / factor);\n }\n\n return (\n <input\n ref={inputRef}\n type=\"text\"\n // Inputmode hints mobile keyboards to show the decimal pad instead\n // of the full keyboard. type=\"number\" would also work but spinners\n // and locale parsing are inconsistent across browsers.\n inputMode=\"decimal\"\n value={draft}\n aria-label={headerName}\n onChange={(e) => {\n const next = e.target.value;\n setDraft(next);\n commit(next);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n stopEditing();\n }\n // Escape — AG Grid cancels by default; the editor doesn't need\n // explicit handling beyond what AG Grid wires automatically.\n }}\n className={[\n 'ds:block ds:w-full ds:appearance-none ds:text-end ds:tabular-nums',\n INPUT_SURFACE_CHROME,\n // Use `md` height — see editable-text-cell-renderer for rationale.\n INPUT_SURFACE_HEIGHT.md,\n INPUT_SURFACE_TEXT.sm,\n INPUT_SURFACE_PADDING_X.sm,\n ].join(' ')}\n />\n );\n}\n"],"names":["useTotalRow","rowData","sumFields","options","useMemo","row","field","total","r","raw","n","ToothIcon","jsx","ToothCellRenderer","props","value","maxInlineSize","Tag","toNumber","CurrencyCellRenderer","currency","colorNegative","strikethrough","i18n","useTranslation","locale","formatted","classNames","reorderColumnWidth","ReorderCellRenderer","data","node","api","onMove","moveUpLabel","moveDownLabel","intent","group","disableAtEnds","t","rowIndex","lastIndex","atFirst","atLast","upLabel","downLabel","buttons","IconButton","ArrowUp","event","ArrowDown","IconButtonGroup","ToggleCellRenderer","onToggle","onError","trueIcon","falseIcon","trueClass","falseClass","label","pending","setPending","useState","isOn","icon","SquareCheckBig","Square","stateClass","resolvedLabel","handleClick","result","err","SIZE_CLASS","readField","HEX_RE","RGB_RE","HSL_RE","CSS_VAR_RE","sanitizeColor","v","ColorDotCellRenderer","colorField","size","labelField","dotRef","useRef","rawColor","color","useIsomorphicLayoutEffect","el","jsxs","readNumber","BalanceCellRenderer","lines","highlightNegative","formatLine","line","rendered","x","item","idx","EditableTextCellRenderer","initialValue","onValueChange","stopEditing","column","setValue","inputRef","useEffect","headerName","_b","_a","e","next","INPUT_SURFACE_CHROME","INPUT_SURFACE_HEIGHT","INPUT_SURFACE_TEXT","INPUT_SURFACE_PADDING_X","EditableCurrencyCellRenderer","decimals","min","max","draft","setDraft","parseDraft","input","lang","partsFmt","groupChar","p","decimalChar","cleaned","commit","parsed","clamped","factor"],"mappings":"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"}
1
+ {"version":3,"file":"editable-currency-cell-renderer-BQYL5GjP.js","sources":["../../src/components/data-table/hooks/use-total-row.ts","../../src/components/data-table/cell-renderers/tooth-cell-renderer.tsx","../../src/components/data-table/cell-renderers/currency-cell-renderer.tsx","../../src/components/data-table/cell-renderers/reorder-cell-renderer.tsx","../../src/components/data-table/cell-renderers/toggle-cell-renderer.tsx","../../src/components/data-table/cell-renderers/color-dot-cell-renderer.tsx","../../src/components/data-table/cell-renderers/balance-cell-renderer.tsx","../../src/components/data-table/cell-renderers/editable-text-cell-renderer.tsx","../../src/components/data-table/cell-renderers/editable-currency-cell-renderer.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\n/**\n * Compute a pinned total row from a dataset and a list of numeric fields.\n *\n * The returned object is structurally a `TData` with non-summed fields left\n * `undefined` — plug it into `pinnedBottomRowData={[totalRow]}`. Cell renderers\n * in the non-summed columns receive `undefined`, so they should render nothing\n * (all of the DS cell renderers short-circuit on `null`/`undefined`).\n *\n * Pass an optional `labelField` + `labelValue` to show a static caption such\n * as \"Total\" in the first column of the pinned row.\n */\nexport function useTotalRow<TData>(\n rowData: TData[] | undefined,\n sumFields: Array<keyof TData & string>,\n options?: {\n labelField?: keyof TData & string;\n labelValue?: string;\n },\n): TData {\n return useMemo(() => {\n const row: Record<string, unknown> = {};\n\n for (const field of sumFields) {\n let total = 0;\n for (const r of rowData ?? []) {\n const raw = (r as Record<string, unknown>)[field];\n const n = typeof raw === 'number' ? raw : Number(raw);\n if (Number.isFinite(n)) total += n;\n }\n row[field] = total;\n }\n\n if (options?.labelField && options.labelValue !== undefined) {\n row[options.labelField] = options.labelValue;\n }\n\n return row as TData;\n }, [rowData, sumFields, options?.labelField, options?.labelValue]);\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { Tag } from '../../tag/tag';\n\n// Tooth glyph — lucide ships no dental icon, so this is a small inline tooth\n// (a crown narrowing to two roots) tinted with `currentColor`, so it inherits\n// the Tag's text colour. Decorative; the FDI numbers are the accessible label.\nfunction ToothIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className=\"ds:size-3.5\"\n >\n <path d=\"M12 5.5c-1.074 -1.426 -2.45 -2.2 -4 -2c-2.5 .323 -3.7 2.5 -3.5 5c.1 1.5 .5 3 .5 4.5c0 1.5 .5 3.5 1 5c.3 .9 .5 2 1.5 2s1.3 -1.5 1.5 -2.5c.2 -1 .5 -2 1.5 -2s1.3 1 1.5 2c.2 1 .5 2.5 1.5 2.5s1.2 -1.1 1.5 -2c.5 -1.5 1 -3.5 1 -5c0 -1.5 .4 -3 .5 -4.5c.2 -2.5 -1 -4.677 -3.5 -5c-1.55 -.2 -2.926 .574 -4 2z\" />\n </svg>\n );\n}\n\nexport interface ToothCellRendererParams {\n /** Max inline size of the chip before its label truncates (with a tooltip). */\n maxInlineSize?: string;\n}\n\n/**\n * Renders an array of tooth ids (FDI notation) as a single outlined Tag — the\n * teeth comma-separated and prefixed with a tooth glyph, so dentition reads at\n * a glance instead of as bare numbers.\n */\nexport function ToothCellRenderer(\n props: CustomCellRendererProps<unknown, string[]> & ToothCellRendererParams,\n) {\n const { value, maxInlineSize = '8rem' } = props;\n if (!Array.isArray(value) || value.length === 0) return null;\n\n return (\n <Tag\n label={value.join(', ')}\n size=\"sm\"\n fill=\"outline\"\n leading={<ToothIcon />}\n maxInlineSize={maxInlineSize}\n />\n );\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface CurrencyCellRendererParams {\n /** ISO 4217 currency code. Default `'EUR'`. */\n currency?: string;\n /** Apply a destructive color token to negative amounts. */\n colorNegative?: boolean;\n /** Render the value with strikethrough — used for written-off balances. */\n strikethrough?: boolean;\n /** `Intl.NumberFormat` escape hatch. Merged on top of currency defaults. */\n options?: Intl.NumberFormatOptions;\n}\n\nfunction toNumber(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function CurrencyCellRenderer(\n props: CustomCellRendererProps & CurrencyCellRendererParams,\n) {\n const {\n value,\n currency = 'EUR',\n colorNegative,\n strikethrough,\n options,\n } = props;\n const { i18n } = useTranslation('ui');\n const n = toNumber(value);\n if (n === null) return null;\n\n const locale = i18n.language || 'en';\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...options,\n }).format(n);\n\n const classNames = ['ds:tabular-nums'];\n if (colorNegative && n < 0)\n classNames.push('ds:text-[color:var(--destructive)]');\n if (strikethrough) classNames.push('line-through');\n\n return <span className={classNames.join(' ')}>{formatted}</span>;\n}\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { ArrowUp, ArrowDown } from 'lucide-react';\nimport { IconButton } from '../../button/icon-button';\nimport { IconButtonGroup } from '../../icon-button-group';\n\n/**\n * Keyboard-accessible row-reorder cell. AG Grid's native row dragging is\n * mouse/touch only; this renderer adds move-up / move-down buttons so the order\n * is reachable by keyboard too (the missing accessible half of the\n * \"drag-sortable column\" primitive). The consumer owns `rowData` order and\n * reorders it in `onMove` — the same controlled contract as the editable cells.\n */\nexport interface ReorderCellRendererParams<TData = unknown> {\n /** Move the row one step in the given direction (consumer reorders rowData). */\n onMove: (data: TData, direction: 'up' | 'down') => void;\n /** Accessible name for the move-up button (defaults to a kit string). */\n moveUpLabel?: string;\n /** Accessible name for the move-down button (defaults to a kit string). */\n moveDownLabel?: string;\n /** Button intent (default `ghost`). */\n intent?: 'ghost' | 'outline';\n /** Render the two buttons as a connected `IconButtonGroup` (default true). */\n group?: boolean;\n /**\n * Disable move-up on the first displayed row and move-down on the last\n * (default true). Turn off when the grid is filtered/sorted and the ends are\n * not meaningful.\n */\n disableAtEnds?: boolean;\n}\n\n/**\n * Pixel width a reorder column needs for the two `sm` IconButtons (32px each)\n * plus the data-table cell's inline padding so the controls never clip. Mirrors\n * {@link actionsColumnWidth}.\n */\nexport function reorderColumnWidth(): number {\n const SM_BUTTON = 32;\n const CELL_INSET = 26;\n return SM_BUTTON * 2 + CELL_INSET;\n}\n\nexport function ReorderCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ReorderCellRendererParams<TData>,\n) {\n const {\n data,\n node,\n api,\n onMove,\n moveUpLabel,\n moveDownLabel,\n intent = 'ghost',\n group = true,\n disableAtEnds = true,\n } = props;\n const { t } = useTranslation('ui');\n if (!data) return null;\n\n const rowIndex = node.rowIndex ?? -1;\n const lastIndex = api.getDisplayedRowCount() - 1;\n const atFirst = disableAtEnds && rowIndex <= 0;\n const atLast = disableAtEnds && rowIndex >= lastIndex;\n\n const upLabel = moveUpLabel ?? t('dataTable.moveUp', 'Move up');\n const downLabel = moveDownLabel ?? t('dataTable.moveDown', 'Move down');\n\n // An ARRAY of IconButtons (not a Fragment): IconButtonGroup inspects its\n // direct children and rejects anything that isn't a DS IconButton.\n const buttons = [\n <IconButton\n key=\"up\"\n size=\"sm\"\n intent={intent}\n icon={<ArrowUp aria-hidden className=\"ds:size-4\" />}\n tooltip={upLabel}\n aria-label={upLabel}\n disabled={atFirst}\n onClick={(event) => {\n event.stopPropagation();\n onMove(data, 'up');\n }}\n />,\n <IconButton\n key=\"down\"\n size=\"sm\"\n intent={intent}\n icon={<ArrowDown aria-hidden className=\"ds:size-4\" />}\n tooltip={downLabel}\n aria-label={downLabel}\n disabled={atLast}\n onClick={(event) => {\n event.stopPropagation();\n onMove(data, 'down');\n }}\n />,\n ];\n\n return group ? (\n <IconButtonGroup\n aria-label={t('dataTable.reorder', 'Reorder row')}\n size=\"sm\"\n >\n {buttons}\n </IconButtonGroup>\n ) : (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {buttons}\n </span>\n );\n}\n","import { useState, type ReactNode } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { SquareCheckBig, Square } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface ToggleCellRendererParams<TData = unknown> {\n /**\n * Fires with the row and the new target value. May return a `Promise` —\n * if it rejects, the consumer is expected to revert the underlying value\n * and flash the row with `data-table-row-error` (return that row class\n * from `getRowClass`). Use `onError` below to be notified inside this\n * renderer.\n */\n onToggle: (data: TData, newValue: boolean) => void | Promise<void>;\n /**\n * Optional reject hook. Fires when the `onToggle` promise rejects, with\n * the row and the error. The button auto-disables during the in-flight\n * promise and re-enables on either settle.\n */\n onError?: (data: TData, error: unknown) => void;\n /** Icon shown when the current value is truthy. */\n trueIcon?: ReactNode;\n /** Icon shown when the current value is falsy. */\n falseIcon?: ReactNode;\n /** Extra classes applied to the \"on\" icon — defaults to success token. */\n trueClass?: string;\n /** Extra classes applied to the \"off\" icon. */\n falseClass?: string;\n /** Accessible label. Falls back to the default on/off announcements. */\n label?: string;\n}\n\nexport function ToggleCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData, boolean> &\n ToggleCellRendererParams<TData>,\n) {\n const {\n value,\n data,\n onToggle,\n onError,\n trueIcon,\n falseIcon,\n trueClass = 'ds:text-[color:var(--success)]',\n falseClass = 'ds:text-[color:var(--muted-foreground)]',\n label,\n } = props;\n const { t } = useTranslation('ui');\n const [pending, setPending] = useState(false);\n if (!data) return null;\n\n const isOn = Boolean(value);\n const icon = isOn\n ? (trueIcon ?? <SquareCheckBig aria-hidden className=\"ds:size-4\" />)\n : (falseIcon ?? <Square aria-hidden className=\"ds:size-4\" />);\n const stateClass = isOn ? trueClass : falseClass;\n const resolvedLabel =\n label ?? (isOn ? t('inputs.switch.on') : t('inputs.switch.off'));\n\n async function handleClick(event: React.MouseEvent) {\n event.stopPropagation();\n if (pending || !data) return;\n const next = !isOn;\n const result = onToggle(data, next);\n if (result && typeof (result as Promise<void>).then === 'function') {\n setPending(true);\n try {\n await result;\n } catch (err) {\n onError?.(data, err);\n } finally {\n setPending(false);\n }\n }\n }\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n aria-busy={pending}\n aria-label={resolvedLabel}\n disabled={pending}\n onClick={handleClick}\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:appearance-none ds:bg-transparent ds:p-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:disabled:opacity-50',\n stateClass,\n ].join(' ')}\n >\n {icon}\n </button>\n );\n}\n","import { useRef } from 'react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useIsomorphicLayoutEffect } from '../../../hooks/use-isomorphic-layout-effect';\n\nexport interface ColorDotCellRendererParams {\n /** Field name on the row whose value holds the hex color. */\n colorField: string;\n /** Visual size of the dot. */\n size?: 'sm' | 'md' | 'lg';\n /** Optional label shown next to the dot. */\n labelField?: string;\n}\n\nconst SIZE_CLASS: Record<\n NonNullable<ColorDotCellRendererParams['size']>,\n string\n> = {\n sm: 'ds:size-[var(--icon-size-sm)]',\n md: 'ds:size-[var(--icon-size-md)]',\n lg: 'ds:size-[var(--icon-size-lg)]',\n};\n\nfunction readField(row: unknown, field: string): string | undefined {\n if (!row || typeof row !== 'object') return undefined;\n const value = (row as Record<string, unknown>)[field];\n return typeof value === 'string' ? value : undefined;\n}\n\n// Only accept trusted CSS color forms. Anything outside this allow-list\n// (including smuggled `url()` or extra declarations) is dropped so the\n// CSS custom-property writer can't be used to inject styles.\nconst HEX_RE = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB_RE = /^rgba?\\(\\s*[\\d.\\s,%/]+\\)$/i;\nconst HSL_RE = /^hsla?\\(\\s*[\\d.\\s,%/]+\\)$/i;\nconst CSS_VAR_RE = /^var\\(--[a-z0-9-]+(?:,\\s*[^)]+)?\\)$/i;\n\nfunction sanitizeColor(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const v = raw.trim();\n if (\n HEX_RE.test(v) ||\n RGB_RE.test(v) ||\n HSL_RE.test(v) ||\n CSS_VAR_RE.test(v)\n ) {\n return v;\n }\n return undefined;\n}\n\nexport function ColorDotCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & ColorDotCellRendererParams,\n) {\n const { data, colorField, size = 'md', labelField } = props;\n const dotRef = useRef<HTMLSpanElement | null>(null);\n const rawColor = data ? readField(data, colorField) : undefined;\n const color = sanitizeColor(rawColor);\n const label = data && labelField ? readField(data, labelField) : undefined;\n\n // Apply the dynamic color via a CSS custom property on the element.\n // Keeps hex/rgb literals out of JSX (constraint #2 and #4). The data\n // itself drives the color — constraints only forbid hardcoded colors\n // in component source, not in consumer row data.\n useIsomorphicLayoutEffect(() => {\n const el = dotRef.current;\n if (!el) return;\n if (color) {\n el.style.setProperty('--data-table-dot-color', color);\n } else {\n el.style.removeProperty('--data-table-dot-color');\n }\n }, [color]);\n\n if (!color) return null;\n\n return (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <span\n ref={dotRef}\n aria-hidden=\"true\"\n className={[\n 'ds:inline-block ds:shrink-0 ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--data-table-dot-color)]',\n 'ds:border ds:border-[color:var(--border)]',\n SIZE_CLASS[size],\n ].join(' ')}\n />\n {label ? <span>{label}</span> : null}\n </span>\n );\n}\n","import type { ColDef } from 'ag-grid-community';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\n\nexport interface BalanceLine {\n /** User-visible label for this line. */\n label: string;\n /** Field name on the row whose numeric value is rendered. */\n valueField: string;\n /** `'currency'` renders via Intl, `'percent'` appends `%`, `'number'` raw. Default `'number'`. */\n format?: 'currency' | 'percent' | 'number';\n}\n\nexport interface BalanceCellRendererParams {\n lines: BalanceLine[];\n /** ISO 4217 code, used by `currency`-formatted lines. Default `'EUR'`. */\n currency?: string;\n /** Apply destructive color to negative values. */\n highlightNegative?: boolean;\n}\n\nfunction readNumber(row: unknown, field: string): number | null {\n if (!row || typeof row !== 'object') return null;\n const raw = (row as Record<string, unknown>)[field];\n const n = typeof raw === 'number' ? raw : Number(raw);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Renders a compact set of label / value pairs inside a single AG Grid cell.\n *\n * Layout is **horizontal** with middle-dot separators so the cell fits\n * inside the default AG Grid row height without spilling into the row\n * below. Use the SALDI / Listini patterns (Totale · Incassato · Da Incassare)\n * as the canonical example.\n *\n * If a consumer's content wraps (long localized labels, narrow columns)\n * they can opt into row auto-growth by spreading\n * {@link balanceCellRendererColDefDefaults} onto the column definition.\n */\nexport function BalanceCellRenderer<TData = unknown>(\n props: CustomCellRendererProps<TData> & BalanceCellRendererParams,\n) {\n const { data, lines, currency = 'EUR', highlightNegative } = props;\n const { i18n } = useTranslation('ui');\n if (!data) return null;\n\n const locale = i18n.language || 'en';\n\n const formatLine = (\n line: BalanceLine,\n ): { label: string; formatted: string; negative: boolean } | null => {\n const n = readNumber(data, line.valueField);\n if (n === null) return null;\n\n let formatted: string;\n switch (line.format ?? 'number') {\n case 'currency':\n formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(n);\n break;\n case 'percent':\n formatted = new Intl.NumberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: 1,\n }).format(n / 100);\n break;\n default:\n formatted = new Intl.NumberFormat(locale).format(n);\n }\n\n return {\n label: line.label,\n formatted,\n negative: Boolean(highlightNegative) && n < 0,\n };\n };\n\n const rendered = lines\n .map(formatLine)\n .filter(\n (x): x is { label: string; formatted: string; negative: boolean } =>\n x !== null,\n );\n if (rendered.length === 0) return null;\n\n return (\n <div\n className={[\n 'ds:flex',\n 'ds:flex-wrap',\n 'ds:items-center',\n 'ds:gap-x-[var(--spacing-sm)]',\n 'ds:gap-y-0',\n 'type-meta',\n 'ds:leading-tight',\n ].join(' ')}\n >\n {rendered.map((item, idx) => (\n <span\n key={`${item.label}-${idx}`}\n className=\"ds:inline-flex ds:items-baseline ds:gap-x-[var(--spacing-xs)]\"\n >\n {idx > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:me-[var(--spacing-xs)] ds:text-[color:var(--muted-foreground)]\"\n >\n ·\n </span>\n ) : null}\n <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {item.label}\n </span>\n <span\n className={[\n 'ds:tabular-nums',\n 'ds:font-medium',\n item.negative ? 'ds:text-[color:var(--destructive)]' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {item.formatted}\n </span>\n </span>\n ))}\n </div>\n );\n}\n\n/**\n * Column-definition defaults consumers can spread onto a `ColDef` when they\n * want the renderer's wrapped / multi-line behaviour to grow the row.\n *\n * The default compact horizontal layout is engineered to fit the standard\n * AG Grid row height, so this opt-in is only needed when a long label set\n * wraps across two or more lines and the consumer would rather grow the\n * row than wrap silently.\n *\n * AG Grid does NOT auto-grow row height to fit a tall cell unless\n * `autoHeight` and `wrapText` are set on the colDef itself — a cell\n * renderer can't impose that from inside.\n *\n * @example\n * ```ts\n * {\n * headerName: 'Saldi',\n * cellRenderer: BalanceCellRenderer,\n * cellRendererParams: { lines, currency: 'EUR' },\n * ...balanceCellRendererColDefDefaults,\n * }\n * ```\n */\nexport const balanceCellRendererColDefDefaults: Readonly<\n Pick<ColDef, 'autoHeight' | 'wrapText'>\n> = {\n autoHeight: true,\n wrapText: true,\n};\n","import { useEffect, useRef, useState } from 'react';\nimport type { CustomCellEditorProps } from 'ag-grid-react';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_HEIGHT,\n INPUT_SURFACE_PADDING_X,\n INPUT_SURFACE_TEXT,\n} from '../../_shared/input-surface';\n\n/**\n * Inline text editor that visually matches `<TextInput size=\"sm\">`. Use as\n * `cellEditor` on a colDef with `editable: true`. The cell renderer (default\n * or custom) takes over again once editing stops.\n *\n * AG Grid commits on Enter or Tab or blur; cancels on Escape. The consumer\n * receives the committed value via `onCellValueChanged`.\n */\nexport function EditableTextCellRenderer<TData = unknown>(\n props: CustomCellEditorProps<TData, string>,\n) {\n const { initialValue, onValueChange, stopEditing, column } = props;\n const [value, setValue] = useState<string>(initialValue ?? '');\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Focus + select on mount so typing replaces the current value.\n useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.select();\n }, []);\n\n // The current value is pushed to AG Grid via `onValueChange` on every\n // keystroke — AG Grid commits the most recent value when editing stops.\n // No `useGridCellEditor` hook needed for that contract.\n\n // Thread the column header into the input's accessible name so screen\n // readers announce \"Edit text, {column}\" instead of an unlabelled input.\n // AG Grid doesn't auto-wire the column header to cell editors.\n const headerName =\n (column?.getColDef?.()?.headerName as string | undefined) ?? undefined;\n\n return (\n <input\n ref={inputRef}\n type=\"text\"\n value={value}\n aria-label={headerName}\n onChange={(e) => {\n const next = e.target.value;\n setValue(next);\n onValueChange(next);\n }}\n onKeyDown={(e) => {\n // Escape cancels, Enter/Tab commit — AG Grid handles both, but we\n // explicitly stop editing on Enter so the consumer sees the commit\n // immediately rather than waiting for the next focus blur.\n if (e.key === 'Enter') {\n e.preventDefault();\n stopEditing();\n }\n }}\n className={[\n 'ds:block ds:w-full ds:appearance-none',\n // Input surface chrome: rounded border + bg + focus halo.\n INPUT_SURFACE_CHROME,\n // Use the `md` height (`--min-target-size`) so the input\n // auto-lifts to 48px under `.theme-accessible` to satisfy\n // WCAG 2.5.5 target size.\n INPUT_SURFACE_HEIGHT.md,\n INPUT_SURFACE_TEXT.sm,\n INPUT_SURFACE_PADDING_X.sm,\n ].join(' ')}\n />\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport type { CustomCellEditorProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_HEIGHT,\n INPUT_SURFACE_PADDING_X,\n INPUT_SURFACE_TEXT,\n} from '../../_shared/input-surface';\n\nexport interface EditableCurrencyCellEditorParams {\n /** ISO 4217 currency code (e.g. `EUR`, `USD`). Defaults to `EUR`. */\n currency?: string;\n /** Decimal places allowed in the editor. Defaults to 2 (cents precision). */\n decimals?: number;\n /** Minimum allowed value — values below this are clamped on commit. */\n min?: number;\n /** Maximum allowed value — values above this are clamped on commit. */\n max?: number;\n}\n\n/**\n * Inline numeric editor that visually matches `<TextInput size=\"sm\">`. Use as\n * `cellEditor` on a colDef with `editable: true`. The display formatting is\n * still the renderer's job — once editing stops, the cell hands back to\n * `CurrencyCellRenderer` (or whichever renderer the colDef declares).\n *\n * Stores a Number, not a string, so consumers receive `row.amount = 12.5`\n * not `\"12.5\"`. Strips locale separators on each change so commas/dots in\n * any language convert to a clean numeric value.\n */\nexport function EditableCurrencyCellRenderer<TData = unknown>(\n props: CustomCellEditorProps<TData, number> &\n EditableCurrencyCellEditorParams,\n) {\n const {\n initialValue,\n onValueChange,\n stopEditing,\n column,\n decimals = 2,\n min,\n max,\n } = props;\n const { i18n } = useTranslation('ui');\n const inputRef = useRef<HTMLInputElement | null>(null);\n // Thread the column header into the input's accessible name — see\n // editable-text-cell-renderer.tsx for the rationale.\n const headerName =\n (column?.getColDef?.()?.headerName as string | undefined) ?? undefined;\n\n // Local string state so the user can type intermediate values like \"12.\"\n // before the trailing zero arrives. We commit a Number to AG Grid on each\n // change for consumers that watch row state live; the final commit fires\n // when editing stops.\n const [draft, setDraft] = useState<string>(() => {\n if (initialValue == null || Number.isNaN(initialValue)) return '';\n return String(initialValue);\n });\n\n useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.select();\n }, []);\n\n function parseDraft(input: string): number | null {\n if (input.trim().length === 0) return null;\n // Accept either the user's locale decimal separator or a `.`. Strip\n // grouping characters (locale thousands separators, plus spaces).\n const lang = i18n.language || 'en';\n const partsFmt = new Intl.NumberFormat(lang).formatToParts(12345.6);\n const groupChar = partsFmt.find((p) => p.type === 'group')?.value ?? '';\n const decimalChar =\n partsFmt.find((p) => p.type === 'decimal')?.value ?? '.';\n const cleaned = input\n .replace(new RegExp(`\\\\${groupChar}`, 'g'), '')\n .replace(decimalChar, '.')\n .replace(/[^\\d.-]/g, '');\n const n = Number(cleaned);\n return Number.isFinite(n) ? n : null;\n }\n\n function commit(input: string) {\n const parsed = parseDraft(input);\n if (parsed == null) {\n onValueChange(null);\n return;\n }\n // Clamp first, then round to the declared precision so we never\n // persist floating-point dust from string parsing.\n let clamped = parsed;\n if (typeof min === 'number') clamped = Math.max(min, clamped);\n if (typeof max === 'number') clamped = Math.min(max, clamped);\n const factor = 10 ** decimals;\n onValueChange(Math.round(clamped * factor) / factor);\n }\n\n return (\n <input\n ref={inputRef}\n type=\"text\"\n // Inputmode hints mobile keyboards to show the decimal pad instead\n // of the full keyboard. type=\"number\" would also work but spinners\n // and locale parsing are inconsistent across browsers.\n inputMode=\"decimal\"\n value={draft}\n aria-label={headerName}\n onChange={(e) => {\n const next = e.target.value;\n setDraft(next);\n commit(next);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n stopEditing();\n }\n // Escape — AG Grid cancels by default; the editor doesn't need\n // explicit handling beyond what AG Grid wires automatically.\n }}\n className={[\n 'ds:block ds:w-full ds:appearance-none ds:text-end ds:tabular-nums',\n INPUT_SURFACE_CHROME,\n // Use `md` height — see editable-text-cell-renderer for rationale.\n INPUT_SURFACE_HEIGHT.md,\n INPUT_SURFACE_TEXT.sm,\n INPUT_SURFACE_PADDING_X.sm,\n ].join(' ')}\n />\n );\n}\n"],"names":["useTotalRow","rowData","sumFields","options","useMemo","row","field","total","r","raw","n","ToothIcon","jsx","ToothCellRenderer","props","value","maxInlineSize","Tag","toNumber","CurrencyCellRenderer","currency","colorNegative","strikethrough","i18n","useTranslation","locale","formatted","classNames","reorderColumnWidth","ReorderCellRenderer","data","node","api","onMove","moveUpLabel","moveDownLabel","intent","group","disableAtEnds","t","rowIndex","lastIndex","atFirst","atLast","upLabel","downLabel","buttons","IconButton","ArrowUp","event","ArrowDown","IconButtonGroup","ToggleCellRenderer","onToggle","onError","trueIcon","falseIcon","trueClass","falseClass","label","pending","setPending","useState","isOn","icon","SquareCheckBig","Square","stateClass","resolvedLabel","handleClick","result","err","SIZE_CLASS","readField","HEX_RE","RGB_RE","HSL_RE","CSS_VAR_RE","sanitizeColor","v","ColorDotCellRenderer","colorField","size","labelField","dotRef","useRef","rawColor","color","useIsomorphicLayoutEffect","el","jsxs","readNumber","BalanceCellRenderer","lines","highlightNegative","formatLine","line","rendered","x","item","idx","EditableTextCellRenderer","initialValue","onValueChange","stopEditing","column","setValue","inputRef","useEffect","headerName","_b","_a","e","next","INPUT_SURFACE_CHROME","INPUT_SURFACE_HEIGHT","INPUT_SURFACE_TEXT","INPUT_SURFACE_PADDING_X","EditableCurrencyCellRenderer","decimals","min","max","draft","setDraft","parseDraft","input","lang","partsFmt","groupChar","p","decimalChar","cleaned","commit","parsed","clamped","factor"],"mappings":"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"}
@@ -7,12 +7,12 @@ import { u as Ji } from "./registry-DvAUVLHh.js";
7
7
  import { m as tt, M as Qi, A as es } from "./annotation-marker-D-M7y4R1.js";
8
8
  import { B as P } from "./button-DohK_Ak_.js";
9
9
  import { I as Ke } from "./icon-button-S8_weU3g.js";
10
- import { B as ts } from "./button-group-ZVb1Q-w4.js";
10
+ import { B as ts } from "./button-group-CUnNnt8a.js";
11
11
  import { C as ns } from "./combobox-D-gpgEDy.js";
12
- import { I as vn } from "./icon-button-group-CRKFR48b.js";
12
+ import { I as vn } from "./icon-button-group-mXvYDaba.js";
13
13
  import { S as Ar } from "./state-backed-text-input-Cgh4ms3p.js";
14
14
  import { C as Ze } from "./card-BA4Ig_kn.js";
15
- import { S as Tt } from "./separator-CYU_bGFn.js";
15
+ import { S as Tt } from "./separator-Bdc9bqoJ.js";
16
16
  import { S as rs } from "./slider-pZ95bEm7.js";
17
17
  import { S as is } from "./switch-D--x7n6h.js";
18
18
  import { a as ss } from "./format-number-DdzqwMs1.js";
@@ -3131,4 +3131,4 @@ export {
3131
3131
  Nn as t,
3132
3132
  Kr as u
3133
3133
  };
3134
- //# sourceMappingURL=face-scheme-BKSE98bo.js.map
3134
+ //# sourceMappingURL=face-scheme-DyHc3zPt.js.map