fix: reverse Toolbox header orientation

This commit is contained in:
2026-07-23 01:47:55 +02:00
parent c296281f89
commit 53c40a61ba
12 changed files with 331 additions and 138 deletions

View File

@@ -11,7 +11,11 @@ import {
} from "@add-ideas/toolbox-contract";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { AppShell, ToolboxHeader } from "../src/index.js";
import {
AppShell,
ToolboxHeader,
ToolboxPersonalizePanel,
} from "../src/index.js";
const currentApp: ToolboxAppManifest = {
schemaVersion: 1,
@@ -124,10 +128,20 @@ describe("AppShell", () => {
element.getAttribute("aria-label"),
),
).toEqual([
"Personalize",
"Apps",
"Source for PDF Workbench on Gitea",
"Help",
"Source for PDF Workbench on Gitea",
"Apps",
"Personalize",
]);
expect(
Array.from(
document.querySelector(".toolbox-shell__bar")?.children ?? [],
(element) => element.className,
),
).toEqual([
"toolbox-shell__brand",
"toolbox-shell__identity",
"toolbox-shell__controls",
]);
fireEvent.click(screen.getByRole("button", { name: "Apps" }));
expect(
@@ -278,6 +292,21 @@ describe("AppShell", () => {
const shell = document.querySelector(".toolbox-shell");
expect(shell).toHaveAttribute("data-toolbox-theme", "dark");
fireEvent.click(screen.getByRole("button", { name: "Personalize" }));
expect(
screen.getByRole("heading", { name: "Personalize your toolbox" }),
).toBeInTheDocument();
expect(screen.getByText("On this device")).toBeInTheDocument();
expect(
screen.getByRole("group", { name: "Appearance" }),
).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Dark" })).toHaveAttribute(
"aria-pressed",
"true",
);
expect(screen.queryByText("Pinned")).not.toBeInTheDocument();
expect(
screen.queryByRole("button", { name: "Export JSON" }),
).not.toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Light" }));
expect(shell).toHaveAttribute("data-toolbox-theme", "light");
expect(
@@ -285,6 +314,29 @@ describe("AppShell", () => {
).toMatchObject({ theme: "light" });
});
it("shares the portal-style personalization frame and extension slot", () => {
const onThemeChange = vi.fn();
render(
<ToolboxPersonalizePanel
theme="system"
onThemeChange={onThemeChange}
storageAvailable={false}
>
<p>Portal preference actions</p>
</ToolboxPersonalizePanel>,
);
expect(
screen.getByRole("heading", { name: "Personalize your toolbox" }),
).toBeInTheDocument();
expect(screen.getByRole("status")).toHaveTextContent(
"Browser storage is unavailable",
);
expect(screen.getByText("Portal preference actions")).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Dark" }));
expect(onThemeChange).toHaveBeenCalledWith("dark");
});
it("resolves manifest-relative header links without rendering an app icon", async () => {
render(
<AppShell