Polish the documentation for BasicTextField2.
Bug: b/277380808
Test: n/a
Relnote: n/a
Change-Id: Ida2413908b80bd45c8ca2bf885462a07ccf78f94
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index d5783f1..f1eb981 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -1358,9 +1358,9 @@
}
@androidx.compose.foundation.ExperimentalFoundationApi public class TextFieldBuffer implements java.lang.Appendable java.lang.CharSequence {
- method public Appendable append(char char);
method public Appendable append(CharSequence? text);
method public Appendable append(CharSequence? text, int start, int end);
+ method public Appendable append(char char);
method public operator char get(int index);
method public final androidx.compose.foundation.text2.input.TextFieldBuffer.ChangeList getChanges();
method public final int getCodepointLength();
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditFilter.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditFilter.kt
index b0ac249..9c25500 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditFilter.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditFilter.kt
@@ -34,6 +34,7 @@
* Prebuilt filters are provided for common filter operations. See:
* - `TextEditFilter`.[maxLengthInChars]`()`
* - `TextEditFilter`.[maxLengthInCodepoints]`()`
+ * - `TextEditFilter`.[allCaps]`()`
*
* @sample androidx.compose.foundation.samples.BasicTextField2CustomFilterSample
*/
@@ -50,8 +51,8 @@
/**
* The filter operation. For more information see the documentation on [TextEditFilter].
*
- * To reject all changes in [newState], call
- * `newState.`[revertAllChanges][MutableTextFieldValueWithSelection.revertAllChanges].
+ * To reject all changes in [originalValue], call
+ * `valueWithChanges.`[revertAllChanges][TextFieldBufferWithSelection.revertAllChanges].
*
* @param originalValue The value of the field before the change was performed.
* @param valueWithChanges The value of the field after the change. This value can be changed
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditResult.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditResult.kt
index bf51901..9b6c9ab 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditResult.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextEditResult.kt
@@ -43,6 +43,8 @@
/**
* Returns the [TextRange] to set as the new selection. If the selection is collapsed, it will
* set the cursor instead.
+ *
+ * @return The new range of the selection, in character offsets.
*/
internal abstract fun calculateSelection(
oldValue: TextFieldCharSequence,
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBuffer.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBuffer.kt
index 0af5830..6281104 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBuffer.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBuffer.kt
@@ -23,12 +23,16 @@
import androidx.compose.ui.text.TextRange
/**
- * A mutable version of [TextFieldCharSequence], similar to [StringBuilder].
+ * A text buffer that can be edited, similar to [StringBuilder].
*
- * This class provides methods for changing the text, such as [replace] and [append].
+ * This class provides methods for changing the text, such as [replace], [append], [insert], and
+ * [delete].
*
* To get one of these, and for usage samples, see [TextFieldState.edit]. Every change to the buffer
* is tracked in a [ChangeList] which you can access via the [changes] property.
+ *
+ * [TextFieldBufferWithSelection] is a special type of buffer that has an associated cursor position
+ * or selection range.
*/
@ExperimentalFoundationApi
open class TextFieldBuffer internal constructor(
@@ -70,18 +74,21 @@
* Replaces the text between [start] (inclusive) and [end] (exclusive) in this value with
* [text], and records the change in [changes].
*
+ * @param start The character offset of the first character to replace.
+ * @param end The character offset of the first character after the text to replace.
+ * @param text The text to replace the range `[start, end)` with.
+ *
+ * @see append
* @see insert
+ * @see delete
*/
fun replace(start: Int, end: Int, text: String) {
onTextWillChange(TextRange(start, end), text.length)
buffer.replace(start, end, text)
}
- override fun append(char: Char): Appendable = apply {
- onTextWillChange(TextRange(length), 1)
- buffer.append(char)
- }
-
+ // Doc inherited from Appendable.
+ // This append overload should be first so it ends up being the target of links to this method.
override fun append(text: CharSequence?): Appendable = apply {
if (text != null) {
onTextWillChange(TextRange(length), text.length)
@@ -89,6 +96,7 @@
}
}
+ // Doc inherited from Appendable.
override fun append(text: CharSequence?, start: Int, end: Int): Appendable = apply {
if (text != null) {
onTextWillChange(TextRange(length), end - start)
@@ -96,6 +104,12 @@
}
}
+ // Doc inherited from Appendable.
+ override fun append(char: Char): Appendable = apply {
+ onTextWillChange(TextRange(length), 1)
+ buffer.append(char)
+ }
+
/**
* Called just before the text contents are about to change.
*
@@ -200,7 +214,14 @@
/**
* Insert [text] at the given [index] in this value.
*
+ * This is equivalent to calling `replace(index, index, text)`.
+ *
+ * @param index The character offset at which to insert [text].
+ * @param text The text to insert.
+ *
* @see TextFieldBuffer.replace
+ * @see TextFieldBuffer.append
+ * @see TextFieldBuffer.delete
*/
@ExperimentalFoundationApi
fun TextFieldBuffer.insert(index: Int, text: String) {
@@ -209,6 +230,13 @@
/**
* Delete the text between [start] (inclusive) and [end] (exclusive).
+ *
+ * @param start The character offset of the first character to delete.
+ * @param end The character offset of the first character after the deleted range.
+ *
+ * @see TextFieldBuffer.replace
+ * @see TextFieldBuffer.append
+ * @see TextFieldBuffer.insert
*/
@ExperimentalFoundationApi
fun TextFieldBuffer.delete(start: Int, end: Int) {
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBufferWithSelection.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBufferWithSelection.kt
index 66c2d4f..e04d4f5 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBufferWithSelection.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldBufferWithSelection.kt
@@ -103,10 +103,10 @@
* If [index] is inside an invalid run, the cursor will be placed at the nearest later index.
*
* To place the cursor at the end of the field, after the last character, pass index
- * [MutableTextFieldValue.codepointLength] or call [placeCursorAtEnd].
+ * [TextFieldBuffer.codepointLength] or call [placeCursorAtEnd].
*
* @param index Codepoint index to place cursor after, should be in range 0 to
- * [MutableTextFieldValue.codepointLength], inclusive.
+ * [TextFieldBuffer.codepointLength], inclusive.
*
* @see placeCursorAfterCharAt
* @see placeCursorBeforeCodepointAt
@@ -124,10 +124,10 @@
* nearest later index.
*
* To place the cursor at the end of the field, after the last character, pass index
- * [MutableTextFieldValue.length] or call [placeCursorAtEnd].
+ * [TextFieldBuffer.length] or call [placeCursorAtEnd].
*
* @param index Character index to place cursor after, should be in range 0 to
- * [MutableTextFieldValue.length], inclusive.
+ * [TextFieldBuffer.length], inclusive.
*
* @see placeCursorAfterCodepointAt
* @see placeCursorBeforeCharAt
@@ -139,14 +139,16 @@
/**
* Places the cursor at the end of the text.
+ *
+ * @see placeCursorBeforeFirstChange
+ * @see placeCursorAfterLastChange
*/
fun placeCursorAtEnd() {
selectionInChars = TextRange(length)
}
/**
- * Returns a [TextEditResult] that places the cursor after the last change made to this
- * [TextFieldBuffer].
+ * Places the cursor after the last change made to this [TextFieldBufferWithSelection].
*
* @see placeCursorAtEnd
* @see placeCursorBeforeFirstChange
@@ -158,8 +160,7 @@
}
/**
- * Returns a [TextEditResult] that places the cursor before the first change made to this
- * [TextFieldBuffer].
+ * Places the cursor before the first change made to this [TextFieldBufferWithSelection].
*
* @see placeCursorAfterLastChange
*/
@@ -213,14 +214,15 @@
/**
* Places the selection around all the text.
+ *
+ * @see selectAllChanges
*/
fun selectAll() {
selectionInChars = TextRange(0, length)
}
/**
- * Returns a [TextEditResult] that places the selection before the first change and after the
- * last change.
+ * Places the selection before the first change and after the last change.
*
* @see selectAll
*/
@@ -236,9 +238,10 @@
}
/**
- * Revert all changes made to this value since it was created. After calling this method, this
- * object will be in the same state it was when it was initially created, and [changes] will be
- * empty.
+ * Revert all changes made to this value since it was created.
+ *
+ * After calling this method, this object will be in the same state it was when it was initially
+ * created, and [changes] will be empty.
*/
fun revertAllChanges() {
replace(0, length, sourceValue.toString())
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldCharSequence.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldCharSequence.kt
index a7e8abf..b32f5fa 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldCharSequence.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldCharSequence.kt
@@ -18,13 +18,14 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.text.constrain
/**
- * An immutable snapshot of the contents of a [TextFieldCharSequence] at a point in time.
+ * An immutable snapshot of the contents of a [TextFieldState].
*
* This class is a [CharSequence] and directly represents the text being edited. It also stores
- * the current [selectionInChars] of the field, which may either represent the cursor (if the selection is
- * [collapsed][TextRange.collapsed]) or the selection range.
+ * the current [selectionInChars] of the field, which may either represent the cursor (if the
+ * selection is [collapsed][TextRange.collapsed]) or the selection range.
*
* This class also may contain the range being composed by the IME, if any, although this is not
* exposed.
@@ -40,16 +41,14 @@
val selectionInChars: TextRange
/**
- * Composition range created by IME. If null, there is no composition range.
+ * Composition range created by IME. If null, there is no composition range.
*
* Input service composition is an instance of text produced by IME. An example visual for the
* composition is that the currently composed word is visually separated from others with
* underline, or text background. For description of composition please check
* [W3C IME Composition](https://www.w3.org/TR/ime-api/#ime-composition)
*
- * Composition can be set on the by the system, however it is possible to apply an existing
- * composition by setting the value to null. Applying a composition will accept the changes
- * that were still being composed by IME.
+ * Composition can only be set by the system.
*/
val compositionInChars: TextRange?
@@ -123,14 +122,4 @@
result = 31 * result + (compositionInChars?.hashCode() ?: 0)
return result
}
-
- // TODO make this function public in ui-text, use that instead.
- private fun TextRange.constrain(minimumValue: Int, maximumValue: Int): TextRange {
- val newStart = start.coerceIn(minimumValue, maximumValue)
- val newEnd = end.coerceIn(minimumValue, maximumValue)
- if (newStart != start || newEnd != end) {
- return TextRange(newStart, newEnd)
- }
- return this
- }
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldLineLimits.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldLineLimits.kt
index deafe71..4b14a14 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldLineLimits.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldLineLimits.kt
@@ -17,12 +17,17 @@
package androidx.compose.foundation.text2.input
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.text2.input.TextFieldLineLimits.MultiLine
+import androidx.compose.foundation.text2.input.TextFieldLineLimits.SingleLine
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
/**
* Values that specify the text wrapping, scrolling, and height measurement behavior for
* text fields.
+ *
+ * @see SingleLine
+ * @see MultiLine
*/
@ExperimentalFoundationApi
@Stable
@@ -32,9 +37,6 @@
* The text field is always a single line tall, ignores newlines in the
* text, and scrolls horizontally when the text overflows.
*/
- // TODO Convert newlines to not newlines once CodepointTransformation is available. Currently
- // softwrap is disabled, but new lines disappear below the bottom and there's no way to see
- // them.
object SingleLine : TextFieldLineLimits
/**
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldState.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldState.kt
index 442a7dd..6173da3 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldState.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/TextFieldState.kt
@@ -62,13 +62,13 @@
* changes.
*
* To observe changes to this property outside a restartable function, see [forEachTextValue]
- * and [textValues].
+ * and [textAsFlow].
*
* @sample androidx.compose.foundation.samples.BasicTextField2TextDerivedStateSample
*
* @see edit
* @see forEachTextValue
- * @see textValues
+ * @see textAsFlow
*/
val text: TextFieldCharSequence
get() = editProcessor.value
@@ -160,7 +160,17 @@
* Sets the text in this [TextFieldState] to [text], replacing any text that was previously there,
* and places the cursor at the end of the new text.
*
- * To perform more complicated edits on the text, call [TextFieldState.edit].
+ * To perform more complicated edits on the text, call [TextFieldState.edit]. This function is
+ * equivalent to calling:
+ * ```
+ * edit {
+ * replace(0, length, text)
+ * placeCursorAtEnd()
+ * }
+ * ```
+ *
+ * @see setTextAndSelectAll
+ * @see TextFieldBuffer.placeCursorAtEnd
*/
@ExperimentalFoundationApi
fun TextFieldState.setTextAndPlaceCursorAtEnd(text: String) {
@@ -174,7 +184,17 @@
* Sets the text in this [TextFieldState] to [text], replacing any text that was previously there,
* and selects all the text.
*
- * To perform more complicated edits on the text, call [TextFieldState.edit].
+ * To perform more complicated edits on the text, call [TextFieldState.edit]. This function is
+ * equivalent to calling:
+ * ```
+ * edit {
+ * replace(0, length, text)
+ * selectAll()
+ * }
+ * ```
+ *
+ * @see setTextAndPlaceCursorAtEnd
+ * @see TextFieldBuffer.selectAll
*/
@ExperimentalFoundationApi
fun TextFieldState.setTextAndSelectAll(text: String) {