bit Bheadless

Field / Input

Form primitives with auto-wired ARIA labels, descriptions, and validation state.

Implementation: CSS Tailwind

Basic Field

Wrap a label, input, and description in an BitBhField. The label's for, the input's id, and the description's aria-describedby are all wired automatically — no manual id management.

We'll never share your email.

Textarea

BitBhTextarea works identically to BitBhInput — same ARIA wiring, same data attributes. Standard HTML attributes like rows pass through.

Max 280 characters.

Select

BitBhSelect renders a native <select> with the same auto-wired ARIA. Place <option> elements inside.

Where you're based.

Disabled Field

Set Disabled="true" on the BitBhField to disable all children at once. The field, label, and input all receive data-disabled for CSS hooks.

Cannot be changed.

Invalid Field

Set Invalid="true" on the BitBhField to mark the input as invalid. The input receives aria-invalid="true" and data-invalid for CSS hooks. Use the description to show an error message.

Password must be at least 8 characters.

Multiple Fields (form layout)

Compose multiple BitBhField components into a form. Each field manages its own id namespace — no collisions.

Your work email.

EditForm validation

Inside an EditForm with DataAnnotationsValidator, every control bound with @bind-Value / @bind-Checked reports its validation state to its BitBhField: the control gets aria-invalid="true" and data-invalid, and BitBhErrorMessage appears with the messages and is added to the control's aria-describedby — no ids to wire. Non-native controls work too: the radio group is named by its BitBhLabel via aria-labelledby, and clicking the label focuses the group. Because these components take plain child content, they nest inside EditForm without Context clashes. Submit empty to see it.

We'll send the receipt here.

An unhandled error has occurred. Reload 🗙