@nextclaw/ui 0.26.4 → 0.27.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 (376) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/.vite/manifest.json +1271 -1227
  3. package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-DmeCRAkd.js} +1 -1
  4. package/dist/assets/account-panel-BYxGT4m4.js +1 -0
  5. package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.js → aiden0z-pptx-renderer.es-ChX5DHqP.js} +1 -1
  6. package/dist/assets/api-CG22BskB.js +20 -0
  7. package/dist/assets/app-presenter-provider-CJFjhVYI.js +28 -0
  8. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
  9. package/dist/assets/appearance-settings-page-BcXr0vHp.js +1 -0
  10. package/dist/assets/{arc-DBRedCax.js → arc-Cu6Ols44.js} +1 -1
  11. package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +1 -0
  12. package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-DrNB0eLE.js} +1 -1
  13. package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-08rHt6DJ.js} +1 -1
  14. package/dist/assets/{book-open-CmRdT3N1.js → book-open-ClbJmmxP.js} +1 -1
  15. package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CCVgRG-u.js} +1 -1
  16. package/dist/assets/{card-CdRBL1E0.js → card-BdC01NFF.js} +1 -1
  17. package/dist/assets/channel-BgpbPyEH.js +1 -0
  18. package/dist/assets/channels-list-page-BrIvJlop.js +8 -0
  19. package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +1 -0
  20. package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-BeCaI-JN.js} +1 -1
  21. package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-ZXIcYPYs.js} +1 -1
  22. package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-DDwTPcy8.js} +1 -1
  23. package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-WygrMYPL.js} +1 -1
  24. package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-o8T3KZgk.js} +1 -1
  25. package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BKFbUT7J.js} +1 -1
  26. package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DYxCRV86.js} +1 -1
  27. package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CvSeJlKZ.js} +1 -1
  28. package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-BhH3RHCY.js} +1 -1
  29. package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-BTL0-xL3.js} +1 -1
  30. package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DWAU4QaD.js} +1 -1
  31. package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-B7ZBMXTx.js} +1 -1
  32. package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D92HvnHE.js} +1 -1
  33. package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-DfOGKwW8.js} +1 -1
  34. package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-DUuJUrXJ.js} +2 -2
  35. package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-i3MDyUY5.js} +1 -1
  36. package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-F_pmNX6t.js} +1 -1
  37. package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DygOelrU.js} +1 -1
  38. package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-BpiZMeRl.js} +1 -1
  39. package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-CV10sB1I.js} +1 -1
  40. package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-Cf1WZNm0.js} +1 -1
  41. package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-DuSw54VR.js} +1 -1
  42. package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-_rt_XKSZ.js} +1 -1
  43. package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-BFPaAGNW.js} +1 -1
  44. package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-GE0v_E5y.js} +1 -1
  45. package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-BK_FpnlJ.js} +1 -1
  46. package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-CpYh6rGo.js} +1 -1
  47. package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-htnxL_Cl.js} +1 -1
  48. package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-wDbE4BZ7.js} +1 -1
  49. package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DDRSVFTB.js} +1 -1
  50. package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +1 -0
  51. package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-COdhHR1o.js} +1 -1
  52. package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-DPDGhyF6.js} +3 -3
  53. package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +1 -0
  54. package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-D8ir9Nx5.js} +1 -1
  55. package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BuNKD836.js} +1 -1
  56. package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DyHzq8jH.js} +1 -1
  57. package/dist/assets/{circle-dashed-HOgt3gIJ.js → circle-dashed-nDaMRmP-.js} +1 -1
  58. package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +1 -0
  59. package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +1 -0
  60. package/dist/assets/{client-DKKbdJ6Q.js → client-DlFB5dW5.js} +1 -1
  61. package/dist/assets/config-split-page-C06fU9OQ.js +1 -0
  62. package/dist/assets/confirm-dialog-DpcmlXhd.js +1 -0
  63. package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
  64. package/dist/assets/context-menu-DKIEaY7f.js +211 -0
  65. package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-B1I1_P6a.js} +1 -1
  66. package/dist/assets/{createLucideIcon-DE0sB9Nu.js → createLucideIcon-Lnt-4LMC.js} +1 -1
  67. package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +1 -0
  68. package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DcOnhnCo.js} +1 -1
  69. package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-hAX89lg3.js} +1 -1
  70. package/dist/assets/{dagre-CrgsRasE.js → dagre-nSYhf9yY.js} +1 -1
  71. package/dist/assets/{desktop-capabilities-page-B9-B9k1A.js → desktop-capabilities-page-DPORyZAu.js} +1 -1
  72. package/dist/assets/desktop-update-config-BMTeWZmn.js +1 -0
  73. package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-C1mRMD2k.js} +1 -1
  74. package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D2XBn5al.js} +1 -1
  75. package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-3LmRsmkC.js} +1 -1
  76. package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-CFWn-osC.js} +1 -1
  77. package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-BqNRbUvU.js} +1 -1
  78. package/dist/assets/dialog-BNXSPMX_.js +1 -0
  79. package/dist/assets/dist-Cuiqqp1O.js +41 -0
  80. package/dist/assets/doc-browser-CDEapjmj.js +1 -0
  81. package/dist/assets/{doc-browser-context-ClLgMbxd.js → doc-browser-context-0QDWYorh.js} +1 -1
  82. package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-CunAATyC.js} +1 -1
  83. package/dist/assets/{download-CKqS1Ksj.js → download-f_sPcoLZ.js} +1 -1
  84. package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-CYb8IwqD.js} +1 -1
  85. package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-H47mUoeK.js} +1 -1
  86. package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +1 -0
  87. package/dist/assets/extensions-B-0xQz3L.js +1 -0
  88. package/dist/assets/external-link-CbVlnlNy.js +1 -0
  89. package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +1 -0
  90. package/dist/assets/{form-actions-CCoxz33Q.js → form-actions-BoTqELHB.js} +1 -1
  91. package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-hSX45zfV.js} +1 -1
  92. package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +1 -0
  93. package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-Br0UW2qg.js} +1 -1
  94. package/dist/assets/{i18n-OGmF0Ws_.js → i18n-B0V5NkFj.js} +2 -2
  95. package/dist/assets/inbox-Bna8iUy0.js +1 -0
  96. package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +1 -0
  97. package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-DQmP_67w.js} +1 -1
  98. package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-BHAV2oes.js} +1 -1
  99. package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-CFHax4_d.js} +1 -1
  100. package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-B4ZA9rp5.js} +1 -1
  101. package/dist/assets/katex-BprZ-Wwb.js +1 -0
  102. package/dist/assets/{keyboard-shortcuts-settings-page-D8rosOVh.js → keyboard-shortcuts-settings-page-BluWKrSo.js} +1 -1
  103. package/dist/assets/{line-D_bHubTL.js → line-BboM0HLF.js} +1 -1
  104. package/dist/assets/{linear-ChlwuS5y.js → linear-4K_M1oYM.js} +1 -1
  105. package/dist/assets/login-page-BMHW0Hh0.js +1 -0
  106. package/dist/assets/{login-page-BT3GV3Sb.js → login-page-JNr5JCEw.js} +1 -1
  107. package/dist/assets/main-BCX_Untx.css +1 -0
  108. package/dist/assets/main-C5kbmGUV.js +2 -0
  109. package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +1 -0
  110. package/dist/assets/{map-oGHTsIu8.js → map-26GpO1wn.js} +1 -1
  111. package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +1 -0
  112. package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-BTJFnvRC.js} +2 -2
  113. package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-B7ufoXgq.js} +3 -3
  114. package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-BHyru6KE.js} +1 -1
  115. package/dist/assets/model-config-page-C-wbM6Fe.js +1 -0
  116. package/dist/assets/{navigation-link-DC-Pku0Y.js → navigation-link-DFLSVIut.js} +2 -2
  117. package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-BqFe2ePF.js} +1 -1
  118. package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +1 -0
  119. package/dist/assets/panel-app-CSQmm_7E.js +1 -0
  120. package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +1 -0
  121. package/dist/assets/panelStandalone-PuuMF65O.js +2 -0
  122. package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
  123. package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-PVTatU5j.js} +1 -1
  124. package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +1 -0
  125. package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-CGc-QCc7.js} +1 -1
  126. package/dist/assets/plus-CywSlIbG.js +1 -0
  127. package/dist/assets/privacy-settings-page-CPdEiouE.js +1 -0
  128. package/dist/assets/projects-D_cd_t4G.js +1 -0
  129. package/dist/assets/provider-models-XRArsply.js +1 -0
  130. package/dist/assets/provider-scoped-model-input-C8JI-hus.js +1 -0
  131. package/dist/assets/providers-config-page-fyMlVgvq.js +1 -0
  132. package/dist/assets/puzzle-Bk3ud1KI.js +1 -0
  133. package/dist/assets/pwa-Cx6Fnox4.js +1 -0
  134. package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-DGL36riv.js} +1 -1
  135. package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +1 -0
  136. package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +1 -0
  137. package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +1 -0
  138. package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +1 -0
  139. package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +1 -0
  140. package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-CyNwvhSb.js} +1 -1
  141. package/dist/assets/{refresh-cw-BG8VfcdA.js → refresh-cw-Ca2napNx.js} +1 -1
  142. package/dist/assets/remote-D5MBQNZE.js +1 -0
  143. package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-C31NMKJ0.js} +1 -1
  144. package/dist/assets/{rotate-cw-DPEegUU2.js → rotate-cw-DXg7sNUE.js} +1 -1
  145. package/dist/assets/runtime-config-page--ivCxBT4.js +1 -0
  146. package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-CwrQ_7PA.js} +1 -1
  147. package/dist/assets/{save-CPlctBjT.js → save-DNigywZ9.js} +1 -1
  148. package/dist/assets/search-U9C0oTQJ.js +1 -0
  149. package/dist/assets/search-config-page-Bdx_RR1q.js +1 -0
  150. package/dist/assets/secrets-config-page-CvMIcsfJ.js +3 -0
  151. package/dist/assets/security-config-CQmMqQ8v.js +1 -0
  152. package/dist/assets/select-DxwDeKUR.js +1 -0
  153. package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-EFD482_y.js} +1 -1
  154. package/dist/assets/service-apps-panel-CiYO1Be4.js +1 -0
  155. package/dist/assets/{settings-2-CrGx9_De.js → settings-2-BrBUdRoY.js} +1 -1
  156. package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-TDvULTE1.js} +1 -1
  157. package/dist/assets/{src-C8AUg09O.js → src-CI2AvEMj.js} +1 -1
  158. package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-JdPsIYHo.js} +1 -1
  159. package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +1 -0
  160. package/dist/assets/{status-dot-Cb8ewlUr.js → status-dot-BbGsrkIX.js} +1 -1
  161. package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BnxpKeK_.js} +2 -2
  162. package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +8 -0
  163. package/dist/assets/tag-chip-BDbxcf6P.js +1 -0
  164. package/dist/assets/theme-provider-D98XGa-c.js +1 -0
  165. package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-2IL22-uC.js} +1 -1
  166. package/dist/assets/trash-2-DwSkRfeB.js +1 -0
  167. package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +1 -0
  168. package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +1 -0
  169. package/dist/assets/{use-config-BM5jC65L.js → use-config-D3cNzk2k.js} +1 -1
  170. package/dist/assets/{use-desktop-capabilities-ezKJwKqg.js → use-desktop-capabilities-D7odgaTB.js} +1 -1
  171. package/dist/assets/use-viewport-layout-BANU5E1t.js +1 -0
  172. package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-Cjf6n5Va.js} +1 -1
  173. package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +1 -0
  174. package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-yv4qKbBO.js} +1 -1
  175. package/dist/assets/x-BqGj6_Vq.js +1 -0
  176. package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-Bmp8Ck8X.js} +1 -1
  177. package/dist/index.html +43 -106
  178. package/dist/panel-standalone.html +18 -12
  179. package/index.html +15 -66
  180. package/package.json +5 -5
  181. package/src/app/configs/__tests__/app-navigation.config.test.ts +4 -2
  182. package/src/app/configs/app-navigation.config.ts +7 -2
  183. package/src/app/styles/design-system.css +85 -1
  184. package/src/app/styles/island-theme.css +8 -6
  185. package/src/features/agents/components/agent-details-dialog.tsx +5 -3
  186. package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
  187. package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
  188. package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
  189. package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
  190. package/src/features/apps/components/app-document-access-section.tsx +17 -14
  191. package/src/features/apps/components/app-marketplace-catalog.tsx +66 -39
  192. package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
  193. package/src/features/apps/components/app-marketplace-detail.tsx +9 -6
  194. package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
  195. package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
  196. package/src/features/apps/components/app-package-card.tsx +224 -147
  197. package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
  198. package/src/features/apps/components/app-packages-panel.tsx +159 -144
  199. package/src/features/apps/components/apps-panel.tsx +40 -11
  200. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
  201. package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
  202. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
  203. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
  204. package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
  205. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -0
  206. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +33 -0
  207. package/src/features/chat/features/message/components/chat-message-list.container.tsx +0 -2
  208. package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +4 -6
  209. package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
  210. package/src/features/chat/features/message/utils/chat-message-process-summary.utils.ts +2 -10
  211. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +2 -0
  212. package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
  213. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +2 -1
  214. package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
  215. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
  216. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
  217. package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
  218. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
  219. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
  220. package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
  221. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
  222. package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
  223. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
  224. package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
  225. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
  226. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +5 -9
  227. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +6 -4
  228. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
  229. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +1 -1
  230. package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
  231. package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
  232. package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
  233. package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
  234. package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
  235. package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +7 -4
  236. package/src/features/cron/components/cron-job-row.tsx +5 -4
  237. package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
  238. package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
  239. package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
  240. package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
  241. package/src/features/inbox/managers/inbox.manager.ts +18 -4
  242. package/src/features/inbox/pages/inbox-page.test.ts +16 -5
  243. package/src/features/inbox/pages/inbox-page.tsx +37 -29
  244. package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
  245. package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
  246. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
  247. package/src/features/projects/components/work/project-work-items.tsx +1 -1
  248. package/src/features/projects/pages/project-home-page.tsx +4 -2
  249. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
  250. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
  251. package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
  252. package/src/features/right-panel-resources/components/page-resource-icon.tsx +15 -7
  253. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +1 -1
  254. package/src/features/right-panel-resources/index.ts +3 -0
  255. package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +5 -0
  256. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
  257. package/src/features/service-apps/components/service-action-row.tsx +4 -3
  258. package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
  259. package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
  260. package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
  261. package/src/features/settings/pages/providers-config-page.tsx +3 -2
  262. package/src/index.css +42 -8
  263. package/src/platforms/mobile/components/__tests__/mobile-app-shell.test.tsx +9 -0
  264. package/src/platforms/mobile/components/mobile-app-shell.tsx +4 -2
  265. package/src/platforms/mobile/components/mobile-topbar.tsx +2 -2
  266. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
  267. package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
  268. package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
  269. package/src/shared/components/ui/actions/action-feedback.ts +1 -8
  270. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  271. package/src/shared/components/ui/confirm-dialog.tsx +1 -2
  272. package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
  273. package/src/shared/components/ui/dialog.tsx +29 -7
  274. package/src/shared/components/ui/popover.tsx +14 -3
  275. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +5 -5
  276. package/src/shared/components/ui/tooltip.tsx +2 -1
  277. package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
  278. package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
  279. package/src/shared/components/workbench/workbench-surface.tsx +5 -2
  280. package/src/shared/lib/i18n/locales/en-US/chat.json +14 -9
  281. package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
  282. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
  283. package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
  284. package/src/shared/lib/i18n/locales/zh-CN/chat.json +14 -9
  285. package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
  286. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
  287. package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
  288. package/src/shared/lib/theme/index.test.ts +28 -1
  289. package/src/shared/lib/theme/index.ts +14 -3
  290. package/dist/assets/account-panel-DVi_jhkG.js +0 -1
  291. package/dist/assets/api-BZvNpFOS.js +0 -20
  292. package/dist/assets/app-presenter-provider-BcYL-VNe.js +0 -124
  293. package/dist/assets/appearance-settings-page-AZNBzLmT.js +0 -1
  294. package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
  295. package/dist/assets/channel-CpMstUPF.js +0 -1
  296. package/dist/assets/channels-list-page-eZN74FN3.js +0 -8
  297. package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
  298. package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
  299. package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
  300. package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
  301. package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
  302. package/dist/assets/config-split-page-BA3V6b3Q.js +0 -1
  303. package/dist/assets/confirm-dialog-8vqYZ0wy.js +0 -1
  304. package/dist/assets/context-menu-DHVVdHzN.js +0 -1
  305. package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
  306. package/dist/assets/desktop-update-config-Cfr3IRUe.js +0 -1
  307. package/dist/assets/dialog-BUfWO8hr.js +0 -5
  308. package/dist/assets/doc-browser-w8q1j0jL.js +0 -1
  309. package/dist/assets/es2015-BiB05Sav.js +0 -41
  310. package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
  311. package/dist/assets/extensions-vPD4dGqt.js +0 -1
  312. package/dist/assets/eye-bKzylu3p.js +0 -1
  313. package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
  314. package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
  315. package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
  316. package/dist/assets/katex-B4FQSo9k.js +0 -1
  317. package/dist/assets/loader-circle-Clq1Gtb1.js +0 -1
  318. package/dist/assets/login-page-DKId3By8.js +0 -1
  319. package/dist/assets/main-bEWCGDHr.js +0 -2
  320. package/dist/assets/main-i18n-catalog.config-Bpu5GcwF.js +0 -1
  321. package/dist/assets/main-kqMRTwOs.css +0 -1
  322. package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +0 -1
  323. package/dist/assets/model-config-page-D21a-BO0.js +0 -1
  324. package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
  325. package/dist/assets/panel-app-BYfQu_TS.js +0 -1
  326. package/dist/assets/panel-app-i18n-catalog.config-D44qmtfk.js +0 -1
  327. package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
  328. package/dist/assets/panelStandalone-CX8X2hjh.js +0 -2
  329. package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
  330. package/dist/assets/privacy-settings-page-e0LFHZJm.js +0 -1
  331. package/dist/assets/projects-Rki7Fmth.js +0 -1
  332. package/dist/assets/provider-models-DFQgF4hS.js +0 -1
  333. package/dist/assets/provider-scoped-model-input-DaONL0j_.js +0 -1
  334. package/dist/assets/providers-config-page-CEOhQlMe.js +0 -1
  335. package/dist/assets/puzzle-D_TiFXOv.js +0 -1
  336. package/dist/assets/pwa-C9ac_1dg.js +0 -1
  337. package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
  338. package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
  339. package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
  340. package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
  341. package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
  342. package/dist/assets/remote-DkSx5x4R.js +0 -1
  343. package/dist/assets/runtime-config-page-DDT1dVLt.js +0 -1
  344. package/dist/assets/search-config-page-CDwmd6eX.js +0 -1
  345. package/dist/assets/secrets-config-page-1OvgmwPv.js +0 -3
  346. package/dist/assets/security-config-Pv4CM-kw.js +0 -1
  347. package/dist/assets/select-Y9IEbx9x.js +0 -1
  348. package/dist/assets/service-apps-panel-DPrLeF3N.js +0 -1
  349. package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
  350. package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
  351. package/dist/assets/tag-chip-D-6aPuuh.js +0 -1
  352. package/dist/assets/theme-provider-BjF1Eowc.js +0 -1
  353. package/dist/assets/trash-2-DER2EJKK.js +0 -1
  354. package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
  355. package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
  356. package/dist/assets/use-viewport-layout-vmbQUNT6.js +0 -1
  357. package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
  358. package/dist/assets/x-DSz9cGhy.js +0 -1
  359. package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
  360. /package/dist/assets/{array-BV9OtnO8.js → array-DstOKG9P.js} +0 -0
  361. /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-0TA8nwgf.js} +0 -0
  362. /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-rfGCG6pM.js} +0 -0
  363. /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-BfGoD7-o.js} +0 -0
  364. /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-DdIcNEda.js} +0 -0
  365. /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-CzXix2iJ.js} +0 -0
  366. /package/dist/assets/{dist-BVCSkfWY.js → dist-D5dwMwKA.js} +0 -0
  367. /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-BKOe0eFe.js} +0 -0
  368. /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-CnSVTaot.js} +0 -0
  369. /package/dist/assets/{init-BF6GH5oe.js → init-OCFb3zgY.js} +0 -0
  370. /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-B2uhSxvV.js} +0 -0
  371. /package/dist/assets/{katex-CsAM73R9.js → katex-dBrYsE7B.js} +0 -0
  372. /package/dist/assets/{middleware-B--6mAUM.js → middleware-CAXxl-af.js} +0 -0
  373. /package/dist/assets/{path-C56XkznJ.js → path-T5eoIRSJ.js} +0 -0
  374. /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  375. /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-DmGXmZEB.js} +0 -0
  376. /package/dist/assets/{xlsx-sds5nUpL.js → xlsx-CoYacou7.js} +0 -0
@@ -12,12 +12,12 @@ describe('PwaShellThemeManager', () => {
12
12
  document.body.style.backgroundColor = '';
13
13
  });
14
14
 
15
- it('applies default work shell colors when no theme is selected', () => {
15
+ it('applies plain paper shell colors when no theme is selected', () => {
16
16
  pwaShellThemeManager.syncCurrentTheme();
17
17
 
18
18
  const meta = document.querySelector('meta[name="theme-color"]');
19
- expect(meta?.getAttribute('content')).toBe('#FFFFFF');
20
- expect(document.body.style.backgroundColor).toBe('rgb(255, 255, 255)');
19
+ expect(meta?.getAttribute('content')).toBe('#FAF8F4');
20
+ expect(document.body.style.backgroundColor).toBe('rgb(250, 248, 244)');
21
21
  });
22
22
 
23
23
  it('applies natural shell colors explicitly', () => {
@@ -2,10 +2,13 @@ import {
2
2
  DEFAULT_UI_THEME,
3
3
  getThemeAppearance,
4
4
  normalizeTheme,
5
+ resolveTheme,
5
6
  type UiTheme,
6
7
  } from '@/shared/lib/theme';
7
8
 
8
- const PWA_SHELL_THEME_COLORS: Record<UiTheme, string> = {
9
+ const PWA_SHELL_THEME_COLORS: Record<Exclude<UiTheme, 'default'>, string> = {
10
+ 'paper-ink': '#FAF8F4',
11
+ 'plain-paper': '#FAF8F4',
9
12
  natural: '#FAF9F7',
10
13
  work: '#FFFFFF',
11
14
  minimal: '#FFFFFF',
@@ -25,10 +28,12 @@ export class PwaShellThemeManager {
25
28
  return;
26
29
  }
27
30
 
28
- const themeColor = PWA_SHELL_THEME_COLORS[theme];
31
+ const themeColor = PWA_SHELL_THEME_COLORS[resolveTheme(theme)];
29
32
  this.updateThemeMeta(themeColor);
30
33
  this.updateSurfaceBackgrounds(themeColor);
31
- document.documentElement.style.colorScheme = getThemeAppearance(theme);
34
+ const appearance = getThemeAppearance(theme);
35
+ document.documentElement.style.colorScheme = appearance;
36
+ document.querySelector('meta[name="color-scheme"]')?.setAttribute('content', appearance);
32
37
  };
33
38
 
34
39
  syncCurrentTheme = () => {
@@ -44,9 +44,9 @@ describe("resource icon precedence", () => {
44
44
  );
45
45
  expect(view.container.textContent).toBe("✎");
46
46
  view.rerender(<PageResourceIcon uri="https://example.com" />);
47
- expect(view.container.querySelector(".lucide-globe")).not.toBeNull();
47
+ expect(view.container.childElementCount).toBe(0);
48
48
  view.rerender(<PageResourceIcon uri="nextclaw://unknown/item" />);
49
- expect(view.container.querySelector(".lucide-link2")).not.toBeNull();
49
+ expect(view.container.childElementCount).toBe(0);
50
50
  });
51
51
  it("uses Panel object identity for its installed icon and falls back to the application icon", () => {
52
52
  const view = render(<PageResourceIcon uri="nextclaw://objects/panel-app/source%3Anotes" />);
@@ -64,4 +64,15 @@ describe("resource icon precedence", () => {
64
64
  );
65
65
  expect(view.container.querySelector(".lucide-github")).not.toBeNull();
66
66
  });
67
+ it.each([
68
+ "/workspace/frontmatter-test.md",
69
+ "./frontmatter-test.md",
70
+ "frontmatter-test.md:12:3",
71
+ "file:///workspace/frontmatter-test.md#L12",
72
+ "nextclaw://workspace-file?path=%2Fworkspace%2Ffrontmatter-test.md",
73
+ ])("shows Markdown identity for %s", (uri) => {
74
+ const view = render(<PageResourceIcon uri={uri} />);
75
+ expect(view.container.querySelector('[data-file-type-icon="markdown"]')).not.toBeNull();
76
+ expect(view.container.querySelector('.lucide-link2')).toBeNull();
77
+ });
67
78
  });
@@ -22,7 +22,6 @@ import {
22
22
  Github,
23
23
  Globe,
24
24
  LayoutDashboard,
25
- Link2,
26
25
  MessageSquare,
27
26
  PanelsTopLeft,
28
27
  Plus,
@@ -44,7 +43,7 @@ const RESOURCE_ICONS = {
44
43
  app: AppWindow,
45
44
  docs: BookOpen,
46
45
  website: Globe,
47
- generic: Link2,
46
+ generic: null,
48
47
  page: PanelsTopLeft,
49
48
  overview: LayoutDashboard,
50
49
  "child-sessions": GitBranch,
@@ -94,7 +93,8 @@ function resourceTypeIcon(
94
93
  if (
95
94
  uri.startsWith("nextclaw://workspace-file") ||
96
95
  uri.startsWith("file:") ||
97
- uri.startsWith("nextclaw://file/")
96
+ uri.startsWith("nextclaw://file/") ||
97
+ (!/^[a-z][a-z0-9+.-]*:/i.test(uri.replace(/:\d+(?::\d+)?$/, "")) && /\.[a-z0-9]{1,16}(?::\d+(?::\d+)?)?(?:[?#]|$)/i.test(uri))
98
98
  )
99
99
  return "file";
100
100
  if (
@@ -104,7 +104,7 @@ function resourceTypeIcon(
104
104
  )
105
105
  return "app";
106
106
  if (uri.startsWith("nextclaw://docs")) return "docs";
107
- return /^https?:/.test(uri) ? "website" : "generic";
107
+ return "generic";
108
108
  }
109
109
 
110
110
  function appIcon(value?: string): DocBrowserDockIcon | undefined {
@@ -222,20 +222,28 @@ function ResourceIcon({
222
222
  {specific.value}
223
223
  </span>
224
224
  );
225
- let pathname = uri;
225
+ let pathname = uri.replace(/:\d+(?::\d+)?$/, "");
226
226
  try {
227
- pathname = new URL(uri).searchParams.get("path") ?? new URL(uri).pathname;
227
+ const url = new URL(pathname);
228
+ pathname = url.searchParams.get("path") ?? url.pathname;
228
229
  } catch {
229
230
  /* Local file link. */
230
231
  }
232
+ pathname = pathname.split(/[?#]/, 1)[0].replace(/:\d+(?::\d+)?$/, "");
233
+ try {
234
+ pathname = decodeURIComponent(pathname);
235
+ } catch {
236
+ /* Keep malformed percent escapes as literal file name characters. */
237
+ }
231
238
  if (
232
239
  resourceTypeIcon(uri, appId) === "file" &&
233
- /\.[a-z0-9]{1,8}(?:[?#]|$)/i.test(pathname)
240
+ /\.[a-z0-9]{1,16}$/i.test(pathname)
234
241
  )
235
242
  return <FileTypeIcon fileName={pathname} size="compact" />;
236
243
  const Icon =
237
244
  (specific?.type === "builtin" && BUILTIN_ICONS[specific.name]) ||
238
245
  RESOURCE_ICONS[resourceTypeIcon(uri, appId)];
246
+ if (!Icon) return null;
239
247
  return (
240
248
  <Icon
241
249
  aria-hidden="true"
@@ -198,7 +198,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
198
198
  historyPolicy: 'managed',
199
199
  kind: RIGHT_PANEL_APPS_TAB_KIND,
200
200
  resourceUri: url,
201
- title: url === RIGHT_PANEL_APPS_URL ? t('appsTitle') : t('serviceAppsTitle'),
201
+ title: t('appsTitle'),
202
202
  url,
203
203
  };
204
204
  },
@@ -1,4 +1,7 @@
1
1
  export {
2
+ createRightPanelAppsUrl,
3
+ getRightPanelAppsTabFromUrl,
4
+ type RightPanelAppsTab,
2
5
  createChatUiResourceReferenceFromTab,
3
6
  createPanelAppContentPath,
4
7
  createPanelAppResourceUri,
@@ -2,6 +2,11 @@ import { describe, expect, it } from 'vitest';
2
2
  import { RightPanelResourceRouteResolver } from '@/features/right-panel-resources';
3
3
 
4
4
  describe('RightPanelResourceRouteResolver', () => {
5
+ it('preserves the app marketplace through resource normalization', () => {
6
+ expect(new RightPanelResourceRouteResolver().resolve('nextclaw://apps?tab=marketplace')).toMatchObject({
7
+ kind: 'apps', dedupeKey: 'apps', url: 'nextclaw://apps?tab=marketplace', resourceUri: 'nextclaw://apps?tab=marketplace',
8
+ });
9
+ });
5
10
  it.each(['cron-job', 'inbox-delivery', 'skill', 'agent', 'project'])('resolves %s as an object, not an unsupported website', (type) => {
6
11
  const uri = 'nextclaw://objects/' + type + '/' + encodeURIComponent('workspace:项目/对象');
7
12
  expect(new RightPanelResourceRouteResolver().resolve(uri)).toMatchObject({ kind: 'system-object', url: uri, resourceUri: uri });
@@ -42,15 +42,16 @@ export function createChatUiResourceReferenceFromTab(
42
42
  });
43
43
  }
44
44
 
45
- export type RightPanelAppsTab = 'apps' | 'panel-apps' | 'service-apps';
45
+ export type RightPanelAppsTab = 'apps' | 'panel-apps' | 'service-apps' | 'marketplace';
46
46
 
47
47
  const DEFAULT_RIGHT_PANEL_APPS_TAB: RightPanelAppsTab = 'apps';
48
48
 
49
49
  function isRightPanelAppsTab(value: unknown): value is RightPanelAppsTab {
50
- return value === 'apps' || value === 'panel-apps' || value === 'service-apps';
50
+ return value === 'apps' || value === 'panel-apps' || value === 'service-apps' || value === 'marketplace';
51
51
  }
52
52
 
53
53
  export function createRightPanelAppsUrl(tab: RightPanelAppsTab = DEFAULT_RIGHT_PANEL_APPS_TAB): string {
54
+ if (tab === 'marketplace') return `${RIGHT_PANEL_APPS_URL}?tab=marketplace`;
54
55
  if (tab === 'panel-apps') return RIGHT_PANEL_PANEL_APPS_URL;
55
56
  if (tab === 'service-apps') return RIGHT_PANEL_SERVICE_APPS_URL;
56
57
  return RIGHT_PANEL_APPS_URL;
@@ -1,3 +1,4 @@
1
+ import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
1
2
  import { useState } from "react";
2
3
  import type {
3
4
  AgentProfileView,
@@ -73,7 +74,7 @@ export function ServiceActionRow({
73
74
  <ShieldPlus className="h-3.5 w-3.5" />
74
75
  </button>
75
76
  </PopoverTrigger>
76
- <PopoverContent align="end" className="w-56 rounded-xl p-1.5">
77
+ <PopoverContent align="end" variant="menu">
77
78
  <div className="px-2 py-1.5 text-[11px] font-medium text-muted-foreground">
78
79
  {t("serviceAppsGrantToAgent")}
79
80
  </div>
@@ -85,9 +86,9 @@ export function ServiceActionRow({
85
86
  onGrantAgent(action.id, agent.id);
86
87
  setAgentMenuOpen(false);
87
88
  }}
88
- className="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-left text-xs text-foreground transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
89
+ className={`${ACTION_MENU_ITEM_CLASS} text-foreground ${ACTION_FEEDBACK.item}`}
89
90
  >
90
- <Bot className="h-3.5 w-3.5 text-muted-foreground" />
91
+ <Bot className="h-4 w-4 shrink-0 text-muted-foreground" />
91
92
  <span className="min-w-0 truncate">
92
93
  {agent.displayName?.trim() || agent.id}
93
94
  </span>
@@ -51,11 +51,11 @@ export function ServiceAppDeleteDialog({
51
51
  onOpenChange={(nextOpen) => !deletePending && onOpenChange(nextOpen)}
52
52
  >
53
53
  <DialogContent
54
- className="max-w-md [&>:last-child]:hidden"
54
+ className="max-w-md"
55
55
  onEscapeKeyDown={(event) => deletePending && event.preventDefault()}
56
56
  onInteractOutside={(event) => deletePending && event.preventDefault()}
57
57
  >
58
- <DialogHeader>
58
+ <DialogHeader showClose={false}>
59
59
  <DialogTitle>{t("serviceAppsDeleteConfirmTitle")}</DialogTitle>
60
60
  <DialogDescription>
61
61
  {t("serviceAppsDeleteConfirmDescription")} {appTitle}
@@ -1,3 +1,4 @@
1
+ import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
1
2
  import { PageResourceActionItems } from "@/features/right-panel-resources";
2
3
  import { pageResourceFromSystemObject } from "@/features/right-panel-resources";
3
4
  import { useState } from "react";
@@ -380,15 +381,15 @@ function ServiceAppMenuItem({
380
381
  <button
381
382
  type="button"
382
383
  className={cn(
383
- "flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-50",
384
+ ACTION_MENU_ITEM_CLASS,
384
385
  destructive
385
- ? "text-destructive hover:bg-destructive/10"
386
- : "text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-accent-foreground",
386
+ ? ACTION_FEEDBACK.destructive
387
+ : `text-foreground ${ACTION_FEEDBACK.item}`,
387
388
  )}
388
389
  disabled={disabled}
389
390
  onClick={onClick}
390
391
  >
391
- <Icon className="h-4 w-4 shrink-0" />
392
+ <Icon className={cn("h-4 w-4 shrink-0", !destructive && "text-muted-foreground")} />
392
393
  <span>{label}</span>
393
394
  </button>
394
395
  );
@@ -101,7 +101,7 @@ export function ProviderModelSuggestionsPanel(props: ProviderModelSuggestionsPan
101
101
  />
102
102
  </div>
103
103
  ) : null}
104
- <div className='custom-scrollbar max-h-44 overflow-y-auto overscroll-contain'>
104
+ <div className='custom-scrollbar max-h-44 overflow-y-auto'>
105
105
  {visibleModels.map((modelName) => (
106
106
  <label
107
107
  key={modelName}
@@ -1,3 +1,4 @@
1
+ import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
1
2
  import { useMemo, useState } from 'react';
2
3
  import { KeyRound, MoreVertical, Plus, Search, Trash2 } from 'lucide-react';
3
4
  import {
@@ -307,10 +308,10 @@ export function ProvidersConfigPage() {
307
308
  <MoreVertical className='h-4 w-4' />
308
309
  </button>
309
310
  </PopoverTrigger>
310
- <PopoverContent className='w-40 p-1' align='end' onClick={(event) => event.stopPropagation()}>
311
+ <PopoverContent variant='menu' align='end' onClick={(event) => event.stopPropagation()}>
311
312
  <button
312
313
  type='button'
313
- className='flex w-full items-center gap-2 rounded-md px-2 py-2 text-sm text-red-600 hover:bg-destructive/10'
314
+ className={`${ACTION_MENU_ITEM_CLASS} ${ACTION_FEEDBACK.destructive}`}
314
315
  onClick={() => setProviderToDelete(provider.providerId)}
315
316
  >
316
317
  <Trash2 className='h-4 w-4' />
package/src/index.css CHANGED
@@ -93,27 +93,35 @@
93
93
  background: hsl(var(--gray-400) / 0.48);
94
94
  }
95
95
 
96
- .doc-browser-tab-scrollbar {
96
+ .compact-tab-scrollbar {
97
97
  scrollbar-width: thin;
98
- scrollbar-color: hsl(var(--gray-300) / 0.34) transparent;
98
+ scrollbar-color: var(--tab-scrollbar-thumb, hsl(var(--gray-300) / 0.34)) transparent;
99
99
  }
100
100
 
101
- .doc-browser-tab-scrollbar::-webkit-scrollbar {
101
+ /* Native thin scrollbars override pixel sizes and may expand on hover. */
102
+ @supports selector(::-webkit-scrollbar) {
103
+ .compact-tab-scrollbar {
104
+ scrollbar-width: auto;
105
+ scrollbar-color: auto;
106
+ }
107
+ }
108
+
109
+ .compact-tab-scrollbar::-webkit-scrollbar {
102
110
  width: 2px;
103
111
  height: 2px;
104
112
  }
105
113
 
106
- .doc-browser-tab-scrollbar::-webkit-scrollbar-track {
114
+ .compact-tab-scrollbar::-webkit-scrollbar-track {
107
115
  background: transparent;
108
116
  }
109
117
 
110
- .doc-browser-tab-scrollbar::-webkit-scrollbar-thumb {
111
- background: hsl(var(--gray-300) / 0.34);
118
+ .compact-tab-scrollbar::-webkit-scrollbar-thumb {
119
+ background: var(--tab-scrollbar-thumb, hsl(var(--gray-300) / 0.34));
112
120
  border-radius: 999px;
113
121
  }
114
122
 
115
- .doc-browser-tab-scrollbar::-webkit-scrollbar-thumb:hover {
116
- background: hsl(var(--gray-400) / 0.44);
123
+ .compact-tab-scrollbar::-webkit-scrollbar-thumb:hover {
124
+ background: var(--tab-scrollbar-thumb-hover, hsl(var(--gray-400) / 0.44));
117
125
  }
118
126
 
119
127
  /* ========================================
@@ -680,6 +688,32 @@
680
688
  --md-table-head-bg: rgba(191, 219, 254, 0.16);
681
689
  }
682
690
 
691
+ :root[data-theme="paper-ink"] .chat-markdown-user {
692
+ --md-text: hsl(var(--primary-foreground));
693
+ --md-muted: hsl(42 20% 80%);
694
+ --md-border: hsl(42 20% 80% / 0.24);
695
+ --md-link: hsl(45 42% 84%);
696
+ --md-inline-code-bg: hsl(45 20% 90% / 0.1);
697
+ --md-inline-code-color: hsl(var(--primary-foreground));
698
+ --md-blockquote-border: hsl(45 30% 80% / 0.5);
699
+ --md-blockquote-bg: hsl(45 20% 90% / 0.06);
700
+ --md-table-head-bg: hsl(45 20% 90% / 0.08);
701
+ }
702
+
703
+ :root[data-theme="plain-paper"] .chat-markdown-user,
704
+ :root[data-theme="plain-paper"] .chat-markdown-assistant,
705
+ :root[data-theme="paper-ink"] .chat-markdown-assistant {
706
+ --md-text: hsl(var(--foreground));
707
+ --md-muted: hsl(var(--gray-600));
708
+ --md-border: hsl(var(--border));
709
+ --md-link: hsl(var(--link-foreground));
710
+ --md-inline-code-bg: hsl(var(--gray-200) / 0.5);
711
+ --md-inline-code-color: hsl(var(--gray-800));
712
+ --md-blockquote-border: hsl(var(--brand-400) / 0.5);
713
+ --md-blockquote-bg: hsl(var(--brand-100) / 0.4);
714
+ --md-table-head-bg: hsl(var(--gray-200) / 0.4);
715
+ }
716
+
683
717
  :root[data-theme="work"] .chat-markdown-assistant {
684
718
  --md-link: #1f73c9;
685
719
  --md-border: rgba(0, 0, 0, 0.11);
@@ -31,6 +31,15 @@ function renderShell(pathname: string) {
31
31
  }
32
32
 
33
33
  describe("MobileAppShell", () => {
34
+ it("lets inbox details own their reading chrome and restores navigation on the list", () => {
35
+ const detail = renderShell("/inbox/report-1");
36
+ expect(screen.queryByTestId("mobile-bottom-nav")).toBeNull();
37
+ expect(screen.queryByTestId("mobile-topbar")).toBeNull();
38
+ detail.unmount();
39
+ renderShell("/inbox");
40
+ expect(screen.getByTestId("mobile-bottom-nav")).toBeTruthy();
41
+ expect(screen.getByTestId("mobile-topbar")).toBeTruthy();
42
+ });
34
43
  it("shows the bottom navigation on the chat list route", () => {
35
44
  const { shell } = renderShell("/chat");
36
45
 
@@ -1,6 +1,7 @@
1
1
  import { lazy, Suspense } from "react";
2
2
  import {
3
3
  isChatSessionDetailRoute,
4
+ isInboxDetailRoute,
4
5
  isMainWorkspaceRoute,
5
6
  } from "@/app/configs/app-navigation.config";
6
7
  import { MobileBottomNav } from "@/platforms/mobile/components/mobile-bottom-nav";
@@ -32,8 +33,9 @@ export function MobileAppShell({
32
33
  children,
33
34
  }: MobileAppShellProps) {
34
35
  const isMainRoute = isMainWorkspaceRoute(pathname);
35
- const showTopbar = pathname !== '/chat' && !isChatSessionDetailRoute(pathname);
36
- const showBottomNav = !isChatSessionDetailRoute(pathname);
36
+ const ownsDetailChrome = isChatSessionDetailRoute(pathname) || isInboxDetailRoute(pathname);
37
+ const showTopbar = pathname !== '/chat' && !ownsDetailChrome;
38
+ const showBottomNav = !ownsDetailChrome;
37
39
 
38
40
  return (
39
41
  <div className="flex h-[100svh] flex-col bg-background font-sans text-foreground supports-[height:100dvh]:h-[100dvh]">
@@ -6,8 +6,8 @@ import { IconActionButton } from "@/shared/components/ui/actions/icon-action-but
6
6
 
7
7
  export function MobileTopbar({ leadingInset }: { leadingInset?: string }) {
8
8
  const navigate = useNavigate();
9
- const { pathname } = useLocation();
10
- const routeMeta = resolveMobileRouteMeta(pathname, t);
9
+ const { pathname, state } = useLocation();
10
+ const routeMeta = resolveMobileRouteMeta(pathname, t, typeof state?.returnTo === 'string' ? state.returnTo : undefined);
11
11
 
12
12
  return (
13
13
  <header
@@ -112,7 +112,7 @@ export function DocBrowserTabStrip({
112
112
  <span className="truncate">{current?.title || t('docBrowserTabUntitled')}</span><ChevronDown className="h-4 w-4 shrink-0" />
113
113
  </button>
114
114
  </PopoverTrigger>
115
- <PopoverContent align="start" className="max-h-[70dvh] w-72 overflow-y-auto p-1">
115
+ <PopoverContent align="start" variant="menu" className="max-h-[70dvh]">
116
116
  <ContextMenuItems groups={mobileGroups} onClose={() => setMobileMenuOpen(false)} />
117
117
  {mobileToolbar}
118
118
  </PopoverContent>
@@ -126,7 +126,7 @@ export function DocBrowserTabStrip({
126
126
  tabs={compactTabs}
127
127
  actions={actions}
128
128
  className="flex h-10 min-w-0 flex-1 gap-1 border-0 bg-transparent px-0 select-none"
129
- scrollClassName="doc-browser-tab-scrollbar flex h-full max-md:h-11 max-md:basis-full items-center gap-0.5"
129
+ scrollClassName="flex h-full max-md:h-11 max-md:basis-full items-center gap-0.5"
130
130
  tabsClassName="items-center gap-0.5"
131
131
  actionsClassName="h-full max-md:h-11 max-md:w-full items-center gap-0.5"
132
132
  tabBaseClassName="inline-flex cursor-pointer items-center gap-0.5 h-7 max-md:min-h-11 px-2 rounded-md text-xs max-w-[220px] shrink-0 transition-colors"
@@ -1,4 +1,4 @@
1
- import { useMemo, useState } from 'react';
1
+ import { useMemo, useState, type ComponentProps } from 'react';
2
2
  import { Search } from 'lucide-react';
3
3
  import { useServerPathBrowse } from '@/shared/hooks/use-server-path-browse';
4
4
  import { useServerPathCreateDirectory } from '@/shared/hooks/use-server-path-create-directory';
@@ -25,6 +25,7 @@ type ServerPathPickerDialogProps = {
25
25
  defaultWorkspacePath?: string | null;
26
26
  isSaving: boolean;
27
27
  onOpenChange: (open: boolean) => void;
28
+ onCloseAutoFocus?: ComponentProps<typeof DialogContent>['onCloseAutoFocus'];
28
29
  onConfirm: (path: string) => Promise<void> | void;
29
30
  title: string;
30
31
  description?: string;
@@ -57,6 +58,7 @@ export function ServerPathPickerDialog({
57
58
  defaultWorkspacePath,
58
59
  isSaving,
59
60
  onOpenChange,
61
+ onCloseAutoFocus,
60
62
  onConfirm,
61
63
  title,
62
64
  description,
@@ -79,8 +81,8 @@ export function ServerPathPickerDialog({
79
81
  onOpenChange(nextOpen);
80
82
  }}
81
83
  >
82
- <DialogContent className="max-h-[92vh] overflow-hidden p-0 sm:h-[44rem] sm:max-w-5xl sm:grid-rows-[auto_minmax(0,1fr)]">
83
- <DialogHeader className="border-b border-border px-5 py-4 pr-12">
84
+ <DialogContent onCloseAutoFocus={onCloseAutoFocus} className="max-h-[92vh] overflow-hidden p-0 sm:h-[44rem] sm:max-w-5xl sm:grid-rows-[auto_minmax(0,1fr)]">
85
+ <DialogHeader className="border-b border-border px-5 py-4">
84
86
  <DialogTitle>{title}</DialogTitle>
85
87
  <DialogDescription className={description ? undefined : 'sr-only'}>
86
88
  {description ?? title}
@@ -1,12 +1,48 @@
1
1
  import { render, screen } from '@testing-library/react';
2
- import { describe, expect, it } from 'vitest';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { t } from '@/shared/lib/i18n';
3
5
  import {
4
6
  Dialog,
5
7
  DialogContent,
8
+ DialogHeader,
9
+ DialogDescription,
10
+ DialogTrigger,
6
11
  DialogTitle,
7
12
  } from '@/shared/components/ui/dialog';
8
13
 
9
14
  describe('Dialog', () => {
15
+ it('keeps header actions separate from closing and restores trigger focus', async () => {
16
+ const onAction = vi.fn();
17
+ const user = userEvent.setup();
18
+ render(<Dialog>
19
+ <DialogTrigger>Open report</DialogTrigger>
20
+ <DialogContent>
21
+ <DialogHeader actions={<button onClick={onAction}>Next report</button>}>
22
+ <DialogTitle>A long report title</DialogTitle>
23
+ <DialogDescription>Report summary</DialogDescription>
24
+ </DialogHeader>
25
+ </DialogContent>
26
+ </Dialog>);
27
+ await user.click(screen.getByRole('button', { name: 'Open report' }));
28
+ expect(screen.getAllByRole('button', { name: t('close') })).toHaveLength(1);
29
+ await user.click(screen.getByRole('button', { name: 'Next report' }));
30
+ expect(onAction).toHaveBeenCalledOnce();
31
+ expect(screen.getByRole('dialog')).toBeTruthy();
32
+ await user.click(screen.getByRole('button', { name: t('close') }));
33
+ expect(screen.queryByRole('dialog')).toBeNull();
34
+ expect(document.activeElement).toBe(screen.getByRole('button', { name: 'Open report' }));
35
+ });
36
+
37
+ it('supports explicit confirmation-only headers', () => {
38
+ render(<Dialog open><DialogContent><DialogHeader showClose={false}>
39
+ <DialogTitle>Confirm deletion</DialogTitle>
40
+ <DialogDescription>Choose an action below.</DialogDescription>
41
+ </DialogHeader></DialogContent></Dialog>);
42
+ expect(screen.queryByRole('button', { name: t('close') })).toBeNull();
43
+ expect(screen.getByRole('heading', { name: 'Confirm deletion' })).toBeTruthy();
44
+ });
45
+
10
46
  it('renders modal layers above floating panels', () => {
11
47
  render(
12
48
  <Dialog open>
@@ -1,8 +1 @@
1
- /** Neutral actions share one theme color across icon and menu surfaces. */
2
- export const ACTION_MENU_ITEM_CLASS = 'flex min-h-8 w-full items-center gap-2 rounded-lg px-2.5 py-1 text-left text-[13px] leading-5 font-medium outline-none transition-colors disabled:pointer-events-none disabled:opacity-45';
3
-
4
- export const ACTION_FEEDBACK = {
5
- icon: 'hover:before:bg-[var(--interaction-hover)] active:before:bg-[var(--interaction-hover)] disabled:hover:before:bg-transparent disabled:active:before:bg-transparent',
6
- item: 'hover:bg-[var(--interaction-hover)] focus-visible:bg-[var(--interaction-hover)] active:bg-[var(--interaction-hover)] disabled:hover:bg-transparent disabled:active:bg-transparent',
7
- destructive: 'text-destructive hover:bg-destructive/10 focus-visible:bg-destructive/10 disabled:hover:bg-transparent',
8
- } as const;
1
+ export { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@nextclaw/agent-chat-ui';
@@ -44,7 +44,7 @@ const IconActionButton = React.forwardRef<HTMLButtonElement, IconActionButtonPro
44
44
  size = 'md',
45
45
  tone = 'default',
46
46
  tooltip,
47
- tooltipSide = 'bottom',
47
+ tooltipSide,
48
48
  ...buttonProps
49
49
  },
50
50
  ref
@@ -48,14 +48,13 @@ export const ConfirmDialog = ({
48
48
  return (
49
49
  <Dialog open={open} onOpenChange={onOpenChange}>
50
50
  <DialogContent
51
- className="[&>:last-child]:hidden"
52
51
  onOpenAutoFocus={(event) => {
53
52
  event.preventDefault();
54
53
  confirmButtonRef.current?.focus();
55
54
  }}
56
55
  onCloseAutoFocus={(event) => event.preventDefault()}
57
56
  >
58
- <DialogHeader>
57
+ <DialogHeader showClose={false}>
59
58
  <DialogTitle>{title}</DialogTitle>
60
59
  {description ? <DialogDescription>{description}</DialogDescription> : null}
61
60
  </DialogHeader>
@@ -5,8 +5,8 @@ import { cn } from "@/shared/lib/utils";
5
5
  import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
6
6
  import type { ContextMenuGroup, ContextMenuItem } from "./context-menu";
7
7
 
8
- export const CONTEXT_MENU_SURFACE_CLASS =
9
- "w-max min-w-52 max-w-[min(18rem,calc(100vw-16px))] overflow-y-auto rounded-xl border border-border/40 bg-popover p-1 text-popover-foreground shadow-floating outline-none";
8
+ import { ACTION_MENU_SURFACE_CLASS as CONTEXT_MENU_SURFACE_CLASS } from '@nextclaw/agent-chat-ui';
9
+ export { CONTEXT_MENU_SURFACE_CLASS };
10
10
 
11
11
  function MenuItemContent({ item }: { item: ContextMenuItem }) {
12
12
  return <>
@@ -4,6 +4,8 @@ import { X } from "lucide-react"
4
4
 
5
5
  import { cn } from "@/shared/lib/utils"
6
6
  import { deferEscapeToNestedMenu } from './context-menu/context-menu';
7
+ import { IconActionButton } from './actions/icon-action-button';
8
+ import { t } from '@/shared/lib/i18n';
7
9
 
8
10
  const Dialog = DialogPrimitive.Root
9
11
 
@@ -49,10 +51,6 @@ const DialogContent = React.forwardRef<
49
51
  }}
50
52
  >
51
53
  {children}
52
- <DialogPrimitive.Close className="absolute right-1 top-1 flex h-11 w-11 items-center justify-center rounded-lg opacity-70 transition-all duration-fast hover:bg-[var(--interaction-hover)] hover:text-accent-foreground hover:opacity-100 focus:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:pointer-events-none sm:right-4 sm:top-4 sm:h-6 sm:w-6">
53
- <X className="h-4 w-4 text-muted-foreground" />
54
- <span className="sr-only">Close</span>
55
- </DialogPrimitive.Close>
56
54
  </DialogPrimitive.Content>
57
55
  </DialogPortal>
58
56
  ))
@@ -60,15 +58,39 @@ DialogContent.displayName = DialogPrimitive.Content.displayName
60
58
 
61
59
  const DialogHeader = ({
62
60
  className,
61
+ children,
62
+ actions,
63
+ showClose = true,
63
64
  ...props
64
- }: React.HTMLAttributes<HTMLDivElement>) => (
65
+ }: React.HTMLAttributes<HTMLDivElement> & {
66
+ actions?: React.ReactNode;
67
+ showClose?: boolean;
68
+ }) => (
65
69
  <div
70
+ data-slot="dialog-header"
66
71
  className={cn(
67
- "flex flex-col space-y-2 pr-7 text-left",
72
+ "grid shrink-0 grid-cols-[minmax(0,1fr)_auto] items-start gap-3 text-left",
68
73
  className
69
74
  )}
70
75
  {...props}
71
- />
76
+ >
77
+ <div className="min-w-0 space-y-2 break-words">{children}</div>
78
+ <div className="flex shrink-0 items-center gap-2" data-slot="dialog-header-controls">
79
+ {actions ? <div className="flex items-center gap-1" data-slot="dialog-header-actions">{actions}</div> : null}
80
+ {showClose ? (
81
+ <div className={cn("flex shrink-0", actions && "pl-2")}>
82
+ <DialogPrimitive.Close asChild>
83
+ <IconActionButton
84
+ size="sm"
85
+ label={t('close')}
86
+ icon={<X className="h-4 w-4" />}
87
+ className="max-md:h-11 max-md:w-11"
88
+ />
89
+ </DialogPrimitive.Close>
90
+ </div>
91
+ ) : null}
92
+ </div>
93
+ </div>
72
94
  )
73
95
  DialogHeader.displayName = "DialogHeader"
74
96