How can i disable text selection from a `BasicText...
# compose
a
How can i disable text selection from a
BasicTextField
? Wrapping it in a
DisableSelection
doesn't seem to work
tldr: You can pass
enabled = false
which disabled everything (including editing and selection). Not ideal but can be used as a workaround.
h
Which BasicTextField overload are you using? For onValueChange you can simply set the new value by collapsing the selection. Whenever the new value's selection is a non-collapsed range, just use the selection from the previous value. In the new BTF, you can use InputTransformation and reject the selection change. I'm on mobile rn so I'll try to follow up with code samples soon
a
im confused. what does collapsing the selection mean? I am on desktop and i want to prevent the
BasicTextField
to handy and dragging (selection) happening to it, but allow editing. This is because I want my text field to be draggable
p
Thoughts: may be to put it to Box and place element that handle mouse event over it?
h
Copy code
var value by remember { mutableStateOf(TextFieldValue()) }
BasicTextField(
    value = value,
    onValueChange = {
        value = it.copy(
            selection = if (it.selection.collapsed) {
                it.selection
            } else {
                TextRange(value.selection.start)
            }
        )
    }
)

// or

BasicTextField(rememberTextFieldState(), inputTransformation = {
    if (!selection.collapsed) {
        selection = TextRange(originalSelection.start)
    }
})
this is essentially about never allowing BasicTextField to have an extended selection. Collapse and Extend refers to the size of the
TextRange
that is used as selection. Collapsed selection means there is no selection, just a cursor. Extended is when
TextRange
spans at least one character.
TextRange(4, 4)
is collapsed,
TextRange(4, 5)
is extended.
a
@PHondogo what you suggest is what I ended up doing. have an 'editable' state and depending on that enable or disable the text. needs a lot of wiring but I was able to get the UX I wanted
@Halil Ozercan your code does not disable selection. it 'blocks' selection after it starts. the text fields ends up consuming the drag event even if nothing gets selected afterwards and the cursor moved to where the drag position starts
For anyone stumbling across this in the future, it is much simpler to be swapping out a
BasicTextField
with a
BasicText
if you need to disable editing. No other code changes needed
h
glad to hear that that approach works for you. BasicTextField has always been designed to be compatible with BasicText. So in a scenario where BasicTextField does not have overflow,
BasicTextField
and
BasicText
rendering should be identical if all text related parameters are the same.
👌 1
a
that's good to hear. overall all seem to be working as expected now. The only difference I found is that the
BasicTextField
has some default width for some reason. Seems like a bug which I filled it here
Would be cool if the text selection API worked the same for both btw. found it very strange how
DisableSelection
doesn't work on
BasicTextField
h
The default width was discussed before, so the current behavior is intended. When a
BasicTextField
is placed on the screen with no content in it, what should be its width? It should not be zero because then you have no way to interact with it.
1.dp
or any other similarly small value is no different than
0.dp
. Therefore we kept the initially chosen
HHHHHHHHHH
as the default text that is measured for the minimum width of any
BasicTextField
. IIRC the workaround you found was also the official suggestion. cc; @Grant Toepfer , I remember you looking into this.
a
ok, i understand that it works as intended. i might be missing something but why is there a need for the text field to be interactive when it has no text?
I see the
Basic
components as building blocks to build UI with. not to use directly in my app. that sounds like a decision for components ie for a design system.
h
We think that by default a
BasicTextField
call should place a box on the screen that can be tapped to bring the keyboard. Otherwise expecting people to explicitly provide width modifier to achieve this behavior sounds unintuitive.
a
i see. I think my "beef" is that there is a Basic_TextField_ component instead of a Basic_TextInput_ component. 100% it makes sense to have some width on a text field, but not so much for any text input
👍 1
just discussing here btw. not arguing in any way
👍 1
h
I see the
Basic
components as building blocks to build UI with. not to use directly in my app. that sounds like a decision for components ie for a design system.
I understand this point of view. You are correct that
Basic
components are not supposed to be called directly in app code. However
BasicTextField
by design has to make some tradeoffs to be at least usable. The min width is one of those. Ideally foundation would provide a modifier or some other composable that doesn't even do text layout, text selection, just text input management from InputConnection.
👍 1