Text area with budget
Auto-growing text area with a pixel character budget that turns amber near the limit and blinks red when over, marking the form invalid.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<PxTextarea
label="Short bio"
limit={120}
placeholder="A sentence or two about you"
/>Installation
pnpm dlx shadcn@latest add @lumesec/px-textareaFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/px-textarea.jsonUsage
import { PxTextarea } from "@/components/lumesec/px-textarea";
export function Example() {
return <PxTextarea name="bio" label="Short bio" limit={120} placeholder="A sentence or two about you" />;
}Behaviour
Grows with its content and shows the character budget as pixels that turn amber near the limit. Going over is allowed but blinks red and marks the form invalid.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
valueTypestringControlled text. Use with onValueChange.
defaultValueTypestringDefault""Initial text when uncontrolled. A form reset restores it.
limitTypenumberDefault280Character budget. Typing past it is allowed but marks the field invalid.
labelTypeReact.ReactNodeLabel above the field, linked to the textarea.
placeholderTypestringPlaceholder of the textarea.
nameTypestringForm field name; the text submits under it.
disabledTypebooleanDefaultfalseDisables the textarea and dims the field.
requiredTypebooleanDefaultfalseMarks the textarea as required for form validation.
readOnlyTypebooleanDefaultfalseMakes the textarea read-only.
onValueChangeType(value: string) => voidCalled on every edit with the new text.
onValueCommitType(value: string) => voidCalled when the textarea commits a change: on blur after editing (the native change event).
Ref
ref points at the root HTMLDivElement.
Accessibility
- A native
<textarea>labelled by a<label htmlFor>. - The counter ("40 left", or "−5" when over) is linked with
aria-describedbyand is anaria-live="polite"region. - Over the limit the textarea has
aria-invalidand a custom validity message. - The pixel budget bar is
aria-hidden. - A native
<textarea>submits the text undername. Overlimitit sets the custom validity message "Keep it under N characters", which blocks submission and anchors the browser's validation bubble to the field. Form reset restoresdefaultValueand callsonValueChange. - Reduced motion: the budget bar jumps to the new length and the over-limit pixels do not blink.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --foreground, --muted-foreground, --card, --border, --lumesec, --lumesec-warning and --destructive.
Notes
- The textarea grows with its content from a minimum height of 84 px, refits when its width changes, and has no resize handle.
- The root carries
data-zoneset took,warn(from 80% of the limit) orover. classNameand otherdivprops go to the wrapper; textarea attributes are the props listed above.
Related
Was this page helpful?