mock: バリアントのバッジをノードより後に描き、キーの下に隠れないようにする

バッジは NodeSvg の再帰の中で各バリアントグループの <g> に描いていたため、
後から描かれる兄弟のキーに隠れていた。選択の描画層の後に PhyBadgeLayer を置き、
位置は純粋関数 variantBadges でワールド座標に直して正立で描く。
フォーカス中、フォーカス外のバッジは薄く描き、クリックを受けない。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NznQtmVPoQAnietqwr1auL
This commit is contained in:
2026-10-22 14:24:49 +09:00
co-authored by Claude Opus 5.5
parent 812e2edfc2
commit 0697e7a3b4
6 changed files with 157 additions and 85 deletions
+14 -3
View File
@@ -269,7 +269,7 @@ test("選択枠は画面上で見え、バリアントバッジで表示を切
const group = page.locator('[data-node-type="variantGroup"]').first();
await page.getByLabel("Rotation").fill("35");
await page.getByLabel("Rotation").dispatchEvent("change");
const badge = group.locator(".badge");
const badge = page.locator(`[data-badge-id="${await group.first().getAttribute("data-node-id")}"]`);
await expect(badge).toBeVisible();
await badge.locator("rect").click();
await page
@@ -303,9 +303,20 @@ test("クラスター内のキーから作ったバリアントグループは
await page.getByRole("button", { name: "選択からバリアントグループ" }).click();
const group = cluster.locator('[data-node-type="variantGroup"]');
await expect(group).toHaveCount(1);
const badge = group.locator(".badge");
const badge = page.locator(`[data-badge-id="${await group.first().getAttribute("data-node-id")}"]`);
await expect(badge.locator("text")).toHaveText("⇄");
await expect(badge.locator("title")).toHaveText("Variant Group: Option A(既定)");
// バッジはキーより後に描き、隣のキーの下に隠れない
const onTop = await badge.evaluate((element) => {
const keys = [...document.querySelectorAll('[data-node-type="key"]')];
const box = element.getBoundingClientRect();
const hit = document.elementFromPoint(box.x + box.width / 2, box.y + box.height / 2);
return [
keys.every((key) => key.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_FOLLOWING),
element.contains(hit),
];
});
expect(onTop).toEqual([true, true]);
await badge.locator("rect").click();
const popover = page.locator(".popover");
await expect(popover.getByRole("button", { name: /Option A/ }).locator(".default-tag")).toHaveText("既定");
@@ -527,7 +538,7 @@ test("削除のキーボード確認とバリアントポップオーバーを
await page.keyboard.press("Escape");
await keysSelectVariantGroup(page);
const badge = page.locator('[data-node-type="variantGroup"] .badge').first();
const badge = page.locator(".badge-layer:not(.dim) .badge").first();
await badge.locator("rect").click();
const badgeBox = await badge.boundingBox();
const popoverBox = await page.locator(".popover").boundingBox();