Skip to content

Commit f1fadc6

Browse files
committed
Polish agent scrolling, search focus, and themed panels
Refine the ACP session auto-scroll behavior so generated messages keep the pane pinned to the bottom only while auto-scroll is enabled. Track explicit user scroll-up intent from wheel, touch, pointer, and keyboard input, restore auto-scroll when the user reaches the bottom again, and observe the rendered message container so late layout changes still scroll correctly. Update the terminal theme integration to derive xterm background, foreground, cursor, and selection colors from the active CSS theme variables. Reapply the terminal theme when the root theme styles change, clean up the observer during disconnects and unmounts, and align terminal fallback colors with the rest of the themed UI. Keep the editor search panel active and focused when navigating matches or clearing the search text. Move search container layout out of inline renderer styles and into CSS, switch the panel positioning to sticky, and tune highlight colors for selected and unselected matches. Bring empty panes, panel picker actions, ACP input controls, terminal empty actions, and References Peek hover styling closer to the shared theme system. Replace hard-coded colors with theme variables, add consistent focus-visible states, and simplify hover/active treatment across these small controls.
1 parent 3aed4a6 commit f1fadc6

12 files changed

Lines changed: 347 additions & 123 deletions

File tree

anycode-base/src/editor.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,9 +1421,11 @@ export class AnycodeEditor {
14211421
if (currentMatches.length === 0) return;
14221422
this.renderer.removeSelectedHighlight(this.search);
14231423
this.search.selectPrev();
1424+
this.search.setFocused(true);
14241425
this.search.setNeedsFocus(true);
14251426
this.renderer.focus(this.getEditorState(), this.search.getSelectedMatch()?.line);
14261427
this.renderer.updateSearchHighlights(this.search);
1428+
this.renderer.focusSearchInput();
14271429
return;
14281430
}
14291431

@@ -1434,9 +1436,11 @@ export class AnycodeEditor {
14341436
if (currentMatches.length === 0) return;
14351437
this.renderer.removeSelectedHighlight(this.search);
14361438
this.search.selectNext();
1439+
this.search.setFocused(true);
14371440
this.search.setNeedsFocus(true);
14381441
this.renderer.focus(this.getEditorState(), this.search.getSelectedMatch()?.line);
14391442
this.renderer.updateSearchHighlights(this.search);
1443+
this.renderer.focusSearchInput();
14401444
return;
14411445
}
14421446

@@ -1467,15 +1471,17 @@ export class AnycodeEditor {
14671471
if (!pattern) {
14681472
this.renderer.updateSearchLabel('');
14691473
this.search.clear();
1470-
this.search.setActive(false);
1471-
this.search.setNeedsFocus(false);
1474+
this.search.setActive(true);
1475+
this.search.setFocused(true);
1476+
this.search.setNeedsFocus(true);
14721477
return;
14731478
}
14741479

14751480
// Perform search
14761481
const matches = this.getEditorState().code.search(pattern);
14771482
this.search.clear();
14781483
this.search.setActive(true);
1484+
this.search.setFocused(true);
14791485
this.search.setMatches(matches);
14801486
this.search.setPattern(pattern);
14811487

anycode-base/src/renderer/SearchRenderer.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ export class SearchRenderer {
4444
// Create a container for the search UI
4545
this.searchContainer = document.createElement('div');
4646
this.searchContainer.className = 'search';
47-
this.searchContainer.style.display = 'flex';
48-
this.searchContainer.style.flexDirection = 'column';
49-
this.searchContainer.style.position = 'fixed';
5047

5148
// Create a search textarea field for multiline search (full width)
5249
const inputField = document.createElement('textarea');

anycode-base/src/styles.css

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,14 @@
306306
}*/
307307

308308
.search {
309-
position: absolute;
309+
position: sticky;
310+
display: flex;
311+
flex-direction: column;
312+
align-self: flex-start;
310313
padding: 0.7rem;
311-
top: 0;
312-
right: 0;
313-
margin-right: 1.3rem;
314-
margin-top: 0.7rem;
314+
top: 3px;
315+
right: 3px;
316+
margin: 0;
315317
min-width: 200px;
316318
max-width: 40vw;
317319
z-index: 10000;
@@ -323,8 +325,6 @@
323325
cursor: pointer;
324326
border: 1px solid #555;
325327
background-color: var(--background-color);
326-
display: flex;
327-
flex-direction: column;
328328
}
329329

330330
.search input,
@@ -339,7 +339,6 @@
339339
width: 100%;
340340
box-sizing: border-box;
341341
/* margin-left: 10px; */
342-
color: white;
343342
line-height: 1.4;
344343
padding: 2px 0;
345344
}
@@ -417,10 +416,10 @@
417416

418417

419418
.highlight {
420-
background: rgba(179, 179, 179, 0.406);
421-
/* border-radius: 3px; */
419+
background: rgba(210, 210, 210, 0.4);
420+
422421
}
423422

424423
.highlight.selected {
425-
background: rgba(210, 210, 210, 0.9);
424+
background: rgba(179, 179, 179, 0.9);
426425
}

anycode/components/agent/AcpEmptyPane.css

Lines changed: 98 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,62 @@
2323
}
2424

2525
.acp-pane-empty-action {
26-
background: rgba(255, 255, 255, 0.03);
26+
appearance: none;
27+
-webkit-appearance: none;
28+
box-sizing: border-box;
29+
border: 1px solid var(--theme-border, #4a4a4a);
30+
background: var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)));
31+
color: var(--theme-tab-foreground, #b2b2b2);
2732
cursor: pointer;
2833
font-size: 12px;
2934
font-weight: 450;
30-
padding: 7px 12px;
35+
padding: 8px 10px;
3136
border-radius: 8px;
32-
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
3337
line-height: 1.1;
34-
max-width: 100%;
35-
overflow: hidden;
36-
text-overflow: ellipsis;
38+
flex: 1 1 140px;
39+
max-width: 160px;
40+
text-align: center;
3741
white-space: nowrap;
3842
}
3943

4044
.acp-pane-empty-action:hover {
41-
background-color: rgba(255, 255, 255, 0.08);
42-
border-color: rgba(255, 255, 255, 0.22);
43-
color: #ffffff;
45+
background: color-mix(
46+
in srgb,
47+
var(--theme-accent-background, #007acc) 12%,
48+
var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)))
49+
);
50+
color: var(--theme-foreground, var(--foreground-color, #f0f0f0));
51+
border-color: color-mix(
52+
in srgb,
53+
var(--theme-accent-background, #007acc) 35%,
54+
var(--theme-border, #4a4a4a)
55+
);
56+
}
57+
58+
.acp-pane-empty-action:focus {
59+
outline: none;
60+
}
61+
62+
.acp-pane-empty-action:focus-visible {
63+
outline: 2px solid var(--theme-accent-background, #007acc);
64+
outline-offset: 2px;
65+
background: color-mix(
66+
in srgb,
67+
var(--theme-accent-background, #007acc) 16%,
68+
var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)))
69+
);
70+
color: var(--theme-foreground, var(--foreground-color, #f0f0f0));
71+
}
72+
73+
.acp-pane-empty-action:active {
74+
transform: translateY(1px);
75+
}
76+
77+
.acp-pane-empty-action,
78+
.acp-pane-settings-btn {
79+
max-width: 100%;
80+
overflow: hidden;
81+
text-overflow: ellipsis;
4482
}
4583

4684
.acp-pane-opened-agents {
@@ -51,7 +89,7 @@
5189

5290
.acp-pane-opened-agents-title {
5391
font-size: 12px;
54-
color: #c8ccd2;
92+
color: var(--theme-muted-foreground, var(--text-color-secondary, #8f8f8f));
5593
margin-bottom: 5px;
5694
letter-spacing: 0.01em;
5795
font-weight: 500;
@@ -65,9 +103,13 @@
65103
}
66104

67105
.acp-pane-opened-agent {
68-
border-color: rgba(112, 233, 189, 0.38);
69-
background: rgba(112, 233, 189, 0.1);
70-
color: #b8f0dc;
106+
border-color: color-mix(in srgb, var(--theme-accent-background, #007acc) 38%, var(--theme-border, #4a4a4a));
107+
background: color-mix(
108+
in srgb,
109+
var(--theme-accent-background, #007acc) 10%,
110+
var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)))
111+
);
112+
color: var(--theme-accent-background, var(--theme-foreground, #7ec8ff));
71113
}
72114

73115
.acp-pane-opened-agent-item {
@@ -80,7 +122,7 @@
80122
.acp-pane-close-button {
81123
opacity: 0;
82124
pointer-events: none;
83-
color: #8ea0ad;
125+
color: var(--theme-muted-foreground, var(--text-color-secondary, #8ea0ad));
84126
font-size: 20px;
85127
line-height: 1;
86128
width: 20px;
@@ -98,7 +140,7 @@
98140
}
99141

100142
.acp-pane-close-button:hover {
101-
color: #eef7ff;
143+
color: var(--theme-accent-background, var(--theme-foreground, #eef7ff));
102144
background: transparent;
103145
}
104146

@@ -109,36 +151,67 @@
109151
}
110152

111153
.acp-pane-start-agents-title {
112-
color: #8f8f8f;
154+
color: var(--theme-muted-foreground, var(--text-color-secondary, #8f8f8f));
113155
text-transform: uppercase;
114156
font-size: 12px;
115157
letter-spacing: 0.08em;
116158
margin-bottom: 6px;
117159
}
118160

119161
.acp-pane-settings-btn {
120-
border: 1px solid rgba(255, 255, 255, 0.12);
121-
background: rgba(255, 255, 255, 0.03);
122-
color: var(--text-color, #cfd3d8);
162+
appearance: none;
163+
-webkit-appearance: none;
164+
box-sizing: border-box;
165+
border: 1px solid var(--theme-border, #4a4a4a);
166+
background: var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)));
167+
color: var(--theme-tab-foreground, #b2b2b2);
123168
font-size: 12px;
124169
line-height: 1;
125-
padding: 7px 12px;
126-
border-radius: 10px;
170+
padding: 8px 10px;
171+
border-radius: 8px;
127172
cursor: pointer;
128-
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
173+
width: min(140px, 100%);
129174
}
130175

131176
.acp-pane-settings-btn:hover {
132-
background-color: rgba(255, 255, 255, 0.08);
133-
border-color: rgba(255, 255, 255, 0.22);
134-
color: #ffffff;
177+
background: color-mix(
178+
in srgb,
179+
var(--theme-accent-background, #007acc) 12%,
180+
var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)))
181+
);
182+
color: var(--theme-foreground, var(--foreground-color, #f0f0f0));
183+
border-color: color-mix(
184+
in srgb,
185+
var(--theme-accent-background, #007acc) 35%,
186+
var(--theme-border, #4a4a4a)
187+
);
188+
}
189+
190+
.acp-pane-settings-btn:focus {
191+
outline: none;
192+
}
193+
194+
.acp-pane-settings-btn:focus-visible {
195+
outline: 2px solid var(--theme-accent-background, #007acc);
196+
outline-offset: 2px;
197+
background: color-mix(
198+
in srgb,
199+
var(--theme-accent-background, #007acc) 16%,
200+
var(--theme-tab-background, var(--theme-background, var(--background-color, #242424)))
201+
);
202+
color: var(--theme-foreground, var(--foreground-color, #f0f0f0));
203+
}
204+
205+
.acp-pane-settings-btn:active {
206+
transform: translateY(1px);
135207
}
136208

137209
.acp-pane-settings-wrap {
138210
margin-top: 10px;
139211
padding-top: 10px;
140212
display: flex;
141213
justify-content: center;
214+
width: 100%;
142215
}
143216

144217
@media (max-width: 768px) {

anycode/components/agent/AcpInput.css

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,6 @@
7878
justify-content: center;
7979
cursor: pointer;
8080
border-radius: 4px;
81-
transition: color 0.2s, background-color 0.2s;
82-
}
83-
84-
.acp-input-toggle-btn:hover {
85-
color: var(--text-color, #fff);
86-
background-color: rgba(255, 255, 255, 0.1);
8781
}
8882

8983
.acp-input-floating-expand-btn {
@@ -97,18 +91,13 @@
9791
display: flex;
9892
align-items: center;
9993
justify-content: center;
100-
color: var(--text-color, #ccc);
101-
background: rgba(45, 45, 45, 0.5);
94+
color: var(--theme-accent-background, #3c3c3c);
95+
background: rgba(45, 45, 45, 0.25);
10296
backdrop-filter: blur(2px);
10397
-webkit-backdrop-filter: blur(2px);
10498
z-index: 2;
10599
}
106100

107-
.acp-input-floating-expand-btn:hover {
108-
background-color: var(--hover-bg, #2a2a2a);
109-
transform: translateY(-1px);
110-
}
111-
112101
.acp-input-controls-row {
113102
display: flex;
114103
align-items: center;
@@ -219,7 +208,7 @@
219208

220209
.acp-send-btn,
221210
.acp-stop-prompt-btn {
222-
background: rgba(45, 45, 45, 0.5);
211+
background: rgba(45, 45, 45, 0.25);
223212
backdrop-filter: blur(2px);
224213
-webkit-backdrop-filter: blur(2px);
225214
color: var(--text-color, #fff);
@@ -236,7 +225,10 @@
236225
height: 36px;
237226
flex-shrink: 0;
238227
outline: none;
239-
transition: background-color 0.2s, transform 0.2s, opacity 0.2s, color 0.2s;
228+
}
229+
230+
.acp-send-btn {
231+
color: var(--theme-accent-background, #3c3c3c);
240232
}
241233

242234
.acp-send-btn:focus,
@@ -253,11 +245,7 @@
253245
height: 20px;
254246
}
255247

256-
.acp-send-btn:hover:not(:disabled),
257-
.acp-stop-prompt-btn:hover:not(:disabled) {
258-
background-color: var(--hover-bg, #2a2a2a);
259-
transform: translateY(-1px);
260-
}
248+
261249

262250
.acp-send-btn:disabled,
263251
.acp-stop-prompt-btn:disabled {

anycode/components/agent/AcpSession.css

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,13 @@
4242
align-items: center;
4343
justify-content: center;
4444
cursor: pointer;
45-
color: var(--text-color, #ccc);
46-
background: rgba(45, 45, 45, 0.5);
45+
color: var(--theme-accent-background, #3c3c3c);
46+
background: rgba(45, 45, 45, 0.25);
4747
backdrop-filter: blur(2px);
4848
-webkit-backdrop-filter: blur(2px);
49-
transition: background-color 0.2s, transform 0.2s, opacity 0.2s, color 0.2s;
5049
z-index: 1;
5150
}
5251

53-
.acp-scroll-to-bottom-btn:hover {
54-
background-color: var(--hover-bg, #2a2a2a);
55-
transform: translateY(-1px);
56-
}
57-
5852
.acp-scroll-to-bottom-btn:focus,
5953
.acp-scroll-to-bottom-btn:active {
6054
outline: none;

0 commit comments

Comments
 (0)