git.iko.soy/opencode-android
on 06fd41b help sign in
49 lines 2.2 kB history raw
1@file:Suppress("MatchingDeclarationName")
3package soy.iko.opencode.ui.components
5import androidx.compose.runtime.Composable
6import androidx.compose.runtime.getValue
7import androidx.compose.runtime.remember
8import androidx.compose.runtime.rememberUpdatedState
9import androidx.compose.ui.ExperimentalComposeUiApi
10import androidx.compose.ui.Modifier
11import androidx.compose.ui.autofill.AutofillNode
12import androidx.compose.ui.autofill.AutofillType
13import androidx.compose.ui.layout.boundsInWindow
14import androidx.compose.ui.layout.onGloballyPositioned
15import androidx.compose.ui.platform.LocalAutofillTree
17/**
18 * A stable, non-experimental hint for which autofill category a field represents, so callers
19 * don't have to opt into the experimental [AutofillType] API (or reference `androidx.compose.ui
20 * .autofill` types) at every text-field call site.
21 */
22enum class AutofillHint { Username, Password, Email }
24/**
25 * Registers an autofill node for [hint] with the Compose autofill tree so password managers and
26 * the system credential service can populate the field. Returns a [Modifier] that reports the
27 * field's window bounds so the platform's autofill UI anchors to it.
28 *
29 * Compose's autofill API is still experimental (`androidx.compose.ui.autofill`); encapsulating
30 * it here keeps the opt-in local and gives every auth field the same hint wiring. Without it,
31 * Compose text fields carry no autofill hints and password managers can't fill them.
32 */
33@OptIn(ExperimentalComposeUiApi::class)
34@Composable
35fun autofillModifier(hint: AutofillHint, onFill: (String) -> Unit): Modifier {
36 val currentOnFill by rememberUpdatedState(onFill)
37 val types = remember(hint) {
38 listOf(
39 when (hint) {
40 AutofillHint.Username -> AutofillType.Username
41 AutofillHint.Password -> AutofillType.Password
42 AutofillHint.Email -> AutofillType.EmailAddress
43 },
44 )
45 }
46 val node = remember(types) { AutofillNode(autofillTypes = types, onFill = { currentOnFill(it) }) }
47 LocalAutofillTree.current += node
48 return Modifier.onGloballyPositioned { coords -> node.boundingBox = coords.boundsInWindow() }