@alfadocs/ui-kit-debug 1.130.1 → 1.131.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/dist/_chunks/{actions-cell-renderer-DTaIQKp9.js → actions-cell-renderer-C-l_ppP6.js} +3 -3
  2. package/dist/_chunks/{actions-cell-renderer-DTaIQKp9.js.map → actions-cell-renderer-C-l_ppP6.js.map} +1 -1
  3. package/dist/_chunks/{alia-sidebar-BBxbMRmX.js → alia-sidebar-CK1zw_Bc.js} +2 -2
  4. package/dist/_chunks/{alia-sidebar-BBxbMRmX.js.map → alia-sidebar-CK1zw_Bc.js.map} +1 -1
  5. package/dist/_chunks/{anamnesis-summary-rows-CtcULkvc.js → anamnesis-summary-rows-CCNmkq55.js} +5 -5
  6. package/dist/_chunks/{anamnesis-summary-rows-CtcULkvc.js.map → anamnesis-summary-rows-CCNmkq55.js.map} +1 -1
  7. package/dist/_chunks/{appointment-card-vbUsDh70.js → appointment-card-OAOur8lH.js} +2 -2
  8. package/dist/_chunks/{appointment-card-vbUsDh70.js.map → appointment-card-OAOur8lH.js.map} +1 -1
  9. package/dist/_chunks/{appointment-peek-DdUhqfEi.js → appointment-peek-DZa6xyUb.js} +2 -2
  10. package/dist/_chunks/{appointment-peek-DdUhqfEi.js.map → appointment-peek-DZa6xyUb.js.map} +1 -1
  11. package/dist/_chunks/{appointment-timeline-B5pfBl-b.js → appointment-timeline-DQePqpyH.js} +3 -3
  12. package/dist/_chunks/{appointment-timeline-B5pfBl-b.js.map → appointment-timeline-DQePqpyH.js.map} +1 -1
  13. package/dist/_chunks/{appointment-tray-BhiXetjs.js → appointment-tray-DSFqO5Rm.js} +2 -2
  14. package/dist/_chunks/{appointment-tray-BhiXetjs.js.map → appointment-tray-DSFqO5Rm.js.map} +1 -1
  15. package/dist/_chunks/{balance-badge-cell-BtFge7Y6.js → balance-badge-cell-DTiMdnCZ.js} +4 -4
  16. package/dist/_chunks/{balance-badge-cell-BtFge7Y6.js.map → balance-badge-cell-DTiMdnCZ.js.map} +1 -1
  17. package/dist/_chunks/bill-line-table-DHKb_O7c.js +2000 -0
  18. package/dist/_chunks/bill-line-table-DHKb_O7c.js.map +1 -0
  19. package/dist/_chunks/body-pointer-lock-CsOEDm1I.js +15 -0
  20. package/dist/_chunks/body-pointer-lock-CsOEDm1I.js.map +1 -0
  21. package/dist/_chunks/{button-group-B2MJo0Se.js → button-group-DuQuuulC.js} +2 -2
  22. package/dist/_chunks/{button-group-B2MJo0Se.js.map → button-group-DuQuuulC.js.map} +1 -1
  23. package/dist/_chunks/{calculator-dialog-BGX5XQCM.js → calculator-dialog-Cg3GjaRf.js} +2 -2
  24. package/dist/_chunks/{calculator-dialog-BGX5XQCM.js.map → calculator-dialog-Cg3GjaRf.js.map} +1 -1
  25. package/dist/_chunks/{calendar-DzR-vdJ5.js → calendar-BIoOeBTT.js} +103 -103
  26. package/dist/_chunks/{calendar-DzR-vdJ5.js.map → calendar-BIoOeBTT.js.map} +1 -1
  27. package/dist/_chunks/{calendar-appointment-editor-dialog-CXch4Pmu.js → calendar-appointment-editor-dialog-WW6V1SGh.js} +15 -15
  28. package/dist/_chunks/{calendar-appointment-editor-dialog-CXch4Pmu.js.map → calendar-appointment-editor-dialog-WW6V1SGh.js.map} +1 -1
  29. package/dist/_chunks/{care-plan-card-CwgkImOD.js → care-plan-card-DKScH9Ss.js} +2 -2
  30. package/dist/_chunks/{care-plan-card-CwgkImOD.js.map → care-plan-card-DKScH9Ss.js.map} +1 -1
  31. package/dist/_chunks/{care-plan-entry-card-cdojypxu.js → care-plan-entry-card-AG1y3nyW.js} +2 -2
  32. package/dist/_chunks/{care-plan-entry-card-cdojypxu.js.map → care-plan-entry-card-AG1y3nyW.js.map} +1 -1
  33. package/dist/_chunks/{chart-Aue_2dMb.js → chart-D0EeFWst.js} +2 -2
  34. package/dist/_chunks/{chart-Aue_2dMb.js.map → chart-D0EeFWst.js.map} +1 -1
  35. package/dist/_chunks/{dashboard-grid-CaxgaEgI.js → dashboard-grid-2uVXEe9e.js} +2 -2
  36. package/dist/_chunks/{dashboard-grid-CaxgaEgI.js.map → dashboard-grid-2uVXEe9e.js.map} +1 -1
  37. package/dist/_chunks/{data-grid-C9xlUMLt.js → data-grid-B2oaI7Lt.js} +2345 -2328
  38. package/dist/_chunks/data-grid-B2oaI7Lt.js.map +1 -0
  39. package/dist/_chunks/{data-table-BCfkcPti.js → data-table-FTV3uRjX.js} +3 -3
  40. package/dist/_chunks/{data-table-BCfkcPti.js.map → data-table-FTV3uRjX.js.map} +1 -1
  41. package/dist/_chunks/{default-tabs-BnB6FUEW.js → default-tabs-DbebYO04.js} +5 -5
  42. package/dist/_chunks/{default-tabs-BnB6FUEW.js.map → default-tabs-DbebYO04.js.map} +1 -1
  43. package/dist/_chunks/{dialog-CIUn5oLb.js → dialog-CVTxyR0v.js} +48 -47
  44. package/dist/_chunks/dialog-CVTxyR0v.js.map +1 -0
  45. package/dist/_chunks/{document-preview-BWDTCEHI.js → document-preview-_kQ9QvZV.js} +2 -2
  46. package/dist/_chunks/{document-preview-BWDTCEHI.js.map → document-preview-_kQ9QvZV.js.map} +1 -1
  47. package/dist/_chunks/{dropdown-menu-Dw6sgQwJ.js → dropdown-menu-DBWaW4pq.js} +92 -88
  48. package/dist/_chunks/dropdown-menu-DBWaW4pq.js.map +1 -0
  49. package/dist/_chunks/{editable-currency-cell-renderer-BlK-8A7b.js → editable-currency-cell-renderer-CZMQ5xRT.js} +2 -2
  50. package/dist/_chunks/{editable-currency-cell-renderer-BlK-8A7b.js.map → editable-currency-cell-renderer-CZMQ5xRT.js.map} +1 -1
  51. package/dist/_chunks/{face-scheme-Bt07zQJU.js → face-scheme-D_Y1StPl.js} +3 -3
  52. package/dist/_chunks/{face-scheme-Bt07zQJU.js.map → face-scheme-D_Y1StPl.js.map} +1 -1
  53. package/dist/_chunks/{file-manager-Dpwv0qs-.js → file-manager-Bzr5NK1t.js} +5 -5
  54. package/dist/_chunks/{file-manager-Dpwv0qs-.js.map → file-manager-Bzr5NK1t.js.map} +1 -1
  55. package/dist/_chunks/{header-settings-ZGvYAuKF.js → header-settings-Cu-MKOsO.js} +2 -2
  56. package/dist/_chunks/{header-settings-ZGvYAuKF.js.map → header-settings-Cu-MKOsO.js.map} +1 -1
  57. package/dist/_chunks/{heatmap-Ds5DJBUL.js → heatmap-C5gJin_F.js} +3 -3
  58. package/dist/_chunks/{heatmap-Ds5DJBUL.js.map → heatmap-C5gJin_F.js.map} +1 -1
  59. package/dist/_chunks/{help-me-write-templates-C28E_rOt.js → help-me-write-templates-DO6vJeP4.js} +2 -2
  60. package/dist/_chunks/{help-me-write-templates-C28E_rOt.js.map → help-me-write-templates-DO6vJeP4.js.map} +1 -1
  61. package/dist/_chunks/{icon-button-group-BKtkVZ1W.js → icon-button-group-SmkdVCNx.js} +2 -2
  62. package/dist/_chunks/{icon-button-group-BKtkVZ1W.js.map → icon-button-group-SmkdVCNx.js.map} +1 -1
  63. package/dist/_chunks/{invoice-upload-list-tJY7W1g_.js → invoice-upload-list-B5aMffTy.js} +22 -22
  64. package/dist/_chunks/{invoice-upload-list-tJY7W1g_.js.map → invoice-upload-list-B5aMffTy.js.map} +1 -1
  65. package/dist/_chunks/{link-cell-renderer-CC9VHU68.js → link-cell-renderer-D3JLPURZ.js} +2 -2
  66. package/dist/_chunks/{link-cell-renderer-CC9VHU68.js.map → link-cell-renderer-D3JLPURZ.js.map} +1 -1
  67. package/dist/_chunks/{marketplace-app-shell-D_HA8CKx.js → marketplace-app-shell-dMmxI6MT.js} +4 -4
  68. package/dist/_chunks/{marketplace-app-shell-D_HA8CKx.js.map → marketplace-app-shell-dMmxI6MT.js.map} +1 -1
  69. package/dist/_chunks/{muscle-scheme-DdIdm8Gw.js → muscle-scheme-BGJD62op.js} +2 -2
  70. package/dist/_chunks/{muscle-scheme-DdIdm8Gw.js.map → muscle-scheme-BGJD62op.js.map} +1 -1
  71. package/dist/_chunks/{notes-panel-DIY7eNsq.js → notes-panel-Cm-_pCRJ.js} +3 -3
  72. package/dist/_chunks/{notes-panel-DIY7eNsq.js.map → notes-panel-Cm-_pCRJ.js.map} +1 -1
  73. package/dist/_chunks/{parts-tGzYz0uG.js → parts-BOnDDU3E.js} +2 -2
  74. package/dist/_chunks/{parts-tGzYz0uG.js.map → parts-BOnDDU3E.js.map} +1 -1
  75. package/dist/_chunks/{patient-search-OAwFgOW3.js → patient-search-DBvLFArV.js} +2 -2
  76. package/dist/_chunks/{patient-search-OAwFgOW3.js.map → patient-search-DBvLFArV.js.map} +1 -1
  77. package/dist/_chunks/{practice-results-BDnZtbDM.js → practice-results-M5A9-X9y.js} +3 -3
  78. package/dist/_chunks/{practice-results-BDnZtbDM.js.map → practice-results-M5A9-X9y.js.map} +1 -1
  79. package/dist/_chunks/{public-header.agent-Db4wm6_S.js → public-header.agent-DaeDfLfy.js} +2 -2
  80. package/dist/_chunks/{public-header.agent-Db4wm6_S.js.map → public-header.agent-DaeDfLfy.js.map} +1 -1
  81. package/dist/_chunks/{radiograph-panel.agent-B-r3BoqU.js → radiograph-panel.agent-88VjqlG7.js} +2 -2
  82. package/dist/_chunks/{radiograph-panel.agent-B-r3BoqU.js.map → radiograph-panel.agent-88VjqlG7.js.map} +1 -1
  83. package/dist/_chunks/{rich-text-editor-TnX0SYdq.js → rich-text-editor-DjHL1b3E.js} +3 -3
  84. package/dist/_chunks/{rich-text-editor-TnX0SYdq.js.map → rich-text-editor-DjHL1b3E.js.map} +1 -1
  85. package/dist/_chunks/{row-actions-Dpf9CrCP.js → row-actions-BF2-uizV.js} +3 -3
  86. package/dist/_chunks/{row-actions-Dpf9CrCP.js.map → row-actions-BF2-uizV.js.map} +1 -1
  87. package/dist/_chunks/{sheet-uZZXaO_S.js → sheet-BdhYeQQT.js} +84 -72
  88. package/dist/_chunks/sheet-BdhYeQQT.js.map +1 -0
  89. package/dist/_chunks/{signature-request-DW2PSp66.js → signature-request-4pGq3YBe.js} +3 -3
  90. package/dist/_chunks/{signature-request-DW2PSp66.js.map → signature-request-4pGq3YBe.js.map} +1 -1
  91. package/dist/_chunks/{tab-bar-CF8R38Og.js → tab-bar-CeC2QOwB.js} +2 -2
  92. package/dist/_chunks/{tab-bar-CF8R38Og.js.map → tab-bar-CeC2QOwB.js.map} +1 -1
  93. package/dist/_chunks/{tabs-P4qFmxk5.js → tabs-CRIDBLP7.js} +2 -2
  94. package/dist/_chunks/{tabs-P4qFmxk5.js.map → tabs-CRIDBLP7.js.map} +1 -1
  95. package/dist/_chunks/{task-editor-CVRrDqpe.js → task-editor-BL2hHxNz.js} +3 -3
  96. package/dist/_chunks/{task-editor-CVRrDqpe.js.map → task-editor-BL2hHxNz.js.map} +1 -1
  97. package/dist/_chunks/{tasks-panel-DBSm3WjK.js → tasks-panel-BE3zaayj.js} +2 -2
  98. package/dist/_chunks/{tasks-panel-DBSm3WjK.js.map → tasks-panel-BE3zaayj.js.map} +1 -1
  99. package/dist/_chunks/{theme-toggle-CeKl8f_f.js → theme-toggle-BQDFxvVS.js} +3 -3
  100. package/dist/_chunks/{theme-toggle-CeKl8f_f.js.map → theme-toggle-BQDFxvVS.js.map} +1 -1
  101. package/dist/_chunks/{token-insert-menu-BrK5NQIq.js → token-insert-menu-BLtfMTJd.js} +2 -2
  102. package/dist/_chunks/{token-insert-menu-BrK5NQIq.js.map → token-insert-menu-BLtfMTJd.js.map} +1 -1
  103. package/dist/_chunks/{toolbar-CC-Ls_eC.js → toolbar-CfdoJzMV.js} +3 -3
  104. package/dist/_chunks/{toolbar-CC-Ls_eC.js.map → toolbar-CfdoJzMV.js.map} +1 -1
  105. package/dist/_chunks/{tooth-scheme-DHRxV2sE.js → tooth-scheme-BtnFgugP.js} +2 -2
  106. package/dist/_chunks/{tooth-scheme-DHRxV2sE.js.map → tooth-scheme-BtnFgugP.js.map} +1 -1
  107. package/dist/_chunks/{use-appointment-details-read-BrykoTOR.js → use-appointment-details-read-_b7FRB1x.js} +4 -4
  108. package/dist/_chunks/{use-appointment-details-read-BrykoTOR.js.map → use-appointment-details-read-_b7FRB1x.js.map} +1 -1
  109. package/dist/_chunks/{verify-identity-types-D_LdByCp.js → verify-identity-types-CxtrBXsZ.js} +2 -2
  110. package/dist/_chunks/{verify-identity-types-D_LdByCp.js.map → verify-identity-types-CxtrBXsZ.js.map} +1 -1
  111. package/dist/_chunks/{warehouse-load-summary-DkAKXcw0.js → warehouse-load-summary-CMMYzTDv.js} +75 -66
  112. package/dist/_chunks/warehouse-load-summary-CMMYzTDv.js.map +1 -0
  113. package/dist/_chunks/{widget-picker-DrxJjEkv.js → widget-picker-D3T7e8a4.js} +2 -2
  114. package/dist/_chunks/{widget-picker-DrxJjEkv.js.map → widget-picker-D3T7e8a4.js.map} +1 -1
  115. package/dist/_chunks/{workflow-map-DCjkRuS_.js → workflow-map-DaZFP9SJ.js} +2 -2
  116. package/dist/_chunks/{workflow-map-DCjkRuS_.js.map → workflow-map-DaZFP9SJ.js.map} +1 -1
  117. package/dist/_chunks/{workflow-status-D0avpoeS.js → workflow-status-D1WgGVTP.js} +2 -2
  118. package/dist/_chunks/{workflow-status-D0avpoeS.js.map → workflow-status-D1WgGVTP.js.map} +1 -1
  119. package/dist/_chunks/{workflow-webhook-action-Cae02r_4.js → workflow-webhook-action-BsGSh3h9.js} +2 -2
  120. package/dist/_chunks/{workflow-webhook-action-Cae02r_4.js.map → workflow-webhook-action-BsGSh3h9.js.map} +1 -1
  121. package/dist/agent-catalog.json +10 -10
  122. package/dist/agent-i18n/en.json +3 -3
  123. package/dist/browser-support.js +1 -1
  124. package/dist/components/_shared/body-pointer-lock.d.ts +2 -0
  125. package/dist/components/_shared/body-pointer-lock.d.ts.map +1 -0
  126. package/dist/components/_shared/decimal.d.ts +2 -0
  127. package/dist/components/_shared/decimal.d.ts.map +1 -1
  128. package/dist/components/appointment-card/index.js +2 -2
  129. package/dist/components/appointment-details-panel/index.js +1 -1
  130. package/dist/components/appointment-peek/index.js +1 -1
  131. package/dist/components/appointment-timeline/index.js +1 -1
  132. package/dist/components/bill-line-table/bill-line-table.agent.d.ts.map +1 -1
  133. package/dist/components/bill-line-table/bill-line-table.columns.d.ts +4 -0
  134. package/dist/components/bill-line-table/bill-line-table.columns.d.ts.map +1 -1
  135. package/dist/components/bill-line-table/bill-line-table.d.ts.map +1 -1
  136. package/dist/components/bill-line-table/bill-line-table.header.d.ts +6 -0
  137. package/dist/components/bill-line-table/bill-line-table.header.d.ts.map +1 -1
  138. package/dist/components/bill-line-table/bill-line-table.invoice-cell.d.ts +6 -0
  139. package/dist/components/bill-line-table/bill-line-table.invoice-cell.d.ts.map +1 -0
  140. package/dist/components/bill-line-table/bill-line-table.model.d.ts +23 -10
  141. package/dist/components/bill-line-table/bill-line-table.model.d.ts.map +1 -1
  142. package/dist/components/bill-line-table/bill-line-table.scope.d.ts +56 -0
  143. package/dist/components/bill-line-table/bill-line-table.scope.d.ts.map +1 -0
  144. package/dist/components/bill-line-table/bill-line-table.types.d.ts +90 -10
  145. package/dist/components/bill-line-table/bill-line-table.types.d.ts.map +1 -1
  146. package/dist/components/bill-line-table/bill-line-table.variants.d.ts +2 -0
  147. package/dist/components/bill-line-table/bill-line-table.variants.d.ts.map +1 -1
  148. package/dist/components/bill-line-table/index.d.ts +3 -2
  149. package/dist/components/bill-line-table/index.d.ts.map +1 -1
  150. package/dist/components/bill-line-table/index.js +20 -18
  151. package/dist/components/bill-table/index.js +1 -1
  152. package/dist/components/button-group/index.js +1 -1
  153. package/dist/components/calculator-dialog/index.js +1 -1
  154. package/dist/components/calendar/calendar.d.ts.map +1 -1
  155. package/dist/components/calendar/index.js +1 -1
  156. package/dist/components/care-plan-card/index.js +1 -1
  157. package/dist/components/care-plan-entry-card/index.js +1 -1
  158. package/dist/components/chart/index.js +1 -1
  159. package/dist/components/dashboard-grid/index.js +1 -1
  160. package/dist/components/data-grid/body.d.ts.map +1 -1
  161. package/dist/components/data-grid/data-grid.d.ts.map +1 -1
  162. package/dist/components/data-grid/data-grid.variants.d.ts.map +1 -1
  163. package/dist/components/data-grid/index.js +2 -2
  164. package/dist/components/data-grid/types.d.ts +6 -0
  165. package/dist/components/data-grid/types.d.ts.map +1 -1
  166. package/dist/components/data-grid/use-data-grid-engine.d.ts.map +1 -1
  167. package/dist/components/data-table/index.js +4 -4
  168. package/dist/components/dialog/dialog.d.ts.map +1 -1
  169. package/dist/components/dialog/index.js +1 -1
  170. package/dist/components/document-preview/index.js +1 -1
  171. package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  172. package/dist/components/dropdown-menu/index.js +1 -1
  173. package/dist/components/face-scheme/index.js +1 -1
  174. package/dist/components/file-manager/index.js +1 -1
  175. package/dist/components/header-settings/index.js +1 -1
  176. package/dist/components/heatmap/index.js +1 -1
  177. package/dist/components/icon-button-group/index.js +1 -1
  178. package/dist/components/invoice-upload-list/index.js +1 -1
  179. package/dist/components/invoice-upload-list/invoice-upload-list.d.ts.map +1 -1
  180. package/dist/components/muscle-scheme/index.js +1 -1
  181. package/dist/components/notes-panel/index.js +1 -1
  182. package/dist/components/patient-search/index.js +1 -1
  183. package/dist/components/patient-table/index.js +1 -1
  184. package/dist/components/practice-results/index.js +1 -1
  185. package/dist/components/public-header/index.js +1 -1
  186. package/dist/components/radiograph-panel/index.js +1 -1
  187. package/dist/components/rich-text-editor/index.js +1 -1
  188. package/dist/components/row-actions/index.js +1 -1
  189. package/dist/components/sheet/index.js +1 -1
  190. package/dist/components/sheet/sheet.d.ts.map +1 -1
  191. package/dist/components/skeleton-scheme/index.js +1 -1
  192. package/dist/components/tab-bar/index.js +1 -1
  193. package/dist/components/tabs/index.js +1 -1
  194. package/dist/components/task-editor/index.js +1 -1
  195. package/dist/components/tasks-panel/index.js +1 -1
  196. package/dist/components/theme-toggle/index.js +1 -1
  197. package/dist/components/token-insert-menu/index.js +1 -1
  198. package/dist/components/tooth-scheme/index.js +1 -1
  199. package/dist/components/warehouse-load-summary/index.js +1 -1
  200. package/dist/components/warehouse-load-summary/warehouse-load-summary.d.ts.map +1 -1
  201. package/dist/components/widget-picker/index.js +1 -1
  202. package/dist/components/workflow/index.js +1 -1
  203. package/dist/components/workflow-status/index.js +1 -1
  204. package/dist/core.css +1 -1
  205. package/dist/decimal/index.js +32 -28
  206. package/dist/decimal/index.js.map +1 -1
  207. package/dist/host-compat.css +4 -1
  208. package/dist/index.js +1063 -1061
  209. package/dist/patterns/alia-assistant/index.js +1 -1
  210. package/dist/patterns/anamnesis/index.js +1 -1
  211. package/dist/patterns/calendar/index.js +1 -1
  212. package/dist/patterns/help-me-write-templates/index.js +1 -1
  213. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  214. package/dist/patterns/signature-request/index.js +1 -1
  215. package/dist/patterns/verify-identity/index.js +1 -1
  216. package/dist/patterns/workflow-webhook-action/index.js +1 -1
  217. package/dist/tokens.css +1 -1
  218. package/package.json +1 -1
  219. package/dist/_chunks/bill-line-table-CzYzg-Qh.js +0 -1757
  220. package/dist/_chunks/bill-line-table-CzYzg-Qh.js.map +0 -1
  221. package/dist/_chunks/data-grid-C9xlUMLt.js.map +0 -1
  222. package/dist/_chunks/dialog-CIUn5oLb.js.map +0 -1
  223. package/dist/_chunks/dropdown-menu-Dw6sgQwJ.js.map +0 -1
  224. package/dist/_chunks/sheet-uZZXaO_S.js.map +0 -1
  225. package/dist/_chunks/warehouse-load-summary-DkAKXcw0.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"dialog-CIUn5oLb.js","sources":["../../src/components/dialog/focus-return.ts","../../src/components/dialog/dialog.agent.ts","../../src/components/dialog/dialog.tsx"],"sourcesContent":["/*\n * Focus return for a Dialog opened without a Dialog.Trigger.\n *\n * Radix returns focus to its Trigger on close, and to nothing when there is\n * no Trigger, so a controlled dialog opened from a button, a row action or a\n * menu item left focus on <body>. Dialog.Root records where focus was when it\n * opened (`focusReturnCandidates`), and Dialog.Content hands it back on close\n * (`restoreFocus`).\n *\n * A menu item is gone by the time the dialog closes, so the list also holds\n * the control that opened each enclosing menu (a submenu's item, then the\n * menu's trigger): the first one still in the page and focusable wins.\n */\n\n/** How many menu levels to climb; a guard against a labelling loop. */\nconst MAX_MENU_DEPTH = 8;\n\nfunction asHTMLElement(node: Element | null | undefined): HTMLElement | null {\n return node instanceof HTMLElement ? node : null;\n}\n\n/** The control that opened a menu: Radix labels the menu with its trigger's\n * id, and the open trigger names the menu in `aria-controls`. */\nfunction menuOpener(menu: HTMLElement): HTMLElement | null {\n const doc = menu.ownerDocument;\n const labelIds = menu.getAttribute('aria-labelledby')?.split(/\\s+/) ?? [];\n for (const id of labelIds) {\n const label = id ? asHTMLElement(doc.getElementById(id)) : null;\n if (label && !menu.contains(label)) return label;\n }\n if (menu.id) {\n const controller = asHTMLElement(\n doc.querySelector(`[aria-controls~=\"${CSS.escape(menu.id)}\"]`),\n );\n if (controller && !menu.contains(controller)) return controller;\n }\n return null;\n}\n\n/**\n * The elements focus should go back to, best first: the element focused when\n * the dialog opened, then the opener of each menu it sits in. Empty when\n * nothing was focused (focus on <body>).\n */\nexport function focusReturnCandidates(active: Element | null): HTMLElement[] {\n const candidates: HTMLElement[] = [];\n let current = asHTMLElement(active);\n if (!current || current === current.ownerDocument.body) return candidates;\n for (let depth = 0; current && depth <= MAX_MENU_DEPTH; depth += 1) {\n candidates.push(current);\n const menu = current.closest<HTMLElement>('[role=\"menu\"]');\n if (!menu) break;\n current = menuOpener(menu);\n }\n return candidates;\n}\n\nfunction canTakeFocus(element: HTMLElement): boolean {\n return (\n element.isConnected &&\n !element.matches(':disabled') &&\n element.closest('[inert]') === null &&\n element.getClientRects().length > 0\n );\n}\n\n/**\n * Focus the first candidate that is still in the page and can take focus.\n * Returns false when none could, so the caller leaves Radix's default alone.\n */\nexport function restoreFocus(candidates: readonly HTMLElement[]): boolean {\n for (const element of candidates) {\n if (!canTakeFocus(element)) continue;\n // As Radix's own focus return: no scroll jump to a far-off row.\n element.focus({ preventScroll: true });\n if (element.ownerDocument.activeElement === element) return true;\n }\n return false;\n}\n","import type { AgentAdapter } from '../../agent/types';\nimport type { DialogHandle } from './dialog';\n\n/**\n * Dialog wraps Radix Dialog. The curated handle (`DialogHandle`) bridges the\n * Radix controlled-or-uncontrolled `open` state so an agent can observe and\n * drive the dialog without owning the React state itself.\n */\nexport const dialogAgent: AgentAdapter<DialogHandle> = {\n id: 'dialog',\n capabilities: ['open', 'close', 'dismiss'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dialog.state.isOpen',\n description: 'True when the dialog is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.open',\n description: 'Open the dialog.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.close',\n description: 'Close the dialog. Reversible by reopening.',\n invoke: (handle) => {\n handle.close();\n },\n },\n dismiss: {\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.dismiss',\n description:\n 'Dismiss the dialog. Loses any in-progress input that has not been committed.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dialog' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Dialog.Root.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport * as RadixDialog from '@radix-ui/react-dialog';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { X } from 'lucide-react';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent';\nimport { useNonModalTabExit } from '../_shared/non-modal-tab-exit';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { focusReturnCandidates, restoreFocus } from './focus-return';\nimport { dialogAgent } from './dialog.agent';\n\n// The `ds-dialog__*` class names below are the framework-agnostic contract\n// defined in src/styles.css (@layer ui-kit-components). The React component\n// renders the SAME classes a vanilla (non-React) host hand-authors — the\n// surface (`ds-dialog__surface` + its size modifiers), the close button\n// (`ds-dialog__close`), and the body slot (`ds-dialog__body`) — so there is\n// ONE visual skin (scrim, radius, elevation, bg, padding, centering, sizing,\n// close-button glyph + hover/focus) and the two surfaces can't drift. The few\n// Tailwind utilities that remain are NOT skin: they are the Radix animation\n// hooks (`data-[state=…]:animate-*`) and the surface focus-suppression chrome\n// — neither lives in the vanilla CSS contract. Layer order\n// (`…, utilities, ui-kit-tokens, ui-kit-components`) puts the `ds-dialog__*`\n// rules after Tailwind's utilities, so the contract owns every visual\n// property and the animation utilities only touch `animation` / `outline`.\nconst OVERLAY_CLASSES = [\n 'ds-dialog__backdrop',\n 'ds:backdrop-blur-sm',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out-0',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\n// Animation + focus chrome only — every visual property (position, centering,\n// bg, radius, elevation, padding, sizing) comes from `.ds-dialog__surface`.\nconst SURFACE_CHROME = [\n 'ds:focus-visible:outline-none',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in-0 ds:data-[state=open]:zoom-in-95',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out-0 ds:data-[state=closed]:zoom-out-95',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\n// CVA drives only the contract class names per size. `ds-dialog` is the host\n// marker (cascade-reset boundary); `ds-dialog__surface` carries the panel skin;\n// the `--sm` / `--lg` / `--fullscreen` modifiers shift only `max-inline-size`\n// (or the fullscreen geometry) and are defined alongside the base rule in\n// src/styles.css — so size, like the skin, lives in one place.\nconst contentVariants = cva(`ds-dialog ds-dialog__surface ${SURFACE_CHROME}`, {\n variants: {\n size: {\n sm: 'ds-dialog__surface--sm',\n md: '',\n lg: 'ds-dialog__surface--lg',\n xl: 'ds-dialog__surface--xl',\n fullscreen: 'ds-dialog__surface--fullscreen',\n },\n // `body` pins the header and footer and scrolls only `Dialog.Body` once\n // the content passes the height cap. `surface` (default) scrolls the\n // whole panel as one block.\n scroll: {\n surface: '',\n body: 'ds-dialog__surface--scroll-body',\n },\n // `flush` drops the surface padding for content that brings its own\n // header, scroll box and footer (a docked panel thrown in a dialog).\n flush: {\n true: 'ds-dialog__surface--flush',\n false: '',\n },\n },\n defaultVariants: { size: 'md', scroll: 'surface', flush: false },\n});\n\n// Curated agent-readiness handle — see dialog.agent.ts.\nexport interface DialogHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface DialogRootProps extends ComponentPropsWithoutRef<\n typeof RadixDialog.Root\n> {\n /** Opaque instance id — forwarded to Dialog.Content as `data-component-id`. */\n id?: string;\n}\n\ninterface DialogContextValue {\n id?: string;\n modal: boolean;\n /** Set while a Dialog.Trigger is mounted: Radix returns focus to it. */\n triggerRef: MutableRefObject<HTMLButtonElement | null>;\n /** Where focus was when the dialog opened, best first (focus-return.ts). */\n returnFocusRef: MutableRefObject<HTMLElement[]>;\n}\n\nconst DialogContext = createContext<DialogContextValue>({\n modal: true,\n triggerRef: { current: null },\n returnFocusRef: { current: [] },\n});\n\nconst DialogRoot = ({\n children,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true,\n ...props\n}: DialogRootProps) => {\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 handle = useMemo<DialogHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [setOpen],\n );\n useAgentRegistration(dialogAgent, handle, id);\n\n // Record where focus is as the dialog opens. A layout effect runs before\n // Radix's FocusScope moves focus into the content (a passive effect), so\n // this still sees the button, row action or menu item that opened it.\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const returnFocusRef = useRef<HTMLElement[]>([]);\n useIsomorphicLayoutEffect(() => {\n if (open) {\n returnFocusRef.current = focusReturnCandidates(document.activeElement);\n }\n }, [open]);\n\n const context = useMemo(\n () => ({ id, modal, triggerRef, returnFocusRef }),\n [id, modal],\n );\n\n return (\n <DialogContext.Provider value={context}>\n <RadixDialog.Root\n open={open}\n onOpenChange={setOpen}\n modal={modal}\n {...props}\n >\n {children}\n </RadixDialog.Root>\n </DialogContext.Provider>\n );\n};\nDialogRoot.displayName = 'Dialog.Root';\n\nconst DialogTrigger = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Trigger>\n>(({ children, ...props }, ref) => {\n const { triggerRef } = useContext(DialogContext);\n return (\n <RadixDialog.Trigger ref={composeRefs(ref, triggerRef)} {...props}>\n {children}\n </RadixDialog.Trigger>\n );\n});\nDialogTrigger.displayName = 'Dialog.Trigger';\n\nconst DialogClose = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Close>\n>(({ children, ...props }, ref) => (\n <RadixDialog.Close ref={ref} {...props}>\n {children}\n </RadixDialog.Close>\n));\nDialogClose.displayName = 'Dialog.Close';\n\nexport interface DialogContentProps\n extends\n Omit<ComponentPropsWithoutRef<typeof RadixDialog.Content>, 'role'>,\n VariantProps<typeof contentVariants> {\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n variant?: 'default' | 'alert' | 'confirmation';\n /**\n * Hide the top-right dismiss \"X\". The default is **variant-aware**: the X is\n * shown for `variant=\"default\"` and hidden for `variant=\"alert\"` /\n * `\"confirmation\"` (forced-choice surfaces, where the decision is made via\n * the explicit footer actions). An explicit value always wins — pass `false`\n * to force the X onto an alert, or `true` to suppress it on a default dialog.\n */\n hideCloseButton?: boolean;\n /**\n * What scrolls once the content passes the height cap (85dvh). `surface`\n * (default) scrolls the whole panel, title and footer included. `body`\n * keeps `Dialog.Header` and `Dialog.Footer` in view and scrolls only\n * `Dialog.Body`, so the content must sit in a `Dialog.Body`. Below 480px\n * of viewport height it falls back to scrolling the whole panel.\n */\n scroll?: 'surface' | 'body';\n /**\n * No surface padding, and the surface becomes a column that does not\n * scroll itself: for one child that brings its own header, scroll box\n * and footer, such as a side panel shown in a dialog. That child must\n * fill the column (`flex: 1; min-block-size: 0`) and scroll inside.\n */\n flush?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nconst DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(\n (\n {\n size = 'md',\n variant = 'default',\n scroll = 'surface',\n flush = false,\n hideCloseButton,\n className,\n children,\n onKeyDown,\n onCloseAutoFocus,\n onInteractOutside,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const {\n id: instanceId,\n modal,\n triggerRef,\n returnFocusRef,\n } = useContext(DialogContext);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const interactedOutsideRef = useRef(false);\n const exitOnTab = useNonModalTabExit(!modal);\n // Only forward `role` when we actually need to override Radix's default\n // (`role=\"dialog\"`). Passing `role={undefined}` explicitly wins over\n // Radix's internal assignment and strips the attribute entirely.\n const roleOverride =\n variant === 'alert' ? { role: 'alertdialog' as const } : {};\n\n // Variant-aware close default: plain dialogs expose the dismiss X; alert\n // and confirmation dialogs are forced-choice (no X) so the decision is\n // made via the explicit footer actions. An explicit `hideCloseButton`\n // always wins.\n const closeHidden = hideCloseButton ?? variant !== 'default';\n\n return (\n <RadixDialog.Portal>\n <RadixDialog.Overlay\n data-component=\"dialog-overlay\"\n className={OVERLAY_CLASSES}\n />\n <RadixDialog.Content\n ref={composeRefs(ref, contentRef)}\n {...roleOverride}\n data-component=\"dialog\"\n data-component-id={instanceId}\n className={contentVariants({ size, scroll, flush, className })}\n {...props}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n exitOnTab(event);\n }}\n onInteractOutside={(event) => {\n onInteractOutside?.(event);\n if (!event.defaultPrevented) interactedOutsideRef.current = true;\n }}\n onCloseAutoFocus={(event) => {\n onCloseAutoFocus?.(event);\n const interactedOutside = interactedOutsideRef.current;\n interactedOutsideRef.current = false;\n // The host chose a target, or a Dialog.Trigger is mounted and\n // Radix returns focus to it, as before.\n if (event.defaultPrevented || triggerRef.current?.isConnected) {\n return;\n }\n // A non-modal dialog left by clicking elsewhere keeps focus\n // where the user put it (Radix does the same for its Trigger).\n if (!modal && interactedOutside) return;\n const active = document.activeElement;\n const focusMovedOn =\n active !== null &&\n active !== document.body &&\n !contentRef.current?.contains(active);\n if (focusMovedOn) return;\n if (restoreFocus(returnFocusRef.current)) event.preventDefault();\n }}\n >\n {children}\n\n {!closeHidden && (\n // The close is a plain button carrying the `ds-dialog__close`\n // contract class — the SAME class a vanilla host renders. The CSS\n // (src/styles.css) owns its position, sizing, glyph size, hover\n // wash, and focus ring from tokens, so the React and non-React\n // close buttons are identical and can't drift.\n <RadixDialog.Close\n type=\"button\"\n className=\"ds-dialog__close\"\n aria-label={t('common.close', 'Close')}\n >\n <X aria-hidden=\"true\" />\n </RadixDialog.Close>\n )}\n </RadixDialog.Content>\n </RadixDialog.Portal>\n );\n },\n);\nDialogContent.displayName = 'Dialog.Content';\n\nconst DialogHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={['ds-dialog__header', className].filter(Boolean).join(' ')}\n {...props}\n />\n ),\n);\nDialogHeader.displayName = 'Dialog.Header';\n\n// Optional body slot. Carries the `ds-dialog__body` contract class — the SAME\n// class a vanilla host renders — so content / iframe slots match between the\n// React and non-React surfaces and can't drift. Additive: content placed\n// directly in Dialog.Content (without this wrapper) still works as before.\nconst DialogBody = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={['ds-dialog__body', className].filter(Boolean).join(' ')}\n {...props}\n />\n ),\n);\nDialogBody.displayName = 'Dialog.Body';\n\nconst DialogTitle = forwardRef<\n HTMLHeadingElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Title>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Title\n ref={ref}\n className={['ds-dialog__title type-title-card ds:break-words', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nDialogTitle.displayName = 'Dialog.Title';\n\nconst DialogDescription = forwardRef<\n HTMLParagraphElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Description>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Description\n ref={ref}\n className={['type-body-sm ds:text-[var(--muted-foreground)]', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nDialogDescription.displayName = 'Dialog.Description';\n\ninterface DialogFooterProps extends HTMLAttributes<HTMLDivElement> {\n divider?: boolean;\n}\n\n// Below 384px of footer width (a phone, whatever the dialog size) every\n// action goes full-width on its own line, in DOM order, so each label fits on\n// one line. The footer is its own container; px so a host root cannot move it.\nconst footerVariants = cva(\n [\n 'ds:@container/dialog-footer',\n 'ds:flex ds:flex-wrap ds:items-center ds:justify-end ds:gap-[var(--spacing-sm)]',\n 'ds:@max-[384px]/dialog-footer:[&>*]:w-full',\n 'ds:mt-[var(--spacing-md)]',\n ].join(' '),\n {\n variants: {\n divider: {\n true: 'ds:border-t ds:border-[color:var(--border)] ds:pt-[var(--spacing-md)]',\n false: '',\n },\n },\n defaultVariants: { divider: false },\n },\n);\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(\n ({ className, divider = false, ...props }, ref) => (\n <div\n ref={ref}\n className={footerVariants({ divider, className })}\n {...props}\n />\n ),\n);\nDialogFooter.displayName = 'Dialog.Footer';\n\nexport const Dialog = Object.assign(DialogRoot, {\n Root: DialogRoot,\n Trigger: DialogTrigger,\n Content: DialogContent,\n Header: DialogHeader,\n Title: DialogTitle,\n Description: DialogDescription,\n Body: DialogBody,\n Footer: DialogFooter,\n Close: DialogClose,\n});\n\nexport type { DialogFooterProps };\n"],"names":["MAX_MENU_DEPTH","asHTMLElement","node","menuOpener","menu","doc","labelIds","_a","id","label","controller","focusReturnCandidates","active","candidates","current","depth","canTakeFocus","element","restoreFocus","dialogAgent","handle","OVERLAY_CLASSES","SURFACE_CHROME","contentVariants","cva","DialogContext","createContext","DialogRoot","children","openProp","defaultOpen","onOpenChange","modal","props","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","useMemo","useAgentRegistration","triggerRef","returnFocusRef","useIsomorphicLayoutEffect","context","jsx","RadixDialog","DialogTrigger","forwardRef","ref","useContext","composeRefs","DialogClose","DialogContent","size","variant","scroll","flush","hideCloseButton","className","onKeyDown","onCloseAutoFocus","onInteractOutside","t","useTranslation","instanceId","contentRef","interactedOutsideRef","exitOnTab","useNonModalTabExit","roleOverride","closeHidden","jsxs","event","interactedOutside","_b","X","DialogHeader","DialogBody","DialogTitle","DialogDescription","footerVariants","DialogFooter","divider","Dialog"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropdown-menu-Dw6sgQwJ.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 useId,\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 // The ink comes from the variants below, one colour class per state:\n // two text-colour utilities on one element resolve by stylesheet order,\n // not by class order, and --foreground would win over --destructive.\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:select-none ds:outline-none',\n // Radix highlights on hover and on keyboard focus alike. The highlight\n // itself comes from the `unavailable` variant below.\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 variants: {\n /* Item only. A lit row repoints --destructive to the accent ink\n (MENU_ROW_HIGHLIGHT), so the label keeps its contrast there. */\n variant: { default: '', destructive: '' },\n /* An Item that is disabled with a reason: it keeps focus, so it is\n muted rather than faded, and the reason stays readable. */\n unavailable: {\n /* Lit, it stays neutral: the accent fill reads as \"ready to\n choose\", and it would turn the muted reason into accent ink. */\n true: [\n 'ds:text-[color:var(--muted-foreground)] ds:cursor-not-allowed',\n 'ds:forced-colors:text-[GrayText]',\n 'ds:data-[highlighted]:bg-[var(--muted)]',\n 'ds:forced-colors:data-[highlighted]:outline-solid',\n 'ds:forced-colors:data-[highlighted]:outline-[length:var(--focus-ring-width)]',\n 'ds:forced-colors:data-[highlighted]:outline-[GrayText]',\n 'ds:forced-colors:data-[highlighted]:[outline-offset:calc(var(--focus-ring-width)*-1)]',\n ].join(' '),\n /* The pointer lives here, not in the base: two cursor utilities on\n one element resolve by stylesheet order, and it would win. */\n false: `ds:cursor-pointer ${MENU_ROW_HIGHLIGHT.highlighted}`,\n },\n },\n compoundVariants: [\n {\n variant: 'default',\n unavailable: false,\n className: 'ds:text-[color:var(--foreground)]',\n },\n {\n variant: 'destructive',\n unavailable: false,\n className: 'ds:text-[color:var(--destructive)]',\n },\n ],\n defaultVariants: { variant: 'default', unavailable: false },\n },\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 /** `'destructive'` paints the label and icon in `--destructive`, for an\n * action that deletes or cancels. The host still confirms it (AlertDialog).\n * Default `'default'`. */\n variant?: 'default' | 'destructive';\n /** Why the item cannot be chosen. Only read with `disabled`: the item then\n * stays reachable by arrow keys and typeahead (the APG menu pattern), is\n * `aria-disabled`, ignores Enter, Space and click (the menu stays open),\n * and shows the reason as its second line, in place of `description`,\n * linked with `aria-describedby`. Without a reason, `disabled` items are\n * skipped, as before. Pass translated text. */\n disabledReason?: 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 variant,\n disabled,\n disabledReason,\n textValue,\n onSelect,\n onClick,\n children,\n 'aria-describedby': ariaDescribedBy,\n ...props\n },\n ref,\n ) => {\n const baseId = useId();\n const reasonId = `${baseId}-reason`;\n const labelId = `${baseId}-label`;\n /* Disabled with a reason: Radix must not see `disabled`, or it would\n take the item out of arrow navigation. The guard below refuses it. */\n const unavailable = Boolean(disabled && disabledReason);\n const secondLine = unavailable ? disabledReason : description;\n /* The reason is the description, so it stays out of the name, which a\n menuitem would otherwise take from all of its text. */\n const nameFromLabel =\n unavailable && !props['aria-label'] && !props['aria-labelledby'];\n return (\n <RadixDropdownMenu.Item\n ref={ref}\n className={itemClasses({ variant, unavailable, className })}\n disabled={unavailable ? false : disabled}\n // Typeahead matches the label, never the reason under it.\n textValue={\n textValue ??\n (unavailable && typeof children === 'string' ? children : undefined)\n }\n aria-describedby={\n unavailable\n ? [ariaDescribedBy, reasonId].filter(Boolean).join(' ')\n : ariaDescribedBy\n }\n onClick={(event) => {\n if (unavailable) return;\n onClick?.(event);\n }}\n onSelect={(event) => {\n if (unavailable) {\n // Keeps the menu open and the item focused.\n event.preventDefault();\n return;\n }\n onSelect?.(event);\n }}\n {...props}\n {...(unavailable\n ? { 'aria-disabled': true, 'data-unavailable': '' }\n : undefined)}\n {...(nameFromLabel ? { 'aria-labelledby': labelId } : undefined)}\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\n id={nameFromLabel ? labelId : undefined}\n className=\"ds:truncate\"\n >\n {children}\n </span>\n {unavailable ? (\n /* Wraps inside the width the labels set (w-0 + min-w-full),\n rather than widening the menu or being cut off. */\n <span\n id={reasonId}\n className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:w-0 ds:min-w-full ds:whitespace-normal ds:[overflow-wrap:anywhere]\"\n >\n {secondLine}\n </span>\n ) : secondLine ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {secondLine}\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 },\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","variant","disabledReason","textValue","onSelect","onClick","children","ariaDescribedBy","baseId","useId","reasonId","labelId","unavailable","secondLine","nameFromLabel","jsxs","event","Kbd","CheckboxItem","Check","useSettingRow","register","latest","useLayoutEffect","proxy","switchTrackClasses","switchThumbClasses","SwitchItem","onCheckedChange","RadioGroup","RadioItem","Label","MenuSeparator","DsSeparator","Shortcut","keys","separator","Sub","SubTrigger","ChevronRight","SubContent","ChoiceSub","label","onValueChange","current","DropdownMenu"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sheet-uZZXaO_S.js","sources":["../../src/components/sheet/sheet.agent.ts","../../src/components/sheet/sheet.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { SheetHandle } from './sheet';\n\nexport const sheetAgent: AgentAdapter<SheetHandle> = {\n id: 'sheet',\n // `dismiss` shares the handle's close() — it is the same imperative close\n // path with destructive intent (loses uncommitted input). Backed.\n capabilities: ['open', 'close', 'dismiss'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.sheet.state.isOpen',\n description: 'True when the sheet is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n // Pure ephemeral UI state — opening loses no data.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.sheet.actions.open',\n description: 'Open the sheet.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n // Pure ephemeral UI state — closing is reversible by reopening and\n // loses no committed data.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.sheet.actions.close',\n description: 'Close the sheet. Reversible by reopening.',\n invoke: (handle) => {\n handle.close();\n },\n },\n dismiss: {\n // Same close() path, but flagged destructive because dismissing a sheet\n // mid-edit discards any in-progress input that was not committed.\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.sheet.actions.dismiss',\n description:\n 'Dismiss the sheet. Loses any in-progress input that has not been committed.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'sheet' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Sheet.Root.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport * as RadixDialog from '@radix-ui/react-dialog';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { X } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { ScrollArea } from '../scroll-area/scroll-area';\nimport { useAgentRegistration } from '../../agent';\nimport { useNonModalTabExit } from '../_shared/non-modal-tab-exit';\nimport { sheetAgent } from './sheet.agent';\n\nconst OVERLAY_CLASSES = [\n 'ds:fixed ds:inset-0 ds:z-[var(--z-modal-backdrop)]',\n 'ds:bg-[var(--background)]/[var(--opacity-70)]',\n 'ds:backdrop-blur-sm',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out-0',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\nconst contentVariants = cva(\n [\n 'ds:fixed ds:z-[var(--z-modal)] ds:flex ds:flex-col',\n 'ds:bg-[var(--popover)] ds:text-[var(--popover-foreground)]',\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:focus-visible:outline-none',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n side: {\n start: [\n 'ds:start-0 ds:inset-y-0',\n 'ds:border-e ds:border-[color:var(--border)]',\n 'ds:data-[state=open]:animate-in ds:ltr:data-[state=open]:slide-in-from-left-full ds:rtl:data-[state=open]:slide-in-from-right-full',\n 'ds:data-[state=closed]:animate-out ds:ltr:data-[state=closed]:slide-out-to-left-full ds:rtl:data-[state=closed]:slide-out-to-right-full',\n 'ds:max-sm:[inline-size:100dvw] ds:max-sm:[block-size:100dvh]',\n ].join(' '),\n end: [\n 'ds:end-0 ds:inset-y-0',\n 'ds:border-s ds:border-[color:var(--border)]',\n 'ds:data-[state=open]:animate-in ds:ltr:data-[state=open]:slide-in-from-right-full ds:rtl:data-[state=open]:slide-in-from-left-full',\n 'ds:data-[state=closed]:animate-out ds:ltr:data-[state=closed]:slide-out-to-right-full ds:rtl:data-[state=closed]:slide-out-to-left-full',\n 'ds:max-sm:[inline-size:100dvw] ds:max-sm:[block-size:100dvh]',\n ].join(' '),\n top: [\n 'ds:top-0 ds:inset-x-0',\n 'ds:border-b ds:border-[color:var(--border)]',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:slide-in-from-top-full',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:slide-out-to-top-full',\n ].join(' '),\n bottom: [\n 'ds:bottom-0 ds:inset-x-0',\n 'ds:border-t ds:border-[color:var(--border)]',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:slide-in-from-bottom-full',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:slide-out-to-bottom-full',\n ].join(' '),\n },\n },\n defaultVariants: { side: 'end' },\n },\n);\n\nfunction getSizeClass(\n side: 'start' | 'end' | 'top' | 'bottom',\n size: 'sm' | 'md' | 'lg',\n): string {\n if (side === 'start' || side === 'end') {\n // These MUST carry the `ds:` prefix — a bare `[inline-size:…]` is not a\n // recognised utility under `prefix: 'ds'`, so Tailwind emits no rule and the\n // sheet renders full-bleed (the mobile `ds:max-sm:[inline-size:100dvw]`\n // classes work precisely because they are prefixed).\n const map = {\n sm: 'ds:[inline-size:360px]',\n md: 'ds:[inline-size:480px]',\n lg: 'ds:[inline-size:640px]',\n } as const;\n return map[size];\n }\n\n const map = {\n sm: 'ds:[block-size:40dvh]',\n md: 'ds:[block-size:60dvh]',\n lg: 'ds:[block-size:80dvh]',\n } as const;\n return map[size];\n}\n\n// Curated agent-readiness handle — see sheet.agent.ts.\nexport interface SheetHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface SheetRootProps extends ComponentPropsWithoutRef<\n typeof RadixDialog.Root\n> {\n /** Opaque instance id — forwarded to Sheet.Content as `data-component-id`. */\n id?: string;\n}\n\ninterface SheetContextValue {\n id?: string;\n modal: boolean;\n}\n\nconst SheetContext = createContext<SheetContextValue>({ modal: true });\n\nconst SheetRoot = ({\n children,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true,\n ...props\n}: SheetRootProps) => {\n const isControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = useState<boolean>(\n defaultOpen ?? false,\n );\n const open = isControlled ? Boolean(openProp) : internalOpen;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n const handle = useMemo<SheetHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [setOpen],\n );\n useAgentRegistration(sheetAgent, handle, id);\n\n const context = useMemo(() => ({ id, modal }), [id, modal]);\n\n return (\n <SheetContext.Provider value={context}>\n <RadixDialog.Root\n open={open}\n onOpenChange={setOpen}\n modal={modal}\n {...props}\n >\n {children}\n </RadixDialog.Root>\n </SheetContext.Provider>\n );\n};\nSheetRoot.displayName = 'Sheet.Root';\n\nconst SheetTrigger = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Trigger>\n>(({ children, ...props }, ref) => (\n <RadixDialog.Trigger ref={ref} {...props}>\n {children}\n </RadixDialog.Trigger>\n));\nSheetTrigger.displayName = 'Sheet.Trigger';\n\nconst SheetClose = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Close>\n>(({ children, ...props }, ref) => (\n <RadixDialog.Close ref={ref} {...props}>\n {children}\n </RadixDialog.Close>\n));\nSheetClose.displayName = 'Sheet.Close';\n\nexport interface SheetContentProps\n extends\n Omit<ComponentPropsWithoutRef<typeof RadixDialog.Content>, 'className'>,\n VariantProps<typeof contentVariants> {\n side?: 'start' | 'end' | 'top' | 'bottom';\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n children: ReactNode;\n}\n\nconst SheetContent = forwardRef<HTMLDivElement, SheetContentProps>(\n (\n { side = 'end', size = 'md', className, children, onKeyDown, ...props },\n ref,\n ) => {\n const { id: instanceId, modal } = useContext(SheetContext);\n const exitOnTab = useNonModalTabExit(!modal);\n return (\n <RadixDialog.Portal>\n <RadixDialog.Overlay\n data-component=\"sheet-overlay\"\n className={OVERLAY_CLASSES}\n />\n <RadixDialog.Content\n ref={ref}\n className={[\n contentVariants({ side }),\n getSizeClass(side, size),\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n data-component=\"sheet\"\n data-component-id={instanceId}\n {...props}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n exitOnTab(event);\n }}\n >\n {children}\n </RadixDialog.Content>\n </RadixDialog.Portal>\n );\n },\n);\nSheetContent.displayName = 'Sheet.Content';\n\nconst SheetHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => {\n const { t } = useTranslation('ui');\n\n return (\n <div\n ref={ref}\n className={[\n 'ds:sticky ds:top-0 ds:z-10 ds:flex ds:items-center ds:justify-between',\n 'ds:ps-[var(--spacing-lg)] ds:pe-[var(--spacing-lg)] ds:py-[var(--spacing-md)]',\n 'ds:border-b ds:border-[color:var(--border)] ds:bg-[var(--popover)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {children}\n <SheetClose asChild>\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('common.close', 'Close')}\n />\n </SheetClose>\n </div>\n );\n },\n);\nSheetHeader.displayName = 'Sheet.Header';\n\nconst SheetBody = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n // ScrollArea forwards its ref to the scroll container (Radix viewport), so\n // SheetBody's ref still points at the scroller — preserving scrollTop access.\n <ScrollArea\n ref={ref}\n orientation=\"vertical\"\n className=\"ds:flex-1 ds:min-h-0\"\n >\n <div\n className={[\n 'ds:ps-[var(--spacing-lg)] ds:pe-[var(--spacing-lg)] ds:py-[var(--spacing-lg)]',\n 'ds:break-words',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n </ScrollArea>\n ),\n);\nSheetBody.displayName = 'Sheet.Body';\n\nconst SheetFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={[\n 'ds:sticky ds:bottom-0 ds:z-10 ds:flex ds:flex-wrap ds:items-center ds:justify-end ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-lg)] ds:pe-[var(--spacing-lg)] ds:py-[var(--spacing-md)]',\n 'ds:border-t ds:border-[color:var(--border)] ds:bg-[var(--popover)]',\n 'ds:max-sm:flex-col ds:max-sm:[&>*]:w-full',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n ),\n);\nSheetFooter.displayName = 'Sheet.Footer';\n\nconst SheetTitle = forwardRef<\n HTMLHeadingElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Title>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Title\n ref={ref}\n className={['type-title-card ds:break-words', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nSheetTitle.displayName = 'Sheet.Title';\n\nconst SheetDescription = forwardRef<\n HTMLParagraphElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Description>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Description\n ref={ref}\n className={['type-body-sm ds:text-[var(--muted-foreground)]', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nSheetDescription.displayName = 'Sheet.Description';\n\nexport const Sheet = Object.assign(SheetRoot, {\n Root: SheetRoot,\n Trigger: SheetTrigger,\n Content: SheetContent,\n Header: SheetHeader,\n Body: SheetBody,\n Footer: SheetFooter,\n Title: SheetTitle,\n Description: SheetDescription,\n Close: SheetClose,\n});\n\nexport type SheetHeaderProps = HTMLAttributes<HTMLDivElement>;\nexport type SheetBodyProps = HTMLAttributes<HTMLDivElement>;\nexport type SheetFooterProps = HTMLAttributes<HTMLDivElement>;\n"],"names":["sheetAgent","handle","OVERLAY_CLASSES","contentVariants","cva","getSizeClass","side","size","SheetContext","createContext","SheetRoot","children","id","openProp","defaultOpen","onOpenChange","modal","props","isControlled","internalOpen","setInternalOpen","useState","open","openRef","useRef","useEffect","setOpen","useCallback","next","useMemo","useAgentRegistration","context","jsx","RadixDialog","SheetTrigger","forwardRef","ref","SheetClose","SheetContent","className","onKeyDown","instanceId","useContext","exitOnTab","useNonModalTabExit","jsxs","event","SheetHeader","t","useTranslation","IconButton","SheetBody","ScrollArea","SheetFooter","SheetTitle","SheetDescription","Sheet"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"warehouse-load-summary-DkAKXcw0.js","sources":["../../src/components/warehouse-load-summary/model.ts","../../src/components/warehouse-load-summary/warehouse-load-summary.agent.ts","../../src/components/warehouse-load-summary/warehouse-load-summary.tsx"],"sourcesContent":["import { WAREHOUSE_COUNT_KEYS } from '../_shared/warehouse-load';\nimport type {\n WarehouseCountKey,\n WarehouseLoadCounts,\n WarehouseLoadFailedFile,\n WarehouseLoadOutcome,\n WarehouseLoadScope,\n} from './types';\n\n/** Counts that hide at zero (nothing to report). */\nconst HIDE_AT_ZERO: ReadonlySet<WarehouseCountKey> = new Set([\n 'itemsUpdated',\n 'filesWithErrors',\n]);\n/** Counts a single-invoice summary leaves out. */\nconst BATCH_ONLY: ReadonlySet<WarehouseCountKey> = new Set([\n 'invoicesLoaded',\n 'filesWithErrors',\n]);\n\nfunction usable(value: number | undefined): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0;\n}\n\n/** The counts to show, in vocabulary order. */\nexport function visibleCounts(\n counts: WarehouseLoadCounts,\n scope: WarehouseLoadScope,\n): Array<{ key: WarehouseCountKey; count: number }> {\n const out: Array<{ key: WarehouseCountKey; count: number }> = [];\n for (const key of WAREHOUSE_COUNT_KEYS) {\n if (scope === 'invoice' && BATCH_ONLY.has(key)) continue;\n const value = counts[key];\n if (!usable(value)) continue;\n const count = Math.trunc(value);\n if (count === 0 && HIDE_AT_ZERO.has(key)) continue;\n out.push({ key, count });\n }\n return out;\n}\n\nexport function resolveOutcome(\n outcome: WarehouseLoadOutcome | undefined,\n counts: WarehouseLoadCounts,\n failedFiles: ReadonlyArray<WarehouseLoadFailedFile>,\n): WarehouseLoadOutcome {\n if (outcome) return outcome;\n const errors = counts.filesWithErrors ?? 0;\n const failed = errors > 0 || failedFiles.length > 0;\n const loaded =\n (usable(counts.invoicesLoaded) && counts.invoicesLoaded >= 1) ||\n (usable(counts.linesLoaded) && counts.linesLoaded >= 1);\n if (failed) return loaded ? 'partial' : 'error';\n return loaded ? 'success' : 'unchanged';\n}\n","/* -------------------------------------------------------------------- */\n/* Agent adapter: WarehouseLoadSummary. */\n/* Read-only display. State is counts and ids; no actions, because the */\n/* host's `actions` slot owns every button. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { WarehouseLoadSummaryHandle } from './types';\n\nexport const warehouseLoadSummaryAgent: AgentAdapter<WarehouseLoadSummaryHandle> =\n {\n id: 'warehouse-load-summary',\n capabilities: [],\n state: {\n counts: {\n type: 'Record<string, number>',\n description:\n 'The counts shown, by key (invoicesLoaded, itemsCreated, itemsUpdated, linesLoaded, linesAlreadyLoaded, linesSkipped, filesWithErrors). Hidden counts are absent.',\n read: (handle) => handle.getCounts(),\n },\n failedFileIds: {\n type: 'string[]',\n description:\n 'Ids of the failed files listed. File names and error texts are not read.',\n read: (handle) => handle.getFailedFileIds(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'warehouse-load-summary',\n description: 'Marks the summary root.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-file-id',\n description: 'Each failed file row emits its id as data-file-id.',\n },\n },\n };\n","import { useEffect, useId, useMemo, useRef, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent';\nimport { Alert } from '../alert';\nimport { Stat } from '../stat';\nimport { StatGroup } from '../stat-group';\nimport { warehouseCountLabel } from '../_shared/warehouse-load';\nimport { visibleCounts, resolveOutcome } from './model';\nimport { warehouseLoadSummaryAgent } from './warehouse-load-summary.agent';\nimport type {\n WarehouseCountKey,\n WarehouseLoadFailedFile,\n WarehouseLoadOutcome,\n WarehouseLoadSummaryHandle,\n WarehouseLoadSummaryProps,\n} from './types';\n\nconst ALERT_VARIANT = {\n success: 'success',\n partial: 'warning',\n error: 'error',\n unchanged: 'info',\n} as const satisfies Record<WarehouseLoadOutcome, string>;\n\nconst NO_FAILED_FILES: ReadonlyArray<WarehouseLoadFailedFile> = [];\n\nconst STAT_INTENT = {\n filesWithErrors: 'destructive',\n} as const satisfies Partial<Record<WarehouseCountKey, string>>;\n\n/**\n * What a warehouse load produced: a heading by outcome, one tile per count\n * and the files that failed. Displays only; the platform counts.\n */\nexport function WarehouseLoadSummary({\n counts,\n scope = 'batch',\n outcome,\n failedFiles = NO_FAILED_FILES,\n headingLevel = 2,\n focusOnMount = true,\n actions,\n variant = 'full',\n id,\n className,\n}: WarehouseLoadSummaryProps) {\n const { t, i18n } = useTranslation('ui');\n const language = i18n.language;\n const headingId = useId();\n const titleRef = useRef<HTMLHeadingElement>(null);\n\n // The summary replaces the review step, so focus would drop to <body>.\n // Focusing the heading makes screen readers read the result (WCAG 2.4.3,\n // 4.1.3); the Alert then stays silent so it is not read twice.\n useEffect(() => {\n if (focusOnMount) titleRef.current?.focus({ preventScroll: true });\n }, [focusOnMount]);\n\n const shown = useMemo(() => visibleCounts(counts, scope), [counts, scope]);\n const resolved = resolveOutcome(outcome, counts, failedFiles);\n\n const handle = useMemo<WarehouseLoadSummaryHandle>(\n () => ({\n getCounts: () => Object.fromEntries(shown.map((c) => [c.key, c.count])),\n getFailedFileIds: () => failedFiles.map((f) => f.id),\n }),\n [shown, failedFiles],\n );\n useAgentRegistration(warehouseLoadSummaryAgent, handle, id);\n\n const title = t(`warehouseLoadSummary.title.${scope}.${resolved}`, {\n defaultValue: DEFAULT_TITLES[scope][resolved],\n });\n const sentence = shown\n .filter((c) => c.count > 0)\n .map((c) => warehouseCountLabel(t, language, c.key, c.count));\n const description = formatList(sentence, language);\n\n if (variant === 'banner') {\n // One line above a table: heading, a neutral dot, the sentence, then the\n // host actions. No cards, no failed-files list. The dot is punctuation\n // that reads the same in every language, so no new string is needed.\n return (\n <div\n data-component=\"warehouse-load-summary\"\n data-component-id={id}\n data-outcome={resolved}\n data-variant=\"banner\"\n className={className}\n >\n <Alert\n variant={ALERT_VARIANT[resolved]}\n announce={focusOnMount ? 'off' : 'polite'}\n >\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-xs)] ds:gap-y-[var(--spacing-xs)]\">\n <Alert.Title\n ref={titleRef}\n tabIndex={-1}\n className=\"ds:outline-none\"\n as={`h${headingLevel}` as const}\n >\n {title}\n </Alert.Title>\n {description ? (\n <>\n <span aria-hidden=\"true\">·</span>\n <p className=\"type-body-sm ds:m-0\">{description}</p>\n </>\n ) : null}\n {actions ? (\n <div className=\"ds:ms-auto ds:flex ds:flex-wrap ds:justify-end ds:gap-[var(--spacing-sm)]\">\n {actions}\n </div>\n ) : null}\n </div>\n </Alert>\n </div>\n );\n }\n\n return (\n <div\n data-component=\"warehouse-load-summary\"\n data-component-id={id}\n data-outcome={resolved}\n className={['ds:flex ds:flex-col ds:gap-[var(--spacing-md)]', className]\n .filter(Boolean)\n .join(' ')}\n >\n <Alert\n variant={ALERT_VARIANT[resolved]}\n announce={focusOnMount ? 'off' : 'polite'}\n >\n <Alert.Title\n ref={titleRef}\n tabIndex={-1}\n className=\"ds:outline-none\"\n as={`h${headingLevel}` as const}\n >\n {title}\n </Alert.Title>\n {description ? (\n <Alert.Description>{description}</Alert.Description>\n ) : null}\n </Alert>\n\n {shown.length > 0 ? (\n <StatGroup\n aria-label={t('warehouseLoadSummary.counts', {\n defaultValue: 'Load counts',\n })}\n maxColumns={4}\n >\n {shown.map(({ key, count }) => (\n <Stat\n key={key}\n variant=\"outlined\"\n size=\"sm\"\n label={t(`warehouseLoadSummary.stat.${key}`, {\n defaultValue: DEFAULT_STAT_LABELS[key],\n })}\n value={count}\n locale={language}\n intent={\n count > 0 && key in STAT_INTENT\n ? STAT_INTENT[key as keyof typeof STAT_INTENT]\n : 'foreground'\n }\n />\n ))}\n </StatGroup>\n ) : null}\n\n {failedFiles.length > 0 ? (\n <div\n role=\"group\"\n aria-labelledby={headingId}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <SubHeading\n as={`h${Math.min(headingLevel + 1, 6)}` as 'h3'}\n id={headingId}\n >\n {t('warehouseLoadSummary.failedFiles', {\n defaultValue: 'Files that could not be loaded',\n })}\n </SubHeading>\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- Safari drops list semantics under list-none */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-0\"\n >\n {failedFiles.map((file) => (\n <li\n key={file.id}\n data-file-id={file.id}\n className=\"ds:flex ds:flex-col ds:break-words ds:border-s-[length:var(--border-width-md)] ds:border-s-[color:var(--destructive)] ds:ps-[var(--spacing-sm)]\"\n >\n <span\n dir=\"auto\"\n className=\"type-label ds:text-[var(--foreground)]\"\n >\n {file.fileName}\n </span>\n <span\n dir=\"auto\"\n className=\"type-meta ds:text-[var(--muted-foreground)]\"\n >\n {file.error}\n </span>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {actions ? (\n <div className=\"ds:flex ds:flex-wrap ds:justify-end ds:gap-[var(--spacing-sm)]\">\n {actions}\n </div>\n ) : null}\n </div>\n );\n}\n\nconst DEFAULT_TITLES = {\n invoice: {\n success: 'Invoice loaded',\n partial: 'Invoice loaded with warnings',\n error: 'The invoice could not be loaded',\n unchanged: 'Nothing new to load',\n },\n batch: {\n success: 'Invoices loaded',\n partial: 'Invoices loaded, some files failed',\n error: 'No invoices were loaded',\n unchanged: 'Nothing new to load',\n },\n} as const;\n\nconst DEFAULT_STAT_LABELS = {\n invoicesLoaded: 'Invoices loaded',\n itemsCreated: 'Items created',\n itemsUpdated: 'Items updated',\n linesLoaded: 'Lines loaded',\n linesAlreadyLoaded: 'Lines already loaded',\n linesSkipped: 'Lines skipped',\n filesWithErrors: 'Files with errors',\n} as const satisfies Record<WarehouseCountKey, string>;\n\nfunction formatList(parts: string[], language: string | undefined): string {\n if (parts.length === 0) return '';\n try {\n return new Intl.ListFormat(language, {\n style: 'long',\n type: 'conjunction',\n }).format(parts);\n } catch {\n return parts.join(', ');\n }\n}\n\nfunction SubHeading({\n as: Tag,\n id,\n children,\n}: {\n as: 'h3' | 'h4' | 'h5' | 'h6';\n id: string;\n children: ReactNode;\n}) {\n return (\n <Tag id={id} className=\"type-label ds:m-0 ds:text-[var(--foreground)]\">\n {children}\n </Tag>\n );\n}\n"],"names":["HIDE_AT_ZERO","BATCH_ONLY","usable","value","visibleCounts","counts","scope","out","key","WAREHOUSE_COUNT_KEYS","count","resolveOutcome","outcome","failedFiles","failed","loaded","warehouseLoadSummaryAgent","handle","ALERT_VARIANT","NO_FAILED_FILES","STAT_INTENT","WarehouseLoadSummary","headingLevel","focusOnMount","actions","variant","id","className","t","i18n","useTranslation","language","headingId","useId","titleRef","useRef","useEffect","_a","shown","useMemo","resolved","c","f","useAgentRegistration","title","DEFAULT_TITLES","sentence","warehouseCountLabel","description","formatList","jsx","Alert","jsxs","Fragment","StatGroup","Stat","DEFAULT_STAT_LABELS","SubHeading","file","parts","Tag","children"],"mappings":"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"}