Mats Bosson fce03b7531 TextField component
Headless TextField with Label, Input, Description, and ErrorMessage parts. Supports invalid, disabled, and required states with full ARIA wiring (aria-invalid, aria-required, aria-describedby, aria-errormessage). 7 tests passing.
2026-03-29 07:42:05 +07:00

79 lines
2.3 KiB
TypeScript

// packages/core/tests/components/text-field/text-field.test.tsx
import { render, screen } from "@solidjs/testing-library";
import { describe, expect, it } from "vitest";
import { TextField } from "../../../src/components/text-field/index";
describe("TextField", () => {
it("label is linked to input via htmlFor/id", () => {
render(() => (
<TextField>
<TextField.Label>Name</TextField.Label>
<TextField.Input />
</TextField>
));
const label = screen.getByText("Name");
const input = screen.getByRole("textbox");
expect(label.getAttribute("for")).toBe(input.id);
});
it("description is linked via aria-describedby", () => {
render(() => (
<TextField>
<TextField.Label>Name</TextField.Label>
<TextField.Input />
<TextField.Description>Enter your full name</TextField.Description>
</TextField>
));
const input = screen.getByRole("textbox");
const desc = screen.getByText("Enter your full name");
expect(input.getAttribute("aria-describedby")).toBe(desc.id);
});
it("error message not shown when not invalid", () => {
render(() => (
<TextField>
<TextField.Input />
<TextField.ErrorMessage>Required</TextField.ErrorMessage>
</TextField>
));
expect(screen.queryByText("Required")).toBeNull();
});
it("error message shown when invalid=true", () => {
render(() => (
<TextField invalid>
<TextField.Input />
<TextField.ErrorMessage>Required</TextField.ErrorMessage>
</TextField>
));
expect(screen.getByText("Required")).toBeTruthy();
});
it("input has aria-invalid when invalid=true", () => {
render(() => (
<TextField invalid>
<TextField.Input />
</TextField>
));
expect(screen.getByRole("textbox").getAttribute("aria-invalid")).toBe("true");
});
it("input is disabled when disabled=true", () => {
render(() => (
<TextField disabled>
<TextField.Input />
</TextField>
));
expect(screen.getByRole("textbox")).toBeDisabled();
});
it("input has aria-required when required=true", () => {
render(() => (
<TextField required>
<TextField.Input />
</TextField>
));
expect(screen.getByRole("textbox").getAttribute("aria-required")).toBe("true");
});
});