1# TextArea 2 3The **\<TextArea>** component provides multi-line text input and automatically wraps text so that each line does not have more than the width of the component. 4 5> **NOTE** 6> 7> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10## Child Components 11 12Not supported 13 14 15## APIs 16 17TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController}) 18 19**Parameters** 20 21| Name | Type | Mandatory | Description | 22| ----------------------- | ---------------------------------------- | ---- | -------------- | 23| placeholder | [ResourceStr](ts-types.md#resourcestr) | No | Text displayed when there is no input.<br>When only the **placeholder** attribute is set, the text selection handle is still available; the caret stays at the beginning of the placeholder text when the handle is released. | 24| text | [ResourceStr](ts-types.md#resourcestr) | No | Current text input.<br>If the component has [stateStyles](ts-universal-attributes-polymorphic-style.md) or any other attribute that may trigger updating configured, you are advised to bind the state variable to the text in real time through the **onChange** event,<br>so as to prevent display errors when the component is updated.<br>Since API version 10, this parameter supports two-way binding through [$$](../../quick-start/arkts-two-way-sync.md).| 25| controller<sup>8+</sup> | [TextAreaController](#textareacontroller8) | No | Text area controller.| 26 27 28## Attributes 29 30Among the [universal attributes](ts-universal-attributes-size.md) and [universal text attributes](ts-universal-attributes-text-style.md), **fontColor**, **fontSize**, **fontStyle**, **fontWeight**, and **fontFamily** are supported. In addition, the following attributes are supported. 31 32| Name | Type | Description | 33| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | 34| placeholderColor | [ResourceColor](ts-types.md#resourcecolor) | Placeholder text color.<br>The default value follows the theme. | 35| placeholderFont | [Font](ts-types.md#font) | Placeholder text style, including the font size, font width, font family, and font style. Currently, only the default font family is supported.| 36| textAlign | [TextAlign](ts-appendix-enums.md#textalign) | Horizontal alignment of the text.<br>Default value: **TextAlign.Start**<br>**NOTE**<br>Available options are **TextAlign.Start**, **TextAlign.Center**, and **TextAlign.End**.<br>To set vertical alignment for the text, use the [align](ts-universal-attributes-location.md) attribute. The **align** attribute alone does not control the horizontal position of the text. In other words, **Alignment.TopStart**, **Alignment.Top**, and **Alignment.TopEnd** produce the same effect, top-aligning the text; **Alignment.Start**, **Alignment.Center**, and **Alignment.End** produce the same effect, centered-aligning the text vertically; **Alignment.BottomStart**, **Alignment.Bottom**, and **Alignment.BottomEnd** produce the same effect, bottom-aligning the text.| 37| caretColor | [ResourceColor](ts-types.md#resourcecolor) | Color of the caret in the text box.<br>Default value: **'#007DFF'** | 38| inputFilter<sup>8+</sup> | {<br>value: [ResourceStr](ts-types.md#resourcestr),<br>error?: (value: string) => void<br>} | Regular expression for input filtering. Only inputs that comply with the regular expression can be displayed. Other inputs are filtered out. The specified regular expression can match single characters, but not strings.<br>- **value**: regular expression to set.<br>- **error**: filtered-out content to return when regular expression matching fails.| 39| copyOption<sup>9+</sup> | [CopyOptions](ts-appendix-enums.md#copyoptions9) | Whether copy and paste is allowed.<br>Default value: **CopyOptions.LocalDevice**<br>If this attribute is set to **CopyOptions.None**, the paste operation is allowed, but the copy and cut operations are not.| 40| maxLength<sup>10+</sup> | number | Maximum number of characters in the text input.<br>By default, there is no maximum number of characters.<br>When the maximum number of characters is reached, no more characters can be entered, and the border turns red.| 41| showCounter<sup>10+</sup> | boolean | Whether to show the number of entered characters when **maxLength** is set.<br>Default value: **false** | 42| style<sup>10+</sup> | [TextContentStyle](ts-appendix-enums.md#textcontentstyle10) | Style of the component.<br>Default value: **TextContentStyle.DEFAULT** | 43| enableKeyboardOnFocus<sup>10+</sup> | boolean | Whether to enable the input method when the component obtains focus.<br>Default value: **true** | 44| selectionMenuHidden<sup>10+</sup> | boolean | Whether to display the text selection menu when the text box is long-pressed or right-clicked.<br>Default value: **false**| 45| barState<sup>10+</sup> | [BarState](ts-appendix-enums.md#BarState) | Scrollbar state when the inline input style is used.<br>Default value: **BarState.Auto**| 46| maxLines<sup>10+</sup> | number | Maximum number of lines that can be displayed when the inline input style is used.<br>Default value: **3**| 47| customKeyboard<sup>10+</sup> | [CustomBuilder](ts-types.md#custombuilder8) | Custom keyboard.<br>**NOTE**<br>When a custom keyboard is set, activating the text box opens the specified custom component, instead of the system input method.<br>The custom keyboard's height can be set through the **height** attribute of the custom component's root node, and its width is fixed at the default value.<br>The custom keyboard is displayed on top of the current page, without compressing or raising the page.<br>The custom keyboard cannot obtain the focus, but it blocks gesture events.<br>By default, the custom keyboard is closed when the input component loses the focus. You can also use the [TextAreaController](#textareacontroller8).[stopEditing](#stopediting10) API to close the keyboard.| 48 49> **NOTE** 50> 51> The default value of the universal attribute [padding](ts-universal-attributes-size.md) is as follows: <br>{<br> top: 8 vp,<br> right: 16 vp,<br> bottom: 8 vp,<br> left: 16 vp<br> } 52 53## Events 54 55In addition to the [universal events](ts-universal-events-click.md), the following events are supported. 56 57| Name | Description | 58| ------------------------------------------------------------ | ------------------------------------------------------------ | 59| onChange(callback: (value: string) => void) | Triggered when the input in the text box changes.<br>- **value**: text entered.| 60| onEditChange(callback: (isEditing: boolean) => void)<sup>10+</sup> | Triggered when the input status changes. When the cursor is placed in the text box, it is in the editing state. Otherwise, it is in the non-editing state. If the value of **isEditing** is **true**, text input is in progress.| 61| onCopy<sup>8+</sup>(callback:(value: string) => void) | Triggered when the copy button on the pasteboard, which displays when the text box is long pressed, is clicked.<br>- **value**: text to be copied.| 62| onCut<sup>8+</sup>(callback:(value: string) => void) | Triggered when the cut button on the pasteboard, which displays when the text box is long pressed, is clicked.<br>- **value**: text to be cut.| 63| onPaste<sup>8+</sup>(callback:(value: string) => void) | Triggered when the paste button on the pasteboard, which displays when the text box is long pressed, is clicked.<br>- **value**: text to be pasted.| 64| onTextSelectionChange(callback: (selectionStart: number, selectionEnd: number) => void)<sup>10+</sup> | Triggered when the text selection position changes.<br>**selectionStart**: start position of the text selection area. The start position of text in the text box is **0**.<br>**selectionEnd**: end position of the text selection area.| 65| onContentScroll(callback: (totalOffsetX: number, totalOffsetY: number) => void)<sup>10+</sup> | Triggered when the text content is scrolled.<br>**totalOffsetX**: X coordinate offset of the text in the content area.<br>**totalOffsetY**: Y coordinate offset of the text in the content area.| 66 67## TextAreaController<sup>8+</sup> 68 69Defines the controller for controlling the **\<TextArea>** component. Currently, the controller can be used to control the caret position. 70 71### Objects to Import 72 73``` 74controller: TextAreaController = new TextAreaController() 75``` 76 77### caretPosition<sup>8+</sup> 78 79caretPosition(value: number): void 80 81Sets the position of the caret. 82 83**Parameters** 84 85| Name| Type| Mandatory| Description | 86| ------ | -------- | ---- | -------------------------------------- | 87| value | number | Yes | Length from the start of the string to the position where the caret is located.| 88 89### setTextSelection<sup>10+</sup> 90 91setTextSelection(selectionStart: number, selectionEnd: number): void 92 93Sets the text selection range and highlights the selected text when the component is focused. This API works only when the value of **selectionStart** is less than that of **selectionEnd**. 94 95**Parameters** 96 97| Name | Type| Mandatory| Description | 98| -------------- | -------- | ---- | ------------------------------------------------------------ | 99| selectionStart | number | Yes | Start position of the text selection range. The start position of text in the text box is 0.<br>A value less than 0 evaluates to the value **0**. A value greater than the maximum text length evaluates to the maximum text length.<br>| 100| selectionEnd | number | Yes | End position of the text selection range.<br>A value less than 0 evaluates to the value **0**. A value greater than the maximum text length evaluates to the maximum text length.<br>| 101 102### stopEditing<sup>10+</sup> 103 104stopEditing(): void 105 106Exits the editing state. 107 108### getTextContentRect<sup>10+</sup> 109 110getTextContentRect(): [RectResult](#rectresult10) 111 112Obtains the position of the edited text area relative to the component and its size. The unit of the return value is pixel. 113 114**Return value** 115 116| Type | Description | 117| ------------------- | -------- | 118| [RectResult](#rectresult10) | Position of the edited text area relative to the component and its size.| 119 120> **NOTE** 121> 122> - If no text is entered, the return value contains the position information, but the size is 0. 123> - The position information is the offset of the first character relative to the editable area. 124> - If there is input, the width in the return value is the fixed width of the editable area. 125 126### RectResult<sup>10+</sup> 127 128Describes the position and size. 129 130| Parameter | Type | Description| 131| ------- | ------ | ----------------------- | 132| x | number | X coordinate.| 133| y | number | Y coordinate.| 134| width | number | Content width.| 135| height | number | Content height.| 136 137 138### getTextContentLineCount<sup>10+</sup> 139 140getTextContentLineCount(): number 141 142Obtains the number of lines of the edited text. 143 144**Return value** 145 146| Type | Description | 147| ----- | -------- | 148| number| Number of lines of the edited text.| 149 150## Example 151 152### Example 1 153 154```ts 155// xxx.ets 156@Entry 157@Component 158struct TextAreaExample { 159 @State text: string = '' 160 controller: TextAreaController = new TextAreaController() 161 162 build() { 163 Column() { 164 TextArea({ 165 text: this.text, 166 placeholder: 'The text area can hold an unlimited amount of text. input your word...', 167 controller: this.controller 168 }) 169 .placeholderFont({ size: 16, weight: 400 }) 170 .width(336) 171 .height(56) 172 .margin(20) 173 .fontSize(16) 174 .fontColor('#182431') 175 .backgroundColor('#FFFFFF') 176 .onChange((value: string) => { 177 this.text = value 178 }) 179 Text(this.text) 180 Button('Set caretPosition 1') 181 .backgroundColor('#007DFF') 182 .margin(15) 183 .onClick(() => { 184 // Move the caret to after the first entered character. 185 this.controller.caretPosition(1) 186 }) 187 }.width('100%').height('100%').backgroundColor('#F1F3F5') 188 } 189} 190``` 191 192 193 194### Example 2 195 196```ts 197// xxx.ets 198@Entry 199@Component 200struct TextAreaExample { 201 @State text: string = 'test' 202 @State counterVisible: boolean = false 203 @State maxNumber: number = -1 204 controller: TextAreaController = new TextAreaController() 205 206 build() { 207 Column() { 208 TextArea({ 209 text: this.text, 210 placeholder: 'The text area can hold an unlimited amount of text. input your word...', 211 controller: this.controller 212 }) 213 .placeholderFont({ size: 16, weight: 400 }) 214 .width(336) 215 .height(56) 216 .margin(20) 217 .fontSize(16) 218 .fontColor('#182431') 219 .maxLength(4) 220 .showCounter(true) 221 .backgroundColor('#FFFFFF') 222 .onChange((value: string) => { 223 this.text = value 224 }) 225 }.width('100%').height('100%').backgroundColor('#F1F3F5') 226 } 227} 228``` 229 230 231 232 233### Example 3 234 235```ts 236// xxx.ets 237@Entry 238@Component 239struct TextAreaExample { 240 controller: TextAreaController = new TextAreaController() 241 @State inputValue: string = "" 242 243 // Create a custom keyboard component. 244 @Builder CustomKeyboardBuilder() { 245 Column() { 246 Button('x').onClick(() => { 247 // Disable the custom keyboard. 248 this.controller.stopEditing() 249 }) 250 Grid() { 251 ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item) => { 252 GridItem() { 253 Button(item + "") 254 .width(110).onClick(() => { 255 this.inputValue += item 256 }) 257 } 258 }) 259 }.maxCount(3).columnsGap(10).rowsGap(10).padding(5) 260 }.backgroundColor(Color.Gray) 261 } 262 263 build() { 264 Column() { 265 TextArea({ controller: this.controller, text: this.inputValue}) 266 // Bind the custom keyboard. 267 .customKeyboard(this.CustomKeyboardBuilder()).margin(10).border({ width: 1 }) 268 .height(200) 269 } 270 } 271} 272``` 273 274 275