Character count
Show how many characters remain in a limited text field with a character count and live feedback.
These examples use the following JavaScript initializers:
Example
Mobile
320pxMobile Lg
480pxTablet
640pxDesktop
1024pxComponent API
Initialization
import { characterCountInit } from '@uswds-tailwind/compat/character-count'
characterCountInit()Initialize after the markup exists. CharacterCount is the corresponding instance class. See initialization and cleanup.
Anatomy
Use data-scope="character-count" data-part="root" on the wrapper. Required descendants are input, status, and sr-status. An ordinary <label> links to the input’s ID; there is no label part.
The optional control receives generated data-invalid. The optional description is a static, visually hidden limit hint. The runtime adds it to the input’s aria-describedby while preserving existing description IDs.
| Part | Attribute | Description |
|---|---|---|
root |
data-maxlength |
Authored fallback limit when the input has no maxlength. Generated from the effective limit after initialization. |
input |
maxlength |
Authored initial limit. The runtime reads it and removes the native limit so users can enter excess characters. The maxLength option takes precedence over both markup limits. |
input, control, status |
data-invalid |
Generated when the value exceeds a positive limit. |
status |
aria-hidden="true" |
Generated. Hides the visual count from assistive technology. |
sr-status |
aria-live |
Generated. Starts unset, then becomes polite; over-limit announcements use assertive. |
Configuration
| Option | Description |
|---|---|
maxLength |
Allowed character count; defaults to the input’s maxlength, then root data-maxlength, then 0 for no limit. |
defaultValue |
Initial text; defaults to the input value. |
value |
Controlled text; your application accepts edits by updating this option. |
errorText |
Custom validity message; defaults to The content is too long. |
statusLabel |
Initial count suffix; defaults to characters allowed. |
ids |
Override root, control, input, description, status, or srStatus IDs. Existing input and description IDs are preserved by default. |
inputDescriptionIds |
Existing hint IDs; defaults to the input’s aria-describedby. |
onValueChange |
Receives { value: string } when the value changes or a controlled edit is requested. This is a JavaScript callback. |
Methods and cleanup
api.setValue(value) requests a text update. api.value, api.count, api.maxLength, api.invalid, api.statusText, and api.srStatusText expose the current state.
characterCountInit() returns the initialized instances. Use CharacterCount.getOrCreateInstance(root, options) to configure an instance, and call destroy() before removing its markup. See initialization and cleanup.
Accessibility
Provide a visible label and a static limit hint. Keep both status elements. Count announcements follow a trailing debounce; over-limit text also sets native custom validity on the input.