Inputs@knitui/components
Textarea
Textarea is a multiline text field built on top of InputBase. It supports optional autosize growth between minRows and maxRows (web), a CSS resize handle, and the full InputBase wrapper API: label, description, error and required state.
import { Textarea } from "@knitui/components";Playground
Loading playground…
<Textarea
placeholder="Write something…"
variant="default"
size="md"
disabled={false}
autosize={false}
minRows={3}
resize="none"
/>Examples
Variants
The three chrome variants — default, filled, and unstyled.
Loading example…
Sizes
The seven token sizes from xxs to xxl.
Loading example…
Matrix
Full variant × size matrix for visual regression.
Loading example…
Shadows
The shadow elevation prop, inherited from Box, across all token levels.
Loading example…
Themed
Theme accent — uses Tamagui's theme prop, not a Mantine color prop.
Loading example…
With Label
Label, description and error are wired via InputBase — no extra wrapper needed.
Loading example…
With Error
Error state — toggles the error border and renders the error message below.
Loading example…
Disabled
Disabled state — reduced opacity and pointer events off.
Loading example…
Autosize
Autosize grows the textarea as the user types, capped at maxRows.
Loading example…
Controlled
Controlled usage — value is held in state and displayed below.
Loading example…
Autosize Controlled
Autosize with controlled state — demonstrates that the textarea re-runs the height calculation whenever the React value changes (not just on DOM input events).
Loading example…
With Sections
Left / right sections should pin to the top edge in multiline mode.
Loading example…
Resize Handles
The resize prop exposes the CSS drag handle — sweep all four options.
Loading example…
Read Only
Read-only — the value is shown but not editable, with no disabled dimming.
Loading example…
Required
Required field — withAsterisk appends the asterisk without forcing validation.
Loading example…
Loading
Loading indicator in either section — pins to the top edge in multiline mode.
Loading example…
Character Limit
Character limit — maxLength caps input; a live counter reflects remaining chars.
Loading example…
Styles
Per-slot styles targets individual parts — here the root frame and label.
Loading example…
Prefilled
Prefilled with long content — a fixed-height field scrolls its overflow.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
autoCapitalize | "none" | (string & {}) | "off" | "on" | "sentences" | "words" | "characters" | undefined | — | |
autoComplete | string | undefined | — | |
autoCorrect | string | boolean | undefined | — | |
autoFocus | boolean | undefined | — | |
autosize | boolean | undefined | false | When true the textarea grows with its content (web only). |
children | ReactNode | — | Rendered inside the host element. Only meaningful for the `button` host (e.g. FileInput's trigger displays the picked file name); ignored for the native `input`/`textarea`/`select` hosts. |
component | InputHostTag | undefined | — | Override the host element tag (defaults to `input`/`textarea`). |
cursorColor | "unset" | ColorTokens | undefined | — | |
defaultValue | string | number | readonly string[] | undefined | — | |
description | ReactNode | — | |
descriptionProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
disabled system | boolean | undefined | false | |
enterKeyHint | "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | undefined | — | |
error | ReactNode | — | Error message — toggles error styling. |
errorProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
id | string | undefined | — | Same as the web id property for setting a uid on an element |
inputContainer | ((children: ReactNode) => ReactNode) | undefined | — | |
inputSize | string | undefined | — | Host size attribute for the input element |
inputWrapperOrder | InputWrapperOrderItem[] | undefined | — | |
label | ReactNode | — | |
labelElement | "div" | "label" | undefined | — | |
labelProps | InputLabelProps | undefined | — | |
leftSection | ReactNode | — | Content section displayed on the left side of the input |
leftSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the left section element |
leftSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the left section element |
leftSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Left section width, by default equals to the input height |
loading | boolean | undefined | — | Displays loading indicator in the left or right section |
loadingPosition | "left" | "right" | undefined | "right" | Position of the loading indicator |
max | string | number | undefined | — | |
maxLength | number | undefined | — | |
maxRows | number | undefined | — | Maximum rows before the autosize textarea starts scrolling (web only). |
min | string | number | undefined | — | |
minLength | number | undefined | — | |
minRows | number | undefined | 2 | Minimum number of visible rows / initial height. |
multiline | undefined | — | Textarea always renders a multiline host; this prop is intentionally owned. |
multiple | boolean | undefined | — | |
name | string | undefined | — | |
onChangeText | ((text: string) => void) | undefined | — | Fires on every change with just the string value. |
onSelectionChange | ((event: InputSelectionChangePayload) => void) | undefined | — | Fires when the text selection changes. |
onSubmitEditing | ((event: InputTextEventPayload) => void) | undefined | — | Fires when Enter/Return is pressed. |
pattern | string | undefined | — | |
placeholder | string | undefined | Write something… | |
placeholderTextColor | "unset" | ColorTokens | undefined | — | |
pointer | boolean | undefined | — | Determines whether the input should have cursor: pointer style |
radius system | string | number | undefined | — | Key of theme radius or a valid CSS value to set border-radius |
readOnly | boolean | undefined | — | |
required | boolean | undefined | — | |
resize | TextareaResize | undefinednone · both · horizontal · vertical | "none" | CSS `resize` property — controls the drag handle (web only). |
rightSection | ReactNode | — | Content section displayed on the right side of the input |
rightSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the right section element |
rightSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the right section element |
rightSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Right section width, by default equals to the input height |
rootRef | Ref<TamaguiElement> | undefined | — | Root element ref |
rows | number | undefined | — | Rows for textarea (when render="textarea") |
selection | { start: number; end?: number; } | undefined | — | Selection range |
selectionColor | "unset" | ColorTokens | undefined | — | |
selectionHandleColor | "unset" | ColorTokens | undefined | — | |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined | — | |
size system | InputSize | undefinedxxs · xs · sm · md · lg · xl · xxl | md | Controls height, padding, radius and font size. |
spellCheck | boolean | undefined | — | Controls spell checking. |
step | string | number | undefined | — | |
styles system | SlotStyles<InputWrapperSlots> | undefined | — | Uniform per-slot style passthrough — sugar over the composable parts. Slots: `wrapper` / `label` / `description` / `error` / `required`. |
textContentType | InputTextContentType | undefined | — | Text content type for iOS autofill. Use `autoComplete` where available. |
theme system | ThemeName | null | undefinedunset · blue · red · green · yellow · pink · gray | — | Tamagui accent theme applied to focused and error-adjacent chrome. |
type | string | undefined | — | |
underlineColorAndroid | "unset" | ColorTokens | undefined | — | |
value | string | number | readonly string[] | undefined | — | |
variant system | InputVariant | undefineddefault · filled · unstyled | "default" | Visual variant of the input chrome. |
withAria | boolean | undefined | true | Determines whether accessibility attributes should be added |
withAsterisk | boolean | undefined | — | |
wrapperProps | ({ readonly br?: number | "$xs" | "$sm" | "$md" | "$lg" | "$xl" | "unset" | "$0" | "$true" | "$xxs" | "$xxl" | Variable<any> | `${number}rem` | UnionableNumber | "inherit" | `var(${string})` | Animated.AnimatedNode | null | undefined; label… | — | Props passed down to the root element (`Input.Wrapper` component) |
Style slots
Every part of Textarea can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
description | styles={{ description: { … } }} |
error | styles={{ error: { … } }} |
label | styles={{ label: { … } }} |
leftSection | styles={{ leftSection: { … } }} |
required | styles={{ required: { … } }} |
rightSection | styles={{ rightSection: { … } }} |
root | styles={{ root: { … } }} |
wrapper | styles={{ wrapper: { … } }} |
Accessibility & DOM props (218)
| Prop | Type |
|---|---|
about | string | undefined |
accept | string | undefined |
accessKey | string | undefined |
alt | string | undefined |
aria-activedescendant | string | undefined |
aria-atomic | (boolean | "true" | "false") | undefined |
aria-autocomplete | "none" | "inline" | "list" | "both" | undefined |
aria-braillelabel | string | undefined |
aria-brailleroledescription | string | undefined |
aria-colcount | number | undefined |
aria-colindex | number | undefined |
aria-colindextext | string | undefined |
aria-colspan | number | undefined |
aria-controls | string | undefined |
aria-current | boolean | "time" | "true" | "false" | "page" | "step" | "location" | "date" | undefined |
aria-describedby | string | undefined |
aria-description | string | undefined |
aria-details | string | undefined |
aria-dropeffect | "link" | "none" | "copy" | "move" | "execute" | "popup" | undefined |
aria-errormessage | string | undefined |
aria-flowto | string | undefined |
aria-grabbed | (boolean | "true" | "false") | undefined |
aria-haspopup | boolean | "dialog" | "menu" | "true" | "false" | "grid" | "tree" | "listbox" | undefined |
aria-invalid | boolean | "true" | "false" | "grammar" | "spelling" | undefined |
aria-keyshortcuts | string | undefined |
aria-level | number | undefined |
aria-multiline | (boolean | "true" | "false") | undefined |
aria-multiselectable | (boolean | "true" | "false") | undefined |
aria-orientation | "horizontal" | "vertical" | undefined |
aria-owns | string | undefined |
aria-placeholder | string | undefined |
aria-posinset | number | undefined |
aria-pressed | boolean | "true" | "false" | "mixed" | undefined |
aria-readonly | (boolean | "true" | "false") | undefined |
aria-relevant | "all" | "text" | "additions" | "additions removals" | "additions text" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined |
aria-required | (boolean | "true" | "false") | undefined |
aria-roledescription | string | undefined |
aria-rowcount | number | undefined |
aria-rowindex | number | undefined |
aria-rowindextext | string | undefined |
aria-rowspan | number | undefined |
aria-setsize | number | undefined |
aria-sort | "none" | "ascending" | "descending" | "other" | undefined |
autoSave | string | undefined |
capture | boolean | "user" | "environment" | undefined |
checked | boolean | undefined |
contentEditable | "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined |
contextMenu | string | undefined |
datatype | string | undefined |
defaultChecked | boolean | undefined |
dir | string | undefined |
draggable | (boolean | "true" | "false") | undefined |
exportparts | string | undefined |
form | string | undefined |
formAction | string | ((formData: FormData) => void | Promise<void>) | undefined |
formEncType | string | undefined |
formMethod | string | undefined |
formNoValidate | boolean | undefined |
formTarget | string | undefined |
hidden | boolean | undefined |
inert | boolean | undefined |
inlist | any |
inputMode | "search" | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined |
is | string | undefined |
itemID | string | undefined |
itemProp | string | undefined |
itemRef | string | undefined |
itemScope | boolean | undefined |
itemType | string | undefined |
key | Key | null | undefined |
lang | string | undefined |
list | string | undefined |
nonce | string | undefined |
onAbort | ReactEventHandler<HTMLInputElement> | undefined |
onAbortCapture | ReactEventHandler<HTMLInputElement> | undefined |
onAnimationEnd | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationEndCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationIteration | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationIterationCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationStart | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationStartCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAuxClick | MouseEventHandler<HTMLInputElement> | undefined |
onAuxClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onBeforeInputCapture | InputEventHandler<HTMLInputElement> | undefined |
onBeforeToggle | ToggleEventHandler<HTMLInputElement> | undefined |
onBlurCapture | FocusEventHandler<HTMLInputElement> | undefined |
onCanPlay | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayCapture | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayThrough | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayThroughCapture | ReactEventHandler<HTMLInputElement> | undefined |
onChangeCapture | ChangeEventHandler<HTMLInputElement, Element> | undefined |
onClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onCompositionEnd | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionEndCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionStart | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionStartCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionUpdate | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionUpdateCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onContextMenuCapture | MouseEventHandler<HTMLInputElement> | undefined |
onCopyCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onCutCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onDoubleClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onDragCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragEndCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragEnterCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragExit | DragEventHandler<HTMLInputElement> | undefined |
onDragExitCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragLeaveCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragOverCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragStartCapture | DragEventHandler<HTMLInputElement> | undefined |
onDropCapture | DragEventHandler<HTMLInputElement> | undefined |
onDurationChange | ReactEventHandler<HTMLInputElement> | undefined |
onDurationChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEmptied | ReactEventHandler<HTMLInputElement> | undefined |
onEmptiedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEncrypted | ReactEventHandler<HTMLInputElement> | undefined |
onEncryptedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEnded | ReactEventHandler<HTMLInputElement> | undefined |
onEndedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onError | ReactEventHandler<HTMLInputElement> | undefined |
onErrorCapture | ReactEventHandler<HTMLInputElement> | undefined |
onFocusCapture | FocusEventHandler<HTMLInputElement> | undefined |
onGotPointerCapture | PointerEventHandler<HTMLInputElement> | undefined |
onGotPointerCaptureCapture | PointerEventHandler<HTMLInputElement> | undefined |
onInputCapture | InputEventHandler<HTMLInputElement> | undefined |
onInvalid | ReactEventHandler<HTMLInputElement> | undefined |
onInvalidCapture | ReactEventHandler<HTMLInputElement> | undefined |
onKeyDownCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyPress | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyPressCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyUpCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onLoad | ReactEventHandler<HTMLInputElement> | undefined |
onLoadCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedData | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedDataCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedMetadata | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedMetadataCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadStart | ReactEventHandler<HTMLInputElement> | undefined |
onLoadStartCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLostPointerCapture | PointerEventHandler<HTMLInputElement> | undefined |
onLostPointerCaptureCapture | PointerEventHandler<HTMLInputElement> | undefined |
onMouseDownCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseMoveCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseOutCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseOverCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseUpCapture | MouseEventHandler<HTMLInputElement> | undefined |
onPasteCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onPause | ReactEventHandler<HTMLInputElement> | undefined |
onPauseCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPlay | ReactEventHandler<HTMLInputElement> | undefined |
onPlayCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPlaying | ReactEventHandler<HTMLInputElement> | undefined |
onPlayingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPointerOut | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOutCapture | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOver | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOverCapture | PointerEventHandler<HTMLInputElement> | undefined |
onProgress | ReactEventHandler<HTMLInputElement> | undefined |
onProgressCapture | ReactEventHandler<HTMLInputElement> | undefined |
onRateChange | ReactEventHandler<HTMLInputElement> | undefined |
onRateChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onReset | ReactEventHandler<HTMLInputElement> | undefined |
onResetCapture | ReactEventHandler<HTMLInputElement> | undefined |
onScrollCapture | UIEventHandler<HTMLInputElement> | undefined |
onScrollEnd | UIEventHandler<HTMLInputElement> | undefined |
onScrollEndCapture | UIEventHandler<HTMLInputElement> | undefined |
onSeeked | ReactEventHandler<HTMLInputElement> | undefined |
onSeekedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSeeking | ReactEventHandler<HTMLInputElement> | undefined |
onSeekingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSelect | ReactEventHandler<HTMLInputElement> | undefined |
onSelectCapture | ReactEventHandler<HTMLInputElement> | undefined |
onStalled | ReactEventHandler<HTMLInputElement> | undefined |
onStalledCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSubmit | SubmitEventHandler<HTMLInputElement> | undefined |
onSubmitCapture | SubmitEventHandler<HTMLInputElement> | undefined |
onSuspend | ReactEventHandler<HTMLInputElement> | undefined |
onSuspendCapture | ReactEventHandler<HTMLInputElement> | undefined |
onTimeUpdate | ReactEventHandler<HTMLInputElement> | undefined |
onTimeUpdateCapture | ReactEventHandler<HTMLInputElement> | undefined |
onToggle | ToggleEventHandler<HTMLInputElement> | undefined |
onTouchCancelCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTouchMoveCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTouchStartCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTransitionCancel | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionCancelCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionEnd | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionEndCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionRun | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionRunCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionStart | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionStartCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onVolumeChange | ReactEventHandler<HTMLInputElement> | undefined |
onVolumeChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onWaiting | ReactEventHandler<HTMLInputElement> | undefined |
onWaitingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onWheelCapture | WheelEventHandler<HTMLInputElement> | undefined |
part | string | undefined |
popover | "" | "auto" | "manual" | "hint" | undefined |
popoverTarget | string | undefined |
popoverTargetAction | "hide" | "show" | "toggle" | undefined |
prefix | string | undefined |
property | string | undefined |
radioGroup | string | undefined |
ref | Ref<TamaguiElement> | undefined |
resource | string | undefined |
results | number | undefined |
rev | string | undefined |
security | string | undefined |
slot | string | undefined |
src | string | undefined |
suppressContentEditableWarning | boolean | undefined |
suppressHydrationWarning | boolean | undefined |
title | string | undefined |
translate | "yes" | "no" | undefined |
typeof | string | undefined |
unselectable | "off" | "on" | undefined |
vocab | string | undefined |
Plus 523 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.