• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Text
2
3The **\<Text>** component is used to display a piece of textual information.
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
12This component can contain the [\<Span>](ts-basic-components-span.md), [\<ImageSpan>](ts-basic-components-imagespan.md), [\<SymbolSpan>](ts-basic-components-symbolSpan.md), and [\<ContainerSpan>](ts-basic-components-containerspan.md) child components.
13
14## APIs
15
16Text(content?: string | Resource, value?: TextOptions)
17
18Since API version 9, this API is supported in ArkTS widgets.
19
20**Parameters**
21
22| Name| Type| Mandatory| Description|
23| -------- | -------- | -------- | -------- |
24| content | string \| [Resource](ts-types.md#resource) | No| Text content. The content and style set for the **\<Text>** component do not take effect when it contains the **\<Span>** child component.<br>Default value: **' '**|
25| value<sup>11+</sup> | [TextOptions](#textoptions11) | No| Initialization options of the component.|
26
27## Attributes
28
29In addition to the [universal attributes](ts-universal-attributes-size.md) and [universal text attributes](ts-universal-attributes-text-style.md), the following attributes are supported.
30
31| Name                      | Type                           | Description                                              |
32| ----------------------- | ----------------------------------- | ------------------------------------------- |
33| textAlign               | [TextAlign](ts-appendix-enums.md#textalign) | Horizontal alignment mode of the text.<br>Default value: **TextAlign.Start**<br>**NOTE**<br/>The text takes up the full width of the **\<Text>** component. 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. Yet, it can work with the **textAlign** attribute to jointly determine the horizontal position of the text.<br>When **textAlign** is set to **TextAlign.JUSTIFY**, the text in the last line is horizontally aligned with the start edge.<br>Since API version 9, this API is supported in ArkTS widgets.|
34| textOverflow            | {overflow: [TextOverflow](ts-appendix-enums.md#textoverflow)} | Display mode when the text is too long.<br>Default value: **{overflow: TextOverflow.Clip}**<br>**NOTE**<br>Text is clipped at the transition between words. To clip text in the middle of a word, add **\u200B** between characters. Since API version 11, you are advised to use this attribute with the **wordBreak** attribute set to **WordBreak.BREAK_ALL** so that word breaks can occur between any two characters when overflow occurs. For details, see [Example](#example-4).<br>If **overflow** is set to **TextOverflow.None**, **TextOverflow.Clip**, or **TextOverflow.Ellipsis**, this attribute must be used with **maxLines** for the settings to take effect. **TextOverflow.None** produces the same effect as **TextOverflow.Clip**.<br>If **overflow** is set to **TextOverflow.MARQUEE**, the text scrolls in a line, and neither **maxLines** nor **copyOption** takes effect. In this case, the **\<ImageSpan>** component is not supported, and **textAlign** takes effect only when the text is not scrollable.<br>Since API version 9, this API is supported in ArkTS widgets.|
35| maxLines                | number | Maximum number of lines in the text.<br>**NOTE**<br>By default, text is automatically folded. If this attribute is specified, the text will not exceed the specified number of lines. If there is extra text, you can use **textOverflow** to specify how it is displayed.<br>Since API version 9, this API is supported in ArkTS widgets.|
36| lineHeight              | string \| number \| [Resource](ts-types.md#resource)  | Text line height. If the value is less than or equal to **0**, the line height is not limited and the font size is adaptive. If the value of the number type, the unit fp is used.<br>Since API version 9, this API is supported in ArkTS widgets.|
37| decoration              | {<br>type: [TextDecorationType](ts-appendix-enums.md#textdecorationtype),<br>color?: [ResourceColor](ts-types.md#resourcecolor)<br>} | Style and color of the text decorative line.<br>Default value: {<br>type: TextDecorationType.None,<br>color: Color.Black<br>} <br>Since API version 9, this API is supported in ArkTS widgets.|
38| baselineOffset          | number \| string | Baseline offset of the text. The default value is **0**.<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br/><br>If this attribute is set to a percentage, the default value is used.|
39| letterSpacing           | number \| string | Letter spacing.<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br/><br>If this attribute is set to a percentage, the default value is used.<br> If this attribute is set to a negative value, the letters will overlap each other.|
40| minFontSize             | number \| string \| [Resource](ts-types.md#resource)      | Minimum font size.<br>For the setting to take effect, this attribute must be used together with **maxFontSize** and **maxLines**, or layout constraint settings. It has no effect on child components.<br>When the adaptive font size is used, the **fontSize** settings do not take effect.<br>Since API version 9, this API is supported in ArkTS widgets.|
41| maxFontSize             | number \| string \| [Resource](ts-types.md#resource)      | Maximum font size.<br>For the setting to take effect, this attribute must be used together with **minFontSize** and **maxLines**, or layout constraint settings. It has no effect on child components.<br>When the adaptive font size is used, the **fontSize** settings do not take effect.<br>Since API version 9, this API is supported in ArkTS widgets.|
42| textCase                | [TextCase](ts-appendix-enums.md#textcase) | Text case.<br>Default value: **TextCase.Normal**<br>Since API version 9, this API is supported in ArkTS widgets.|
43| copyOption<sup>9+</sup> | [CopyOptions](ts-appendix-enums.md#copyoptions9) | Whether copy and paste is allowed.<br>Default value: **CopyOptions.None**<br>This API is supported in ArkTS widgets.<br>**NOTE**<br/><br>When this attribute is set to **CopyOptions.InApp** or **CopyOptions.LocalDevice**, a long press on the text will display a context menu that offers the copy and select-all options.|
44| draggable<sup>9+</sup>  | boolean | Drag effect of the selected text.<br>This attribute cannot be used with the [onDragStart](ts-universal-events-drag-drop.md) event.<br>It must be used together with **copyOption**. When it is set to **true** and **copyOptions** is set to **CopyOptions.InApp** or **CopyOptions.LocalDevice**, the selected text can be dragged and copied to the text box.<br>Default value: **false**<br>**NOTE**<br/><br>This API is supported since API version 9.|
45| font<sup>10+</sup>  | [Font](ts-types.md#font) | Text style, covering the font size, font width, Font family, and font style.|
46| textShadow<sup>10+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions) \| Array&lt;[ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions)&gt;<sup>11+</sup>  | Text shadow.<br>**NOTE**<br>This API does not work with the **fill** attribute or coloring strategy.<br>If the **\<Text>** component's **clip** attribute is set to true (default), the content (for example, text shadow) outside of the component's content area is clipped. Therefore, to fully show the text shadow when the content exceeds the component's content area, set the **clip** attribute to **false**.<br>Since API version 11, this API supports input parameters in an array to implement multiple text shadows.|
47| heightAdaptivePolicy<sup>10+</sup> | [TextHeightAdaptivePolicy](ts-appendix-enums.md#textheightadaptivepolicy10) | How the adaptive height is determined for the text.<br>Default value: **TextHeightAdaptivePolicy.MAX_LINES_FIRST**<br>**NOTE**<br/><br>When this attribute is set to **TextHeightAdaptivePolicy.MAX_LINES_FIRST**, the **maxLines** attribute takes precedence for adjusting the text height. If the **maxLines** setting results in a layout beyond the layout constraints, the text will shrink to a font size between `minFontSize` and `maxFontSize` to allow for more content to be shown.<br>When this attribute is set to **TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST**, the **minFontSize** attribute takes precedence for adjusting the text height. If the text can fit in one line with the **minFontSize** setting, the text will enlarge to the largest possible font size between **minFontSize** and **maxFontSize**.<br>When this attribute is set to **TextHeightAdaptivePolicy.LAYOUT_CONSTRAINT_FIRST**, the layout constraints take precedence for adjusting the text height. If the resultant layout is beyond the layout constraints, the text will shrink to a font size between **minFontSize** and **maxFontSize** to respect the layout constraints. If the layout still exceeds the layout constraints after the font size is reduced to **minFontSize**, the lines that exceed the layout constraints are deleted.|
48| textIndent<sup>10+</sup> | [Length](ts-types.md#length) | Indentation of the first line.<br>Default value: **0**|
49| font<sup>10+</sup> | [Font](ts-types.md#font) | Text style, covering the font size, font width, Font family, and font style.|
50| wordBreak<sup>11+</sup> | [WordBreak](ts-appendix-enums.md#wordbreak11) | Line break rule.<br>Default value: **WordBreak.BREAK_WORD**<br>**NOTE**<br/><br>Since API version 11, this API is supported in ArkTS widgets.<br>When used with **{overflow: TextOverflow.Ellipsis}** and **maxLines**, **WordBreak.BREAK_ALL** can insert line breaks between letters when overflow occurs and display excess content with an ellipsis (...).|
51| selection<sup>11+</sup> |(selectionStart: number, selectionEnd: number)| Text selection. The selected text is highlighted, and a selection handle is displayed together with a menu of available actions.<br>Default value: (-1, -1)<br>**NOTE**<br/><br>Since API version 11, this API is supported in ArkTS widgets.<br>When **copyOption** is set to **CopyOptions.None**, the **selection** attribute is not effective.<br>When **overflow** is set to **TextOverflow.MARQUEE**, the **selection** attribute is not effective.<br>If the value of **selectionStart** is greater than or equal to that of **selectionEnd**, no text will be selected. The value range is [0, textSize], where **textSize** indicates the maximum number of characters in the text content. If the value is less than 0, the value **0** will be used. If the value is greater than **textSize**, **textSize** will be used.<br>If value of **selectionStart** or **selectionEnd** falls within the invisible area, no text will be selected. If clipping is disabled, the text selection outside of the parent component takes effect.|
52| ellipsisMode<sup>11+</sup> |[EllipsisMode](ts-appendix-enums.md#ellipsismode11)| Ellipsis position.<br>Default value: **EllipsisMode.END**<br>**NOTE**<br/>Since API version 11, this API is supported in ArkTS widgets.<br>For the settings to work, **overflow** must be set to **TextOverflow.Ellipsis** and **maxLines** must be specified. Setting **ellipsisMode** alone does not take effect.<br>**EllipsisMode.START** and **EllipsisMode.CENTER** take effect only when text overflows in a single line. |
53| enableDataDetector<sup>11+</sup> |boolean| Whether to enable text recognition.<br>Default value: **false**<br>**NOTE**<br>The recognized entity is in the following style settings:<br>fontColor: Color.Blue<br>decoration: {<br>type: TextDecorationType.Underline,<br>color: Color.Blue<br>}<br>For this API to work, the target device must provide the text recognition capability.<br>When **enableDataDetector** is set to **true** and **dataDetectorConfig** is not set, all types of entities are recognized by default.<br>When **copyOption** is set to **CopyOptions.None**, this API does not take effect.|
54| dataDetectorConfig<sup>11+</sup> | [TextDataDetectorConfig](#textdatadetectorconfig11) | Text recognition configuration.<br>Default value: {<br>types: [ ],<br>onDetectResultUpdate: null<br>} <br>**NOTE**<br>This API must be used together with **enableDataDetector**. It takes effect only when **enableDataDetector** is set to **true**.<br>When entities A and B overlap, the following rules are followed:<br>1. If A  ⊂ B, retain B. Otherwise, retain A.<br>2. When A ⊄ B and B ⊄ A: If A.start < B.start, retain A; otherwise, retain B.|
55| bindSelectionMenu<sup>11+</sup> | {<br>spantype: [TextSpanType](ts-appendix-enums.md#textspantype11),<br>content: [CustomBuilder](ts-types.md#custombuilder8),<br>responseType: [TextResponseType](ts-appendix-enums.md#textresponsetype11) \,<br>options?: [SelectionMenuOptions](ts-appendix-enums.md#selectionmenuoptions11)<br>} | Custom context menu on text selection.<br> Default value: {<br>  spanType: TextSpanType.TEXT<br>**content**: null<br>responseType: TextResponseType.LONG_PRESS <br>}<br>**NOTE**<br/>The duration required for a long-press gesture is 600 ms for **bindSelectionMenu** and 800 ms for **bindContextMenu**. When both **bindSelectionMenu** and **bindContextMenu** are set and both are configured to be triggered by a long-press gesture, **bindSelectionMenu** is triggered first.<br>If the custom menu is too long, embed a [\<Scroll>](./ts-container-scroll.md) component to prevent the keyboard from being blocked. |
56
57>  **NOTE**
58>
59>  The **\<Text>** component cannot contain both text and the child component **\<Span>** or **\<ImageSpan>**. If both of them exist, only the content in **\<Span>** or **\<ImageSpan>** is displayed.
60>
61>  For the **\<Text>** component, the default value of the universal attribute [clip](ts-universal-attributes-sharp-clipping.md) is **true**, which means that the content outside of the component's content area is clipped. To display the content in full, set **clip** to **false**.
62
63## TextDataDetectorConfig<sup>11+</sup>
64| Name| Type | Mandatory| Description |
65| ------ | -------- | ---- | ------------------------------------------- |
66| types   | [TextDataDetectorType](ts-appendix-enums.md#textdatadetectortype11) | Yes  | Entity types for text recognition. Values **null** and **[]** indicate that all types of entities can be recognized.|
67| onDetectResultUpdate   | (callback:(result: string) => void) | Yes  | Callback invoked when text recognition succeeds.<br>- **result**: text recognition result, in JSON format.|
68
69## Events
70
71In addition to the [universal events](ts-universal-events-click.md), the following events are supported.
72
73| Name                                                        | Description                                                    |
74| ------------------------------------------------------------ | ------------------------------------------------------------ |
75| onCopy(callback:(value: string) =&gt; void)<sup>11+</sup> | Triggered when data is copied to the pasteboard, which is displayed when the text box is long pressed.<br>**value**: text to be copied.<br>**NOTE**<br/><br>Since API version 11, this API is supported in ArkTS widgets.<br>Currently, only text can be copied.|
76| onTextSelectionChange(callback: (selectionStart: number, selectionEnd: number) => void)<sup>11+</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.|
77
78## TextOptions<sup>11+</sup>
79
80Describes the initialization options of the **\<Text>** component.
81
82| Name| Type| Mandatory| Description|
83| -------- | -------- | -------- | -------- |
84| controller | [TextController](#textcontroller11)  | Yes| Text controller.|
85
86## TextController<sup>11+</sup>
87
88Defines the controller of the **\<Text>** component.
89
90### Objects to Import
91
92```
93controller: TextController = new TextController()
94```
95
96### closeSelectionMenu
97
98closeSelectionMenu(): void
99
100Closes the custom or default context menu on selection.
101
102## Example
103
104### Example 1
105
106```ts
107// xxx.ets
108@Entry
109@Component
110struct TextExample1 {
111  build() {
112    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
113      // Set the horizontal alignment mode for the text.
114      // Single-line text
115      Text('textAlign').fontSize(9).fontColor(0xCCCCCC)
116      Text('TextAlign set to Center.')
117        .textAlign(TextAlign.Center)
118        .fontSize(12)
119        .border({ width: 1 })
120        .padding(10)
121        .width('100%')
122      Text('TextAlign set to Start.')
123        .textAlign(TextAlign.Start)
124        .fontSize(12)
125        .border({ width: 1 })
126        .padding(10)
127        .width('100%')
128      Text('TextAlign set to End.')
129        .textAlign(TextAlign.End)
130        .fontSize(12)
131        .border({ width: 1 })
132        .padding(10)
133        .width('100%')
134
135      // Multi-line text
136      Text('This is the text content with textAlign set to Center.')
137        .textAlign(TextAlign.Center)
138        .fontSize(12)
139        .border({ width: 1 })
140        .padding(10)
141        .width('100%')
142      Text('This is the text content with textAlign set to Start.')
143        .textAlign(TextAlign.Start)
144        .fontSize(12)
145        .border({ width: 1 })
146        .padding(10)
147        .width('100%')
148      Text('This is the text content with textAlign set to End.')
149        .textAlign(TextAlign.End)
150        .fontSize(12)
151        .border({ width: 1 })
152        .padding(10)
153        .width('100%')
154
155
156      // Set the display mode when the text is too long.
157      Text('TextOverflow+maxLines').fontSize(9).fontColor(0xCCCCCC)
158      // Clip the text when the value of maxLines is exceeded.
159      Text('This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content. This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content.')
160        .textOverflow({ overflow: TextOverflow.Clip })
161        .maxLines(1)
162        .fontSize(12)
163        .border({ width: 1 })
164        .padding(10)
165
166      // Show an ellipsis (...) when the value of maxLines is exceeded.
167      Text('This is set textOverflow to Ellipsis text content This is set textOverflow to Ellipsis text content.'.split('')
168        .join('\u200B'))
169        .textOverflow({ overflow: TextOverflow.Ellipsis })
170        .maxLines(1)
171        .fontSize(12)
172        .border({ width: 1 })
173        .padding(10)
174
175      Text('lineHeight').fontSize(9).fontColor(0xCCCCCC)
176      Text('This is the text with the line height set. This is the text with the line height set.')
177        .fontSize(12).border({ width: 1 }).padding(10)
178      Text('This is the text with the line height set. This is the text with the line height set.')
179        .fontSize(12).border({ width: 1 }).padding(10)
180        .lineHeight(20)
181    }.height(600).width(350).padding({ left: 35, right: 35, top: 35 })
182  }
183}
184```
185![textExp1](figures/textExp1.png)
186
187### Example 2
188
189```ts
190@Entry
191@Component
192struct TextExample2 {
193  build() {
194    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
195      Text('decoration').fontSize(9).fontColor(0xCCCCCC)
196      Text('This is the text content with the decoration set to LineThrough and the color set to Red.')
197        .decoration({
198          type: TextDecorationType.LineThrough,
199          color: Color.Red
200        })
201        .fontSize(12)
202        .border({ width: 1 })
203        .padding(10)
204        .width('100%')
205
206
207      Text('This is the text content with the decoration set to Overline and the color set to Red.')
208        .decoration({
209          type: TextDecorationType.Overline,
210          color: Color.Red
211        })
212        .fontSize(12)
213        .border({ width: 1 })
214        .padding(10)
215        .width('100%')
216
217
218      Text('This is the text content with the decoration set to Underline and the color set to Red.')
219        .decoration({
220          type: TextDecorationType.Underline,
221          color: Color.Red
222        })
223        .fontSize(12)
224        .border({ width: 1 })
225        .padding(10)
226        .width('100%')
227
228      // Set the text baseline offset.
229      Text('baselineOffset').fontSize(9).fontColor(0xCCCCCC)
230      Text('This is the text content with baselineOffset 0.')
231        .baselineOffset(0)
232        .fontSize(12)
233        .border({ width: 1 })
234        .padding(10)
235        .width('100%')
236      Text('This is the text content with baselineOffset 30.')
237        .baselineOffset(30)
238        .fontSize(12)
239        .border({ width: 1 })
240        .padding(10)
241        .width('100%')
242      Text('This is the text content with baselineOffset -20.')
243        .baselineOffset(-20)
244        .fontSize(12)
245        .border({ width: 1 })
246        .padding(10)
247        .width('100%')
248
249      // Set the letter spacing.
250      Text('letterSpacing').fontSize(9).fontColor(0xCCCCCC)
251      Text('This is the text content with letterSpacing 0.')
252        .letterSpacing(0)
253        .fontSize(12)
254        .border({ width: 1 })
255        .padding(10)
256        .width('100%')
257      Text('This is the text content with letterSpacing 3.')
258        .letterSpacing(3)
259        .fontSize(12)
260        .border({ width: 1 })
261        .padding(10)
262        .width('100%')
263      Text('This is the text content with letterSpacing -1.')
264        .letterSpacing(-1)
265        .fontSize(12)
266        .border({ width: 1 })
267        .padding(10)
268        .width('100%')
269
270      Text('textCase').fontSize(9).fontColor(0xCCCCCC)
271      Text('This is the text content with textCase set to Normal.')
272        .textCase(TextCase.Normal)
273        .fontSize(12)
274        .border({ width: 1 })
275        .padding(10)
276        .width('100%')
277      // Display the text in lowercase.
278      Text('This is the text content with textCase set to LowerCase.')
279        .textCase(TextCase.LowerCase)
280        .fontSize(12)
281        .border({ width: 1 })
282        .padding(10)
283        .width('100%')
284      // Display the text in uppercase.
285      Text('This is the text content with textCase set to UpperCase.')
286        .textCase(TextCase.UpperCase)
287        .fontSize(12).border({ width: 1 }).padding(10)
288
289    }.height(700).width(350).padding({ left: 35, right: 35, top: 35 })
290  }
291}
292```
293![textExp1](figures/textExp2.png)
294
295### Example 3
296
297Example of using **textShadow**, **heightAdaptivePolicy**, and **TextOverflow.MARQUEE**:
298
299```ts
300@Entry
301@Component
302struct TextExample {
303  build() {
304    Column({ space: 8 }) {
305      Text('textShadow').fontSize(9).fontColor(0xCCCCCC).margin(15).width('90%')
306      // Set the text shadow.
307      Text('textShadow')
308        .width('80%')
309        .height(55)
310        .fontSize(40)
311        .lineHeight(55)
312        .textAlign(TextAlign.Center)
313        .textShadow({ radius: 10, color: Color.Black, offsetX: 0, offsetY: 0 })
314        .borderWidth(1)
315      Divider()
316      // Set how the adaptive height is determined for the text.
317      Text('heightAdaptivePolicy').fontSize(9).fontColor(0xCCCCCC).margin(15).width('90%')
318      Text('This is the text with the height adaptive policy set')
319        .width('80%')
320        .height(90)
321        .borderWidth(1)
322        .minFontSize(10)
323        .maxFontSize(30)
324        .maxLines(3)
325        .textOverflow({ overflow: TextOverflow.Ellipsis })
326        .heightAdaptivePolicy(TextHeightAdaptivePolicy.MAX_LINES_FIRST)
327      Text('This is the text with the height adaptive policy set')
328        .width('80%')
329        .height(90)
330        .borderWidth(1)
331        .minFontSize(10)
332        .maxFontSize(30)
333        .maxLines(3)
334        .textOverflow({ overflow: TextOverflow.Ellipsis })
335        .heightAdaptivePolicy(TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST)
336      Text('This is the text with the height adaptive policy set')
337        .width('80%')
338        .height(90)
339        .borderWidth(1)
340        .minFontSize(10)
341        .maxFontSize(30)
342        .maxLines(3)
343        .textOverflow({ overflow: TextOverflow.Ellipsis })
344        .heightAdaptivePolicy(TextHeightAdaptivePolicy.LAYOUT_CONSTRAINT_FIRST)
345      Divider()
346      Text('marquee').fontSize(9).fontColor(0xCCCCCC).margin(15).width('90%')
347      // Set the text to continuously scroll when text overflow occurs.
348      Text('This is the text with the text overflow set marquee')
349        .width(300)
350        .borderWidth(1)
351        .textOverflow({ overflow: TextOverflow.MARQUEE })
352    }
353  }
354}
355```
356
357![](figures/text_3.gif)
358
359### Example 4
360Example of using **WordBreak**:
361
362```ts
363@Entry
364@Component
365struct TextExample4 {
366  @State type: string = 'WordBreakType:Normal with clip set to true'
367  @State text: string = 'This is set wordBreak to WordBreak text content This is set wordBreak to WordBreak text content.'
368
369  build() {
370    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
371      Text(this.type).fontSize(9).fontColor(0xCCCCCC)
372      Text('This is set wordBreak to WordBreak text Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu.')
373        .fontSize(12)
374        .border({ width: 1 })
375        .wordBreak(WordBreak.NORMAL)
376        .lineHeight(20)
377        .maxLines(2)
378      Text('WordBreakType:Normal with clip set to false').fontSize(9).fontColor(0xCCCCCC)
379      Text('This is set wordBreak to WordBreak text Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu.')
380        .fontSize(12)
381        .border({ width: 1 })
382        .wordBreak(WordBreak.NORMAL)
383        .lineHeight(20)
384        .maxLines(2)
385        .clip(false)
386      Text("WordBreakType:BreakAll").fontSize(9).fontColor(0xCCCCCC)
387      Text(this.text)
388        .fontSize(12)
389        .border({ width: 1 })
390        .maxLines(2)
391        .textOverflow({ overflow: TextOverflow.Ellipsis })
392        .wordBreak(WordBreak.BREAK_ALL)
393        .lineHeight(20)
394      Text("WordBreakType:BreakWord").fontSize(9).fontColor(0xCCCCCC)
395      Text(this.text)
396        .fontSize(12)
397        .border({ width: 1 })
398        .maxLines(2)
399        .textOverflow({ overflow: TextOverflow.Ellipsis })
400        .wordBreak(WordBreak.BREAK_WORD)
401        .lineHeight(20)
402    }.height(300).width(335).padding({ left: 35, right: 35, top: 35 })
403  }
404}
405```
406![](figures/textExample4.jpeg)
407
408### Example 5
409Example of using **selection** and **onCopy**:
410
411```ts
412@Entry
413@Component
414struct TextExample5 {
415  @State onCopy: string = ''
416  @State text: string = 'This is set selection to Selection text content This is set selection to Selection text content.'
417  @State start: number = 0
418  @State end: number = 20
419
420  build() {
421    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
422      Text(this.text)
423        .fontSize(12)
424        .border({ width: 1 })
425        .lineHeight(20)
426        .margin(30)
427        .copyOption(CopyOptions.InApp)
428        .selection(this.start, this.end)
429        .onCopy((value: string) => {
430          this.onCopy = value
431        })
432      Button('Set text selection')
433        .margin({left:20})
434        .onClick(() => {
435          // Change the start point and end point of the text selection.
436          this.start = 10
437          this.end = 30
438        })
439      Text(this.onCopy).fontSize(12).margin(10).key('copy')
440    }.height(600).width(335).padding({ left: 35, right: 35, top: 35 })
441  }
442}
443```
444![](figures/textExample5.jpeg)
445
446### Example 6
447Example of using **ellipsisMode**:
448
449```ts
450@Entry
451@Component
452struct TextExample6 {
453  @State text: string = 'This is set ellipsisMode to EllipsisMode text content This is set ellipsisMode to EllipsisMode text content.'
454  @State ellipsisModeIndex: number = 0;
455  @State ellipsisMode: EllipsisMode[] = [EllipsisMode.START, EllipsisMode.CENTER, EllipsisMode.END]
456  @State ellipsisModeStr: string[] = ['START', 'CENTER', 'END']
457  build() {
458    Column() {
459      Text(this.text)
460        .fontSize(16)
461        .border({ width: 1 })
462        .lineHeight(20)
463        .maxLines(1)
464        .textOverflow({overflow:TextOverflow.Ellipsis})
465        .ellipsisMode(this.ellipsisMode[this.ellipsisModeIndex])
466        .width(300)
467        .margin({ left: 20, top: 20 })
468
469      Row() {
470        Button ('Change Ellipsis Position:' + this.ellipsisModeStr[this.ellipsisModeIndex]).onClick (() => {
471          this.ellipsisModeIndex++
472          if(this.ellipsisModeIndex > (this.ellipsisModeStr.length - 1)) {
473            this.ellipsisModeIndex = 0
474          }
475        })
476      }.margin({ top: 10 })
477    }
478  }
479}
480```
481![](figures/textExample6.gif)
482
483### Example 7
484Example of using **enableDataDetector** and **dataDetectorConfig**
485
486```ts
487@Entry
488@Component
489struct TextExample7 {
490  @State phoneNumber: string = '(86) (755) ********';
491  @State url: string = 'www.********.com';
492  @State email: string = '***@example.com';
493  @State address: string = 'XX (province) XX (city) XX (county) XXXX';
494  @State enableDataDetector: boolean = true;
495  @State types: TextDataDetectorType[] = [];
496
497  build() {
498    Row() {
499      Column() {
500        Text(
501          'Phone number:' + this.phoneNumber + '\n' +
502          'URL:' + this.url + '\n' +
503          'Email:' + this.email + '\n' +
504          'Address:' + this.address
505        )
506          .fontSize(16)
507          .copyOption(CopyOptions.InApp)
508          .enableDataDetector(this.enableDataDetector)
509          .dataDetectorConfig({types : this.types, onDetectResultUpdate: (result: string)=>{}})
510          .textAlign(TextAlign.Center)
511          .borderWidth(1)
512          .padding(10)
513          .width('100%')
514      }
515      .width('100%')
516    }
517    .height('100%')
518  }
519}
520```
521### Example 8
522Example of using **bindSelectionMenu**, **onTextSelectionChange**, and **closeSelectionMenu**:
523
524```ts
525@Entry
526@Component
527struct Demo {
528  controller: TextController = new TextController();
529  options: TextOptions = { controller: this.controller };
530
531  build() {
532    Column() {
533      Column() {
534        Text(undefined, this.options) {
535          Span('Hello World')
536          ImageSpan($r('app.media.icon'))
537            .width('100px')
538            .height('100px')
539            .objectFit(ImageFit.Fill)
540            .verticalAlign(ImageSpanAlignment.CENTER)
541        }
542        .copyOption(CopyOptions.InApp)
543        .bindSelectionMenu(TextSpanType.IMAGE, this.LongPressImageCustomMenu, TextResponseType.LONG_PRESS, {
544          onDisappear: () => {
545            console.info(`Triggered when the custom context menu on selection is closed.`);
546          },
547          onAppear: () => {
548            console.info(`Triggered when the custom context menu on selection is displayed`);
549          }
550        })
551        .bindSelectionMenu(TextSpanType.TEXT, this.RightClickTextCustomMenu, TextResponseType.RIGHT_CLICK)
552        .bindSelectionMenu(TextSpanType.MIXED, this.SelectMixCustomMenu, TextResponseType.SELECT)
553        .onTextSelectionChange((selectionStart: number, selectionEnd: number) => {
554          console.info(`Triggered when the text selection position changes, selectionStart: ${selectionStart}, selectionEnd: ${selectionEnd}`);
555        })
556        .borderWidth(1)
557        .borderColor(Color.Red)
558        .width(200)
559        .height(100)
560      }
561      .width('100%')
562      .backgroundColor(Color.White)
563      .alignItems(HorizontalAlign.Start)
564      .padding(25)
565    }
566    .height('100%')
567  }
568
569  @Builder
570  RightClickTextCustomMenu() {
571    Column() {
572      Menu() {
573        MenuItemGroup() {
574          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Right Click Menu 1", labelInfo: "" })
575            .onClick((event) => {
576              this.controller.closeSelectionMenu();
577            })
578          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Right Click Menu 2", labelInfo: "" })
579          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Right Click Menu 3", labelInfo: "" })
580        }
581      }
582      .MenuStyles()
583    }
584  }
585
586  @Builder
587  LongPressImageCustomMenu() {
588    Column() {
589      Menu() {
590        MenuItemGroup() {
591          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Long Press Image Menu 1", labelInfo: "" })
592            .onClick((event) => {
593              this.controller.closeSelectionMenu();
594            })
595          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Long Press Image Menu 2", labelInfo: "" })
596          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Long Press Image Menu 3", labelInfo: "" })
597        }
598      }
599      .MenuStyles()
600    }
601  }
602
603  @Builder
604  SelectMixCustomMenu() {
605    Column() {
606      Menu() {
607        MenuItemGroup() {
608          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Select Mixed Menu 1", labelInfo: "" })
609            .onClick((event) => {
610              this.controller.closeSelectionMenu();
611            })
612          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Select Mixed Menu 2", labelInfo: "" })
613          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Select Mixed Menu 3", labelInfo: "" })
614        }
615      }
616      .MenuStyles()
617    }
618  }
619}
620
621@Extend(Menu)
622function MenuStyles() {
623  .radius($r('sys.float.ohos_id_corner_radius_card'))
624  .clip(true)
625  .backgroundColor('#F0F0F0')
626}
627```
628
629![](figures/textBindSelectionMenu.gif)
630