Skip to content

shadcn.io is an independent project built on shadcn/ui

Label with Counter Input Group for React

A title field with Title and a fixed 0/60 in the header, and typing stops at 60 characters.

The header holds the Title label and, at the end, the text 0/60. The count does not change as someone types. The input stops at 60 characters. Clicking Title focuses the field.

Use it for a headline with the cap shown next to the name. If the count should sit under a long note, use a Textarea. In React, Base UI does not update 0/60 while someone types.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Input Group anatomy: root, addon, input, text, button

Usage

<InputGroup className="w-full max-w-sm bg-background">
  <InputGroupInput
    id="input-group-counter-title"
    maxLength={60}
    placeholder="Enter title"
    type="text"
  />
  <InputGroupAddon align="block-start">
    <Label className="text-foreground" htmlFor="input-group-counter-title">
      Title
    </Label>
    <InputGroupText className="ms-auto">0/60</InputGroupText>
  </InputGroupAddon>
</InputGroup>

FAQ

How do the label and the count share the header?

Both sit in one block-start InputGroupAddon; ms-auto on the count pushes it to the end.

What stops typing at 60 characters?

maxLength={60} on InputGroupInput.

Does 0/60 update?

No, it's fixed text. Keep the value in state and render its length there.

How is the label tied to the input?

htmlFor on Label matches the input's id.

How do I make screen readers hear the count?

Give the count an id and point the input's aria-describedby at it.

Why is the count lighter than the label?

Addon text is muted; the label gets text-foreground, the count keeps the muted color.

API Reference

Input Group

Sets id="input-group-counter-title", maxLength={60}, placeholder="Enter title", type="text" and align="block-start". The rest is on the Input Group page.

Label

Sets htmlFor="input-group-counter-title". The rest is on the Label page.