feat: menus tableur a icones, fermeture au focus et polish mobile #179
This commit is contained in:
@@ -1867,6 +1867,95 @@ await test("the find scans every sheet and steps across tabs (#156-A11)", () =>
|
||||
assert.ok(area.querySelector('.xlsx-panel[data-sheet="1"] mark.xlsx-find-current'), "the current hit sits in sheet 2");
|
||||
});
|
||||
|
||||
// ── #179 — menu icons + dismissal at viewer level ─────────────────────────
|
||||
await test("the grid context menu shows one icon per entry (#179-A1)", () => {
|
||||
const area = mount();
|
||||
const menu = openMenuOn(area, "A1");
|
||||
assert.ok(menu, "menu opens on right-click");
|
||||
const items = [...menu.querySelectorAll(".xlsx-context-item")];
|
||||
assert.ok(items.length > 3, "several entries");
|
||||
for (const b of items) {
|
||||
const icon = b.querySelector("i[data-lucide]");
|
||||
assert.ok(icon, `"${b.textContent}" carries an icon`);
|
||||
assert.match(icon.getAttribute("data-lucide"), /^[a-z0-9-]+$/);
|
||||
}
|
||||
assert.equal(
|
||||
menu.querySelector(".xlsx-context-item .xlsx-menu-label").textContent,
|
||||
FR["xlsx.cut"]
|
||||
);
|
||||
const danger = items.find(
|
||||
(b) => b.textContent === FR["xlsx.delete_rows"].replace("{n}", "1")
|
||||
);
|
||||
assert.ok(danger && danger.querySelector('i[data-lucide="trash-2"]'), "delete reads as danger");
|
||||
});
|
||||
|
||||
await test("the grid context menu closes when the focus leaves it (#179-A3)", () => {
|
||||
const area = mount();
|
||||
openMenuOn(area, "A1");
|
||||
assert.ok(document.querySelector(".xlsx-context-menu"), "menu open");
|
||||
const first = document.querySelector(".xlsx-context-item");
|
||||
const outside = document.createElement("button");
|
||||
document.body.appendChild(outside);
|
||||
first.dispatchEvent(new w.FocusEvent("focusout", { bubbles: true, relatedTarget: outside }));
|
||||
assert.equal(document.querySelector(".xlsx-context-menu"), null, "menu closed on focus loss");
|
||||
outside.remove();
|
||||
});
|
||||
|
||||
await test("the structure menu shows icons and closes on outside click (#179-A2/A3)", () => {
|
||||
const area = mount();
|
||||
area.querySelector("#xlsx-structure-btn").click();
|
||||
const menu = area.querySelector(".xlsx-structure-menu");
|
||||
assert.ok(menu, "structure menu opens");
|
||||
const icons = [...menu.querySelectorAll(".xlsx-structure-item i[data-lucide]")].map((i) =>
|
||||
i.getAttribute("data-lucide")
|
||||
);
|
||||
assert.ok(icons.includes("file-plus"), "sheet add icon");
|
||||
assert.ok(icons.includes("trash-2"), "delete icon");
|
||||
assert.equal(
|
||||
area.querySelector("#xlsx-structure-btn").getAttribute("aria-expanded"),
|
||||
"true"
|
||||
);
|
||||
document.body.dispatchEvent(new w.MouseEvent("click", { bubbles: true }));
|
||||
assert.equal(area.querySelector(".xlsx-structure-menu"), null, "outside click closes");
|
||||
assert.equal(
|
||||
area.querySelector("#xlsx-structure-btn").getAttribute("aria-expanded"),
|
||||
"false"
|
||||
);
|
||||
});
|
||||
|
||||
await test("the format menu shows icons and closes on Escape (#179-A2/A3)", () => {
|
||||
const area = mount();
|
||||
area.querySelector("#xlsx-format-btn").click();
|
||||
const menu = area.querySelector(".xlsx-format-menu");
|
||||
assert.ok(menu, "format menu opens");
|
||||
const find = (icon) => menu.querySelector(`.xlsx-structure-item i[data-lucide="${icon}"]`);
|
||||
assert.ok(find("bold"), "bold icon");
|
||||
assert.ok(find("align-center"), "align icon");
|
||||
assert.ok(menu.querySelector('.xlsx-format-colour i[data-lucide="palette"]'), "font colour icon");
|
||||
document.dispatchEvent(new w.KeyboardEvent("keydown", { key: "Escape", bubbles: true }));
|
||||
assert.equal(area.querySelector(".xlsx-format-menu"), null, "Escape closes");
|
||||
});
|
||||
|
||||
await test("the export menu closes on outside click (#179-A3)", () => {
|
||||
const area = mount();
|
||||
area.querySelector("#xlsx-export-btn").click();
|
||||
assert.equal(area.querySelector("#xlsx-export-menu").style.display, "block", "menu opens");
|
||||
document.body.dispatchEvent(new w.MouseEvent("click", { bubbles: true }));
|
||||
assert.equal(area.querySelector("#xlsx-export-menu").style.display, "none", "outside click closes");
|
||||
});
|
||||
|
||||
await test("the ribbon save and tab + buttons carry icons (#179-A2)", () => {
|
||||
const area = mount();
|
||||
assert.equal(
|
||||
area.querySelector('#xlsx-save-btn i[data-lucide]').getAttribute("data-lucide"),
|
||||
"save"
|
||||
);
|
||||
assert.equal(
|
||||
area.querySelector('#xlsx-tab-add i[data-lucide]').getAttribute("data-lucide"),
|
||||
"plus"
|
||||
);
|
||||
});
|
||||
|
||||
// ── Report ──────────────────────────────────────────────────────────────────
|
||||
console.log(`\n${passCount}/${testCount} tests passed\n`);
|
||||
process.exit(passCount === testCount ? 0 : 1);
|
||||
|
||||
Reference in New Issue
Block a user