feat(admin-ui): add responsive layout state
This commit is contained in:
1 parent
63ce8797bc
commit
0b106a3dd2
2 files changed
+182
No files matched your search
@@ -0,0 +1,79 @@
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { useLayoutStore } from "./layout";
|
||||
|
||||
describe("layout store", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it.each([
|
||||
[991, "mobile"],
|
||||
[992, "desktop"],
|
||||
[993, "desktop"],
|
||||
] as const)("uses the strict mobile breakpoint at %spx", (width, expectedDevice) => {
|
||||
setActivePinia(createPinia());
|
||||
const store = useLayoutStore();
|
||||
|
||||
store.syncViewport(width);
|
||||
|
||||
expect(store.device).toBe(expectedDevice);
|
||||
expect(store.sidebarOpened).toBe(expectedDevice === "desktop");
|
||||
});
|
||||
|
||||
it("is safe to use without window", () => {
|
||||
setActivePinia(createPinia());
|
||||
const store = useLayoutStore();
|
||||
|
||||
expect(() => store.syncViewport()).not.toThrow();
|
||||
expect(() => store.startViewportWatcher()).not.toThrow();
|
||||
expect(store.device).toBe("desktop");
|
||||
});
|
||||
|
||||
it("registers one resize watcher, updates on resize, and unsubscribes idempotently", () => {
|
||||
const addEventListener = vi.fn();
|
||||
const removeEventListener = vi.fn();
|
||||
const browserWindow = { innerWidth: 993, addEventListener, removeEventListener };
|
||||
vi.stubGlobal("window", browserWindow);
|
||||
setActivePinia(createPinia());
|
||||
const store = useLayoutStore();
|
||||
|
||||
const stop = store.startViewportWatcher();
|
||||
const sameStop = store.startViewportWatcher();
|
||||
const resizeHandler = addEventListener.mock.calls[0][1] as () => void;
|
||||
|
||||
expect(sameStop).toBe(stop);
|
||||
expect(addEventListener).toHaveBeenCalledTimes(1);
|
||||
expect(store.device).toBe("desktop");
|
||||
|
||||
browserWindow.innerWidth = 991;
|
||||
resizeHandler();
|
||||
expect(store.device).toBe("mobile");
|
||||
expect(store.sidebarOpened).toBe(false);
|
||||
|
||||
stop();
|
||||
stop();
|
||||
expect(removeEventListener).toHaveBeenCalledTimes(1);
|
||||
|
||||
browserWindow.innerWidth = 993;
|
||||
resizeHandler();
|
||||
expect(store.device).toBe("mobile");
|
||||
});
|
||||
|
||||
it("controls the sidebar and animation flag independently", () => {
|
||||
setActivePinia(createPinia());
|
||||
const store = useLayoutStore();
|
||||
|
||||
store.toggleSidebar({ withoutAnimation: true });
|
||||
expect(store.sidebarOpened).toBe(false);
|
||||
expect(store.withoutAnimation).toBe(true);
|
||||
|
||||
store.openSidebar({ withoutAnimation: false });
|
||||
expect(store.sidebarOpened).toBe(true);
|
||||
expect(store.withoutAnimation).toBe(false);
|
||||
|
||||
store.closeSidebar();
|
||||
expect(store.sidebarOpened).toBe(false);
|
||||
expect(store.withoutAnimation).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user