import { render, screen } from '@testing-library/react';
import { fireEvent } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { Checkbox } from './Checkbox';
describe('Checkbox', () => {
it('renders unchecked by default', () => {
render();
const checkbox = screen.getByRole('checkbox', { name: 'Accept' });
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
});
it('renders the control as a native button for sibling labels', () => {
render();
expect(screen.getByRole('checkbox', { name: 'Accept' }).tagName).toBe(
'BUTTON',
);
});
it('toggles on click', () => {
render();
const checkbox = screen.getByRole('checkbox', { name: 'Accept' });
expect(checkbox).not.toBeChecked();
fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
fireEvent.click(checkbox);
expect(checkbox).not.toBeChecked();
});
it('does not render the check indicator when unchecked', () => {
render();
expect(
screen
.getByRole('checkbox', { name: 'Accept' })
.querySelector('[data-slot="checkbox-indicator"]'),
).not.toBeInTheDocument();
});
it('clicking the label toggles the checkbox', () => {
render();
const label = screen.getByText('Accept terms');
const checkbox = screen.getByRole('checkbox');
expect(checkbox).not.toBeChecked();
fireEvent.click(label);
expect(checkbox).toBeChecked();
});
it('renders as indeterminate', () => {
render();
const checkbox = screen.getByRole('checkbox', { name: 'Partial' });
// Base UI renders the checkbox root as a span with role="checkbox";
// aria-checked="mixed" signals indeterminate state.
expect(checkbox).toHaveAttribute('aria-checked', 'mixed');
});
it('is disabled and blocks interaction', () => {
render();
const checkbox = screen.getByRole('checkbox', { name: 'Accept' });
expect(checkbox).toBeDisabled();
fireEvent.click(checkbox);
expect(checkbox).not.toBeChecked();
});
it('merges custom className', () => {
render();
const root = screen
.getByRole('checkbox', { name: 'Accept' })
.closest('[data-slot="checkbox"]');
expect(root).toHaveClass('my-class');
});
it('renders Checkbox.Label as a standalone label element', () => {
render(
<>
Composed label
>,
);
expect(screen.getByText('Composed label')).toHaveAttribute(
'data-slot',
'checkbox-label',
);
});
});