@rexvane/piweb 0.3.24 → 0.3.26
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +11 -11
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +5 -5
- package/.next/react-loadable-manifest.json +13 -20
- package/.next/required-server-files.js +2 -1
- package/.next/required-server-files.json +2 -1
- package/.next/routes-manifest.json +6 -8
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/agent/[id]/events/route.js +2 -2
- package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/route.js +1 -1
- package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/tree/route.js +1 -1
- package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/new/route.js +1 -1
- package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/resources/route.js +1 -0
- package/.next/server/app/api/agent/resources/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/resources/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/config/route.js +1 -1
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/files/route.js +1 -1
- package/.next/server/app/api/files/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/route.js +1 -1
- package/.next/server/app/api/fs/route.js.nft.json +1 -1
- package/.next/server/app/api/git/route.js +4 -4
- package/.next/server/app/api/git/route.js.nft.json +1 -1
- package/.next/server/app/api/github/route.js +4 -4
- package/.next/server/app/api/github/route.js.nft.json +1 -1
- package/.next/server/app/api/growth/route.js +1 -1
- package/.next/server/app/api/growth/route.js.nft.json +1 -1
- package/.next/server/app/api/health/route.js +1 -1
- package/.next/server/app/api/models/defaults/route.js +1 -1
- package/.next/server/app/api/models/defaults/route.js.nft.json +1 -1
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/pi-settings/route.js +1 -1
- package/.next/server/app/api/pi-settings/route.js.nft.json +1 -1
- package/.next/server/app/api/plugins/route.js +1 -1
- package/.next/server/app/api/plugins/route.js.nft.json +1 -1
- package/.next/server/app/api/prompts/route.js +1 -1
- package/.next/server/app/api/prompts/route.js.nft.json +1 -1
- package/.next/server/app/api/remote/route.js +4 -3
- package/.next/server/app/api/security/route.js +1 -1
- package/.next/server/app/api/security/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/import/route.js +2 -2
- package/.next/server/app/api/sessions/import/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/route.js +1 -1
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +2 -2
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/update/route.js +2 -2
- package/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/version/route.js.nft.json +1 -1
- package/.next/server/app/api/web-auth/route.js +2 -2
- package/.next/server/app/api/workspaces/route.js +1 -1
- package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
- package/.next/server/app/icon.svg/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +6 -7
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -7
- package/.next/server/app/index.segments/_full.segment.rsc +6 -7
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -3
- package/.next/server/app/login/page.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +11 -11
- package/.next/server/chunks/3924.js +3 -3
- package/.next/server/chunks/538.js +1 -1
- package/.next/server/chunks/620.js +1 -0
- package/.next/server/chunks/6229.js +1 -1
- package/.next/server/chunks/7496.js +1 -1
- package/.next/server/chunks/7662.js +2 -2
- package/.next/server/chunks/8686.js +1 -1
- package/.next/server/functions-config-manifest.json +1 -2
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/preview-props.json +3 -3
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/QJCtqgDKzGS2BdKABd9ch/_buildManifest.js +1 -0
- package/.next/static/chunks/2577.86c8538fbf05a8b2.js +1 -0
- package/.next/static/chunks/2716.fa561519675a3ff1.js +1 -0
- package/.next/static/chunks/2906.8a0e09bb47605cf1.js +1 -0
- package/.next/static/chunks/4673.ea36e55005c0f82f.js +1 -0
- package/.next/static/chunks/4686-4dc565817a160351.js +1 -0
- package/.next/static/chunks/4778.0d2c5d75b791d352.js +1 -0
- package/.next/static/chunks/{618.949981da99be7182.js → 618.9a22656b863f242b.js} +2 -2
- package/.next/static/chunks/app/_global-error/page-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/tree/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/agent/resources/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/config/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/files/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/fs/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/git/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/github/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/growth/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/health/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/models/defaults/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/models/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/pi-settings/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/prompts/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/remote/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/security/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/sessions/import/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/skills/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/update/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/version/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/web-auth/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/api/workspaces/route-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/app/page-71f2d3b3ed864b3d.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f2d93969c0bcf406.js +1 -0
- package/.next/static/chunks/webpack-ffc09b5fcc8aaa6d.js +1 -0
- package/.next/static/css/014eb1f21414e615.css +1 -0
- package/.next/static/css/56b129a13637fcfd.css +1 -0
- package/.next/static/css/7e3caf797e4cb19a.css +1 -0
- package/.next/types/app/api/agent/{[id]/side-chat → resources}/route.ts +3 -3
- package/.next/types/routes.d.ts +2 -2
- package/.next/types/validator.ts +9 -9
- package/README.md +1 -1
- package/next.config.ts +1 -1
- package/package.json +9 -9
- package/scripts/apply-global.mjs +87 -0
- package/scripts/launcher.mjs +21 -0
- package/scripts/testing/prepare-sdk-tools.mjs +19 -0
- package/src/app/api/agent/new/route.ts +2 -1
- package/src/app/api/agent/resources/route.ts +18 -0
- package/src/app/api/models/route.ts +22 -1
- package/src/app/api/plugins/route.ts +3 -2
- package/src/app/api/prompts/route.ts +3 -2
- package/src/app/api/remote/route.ts +22 -4
- package/src/app/api/sessions/[id]/export/route.ts +3 -1
- package/src/app/api/skills/route.ts +3 -2
- package/src/app/globals.css +1002 -1765
- package/src/components/AppShell.tsx +128 -93
- package/src/components/ChatInput.tsx +177 -98
- package/src/components/ChatWindow.tsx +189 -56
- package/src/components/ContextMeter.tsx +33 -9
- package/src/components/CustomSelect.module.css +142 -0
- package/src/components/CustomSelect.tsx +157 -0
- package/src/components/DrawerPanel.tsx +1 -1
- package/src/components/ExtensionUI.tsx +9 -3
- package/src/components/FileViewer.tsx +24 -21
- package/src/components/GitPanel.tsx +35 -13
- package/src/components/GrowthTree.tsx +6 -2
- package/src/components/ImageViewer.tsx +72 -0
- package/src/components/MarkdownBlock.tsx +67 -96
- package/src/components/ModelSelector.tsx +36 -39
- package/src/components/PiMark.tsx +76 -41
- package/src/components/PreviewImage.tsx +33 -0
- package/src/components/ProjectPanel.tsx +8 -5
- package/src/components/PromptPanel.tsx +85 -20
- package/src/components/ProviderSetupModal.module.css +12 -11
- package/src/components/ProviderSetupModal.tsx +107 -36
- package/src/components/RemoteSection.tsx +53 -2
- package/src/components/SessionImportSection.tsx +30 -15
- package/src/components/SessionSidebar.tsx +72 -62
- package/src/components/SettingsPanel.tsx +49 -151
- package/src/components/TrajectoryAnalyzer.module.css +26 -11
- package/src/components/TrajectoryView.tsx +11 -3
- package/src/components/chat/markdown-actions.tsx +23 -0
- package/src/components/composer/ComposerFiles.tsx +224 -0
- package/src/components/composer/ComposerImages.tsx +59 -127
- package/src/hooks/usePiWeb.ts +47 -2
- package/src/i18n.tsx +62 -80
- package/src/lib/agent-manager.ts +365 -33
- package/src/lib/chat/file-path.ts +54 -0
- package/src/lib/chat/skill-expansion.ts +51 -0
- package/src/lib/extension-ui.ts +25 -1
- package/src/lib/font.ts +37 -39
- package/src/lib/git-service.ts +4 -2
- package/src/lib/growth-turns.ts +3 -1
- package/src/lib/model-draft.ts +69 -2
- package/src/lib/models-service.ts +53 -3
- package/src/lib/pi.ts +2 -2
- package/src/lib/remote/assets.json +1 -1
- package/src/lib/remote/supervisor.ts +48 -5
- package/src/lib/security-service.ts +2 -1
- package/src/lib/session-reader.ts +25 -13
- package/src/lib/session-retention.ts +11 -8
- package/src/lib/skills-service.ts +2 -1
- package/src/lib/slash-command-token.ts +14 -0
- package/src/lib/trajectory.ts +111 -15
- package/src/lib/types.ts +28 -3
- package/src/lib/update-service.ts +29 -9
- package/src/lib/workspace-store.ts +36 -1
- package/.next/server/app/api/agent/[id]/side-chat/route.js +0 -5
- package/.next/server/app/api/agent/[id]/side-chat/route.js.nft.json +0 -1
- package/.next/server/app/api/agent/[id]/side-chat/route_client-reference-manifest.js +0 -1
- package/.next/server/chunks/3421.js +0 -1
- package/.next/static/chunks/2716.44fdf1b21454b961.js +0 -1
- package/.next/static/chunks/4673.e261707dce391be7.js +0 -1
- package/.next/static/chunks/4686-0cd87513f9ea3538.js +0 -1
- package/.next/static/chunks/4778.eddd3a5813f85824.js +0 -1
- package/.next/static/chunks/7411.5f79671208209b13.js +0 -1
- package/.next/static/chunks/8552.25c39ef4c995eba0.js +0 -1
- package/.next/static/chunks/app/_global-error/page-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/events/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/side-chat/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/tree/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/agent/new/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/config/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/files/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/fs/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/git/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/github/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/growth/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/health/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/models/defaults/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/models/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/pi-settings/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/plugins/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/prompts/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/remote/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/security/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/export/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/sessions/import/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/skills/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/update/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/version/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/web-auth/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/api/workspaces/route-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/app/page-dc3cb41d91c7432e.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-cbaaee0d7aacb85a.js +0 -1
- package/.next/static/chunks/webpack-2ac3d76b81895f5b.js +0 -1
- package/.next/static/css/08815507594e8b8d.css +0 -1
- package/.next/static/css/9fc559c2c4ad1d0f.css +0 -1
- package/.next/static/css/c6e2227c36ec2fd6.css +0 -1
- package/.next/static/css/f15a853af8b5127f.css +0 -1
- package/.next/static/lvKCJmjFj8LuqSojRVLRF/_buildManifest.js +0 -1
- package/src/app/api/agent/[id]/side-chat/route.ts +0 -77
- package/src/components/side-chat/SideChatPanel.module.css +0 -131
- package/src/components/side-chat/SideChatPanel.tsx +0 -189
- package/src/components/side-chat/icons.tsx +0 -8
- package/src/components/side-chat/request-history.ts +0 -29
- package/src/components/side-chat/store.ts +0 -248
- package/src/lib/chat/stream-settings.ts +0 -192
- package/src/lib/side-chat/context.ts +0 -123
- package/src/lib/side-chat/service.ts +0 -191
- package/src/lib/side-chat/types.ts +0 -61
- /package/.next/static/{lvKCJmjFj8LuqSojRVLRF → QJCtqgDKzGS2BdKABd9ch}/_ssgManifest.js +0 -0
|
@@ -130,9 +130,9 @@ export function SessionImportSection({ cwd }: { cwd: string }) {
|
|
|
130
130
|
*/
|
|
131
131
|
const [activeSource, setActiveSource] = useState("");
|
|
132
132
|
useEffect(() => {
|
|
133
|
-
|
|
134
|
-
setActiveSource(groups[0]?.source ?? "");
|
|
135
|
-
}, [groups
|
|
133
|
+
// 扫描完成的 effect 可能晚于用户点击;按执行时的最新选择决定是否回退。
|
|
134
|
+
setActiveSource((current) => groups.some((group) => group.source === current) ? current : groups[0]?.source ?? "");
|
|
135
|
+
}, [groups]);
|
|
136
136
|
const activeGroup = groups.find((group) => group.source === activeSource);
|
|
137
137
|
|
|
138
138
|
const toggle = (summary: Summary) => {
|
|
@@ -348,36 +348,51 @@ export function SessionImportSection({ cwd }: { cwd: string }) {
|
|
|
348
348
|
return (
|
|
349
349
|
<label
|
|
350
350
|
key={rowKey}
|
|
351
|
-
className="flex cursor-pointer items-center gap-3 rounded-
|
|
351
|
+
className="flex cursor-pointer items-center gap-3 rounded-2xl px-3.5 py-2.5 transition-all"
|
|
352
352
|
style={{
|
|
353
|
-
border: `
|
|
354
|
-
background: checked ? "var(--dsw-accent-soft)" : "
|
|
355
|
-
opacity: done ? 0.
|
|
353
|
+
border: `1px solid ${checked ? "var(--dsw-accent)" : "var(--dsw-border-l2)"}`,
|
|
354
|
+
background: checked ? "var(--dsw-accent-soft)" : "var(--dsw-bg-elevated)",
|
|
355
|
+
opacity: done ? 0.45 : 1,
|
|
356
|
+
transition: "all 0.2s var(--isx-ease)",
|
|
357
|
+
}}
|
|
358
|
+
onMouseEnter={(e) => {
|
|
359
|
+
if (!checked && !done) {
|
|
360
|
+
e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
|
|
361
|
+
e.currentTarget.style.background = "var(--dsw-hover)";
|
|
362
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
363
|
+
}
|
|
364
|
+
}}
|
|
365
|
+
onMouseLeave={(e) => {
|
|
366
|
+
if (!checked && !done) {
|
|
367
|
+
e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
|
|
368
|
+
e.currentTarget.style.background = "var(--dsw-bg-elevated)";
|
|
369
|
+
e.currentTarget.style.transform = "none";
|
|
370
|
+
}
|
|
356
371
|
}}
|
|
357
372
|
>
|
|
358
|
-
<input type="checkbox" checked={checked} disabled={done} onChange={() => toggle(row)} className="flex-none" />
|
|
373
|
+
<input type="checkbox" checked={checked} disabled={done} onChange={() => toggle(row)} className="flex-none accent-[var(--dsw-accent)]" />
|
|
359
374
|
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
360
|
-
<div className="truncate" style={{ fontSize: 12.5, color: done ? "var(--dsw-label-tertiary)" : "var(--dsw-label-primary)" }} title={row.title}>
|
|
375
|
+
<div className="truncate font-medium" style={{ fontSize: 12.5, color: done ? "var(--dsw-label-tertiary)" : "var(--dsw-label-primary)" }} title={row.title}>
|
|
361
376
|
{row.title || t.importUntitled}
|
|
362
377
|
</div>
|
|
363
378
|
<div className="flex min-w-0 items-center gap-1.5" title={row.projectPath}>
|
|
364
379
|
<span
|
|
365
|
-
className="flex-none rounded px-
|
|
366
|
-
style={{ fontSize: 10, background: "var(--dsw-selector)", color: "var(--dsw-label-
|
|
380
|
+
className="flex-none rounded-full px-2 py-0.5"
|
|
381
|
+
style={{ fontSize: 10, background: "var(--dsw-selector)", color: "var(--dsw-label-secondary)", border: "1px solid var(--dsw-border-l1)" }}
|
|
367
382
|
>
|
|
368
383
|
{goesOriginal ? t.importGoesOriginal : t.importGoesFallback}
|
|
369
384
|
</span>
|
|
370
|
-
<span className="truncate" style={{ fontSize: 11, color: "var(--dsw-label-caption)" }}>
|
|
385
|
+
<span className="truncate font-mono" style={{ fontSize: 11, color: "var(--dsw-label-caption)" }}>
|
|
371
386
|
{target || t.importNoProject}
|
|
372
387
|
</span>
|
|
373
388
|
</div>
|
|
374
389
|
</div>
|
|
375
|
-
<span className="flex-none" style={{ fontSize: 11, color: "var(--dsw-label-caption)", whiteSpace: "nowrap" }}>
|
|
390
|
+
<span className="flex-none font-mono" style={{ fontSize: 11, color: "var(--dsw-label-caption)", whiteSpace: "nowrap" }}>
|
|
376
391
|
{typeof row.messageCount === "number" ? t.importMessages.replace("{n}", String(row.messageCount)) : "—"}
|
|
377
392
|
</span>
|
|
378
|
-
<span className="flex-none" style={{ fontSize: 11, color: "var(--dsw-label-caption)", whiteSpace: "nowrap" }}>{dayOf(row.updatedAt ?? row.createdAt)}</span>
|
|
393
|
+
<span className="flex-none font-mono" style={{ fontSize: 11, color: "var(--dsw-label-caption)", whiteSpace: "nowrap" }}>{dayOf(row.updatedAt ?? row.createdAt)}</span>
|
|
379
394
|
{done && (
|
|
380
|
-
<span className="flex-none rounded-full px-2 py-0.5" style={{ fontSize: 10, background: "var(--dsw-selector)", color: "var(--dsw-label-caption)" }}>
|
|
395
|
+
<span className="flex-none rounded-full px-2 py-0.5 font-medium" style={{ fontSize: 10, background: "var(--dsw-selector)", color: "var(--dsw-label-caption)", border: "1px solid var(--dsw-border-l1)" }}>
|
|
381
396
|
{t.importAlready}
|
|
382
397
|
</span>
|
|
383
398
|
)}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 搜索模式(输入框替身标题行,空查询=工作区平铺,输入=会话平铺),
|
|
9
9
|
* 滑杆菜单(分组方式:按工作区/单列表;排序方式:手动排序/最近更新)。
|
|
10
10
|
*/
|
|
11
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
11
|
+
import { memo, useEffect, useMemo, useRef, useState } from "react";
|
|
12
12
|
import { createPortal } from "react-dom";
|
|
13
13
|
import { BrandPi, PiMark } from "@/components/PiMark";
|
|
14
14
|
import {
|
|
@@ -68,7 +68,7 @@ interface WorkspaceGroup {
|
|
|
68
68
|
lastModified: string;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
function SessionSidebarImpl({
|
|
72
72
|
sessions,
|
|
73
73
|
sessionListError,
|
|
74
74
|
onRetrySessionList,
|
|
@@ -221,11 +221,17 @@ export function SessionSidebar({
|
|
|
221
221
|
}
|
|
222
222
|
};
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
// 路径一律按 normPath 比:注册表里的工作区经过 path.resolve,会话头里的 cwd 是原样记下的,
|
|
225
|
+
// Windows 上盘符大小写、分隔符、尾斜杠都可能不同
|
|
226
|
+
const currentKey = currentPath ? normPath(currentPath) : "";
|
|
227
|
+
const currentCwd = currentKey ? sessions.find((s) => normPath(s.path) === currentKey)?.cwd : undefined;
|
|
225
228
|
|
|
226
229
|
useEffect(() => {
|
|
227
230
|
if (!viewMenu && !rowMenu && !sessionMenu) return;
|
|
228
231
|
const h = (e: MouseEvent) => {
|
|
232
|
+
// 按在行菜单的「…」按钮上:交给按钮的 onClick 切换(它也会关掉另一种菜单)。
|
|
233
|
+
// 这里先关的话,紧跟着的 click 又把菜单打开,再点一下「…」永远关不掉
|
|
234
|
+
if ((e.target as Element | null)?.closest?.("[data-menu-trigger]")) return;
|
|
229
235
|
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
|
|
230
236
|
setViewMenu(false);
|
|
231
237
|
setRowMenu(null);
|
|
@@ -325,7 +331,7 @@ export function SessionSidebar({
|
|
|
325
331
|
} catch {
|
|
326
332
|
/* ignore */
|
|
327
333
|
}
|
|
328
|
-
const s = sessions.find((item) => item.path === currentPath);
|
|
334
|
+
const s = sessions.find((item) => normPath(item.path) === normPath(currentPath));
|
|
329
335
|
if (!s) return; // 会话列表尚未加载,等轮询后重试
|
|
330
336
|
lastExpandedFor.current = currentPath;
|
|
331
337
|
const matchedGroup = workspaceGroups.find((g) => normPath(g.cwd) === normPath(s.cwd));
|
|
@@ -400,46 +406,40 @@ export function SessionSidebar({
|
|
|
400
406
|
}
|
|
401
407
|
|
|
402
408
|
const sessionRow = (s: SessionListItem, indented: boolean, archived = false) => {
|
|
403
|
-
const selected = s.path ===
|
|
409
|
+
const selected = !!currentKey && normPath(s.path) === currentKey;
|
|
404
410
|
// dsh 合同:被归档的当前会话仍显示在主列表,菜单按真实归档态切换
|
|
405
411
|
const reallyArchived = archived || archivedPaths.some((p) => normPath(p) === normPath(s.path));
|
|
406
412
|
return (
|
|
407
413
|
<div
|
|
408
414
|
key={s.path}
|
|
409
|
-
|
|
415
|
+
data-active={selected ? "true" : undefined}
|
|
416
|
+
className="isx-menu-item group relative flex items-center rounded-xl"
|
|
410
417
|
style={{
|
|
411
|
-
background: selected ? "var(--dsw-active)" : "transparent",
|
|
412
418
|
paddingLeft: indented ? 38 : 10,
|
|
413
|
-
paddingRight:
|
|
419
|
+
paddingRight: 14,
|
|
414
420
|
paddingTop: 6,
|
|
415
421
|
paddingBottom: 6,
|
|
416
422
|
// 选中/悬停框之间留缝,不互相粘连
|
|
417
423
|
marginTop: 2,
|
|
418
424
|
marginBottom: 2,
|
|
419
425
|
}}
|
|
420
|
-
onMouseEnter={(e) => {
|
|
421
|
-
if (!selected) e.currentTarget.style.background = "var(--dsw-hover)";
|
|
422
|
-
}}
|
|
423
|
-
onMouseLeave={(e) => {
|
|
424
|
-
if (!selected) e.currentTarget.style.background = "transparent";
|
|
425
|
-
}}
|
|
426
426
|
>
|
|
427
427
|
{s.streaming && <span className="state-dot running" style={{ position: "absolute", left: indented ? 26 : 6, width: 6, height: 6 }} />}
|
|
428
428
|
<button className="flex min-w-0 flex-1 flex-col items-start text-left" onClick={() => onOpen(s.path)}>
|
|
429
429
|
<span
|
|
430
|
-
className="w-full truncate"
|
|
431
|
-
style={{ fontSize: 13,
|
|
430
|
+
className="isx-menu-shift w-full truncate"
|
|
431
|
+
style={{ fontSize: 13, fontWeight: selected ? 500 : 400 }}
|
|
432
432
|
>
|
|
433
433
|
{s.name || s.firstMessage || "(untitled)"}
|
|
434
434
|
</span>
|
|
435
435
|
{s.streaming && s.lastStep && (
|
|
436
|
-
<span className="w-full truncate" style={{ fontSize: 11, fontFamily: "var(--font-mono)", color: "var(--dsw-label-caption)", lineHeight: "16px" }} title={s.lastStep}>
|
|
436
|
+
<span className="isx-menu-sub w-full truncate" style={{ fontSize: 11, fontFamily: "var(--font-mono)", color: "var(--dsw-label-caption)", lineHeight: "16px" }} title={s.lastStep}>
|
|
437
437
|
{s.lastStep}
|
|
438
438
|
</span>
|
|
439
439
|
)}
|
|
440
440
|
</button>
|
|
441
441
|
<span
|
|
442
|
-
className={`flex-none pl-1 ${sessionMenu === s.path ? "hidden" : "group-hover:hidden group-focus-within:hidden"}`}
|
|
442
|
+
className={`isx-menu-sub flex-none pl-1 ${sessionMenu === s.path ? "hidden" : "group-hover:hidden group-focus-within:hidden"}`}
|
|
443
443
|
style={{ fontSize: 10.5, color: "var(--dsw-label-caption)" }}
|
|
444
444
|
>
|
|
445
445
|
{relTime(s.modified, lang)}
|
|
@@ -450,6 +450,7 @@ export function SessionSidebar({
|
|
|
450
450
|
style={{ width: 22, height: 22 }}
|
|
451
451
|
title="..."
|
|
452
452
|
aria-label="session-actions"
|
|
453
|
+
data-menu-trigger="session"
|
|
453
454
|
onClick={(e) => {
|
|
454
455
|
e.stopPropagation();
|
|
455
456
|
setSessionMenu(sessionMenu === s.path ? null : s.path);
|
|
@@ -495,6 +496,7 @@ export function SessionSidebar({
|
|
|
495
496
|
<MenuItem
|
|
496
497
|
icon={<IconArchiveOutline20 size={14} />}
|
|
497
498
|
label={reallyArchived ? t.unarchiveSession : t.archiveSession}
|
|
499
|
+
title={reallyArchived ? undefined : t.archiveRetentionHint}
|
|
498
500
|
onClick={(e) => {
|
|
499
501
|
e.stopPropagation();
|
|
500
502
|
setSessionMenu(null);
|
|
@@ -511,7 +513,7 @@ export function SessionSidebar({
|
|
|
511
513
|
const workspaceRow = (g: WorkspaceGroup) => {
|
|
512
514
|
const isUngrouped = g.cwd === "__ungrouped__";
|
|
513
515
|
const open = openSet.has(g.cwd);
|
|
514
|
-
const isCurrent = !isUngrouped && g.cwd === currentCwd;
|
|
516
|
+
const isCurrent = !isUngrouped && !!currentCwd && normPath(g.cwd) === normPath(currentCwd);
|
|
515
517
|
// 草稿新会话属于哪个分组:路径匹配的工作区,否则归未分组
|
|
516
518
|
const draftInThisGroup = draftCwd
|
|
517
519
|
? (isUngrouped
|
|
@@ -525,42 +527,37 @@ export function SessionSidebar({
|
|
|
525
527
|
return (
|
|
526
528
|
<div key={g.cwd}>
|
|
527
529
|
<div
|
|
528
|
-
className="group relative flex items-center rounded-xl
|
|
530
|
+
className="isx-menu-item group relative flex items-center rounded-xl"
|
|
529
531
|
style={{
|
|
530
532
|
background: open || isCurrent ? "var(--dsw-hover)" : "transparent",
|
|
531
533
|
paddingLeft: 10,
|
|
532
|
-
paddingRight:
|
|
534
|
+
paddingRight: 12,
|
|
533
535
|
paddingTop: 7,
|
|
534
536
|
paddingBottom: 7,
|
|
535
537
|
// 悬停/展开框之间留缝,不互相粘连(与会话行一致)
|
|
536
538
|
marginTop: 2,
|
|
537
539
|
marginBottom: 2,
|
|
538
540
|
}}
|
|
539
|
-
onMouseEnter={(e) => {
|
|
540
|
-
if (!(open || isCurrent)) e.currentTarget.style.background = "var(--dsw-hover)";
|
|
541
|
-
}}
|
|
542
|
-
onMouseLeave={(e) => {
|
|
543
|
-
if (!(open || isCurrent)) e.currentTarget.style.background = "transparent";
|
|
544
|
-
}}
|
|
545
541
|
>
|
|
546
542
|
<button className="flex min-w-0 flex-1 items-center gap-2 text-left" onClick={() => toggleOpen(g.cwd)} title={displayName}>
|
|
547
543
|
<span
|
|
544
|
+
className="isx-menu-sub"
|
|
548
545
|
style={{
|
|
549
546
|
color: "var(--dsw-label-tertiary)",
|
|
550
547
|
display: "inline-flex",
|
|
551
548
|
transform: open ? "rotate(90deg)" : "none",
|
|
552
|
-
transition: "transform
|
|
549
|
+
transition: "transform 180ms var(--isx-ease)",
|
|
553
550
|
flex: "none",
|
|
554
551
|
}}
|
|
555
552
|
>
|
|
556
553
|
<IconTriangleRightFill14 size={11} />
|
|
557
554
|
</span>
|
|
558
|
-
<span style={{ color: isCurrent ? "var(--dsw-accent)" : "var(--dsw-label-tertiary)", display: "inline-flex", flex: "none" }}>
|
|
555
|
+
<span className="isx-menu-icon" style={{ color: isCurrent ? "var(--dsw-accent)" : "var(--dsw-label-tertiary)", display: "inline-flex", flex: "none" }}>
|
|
559
556
|
{open ? <IconFolderOpenOutline16 size={15} /> : <IconFolderClose16 size={15} />}
|
|
560
557
|
</span>
|
|
561
558
|
<span
|
|
562
|
-
className="truncate"
|
|
563
|
-
style={{ fontSize: 13,
|
|
559
|
+
className="isx-menu-shift truncate"
|
|
560
|
+
style={{ fontSize: 13, fontWeight: isCurrent ? 500 : 400 }}
|
|
564
561
|
>
|
|
565
562
|
{displayName}
|
|
566
563
|
</span>
|
|
@@ -572,6 +569,7 @@ export function SessionSidebar({
|
|
|
572
569
|
style={{ width: 22, height: 22 }}
|
|
573
570
|
title="..."
|
|
574
571
|
aria-label="workspace-actions"
|
|
572
|
+
data-menu-trigger="workspace"
|
|
575
573
|
onClick={() => {
|
|
576
574
|
setRowMenu(rowMenu === g.cwd ? null : g.cwd);
|
|
577
575
|
setSessionMenu(null);
|
|
@@ -661,7 +659,7 @@ export function SessionSidebar({
|
|
|
661
659
|
</button>
|
|
662
660
|
</div>
|
|
663
661
|
|
|
664
|
-
{/* 新会话(
|
|
662
|
+
{/* 新会话(Iconsax .button-gradient 光晕胶囊) */}
|
|
665
663
|
<div className="px-3 pt-1">
|
|
666
664
|
<button className="btn-new-session w-full" onClick={onNew}>
|
|
667
665
|
<IconNewChatOutline16 size={14} />
|
|
@@ -669,11 +667,11 @@ export function SessionSidebar({
|
|
|
669
667
|
</button>
|
|
670
668
|
</div>
|
|
671
669
|
|
|
672
|
-
{/* 工作区标题行 / 搜索框(互替,照
|
|
670
|
+
{/* 工作区标题行 / 搜索框(互替,照 Iconsax .con-search) */}
|
|
673
671
|
{searchOpen ? (
|
|
674
672
|
<div className="px-3 pb-1 pt-3">
|
|
675
|
-
<div className="flex items-center gap-2
|
|
676
|
-
<IconSearchOutline16 size={14} style={{ color: "var(--dsw-label-caption)" }} />
|
|
673
|
+
<div className="isx-search flex items-center gap-2 px-3 py-2">
|
|
674
|
+
<IconSearchOutline16 size={14} className="isx-search-icon" style={{ color: "var(--dsw-label-caption)", flex: "none" }} />
|
|
677
675
|
<input
|
|
678
676
|
autoFocus
|
|
679
677
|
value={q}
|
|
@@ -717,7 +715,7 @@ export function SessionSidebar({
|
|
|
717
715
|
</div>
|
|
718
716
|
<MenuCheck label={t.byWorkspace} checked={groupBy === "workspace"} onClick={() => { setGroupBy("workspace"); setViewMenu(false); }} />
|
|
719
717
|
<MenuCheck label={t.flatList} checked={groupBy === "flat"} onClick={() => { setGroupBy("flat"); setViewMenu(false); }} />
|
|
720
|
-
<div className="my-1.5" style={{ borderTop: "
|
|
718
|
+
<div className="my-1.5" style={{ borderTop: "1px solid var(--dsw-border-l2)" }} />
|
|
721
719
|
<div className="px-3 pb-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>
|
|
722
720
|
{t.sortBy}
|
|
723
721
|
</div>
|
|
@@ -766,19 +764,17 @@ export function SessionSidebar({
|
|
|
766
764
|
[...workspaceGroups, ...(ungroupedGroup ? [ungroupedGroup] : [])].map((g) => (
|
|
767
765
|
<div
|
|
768
766
|
key={g.cwd}
|
|
769
|
-
className="flex items-center gap-2.5 rounded-xl px-2.5 py-2
|
|
770
|
-
onMouseEnter={(e) => (e.currentTarget.style.background = "var(--dsw-hover)")}
|
|
771
|
-
onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
|
|
767
|
+
className="isx-menu-item flex cursor-pointer items-center gap-2.5 rounded-xl px-2.5 py-2"
|
|
772
768
|
onClick={() => {
|
|
773
769
|
setSearchOpen(false);
|
|
774
770
|
toggleOpen(g.cwd);
|
|
775
771
|
}}
|
|
776
772
|
title={g.cwd === "__ungrouped__" ? (t.ungrouped || "未分组") : g.cwd}
|
|
777
773
|
>
|
|
778
|
-
<span style={{ color: "var(--dsw-label-tertiary)", display: "inline-flex" }}>
|
|
774
|
+
<span className="isx-menu-icon" style={{ color: "var(--dsw-label-tertiary)", display: "inline-flex" }}>
|
|
779
775
|
<IconFolderClose16 size={15} />
|
|
780
776
|
</span>
|
|
781
|
-
<span className="truncate" style={{ fontSize: 13 }}>
|
|
777
|
+
<span className="isx-menu-shift truncate" style={{ fontSize: 13 }}>
|
|
782
778
|
{g.cwd === "__ungrouped__"
|
|
783
779
|
? (t.ungrouped || "未分组")
|
|
784
780
|
: (getWorkspaceName ? getWorkspaceName(g.cwd) : basename(g.cwd))}
|
|
@@ -839,26 +835,33 @@ export function SessionSidebar({
|
|
|
839
835
|
<div className="mt-2 border-t pt-2" style={{ borderColor: "var(--dsw-border-l2)" }}>
|
|
840
836
|
<button
|
|
841
837
|
type="button"
|
|
842
|
-
className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left
|
|
838
|
+
className="isx-menu-item flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left"
|
|
843
839
|
aria-expanded={archiveOpen}
|
|
840
|
+
title={t.archiveRetentionDetail}
|
|
844
841
|
onClick={() => setArchiveOpen((open) => !open)}
|
|
845
|
-
onMouseEnter={(event) => (event.currentTarget.style.background = "var(--dsw-hover)")}
|
|
846
|
-
onMouseLeave={(event) => (event.currentTarget.style.background = "transparent")}
|
|
847
842
|
>
|
|
848
843
|
<span
|
|
844
|
+
className="isx-menu-sub"
|
|
849
845
|
style={{
|
|
850
846
|
display: "inline-flex",
|
|
851
847
|
transform: archiveOpen ? "rotate(90deg)" : "none",
|
|
852
|
-
transition: "transform
|
|
848
|
+
transition: "transform 180ms var(--isx-ease)",
|
|
853
849
|
color: "var(--dsw-label-tertiary)",
|
|
854
850
|
}}
|
|
855
851
|
>
|
|
856
852
|
<IconTriangleRightFill14 size={11} />
|
|
857
853
|
</span>
|
|
858
|
-
<
|
|
859
|
-
|
|
860
|
-
|
|
854
|
+
<span className="isx-menu-icon" style={{ display: "inline-flex", color: "var(--dsw-label-tertiary)" }}>
|
|
855
|
+
<IconArchiveOutline20 size={15} />
|
|
856
|
+
</span>
|
|
857
|
+
<span className="isx-menu-shift min-w-0 flex-1 truncate" style={{ fontSize: 13 }}>{t.archivedSessions}</span>
|
|
858
|
+
<span className="isx-menu-sub pr-2" style={{ fontSize: 11, color: "var(--dsw-label-caption)" }}>{archivedSessions.length}</span>
|
|
861
859
|
</button>
|
|
860
|
+
{archiveOpen && (
|
|
861
|
+
<div className="px-2.5 pb-1" style={{ fontSize: 11, color: "var(--dsw-label-caption)" }} title={t.archiveRetentionDetail}>
|
|
862
|
+
{t.archiveRetentionHint}
|
|
863
|
+
</div>
|
|
864
|
+
)}
|
|
862
865
|
{archiveOpen && archivedSessions.map((session) => sessionRow(session, true, true))}
|
|
863
866
|
</div>
|
|
864
867
|
)}
|
|
@@ -867,14 +870,14 @@ export function SessionSidebar({
|
|
|
867
870
|
{/* 设置固定左下角 */}
|
|
868
871
|
<div className="px-3 py-2.5">
|
|
869
872
|
<button
|
|
870
|
-
className="flex w-full items-center gap-2.5 rounded-xl px-4 py-2 text-left
|
|
873
|
+
className="isx-menu-item flex w-full items-center gap-2.5 rounded-xl px-4 py-2 text-left"
|
|
871
874
|
style={{ color: "var(--dsw-label-secondary)" }}
|
|
872
|
-
onMouseEnter={(e) => (e.currentTarget.style.background = "var(--dsw-hover)")}
|
|
873
|
-
onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
|
|
874
875
|
onClick={onOpenSettings}
|
|
875
876
|
>
|
|
876
|
-
<
|
|
877
|
-
|
|
877
|
+
<span className="isx-menu-icon" style={{ display: "inline-flex" }}>
|
|
878
|
+
<IconSettingsOutline16 size={16} />
|
|
879
|
+
</span>
|
|
880
|
+
<span className="isx-menu-shift" style={{ fontSize: "var(--dsh-content-font-size)" }}>{t.settings}</span>
|
|
878
881
|
</button>
|
|
879
882
|
</div>
|
|
880
883
|
|
|
@@ -1025,27 +1028,35 @@ export function SessionSidebar({
|
|
|
1025
1028
|
);
|
|
1026
1029
|
}
|
|
1027
1030
|
|
|
1031
|
+
/**
|
|
1032
|
+
* memo:流式期间 AppShell 每 16ms 重渲染一次(state.messages 换引用),侧栏的 props
|
|
1033
|
+
* (会话列表、回调)在此期间全部不变,几百行会话树的 reconciliation 是纯浪费。
|
|
1034
|
+
*/
|
|
1035
|
+
export const SessionSidebar = memo(SessionSidebarImpl);
|
|
1036
|
+
|
|
1028
1037
|
function MenuItem({
|
|
1029
1038
|
icon,
|
|
1030
1039
|
label,
|
|
1040
|
+
title,
|
|
1031
1041
|
danger,
|
|
1032
1042
|
onClick,
|
|
1033
1043
|
}: {
|
|
1034
1044
|
icon: React.ReactNode;
|
|
1035
1045
|
label: string;
|
|
1046
|
+
title?: string;
|
|
1036
1047
|
danger?: boolean;
|
|
1037
1048
|
onClick: (e: React.MouseEvent) => void;
|
|
1038
1049
|
}) {
|
|
1039
1050
|
return (
|
|
1040
1051
|
<button
|
|
1041
|
-
|
|
1052
|
+
title={title}
|
|
1053
|
+
data-danger={danger ? "true" : undefined}
|
|
1054
|
+
className="isx-menu-item mx-1 flex w-[calc(100%-8px)] items-center gap-2.5 rounded-lg px-3 py-2 text-left"
|
|
1042
1055
|
style={{ fontSize: 13, color: danger ? "var(--dsw-danger)" : "var(--dsw-label-primary)" }}
|
|
1043
|
-
onMouseEnter={(e) => (e.currentTarget.style.background = "var(--dsw-hover)")}
|
|
1044
|
-
onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
|
|
1045
1056
|
onClick={onClick}
|
|
1046
1057
|
>
|
|
1047
|
-
{icon}
|
|
1048
|
-
{label}
|
|
1058
|
+
<span className="isx-menu-icon" style={{ display: "inline-flex" }}>{icon}</span>
|
|
1059
|
+
<span className="isx-menu-shift">{label}</span>
|
|
1049
1060
|
</button>
|
|
1050
1061
|
);
|
|
1051
1062
|
}
|
|
@@ -1053,13 +1064,12 @@ function MenuItem({
|
|
|
1053
1064
|
function MenuCheck({ label, checked, onClick }: { label: string; checked: boolean; onClick: () => void }) {
|
|
1054
1065
|
return (
|
|
1055
1066
|
<button
|
|
1056
|
-
|
|
1067
|
+
data-active={checked ? "true" : undefined}
|
|
1068
|
+
className="isx-menu-item mx-1 flex w-[calc(100%-8px)] items-center justify-between rounded-lg pl-4 pr-4 py-2 text-left"
|
|
1057
1069
|
style={{ fontSize: 13, color: "var(--dsw-label-primary)" }}
|
|
1058
|
-
onMouseEnter={(e) => (e.currentTarget.style.background = "var(--dsw-hover)")}
|
|
1059
|
-
onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
|
|
1060
1070
|
onClick={onClick}
|
|
1061
1071
|
>
|
|
1062
|
-
{label}
|
|
1072
|
+
<span className="isx-menu-shift">{label}</span>
|
|
1063
1073
|
{checked && <IconCheckOutline14 size={13} />}
|
|
1064
1074
|
</button>
|
|
1065
1075
|
);
|