Align chat toolbar states and thread view spacing

This commit is contained in:
murashit 2026-05-28 11:10:04 +09:00
parent 9314884799
commit 6f9ca853a0
4 changed files with 43 additions and 9 deletions

View file

@ -96,7 +96,7 @@ function Toolbar({ model, actions }: { model: ToolbarViewModel; actions: Toolbar
<ToolbarIconButton
icon="history"
label={model.historyOpen ? "Hide thread list" : "Show thread list"}
className={`codex-panel__history-toggle ${model.historyOpen ? "is-active" : ""}`}
className="codex-panel__history-toggle"
aria-pressed={model.historyOpen ? "true" : "false"}
onClick={actions.toggleHistory}
/>
@ -133,7 +133,7 @@ function ToolbarIconButton({
{...props}
icon={icon}
label={label}
className={["clickable-icon nav-action-button codex-panel-ui__toolbar-control", className ?? ""].filter(Boolean).join(" ")}
className={["clickable-icon codex-panel-ui__toolbar-control", className ?? ""].filter(Boolean).join(" ")}
/>
);
}
@ -197,7 +197,7 @@ function StatusButton({ model, actions }: { model: ToolbarViewModel; actions: To
return (
<button
className={[
"clickable-icon nav-action-button codex-panel-ui__toolbar-control codex-panel__status-dot",
"clickable-icon codex-panel-ui__toolbar-control codex-panel__status-dot",
`codex-panel__status-dot--${model.statusState}`,
alertClass,
model.statusPanelOpen ? "is-active" : "",

View file

@ -7,6 +7,10 @@
--codex-panel-radius-pill: 999px;
--codex-panel-size-icon-s: var(--icon-s, 16px);
--codex-panel-size-icon-xs: var(--icon-xs, 14px);
--codex-panel-size-clickable-icon: var(
--clickable-icon-size,
var(--icon-container-size, calc(var(--codex-panel-control-icon-size) + var(--codex-panel-control-gap) * 2))
);
--codex-panel-size-nav-item: var(--nav-item-size, 28px);
--codex-panel-size-settings-archived-list-max-height: 360px;
--codex-panel-size-settings-hook-list-max-height: 420px;
@ -123,12 +127,6 @@
flex: 0 0 auto;
}
.codex-panel-threads__toolbar-actions {
display: flex;
align-items: center;
gap: var(--codex-panel-toolbar-button-gap);
}
.codex-panel-threads__list {
display: flex;
flex: 1 1 auto;
@ -362,6 +360,25 @@
border-radius: var(--codex-panel-control-radius);
}
.codex-panel-ui__toolbar-control:hover,
.codex-panel-ui__toolbar-control:focus-visible,
.codex-panel-ui__toolbar-control:active {
background: var(--background-modifier-hover);
box-shadow: none;
color: var(--icon-color);
}
.codex-panel-ui__toolbar-control:active svg {
color: var(--icon-color);
stroke: currentcolor;
}
.codex-panel-ui__toolbar-control:focus:not(:hover):not(:focus-visible) {
background: transparent;
box-shadow: none;
color: var(--icon-color);
}
.codex-panel-ui__icon-button {
--icon-size: var(--codex-panel-control-icon-size);
--icon-stroke: var(--icon-m-stroke-width, 1.75px);
@ -381,6 +398,10 @@
.codex-panel-threads__toolbar-button {
--icon-size: var(--codex-panel-control-icon-size);
--icon-stroke: var(--icon-m-stroke-width, 1.75px);
width: var(--codex-panel-size-clickable-icon);
height: var(--codex-panel-size-clickable-icon);
padding: var(--clickable-icon-padding, var(--codex-panel-control-gap));
border-radius: var(--clickable-icon-radius, var(--codex-panel-control-radius));
}
.codex-panel-threads__row-button {

View file

@ -302,13 +302,19 @@ describe("toolbar renderer decisions", () => {
expect(statusButton?.tagName).toBe("BUTTON");
expect(statusButton?.getAttribute("role")).toBeNull();
expect(statusButton?.getAttribute("aria-label")).toBe("Show connection status");
expect(statusButton?.classList.contains("nav-action-button")).toBe(false);
expect(statusButton?.classList.contains("clickable-icon")).toBe(true);
const historyButton = parent.querySelector<HTMLButtonElement>(".codex-panel__history-toggle");
expect(historyButton?.getAttribute("aria-label")).toBe("Show thread list");
expect(historyButton?.classList.contains("nav-action-button")).toBe(false);
expect(historyButton?.classList.contains("clickable-icon")).toBe(true);
historyButton?.click();
expect(toggleHistory).toHaveBeenCalled();
const autoReviewButton = parent.querySelector<HTMLButtonElement>(".codex-panel__auto-review-toggle");
expect(autoReviewButton?.getAttribute("aria-label")).toBe("Toggle auto-review");
expect(autoReviewButton?.getAttribute("aria-pressed")).toBe("false");
expect(autoReviewButton?.classList.contains("nav-action-button")).toBe(false);
expect(autoReviewButton?.classList.contains("clickable-icon")).toBe(true);
autoReviewButton?.click();
expect(toggleAutoReview).toHaveBeenCalled();
@ -320,6 +326,7 @@ describe("toolbar renderer decisions", () => {
parent.empty();
renderToolbar(parent, toolbarModel({ historyOpen: true, statusPanelOpen: true }), toolbarActions());
expect(parent.querySelector(".codex-panel__history-toggle")?.getAttribute("aria-label")).toBe("Hide thread list");
expect(parent.querySelector(".codex-panel__history-toggle")?.classList.contains("is-active")).toBe(false);
expect(parent.querySelector(".codex-panel__status-dot")?.getAttribute("aria-label")).toBe("Hide connection status");
expect(parent.querySelector(".codex-panel__runtime-model")?.getAttribute("aria-label")).toBe("Change model and reasoning effort");
});

View file

@ -28,6 +28,7 @@ describe("threads view CSS", () => {
});
it("keeps toolbar hover color separate from row action hover color", () => {
const toolbarButton = /\.codex-panel-threads__toolbar-button \{(?<body>[^}]+)\}/.exec(styles)?.groups?.["body"] ?? "";
const toolbarHover =
/\.codex-panel-threads__toolbar-button:hover,\n\.codex-panel-threads__toolbar-button:focus-visible \{(?<body>[^}]+)\}/.exec(styles)
?.groups?.["body"] ?? "";
@ -39,6 +40,11 @@ describe("threads view CSS", () => {
styles,
)?.groups?.["body"] ?? "";
expect(styles).not.toContain(".codex-panel-threads__toolbar-actions {");
expect(styles).toContain("--codex-panel-size-clickable-icon");
expect(toolbarButton).toContain("width: var(--codex-panel-size-clickable-icon)");
expect(toolbarButton).toContain("height: var(--codex-panel-size-clickable-icon)");
expect(toolbarButton).toContain("padding: var(--clickable-icon-padding, var(--codex-panel-control-gap))");
expect(toolbarHover).toContain("background: var(--background-modifier-hover)");
expect(toolbarHover).toContain("color: var(--icon-color)");
expect(toolbarHover).not.toContain("var(--icon-color-active)");