TextArea

The TextArea component provides a multi-line text input with support for auto-resizing, character counting, validation states, and flexible sizing options.

Basic

Controlled text area with helper copy and inline character count feedback.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

Text

,

 

TextArea

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

value

,

setValue

]

 

=

 

useState

(

''

)

;

 

  

return

 

(

    

<Block

fullWidth

>

      

<TextArea

        

label

=

"Message"

        

placeholder

=

"Enter your message"

        

value

=

{

value

}

        

onChangeText

=

{

setValue

}

        

description

=

"Provide helpful context for your request."

        

error

=

{

value

.

length

>

 

120

 

?

 

'Message is too long. Keep it under 120 characters.'

 

:

 

undefined

}

        

rows

=

{

4

}

        fullWidth

      

/>

      

{

value

?

 

(

        

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

          

Character

count

:

 

{

value

.

length

}

        

</Text

>

      

)

 

:

 

null

}

    

</Block

>

  

)

;

}

Features

Showcases auto-resize, character counting, validation, disabled, and required helper scenarios.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

Text

,

 

TextArea

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

autoResizeValue

,

setAutoResizeValue

]

 

=

 

useState

(

    

'Type more text to see auto-resize in action...\n\nAdd multiple lines to watch the text area grow and shrink with content.'

  

)

;

  

const

 

[

counterValue

,

setCounterValue

]

 

=

 

useState

(

''

)

;

  

const

 

[

errorValue

,

setErrorValue

]

 

=

 

useState

(

''

)

;

 

  

return

 

(

    

<Block

fullWidth

>

        

<TextArea

          

label

=

"Auto-resize message"

          

placeholder

=

"Adjusts height between two and six rows based on content."

          

value

=

{

autoResizeValue

}

          

onChangeText

=

{

setAutoResizeValue

}

          autoResize

          

minRows

=

{

2

}

          

maxRows

=

{

6

}

          fullWidth

        

/>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Character

counter

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Enforces

a maximum length

while

surfacing a live counter

.

        

</Text

>

        

<TextArea

          

label

=

"Support message"

          

placeholder

=

"Type to see the counter (max 100 characters)"

          

value

=

{

counterValue

}

          

onChangeText

=

{

setCounterValue

}

          

maxLength

=

{

100

}

          showCharCounter

          

rows

=

{

3

}

          

helperText

=

"Helpful for concise feedback or short-form inputs."

          fullWidth

        

/>

      

</Block

>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Error

and required states

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Show

validation messaging when the field is empty

.

        

</Text

>

        

<TextArea

          

label

=

"Required response"

          

placeholder

=

"This field cannot be empty"

          

value

=

{

errorValue

}

          

onChangeText

=

{

setErrorValue

}

          

error

=

{

errorValue

.

length

>

 

0

 

?

 

undefined

 

:

 

'A response is required before submission.'

}

          required

          

rows

=

{

3

}

          fullWidth

        

/>

      

</Block

>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Disabled

field

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Communicates

when editing is not allowed

.

        

</Text

>

        

<TextArea

          

label

=

"Disabled text area"

          

placeholder

=

"Disabled state"

          

value

=

"This text area is disabled and cannot be edited."

          disabled

          

rows

=

{

2

}

          fullWidth

        

/>

      

</Block

>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Required

helper copy

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Pair

helper text with the required badge to give extra guidance

.

        

</Text

>

        

<TextArea

          

label

=

"Required with helper"

          

placeholder

=

"Add details"

          required

          

rows

=

{

2

}

          

helperText

=

"Required fields display an asterisk and supporting guidance."

          fullWidth

        

/>

      

</Block

>

    

</Block

>

  

)

;

}

Sizes

Walks the full size scale, xs through 3xl, so the field matches the surrounding form density.

Loading demo…

import

 

{

 

Block

,

 

Text

,

 

TextArea

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

const

 

SIZES

 

=

 

[

'xs'

,

 

'sm'

,

 

'md'

,

 

'lg'

,

 

'xl'

,

 

'2xl'

,

 

'3xl'

]

as

const

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Block

fullWidth

>

      

{

SIZES

.

map

(

(

size

)

 

=>

 

(

        

<Block

 

key

=

{

size

}

fullWidth

>

          

<Text

 

variant

=

"small"

 

color

=

"secondary"

>

{

size

}

</Text

>

          

<TextArea

 

size

=

{

size

}

 

rows

=

{

3

}

 

placeholder

=

"Write a message"

fullWidth

/>

        

</Block

>

      

)

)

}

    

</Block

>

  

)

;

}

Validation

Demonstrates required validation, length limits, inline success messaging, and error summaries.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

Button

,

 

Text

,

 

TextArea

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

type

 

ValidationErrors

 

=

 

{

  feedback

?:

 

string

;

  message

?:

 

string

;

}

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

feedback

,

setFeedback

]

 

=

 

useState

(

''

)

;

  

const

 

[

message

,

setMessage

]

 

=

 

useState

(

''

)

;

  

const

 

[

errors

,

setErrors

]

 

=

useState

<ValidationErrors

>

(

{

}

)

;

  

const

 

[

status

,

setStatus

]

 

=

 

useState

(

''

)

;

 

  

const

validateForm

=

 

(

)

 

=>

 

{

    

const

nextErrors

:

 

ValidationErrors

 

=

 

{

}

;

 

    

if

 

(

!

feedback

.

trim

(

)

)

 

{

      nextErrors

.

feedback

=

 

'Feedback is required.'

;

    

}

 

else

 

if

 

(

feedback

.

trim

(

)

.

length

<

 

10

)

 

{

      nextErrors

.

feedback

=

 

'Feedback must be at least 10 characters.'

;

    

}

 

    

if

 

(

message

.

length

>

 

500

)

 

{

      nextErrors

.

message

=

 

'Message cannot exceed 500 characters.'

;

    

}

 

    

setErrors

(

nextErrors

)

;

    

return

 

Object

.

keys

(

nextErrors

)

.

length

===

 

0

;

  

}

;

 

  

const

handleSubmit

=

 

(

)

 

=>

 

{

    

if

 

(

validateForm

(

)

)

 

{

      

setStatus

(

'Feedback submitted successfully.'

)

;

      

return

;

    

}

 

    

setStatus

(

''

)

;

  

}

;

 

  

return

 

(

    

<Block

fullWidth

>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Required

feedback

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Must

include at least ten characters before the form can submit

.

        

</Text

>

        

<TextArea

          

label

=

"Feedback"

          

placeholder

=

"Share your thoughts (minimum 10 characters)"

          

value

=

{

feedback

}

          

onChangeText

=

{

(

value

)

 

=>

 

{

            

setFeedback

(

value

)

;

            

if

 

(

errors

.

feedback

)

 

{

              

setErrors

(

(

prev

)

 

=>

 

(

{

 

.

.

.

prev

,

feedback

:

 

undefined

 

}

)

)

;

            

}

          

}

}

          

error

=

{

errors

.

feedback

}

          required

          

rows

=

{

4

}

          

helperText

=

"Tell us what went well and what could improve."

          fullWidth

        

/>

      

</Block

>

 

 

      

<Button

 

variant

=

"filled"

 

onPress

=

{

handleSubmit

}

>

        

Submit

feedback

      

</Button

>

 

      

{

status

?

 

(

        

<Text

 

size

=

"xs"

 

color

=

"success"

>

          

{

status

}

        

</Text

>

      

)

 

:

 

null

}

 

      

{

Object

.

keys

(

errors

)

.

length

>

 

0

 

&&

 

(

        

<Block

          

style

=

{

{

            borderRadius

:

 

8

,

            borderWidth

:

 

1

,

            borderColor

:

 

'#FCA5A5'

,

            backgroundColor

:

 

'#FEF2F2'

,

            padding

:

 

12

,

          

}

}

        

>

          

<Text

 

size

=

"sm"

 

weight

=

"semibold"

 

color

=

"error"

>

            

Please

fix the following before submitting

:

          

</Text

>

          

{

Object

.

values

(

errors

)

            

.

filter

(

Boolean

)

            

.

map

(

(

errorMessage

)

 

=>

 

(

              

<Text

 

key

=

{

errorMessage

}

 

size

=

"xs"

 

color

=

"error"

>

                •

{

errorMessage

}

              

</Text

>

            

)

)

}

        

</Block

>

      

)

}

    

</Block

>

  

)

;

}

Scan to open this page on your phonereact-ui-library.com/components/TextArea

</>

react-ui-library

100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.

A Platform Blocks product.