style: refine agent composer focus feedback
This commit is contained in:
@@ -2097,6 +2097,21 @@ details[open] > summary > .disclosure-accordion-indicator {
|
|||||||
background-image: none;
|
background-image: none;
|
||||||
backdrop-filter: none;
|
backdrop-filter: none;
|
||||||
-webkit-backdrop-filter: none;
|
-webkit-backdrop-filter: none;
|
||||||
|
transition: transform 160ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 160ms ease;
|
||||||
|
}
|
||||||
|
/* Keep the border neutral and express focus as a small elevation change. */
|
||||||
|
.agent-panel-shell[data-agent-presentation] .agent-panel-input-form:focus-within {
|
||||||
|
border-color: #e4e4e7;
|
||||||
|
box-shadow: 0 4px 10px rgb(15 23 42 / 0.08), 0 18px 36px -14px rgb(15 23 42 / 0.22);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.agent-panel-shell[data-agent-presentation] .agent-panel-input-form {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
.agent-panel-shell[data-agent-presentation] .agent-panel-input-form:focus-within {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.agent-panel-shell[data-agent-presentation] .agent-panel-input-body {
|
.agent-panel-shell[data-agent-presentation] .agent-panel-input-body {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -10,22 +10,29 @@ test.beforeEach(async ({ page }) => {
|
|||||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Agent composer keeps one thin focus boundary without an outer blue ring", async ({ page }) => {
|
test("Agent composer uses a neutral shadow instead of a blue focus border", async ({ page }) => {
|
||||||
|
await page.emulateMedia({ reducedMotion: "no-preference" });
|
||||||
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
|
await page.getByRole("button", { name: /展开 Agent 助手面板/ }).click();
|
||||||
const form = page.locator("form.agent-panel-control");
|
const form = page.locator("form.agent-panel-control");
|
||||||
const textarea = page.getByPlaceholder(/输入调度问题/);
|
const textarea = page.getByRole("textbox", { name: "询问供水问题,或描述需要处理的任务" });
|
||||||
const restingShadow = await form.evaluate((element) => getComputedStyle(element).boxShadow);
|
const restingShadow = await form.evaluate((element) => getComputedStyle(element).boxShadow);
|
||||||
|
const restingBorder = await form.evaluate((element) => getComputedStyle(element).borderColor);
|
||||||
expect(restingShadow).not.toBe("none");
|
expect(restingShadow).not.toBe("none");
|
||||||
const restingBox = await form.boundingBox();
|
const restingBox = await form.boundingBox();
|
||||||
await textarea.click();
|
await textarea.click();
|
||||||
await expectThemeColor(form, "border-color", "--action-blue-hover");
|
await expect(form).toHaveCSS("border-color", restingBorder);
|
||||||
await expect(form).toHaveCSS("border-width", "1px");
|
await expect(form).toHaveCSS("border-width", "1px");
|
||||||
await expect(form).toHaveCSS("box-shadow", restingShadow);
|
await expect(form).not.toHaveCSS("box-shadow", restingShadow);
|
||||||
|
await expect(form).toHaveCSS("transform", "matrix(1, 0, 0, 1, 0, -2)");
|
||||||
await expect(textarea).toHaveCSS("outline-style", "none");
|
await expect(textarea).toHaveCSS("outline-style", "none");
|
||||||
expect(await form.boundingBox()).toEqual(restingBox);
|
const liftedBox = await form.boundingBox();
|
||||||
|
expect(liftedBox?.x).toBeCloseTo(restingBox!.x, 1);
|
||||||
|
expect(liftedBox?.y).toBeCloseTo(restingBox!.y - 2, 1);
|
||||||
|
expect(liftedBox?.width).toBeCloseTo(restingBox!.width, 1);
|
||||||
|
expect(liftedBox?.height).toBeCloseTo(restingBox!.height, 1);
|
||||||
await page.keyboard.press("Tab");
|
await page.keyboard.press("Tab");
|
||||||
await textarea.focus();
|
await textarea.focus();
|
||||||
await expectThemeColor(form, "border-color", "--action-blue-hover");
|
await expect(form).toHaveCSS("border-color", restingBorder);
|
||||||
const focusedBox = await form.boundingBox();
|
const focusedBox = await form.boundingBox();
|
||||||
await page.screenshot({
|
await page.screenshot({
|
||||||
path: "test-results/form-focus/agent-focused.png",
|
path: "test-results/form-focus/agent-focused.png",
|
||||||
@@ -89,16 +96,20 @@ test("borderless selects and choice controls keep one theme keyboard focus indic
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const width of [320, 375]) {
|
for (const width of [320, 375]) {
|
||||||
test(`mobile composer owns a single inset focus stroke at ${width}px`, async ({ page }) => {
|
test(`mobile composer keeps a neutral focus treatment at ${width}px`, async ({ page }) => {
|
||||||
await page.setViewportSize({ width, height: 844 });
|
await page.setViewportSize({ width, height: 844 });
|
||||||
await page.getByRole("button", { name: "打开 Agent 面板" }).click();
|
await page.getByRole("button", { name: "打开 Agent 面板" }).click();
|
||||||
const textarea = page.getByPlaceholder(/输入调度问题/);
|
const textarea = page.getByRole("textbox", { name: "询问供水问题,或描述需要处理的任务" });
|
||||||
|
const material = page.locator("form.agent-panel-input-form");
|
||||||
|
const restingBorder = await material.evaluate((element) => getComputedStyle(element).borderColor);
|
||||||
|
const restingShadow = await material.evaluate((element) => getComputedStyle(element).boxShadow);
|
||||||
|
const restingBox = await material.boundingBox();
|
||||||
await textarea.click();
|
await textarea.click();
|
||||||
const material = page.locator(".agent-panel-composer");
|
await expect(material).toHaveCSS("border-width", "1px");
|
||||||
await expect(material).toHaveCSS("outline-width", "1px");
|
await expect(material).toHaveCSS("border-color", restingBorder);
|
||||||
await expect(material).toHaveCSS("outline-offset", "-1px");
|
await expect(material).not.toHaveCSS("box-shadow", restingShadow);
|
||||||
await expectThemeColor(material, "outline-color", "--action-blue-hover");
|
|
||||||
await expect(textarea).toHaveCSS("outline-style", "none");
|
await expect(textarea).toHaveCSS("outline-style", "none");
|
||||||
|
expect(await material.boundingBox()).toEqual(restingBox);
|
||||||
await page.screenshot({ path: `test-results/form-focus/mobile-${width}.png` });
|
await page.screenshot({ path: `test-results/form-focus/mobile-${width}.png` });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user