Skip to content

Commit

Permalink
foundation. physics. Fix outlined text view regression (#855)
Browse files Browse the repository at this point in the history
## Proposed Changes

Construct `OverscrollEffect` outside of `textFieldScrollable` and pass
it there to keep scroll behavior similar to iOS (the only platform
providing text field overscroll for now)
Use the `OverscrollEffect.effectModifier` (if any) for internal text and
not decoration box itself to avoid unintended clipping.

## Testing

Test: check that `OutlinedTextField` is not incorrectly clipped.
`OverscrollEffect` for large text fields still works correctly.

## Issues Fixed

Fixes: JetBrains/compose-multiplatform#3737

---------

Co-authored-by: dima.avdeev <dima.avdeev@jetbrains.com>
  • Loading branch information
2 people authored and igordmn committed Nov 14, 2023
1 parent b7ddc4d commit 472c075
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -591,14 +591,16 @@ internal fun CoreTextField(
imeAction = imeOptions.imeAction,
)

val overscrollEffect = rememberTextFieldOverscrollEffect()

// Modifiers that should be applied to the outer text field container. Usually those include
// gesture and semantics modifiers.
val decorationBoxModifier = modifier
.then(focusModifier)
.interceptDPadAndMoveFocus(state, focusManager)
.previewKeyEventToDeselectOnBack(state, manager)
.then(textKeyInputModifier)
.textFieldScrollable(scrollerPosition, interactionSource, enabled)
.textFieldScrollable(scrollerPosition, interactionSource, enabled, overscrollEffect)
.then(pointerModifier)
.then(semanticsModifier)
.onGloballyPositioned {
Expand All @@ -614,6 +616,11 @@ internal fun CoreTextField(

CoreTextFieldRootBox(decorationBoxModifier, manager) {
decorationBox {
fun Modifier.overscroll(): Modifier =
overscrollEffect?.let {
this then it.effectModifier
} ?: this

// Modifiers applied directly to the internal input field implementation. In general,
// these will most likely include draw, layout and IME related modifiers.
val coreTextFieldModifier = Modifier
Expand All @@ -625,6 +632,7 @@ internal fun CoreTextField(
minLines = minLines,
maxLines = maxLines
)
.overscroll()
.textFieldScroll(
scrollerPosition,
value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ internal expect fun rememberTextFieldOverscrollEffect(): OverscrollEffect?
internal fun Modifier.textFieldScrollable(
scrollerPosition: TextFieldScrollerPosition,
interactionSource: MutableInteractionSource? = null,
enabled: Boolean = true
enabled: Boolean = true,
overscrollEffect: OverscrollEffect? = null
) = composed(
inspectorInfo = debugInspectorInfo {
name = "textFieldScrollable"
Expand Down Expand Up @@ -98,8 +99,6 @@ internal fun Modifier.textFieldScrollable(
}
}

val overscrollEffect = rememberTextFieldOverscrollEffect()

val scroll = Modifier.scrollable(
orientation = scrollerPosition.orientation,
reverseDirection = reverseDirection,
Expand All @@ -109,11 +108,7 @@ internal fun Modifier.textFieldScrollable(
enabled = enabled && scrollerPosition.maximum != 0f
)

overscrollEffect?.effectModifier?.let { overscrollModifer ->
// Just like LazyList does, we need to apply clipScrollableContainer
// to avoid situation where overscroll modifier causes text to clip through the container
Modifier.clipScrollableContainer(scrollerPosition.orientation) then overscrollModifer then scroll
} ?: scroll
scroll

}

Expand Down

0 comments on commit 472c075

Please sign in to comment.