@nextclaw/ui 0.26.3 → 0.26.4
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.
- package/CHANGELOG.md +24 -0
- package/dist/.vite/manifest.json +329 -329
- package/dist/assets/{account-panel-DIdHjKG-.js → account-panel-DVi_jhkG.js} +1 -1
- package/dist/assets/{api-DkLJrSCd.js → api-BZvNpFOS.js} +1 -1
- package/dist/assets/app-presenter-provider-BcYL-VNe.js +124 -0
- package/dist/assets/{appearance-settings-page-DI8aDY2G.js → appearance-settings-page-AZNBzLmT.js} +1 -1
- package/dist/assets/{book-open-BPMkKSci.js → book-open-CmRdT3N1.js} +1 -1
- package/dist/assets/card-CdRBL1E0.js +1 -0
- package/dist/assets/{channels-list-page-CCIaTQu7.js → channels-list-page-eZN74FN3.js} +2 -2
- package/dist/assets/{circle-dashed-B48a0t6p.js → circle-dashed-HOgt3gIJ.js} +1 -1
- package/dist/assets/{client-imrVphQb.js → client-DKKbdJ6Q.js} +1 -1
- package/dist/assets/config-split-page-BA3V6b3Q.js +1 -0
- package/dist/assets/{confirm-dialog-10Qb3dpZ.js → confirm-dialog-8vqYZ0wy.js} +1 -1
- package/dist/assets/{context-menu-CRqH2SEk.js → context-menu-DHVVdHzN.js} +1 -1
- package/dist/assets/{createLucideIcon-B4xj2I2g.js → createLucideIcon-DE0sB9Nu.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-CFcT2g8-.js → desktop-capabilities-page-B9-B9k1A.js} +1 -1
- package/dist/assets/{desktop-update-config-CRJd_An1.js → desktop-update-config-Cfr3IRUe.js} +1 -1
- package/dist/assets/{dialog-BgL3vKJQ.js → dialog-BUfWO8hr.js} +1 -1
- package/dist/assets/{doc-browser-context-DH4aWvkS.js → doc-browser-context-ClLgMbxd.js} +1 -1
- package/dist/assets/doc-browser-w8q1j0jL.js +1 -0
- package/dist/assets/{download-Cr337h4W.js → download-CKqS1Ksj.js} +1 -1
- package/dist/assets/{es2015-D-CRf3_Z.js → es2015-BiB05Sav.js} +1 -1
- package/dist/assets/{extensions-CsmJPz7g.js → extensions-vPD4dGqt.js} +1 -1
- package/dist/assets/{eye-DrQRSAfJ.js → eye-bKzylu3p.js} +1 -1
- package/dist/assets/{form-actions-BEeWTGUZ.js → form-actions-CCoxz33Q.js} +1 -1
- package/dist/assets/{keyboard-shortcuts-settings-page-DQU56SrW.js → keyboard-shortcuts-settings-page-D8rosOVh.js} +1 -1
- package/dist/assets/loader-circle-Clq1Gtb1.js +1 -0
- package/dist/assets/{login-page-sgivRYG1.js → login-page-BT3GV3Sb.js} +1 -1
- package/dist/assets/login-page-DKId3By8.js +1 -0
- package/dist/assets/{main-B-oxUq-o.js → main-bEWCGDHr.js} +2 -2
- package/dist/assets/main-kqMRTwOs.css +1 -0
- package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +1 -0
- package/dist/assets/{model-config-page-CDQBhmVr.js → model-config-page-D21a-BO0.js} +1 -1
- package/dist/assets/{navigation-link-D3pzNHeA.js → navigation-link-DC-Pku0Y.js} +1 -1
- package/dist/assets/panelStandalone-BRg7B1EI.css +1 -0
- package/dist/assets/{panelStandalone-CGkYeMK5.js → panelStandalone-CX8X2hjh.js} +2 -2
- package/dist/assets/{privacy-settings-page-CjoAkoDt.js → privacy-settings-page-e0LFHZJm.js} +1 -1
- package/dist/assets/{projects-C7Zxpcoi.js → projects-Rki7Fmth.js} +1 -1
- package/dist/assets/provider-models-DFQgF4hS.js +1 -0
- package/dist/assets/provider-scoped-model-input-DaONL0j_.js +1 -0
- package/dist/assets/providers-config-page-CEOhQlMe.js +1 -0
- package/dist/assets/{puzzle--RLCeYML.js → puzzle-D_TiFXOv.js} +1 -1
- package/dist/assets/{pwa-DcizGowz.js → pwa-C9ac_1dg.js} +1 -1
- package/dist/assets/{refresh-cw-syCVj_nw.js → refresh-cw-BG8VfcdA.js} +1 -1
- package/dist/assets/remote-DkSx5x4R.js +1 -0
- package/dist/assets/{rotate-cw-BlH9El3x.js → rotate-cw-DPEegUU2.js} +1 -1
- package/dist/assets/{runtime-config-page-Cco9dS73.js → runtime-config-page-DDT1dVLt.js} +1 -1
- package/dist/assets/{save-BWynuRQ2.js → save-CPlctBjT.js} +1 -1
- package/dist/assets/{search-config-page-Cc74_SAU.js → search-config-page-CDwmd6eX.js} +1 -1
- package/dist/assets/{secrets-config-page-raYDzlFC.js → secrets-config-page-1OvgmwPv.js} +1 -1
- package/dist/assets/security-config-Pv4CM-kw.js +1 -0
- package/dist/assets/{select-6Uq4chZW.js → select-Y9IEbx9x.js} +1 -1
- package/dist/assets/service-apps-panel-DPrLeF3N.js +1 -0
- package/dist/assets/{settings-2-COvVf1XX.js → settings-2-CrGx9_De.js} +1 -1
- package/dist/assets/{status-dot-DZlxa5zW.js → status-dot-Cb8ewlUr.js} +1 -1
- package/dist/assets/{tag-chip-DXHtZ8AS.js → tag-chip-D-6aPuuh.js} +1 -1
- package/dist/assets/{theme-provider-C5PCDBPB.js → theme-provider-BjF1Eowc.js} +1 -1
- package/dist/assets/{trash-2-DazgBvmJ.js → trash-2-DER2EJKK.js} +1 -1
- package/dist/assets/{use-config-DRRGF9Zb.js → use-config-BM5jC65L.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-CdfOUjdE.js → use-desktop-capabilities-ezKJwKqg.js} +1 -1
- package/dist/assets/{use-viewport-layout-DdxVnCYc.js → use-viewport-layout-vmbQUNT6.js} +1 -1
- package/dist/assets/x-DSz9cGhy.js +1 -0
- package/dist/index.html +33 -33
- package/dist/panel-standalone.html +10 -10
- package/package.json +4 -4
- package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +2 -2
- package/src/app/components/layout/sidebar-rail.styles.ts +3 -3
- package/src/app/styles/charcoal-theme.css +0 -3
- package/src/app/styles/design-system.css +12 -6
- package/src/app/styles/island-theme.css +2 -15
- package/src/features/app-data/components/app-data-removal-choice.tsx +1 -1
- package/src/features/channels/pages/channels-list-page.tsx +1 -1
- package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +1 -1
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +28 -16
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +8 -2
- package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +6 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +22 -1
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +10 -14
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +38 -7
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +4 -4
- package/src/features/chat/components/layout/chat-sidebar.tsx +2 -2
- package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +1 -1
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +12 -1
- package/src/features/chat/features/message/components/chat-tool-call-stress-harness.tsx +32 -2
- package/src/features/chat/features/message/hooks/__tests__/use-chat-message-virtualizer.test.tsx +7 -5
- package/src/features/chat/features/message/hooks/use-chat-message-virtualizer.ts +7 -3
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +1 -1
- package/src/features/chat/features/session/components/chat-mobile-session-row.tsx +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-context-card.tsx +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +7 -5
- package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +45 -10
- package/src/features/chat/features/session/components/session-header/chat-session-more-actions-menu.tsx +3 -0
- package/src/features/chat/features/session/components/session-header/chat-session-switcher-groups.tsx +6 -6
- package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +5 -4
- package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +0 -1
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +1 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +2 -2
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +2 -2
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +1 -1
- package/src/features/chat/features/workspace/components/child-sessions/chat-session-child-sessions.tsx +2 -2
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +2 -2
- package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +3 -3
- package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +1 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +4 -3
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +2 -1
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +3 -3
- package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +2 -2
- package/src/features/chat/features/workspace/components/workspace-markdown-outline.tsx +1 -1
- package/src/features/cron/components/cron-config.tsx +2 -2
- package/src/features/cron/components/cron-job-detail-dialog.tsx +1 -1
- package/src/features/cron/components/cron-job-row.tsx +3 -3
- package/src/features/cron/components/cron-task-discovery.tsx +1 -1
- package/src/features/inbox/pages/inbox-page.tsx +1 -1
- package/src/features/marketplace/components/curated-shelves/marketplace-curated-shelves.tsx +2 -2
- package/src/features/marketplace/components/curated-shelves/marketplace-shelf-card.tsx +2 -2
- package/src/features/marketplace/components/marketplace-list-card.tsx +4 -4
- package/src/features/marketplace/components/marketplace-page.tsx +2 -2
- package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
- package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +3 -3
- package/src/features/panel-apps/components/panel-app-list-item.tsx +3 -3
- package/src/features/pwa/components/pwa-install-entry.tsx +1 -1
- package/src/features/right-panel-resources/components/__tests__/page-resource-sidebar-nav.test.tsx +9 -1
- package/src/features/right-panel-resources/components/page-resource-sidebar-nav.tsx +1 -1
- package/src/features/right-panel-resources/components/right-panel-resource-home-page.tsx +1 -1
- package/src/features/service-apps/components/service-action-row.tsx +3 -3
- package/src/features/service-apps/components/service-app-list-item.tsx +4 -4
- package/src/features/service-apps/components/service-apps-panel.tsx +1 -1
- package/src/features/settings/components/config/provider-model-list.tsx +5 -5
- package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +4 -4
- package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
- package/src/features/settings/pages/appearance-settings-page.tsx +2 -2
- package/src/features/settings/pages/providers-config-page.tsx +6 -6
- package/src/features/side-dock/components/side-dock.tsx +4 -4
- package/src/index.css +4 -0
- package/src/platforms/desktop/components/desktop-window-chrome.tsx +1 -1
- package/src/platforms/mobile/components/mobile-bottom-nav.tsx +3 -3
- package/src/shared/components/common/brand-header.tsx +1 -1
- package/src/shared/components/common/searchable-model-input.tsx +2 -2
- package/src/shared/components/config-split-page.tsx +3 -3
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
- package/src/shared/components/path-picker/server-path-picker-locations.tsx +1 -1
- package/src/shared/components/ui/button.tsx +2 -2
- package/src/shared/components/ui/card.tsx +1 -1
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +3 -3
- package/src/shared/components/ui/input.tsx +7 -3
- package/src/shared/components/ui/overlays/sheet.tsx +1 -1
- package/src/shared/components/ui/popover.tsx +1 -1
- package/src/shared/components/ui/select.tsx +2 -2
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +3 -3
- package/src/shared/components/ui/tabs.tsx +1 -1
- package/dist/assets/app-presenter-provider-Co8uKOyW.js +0 -124
- package/dist/assets/card-Bqu8zWLq.js +0 -1
- package/dist/assets/config-split-page-Bd-bGKsw.js +0 -1
- package/dist/assets/doc-browser-52t2_rSF.js +0 -1
- package/dist/assets/loader-circle-DbOQWT9C.js +0 -1
- package/dist/assets/login-page-DW1AZXqX.js +0 -1
- package/dist/assets/main-BpL6OjwM.css +0 -1
- package/dist/assets/mcp-marketplace-page-DSLRpJEB.js +0 -1
- package/dist/assets/panelStandalone-D-mhAGNa.css +0 -1
- package/dist/assets/provider-models-YW7rIeOD.js +0 -1
- package/dist/assets/provider-scoped-model-input-axJ-pTEu.js +0 -1
- package/dist/assets/providers-config-page-_QhBXQ4M.js +0 -1
- package/dist/assets/remote-BLQU7aY5.js +0 -1
- package/dist/assets/security-config-aE_jOwy-.js +0 -1
- package/dist/assets/service-apps-panel-jBWAa4qZ.js +0 -1
- package/dist/assets/x-CQIp_nJT.js +0 -1
package/dist/index.html
CHANGED
|
@@ -258,47 +258,47 @@
|
|
|
258
258
|
})();
|
|
259
259
|
</script>
|
|
260
260
|
<title>NextClaw</title>
|
|
261
|
-
<script type="module" crossorigin src="/assets/main-
|
|
261
|
+
<script type="module" crossorigin src="/assets/main-bEWCGDHr.js"></script>
|
|
262
262
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DF37yw5_.js">
|
|
263
263
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
|
|
264
264
|
<link rel="modulepreload" crossorigin href="/assets/i18n-OGmF0Ws_.js">
|
|
265
|
-
<link rel="modulepreload" crossorigin href="/assets/api-
|
|
266
|
-
<link rel="modulepreload" crossorigin href="/assets/client-
|
|
267
|
-
<link rel="modulepreload" crossorigin href="/assets/es2015-
|
|
268
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-
|
|
269
|
-
<link rel="modulepreload" crossorigin href="/assets/select-
|
|
270
|
-
<link rel="modulepreload" crossorigin href="/assets/context-menu-
|
|
271
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
272
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
265
|
+
<link rel="modulepreload" crossorigin href="/assets/api-BZvNpFOS.js">
|
|
266
|
+
<link rel="modulepreload" crossorigin href="/assets/client-DKKbdJ6Q.js">
|
|
267
|
+
<link rel="modulepreload" crossorigin href="/assets/es2015-BiB05Sav.js">
|
|
268
|
+
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-DE0sB9Nu.js">
|
|
269
|
+
<link rel="modulepreload" crossorigin href="/assets/select-Y9IEbx9x.js">
|
|
270
|
+
<link rel="modulepreload" crossorigin href="/assets/context-menu-DHVVdHzN.js">
|
|
271
|
+
<link rel="modulepreload" crossorigin href="/assets/x-DSz9cGhy.js">
|
|
272
|
+
<link rel="modulepreload" crossorigin href="/assets/dialog-BUfWO8hr.js">
|
|
273
273
|
<link rel="modulepreload" crossorigin href="/assets/katex-CsAM73R9.js">
|
|
274
|
-
<link rel="modulepreload" crossorigin href="/assets/puzzle
|
|
274
|
+
<link rel="modulepreload" crossorigin href="/assets/puzzle-D_TiFXOv.js">
|
|
275
275
|
<link rel="modulepreload" crossorigin href="/assets/middleware-B--6mAUM.js">
|
|
276
|
-
<link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-
|
|
277
|
-
<link rel="modulepreload" crossorigin href="/assets/book-open-
|
|
276
|
+
<link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-vmbQUNT6.js">
|
|
277
|
+
<link rel="modulepreload" crossorigin href="/assets/book-open-CmRdT3N1.js">
|
|
278
278
|
<link rel="modulepreload" crossorigin href="/assets/navigation-history-CzErJuPG.js">
|
|
279
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-provider-
|
|
280
|
-
<link rel="modulepreload" crossorigin href="/assets/confirm-dialog-
|
|
281
|
-
<link rel="modulepreload" crossorigin href="/assets/download-
|
|
279
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-provider-BjF1Eowc.js">
|
|
280
|
+
<link rel="modulepreload" crossorigin href="/assets/confirm-dialog-8vqYZ0wy.js">
|
|
281
|
+
<link rel="modulepreload" crossorigin href="/assets/download-CKqS1Ksj.js">
|
|
282
282
|
<link rel="modulepreload" crossorigin href="/assets/host-capabilities-DuIFVsvM.js">
|
|
283
|
-
<link rel="modulepreload" crossorigin href="/assets/navigation-link-
|
|
284
|
-
<link rel="modulepreload" crossorigin href="/assets/eye-
|
|
285
|
-
<link rel="modulepreload" crossorigin href="/assets/tag-chip-
|
|
286
|
-
<link rel="modulepreload" crossorigin href="/assets/loader-circle-
|
|
287
|
-
<link rel="modulepreload" crossorigin href="/assets/trash-2-
|
|
288
|
-
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-
|
|
289
|
-
<link rel="modulepreload" crossorigin href="/assets/use-desktop-capabilities-
|
|
290
|
-
<link rel="modulepreload" crossorigin href="/assets/status-dot-
|
|
291
|
-
<link rel="modulepreload" crossorigin href="/assets/doc-browser-context-
|
|
292
|
-
<link rel="modulepreload" crossorigin href="/assets/card-
|
|
293
|
-
<link rel="modulepreload" crossorigin href="/assets/provider-models-
|
|
294
|
-
<link rel="modulepreload" crossorigin href="/assets/use-config-
|
|
295
|
-
<link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-
|
|
296
|
-
<link rel="modulepreload" crossorigin href="/assets/provider-scoped-model-input-
|
|
297
|
-
<link rel="modulepreload" crossorigin href="/assets/settings-2-
|
|
298
|
-
<link rel="modulepreload" crossorigin href="/assets/pwa-
|
|
299
|
-
<link rel="modulepreload" crossorigin href="/assets/login-page-
|
|
283
|
+
<link rel="modulepreload" crossorigin href="/assets/navigation-link-DC-Pku0Y.js">
|
|
284
|
+
<link rel="modulepreload" crossorigin href="/assets/eye-bKzylu3p.js">
|
|
285
|
+
<link rel="modulepreload" crossorigin href="/assets/tag-chip-D-6aPuuh.js">
|
|
286
|
+
<link rel="modulepreload" crossorigin href="/assets/loader-circle-Clq1Gtb1.js">
|
|
287
|
+
<link rel="modulepreload" crossorigin href="/assets/trash-2-DER2EJKK.js">
|
|
288
|
+
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-BG8VfcdA.js">
|
|
289
|
+
<link rel="modulepreload" crossorigin href="/assets/use-desktop-capabilities-ezKJwKqg.js">
|
|
290
|
+
<link rel="modulepreload" crossorigin href="/assets/status-dot-Cb8ewlUr.js">
|
|
291
|
+
<link rel="modulepreload" crossorigin href="/assets/doc-browser-context-ClLgMbxd.js">
|
|
292
|
+
<link rel="modulepreload" crossorigin href="/assets/card-CdRBL1E0.js">
|
|
293
|
+
<link rel="modulepreload" crossorigin href="/assets/provider-models-DFQgF4hS.js">
|
|
294
|
+
<link rel="modulepreload" crossorigin href="/assets/use-config-BM5jC65L.js">
|
|
295
|
+
<link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-BcYL-VNe.js">
|
|
296
|
+
<link rel="modulepreload" crossorigin href="/assets/provider-scoped-model-input-DaONL0j_.js">
|
|
297
|
+
<link rel="modulepreload" crossorigin href="/assets/settings-2-CrGx9_De.js">
|
|
298
|
+
<link rel="modulepreload" crossorigin href="/assets/pwa-C9ac_1dg.js">
|
|
299
|
+
<link rel="modulepreload" crossorigin href="/assets/login-page-BT3GV3Sb.js">
|
|
300
300
|
<link rel="stylesheet" crossorigin href="/assets/app-presenter-provider-jNGlmBLe.css">
|
|
301
|
-
<link rel="stylesheet" crossorigin href="/assets/main-
|
|
301
|
+
<link rel="stylesheet" crossorigin href="/assets/main-kqMRTwOs.css">
|
|
302
302
|
</head>
|
|
303
303
|
|
|
304
304
|
<body>
|
|
@@ -5,20 +5,20 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="theme-color" content="#ffffff" />
|
|
7
7
|
<title>Panel App · NextClaw</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/panelStandalone-
|
|
8
|
+
<script type="module" crossorigin src="/assets/panelStandalone-CX8X2hjh.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DF37yw5_.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/i18n-OGmF0Ws_.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/api-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/client-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/es2015-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/context-menu-
|
|
17
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/api-BZvNpFOS.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/client-DKKbdJ6Q.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/es2015-BiB05Sav.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-DE0sB9Nu.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/context-menu-DHVVdHzN.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/x-DSz9cGhy.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/dialog-BUfWO8hr.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/navigation-history-CzErJuPG.js">
|
|
20
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-provider-
|
|
21
|
-
<link rel="stylesheet" crossorigin href="/assets/panelStandalone-
|
|
20
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-provider-BjF1Eowc.js">
|
|
21
|
+
<link rel="stylesheet" crossorigin href="/assets/panelStandalone-BRg7B1EI.css">
|
|
22
22
|
</head>
|
|
23
23
|
<body>
|
|
24
24
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/ui",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"zod": "^3.23.8",
|
|
36
36
|
"zustand": "^5.0.2",
|
|
37
37
|
"@nextclaw/agent-chat": "0.3.14",
|
|
38
|
-
"@nextclaw/client-sdk": "0.12.
|
|
38
|
+
"@nextclaw/client-sdk": "0.12.9",
|
|
39
39
|
"@nextclaw/ncp": "0.11.2",
|
|
40
|
-
"@nextclaw/agent-chat-ui": "0.
|
|
41
|
-
"@nextclaw/ncp-http-agent-client": "0.4.25",
|
|
40
|
+
"@nextclaw/agent-chat-ui": "0.11.0",
|
|
42
41
|
"@nextclaw/ncp-react": "0.5.30",
|
|
42
|
+
"@nextclaw/ncp-http-agent-client": "0.4.25",
|
|
43
43
|
"@nextclaw/ncp-toolkit": "0.6.27",
|
|
44
44
|
"@nextclaw/shared": "0.8.2"
|
|
45
45
|
},
|
|
@@ -107,7 +107,7 @@ describe("Sidebar", () => {
|
|
|
107
107
|
expect(backLink).toBeTruthy();
|
|
108
108
|
expect(header.className).not.toContain("bg-white");
|
|
109
109
|
expect(header.className).not.toContain("rounded-2xl");
|
|
110
|
-
expect(backLink.className).toContain("hover:bg-[
|
|
110
|
+
expect(backLink.className).toContain("hover:bg-[var(--sidebar-interaction-hover)]");
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
it("keeps the settings navigation in the expected product order", () => {
|
|
@@ -207,7 +207,7 @@ describe("Sidebar", () => {
|
|
|
207
207
|
expect(screen.queryByRole("combobox", { name: "Language" })).toBeNull();
|
|
208
208
|
expect(accountEntry.className).toContain("py-2");
|
|
209
209
|
expect(accountEntry.className).toContain("text-muted-foreground");
|
|
210
|
-
expect(accountEntry.className).toContain("hover:bg-[
|
|
210
|
+
expect(accountEntry.className).toContain("hover:bg-[var(--sidebar-interaction-hover)]");
|
|
211
211
|
expect(navigationList?.className).toContain("space-y-0.5");
|
|
212
212
|
expect(footer?.className).toContain("space-y-0.5");
|
|
213
213
|
expect(footer?.firstElementChild?.textContent).toContain("Help Docs");
|
|
@@ -10,13 +10,13 @@ export const SIDEBAR_RAIL_ITEM_GAP_CLASS = "gap-1";
|
|
|
10
10
|
// Use theme neutral tokens directly so legacy gray utility overrides cannot
|
|
11
11
|
// turn sidebar feedback into a content selection or accent surface.
|
|
12
12
|
export const SIDEBAR_ITEM_SURFACE_CLASS =
|
|
13
|
-
"rounded-xl text-muted-foreground transition-colors duration-base hover:bg-[
|
|
13
|
+
"rounded-xl text-muted-foreground transition-colors duration-base hover:bg-[var(--sidebar-interaction-hover)] hover:text-foreground focus-within:bg-[var(--sidebar-interaction-hover)] has-[[data-context-menu-open]]:bg-[var(--sidebar-interaction-hover)]";
|
|
14
14
|
|
|
15
15
|
export const SIDEBAR_ITEM_ACTIVE_SURFACE_CLASS =
|
|
16
|
-
"bg-[
|
|
16
|
+
"bg-[var(--sidebar-interaction-selection)] text-foreground hover:bg-[var(--sidebar-interaction-selection)] focus-within:bg-[var(--sidebar-interaction-selection)] has-[[data-context-menu-open]]:bg-[var(--sidebar-interaction-selection)]";
|
|
17
17
|
|
|
18
18
|
export const SIDEBAR_RAIL_SURFACE_CLASS =
|
|
19
|
-
`${SIDEBAR_ITEM_SURFACE_CLASS} active:bg-[
|
|
19
|
+
`${SIDEBAR_ITEM_SURFACE_CLASS} active:bg-[var(--sidebar-interaction-selection)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border`;
|
|
20
20
|
|
|
21
21
|
export const SIDEBAR_RAIL_ACTIVE_SURFACE_CLASS = SIDEBAR_ITEM_ACTIVE_SURFACE_CLASS;
|
|
22
22
|
|
|
@@ -42,9 +42,6 @@
|
|
|
42
42
|
--secondary-foreground: var(--gray-800);
|
|
43
43
|
--accent: 0 0% 19%;
|
|
44
44
|
--accent-foreground: var(--gray-900);
|
|
45
|
-
--interaction-hover: hsl(var(--muted));
|
|
46
|
-
--interaction-selection: hsl(202 38% 27%);
|
|
47
|
-
--interaction-selection-border: hsl(202 48% 40%);
|
|
48
45
|
--muted: var(--gray-100);
|
|
49
46
|
--muted-foreground: var(--gray-500);
|
|
50
47
|
--destructive: 0 72% 60%;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
:root {
|
|
15
|
+
--shadow-popover: 0 12px 36px -8px rgb(0 0 0 / 0.18), 0 3px 10px -2px rgb(0 0 0 / 0.08);
|
|
15
16
|
color-scheme: light;
|
|
16
17
|
|
|
17
18
|
/* Mobile density: hit target, visual feedback, and chrome are separate. */
|
|
@@ -86,9 +87,16 @@
|
|
|
86
87
|
/* Accent */
|
|
87
88
|
--accent: var(--brand-50);
|
|
88
89
|
--accent-foreground: var(--brand-700);
|
|
89
|
-
--interaction-hover: hsl(var(--
|
|
90
|
-
--interaction-selection: hsl(
|
|
91
|
-
--interaction-selection-border: hsl(
|
|
90
|
+
--interaction-hover: hsl(var(--foreground) / 0.04);
|
|
91
|
+
--interaction-selection: hsl(var(--foreground) / 0.07);
|
|
92
|
+
--interaction-selection-border: hsl(var(--foreground) / 0.12);
|
|
93
|
+
/* Desktop sidebar feedback matches the verified VPS v0.54.2 baseline. */
|
|
94
|
+
--sidebar-interaction-hover: hsl(var(--gray-200) / 0.6);
|
|
95
|
+
--sidebar-interaction-selection: hsl(var(--gray-200) / 0.8);
|
|
96
|
+
--sidebar-segment-selection: hsl(var(--gray-200) / 0.7);
|
|
97
|
+
/* Mobile conversation rows retain their separate paper surface. */
|
|
98
|
+
--session-interaction-hover: hsl(var(--background) / 0.65);
|
|
99
|
+
--session-interaction-selection: hsl(var(--background) / 0.9);
|
|
92
100
|
|
|
93
101
|
/* Muted */
|
|
94
102
|
--muted: var(--gray-100);
|
|
@@ -723,9 +731,6 @@
|
|
|
723
731
|
--secondary-foreground: var(--gray-800);
|
|
724
732
|
--accent: 151 32% 18%;
|
|
725
733
|
--accent-foreground: 148 34% 84%;
|
|
726
|
-
--interaction-hover: hsl(var(--muted));
|
|
727
|
-
--interaction-selection: hsl(211 48% 30%);
|
|
728
|
-
--interaction-selection-border: hsl(211 48% 42%);
|
|
729
734
|
--muted: var(--gray-100);
|
|
730
735
|
--muted-foreground: var(--gray-500);
|
|
731
736
|
--destructive: 0 70% 52%;
|
|
@@ -834,6 +839,7 @@
|
|
|
834
839
|
|
|
835
840
|
@layer base {
|
|
836
841
|
:root[data-theme-appearance="dark"] {
|
|
842
|
+
--shadow-popover: 0 8px 32px -8px rgb(0 0 0 / 0.4), 0 2px 8px -2px rgb(0 0 0 / 0.24);
|
|
837
843
|
--link-foreground: 213 94% 68%;
|
|
838
844
|
--link-foreground-hover: 213 97% 79%;
|
|
839
845
|
}
|
|
@@ -44,9 +44,6 @@
|
|
|
44
44
|
--secondary-foreground: var(--gray-800);
|
|
45
45
|
--accent: 151 28% 88%;
|
|
46
46
|
--accent-foreground: var(--brand-800);
|
|
47
|
-
--interaction-hover: hsl(var(--muted));
|
|
48
|
-
--interaction-selection: hsl(153 35% 80% / 0.82);
|
|
49
|
-
--interaction-selection-border: hsl(157 37% 58% / 0.88);
|
|
50
47
|
--muted: var(--gray-100);
|
|
51
48
|
--muted-foreground: var(--gray-500);
|
|
52
49
|
--destructive: 5 61% 47%;
|
|
@@ -323,8 +320,8 @@
|
|
|
323
320
|
-webkit-backdrop-filter: blur(18px) saturate(0.9);
|
|
324
321
|
backdrop-filter: blur(18px) saturate(0.9);
|
|
325
322
|
background-color: hsl(var(--popover) / 0.9);
|
|
326
|
-
border-color: hsl(var(--border) / 0.
|
|
327
|
-
box-shadow:
|
|
323
|
+
border-color: hsl(var(--border) / 0.4);
|
|
324
|
+
box-shadow: var(--shadow-popover);
|
|
328
325
|
}
|
|
329
326
|
|
|
330
327
|
:root[data-theme="island"] [data-theme-overlay="tooltip"] {
|
|
@@ -446,16 +443,6 @@
|
|
|
446
443
|
border-radius: 0;
|
|
447
444
|
}
|
|
448
445
|
|
|
449
|
-
:root[data-theme="island"]
|
|
450
|
-
[data-theme-surface="navigation"]
|
|
451
|
-
:is([aria-current="page"], [aria-selected="true"], [data-state="active"]),
|
|
452
|
-
:root[data-theme="island"]
|
|
453
|
-
[data-theme-surface="utility-rail"]
|
|
454
|
-
:is([aria-pressed="true"], [data-state="active"]) {
|
|
455
|
-
background-color: hsl(151 27% 84% / 0.68);
|
|
456
|
-
color: hsl(var(--brand-800));
|
|
457
|
-
}
|
|
458
|
-
|
|
459
446
|
:root[data-theme="island"]
|
|
460
447
|
:is(
|
|
461
448
|
.custom-scrollbar,
|
|
@@ -25,7 +25,7 @@ export function AppDataRemovalChoice({
|
|
|
25
25
|
onClick={onClick}
|
|
26
26
|
className={cn(
|
|
27
27
|
'flex items-start gap-3 rounded-xl border px-3 py-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-50',
|
|
28
|
-
checked ? 'border-
|
|
28
|
+
checked ? 'border-[var(--interaction-selection-border)] bg-[var(--interaction-selection)]' : 'border-border/60 hover:bg-[var(--interaction-hover)]',
|
|
29
29
|
)}
|
|
30
30
|
>
|
|
31
31
|
<span className={cn(
|
|
@@ -138,7 +138,7 @@ export function ChannelsList() {
|
|
|
138
138
|
<a
|
|
139
139
|
href={tutorialUrl}
|
|
140
140
|
onClick={(event) => event.stopPropagation()}
|
|
141
|
-
className='inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground/45 transition-colors hover:bg-
|
|
141
|
+
className='inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground/45 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground'
|
|
142
142
|
title={t('channelsGuideTitle')}
|
|
143
143
|
>
|
|
144
144
|
<ExternalLink className='h-3.5 w-3.5' />
|
|
@@ -14,7 +14,7 @@ export function ChatSidebarListModeSwitch({ isProjectFirstView, onSelectMode }:
|
|
|
14
14
|
<span
|
|
15
15
|
aria-hidden="true"
|
|
16
16
|
className={cn(
|
|
17
|
-
'pointer-events-none absolute bottom-0.5 left-0.5 top-0.5 w-[calc(50%-2px)] rounded-full bg-
|
|
17
|
+
'pointer-events-none absolute bottom-0.5 left-0.5 top-0.5 w-[calc(50%-2px)] rounded-full bg-[var(--sidebar-segment-selection)] transition-transform duration-200 ease-out motion-reduce:transition-none',
|
|
18
18
|
isProjectFirstView && 'translate-x-full',
|
|
19
19
|
)}
|
|
20
20
|
/>
|
|
@@ -8,6 +8,7 @@ import { useChatQueryStore } from "@/features/chat/stores/ncp-chat-query.store";
|
|
|
8
8
|
import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
|
|
9
9
|
import { useChatThreadStore } from "@/features/chat/stores/chat-thread.store";
|
|
10
10
|
import { viewportLayoutManager } from "@/app/managers/viewport-layout.manager";
|
|
11
|
+
import { ChatSessionSwitcherGroups } from "@/features/chat/features/session/components/session-header/chat-session-switcher-groups";
|
|
11
12
|
import type { NcpSessionListItemView } from "@/features/chat/features/ncp/hooks/use-ncp-session-list-view";
|
|
12
13
|
import type { NcpSessionSummaryView, SessionEntryView } from "@/shared/lib/api";
|
|
13
14
|
|
|
@@ -312,42 +313,51 @@ describe("ChatConversationHeaderSection", () => {
|
|
|
312
313
|
).toBeTruthy();
|
|
313
314
|
});
|
|
314
315
|
|
|
315
|
-
it("
|
|
316
|
+
it("renders compact collapsible project groups inside the header popover", async () => {
|
|
316
317
|
const user = userEvent.setup();
|
|
317
|
-
|
|
318
|
-
mocks.sessionItems = [
|
|
319
|
-
createSessionListItem({
|
|
318
|
+
const alphaItem = createSessionListItem({
|
|
320
319
|
key: "parent-session-1",
|
|
321
320
|
label: "Parent Task",
|
|
322
321
|
projectName: "Alpha",
|
|
323
322
|
projectRoot: "/workspace/alpha",
|
|
324
|
-
})
|
|
325
|
-
|
|
323
|
+
});
|
|
324
|
+
const betaItem = createSessionListItem({
|
|
326
325
|
key: "session:ncp-2",
|
|
327
326
|
label: "Background Task",
|
|
328
327
|
projectName: "Beta",
|
|
329
328
|
projectRoot: "/workspace/beta",
|
|
330
|
-
})
|
|
331
|
-
];
|
|
329
|
+
});
|
|
332
330
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
331
|
+
render(
|
|
332
|
+
<ChatSessionSwitcherGroups
|
|
333
|
+
collapsedProjectRoots={[]}
|
|
334
|
+
dateGroups={[]}
|
|
335
|
+
isProjectFirstView
|
|
336
|
+
onSelect={mocks.selectSession}
|
|
337
|
+
onToggleProjectCollapsed={mocks.toggleProjectCollapsed}
|
|
338
|
+
optimisticReadAtBySessionKey={{}}
|
|
339
|
+
projectGroups={[
|
|
340
|
+
{ projectRoot: "/workspace/alpha", projectName: "Alpha", items: [alphaItem], latestUpdatedAt: 1, isPinned: false },
|
|
341
|
+
{ projectRoot: "/workspace/beta", projectName: "Beta", items: [betaItem], latestUpdatedAt: 1, isPinned: false },
|
|
342
|
+
]}
|
|
343
|
+
selectedSessionKey="parent-session-1"
|
|
344
|
+
sessionTypeOptions={[]}
|
|
345
|
+
/>,
|
|
346
|
+
);
|
|
336
347
|
|
|
337
|
-
|
|
338
|
-
const alphaGroup = screen.getByRole("region", { name: "Alpha" });
|
|
348
|
+
const alphaGroup = await screen.findByRole("region", { name: "Alpha" });
|
|
339
349
|
const alphaToggle = within(alphaGroup).getByRole("button", {
|
|
340
350
|
name: "Collapse project · Alpha",
|
|
341
351
|
});
|
|
342
352
|
expect(alphaToggle.getAttribute("aria-expanded")).toBe("true");
|
|
353
|
+
expect(alphaToggle.className).toContain("h-8");
|
|
343
354
|
expect(alphaToggle.className).not.toContain("bg-muted");
|
|
355
|
+
expect(alphaToggle.querySelector('[title="/workspace/alpha"]')?.getAttribute("class")).toContain("text-[13px]");
|
|
356
|
+
expect(alphaGroup.parentElement?.className).toContain("space-y-0.5");
|
|
344
357
|
expect(within(alphaGroup).getByText("Parent Task")).toBeTruthy();
|
|
345
358
|
|
|
346
359
|
await user.click(alphaToggle);
|
|
347
360
|
expect(mocks.toggleProjectCollapsed).toHaveBeenCalledWith("/workspace/alpha");
|
|
348
|
-
expect(
|
|
349
|
-
within(screen.getByRole("region", { name: "Alpha" })).queryByText("Parent Task"),
|
|
350
|
-
).toBeNull();
|
|
351
361
|
});
|
|
352
362
|
|
|
353
363
|
it("keeps the desktop title plain while the sidebar is expanded", () => {
|
|
@@ -447,6 +457,8 @@ describe("ChatConversationHeaderSection", () => {
|
|
|
447
457
|
const searchInput = screen.getByRole("textbox", {
|
|
448
458
|
name: "Search session key / label",
|
|
449
459
|
});
|
|
460
|
+
expect(searchInput.className).toContain("max-md:text-[13px]");
|
|
461
|
+
expect(searchInput.className).toContain("max-md:min-h-0");
|
|
450
462
|
await user.type(searchInput, "Background");
|
|
451
463
|
await user.click(screen.getByRole("button", { name: /Background Task/ }));
|
|
452
464
|
|
|
@@ -95,6 +95,9 @@ export function ChatConversationContent({
|
|
|
95
95
|
}: ChatConversationContentProps) {
|
|
96
96
|
const threadRef = useRef<HTMLDivElement>(null);
|
|
97
97
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
98
|
+
const turnAnchorRef = useRef<HTMLDivElement>(null);
|
|
99
|
+
const turnFrameRef = useRef<HTMLDivElement>(null);
|
|
100
|
+
const latestUserMessageId = messages.findLast((message) => message.role === "user")?.id ?? null;
|
|
98
101
|
const hasConversationContent = messages.length > 0 || isSending;
|
|
99
102
|
const readingKey = createConversationScrollRestorationKey(sessionKey, showWelcome);
|
|
100
103
|
const initialReadingPosition = useMemo(() => readingKey ? scrollRestorationManager.read(readingKey) : null, [readingKey]);
|
|
@@ -112,6 +115,8 @@ export function ChatConversationContent({
|
|
|
112
115
|
isLoading: isHistoryLoading,
|
|
113
116
|
hasContent: hasConversationContent,
|
|
114
117
|
contentVersion: messages[messages.length - 1] ?? isSending,
|
|
118
|
+
stickyThresholdPx: 80,
|
|
119
|
+
turnSpace: { key: latestUserMessageId, anchorRef: turnAnchorRef, frameRef: turnFrameRef },
|
|
115
120
|
});
|
|
116
121
|
const hasMessages = messages.length > 0;
|
|
117
122
|
const handleScroll = useCallback(
|
|
@@ -148,7 +153,7 @@ export function ChatConversationContent({
|
|
|
148
153
|
{showWelcome ? (
|
|
149
154
|
(welcomeSlot ?? null)
|
|
150
155
|
) : (
|
|
151
|
-
<div ref={contentRef} className="pb-7">
|
|
156
|
+
<div ref={turnFrameRef}><div ref={contentRef} className="pb-7">
|
|
152
157
|
{hasConversationContent ? (
|
|
153
158
|
<ChatConversationTrack className="relative py-4 sm:py-5">
|
|
154
159
|
<ConversationHistoryStatus historyError={historyError} isLoadingPreviousMessages={isLoadingPreviousMessages} onLoadPreviousMessages={onLoadPreviousMessages} />
|
|
@@ -163,6 +168,7 @@ export function ChatConversationContent({
|
|
|
163
168
|
onLoadMessageDetails={onLoadMessageDetails}
|
|
164
169
|
scrollRef={threadRef}
|
|
165
170
|
sessionKey={sessionKey}
|
|
171
|
+
turnAnchorRef={turnAnchorRef}
|
|
166
172
|
/>
|
|
167
173
|
{isContextCompacting ? <ChatContextCompactionDivider /> : null}
|
|
168
174
|
</ChatConversationTrack>
|
|
@@ -172,7 +178,7 @@ export function ChatConversationContent({
|
|
|
172
178
|
{bottomSlot}
|
|
173
179
|
</ChatConversationTrack>
|
|
174
180
|
) : null}
|
|
175
|
-
</div>
|
|
181
|
+
</div></div>
|
|
176
182
|
)}
|
|
177
183
|
</div>
|
|
178
184
|
{hasMessages && !showWelcome && !isAtBottom ? (
|
|
@@ -8,6 +8,8 @@ function renderSessionArea(isProjectFirstView: boolean, onScrollNearEnd = vi.fn(
|
|
|
8
8
|
|
|
9
9
|
render(
|
|
10
10
|
<ChatSidebarSessionArea
|
|
11
|
+
query=""
|
|
12
|
+
onQueryChange={vi.fn()}
|
|
11
13
|
defaultSessionType="native"
|
|
12
14
|
groups={[]}
|
|
13
15
|
isCollapsed={false}
|
|
@@ -50,9 +52,9 @@ describe("ChatSidebarSessionArea", () => {
|
|
|
50
52
|
expect(projectButton.className).toContain("rounded-full");
|
|
51
53
|
expect(timeButton.querySelector("svg")).not.toBeNull();
|
|
52
54
|
expect(projectButton.querySelector("svg")).not.toBeNull();
|
|
53
|
-
expect(modeGroup.parentElement?.className).toContain("justify-
|
|
55
|
+
expect(modeGroup.parentElement?.className).toContain("justify-between");
|
|
54
56
|
expect(modeGroup.parentElement?.className).toContain("h-8");
|
|
55
|
-
expect(modeGroup.parentElement?.
|
|
57
|
+
expect(modeGroup.parentElement?.firstElementChild).toBe(modeGroup);
|
|
56
58
|
|
|
57
59
|
fireEvent.click(projectButton);
|
|
58
60
|
|
|
@@ -73,7 +75,7 @@ describe("ChatSidebarSessionArea", () => {
|
|
|
73
75
|
.querySelector("svg")
|
|
74
76
|
?.classList.contains("lucide-folder-plus"),
|
|
75
77
|
).toBe(true);
|
|
76
|
-
expect(addProjectButton.className).toContain("hover:bg-
|
|
78
|
+
expect(addProjectButton.className).toContain("hover:before:bg-[var(--interaction-hover)]");
|
|
77
79
|
expect(modeIndicator?.className).toContain("translate-x-full");
|
|
78
80
|
expect(modeIndicator?.className).toContain("motion-reduce:transition-none");
|
|
79
81
|
expect(
|
|
@@ -81,7 +83,7 @@ describe("ChatSidebarSessionArea", () => {
|
|
|
81
83
|
.getByRole("button", { name: "Project" })
|
|
82
84
|
.getAttribute("aria-pressed"),
|
|
83
85
|
).toBe("true");
|
|
84
|
-
expect(
|
|
86
|
+
expect(screen.getByRole("button", { name: "Search conversations..." }).previousElementSibling).toBe(
|
|
85
87
|
addProjectButton,
|
|
86
88
|
);
|
|
87
89
|
fireEvent.click(addProjectButton);
|
|
@@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
3
3
|
import { describe, expect, it, vi } from "vitest";
|
|
4
4
|
import {
|
|
5
5
|
ChatSidebarDesktopToolbar,
|
|
6
|
+
ChatSidebarListToolbar,
|
|
6
7
|
ChatSidebarMobileToolbar,
|
|
7
8
|
} from "@/features/chat/components/layout/chat-sidebar-toolbar";
|
|
8
9
|
import type { ChatSessionTypeOption } from "@/features/chat/features/session-type/utils/chat-session-type.utils";
|
|
@@ -34,8 +35,18 @@ function searchIconClassName() {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
describe("ChatSidebarToolbar", () => {
|
|
37
|
-
it("
|
|
38
|
+
it("does not reserve a search row in the desktop header", () => {
|
|
38
39
|
render(<ChatSidebarDesktopToolbar {...toolbarProps} />);
|
|
40
|
+
expect(screen.queryByRole("textbox")).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
it("reveals desktop search below the list controls and clears it on close", async () => {
|
|
43
|
+
const user = userEvent.setup();
|
|
44
|
+
const onQueryChange = vi.fn();
|
|
45
|
+
render(<ChatSidebarListToolbar {...toolbarProps} onQueryChange={onQueryChange} isProjectFirstView={false} onSelectMode={vi.fn()} onAddProject={vi.fn()} />);
|
|
46
|
+
expect(screen.queryByRole("textbox")).toBeNull();
|
|
47
|
+
const trigger = screen.getByRole("button", { name: "Search conversations..." });
|
|
48
|
+
await user.click(trigger);
|
|
49
|
+
expect(document.activeElement).toBe(screen.getByRole("textbox"));
|
|
39
50
|
|
|
40
51
|
expect(searchIconClassName()).toContain("pointer-events-none");
|
|
41
52
|
expect(
|
|
@@ -46,6 +57,16 @@ describe("ChatSidebarToolbar", () => {
|
|
|
46
57
|
.getByPlaceholderText("Search conversations...")
|
|
47
58
|
.getAttribute("data-theme-control"),
|
|
48
59
|
).toBe("chat-search");
|
|
60
|
+
await user.type(screen.getByRole("textbox"), "a");
|
|
61
|
+
expect(onQueryChange).toHaveBeenLastCalledWith("a");
|
|
62
|
+
await user.click(screen.getByRole("button", { name: "Close search" }));
|
|
63
|
+
expect(onQueryChange).toHaveBeenLastCalledWith("");
|
|
64
|
+
expect(screen.queryByRole("textbox")).toBeNull();
|
|
65
|
+
expect(document.activeElement).toBe(trigger);
|
|
66
|
+
await user.click(trigger);
|
|
67
|
+
await user.keyboard("{Escape}");
|
|
68
|
+
expect(screen.queryByRole("textbox")).toBeNull();
|
|
69
|
+
expect(document.activeElement).toBe(trigger);
|
|
49
70
|
});
|
|
50
71
|
|
|
51
72
|
it('reveals mobile search on demand and clears the filter when closed', async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BrandHeader } from "@/shared/components/common/brand-header";
|
|
2
2
|
import { StatusBadge } from "@/shared/components/common/status-badge";
|
|
3
|
-
import {
|
|
3
|
+
import { ChatSidebarListToolbar } from "@/features/chat/components/layout/chat-sidebar-toolbar";
|
|
4
4
|
import type {
|
|
5
5
|
groupSessionsByDate,
|
|
6
6
|
groupSessionsByProject,
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
Inbox,
|
|
21
21
|
PanelLeftClose,
|
|
22
22
|
PanelLeftOpen,
|
|
23
|
-
FolderPlus,
|
|
24
23
|
} from "lucide-react";
|
|
25
24
|
import { useInboxUnreadCount } from "@/features/inbox";
|
|
26
25
|
import { ChatSidebarSessionList } from "@/features/chat/features/session/components/chat-sidebar-session-list";
|
|
@@ -148,6 +147,8 @@ export function ChatSidebarDesktopNav({
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
export function ChatSidebarSessionArea({
|
|
150
|
+
query,
|
|
151
|
+
onQueryChange,
|
|
151
152
|
variant = 'desktop',
|
|
152
153
|
defaultSessionType,
|
|
153
154
|
groups,
|
|
@@ -162,6 +163,8 @@ export function ChatSidebarSessionArea({
|
|
|
162
163
|
renderSessionItem,
|
|
163
164
|
sessionTypeOptions,
|
|
164
165
|
}: {
|
|
166
|
+
query: string;
|
|
167
|
+
onQueryChange: (query: string) => void;
|
|
165
168
|
variant?: 'desktop' | 'mobile';
|
|
166
169
|
defaultSessionType: string;
|
|
167
170
|
groups: ReturnType<typeof groupSessionsByDate>;
|
|
@@ -189,20 +192,13 @@ export function ChatSidebarSessionArea({
|
|
|
189
192
|
|
|
190
193
|
return (
|
|
191
194
|
<>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
icon={<FolderPlus className="h-3.5 w-3.5" />}
|
|
196
|
-
label={t("chatProjectAdd")}
|
|
197
|
-
tone="surface"
|
|
198
|
-
onClick={onAddProject}
|
|
199
|
-
/>
|
|
200
|
-
) : null}
|
|
201
|
-
<ChatSidebarListModeSwitch
|
|
195
|
+
{variant === 'desktop' ? <ChatSidebarListToolbar
|
|
196
|
+
query={query}
|
|
197
|
+
onQueryChange={onQueryChange}
|
|
202
198
|
isProjectFirstView={isProjectFirstView}
|
|
203
199
|
onSelectMode={onSelectMode}
|
|
204
|
-
|
|
205
|
-
|
|
200
|
+
onAddProject={onAddProject}
|
|
201
|
+
/> : null}
|
|
206
202
|
|
|
207
203
|
<div
|
|
208
204
|
ref={scrollRef}
|