-
Notifications
You must be signed in to change notification settings - Fork 0
Theme
The theme is defined by a quite complex but not really token structure.
A token is a key-value pair that describes a specific characteristic in the design system.
Example:
button.color.primary.background.enabled = Green100
These tokens are used to ensure consistency across platforms, tools, and departments in our organization.
These are mostly used inside the design system when developing components BUT can also be changed by client apps as part of a custom theme, allowing very granular changes in the theme.
By default, the design system comes with a DefaultTheme to be used right away, but there is the possibility to customize each token in client apps.
You need to define a EverliTheme as the root of your composition tree or use the DefaultTheme
ℹ️ The theme is heavily inspired by Material Theme and involves usage of Composition Local Providers.
🙏 Please have a look at these two concepts to understand how theme works in compose.
@Composable
fun EverliApp() {
DefaultTheme() {
// your app
}
}Then inside any @Composable you will have access to any token of the design system via the EverliTheme object
@Composable
fun SomeRandomComponent() {
Text(
text = "label",
style = EverliTheme.typography.subtitleSemibold),
)
}Note: Most (if not all) components provided in the library, require you to have a defined EverliTheme to work properly.
If you want to provide a custom implementation, you can just copy DefaultTheme components or implement your own EverliTheme
val SupplyButtonTheme = DefaultButtonTheme.copy(
color = DefaultButtonTheme.color.copy(
primary = DefaultButtonTheme.color.primary.copy(
fill = DefaultButtonTheme.color.primary.fill.copy(
background = DefaultButtonTheme.color.primary.fill.background.copy(
enabled = EverliColors.Purple100,
pressed = purple80,
),
),
outline = DefaultButtonTheme.color.primary.outline.copy(
background = DefaultButtonTheme.color.primary.outline.background.copy(
pressed = purple20,
),
border = DefaultButtonTheme.color.primary.outline.border.copy(
enabled = purple80,
),
),
flat = DefaultButtonTheme.color.primary.flat.copy(
background = DefaultButtonTheme.color.primary.flat.background.copy(
pressed = purple20,
),
),
),
),
)
@Composable
fun AppWithCustomTheme() {
EverliTheme(
typography = DefaultTypography,
radius = DefaultRadius,
dimensions = DefaultDimensions,
buttonTheme = SupplyButtonTheme,
) {
// your content
}
}In the above example, we define a custom theme just for the Button. Note that all components of the Theme have dedicated data classes and are easily customizable via kotlin's .copy method as shown above.
Another nice advantage of Compose is that we can nest multiple themes in the same app:
@Preview
@Composable
fun InnerCustomTheme() {
DefaultTheme {
Column {
// Default Theme
EverliButton(onClick = { /*TODO*/ }, text = "Default Theme")
// Inner custom theme
EverliTheme(
buttonTheme = SupplyButtonTheme,
) {
EverliButton(onClick = { /*TODO*/ }, text = "Custom Theme")
}
}
}
}
Notice that the second button used a different theme just for the button, all other tokens are inherited by the parent theme. Again, all this is possible thanks to CompositionLocalProviders
This can be useful if you want a particular section of the app to use a different theme (e.g. debug area).