mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
style(vscode-ide-companion/ui): improve component styling and layout
This commit is contained in:
@@ -20,7 +20,7 @@ export const InterruptedMessage: React.FC<InterruptedMessageProps> = ({
|
||||
style={{
|
||||
width: '100%',
|
||||
alignItems: 'flex-start',
|
||||
paddingLeft: '30px', // keep alignment with other assistant messages, but no status icon
|
||||
paddingLeft: '10px', // keep alignment with other assistant messages, but no status icon
|
||||
position: 'relative',
|
||||
paddingTop: '8px',
|
||||
paddingBottom: '8px',
|
||||
|
||||
@@ -42,7 +42,8 @@ const parseTodoEntries = (textOutputs: string[]): TodoEntry[] => {
|
||||
const lines = text.split(/\r?\n/);
|
||||
const entries: TodoEntry[] = [];
|
||||
|
||||
const todoRe = /^(?:\s*(?:[-*]|\d+[.)])\s*)?\[( |x|X|-)\]\s+(.*)$/;
|
||||
// Accept [ ], [x]/[X] and in-progress markers [-] or [*]
|
||||
const todoRe = /^(?:\s*(?:[-*]|\d+[.)])\s*)?\[( |x|X|-|\*)\]\s+(.*)$/;
|
||||
for (const line of lines) {
|
||||
const m = line.match(todoRe);
|
||||
if (m) {
|
||||
@@ -51,7 +52,7 @@ const parseTodoEntries = (textOutputs: string[]): TodoEntry[] => {
|
||||
const status: EntryStatus =
|
||||
mark === 'x' || mark === 'X'
|
||||
? 'completed'
|
||||
: mark === '-'
|
||||
: mark === '-' || mark === '*'
|
||||
? 'in_progress'
|
||||
: 'pending';
|
||||
if (title) {
|
||||
|
||||
@@ -42,7 +42,8 @@ const parsePlanEntries = (textOutputs: string[]): PlanEntry[] => {
|
||||
const lines = text.split(/\r?\n/);
|
||||
const entries: PlanEntry[] = [];
|
||||
|
||||
const todoRe = /^(?:\s*(?:[-*]|\d+[.)])\s*)?\[( |x|X|-)\]\s+(.*)$/;
|
||||
// Accept [ ], [x]/[X] and in-progress markers [-] or [*]
|
||||
const todoRe = /^(?:\s*(?:[-*]|\d+[.)])\s*)?\[( |x|X|-|\*)\]\s+(.*)$/;
|
||||
for (const line of lines) {
|
||||
const m = line.match(todoRe);
|
||||
if (m) {
|
||||
@@ -51,7 +52,7 @@ const parsePlanEntries = (textOutputs: string[]): PlanEntry[] => {
|
||||
const status: EntryStatus =
|
||||
mark === 'x' || mark === 'X'
|
||||
? 'completed'
|
||||
: mark === '-'
|
||||
: mark === '-' || mark === '*'
|
||||
? 'in_progress'
|
||||
: 'pending';
|
||||
if (title) {
|
||||
|
||||
@@ -33,7 +33,7 @@ export const CheckboxDisplay: React.FC<CheckboxDisplayProps> = ({
|
||||
// Pseudo-elements do not reliably render on <input> in Chromium (VS Code webviews),
|
||||
// which caused the missing icon. This version is font-free and uses borders.
|
||||
const showCheck = !!checked && !indeterminate;
|
||||
const showDash = !!indeterminate;
|
||||
const showInProgress = !!indeterminate;
|
||||
|
||||
return (
|
||||
<span
|
||||
@@ -66,16 +66,18 @@ export const CheckboxDisplay: React.FC<CheckboxDisplayProps> = ({
|
||||
].join(' ')}
|
||||
/>
|
||||
) : null}
|
||||
{showDash ? (
|
||||
{showInProgress ? (
|
||||
<span
|
||||
aria-hidden
|
||||
className={[
|
||||
'absolute block',
|
||||
'absolute inline-block',
|
||||
'left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2',
|
||||
'w-2 h-[2px] rounded-sm',
|
||||
'bg-[#e1c08d]',
|
||||
// Use a literal star; no icon font needed
|
||||
'text-[11px] leading-none text-[#e1c08d] select-none',
|
||||
].join(' ')}
|
||||
/>
|
||||
>
|
||||
*
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
=========================== */
|
||||
:root {
|
||||
/* Qwen Brand Colors */
|
||||
--app-qwen-orange: #615fff;
|
||||
--app-qwen-theme: #615fff;
|
||||
--app-qwen-clay-button-orange: #4f46e5;
|
||||
--app-qwen-ivory: #f5f5ff;
|
||||
--app-qwen-slate: #141420;
|
||||
@@ -46,7 +46,7 @@
|
||||
--app-input-placeholder-foreground: var(--vscode-input-placeholderForeground);
|
||||
--app-input-secondary-background: var(--vscode-menu-background);
|
||||
/* Input Highlight (focus ring/border) */
|
||||
--app-input-highlight: var(--app-qwen-orange);
|
||||
--app-input-highlight: var(--app-qwen-theme);
|
||||
|
||||
/* Code Highlighting */
|
||||
--app-code-background: var(--vscode-textCodeBlock-background, rgba(0, 0, 0, 0.05));
|
||||
@@ -211,7 +211,7 @@ button {
|
||||
}
|
||||
|
||||
.input-field:focus {
|
||||
border-color: var(--app-qwen-orange);
|
||||
border-color: var(--app-qwen-theme);
|
||||
}
|
||||
|
||||
.input-field:disabled {
|
||||
@@ -355,7 +355,7 @@ button {
|
||||
=========================== */
|
||||
.permission-request-card {
|
||||
background: var(--app-input-background);
|
||||
border: 1px solid var(--app-qwen-orange);
|
||||
border: 1px solid var(--app-qwen-theme);
|
||||
border-radius: var(--corner-radius-medium);
|
||||
margin: var(--app-spacing-medium) 0;
|
||||
margin-bottom: var(--app-spacing-xlarge);
|
||||
@@ -500,18 +500,10 @@ button {
|
||||
}
|
||||
|
||||
.permission-option.selected {
|
||||
border-color: var(--app-qwen-orange);
|
||||
border-color: var(--app-qwen-theme);
|
||||
background: rgba(97, 95, 255, 0.1);
|
||||
}
|
||||
|
||||
.permission-option.allow {
|
||||
/* Allow options */
|
||||
}
|
||||
|
||||
.permission-option.reject {
|
||||
/* Reject options */
|
||||
}
|
||||
|
||||
.permission-radio {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -540,7 +532,7 @@ button {
|
||||
|
||||
.permission-option.selected .permission-option-number {
|
||||
color: var(--app-qwen-ivory);
|
||||
background-color: var(--app-qwen-orange);
|
||||
background-color: var(--app-qwen-theme);
|
||||
}
|
||||
|
||||
.permission-always-badge {
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
.composer-form:focus-within {
|
||||
/* match existing highlight behavior */
|
||||
border-color: var(--app-input-highlight);
|
||||
box-shadow: 0 1px 2px color-mix(in srgb, var(--app-input-highlight), transparent 80%);
|
||||
box-shadow: 0 1px 2px
|
||||
color-mix(in srgb, var(--app-input-highlight), transparent 80%);
|
||||
}
|
||||
|
||||
/* Composer: input editable area */
|
||||
@@ -62,7 +63,11 @@
|
||||
font-size: var(--vscode-chat-font-size, 13px);
|
||||
color: var(--app-input-foreground);
|
||||
}
|
||||
.composer-input:empty:before {
|
||||
/* Show placeholder when truly empty OR when flagged as empty via data attribute.
|
||||
The data attribute is needed because some browsers insert a <br> in
|
||||
contentEditable, which breaks :empty matching. */
|
||||
.composer-input:empty:before,
|
||||
.composer-input[data-empty='true']::before {
|
||||
content: attr(data-placeholder);
|
||||
color: var(--app-input-placeholder-foreground);
|
||||
pointer-events: none;
|
||||
@@ -76,7 +81,7 @@
|
||||
outline: none;
|
||||
}
|
||||
.composer-input:disabled,
|
||||
.composer-input[contenteditable="false"] {
|
||||
.composer-input[contenteditable='false'] {
|
||||
color: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@@ -105,7 +110,8 @@
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
.btn-text-compact > svg {
|
||||
height: 1em; /* match font size */
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.btn-text-compact > span {
|
||||
@@ -119,7 +125,9 @@
|
||||
}
|
||||
|
||||
@media screen and (max-width: 300px) {
|
||||
.btn-text-compact > svg { display: none; }
|
||||
.btn-text-compact > svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Icon-only button, compact square (26x26) */
|
||||
@@ -173,3 +181,16 @@
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
Utilities
|
||||
=========================== */
|
||||
@layer utilities {
|
||||
/* Multi-line clamp with ellipsis (Chromium-based webview supported) */
|
||||
.q-line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user