Skip to content

Commit

Permalink
Implement GravatarTheme
Browse files Browse the repository at this point in the history
It would be nice to have our own GravatarTheme so that we can keep our Gravatar style in all UI components, at least for the default state.

Developers using the SDK could override our Theme if they don't want to use it. Using CompositionLocal, they'll be able to provide another implementation of GravatarTheme using whatever they want.

Right now, we are using the Material 3 base styles, but we plan to update those with our colors, typographies, and shapes.
  • Loading branch information
hamorillo committed Apr 18, 2024
1 parent c94ff24 commit ccda739
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 78 deletions.
57 changes: 57 additions & 0 deletions gravatar-ui/src/main/java/com/gravatar/ui/GravatarTheme.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.gravatar.ui

import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.staticCompositionLocalOf

/**
* [GravatarTheme] is a composable that wraps the content of the application with the Gravatar theme.
*/
@Composable
public fun GravatarTheme(content: @Composable () -> Unit) {
MaterialTheme(
colorScheme = gravatarTheme.colorScheme,
typography = gravatarTheme.typography,
shapes = gravatarTheme.shapes,
) {
content()
}
}

/**
* [GravatarTheme] contains the colors, typography, and shapes to be used in the Gravatar UI components.
* Those values follow the Gravatar style guide but can be customized by the user.
* In order to customize the theme, the user can provide a custom [GravatarTheme] using [Composition Local](https://developer.android.com/develop/ui/compose/compositionlocal)
*
* [colorScheme] The color scheme to be used in the Gravatar UI components
* [typography] The typography to be used in the Gravatar UI components
* [shapes] The shapes to be used in the Gravatar UI components
*/
public interface GravatarTheme {
public val colorScheme: ColorScheme
@Composable
get() = MaterialTheme.colorScheme

public val typography: Typography
@Composable
get() = MaterialTheme.typography

public val shapes: Shapes
@Composable
get() = MaterialTheme.shapes
}

/**
* [LocalGravatarTheme] is a CompositionLocal that provides the current [GravatarTheme].
*/
public val LocalGravatarTheme: ProvidableCompositionLocal<GravatarTheme> =
staticCompositionLocalOf { object : GravatarTheme {} }

/** The current [GravatarTheme]. */
public val gravatarTheme: GravatarTheme
@Composable
get() = LocalGravatarTheme.current
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
import com.gravatar.api.models.Account
import com.gravatar.api.models.Email
import com.gravatar.api.models.UserProfile
import com.gravatar.ui.GravatarTheme
import com.gravatar.ui.components.atomic.AboutMe
import com.gravatar.ui.components.atomic.Avatar
import com.gravatar.ui.components.atomic.DisplayName
Expand All @@ -31,26 +32,28 @@ import com.gravatar.ui.components.atomic.ViewProfileButton
*/
@Composable
public fun LargeProfile(profile: UserProfile, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
) {
Avatar(
profile = profile,
size = 132.dp,
modifier = Modifier.clip(CircleShape),
)
DisplayName(profile, modifier = Modifier.padding(top = 16.dp))
UserInfo(profile)
AboutMe(profile, modifier = Modifier.padding(top = 8.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
GravatarTheme {
Column(
modifier = modifier,
) {
SocialIconRow(profile, maxIcons = 4)
ViewProfileButton(profile, Modifier.padding(0.dp))
Avatar(
profile = profile,
size = 132.dp,
modifier = Modifier.clip(CircleShape),
)
DisplayName(profile, modifier = Modifier.padding(top = 16.dp))
UserInfo(profile)
AboutMe(profile, modifier = Modifier.padding(top = 8.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
SocialIconRow(profile, maxIcons = 4)
ViewProfileButton(profile, Modifier.padding(0.dp))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
import com.gravatar.api.models.Account
import com.gravatar.api.models.Email
import com.gravatar.api.models.UserProfile
import com.gravatar.ui.GravatarTheme
import com.gravatar.ui.components.atomic.Avatar
import com.gravatar.ui.components.atomic.DisplayName
import com.gravatar.ui.components.atomic.UserInfo
Expand All @@ -29,24 +30,26 @@ import com.gravatar.ui.components.atomic.ViewProfileButton
*/
@Composable
public fun LargeProfileSummary(profile: UserProfile, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Avatar(
profile = profile,
size = 132.dp,
modifier = Modifier.clip(CircleShape),
)
DisplayName(profile, modifier = Modifier.padding(top = 16.dp))
UserInfo(
profile,
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.outline,
textAlign = TextAlign.Center,
),
)
ViewProfileButton(profile, Modifier.padding(0.dp), inlineContent = null)
GravatarTheme {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Avatar(
profile = profile,
size = 132.dp,
modifier = Modifier.clip(CircleShape),
)
DisplayName(profile, modifier = Modifier.padding(top = 16.dp))
UserInfo(
profile,
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.outline,
textAlign = TextAlign.Center,
),
)
ViewProfileButton(profile, Modifier.padding(0.dp), inlineContent = null)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.gravatar.api.models.UserProfile
import com.gravatar.ui.GravatarTheme
import com.gravatar.ui.components.atomic.Avatar
import com.gravatar.ui.components.atomic.DisplayName
import com.gravatar.ui.components.atomic.Location
Expand All @@ -27,21 +28,26 @@ import com.gravatar.ui.components.atomic.ViewProfileButton
*/
@Composable
public fun MiniProfileCard(profile: UserProfile, modifier: Modifier = Modifier) {
Row(modifier = modifier) {
Avatar(
profile = profile,
size = 72.dp,
modifier = Modifier.clip(CircleShape),
)
Column(modifier = Modifier.padding(start = 14.dp)) {
DisplayName(profile, textStyle = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold))
if (!profile.currentLocation.isNullOrBlank()) {
Location(profile)
}
ViewProfileButton(
profile,
modifier = Modifier.height(32.dp),
GravatarTheme {
Row(modifier = modifier) {
Avatar(
profile = profile,
size = 72.dp,
modifier = Modifier.clip(CircleShape),
)
Column(modifier = Modifier.padding(start = 14.dp)) {
DisplayName(
profile,
textStyle = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
)
if (!profile.currentLocation.isNullOrBlank()) {
Location(profile)
}
ViewProfileButton(
profile,
modifier = Modifier.height(32.dp),
)
}
}
}
}
Expand Down
57 changes: 30 additions & 27 deletions gravatar-ui/src/main/java/com/gravatar/ui/components/ProfileCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.compose.ui.unit.dp
import com.gravatar.api.models.Account
import com.gravatar.api.models.Email
import com.gravatar.api.models.UserProfile
import com.gravatar.ui.GravatarTheme
import com.gravatar.ui.components.atomic.AboutMe
import com.gravatar.ui.components.atomic.Avatar
import com.gravatar.ui.components.atomic.DisplayName
Expand All @@ -35,35 +36,37 @@ import com.gravatar.ui.components.atomic.ViewProfileButton
*/
@Composable
public fun ProfileCard(profile: UserProfile, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top,
) {
Row {
Avatar(
profile = profile,
size = 72.dp,
modifier = Modifier.clip(CircleShape),
)
Column(modifier = Modifier.padding(14.dp, 0.dp, 0.dp, 0.dp)) {
DisplayName(
profile,
textStyle = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
GravatarTheme {
Column(
modifier = modifier,
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top,
) {
Row {
Avatar(
profile = profile,
size = 72.dp,
modifier = Modifier.clip(CircleShape),
)
UserInfo(profile)
Column(modifier = Modifier.padding(14.dp, 0.dp, 0.dp, 0.dp)) {
DisplayName(
profile,
textStyle = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
)
UserInfo(profile)
}
}
Spacer(modifier = Modifier.height(16.dp))
AboutMe(profile)
Spacer(modifier = Modifier.height(4.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
SocialIconRow(profile, maxIcons = 4)
ViewProfileButton(profile, Modifier.padding(0.dp))
}
}
Spacer(modifier = Modifier.height(16.dp))
AboutMe(profile)
Spacer(modifier = Modifier.height(4.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
SocialIconRow(profile, maxIcons = 4)
ViewProfileButton(profile, Modifier.padding(0.dp))
}
}
}
Expand Down

0 comments on commit ccda739

Please sign in to comment.