- 51 headless Web Components (45 core + 6 animation) - Shared helpers: emit(), part(), listen(), wireLabel(), initialValue() - Zero `new CustomEvent` or `static #counter` — all use shared utils - Zod schemas for all 44 core components - MCP package with discover, inspect, compose, validate tools - Showcase with Aperture Science theme, M3 Expressive motion - 81 tests passing, TypeScript strict mode clean - Signals (~500B), SPA router (~400B), zero dependencies
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { describe, it, expect, beforeEach } from "vitest";
|
|
import { PettyTabs } from "../src/components/tabs/index";
|
|
import { h } from "./helpers";
|
|
|
|
describe("petty-tabs", () => {
|
|
let el: PettyTabs;
|
|
|
|
beforeEach(() => {
|
|
document.body.textContent = "";
|
|
el = document.createElement("petty-tabs") as PettyTabs;
|
|
el.setAttribute("default-value", "one");
|
|
const tab1 = h("petty-tab", { value: "one" }, "Tab 1");
|
|
const tab2 = h("petty-tab", { value: "two" }, "Tab 2");
|
|
const tablist = h("div", { role: "tablist" }, tab1, tab2);
|
|
const panel1 = h("petty-tab-panel", { value: "one" }, "Content 1");
|
|
const panel2 = h("petty-tab-panel", { value: "two" }, "Content 2");
|
|
el.appendChild(tablist);
|
|
el.appendChild(panel1);
|
|
el.appendChild(panel2);
|
|
document.body.appendChild(el);
|
|
});
|
|
|
|
it("registers the custom elements", () => {
|
|
expect(customElements.get("petty-tabs")).toBe(PettyTabs);
|
|
});
|
|
|
|
it("initializes with default-value", () => {
|
|
expect(el.value).toBe("one");
|
|
});
|
|
|
|
it("sets data-state and aria-selected on active tab", () => {
|
|
const tab1 = el.querySelector("petty-tab[value='one']")!;
|
|
const tab2 = el.querySelector("petty-tab[value='two']")!;
|
|
expect(tab1.getAttribute("data-state")).toBe("active");
|
|
expect(tab1.getAttribute("aria-selected")).toBe("true");
|
|
expect(tab2.getAttribute("data-state")).toBe("inactive");
|
|
});
|
|
|
|
it("hides inactive panels", () => {
|
|
const panel2 = el.querySelector("petty-tab-panel[value='two']")!;
|
|
expect(panel2.hasAttribute("hidden")).toBe(true);
|
|
});
|
|
|
|
it("fires petty-change on selectTab", () => {
|
|
let detail: { value: string } | null = null;
|
|
el.addEventListener("petty-change", ((e: CustomEvent) => {
|
|
detail = e.detail;
|
|
}) as EventListener);
|
|
el.selectTab("two");
|
|
expect(detail).toEqual({ value: "two" });
|
|
expect(el.value).toBe("two");
|
|
});
|
|
});
|