Skip to content
NewService Map: 30 components for hosts, ports and routes
<PxTextarea />ReactFormsForm controlFree

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.

View as Markdown
<PxTextarea />

Playground

Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.

Loading <PxTextarea />
Props
labellive
limitlive
defaultValueremounts
disabledlive
React
<PxTextarea
  label="Short bio"
  limit={120}
  placeholder="A sentence or two about you"
/>

Installation

pnpm dlx shadcn@latest add @lumesec/px-textarea
First 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}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/px-textarea.json

Usage

px-textarea-example.tsx
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.

valueTypestring

Controlled text. Use with onValueChange.

defaultValueTypestringDefault""

Initial text when uncontrolled. A form reset restores it.

limitTypenumberDefault280

Character budget. Typing past it is allowed but marks the field invalid.

labelTypeReact.ReactNode

Label above the field, linked to the textarea.

placeholderTypestring

Placeholder of the textarea.

nameTypestring

Form field name; the text submits under it.

disabledTypebooleanDefaultfalse

Disables the textarea and dims the field.

requiredTypebooleanDefaultfalse

Marks the textarea as required for form validation.

readOnlyTypebooleanDefaultfalse

Makes the textarea read-only.

onValueChangeType(value: string) => void

Called on every edit with the new text.

onValueCommitType(value: string) => void

Called 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-describedby and is an aria-live="polite" region.
  • Over the limit the textarea has aria-invalid and a custom validity message.
  • The pixel budget bar is aria-hidden.
  • A native <textarea> submits the text under name. Over limit it 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 restores defaultValue and calls onValueChange.
  • 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-zone set to ok, warn (from 80% of the limit) or over.
  • className and other div props go to the wrapper; textarea attributes are the props listed above.

Was this page helpful?