The Gallery app uses KSP and KotlinPoet to automatically generate navigation and example code. To add a new component page, follow these steps:
- Create a Screen file: Create
[YourComponent]Screen.kt in the package corresponding to the component group. - Annotate the Screen method: Create a
@Composable function named [YourComponent]Screen and annotate it with @Component(index = ..., description = "..."). - Implement
GalleryPage: Use the GalleryPage method within your screen. It requires componentPath (from FluentSourceFile) and galleryPath (from ComponentPagePath). - Define Sections: Inside
GalleryPage, use the Section method for each example.title: String title of the section.content: The @Composable code for the example.output: (Optional) A @Composable block to display state changes.options: (Optional) A @Composable block for user controls (e.g., CheckBoxes).sourceCode: The global variable generated by the @Sample annotation.
- Create the
@Sample method: Create a private @Composable method named [YourComponentCase]Sample and annotate it with @Sample. This generates the sourceCodeOf[YourComponentCase]Sample variable used in the Section.
Example implementation:
// ButtonScreen.kt
package io.github.composefluent.gallery.screen.basicinput
@Component(index = 0, description = "A control that responds to user input")
@Composable
fun ButtonScreen() {
GalleryPage(
componentPath = FluentSourceFile.Button,
galleryPath = ComponentPagePath.ButtonScreen,
) {
val clickTextContent = remember { mutableStateOf("") }
val buttonEnabled = remember { mutableStateOf(true) }
Section(
title = "A simple Button with text content.",
content = {
ButtonSample(enabled = buttonEnabled.value) {
clickTextContent.value = "You clicked: Button 1"
}
},
output = {
if (clickTextContent.value.isNotBlank()) {
Text(clickTextContent.value)
}
},
options = {
CheckBox(
checked = !buttonEnabled.value,
onCheckStateChange = { buttonEnabled.value = !it },
label = "Disable button"
)
},
sourceCode = sourceCodeOfButtonSample
)
}
}
@Sample
@Composable
private fun ButtonSample(enabled: Boolean = true, onClick: () -> Unit) {
Button(disabled = !enabled, onClick = onClick) {
Text("Standard Compose Button")
}
}
// ButtonScreen.kt
package io.github.composefluent.gallery.screen.basicinput
@Component(index = 0, description = "A control that responds to user input")
@Composable
fun ButtonScreen() {
GalleryPage(
componentPath = FluentSourceFile.Button,
galleryPath = ComponentPagePath.ButtonScreen,
) {
val clickTextContent = remember { mutableStateOf("") }
val buttonEnabled = remember { mutableStateOf(true) }
Section(
title = "A simple Button with text content.",
content = {
ButtonSample(enabled = buttonEnabled.value) {
clickTextContent.value = "You clicked: Button 1"
}
},
output = {
if (clickTextContent.value.isNotBlank()) {
Text(clickTextContent.value)
}
},
options = {
CheckBox(
checked = !buttonEnabled.value,
onCheckStateChange = { buttonEnabled.value = !it },
label = "Disable button"
)
},
sourceCode = sourceCodeOfButtonSample
)
}
}
@Sample
@Composable
private fun ButtonSample(enabled: Boolean = true, onClick: () -> Unit) {
Button(disabled = !enabled, onClick = onClick) {
Text("Standard Compose Button")
}
}