AdminKitDocs
Forms

React Bootstrap Form Controls

React Bootstrap form controls in AdminKit: inputs and textareas as plain Bootstrap markup in JSX, with sizes, disabled and read-only states, controlled or not.

Text inputs and textareas are the fields people type into: a name, an email address, a message. In AdminKit for React they are not components. You write Bootstrap's markup in JSX, with className instead of class and htmlFor instead of for. Bootstrap's Sass styles them in the free and PRO versions of AdminKit for React, so every class of the Bootstrap form docs works.

Only three form fields have their own component, and they are part of AdminKit PRO: the select, the input mask and the date picker. The demo shows the other controls on the Basic Inputs page.

Example

<div className="mb-3">
  <label htmlFor="formControlEmail" className="form-label">Email address</label>
  <input type="email" className="form-control" id="formControlEmail" placeholder="name@example.com" />
</div>
<div className="mb-3">
  <label htmlFor="formControlMessage" className="form-label">Message</label>
  <textarea className="form-control" id="formControlMessage" rows={3} />
</div>

Classes

ClassElementDescription
form-label<label>The label above a field
form-control<input>, <textarea>The text field
form-control-lg, form-control-sm.form-controlLarger or smaller field
form-control-plaintext<input readOnly>A read-only value without the field border
form-control-color<input type="color">The color picker
form-text<div>Help text below a field
form-select<select>The native select, see Select

Controlled and uncontrolled inputs

An uncontrolled input keeps its own value. Give it a starting value with defaultValue, and read the value when the form is submitted. The demo pages work this way, and it is enough for most forms:

import type { FormEvent } from "react";

export function ContactForm() {
  const onSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    console.log(data.get("email"), data.get("message"));
  };

  return (
    <form onSubmit={onSubmit}>
      <div className="mb-3">
        <label htmlFor="contact-email" className="form-label">Email address</label>
        <input type="email" className="form-control" id="contact-email" name="email" required />
      </div>
      <div className="mb-3">
        <label htmlFor="contact-message" className="form-label">Message</label>
        <textarea className="form-control" id="contact-message" name="message" rows={3} />
      </div>
      <button type="submit" className="btn btn-primary">Send</button>
    </form>
  );
}

A controlled input takes its value from state and updates that state in onChange. Use one when the page reacts to each keystroke, such as a character count:

import { useState } from "react";

export function BioField() {
  const [bio, setBio] = useState("");

  return (
    <div className="mb-3">
      <label htmlFor="bio" className="form-label">Bio</label>
      <textarea
        className="form-control"
        id="bio"
        rows={3}
        maxLength={160}
        value={bio}
        onChange={(event) => setBio(event.target.value)}
        aria-describedby="bio-count"
      />
      <div className="form-text" id="bio-count">{160 - bio.length} characters left</div>
    </div>
  );
}

A value without onChange makes the field read-only, and React warns about it. Use defaultValue, or add readOnly on purpose.

Sizes

When a field sits next to a large button or in a compact toolbar, match its height with form-control-lg or form-control-sm.

<input className="form-control form-control-lg mb-3" type="text" placeholder="Large input" aria-label="Large input" />
<input className="form-control mb-3" type="text" placeholder="Medium input" aria-label="Medium input" />
<input className="form-control form-control-sm" type="text" placeholder="Small input" aria-label="Small input" />

Disabled and read only

Use these when a field should show a value that the user cannot change. disabled grays the field out and leaves it out of the submitted form data. readOnly keeps the value selectable and submitted, but not editable.

<input className="form-control mb-3" type="text" placeholder="Disabled input" aria-label="Disabled input" disabled />
<input className="form-control" type="text" placeholder="Readonly input" aria-label="Readonly input" readOnly />

Accessibility

  • Give every field a label: a <label> with htmlFor set to the field's id, or aria-label when the design has no visible label. A placeholder is not a label.
  • Point aria-describedby at the id of help text (.form-text), so screen readers read it with the field.
  • Use the right type (email, tel, url, number) and autoComplete values: mobile keyboards and password managers rely on them.
  • A disabled field cannot get the focus. If the value has to stay readable by keyboard, use readOnly.

Last updated on

On this page