airbnb / Showkase

🔦 Showkase is an annotation-processor based Android library that helps you organize, discover, search and visualize Jetpack Compose UI elements
https://medium.com/airbnb-engineering/introducing-showkase-a-library-to-organize-discover-and-visualize-your-jetpack-compose-elements-d5c34ef01095
Apache License 2.0
2.11k stars 107 forks source link

Add support for Custom Preview Annotations #263

Closed oas004 closed 1 year ago

oas004 commented 2 years ago

Add support for CustomMultiPreviewAnnotations in Showkase.

This is the third PR in a series to add support for Custom MultiPreview Annotations. Referencing as a followup on #259 and #255.

By completing this should solve #233

What do I mean by Custom MultiPreview Annotations?

This is an annotation in the form

@Preview(name = "Custom Preview One First", group = "Custom Previews")
@Preview(name = "Custom Preview One Second", group = "Custom Previews")
annotation class CustomPreview

this can be used to annotate a composable function like you would do any other preview function in Compose like this:

@CustomPreview
@Composable
fun CustomAnnotationPreview() {
}

This can also be combined like this:

@Preview(name = "Custom Preview One First", group = "Custom Previews")
@Preview(name = "Custom Preview One Second", group = "Custom Previews")
annotation class CustomPreviewOne

@Preview(name = "Custom Preview Two First", group = "Custom Previews")
@Preview(name = "Custom Preview Two Second", group = "Custom Previews")
annotation class CustomPreviewTwo

@CustomPreviewOne
@CustomPreviewTwo
@Composable
fun CustomAnnotationPreviewCombined() {
}

They should be able to have the custom annotations and the use of them in different modules in a project.

For more information, please see docs on tooling in compose here

Goal

The goal is to add support for this in Showkase. We would like showkase to act like the tooling in Android Studio does. That means that when Android Studio Preview would have generated a Preview, showkase should also generate a ShowkaseMetadata function.

Testing

Sample App

In the sample app I have introduced Shapes. This is to showkase different shapes in Showkase.

Here I have made two internal (in same module) and one external (in submodule) annotations

Internals:

@Preview(name = "Square 200 by 200", group = "Shape", widthDp = 200, heightDp = 200)
@Preview(name = "Square 400 by 400", group = "Shape", widthDp = 400, heightDp = 400)
annotation class ShapePreview

@Preview(
    name = "Phone 200 by 200",
    group = "Shape",
    widthDp = 200,
    heightDp = 200,
    device = Devices.PHONE
)
@Preview(
    name = "Tablet 400 by 400",
    group = "Shape",
    widthDp = 400,
    heightDp = 400,
    device = Devices.TABLET
)
annotation class DevicePreview

Eksternal

@Preview(name = "Circle 150 by 150", group = "Shape", widthDp = 150, heightDp = 150)
@Preview(name = "Circle 200 by 200", group = "Shape", widthDp = 200, heightDp = 200)
annotation class CircleShapePreview

This is annotating different Composables in the shapes domain. Here is an overview of the Composables that are annotated.

ElementName Comined Scope
CirclePreview No External
RoundRectanglePreview Yes Both
SquarePreview No Internal

The RoundRectanglePreview here is also annotated with a singular Preview annotation to check that the combination works. Since It is annotated with two annotations that has two preview annotations this should generate 2 + 2 + 1 previews in Showkase.

Please check out the app with the useKsp=trueand click on the shapes tab to see the samples.

Browser Test

For the UI tests I have currently made two custom annotations. One internal (same module) and one external(submodule)

Internal

@Preview(
    name = "Custom Text Light",
    group = "Button",
    uiMode = Configuration.UI_MODE_NIGHT_NO,
)
@Preview(
    name = "Custom Text Dark",
    group = "Button",
    uiMode = Configuration.UI_MODE_NIGHT_YES,
)
annotation class CustomButtonPreview

External


@Preview(name = "CustomPreview one", group = "CustomExternalPreview")
@Preview(name = "CustomPreview two", group = "CustomExternalPreview")
annotation class CustomPreviewAnnotation

These are annotating different Composables. Here I have tried to combine them as well with each other and with singular ones.

Added tests for the different cases and checked that they are generating individual Composables in their respective group. This should be the same as what is generated in the Sample application just with different names.

Processor Test

In the processor tests, I have made tests that make sure all the correct metadata objects are created and that we are creating the files to store the custom annotations that the processor has registered. You can check these tests in showcase-processor-testing module.

What is left

This is very much still a work in progress. I have tried to list up what I have left under to get an overview.

- [ ] Add docs about how to support your custom preview annotations. - This should be done in a different PR that can be merged just before release so that it does not cause confusion.

polivmi1 commented 1 year ago

Is this still planned in near future? Is any help needed?

oas004 commented 1 year ago

Is this still planned in near future? Is any help needed?

With this PR it should work for KSP. We had to do some changes for KAPT. I think I will have to make another PR because there is to much conflicts and we have to change the approach a bit after some of the changes that has been merged. I have not gotten around to it quite yet because of other things. If you want to help and check this out, you are more than welcome to :)

anhanh11001 commented 1 year ago

Hi @oas004 , thanks for the work!

My team’s work is dependent on this custom preview annotation in order to support Paparazzi screenshot testing. Can I ask if there are estimated timeline on having this released (only KSP is already great to us)?

I’d love to help if I can do anything but I’m really new to annotation processing programming so maybe guides are needed

oas004 commented 1 year ago

Hi @oas004 , thanks for the work!

My team’s work is dependent on this custom preview annotation in order to support Paparazzi screenshot testing. Can I ask if there are estimated timeline on having this released (only KSP is already great to us)?

I’d love to help if I can do anything but I’m really new to annotation processing programming so maybe guides are needed

Hey @anhanh11001. Sorry for blocking you. Had a bit to much on my plate at work, so this has been a bit down prioritised. I will try my best to get some work in on this this week. Since we have released #255, it should at least not throw at compile time, it will just be bypassed from Showkase point of view.

I think the stuff in this PR should be enough for it to work with KSP at least. It has to be changed along with this #284

oas004 commented 1 year ago

Closing this in favour of #303