1# Rich Text (RichEditor) 2**RichEditor** is a component that supports interactive text editing and mixture of text and images. It is typically used in scenarios where mixed-content user input is expected, such as comment sections that accept both image and text submissions. For details, see [RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md). 3 4## Creating a RichEditor Component 5You can create a **RichEditor** component with or without a styled string. 6 7### Creating a RichEditor Component Without a Styled String 8Use the **RichEditor(value: [RichEditorOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditoroptions))** API to generate a **RichEditor** component from scratch. This approach is typically employed when you wish to present straightforward text and image content, for example, contact details. It can also serve in instances where a consistent content format is desired, such as in certain code editors. 9 10```ts 11controller: RichEditorController = new RichEditorController(); 12options: RichEditorOptions = { controller: this.controller }; 13 14RichEditor(this.options) 15 .onReady(() => { 16 this.controller.addTextSpan('Create a RichEditor component without using a styled string.', { 17 style: { 18 fontColor: Color.Black, 19 fontSize: 15 20 } 21 }) 22 }) 23``` 24 25 26### Creating a RichEditor Component with a Styled String 27Alternatively, you can use the **RichEditor(options: [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12))** API to create a **RichEditor** component that is based on a styled string. This approach is particularly useful when you aim to enhance the GUI's aesthetics and emphasize the content, 28 29because it allows for a variety of text formatting options, including changing font size, adding font colors, making text interactive, and custom text rendering. In addition, this approach offers an array of style objects that cover a range of common text formatting styles, such as text with decorative lines, line height, and shadow effects. 30 31```ts 32mutableStyledString: MutableStyledString = new MutableStyledString("Create a RichEditor component using a styled string.", 33 [{ 34 start: 0, 35 length: 5, 36 styledKey: StyledStringKey.FONT, 37 styledValue: this.fontStyle 38 }]); 39 40controller: RichEditorStyledStringController = new RichEditorStyledStringController(); 41options: RichEditorStyledStringOptions = {controller: this.controller}; 42 43RichEditor(this.options) 44 .onReady(() => { 45 this.controller.setStyledString(this.mutableStyledString); 46 }) 47``` 48 49 50## Setting Attributes 51 52### Setting the Custom Context Menu on Text Selection 53You can set a custom context menu on text selection using the [bindSelectionMenu](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#bindselectionmenu) API. 54 55By default, the context menu on text selection includes the copy, cut, and select all options. You can offer additional options for enhanced interactions, for example, a translate option for multilingual support or a bold option for emphasizing selected text. 56 57If the custom menu is too long, consider embedding a **Scroll** component to prevent the keyboard from being blocked. 58 59```ts 60RichEditor(this.options) 61 .onReady(() => { 62 this.controller.addTextSpan('The component has a custom menu that can be triggered by a long press.', { 63 style: { 64 fontColor: Color.Black, 65 fontSize: 18 66 } 67 }) 68 }) 69 .bindSelectionMenu(RichEditorSpanType.TEXT, this.SystemMenu, ResponseType.LongPress, { 70 onDisappear: () => { 71 this.sliderShow = false 72 } 73 }) 74 .width(300) 75 .height(300) 76 77@Builder 78SystemMenu() { 79 Column() { 80 Menu() { 81 if (this.controller) { 82 MenuItemGroup() { 83 MenuItem({ 84 startIcon: this.theme.cutIcon, 85 content: "Cut", 86 labelInfo: "Ctrl+X", 87 }) 88 MenuItem({ 89 startIcon: this.theme.copyIcon, 90 content: "Copy", 91 labelInfo: "Ctrl+C" 92 }) 93 MenuItem({ 94 startIcon: this.theme.pasteIcon, 95 content: "Paste", 96 labelInfo: "Ctrl+V" 97 }) 98 } 99 } 100 } 101 .radius(this.theme.containerBorderRadius) 102 .clip(true) 103 .backgroundColor(Color.White) 104 .width(this.theme.defaultMenuWidth) 105 } 106 .width(this.theme.defaultMenuWidth) 107} 108``` 109 110 111 112### Setting Caret and Selection Handle Colors in the Text Box 113You can set the caret and selection handle colors in the text box using the [caretColor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#caretcolor12) API. 114 115This feature allows for a more distinct visual representation of the caret and text selection, which can significantly aid users in navigating through complex UI that incorporate various input fields. It can also be particularly beneficial for text boxes that signify special features or states, such as a password text area. 116 117```ts 118RichEditor(this.options) 119 .onReady(() => { 120 this.controller.addTextSpan('The component has the color set for the caret and selection handle.', { 121 style: { 122 fontColor: Color.Black, 123 fontSize: 15 124 } 125 }) 126 }) 127 .caretColor(Color.Orange) 128 .width(300) 129 .height(300) 130``` 131 132 133 134### Setting Placeholder Text 135You can set the placeholder text, which is displayed when there is no input, using the [placeholder](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#placeholder12) API. 136 137Placeholder text serves as a useful cue, assisting users in navigating through your application's UI, particularly in scenarios where text areas require specific attention or instructions, such as a login screen, or a text editing box with a character limit. 138 139```ts 140RichEditor(this.options) 141 .placeholder("Enter your content here", { 142 fontColor: Color.Gray, 143 font: { 144 size: 15, 145 weight: FontWeight.Normal, 146 family: "HarmonyOS Sans", 147 style: FontStyle.Normal 148 } 149 }) 150 .width(300) 151 .height(300) 152``` 153 154 155 156For details about all available attributes, see [RichEditor Attributes](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#attributes). 157 158## Adding Events 159 160### Adding a Callback for Component Initialization 161Use the [onReady](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onready) API to add a callback that is invoked after the component has been initialized. 162 163This callback can be used to effectively display rich content including images, texts, and emoticons after the component is initialized. When the **RichEditor** component is used to display news, this callback can initiate the process of obtaining image and text data from the server. The obtained data is then populated into the component, ensuring that the complete news content is promptly displayed on the page after initialization. 164 165```ts 166RichEditor(this.options) 167 .onReady(() => { 168 this.controller.addTextSpan('The onReady callback content is preset text within the component.', { 169 style: { 170 fontColor: Color.Black, 171 fontSize: 15 172 } 173 }) 174 }) 175``` 176 177 178 179### Adding a Callback for Content Selection 180Use the [onSelect](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onselect) API to add a callback that is invoked when content within the component is selected. 181 182This callback can be used to enhance the user experience following text selection For example, it can be used to trigger a context menu, allowing users to modify text styles, or to perform content analysis and processing on the selected text, providing input suggestions and thereby improving the efficiency and convenience of text editing. 183 184The callback can be triggered in two ways: by pressing and releasing the left mouse button to select content, or by selecting content with a finger touch and releasing the finger. 185 186```ts 187RichEditor(this.options) 188 .onReady(() => { 189 this.controller.addTextSpan('Select this text to invoke the onSelect callback.', { 190 style: { 191 fontColor: Color.Black, 192 fontSize: 15 193 } 194 }) 195 }) 196 .onSelect((value: RichEditorSelection) => { 197 this.controller1.addTextSpan(JSON.stringify(value), { 198 style: { 199 fontColor: Color.Gray, 200 fontSize: 10 201 } 202 }) 203 }) 204 .width(300) 205 .height(50) 206Text('View callback content:').fontSize(10).fontColor(Color.Gray).width(300) 207RichEditor(this.options1) 208 .width(300) 209 .height(70) 210``` 211 212 213 214### Adding Callbacks for Before and After Text and Image Changes 215Use the [onWillChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onwillchange12) API to add a callback invoked before text or image changes. This callback is applicable to real-time data verification and notification. For example, it can be used to enable features such as detecting sensitive words and displaying an alert dialog box immediately, as well as real-time character count statistics and limitation. 216 217Use the [onDidChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidchange12) API to add a callback invoked after text or image changes. This callback applies to content saving and synchronization. For example, it can be used to automatically save the latest content to the local host or synchronizing it to the server, and for updating content status and rendering. 218 219Note that the **RichEditor** component constructed with [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) does not support these two types of callbacks. 220 221```ts 222RichEditor(this.options) 223 .onReady(() => { 224 this.controller.addTextSpan('The callback is invoked before the text or image change.\nThe callback is invoked after the text or image change.', { 225 style: { 226 fontColor: Color.Black, 227 fontSize: 15 228 } 229 }) 230 }) 231 .onWillChange((value: RichEditorChangeValue) => { 232 this.controller1.addTextSpan('The callback is invoked before the text or image change: \n' + JSON.stringify(value), { 233 style: { 234 fontColor: Color.Gray, 235 fontSize: 10 236 } 237 }) 238 return true; 239 }) 240 .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => { 241 this.controller1.addTextSpan('\nThe callback is invoked after the text or image change: \nrangeBefore: ' + JSON.stringify(rangeBefore) + '\nrangeAfter: ' + JSON.stringify(rangeBefore), { 242 style: { 243 fontColor: Color.Gray, 244 fontSize: 10 245 } 246 }) 247 return true; 248 }) 249 .width(300) 250 .height(50) 251Text('View callback content:').fontSize(10).fontColor(Color.Gray).width(300) 252RichEditor(this.options1) 253 .width(300) 254 .height(70) 255``` 256 257 258 259### Adding Callbacks for Before and After Content Input in the Input Method 260To facilitate intelligent input assistance, use [aboutToIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#abouttoimeinput) to trigger a callback before adding input content, and [onIMEInputComplete](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onimeinputcomplete) to trigger a callback after the input is complete. 261 262These callbacks can be used to provide text prediction before user input and to perform automatic error correction or format conversion after input completion. 263 264Note that the **RichEditor** component constructed with [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) does not support these two types of callbacks. 265 266```ts 267RichEditor(this.options) 268 .onReady(() => { 269 this.controller.addTextSpan('The callback is invoked before content input in the input method.\nThe callback is invoked when text input in the input method is complete.' , { 270 style: { 271 fontColor: Color.Black, 272 fontSize: 15 273 } 274 }) 275 }) 276 .aboutToIMEInput((value: RichEditorInsertValue) => { 277 this.controller1.addTextSpan('The callback is invoked before content input in the input method: \n'+JSON.stringify(value), { 278 style: { 279 fontColor: Color.Gray, 280 fontSize: 10 281 } 282 }) 283 return true; 284 }) 285 .onIMEInputComplete((value: RichEditorTextSpanResult) => { 286 this.controller1.addTextSpan('The callback is invoked when text input in the input method is complete: \n'+ JSON.stringify(value), { 287 style: { 288 fontColor: Color.Gray, 289 fontSize: 10 290 } 291 }) 292 return true; 293 }) 294 .width(300) 295 .height(50) 296Text('View callback content:').fontSize(10).fontColor(Color.Gray).width(300) 297RichEditor(this.options1) 298 .width(300) 299 .height(70) 300``` 301 302 303 304### Adding a Callback for Before Paste Completion 305Use the [onPaste](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onpaste11) API to add a callback invoked when the paste is about to be completed. 306 307This is useful for content format processing, such as converting text containing HTML tags to a format supported by the **RichEditor** component and removing unnecessary tags or retaining only plain text content. 308 309You can use this API to override the default pasting behavior, which is limited to plain text, so that both images and text can be pasted. 310 311```ts 312RichEditor(this.options) 313 .onReady(() => { 314 this.controller.addTextSpan('Copy and paste operations on this text trigger the corresponding callbacks.', { 315 style: { 316 fontColor: Color.Black, 317 fontSize: 15 318 } 319 }) 320 }) 321 .onPaste(() => { 322 this.controller1.addTextSpan('The onPaste callback is invoked.\n', { 323 style: { 324 fontColor: Color.Gray, 325 fontSize: 10 326 } 327 }) 328 }) 329 .width(300) 330 .height(70) 331``` 332 333### Adding a Callback for Before Cut Completion 334Use the [onCut](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncut12) API to add a callback invoked when text is about to be cut. 335 336This can be used to temporarily store the cut content, ensuring accurate restoration in subsequent pasting operations. 337 338You can use this API to override the default cutting behavior, which is limited to plain text, so that both images and text can be cut. 339 340```ts 341RichEditor(this.options) 342 .onReady(() => { 343 this.controller.addTextSpan('Copy and paste operations on this text trigger the corresponding callbacks.', { 344 style: { 345 fontColor: Color.Black, 346 fontSize: 15 347 } 348 }) 349 }) 350 .onCut(() => { 351 this.controller1.addTextSpan('The onCut callback is invoked.\n', { 352 style: { 353 fontColor: Color.Gray, 354 fontSize: 10 355 } 356 }) 357 }) 358 .width(300) 359 .height(70) 360``` 361 362### Adding a Callback for Before Copy Completion 363Use the [onCopy](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncopy12) API to add a callback invoked when text is about to be copied. 364 365This callback applies to content backup and sharing. For example, the following operations can be performed in the callback: saving the copied content and its format information to a local backup folder, or automatically generating copywriting that includes the copied content and a product purchase link for users to paste and share. 366 367You can use this API to override the default copying behavior, which is limited to plain text, so that both images and text can be copied. 368 369```ts 370RichEditor(this.options) 371 .onReady(() => { 372 this.controller.addTextSpan('Copy and paste operations on this text trigger the corresponding callbacks.', { 373 style: { 374 fontColor: Color.Black, 375 fontSize: 15 376 } 377 }) 378 }) 379 .onCopy(() => { 380 this.controller1.addTextSpan('The onCopy callback is invoked.\n', { 381 style: { 382 fontColor: Color.Gray, 383 fontSize: 10 384 } 385 }) 386 }) 387 .width(300) 388 .height(70) 389``` 390 391 392 393 394For details about all available events, see [RichEditor Events](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#events). 395 396## Setting the Typing Style 397Use the [setTypingStyle](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#settypingstyle11) API to set the typing style. 398 399This allows you to deliver a personalized writing experience. For example, you might want to use this API to automatically apply corresponding formats to different levels of headings (such as level-1 and level-2 headings) as users type. 400 401```ts 402RichEditor(this.options) 403 .onReady(() => { 404 this.controller.addTextSpan('Click the button to change the preset typing style.', { 405 style: { 406 fontColor: Color.Black, 407 fontSize: 15 408 } 409 }) 410 }) 411 .width(300) 412 .height(60) 413Button('setTypingStyle', { 414 buttonStyle: ButtonStyleMode.NORMAL 415 }) 416 .height(30) 417 .fontSize(13) 418 .onClick(() => { 419 this.controller.setTypingStyle({ 420 fontWeight: 'medium', 421 fontColor: Color.Pink, 422 fontSize: 15, 423 fontStyle: FontStyle.Italic, 424 decoration: { 425 type: TextDecorationType.Underline, 426 color: Color.Gray 427 } 428 }) 429 }) 430``` 431 432 433 434## Setting Highlight for Selected Content 435Use the [setSelection](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#setselection11) API to configure the component to highlight the background of the selected portion. 436 437This API enables the implementation of text focus effects. For example, clicking a title or abstract can trigger the automatic selection and highlighting of the corresponding text content. 438 439If this API is called when the text box is not focused, the selection effect is not displayed. 440 441```ts 442RichEditor(this.options) 443 .onReady(() => { 444 this.controller.addTextSpan('Click the button to select the text at positions 0 to 2 here.', { 445 style: { 446 fontColor: Color.Black, 447 fontSize: 15 448 } 449 }) 450 }) 451 .width(300) 452 .height(60) 453Button('setSelection(0,2)', { 454 buttonStyle: ButtonStyleMode.NORMAL 455 }) 456 .height(30) 457 .fontSize(13) 458 .onClick(() => { 459 this.controller.setSelection(0, 2) 460 }) 461``` 462 463 464 465## Adding a Text Span 466In addition to directly entering content into the component, you can add a text span using the [addTextSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addtextspan) API. 467 468This API offers a way to diversify text styles. For example, you can use it to create mixed text styles. 469 470When the component is focused and the cursor is blinking, adding text content through **addTextSpan** updates the cursor position to the right of the newly added text. 471 472```ts 473RichEditor(this.options) 474 .onReady(() => { 475 this.controller.addTextSpan('Click the button to add text here.', { 476 style: { 477 fontColor: Color.Black, 478 fontSize: 15 479 } 480 }) 481 }) 482 .width(300) 483 .height(100) 484Button('addTextSpan', { 485 buttonStyle: ButtonStyleMode.NORMAL 486 }) 487 .height(30) 488 .fontSize(13) 489 .onClick(() => { 490 this.controller.addTextSpan('Add text.') 491 }) 492``` 493 494 495 496## Adding an Image Span 497Use the [addImageSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addimagespan) API to add an image span. 498 499This API is useful in enriching and visualizing content. For example, you can use it to add images to news or data visualization graphics to documents. 500 501When the component is focused and the cursor is blinking, adding image content through **addImageSpan** updates the cursor position to the right of the newly added image. 502 503```ts 504RichEditor(this.options) 505 .onReady(() => { 506 this.controller.addTextSpan('Click the button to add an image here.', { 507 style: { 508 fontColor: Color.Black, 509 fontSize: 15 510 } 511 }) 512 }) 513 .width(300) 514 .height(100) 515Button('addImageSpan', { 516 buttonStyle: ButtonStyleMode.NORMAL 517 }) 518 .height(30) 519 .fontSize(13) 520 .onClick(() => { 521 this.controller.addImageSpan($r("app.media.startIcon"), { 522 imageStyle: { 523 size: ["57px", "57px"] 524 } 525 }) 526 }) 527``` 528 529 530 531## Adding @Builder Decorated Content 532Use [addBuilderSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addbuilderspan11) to add the content decorated by the @Builder decorator. 533 534This approach applies when you need to integrate customized complex components, such as custom charts. 535 536With this API, you can specify the addition position using [RichEditorBuilderSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorbuilderspanoptions11). If no position is specified or an abnormal value is provided, the builder is appended to the end of all content. 537 538```ts 539@Builder 540TextBuilder() { 541 Row() { 542 Image($r('app.media.startIcon')).width(50).height(50).margin(16) 543 Column() { 544 Text("Text.txt").fontWeight(FontWeight.Bold).fontSize(16) 545 Text("123.45KB").fontColor('#8a8a8a').fontSize(12) 546 }.alignItems(HorizontalAlign.Start) 547 }.backgroundColor('#f4f4f4') 548 .borderRadius("20") 549 .width(220) 550} 551 552Button('addBuilderSpan', { 553 buttonStyle: ButtonStyleMode.NORMAL 554 }) 555 .height(30) 556 .fontSize(13) 557 .onClick(() => { 558 this.my_builder = () => { 559 this.TextBuilder() 560 } 561 this.controller.addBuilderSpan(this.my_builder) 562 }) 563``` 564 565 566## Adding a Symbol Span 567Use the [addSymbolSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addsymbolspan11) API to add symbol content. This API enables the addition and display of special characters, such as mathematical symbols in academic papers. 568 569When the component is focused and the cursor is blinking, adding symbol content through **addSymbolSpan** updates the cursor position to the right of the newly added symbol. 570Currently, gestures, copying, and dragging are not supported for the symbol content. 571 572```ts 573RichEditor(this.options) 574 .onReady(() => { 575 this.controller.addTextSpan('Click the button to add a symbol here.', { 576 style: { 577 fontColor: Color.Black, 578 fontSize: 15 579 } 580 }) 581 }) 582 .width(300) 583 .height(100) 584Button('addSymbolSpan', { 585 buttonStyle: ButtonStyleMode.NORMAL 586 }) 587 .height(30) 588 .fontSize(13) 589 .onClick(() => { 590 this.controller.addSymbolSpan($r("sys.symbol.basketball_fill"), { 591 style: { 592 fontSize: 30 593 } 594 }) 595 }) 596``` 597 598 599## Obtaining the Image and Text Information in a Component 600Use the [getSpans](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#getspans) API to obtain information about all images and text in the component, including content, ID, style, and position. After obtaining the position information, you can update the style of the content in the specified range. 601 602This API is useful for obtaining and checking existing content styles, such as in template use cases, and for content parsing and processing, such as in text analysis applications. 603 604```ts 605RichEditor(this.options) 606 .onReady(() => { 607 this.controller.addTextSpan('Click the button to obtain the span information.', { 608 style: { 609 fontColor: Color.Black, 610 fontSize: 15 611 } 612 }) 613 }) 614 .width(300) 615 .height(50) 616Text('View the return value of getSpans: ').fontSize(10).fontColor(Color.Gray).width(300) 617RichEditor(this.options1) 618 .width(300) 619 .height(50) 620Button('getSpans', { 621 buttonStyle: ButtonStyleMode.NORMAL 622 }) 623 .height(30) 624 .fontSize(13) 625 .onClick(() => { 626 this.controller1.addTextSpan(JSON.stringify(this.controller.getSpans()), { 627 style: { 628 fontColor: Color.Gray, 629 fontSize: 10 630 } 631 }) 632 633 }) 634``` 635 636<!--RP1--><!--RP1End--> 637