Merge "Polish the documentation for BasicTextField2." into androidx-main
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) {