Jetpack Compose / CMP¶
- Create your
ComponentPropertyClasswith all the properties your component needs.
In this example, we’re using a checkbox component.
Immutable and Stable annotations
To avoid unnecessary recompositions in your component,
we recommend using the @Immutable and @Stable annotations in your properties.
1. Enable Kotlin Serialization¶
In your root build.gradle.kts, add the Kotlin serialization plugin (version 2.2.21 or higher):
id("org.jetbrains.kotlin.plugin.serialization") version "2.2.21"
In your module build.gradle.kts add
implementation(libs.kotlinx.serialization.json)
- Create your owner object that has the same field in your json like: (This class must match the structure of the JSON that will be parsed:)
@Stable
@Immutable
@Serializable
data class CheckBoxProperties(
@SerialName("text") val text: String? = null,
... define your properties here
)
Note
You can use your component object in dynamic.json inside the sample project app-sample-android or KMP-sample:
{
"key": "CraftDCheckBox",
"value": {
... define your properties here
}
}
- Create your Component
Your component must have three properties
- componentProperties: The mapped properties from json
- modifier: Default for composable componets
- behaviour: This make reference to the component’s behaviour, for example: onclick -> for buttons, onchange -> for checkbox etc…
class CraftDCheckBoxBuilder(
override val key: String = CraftDComponentKey.CHECK_BOX_COMPONENT.key
) :
CraftDBuilder {
@Composable
override fun craft(model: SimpleProperties, listener: CraftDViewListener) {
val checkBoxProperties = model.value.convertToVO<CheckBoxProperties>()
CraftDCheckBox(checkBoxProperties) {
checkBoxProperties.actionProperties?.let { listener.invoke(it) }
}
}
}
- Create your Component Builder:
Note
This Builder must extend CraftBuilder Class and override craft method.
class CraftDCheckBoxBuilder(
override val key: String = CraftDComponentKey.CHECK_BOX_COMPONENT.key
) :
CraftDBuilder {
@Composable
override fun craft(model: SimpleProperties, listener: CraftDViewListener) {
val checkBoxProperties = model.value.convertToVO<CheckBoxProperties>()
CraftDCheckBox(checkBoxProperties) {
checkBoxProperties.actionProperties?.let { listener.invoke(it) }
}
}
}
- In your screen you can add the builder inside of
CraftBuilderManager
@Composable
fun InitialScreen(
vm: SampleCraftDComposeViewModel
) {
val properties by vm.properties.collectAsStateWithLifecycle()
val dynamicBuilder = remember {
CraftDBuilderManager().add(
CraftDCheckBoxBuilder()
)
}
LaunchedEffect(Unit) {
vm.loadProperties()
}
CraftDynamic(
properties = properties,
dynamicBuilder = dynamicBuilder
) {
//Component click return to do something
}
}
So now enjoy your component!
CraftDImage — Built-in image component¶
CraftDImage is a built-in component for rendering remote images via Server Driven UI. It requires an injected imageLoader so the consuming app chooses the image library.
JSON payload¶
{
"key": "CraftDImage",
"value": {
"url": "https://example.com/photo.jpg",
"contentScale": "CROP",
"contentDescription": "A description for accessibility",
"actionProperties": {
"deeplink": "myapp://detail/1",
"analytics": {
"category": "image",
"action": "tap",
"label": "banner"
}
}
}
}
Supported contentScale values: CROP, FIT, FILL_BOUNDS, FILL_WIDTH, FILL_HEIGHT, INSIDE, NONE.
Registering the builder (with Coil)¶
CraftDImageBuilder is not pre-registered in CraftDBuilderManager because it requires an imageLoader lambda injected by the consumer.
// build.gradle.kts
implementation("io.coil-kt:coil-compose:2.6.0")
@Composable
fun InitialScreen(vm: SampleViewModel) {
val craftdBuilderManager = remember {
CraftDBuilderManager().add(
CraftDImageBuilder(
imageLoader = { url, contentDescription, modifier ->
AsyncImage(
model = url,
contentDescription = contentDescription,
modifier = modifier,
)
}
)
)
}
CraftDynamic(
properties = properties,
craftDBuilderManager = craftdBuilderManager,
) { action -> /* handle action */ }
}