[go: nahoru, domu]

blob: 44a1f15af00c872150db76b2a0f4035ead424d10 [file] [log] [blame]
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +00001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.compose.material
18
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000019import androidx.compose.foundation.text.BasicText
20import androidx.compose.foundation.text.InlineTextContent
21import androidx.compose.runtime.Composable
Leland Richardson0f99bf12021-02-02 20:56:41 -080022import androidx.compose.runtime.CompositionLocalProvider
Louis Pullen-Freilichdb286532021-01-27 17:36:54 +000023import androidx.compose.runtime.compositionLocalOf
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000024import androidx.compose.runtime.structuralEqualityPolicy
25import androidx.compose.ui.Modifier
26import androidx.compose.ui.graphics.Color
George Mountc6549b92020-12-14 10:49:53 -080027import androidx.compose.ui.graphics.takeOrElse
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000028import androidx.compose.ui.text.AnnotatedString
29import androidx.compose.ui.text.Paragraph
30import androidx.compose.ui.text.TextLayoutResult
31import androidx.compose.ui.text.TextStyle
32import androidx.compose.ui.text.font.FontFamily
33import androidx.compose.ui.text.font.FontStyle
34import androidx.compose.ui.text.font.FontWeight
35import androidx.compose.ui.text.style.TextAlign
36import androidx.compose.ui.text.style.TextDecoration
37import androidx.compose.ui.text.style.TextOverflow
38import androidx.compose.ui.unit.TextUnit
39
40/**
41 * High level element that displays text and provides semantics / accessibility information.
42 *
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +000043 * The default [style] uses the [LocalTextStyle] provided by the [MaterialTheme] / components. If
44 * you are setting your own style, you may want to consider first retrieving [LocalTextStyle],
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000045 * and using [TextStyle.copy] to keep any theme defined attributes, only modifying the specific
46 * attributes you want to override.
47 *
48 * For ease of use, commonly used parameters from [TextStyle] are also present here. The order of
49 * precedence is as follows:
haoyudf2e07c2020-11-09 17:36:11 -080050 * - If a parameter is explicitly set here (i.e, it is _not_ `null` or [TextUnit.Unspecified]),
51 * then this parameter will always be used.
52 * - If a parameter is _not_ set, (`null` or [TextUnit.Unspecified]), then the corresponding value
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000053 * from [style] will be used instead.
54 *
55 * Additionally, for [color], if [color] is not set, and [style] does not have a color, then
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +000056 * [LocalContentColor] will be used with an alpha of [LocalContentAlpha]- this allows this
Louis Pullen-Freilich3772ac52020-11-02 19:23:39 +000057 * [Text] or element containing this [Text] to adapt to different background colors and still
58 * maintain contrast and accessibility.
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000059 *
60 * @param text The text to be displayed.
61 * @param modifier [Modifier] to apply to this layout node.
62 * @param color [Color] to apply to the text. If [Color.Unspecified], and [style] has no color set,
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +000063 * this will be [LocalContentColor].
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000064 * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize].
65 * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic).
66 * See [TextStyle.fontStyle].
67 * @param fontWeight The typeface thickness to use when painting the text (e.g., [FontWeight.Bold]).
68 * @param fontFamily The font family to be used when rendering the text. See [TextStyle.fontFamily].
69 * @param letterSpacing The amount of space to add between each letter.
70 * See [TextStyle.letterSpacing].
71 * @param textDecoration The decorations to paint on the text (e.g., an underline).
72 * See [TextStyle.textDecoration].
73 * @param textAlign The alignment of the text within the lines of the paragraph.
74 * See [TextStyle.textAlign].
75 * @param lineHeight Line height for the [Paragraph] in [TextUnit] unit, e.g. SP or EM.
76 * See [TextStyle.lineHeight].
77 * @param overflow How visual overflow should be handled.
78 * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the
79 * text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,
80 * [overflow] and TextAlign may have unexpected effects.
81 * @param maxLines An optional maximum number of lines for the text to span, wrapping if
82 * necessary. If the text exceeds the given number of lines, it will be truncated according to
83 * [overflow] and [softWrap]. If it is not null, then it must be greater than zero.
84 * @param onTextLayout Callback that is executed when a new text layout is calculated.
85 * @param style Style configuration for the text such as color, font, line height etc.
86 */
87@Composable
88fun Text(
89 text: String,
90 modifier: Modifier = Modifier,
91 color: Color = Color.Unspecified,
haoyudf2e07c2020-11-09 17:36:11 -080092 fontSize: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000093 fontStyle: FontStyle? = null,
94 fontWeight: FontWeight? = null,
95 fontFamily: FontFamily? = null,
haoyudf2e07c2020-11-09 17:36:11 -080096 letterSpacing: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +000097 textDecoration: TextDecoration? = null,
98 textAlign: TextAlign? = null,
haoyudf2e07c2020-11-09 17:36:11 -080099 lineHeight: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000100 overflow: TextOverflow = TextOverflow.Clip,
101 softWrap: Boolean = true,
102 maxLines: Int = Int.MAX_VALUE,
103 onTextLayout: (TextLayoutResult) -> Unit = {},
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000104 style: TextStyle = LocalTextStyle.current
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000105) {
106 Text(
107 AnnotatedString(text),
108 modifier,
109 color,
110 fontSize,
111 fontStyle,
112 fontWeight,
113 fontFamily,
114 letterSpacing,
115 textDecoration,
116 textAlign,
117 lineHeight,
118 overflow,
119 softWrap,
120 maxLines,
121 emptyMap(),
122 onTextLayout,
123 style
124 )
125}
126
127/**
128 * High level element that displays text and provides semantics / accessibility information.
129 *
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000130 * The default [style] uses the [LocalTextStyle] provided by the [MaterialTheme] / components. If
131 * you are setting your own style, you may want to consider first retrieving [LocalTextStyle],
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000132 * and using [TextStyle.copy] to keep any theme defined attributes, only modifying the specific
133 * attributes you want to override.
134 *
135 * For ease of use, commonly used parameters from [TextStyle] are also present here. The order of
136 * precedence is as follows:
haoyudf2e07c2020-11-09 17:36:11 -0800137 * - If a parameter is explicitly set here (i.e, it is _not_ `null` or [TextUnit.Unspecified]),
138 * then this parameter will always be used.
139 * - If a parameter is _not_ set, (`null` or [TextUnit.Unspecified]), then the corresponding value
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000140 * from [style] will be used instead.
141 *
142 * Additionally, for [color], if [color] is not set, and [style] does not have a color, then
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000143 * [LocalContentColor] will be used with an alpha of [LocalContentAlpha]- this allows this
Louis Pullen-Freilich3772ac52020-11-02 19:23:39 +0000144 * [Text] or element containing this [Text] to adapt to different background colors and still
145 * maintain contrast and accessibility.
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000146 *
147 * @param text The text to be displayed.
148 * @param modifier [Modifier] to apply to this layout node.
149 * @param color [Color] to apply to the text. If [Color.Unspecified], and [style] has no color set,
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000150 * this will be [LocalContentColor].
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000151 * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize].
152 * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic).
153 * See [TextStyle.fontStyle].
154 * @param fontWeight The typeface thickness to use when painting the text (e.g., [FontWeight.Bold]).
155 * @param fontFamily The font family to be used when rendering the text. See [TextStyle.fontFamily].
156 * @param letterSpacing The amount of space to add between each letter.
157 * See [TextStyle.letterSpacing].
158 * @param textDecoration The decorations to paint on the text (e.g., an underline).
159 * See [TextStyle.textDecoration].
160 * @param textAlign The alignment of the text within the lines of the paragraph.
161 * See [TextStyle.textAlign].
162 * @param lineHeight Line height for the [Paragraph] in [TextUnit] unit, e.g. SP or EM.
163 * See [TextStyle.lineHeight].
164 * @param overflow How visual overflow should be handled.
165 * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the
166 * text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,
167 * [overflow] and TextAlign may have unexpected effects.
168 * @param maxLines An optional maximum number of lines for the text to span, wrapping if
169 * necessary. If the text exceeds the given number of lines, it will be truncated according to
170 * [overflow] and [softWrap]. If it is not null, then it must be greater than zero.
171 * @param inlineContent A map store composables that replaces certain ranges of the text. It's
172 * used to insert composables into text layout. Check [InlineTextContent] for more information.
173 * @param onTextLayout Callback that is executed when a new text layout is calculated.
174 * @param style Style configuration for the text such as color, font, line height etc.
175 */
176@Composable
177fun Text(
178 text: AnnotatedString,
179 modifier: Modifier = Modifier,
180 color: Color = Color.Unspecified,
haoyudf2e07c2020-11-09 17:36:11 -0800181 fontSize: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000182 fontStyle: FontStyle? = null,
183 fontWeight: FontWeight? = null,
184 fontFamily: FontFamily? = null,
haoyudf2e07c2020-11-09 17:36:11 -0800185 letterSpacing: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000186 textDecoration: TextDecoration? = null,
187 textAlign: TextAlign? = null,
haoyudf2e07c2020-11-09 17:36:11 -0800188 lineHeight: TextUnit = TextUnit.Unspecified,
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000189 overflow: TextOverflow = TextOverflow.Clip,
190 softWrap: Boolean = true,
191 maxLines: Int = Int.MAX_VALUE,
192 inlineContent: Map<String, InlineTextContent> = mapOf(),
193 onTextLayout: (TextLayoutResult) -> Unit = {},
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000194 style: TextStyle = LocalTextStyle.current
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000195) {
George Mountc6549b92020-12-14 10:49:53 -0800196 val textColor = color.takeOrElse {
197 style.color.takeOrElse {
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000198 LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
Louis Pullen-Freilich3772ac52020-11-02 19:23:39 +0000199 }
200 }
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000201 val mergedStyle = style.merge(
202 TextStyle(
203 color = textColor,
204 fontSize = fontSize,
205 fontWeight = fontWeight,
206 textAlign = textAlign,
207 lineHeight = lineHeight,
208 fontFamily = fontFamily,
209 textDecoration = textDecoration,
210 fontStyle = fontStyle,
211 letterSpacing = letterSpacing
212 )
213 )
214 BasicText(
215 text,
216 modifier,
217 mergedStyle,
218 onTextLayout,
219 overflow,
220 softWrap,
221 maxLines,
222 inlineContent
223 )
224}
225
226/**
Louis Pullen-Freilichdb286532021-01-27 17:36:54 +0000227 * CompositionLocal containing the preferred [TextStyle] that will be used by [Text] components by
228 * default. To set the value for this CompositionLocal, see [ProvideTextStyle] which will merge any
229 * missing [TextStyle] properties with the existing [TextStyle] set in this CompositionLocal.
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000230 *
231 * @see ProvideTextStyle
232 */
Louis Pullen-Freilichdb286532021-01-27 17:36:54 +0000233val LocalTextStyle = compositionLocalOf(structuralEqualityPolicy()) { TextStyle.Default }
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000234
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000235// TODO: b/156598010 remove this and replace with fold definition on the backing CompositionLocal
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000236/**
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000237 * This function is used to set the current value of [LocalTextStyle], merging the given style
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000238 * with the current style values for any missing attributes. Any [Text] components included in
Louis Pullen-Freilichdc68dd502020-11-13 02:10:48 +0000239 * this component's [content] will be styled with this style unless styled explicitly.
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000240 *
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000241 * @see LocalTextStyle
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000242 */
243@Composable
Louis Pullen-Freilichdc68dd502020-11-13 02:10:48 +0000244fun ProvideTextStyle(value: TextStyle, content: @Composable () -> Unit) {
Louis Pullen-Freilichd42e1072021-01-27 18:20:02 +0000245 val mergedStyle = LocalTextStyle.current.merge(value)
Leland Richardson0f99bf12021-02-02 20:56:41 -0800246 CompositionLocalProvider(LocalTextStyle provides mergedStyle, content = content)
Louis Pullen-Freilicha77fc3c2020-10-30 16:50:54 +0000247}