feat(FN-2649): add themed scrollbar styles in task detail modal
- Add token-based scrollbar styling for .detail-body across Firefox and WebKit pseudo-elements - Scope agent log scrollbar rules to .detail-section--agent-log .agent-log-viewer-scroll to avoid selector target drift - Add TaskDetailModal CSS regression tests that assert scrollbar declarations for modal body and agent log containers - Introduce shared test helpers for robust selector/declaration matching in stylesheet assertions
This commit is contained in:
@@ -45,9 +45,28 @@
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
scrollbar-color: var(--border) transparent;
|
||||
scrollbar-width: thin;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.detail-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.detail-body::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.detail-body::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.detail-body::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-muted);
|
||||
}
|
||||
|
||||
/* When the Agent Log tab is active, switch to flex layout so the log section
|
||||
can stretch to fill the remaining space above the action bar.
|
||||
The detail-body itself should NOT scroll; the agent-log-viewer scrolls instead. */
|
||||
@@ -241,11 +260,13 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.agent-log-viewer-scroll {
|
||||
.detail-section--agent-log .agent-log-viewer-scroll {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-color: var(--border) transparent;
|
||||
scrollbar-width: thin;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
@@ -256,6 +277,23 @@
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-muted);
|
||||
}
|
||||
|
||||
.agent-log-model-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -104,6 +104,15 @@ function getCssRuleBlock(css: string, selector: string): string {
|
||||
return ruleMatch?.[1] ?? "";
|
||||
}
|
||||
|
||||
function escapeRegExp(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function expectBaseRule(css: string, selector: string, declaration: string): void {
|
||||
const pattern = new RegExp(`${escapeRegExp(selector)}\\s*\\{[^}]*${escapeRegExp(declaration)}`);
|
||||
expect(pattern.test(css)).toBe(true);
|
||||
}
|
||||
|
||||
function readDashboardStylesSource(): string {
|
||||
return loadAllAppCss();
|
||||
}
|
||||
@@ -119,6 +128,26 @@ describe("TaskDetailModal", () => {
|
||||
localStorage.removeItem("fn.authToken");
|
||||
});
|
||||
|
||||
it("styles detail-body scrollbar rules", () => {
|
||||
const css = loadAllAppCss();
|
||||
|
||||
expectBaseRule(css, ".detail-body", "scrollbar-color: var(--border) transparent;");
|
||||
expectBaseRule(css, ".detail-body", "scrollbar-width: thin;");
|
||||
expectBaseRule(css, ".detail-body::-webkit-scrollbar", "width: 6px;");
|
||||
expectBaseRule(css, ".detail-body::-webkit-scrollbar-track", "background: transparent;");
|
||||
expectBaseRule(css, ".detail-body::-webkit-scrollbar-thumb", "background: var(--border);");
|
||||
expectBaseRule(css, ".detail-body::-webkit-scrollbar-thumb:hover", "background: var(--text-muted);");
|
||||
});
|
||||
|
||||
it("styles agent log viewer scroll container scrollbar rules", () => {
|
||||
const css = loadAllAppCss();
|
||||
|
||||
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll", "scrollbar-color: var(--border) transparent;");
|
||||
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll", "scrollbar-width: thin;");
|
||||
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar", "width: 6px;");
|
||||
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar-thumb", "background: var(--border);");
|
||||
});
|
||||
|
||||
it("renders markdown-body without detail-prompt class when prompt exists", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
|
||||
Reference in New Issue
Block a user