Extends Supabase-kt with UI composables
Supported targets:
Target | JVM | Android | JS | iOS | tvOS | watchOS | macOS | Windows | Linux |
---|---|---|---|---|---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
In-depth Kotlin targets
iOS: iosArm64, iosSimulatorArm64, iosX64
JS: Browser, NodeJS
tvOS: tvosArm64, tvosX64, tvosSimulatorArm64
watchOS: watchosArm64, watchosX64, watchosSimulatorArm64
MacOS: macosX64, macosArm64
Windows: mingwX64
Linux: linuxX64
dependencies {
implementation("io.github.jan-tennert.supabase:compose-auth-ui:VERSION")
}
Full Compose for Desktop Example
singleWindowApplication {
MaterialTheme(
darkColorScheme()
) {
Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background), contentAlignment = Alignment.Center) {
AuthForm {
var password by remember { mutableStateOf("") }
var email by remember { mutableStateOf("") }
var phone by remember { mutableStateOf("") }
val state = LocalAuthState.current
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
OutlinedEmailField(
value = email,
onValueChange = { email = it },
label = { Text("E-Mail") },
mandatory = email.isNotBlank() //once an email is entered, it is mandatory. (which enable validation)
)
OutlinedPhoneField(
value = phone,
onValueChange = { phone = it },
label = { Text("Phone Number") }
)
OutlinedPasswordField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
rules = rememberPasswordRuleList(PasswordRule.minLength(6), PasswordRule.containsSpecialCharacter(), PasswordRule.containsDigit(), PasswordRule.containsLowercase(), PasswordRule.containsUppercase())
)
FormComponent("accept_terms") { valid ->
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(
checked = valid.value,
onCheckedChange = { valid.value = it },
)
Text("Accept Terms", color = MaterialTheme.colorScheme.onBackground)
}
}
Button(
onClick = {}, //Login with email and password,
enabled = state.validForm,
) {
Text("Login")
}
OutlinedButton(
onClick = {}, //Login with Google,
content = { ProviderButtonContent(Google) }
)
Button(
onClick = {}, //Login with Twitch,
content = { ProviderButtonContent(Twitch) }
)
}
}
}
}
}
java_2023-08-22_16-48-18.mp4
You can set rules
for the password like this:
OutlinedPasswordField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
rules = rememberPasswordRuleList(PasswordRule.minLength(6), PasswordRule.containsSpecialCharacter(), PasswordRule.containsDigit(), PasswordRule.containsLowercase(), PasswordRule.containsUppercase())
)
Once set, the field will automatically display an error supporting text if the password doesn't match the criteria. Note that the built-in roles also accept a custom description as a parameter. You can also easily create your own rules:
val myRule = PasswordRule("description") { password ->
password.contains("-")
}
The email field has a validator parameter which defaults to a regex solution. Example:
OutlinedEmailField(
value = email,
onValueChange = { email = it },
label = { Text("E-Mail") },
validator = EmailValidator {
//validate email
}
)
The phone field also has a validator parameter, which just checks whether the phone number only consists of digits.
On top of that you can provide a mask
parameter, which changes how the phone number gets displayed. The value is just the raw number.
Example with the default mask:
OutlinedPhoneField(
value = phone,
onValueChange = { phone = it },
label = { Text("Phone") }
)
Example with custom mask: (you can also set it to null, if you don't want a mask)
OutlinedPhoneField(
value = phone,
onValueChange = { phone = it },
label = { Text("Phone") },
mask = "(###) ###-####"
)
Note: You can customize the fields completely, they just all have default values. They also have a `mandatory´ option, you can use that to have optional fields. It is also possible to make fields only mandatory (=validation enabled) once the field is not empty. (See example)
This module provides a function to generate the button content independently of the variation:
OutlinedButton(
onClick = {}, //Login with Google,
content = { ProviderButtonContent(Google) }
)
Button(
onClick = {}, //Login with Twitch,
content = { ProviderButtonContent(Twitch) }
)
You can also only use the icon if you want a custom layout:
Button(
onClick = {},
) {
ProviderIcon(Google)
Text("Login with Google")
}
You can also easily make your own form components:
FormComponent(formKey = "accept_terms", mandatory = true) { valid ->
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(
checked = valid.value,
onCheckedChange = { valid.value = it },
)
Text("Accept Terms", color = MaterialTheme.colorScheme.onBackground)
}
}
Mandatory changes whether the AuthState#validForm
property is affected by this component.