Slide 1

Slide 1 text

Jetpack Compose + Design Systems François Blavoet

Slide 2

Slide 2 text

Jetpack Compose • Compose is the future of Android UI development • When is the best time to start adopting it ?

Slide 3

Slide 3 text

Design systems What is a Design system ? -> it is a complete set of standards intended to manage design at scale using reusable components and patterns.

Slide 4

Slide 4 text

Design systems @GET("/addresses") fun getAddresses(): Single @PUT("/addresses/{address_id}") fun updateAddress(@Path("address_id") id: String, @Body body: Map): Single

Slide 5

Slide 5 text

Let’s have a look at one component

Slide 6

Slide 6 text

Let’s have a look at one component

Slide 7

Slide 7 text

Let’s have a look at one component

Slide 8

Slide 8 text

Let’s have a look at one component

Slide 9

Slide 9 text

Let’s have a look at one component Row.Content { leading( label = "Order Changes Preferences", label2 = "Suggest replacements ...", ) trailing( label = "Edit", option = Row.TrailingOption.Clickable(onPreferenceClick) ) }

Slide 10

Slide 10 text

Let’s have a look at one component Row.Content { leading( label = "Tue Jun 2, 4–5pm", option = LeadingOption.Icon(Icon.Time), ) }

Slide 11

Slide 11 text

One design system

Slide 12

Slide 12 text

Material Design

Slide 13

Slide 13 text

Material Design Button( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, interactionSource: MutableInteractionSource = remember {..}, elevation: ButtonElevation? = ButtonDefaults.elevation(), shape: Shape = MaterialTheme.shapes.small, border: BorderStroke? = null, colors: ButtonColors = ButtonDefaults.buttonColors(), contentPadding: PaddingValues = ButtonDefaults.ContentPadding, content: @Composable RowScope.() -> Unit, )

Slide 14

Slide 14 text

Material Design?

Slide 15

Slide 15 text

Material Design? ?

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Let’s implement our own system

Slide 18

Slide 18 text

Atoms

Slide 19

Slide 19 text

Atoms Requirements: • Day/night • Customizable for white label apps • As easy to use as possible • Have an abstract representation outside of the composition

Slide 20

Slide 20 text

Atoms interface ColorSpec { @Composable fun value(): Color }

Slide 21

Slide 21 text

Atoms interface ColorSpec { @Composable fun value(): Color companion object { val SystemGrayscale70: ColorSpec = … val SystemGrayscale50: ColorSpec = … … } }

Slide 22

Slide 22 text

Atoms interface ColorSpec { @Composable fun value(): Color companion object { val SystemGrayscale70: ColorSpec = … val SystemGrayscale50: ColorSpec = … … fun fromColor(color: Color): ColorSpec { return StaticColor(color) } } }

Slide 23

Slide 23 text

Atoms @Composable fun DesignTheme( configuration: ThemeConfig? = null, content: @Composable () -> Unit, ) { … } object DesignTheme { val colors: Colors @Composable @ReadOnlyComposable get() = LocalColors.current }

Slide 24

Slide 24 text

Atoms

Slide 25

Slide 25 text

Atoms interface IconSlot { @Composable fun Content(contentColor: Color) }

Slide 26

Slide 26 text

Atoms interface IconSlot { @Composable fun Content(contentColor: Color) companion object { fun fromResource( @DrawableRes res: Int, contentDescription: TextSpec?, ): IconSlot { return ResIcon(res, contentDescription) } } }

Slide 27

Slide 27 text

Atoms enum class Icons(@DrawableRes internal val resId: Int) : IconSlot { Accessibility(R.drawable.cp_accessibility), Account(R.drawable.cp_account), Add(R.drawable.cp_add), … }

Slide 28

Slide 28 text

Molecules

Slide 29

Slide 29 text

Molecules data class PillSpec( val label: TextSpec, val onClick: (() -> Unit)?, val selected: Boolean = false, ) @Composable fun Pill( spec: PillSpec, modifier: Modifier = Modifier, )

Slide 30

Slide 30 text

Molecules data class PillSpec( val label: TextSpec, val onClick: (() -> Unit)?, val selected: Boolean = false, ) @Composable fun Pill( spec: PillSpec, modifier: Modifier = Modifier, ) @Composable fun BasePill( selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier = Modifier, … content: @Composable BoxScope.(contentColor: Color) -> Unit, )

Slide 31

Slide 31 text

Going Further import androidx.compose.material.Text @Composable fun Text( text: AnnotatedString, modifier: Modifier = Modifier, style: TextStyle = LocalTextStyle.current, … ) {

Slide 32

Slide 32 text

Going Further import com.instacart.compote.foundation.Text @Composable fun Text( text: RichTextSpec, modifier: Modifier = Modifier, style: TextStyle = TextStyleSpec.Default, … )

Slide 33

Slide 33 text

33

Slide 34

Slide 34 text

Thank you! François Blavoet