Skip to content

Commit 10d5e35

Browse files
committed
feat: AuthMethodPicker, logo and provider theme style
1 parent ba57e4a commit 10d5e35

File tree

2 files changed

+197
-7
lines changed

2 files changed

+197
-7
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package com.firebase.ui.auth.compose
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.foundation.layout.Column
8+
import androidx.compose.foundation.layout.PaddingValues
9+
import androidx.compose.foundation.layout.Spacer
10+
import androidx.compose.foundation.layout.fillMaxHeight
11+
import androidx.compose.foundation.layout.fillMaxSize
12+
import androidx.compose.foundation.layout.height
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.safeContentPadding
15+
import androidx.compose.foundation.layout.safeDrawingPadding
16+
import androidx.compose.foundation.layout.widthIn
17+
import androidx.compose.foundation.lazy.LazyColumn
18+
import androidx.compose.material.icons.Icons
19+
import androidx.compose.material.icons.filled.Favorite
20+
import androidx.compose.material.icons.filled.Star
21+
import androidx.compose.material3.Icon
22+
import androidx.compose.material3.Scaffold
23+
import androidx.compose.material3.Text
24+
import androidx.compose.runtime.Composable
25+
import androidx.compose.ui.Alignment
26+
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.graphics.Color
28+
import androidx.compose.ui.platform.LocalContext
29+
import androidx.compose.ui.text.style.TextAlign
30+
import androidx.compose.ui.tooling.preview.Preview
31+
import androidx.compose.ui.unit.dp
32+
import com.firebase.ui.auth.R
33+
import com.firebase.ui.auth.compose.AuthProviderButton
34+
import com.firebase.ui.auth.compose.configuration.AuthProvider
35+
import com.firebase.ui.auth.compose.configuration.stringprovider.DefaultAuthUIStringProvider
36+
import com.firebase.ui.auth.compose.configuration.theme.AuthUIAsset
37+
38+
//AuthMethodPicker(
39+
// providers = listOf(GoogleAuthProvider(), EmailAuthProvider()),
40+
// onProviderSelected = { provider -> /* ... */ }
41+
//)
42+
43+
/**
44+
* Renders the provider selection screen.
45+
*
46+
* **Example usage:**
47+
* ```kotlin
48+
* AuthMethodPicker(
49+
* providers = listOf(
50+
* AuthProvider.Google(),
51+
* AuthProvider.Email(),
52+
* ),
53+
* onProviderSelected = { provider -> /* ... */ }
54+
* )
55+
* ```
56+
*
57+
* @param modifier A modifier for the screen layout.
58+
* @param providers The list of providers to display.
59+
* @param logo An optional logo to display.
60+
* @param onProviderSelected A callback when a provider is selected.
61+
* @param customLayout An optional custom layout composable for the provider buttons.
62+
*
63+
* @since 10.0.0
64+
*/
65+
@Composable
66+
fun AuthMethodPicker(
67+
modifier: Modifier = Modifier,
68+
providers: List<AuthProvider>,
69+
logo: AuthUIAsset? = null,
70+
onProviderSelected: (AuthProvider) -> Unit,
71+
customLayout: @Composable ((List<AuthProvider>, (AuthProvider) -> Unit) -> Unit)? = null,
72+
) {
73+
val context = LocalContext.current
74+
75+
Column(
76+
modifier = modifier
77+
.fillMaxSize()
78+
.safeDrawingPadding(),
79+
horizontalAlignment = Alignment.CenterHorizontally
80+
) {
81+
logo?.let {
82+
Image(
83+
modifier = Modifier
84+
.weight(0.4f),
85+
painter = it.painter,
86+
contentDescription = "AuthMethodPicker logo",
87+
)
88+
}
89+
if (customLayout != null) {
90+
customLayout(providers, onProviderSelected)
91+
} else {
92+
LazyColumn(
93+
modifier = Modifier
94+
.fillMaxSize()
95+
.weight(1f),
96+
horizontalAlignment = Alignment.CenterHorizontally,
97+
contentPadding = PaddingValues(bottom = 64.dp) // Space for text
98+
) {
99+
items(providers.size) { index ->
100+
val provider = providers[index]
101+
Box(
102+
modifier = Modifier
103+
.padding(bottom = 16.dp)
104+
) {
105+
AuthProviderButton(
106+
onClick = {
107+
onProviderSelected(provider)
108+
},
109+
provider = provider,
110+
stringProvider = DefaultAuthUIStringProvider(context)
111+
)
112+
}
113+
}
114+
}
115+
Text(
116+
"By continuing, you are indicating that you accept our " +
117+
"Terms of Service and Privacy Policy.",
118+
textAlign = TextAlign.Center,
119+
modifier = Modifier
120+
.padding(horizontal = 16.dp, vertical = 16.dp)
121+
)
122+
}
123+
}
124+
}
125+
126+
@Preview(showBackground = true)
127+
@Composable
128+
fun PreviewAuthMethodPicker() {
129+
AuthMethodPicker(
130+
providers = listOf(
131+
AuthProvider.Email(
132+
actionCodeSettings = null,
133+
passwordValidationRules = emptyList()
134+
),
135+
AuthProvider.Phone(
136+
defaultNumber = null,
137+
defaultCountryCode = null,
138+
allowedCountries = null,
139+
),
140+
AuthProvider.Google(
141+
scopes = emptyList(),
142+
serverClientId = null
143+
),
144+
AuthProvider.Facebook(),
145+
AuthProvider.Twitter(
146+
customParameters = emptyMap()
147+
),
148+
AuthProvider.Github(
149+
customParameters = emptyMap()
150+
),
151+
AuthProvider.Microsoft(
152+
tenant = null,
153+
customParameters = emptyMap()
154+
),
155+
AuthProvider.Yahoo(
156+
customParameters = emptyMap()
157+
),
158+
AuthProvider.Apple(
159+
locale = null,
160+
customParameters = emptyMap()
161+
),
162+
AuthProvider.Anonymous,
163+
AuthProvider.GenericOAuth(
164+
providerId = "google.com",
165+
scopes = emptyList(),
166+
customParameters = emptyMap(),
167+
buttonLabel = "Generic Provider",
168+
buttonIcon = AuthUIAsset.Vector(Icons.Default.Star),
169+
buttonColor = Color.Gray,
170+
contentColor = Color.White
171+
)
172+
),
173+
logo = AuthUIAsset.Resource(R.drawable.fui_ic_check_circle_black_128dp),
174+
onProviderSelected = { provider ->
175+
176+
},
177+
)
178+
}

auth/src/main/java/com/firebase/ui/auth/compose/AuthProviderButton.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import androidx.compose.foundation.Image
44
import androidx.compose.material3.Icon
55
import androidx.compose.foundation.layout.Arrangement
66
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.PaddingValues
78
import androidx.compose.foundation.layout.Row
89
import androidx.compose.foundation.layout.Spacer
910
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.fillMaxWidth
1012
import androidx.compose.foundation.layout.width
13+
import androidx.compose.foundation.layout.widthIn
1114
import androidx.compose.foundation.shape.RoundedCornerShape
1215
import androidx.compose.material.icons.Icons
1316
import androidx.compose.material.icons.filled.Star
@@ -19,6 +22,8 @@ import androidx.compose.ui.Alignment
1922
import androidx.compose.ui.Modifier
2023
import androidx.compose.ui.graphics.Color
2124
import androidx.compose.ui.platform.LocalContext
25+
import androidx.compose.ui.text.style.TextAlign
26+
import androidx.compose.ui.text.style.TextOverflow
2227
import androidx.compose.ui.tooling.preview.Preview
2328
import androidx.compose.ui.unit.dp
2429
import com.firebase.ui.auth.compose.configuration.AuthProvider
@@ -63,10 +68,12 @@ fun AuthProviderButton(
6368
stringProvider: AuthUIStringProvider,
6469
) {
6570
val providerStyle = resolveProviderStyle(provider, style)
66-
val providerText = resolveProviderLabel(provider, stringProvider)
71+
val providerLabel = resolveProviderLabel(provider, stringProvider)
6772

6873
Button(
69-
modifier = modifier,
74+
modifier = modifier
75+
.width(208.dp),
76+
contentPadding = PaddingValues(horizontal = 12.dp),
7077
colors = ButtonDefaults.buttonColors(
7178
containerColor = providerStyle.backgroundColor,
7279
contentColor = providerStyle.contentColor,
@@ -79,27 +86,32 @@ fun AuthProviderButton(
7986
enabled = enabled,
8087
) {
8188
Row(
82-
verticalAlignment = Alignment.CenterVertically
89+
modifier = Modifier
90+
.fillMaxWidth(),
91+
verticalAlignment = Alignment.CenterVertically,
92+
horizontalArrangement = Arrangement.Start
8393
) {
8494
val providerIcon = providerStyle.icon
8595
if (providerIcon != null) {
8696
val iconTint = providerStyle.iconTint
8797
if (iconTint != null) {
8898
Icon(
8999
painter = providerIcon.painter,
90-
contentDescription = providerText,
100+
contentDescription = providerLabel,
91101
tint = iconTint
92102
)
93103
} else {
94104
Image(
95105
painter = providerIcon.painter,
96-
contentDescription = providerText
106+
contentDescription = providerLabel
97107
)
98108
}
99-
Spacer(modifier = Modifier.width(8.dp))
109+
Spacer(modifier = Modifier.width(12.dp))
100110
}
101111
Text(
102-
text = providerText
112+
text = providerLabel,
113+
overflow = TextOverflow.Ellipsis,
114+
maxLines = 1,
103115
)
104116
}
105117
}

0 commit comments

Comments
 (0)