Skip to content

Instantly share code, notes, and snippets.

@rahul-gill
Last active April 12, 2022 08:47
Show Gist options
  • Save rahul-gill/78c3be824d13fe565b41e4c02b8b46bf to your computer and use it in GitHub Desktop.
Save rahul-gill/78c3be824d13fe565b41e4c02b8b46bf to your computer and use it in GitHub Desktop.
Design System
/**
* creating custom design system colors
* we can also add attributes like buttonColor, headerColor, topBarColor etc.
*/
class DlsColors(
primary: Color,
onPrimary: Color,
background: Color,
onBackground: Color,
error: Color,
onError: Color,
warning: Color,
onWarning: Color,
isLight: Boolean
) {
var primary by mutableStateOf(primary, structuralEqualityPolicy())
internal set
var onPrimary by mutableStateOf(onPrimary, structuralEqualityPolicy())
internal set
var background by mutableStateOf(background, structuralEqualityPolicy())
internal set
var onBackground by mutableStateOf(onBackground, structuralEqualityPolicy())
internal set
var error by mutableStateOf(error, structuralEqualityPolicy())
internal set
var onError by mutableStateOf(onError, structuralEqualityPolicy())
internal set
var warning by mutableStateOf(warning, structuralEqualityPolicy())
internal set
var onWarning by mutableStateOf(onWarning, structuralEqualityPolicy())
internal set
var isLight by mutableStateOf(isLight, structuralEqualityPolicy())
internal set
/**
* Returns a copy of this Colors, optionally overriding some of the values.
*/
fun copy(
primary: Color = this.primary,
onPrimary: Color = this.onPrimary,
background: Color = this.background,
onBackground: Color = this.onBackground,
error: Color = this.error,
onError: Color = this.onError,
warning: Color = this.warning,
onWarning: Color = this.onWarning,
isLight: Boolean = this.isLight
): DlsColors = DlsColors(
primary,
onPrimary,
background,
onBackground,
error,
onError,
warning,
onWarning,
isLight
)
}
fun lightDlsColors(
primary: Color = Color(0xFF6200EE),
onPrimary: Color = Color.White,
background: Color = Color.White,
onBackground: Color = Color.Black,
error: Color = Color(0xFFB00020),
onError: Color = Color.White,
warning: Color = Color(0xFFD0D000),
onWarning: Color = Color.Black
): DlsColors = DlsColors(
primary,
onPrimary,
background,
onBackground,
error,
onError,
warning,
onWarning,
true
)
fun darkDlsColors(
primary: Color = Color(0xFFBB86FC),
onPrimary: Color = Color.Black,
background: Color = Color(0xFF121212),
onBackground: Color = Color.White,
error: Color = Color(0xFFCF6679),
onError: Color = Color.Black,
warning: Color = Color(0xFFA0A030),
onWarning: Color = Color.White
): DlsColors = DlsColors(
primary,
onPrimary,
background,
onBackground,
error,
onError,
warning,
onWarning,
false
)
internal fun DlsColors.updateColorsFrom(other: DlsColors) {
primary = other.primary
onPrimary = other.onPrimary
background = other.background
onBackground = other.onBackground
error = other.error
onError = other.onError
warning = other.warning
onWarning = other.onWarning
isLight = other.isLight
}
internal val LocalDlsColors = staticCompositionLocalOf { lightDlsColors() }
/**
* A reusable ui component
*/
@Composable
fun DashboardAction(
title: String,
@DrawableRes imageResId: Int,
buttonColor: Color = DlsTheme.colors.primary,
iconTextColor: Color = DlsTheme.colors.onPrimary,
onClick: () -> Unit
){
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = { onClick() },
modifier = Modifier.size(100.dp),
shape = CircleShape,
contentPadding = PaddingValues(0.dp),
colors = ButtonDefaults.buttonColors(backgroundColor = buttonColor)
) {
Icon(
painter = painterResource(id = imageResId),
contentDescription = null,
tint = iconTextColor,
modifier = Modifier.size(50.dp)
)
}
Text(
text = title,
color = iconTextColor,
modifier = Modifier.padding(top = 16.dp)
)
}
}
@Preview
@Composable
fun Preview1(){
DashboardAction(
title = "Accounts",
imageResId = R.drawable.ic_baseline_home_repair_service_24,
onClick = {}
)
}
/**
* A little customization of theme
* If the devs using the library would want to have their own colors for example, this is how they'll do it
*/
@Preview
@Composable
fun Preview2(){
DlsTheme(
colors = DlsTheme.colors.copy(primary = Color.Yellow, onPrimary = Color.Black)
) {
DashboardAction(
title = "Accounts",
imageResId = R.drawable.ic_baseline_home_repair_service_24,
onClick = {}
)
}
}
/**
* We don't want color and border of our button to be modifier so:
* Restricting border and color of button
* for that border and color are removed from argument list, rest option are kept
*/
@Composable
fun DlsButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),
shape: Shape = DlsTheme.shapes.small,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
){
Button(
onClick = onClick,
modifier - modifier,
enabled = enabled,
interactionSource = interactionSource,
elevation = elevation,
shape = shape,
border = null,
colors = ButtonDefaults.buttonColors(backgroundColor = DlsTheme.colors.primary, contentColor = DlsTheme.colors.onPrimary),
contentPadding = contentPadding,
content = content
)
}
/**
* The way we made variant of Colors as dark and light colors we can also make variants of these for diffenent screen sizes
*/
data class DlsSize internal constructor(
val smaller: Dp = 4.dp,
val small: Dp = 8.dp,
val medium: Dp = 16.dp,
val large: Dp = 32.dp,
val larger: Dp = 64.dp
)
val Shapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(4.dp),
large = RoundedCornerShape(0.dp)
)
val LocalSizes = staticCompositionLocalOf { DlsSize() }
val LocalShapes = staticCompositionLocalOf { Shapes }
@Composable
fun DlsTheme(
colors: DlsColors = DlsTheme.colors,
typography: DlsTypography = DlsTheme.typography,
shapes: Shapes = DlsTheme.shapes,
size: DlsSize = DlsTheme.sizes,
content: @Composable () -> Unit
) {
CompositionLocalProvider(
LocalDlsColors provides colors,
LocalShapes provides shapes,
LocalDlsTypography provides typography,
LocalSizes provides size
) {
MaterialTheme {
content()
}
}
}
/**
* This object would provide the attributes to child composable which are inside the above DlsTheme composable
* These attributes will automatically reflect changes when they're changed, for example when theme is changed light<->dark
*/
object DlsTheme {
val colors: DlsColors
@Composable
@ReadOnlyComposable
get() = LocalDlsColors.current
val typography: DlsTypography
@Composable
@ReadOnlyComposable
get() = LocalDlsTypography.current
val shapes: Shapes
@Composable
@ReadOnlyComposable
get() = LocalShapes.current
val sizes: DlsSize
@Composable
@ReadOnlyComposable
get() = LocalSizes.current
}
data class DlsTypography internal constructor(
val headline1: TextStyle = TextStyle(
fontSize = 36.sp,
fontWeight = FontWeight.Bold,
lineHeight = 48.sp
),
val headline2: TextStyle = TextStyle(
fontSize = 32.sp,
fontWeight = FontWeight.Bold,
lineHeight = 40.sp
),
val headline3: TextStyle = TextStyle(
fontSize = 30.sp,
fontWeight = FontWeight.Bold,
lineHeight = 40.sp
),
val label: TextStyle = TextStyle(
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
lineHeight = 16.sp
),
val button: TextStyle = TextStyle(
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
lineHeight = 16.sp
),
val materialTypography: Typography = Typography()
)
val LocalDlsTypography = staticCompositionLocalOf { DlsTypography() }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment