Skip to content

Commit 2df1ddd

Browse files
committed
refactor(ui): 优化按钮样式和上下文组件命名
- 为按钮添加了 cursor-pointer 样式,提升交互体验 - 将 ContextMeter 组件重命名为 ContextIndicator,统一命名规范 - 更新引入和测试中对应的组件名称 - InputPrompt 组件中用 ContextIndicator 替换 ContextMeter - 优化 InputPrompt 中发送按钮及加载状态样式和逻辑 - SystemBubble 组件中新增 Markdown 渲染支持技能描述文本 - 调整 SystemBubble 中技能描述的样式结构,增强可读性
1 parent 66dfa3d commit 2df1ddd

5 files changed

Lines changed: 21 additions & 17 deletions

File tree

packages/vscode-ide-companion/src/webview/components/ContextMeter.tsx renamed to packages/vscode-ide-companion/src/webview/components/ContextIndicator.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function formatTokenCount(value: unknown): string {
1717
return n.toLocaleString();
1818
}
1919

20-
export default function ContextMeter({ tokenTelemetry }: ContextMeterProps) {
20+
export default function ContextIndicator({ tokenTelemetry }: ContextMeterProps) {
2121
const activeTokens = tokenTelemetry?.activeTokens || 0;
2222
const percent = getTokenUsagePercent(tokenTelemetry);
2323
const usedRows = flattenUsageFields(tokenTelemetry?.usage);

packages/vscode-ide-companion/src/webview/components/InputPrompt.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ vi.mock("@/webview/components/SkillsTags", () => ({
2323
default: vi.fn(({ children }) => <div data-testid="skills-tags">{children}</div>),
2424
}));
2525

26-
vi.mock("@/webview/components/ContextMeter", () => ({
26+
vi.mock("@/webview/components/ContextIndicator", () => ({
2727
default: vi.fn(() => <div data-testid="context-meter" />),
2828
}));
2929

packages/vscode-ide-companion/src/webview/components/InputPrompt.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React, { useCallback, useEffect, useRef, useState } from "react";
22
import SkillsPanel from "@/webview/components/SkillsPanel";
33
import SkillsTags from "@/webview/components/SkillsTags";
4-
import ContextMeter from "@/webview/components/ContextMeter";
4+
import ContextIndicator from "@/webview/components/ContextIndicator";
55
import { PromptAttachments, usePromptAttachments } from "@/webview/components/PromptAttachments";
66
import type { ActiveEditor, EditingMessage, SkillInfo, TokenTelemetry } from "@/webview/types";
7-
import { FileCodeIcon, Send, Square } from "lucide-react";
7+
import { FileCodeIcon, Reply, Square } from "lucide-react";
88
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupTextarea } from "@/webview/components/ui/input-group";
99
import { Separator } from "@/webview/components/ui/separator";
1010
import { HoverCard, HoverCardContent, HoverCardTrigger } from "./ui/hover-card";
1111
import { cn } from "@/webview/lib/utils";
1212
import { Field, FieldGroup } from "./ui/field";
13+
import { Spinner } from "@/webview/components/ui/spinner";
1314

1415
export interface InputPromptProps {
1516
loading: boolean;
@@ -152,7 +153,6 @@ export default function InputPrompt({
152153
[handleSend, history, historyIdx, value, draftBeforeHistory]
153154
);
154155

155-
const isProcessing = loading;
156156
const hasContent = value.trim().length > 0 || attachments.length > 0;
157157

158158
return (
@@ -189,7 +189,7 @@ export default function InputPrompt({
189189
}}
190190
/>
191191
<Separator orientation="vertical" className="h-5 mt-1.5" />
192-
<ContextMeter tokenTelemetry={tokenTelemetry} />
192+
<ContextIndicator tokenTelemetry={tokenTelemetry} />
193193
<Separator orientation="vertical" className="h-5 mt-1.5" />
194194
{activeEditor && (
195195
<HoverCard openDelay={300} closeDelay={100}>
@@ -204,36 +204,37 @@ export default function InputPrompt({
204204
</HoverCardTrigger>
205205
<HoverCardContent className="text-xs space-y-1">
206206
<div className="font-medium truncate">{activeEditor.fileName.split("/").pop()}</div>
207-
<div className="text-muted-foreground">{activeEditor.fileName}</div>
207+
<p className="text-muted-foreground text-wrap break-all line-clamp-3">{activeEditor.fileName}</p>
208208
<div className="flex gap-3 text-muted-foreground">
209209
<span>{activeEditor.languageId}</span>
210210
<span>{activeEditor.lineCount} lines</span>
211211
</div>
212212
</HoverCardContent>
213213
</HoverCard>
214214
)}
215-
{isProcessing ? (
215+
{loading ? (
216216
<InputGroupButton
217-
variant="ghost"
217+
variant="secondary"
218218
size="icon-sm"
219-
className="ml-auto h-7 w-7"
219+
className="ml-auto group"
220220
onClick={onInterrupt}
221221
title="Stop"
222222
>
223-
<Square className="h-4 w-4" />
223+
<Square className="h-3 w-3 hidden fill-primary group-hover:block" strokeWidth={0} />
224+
<Spinner className="h-4 w-4 block group-hover:hidden text-primary" />
224225
</InputGroupButton>
225226
) : (
226227
<InputGroupButton
227228
variant="default"
228-
className={cn("h-7 w-7 ml-auto cursor-pointer", {
229-
"cursor-not-allowed!": !hasContent && !isProcessing,
229+
className={cn("ml-auto cursor-pointer", {
230+
"cursor-not-allowed!": !hasContent && !loading,
230231
})}
231232
onClick={handleSend}
232-
disabled={!hasContent && !isProcessing}
233+
disabled={!hasContent && !loading}
233234
title="Send"
234235
size="icon-sm"
235236
>
236-
<Send />
237+
<Reply className="rotate-x-180" />
237238
</InputGroupButton>
238239
)}
239240
</InputGroupAddon>

packages/vscode-ide-companion/src/webview/components/bubbles/SystemBubble.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/webview/c
33
import BubbleDot from "@/webview/components/bubbles/BubbleDot";
44
import { ChevronDown } from "lucide-react";
55
import { Button } from "../ui/button";
6+
import Markdown from "@/webview/components/markdown";
67

78
interface SystemBubbleProps {
89
content: string;
@@ -28,7 +29,9 @@ export default function SystemBubble({ content, meta, shouldConnect = false }: S
2829
</Button>
2930
</CollapsibleTrigger>
3031
<CollapsibleContent className="w-auto">
31-
<div className="mt-2 text-sm text-muted-foreground whitespace-pre-wrap p-2">{skillDescription}</div>
32+
<div className="mt-2 text-sm text-muted-foreground whitespace-pre-wrap p-2">
33+
<Markdown>{skillDescription}</Markdown>
34+
</div>
3235
</CollapsibleContent>
3336
</div>
3437
</Collapsible>

packages/vscode-ide-companion/src/webview/components/ui/button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Slot } from "radix-ui";
55
import { cn } from "@/webview/lib/utils";
66

77
const buttonVariants = cva(
8-
"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8+
"group/button inline-flex shrink-0 items-center cursor-pointer justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
99
{
1010
variants: {
1111
variant: {

0 commit comments

Comments
 (0)