feat: add core UI components and baseline tests

This commit is contained in:
2026-03-19 16:56:27 +08:00
parent 12642e0a92
commit 063179933c
73 changed files with 5756 additions and 2 deletions
@@ -0,0 +1,52 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { Button } from "./button";
describe("Button", () => {
it("renders a native button with root and label slots", () => {
render(<Button variant="secondary">Save changes</Button>);
const button = screen.getByRole("button", { name: "Save changes" });
expect(button).toHaveAttribute("data-slot", "root");
expect(button).toHaveAttribute("data-variant", "secondary");
expect(button).toHaveAttribute("type", "button");
expect(screen.getByText("Save changes")).toHaveAttribute("data-slot", "label");
});
it("disables interaction and exposes loading hooks when loading", async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render(
<Button loading onClick={onClick}>
Saving
</Button>
);
const button = screen.getByRole("button", { name: "Saving" });
await user.click(button);
expect(button).toBeDisabled();
expect(button).toHaveAttribute("data-loading", "");
expect(button.querySelector('[data-slot="icon"]')).toBeInTheDocument();
expect(onClick).not.toHaveBeenCalled();
});
it("supports asChild rendering without forcing button semantics", () => {
render(
<Button asChild variant="ghost">
<a href="/release-notes">Release notes</a>
</Button>
);
const link = screen.getByRole("link", { name: "Release notes" });
expect(link).toHaveAttribute("data-slot", "root");
expect(link).toHaveAttribute("data-variant", "ghost");
expect(link).not.toHaveAttribute("type");
});
});