androidx.compose.material3.a2ui.catalog

Interfaces

A2uiAudioPlayerRenderer

An abstraction of an asynchronous audio player which should be implemented using the application's media loading library (such as Media3/ExoPlayer), used for rendering audio playback controls for A2uiBasicCatalogV1.AudioPlayer.

A2uiImageRenderer

An abstraction of an asynchronous image loader which should be implemented using the application's image loading library (such as Coil or Glide), used for rendering an image for A2uiBasicCatalogV1.Image.

A2uiVideoRenderer

An abstraction of an asynchronous video player which should be implemented using the application's media loading library (such as Media3/ExoPlayer), used for rendering video playback for A2uiBasicCatalogV1.Video.

Objects

MaterialA2uiBasicCatalogV1Defaults

Default component implementations for materialA2uiBasicCatalogV1.

Top-level functions summary

A2uiCatalog
materialA2uiBasicCatalogV1(
    image: A2uiBasicCatalogV1.Image,
    video: A2uiBasicCatalogV1.Video,
    audioPlayer: A2uiBasicCatalogV1.AudioPlayer,
    functions: A2uiBasicCatalogV1.Functions,
    text: A2uiBasicCatalogV1.Text,
    icon: A2uiBasicCatalogV1.Icon,
    row: A2uiBasicCatalogV1.Row,
    column: A2uiBasicCatalogV1.Column,
    list: A2uiBasicCatalogV1.List,
    card: A2uiBasicCatalogV1.Card,
    tabs: A2uiBasicCatalogV1.Tabs,
    modal: A2uiBasicCatalogV1.Modal,
    divider: A2uiBasicCatalogV1.Divider,
    button: A2uiBasicCatalogV1.Button,
    textField: A2uiBasicCatalogV1.TextField,
    checkBox: A2uiBasicCatalogV1.CheckBox,
    choicePicker: A2uiBasicCatalogV1.ChoicePicker,
    slider: A2uiBasicCatalogV1.Slider,
    dateTimeInput: A2uiBasicCatalogV1.DateTimeInput
)

Creates an A2uiCatalog for the A2UI Basic Catalog V1 using Material Design 3.

Top-level functions

materialA2uiBasicCatalogV1

fun materialA2uiBasicCatalogV1(
    image: A2uiBasicCatalogV1.Image,
    video: A2uiBasicCatalogV1.Video,
    audioPlayer: A2uiBasicCatalogV1.AudioPlayer,
    functions: A2uiBasicCatalogV1.Functions,
    text: A2uiBasicCatalogV1.Text = MaterialA2uiBasicCatalogV1Defaults.text,
    icon: A2uiBasicCatalogV1.Icon = MaterialA2uiBasicCatalogV1Defaults.icon,
    row: A2uiBasicCatalogV1.Row = MaterialA2uiBasicCatalogV1Defaults.row,
    column: A2uiBasicCatalogV1.Column = MaterialA2uiBasicCatalogV1Defaults.column,
    list: A2uiBasicCatalogV1.List = MaterialA2uiBasicCatalogV1Defaults.list,
    card: A2uiBasicCatalogV1.Card = MaterialA2uiBasicCatalogV1Defaults.card,
    tabs: A2uiBasicCatalogV1.Tabs = MaterialA2uiBasicCatalogV1Defaults.tabs,
    modal: A2uiBasicCatalogV1.Modal = MaterialA2uiBasicCatalogV1Defaults.modal,
    divider: A2uiBasicCatalogV1.Divider = MaterialA2uiBasicCatalogV1Defaults.divider,
    button: A2uiBasicCatalogV1.Button = MaterialA2uiBasicCatalogV1Defaults.button,
    textField: A2uiBasicCatalogV1.TextField = MaterialA2uiBasicCatalogV1Defaults.textField,
    checkBox: A2uiBasicCatalogV1.CheckBox = MaterialA2uiBasicCatalogV1Defaults.checkBox,
    choicePicker: A2uiBasicCatalogV1.ChoicePicker = MaterialA2uiBasicCatalogV1Defaults.choicePicker,
    slider: A2uiBasicCatalogV1.Slider = MaterialA2uiBasicCatalogV1Defaults.slider,
    dateTimeInput: A2uiBasicCatalogV1.DateTimeInput = MaterialA2uiBasicCatalogV1Defaults.dateTimeInput
): A2uiCatalog

Creates an A2uiCatalog for the A2UI Basic Catalog V1 using Material Design 3.

Provides default Material 3 implementations for all components in the A2UI Basic Catalog V1 specification, while allowing individual component implementations to be overridden.

To customize how URLs are opened:

import androidx.a2ui.compose.ui.A2uiMessageProcessor
import androidx.a2ui.compose.ui.catalog.A2uiBasicCatalogV1
import androidx.a2ui.model.protocol.A2uiComponentPayload
import androidx.a2ui.model.protocol.A2uiCreateSurfaceMessage
import androidx.a2ui.model.protocol.A2uiException
import androidx.a2ui.model.protocol.A2uiExecutionContext
import androidx.a2ui.model.protocol.A2uiUpdateComponentsMessage
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.a2ui.A2uiSurface
import androidx.compose.material3.a2ui.catalog.MaterialA2uiBasicCatalogV1Defaults
import androidx.compose.material3.a2ui.catalog.materialA2uiBasicCatalogV1
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext

val context = LocalContext.current
val catalog =
    remember(context) {
        materialA2uiBasicCatalogV1(
            image = MaterialA2uiBasicCatalogV1Defaults.image { _, _, _, _, _ -> },
            video = MaterialA2uiBasicCatalogV1Defaults.video { _, _, _ -> },
            audioPlayer = MaterialA2uiBasicCatalogV1Defaults.audioPlayer { _, _, _, _ -> },
            functions =
                object : A2uiBasicCatalogV1.Functions {
                    // Only opens HTTPS URLs. Throwing reports the error to the agent. All
                    // other functions use their default implementations.
                    override fun openUrl(url: String, executionContext: A2uiExecutionContext) {
                        if (!url.startsWith("https://", ignoreCase = true)) {
                            throw A2uiException.A2uiRuntimeException(
                                "Only HTTPS URLs are allowed"
                            )
                        }
                        context.startActivity(
                            Intent(Intent.ACTION_VIEW, Uri.parse(url))
                                .addCategory(Intent.CATEGORY_BROWSABLE)
                        )
                    }
                },
        )
    }
// Note: The message processor should typically be hosted in a ViewModel.
val processor = remember(catalog) { A2uiMessageProcessor(catalogs = listOf(catalog)) }

LaunchedEffect(processor) {
    // Note: Message collection should typically be run on a background thread.
    launch(Dispatchers.Default) { processor.collectMessages() }

    val surfaceId = "surface_1"
    // Simulate payloads received from an agent to create a button that opens a URL
    processor.processMessage(A2uiCreateSurfaceMessage(surfaceId, catalog.id))
    processor.processMessage(
        A2uiUpdateComponentsMessage(
            surfaceId,
            listOf(
                A2uiComponentPayload(
                    id = "root",
                    type = "Button",
                    properties =
                        mapOf(
                            "child" to "label",
                            "action" to
                                mapOf(
                                    "functionCall" to
                                        mapOf(
                                            "call" to "openUrl",
                                            "args" to
                                                mapOf("url" to "https://developer.android.com"),
                                        )
                                ),
                        ),
                ),
                A2uiComponentPayload(
                    id = "label",
                    type = "Text",
                    properties = mapOf("text" to "Open developer.android.com"),
                ),
            ),
        )
    )
}

val surfaces by processor.activeSurfaces.collectAsState()
// Note: The UI is typically expected to render all active surfaces (e.g., in a list).
val surfaceModel = surfaces.firstOrNull()

if (surfaceModel != null) {
    A2uiSurface(surfaceModel = surfaceModel, modifier = Modifier.fillMaxSize())
}

To wrap the default implementation of a function while keeping the default implementations of all other functions, including openUrl:

import androidx.a2ui.compose.ui.A2uiMessageProcessor
import androidx.a2ui.compose.ui.catalog.A2uiBasicCatalogV1
import androidx.a2ui.model.protocol.A2uiComponentPayload
import androidx.a2ui.model.protocol.A2uiCreateSurfaceMessage
import androidx.a2ui.model.protocol.A2uiExecutionContext
import androidx.a2ui.model.protocol.A2uiUpdateComponentsMessage
import androidx.a2ui.model.protocol.A2uiUpdateDataModelMessage
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.a2ui.A2uiSurface
import androidx.compose.material3.a2ui.catalog.MaterialA2uiBasicCatalogV1Defaults
import androidx.compose.material3.a2ui.catalog.materialA2uiBasicCatalogV1
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext

val context = LocalContext.current
val catalog =
    remember(context) {
        materialA2uiBasicCatalogV1(
            image = MaterialA2uiBasicCatalogV1Defaults.image { _, _, _, _, _ -> },
            video = MaterialA2uiBasicCatalogV1Defaults.video { _, _, _ -> },
            audioPlayer = MaterialA2uiBasicCatalogV1Defaults.audioPlayer { _, _, _, _ -> },
            // Delegates to the default implementations of all functions, including openUrl,
            // and only overrides email.
            functions =
                object : A2uiBasicCatalogV1.Functions by A2uiBasicCatalogV1.Functions(context) {
                    // Only accepts example.com addresses, and calls the default implementation
                    // to check that the value is a valid email address.
                    override fun email(
                        value: String,
                        executionContext: A2uiExecutionContext,
                    ): Boolean =
                        value.endsWith("@example.com", ignoreCase = true) &&
                            super.email(value, executionContext)
                },
        )
    }
// Note: The message processor should typically be hosted in a ViewModel.
val processor = remember(catalog) { A2uiMessageProcessor(catalogs = listOf(catalog)) }

LaunchedEffect(processor) {
    // Note: Message collection should typically be run on a background thread.
    launch(Dispatchers.Default) { processor.collectMessages() }

    val surfaceId = "surface_1"
    // Simulate payloads received from an agent to create an email field with an email check
    processor.processMessage(A2uiCreateSurfaceMessage(surfaceId, catalog.id))
    processor.processMessage(
        A2uiUpdateDataModelMessage(surfaceId, path = "/email", value = "user@example.org")
    )
    processor.processMessage(
        A2uiUpdateComponentsMessage(
            surfaceId,
            listOf(
                A2uiComponentPayload(
                    id = "root",
                    type = "TextField",
                    properties =
                        mapOf(
                            "label" to "Work email",
                            "value" to mapOf("path" to "/email"),
                            "checks" to
                                listOf(
                                    mapOf(
                                        "condition" to
                                            mapOf(
                                                "call" to "email",
                                                "args" to
                                                    mapOf("value" to mapOf("path" to "/email")),
                                            ),
                                        "message" to "Enter an example.com email address",
                                    )
                                ),
                        ),
                )
            ),
        )
    )
}

val surfaces by processor.activeSurfaces.collectAsState()
// Note: The UI is typically expected to render all active surfaces (e.g., in a list).
val surfaceModel = surfaces.firstOrNull()

if (surfaceModel != null) {
    A2uiSurface(surfaceModel = surfaceModel, modifier = Modifier.fillMaxSize())
}
Parameters
image: A2uiBasicCatalogV1.Image

A2uiBasicCatalogV1.Image component implementation. Use MaterialA2uiBasicCatalogV1Defaults.image to create a default Material 3 implementation with an A2uiImageRenderer

video: A2uiBasicCatalogV1.Video

A2uiBasicCatalogV1.Video component implementation. Use MaterialA2uiBasicCatalogV1Defaults.video to create a default Material 3 implementation with an A2uiVideoRenderer

audioPlayer: A2uiBasicCatalogV1.AudioPlayer

A2uiBasicCatalogV1.AudioPlayer component implementation. Use MaterialA2uiBasicCatalogV1Defaults.audioPlayer to create a default Material 3 implementation with an A2uiAudioPlayerRenderer

functions: A2uiBasicCatalogV1.Functions

A2uiBasicCatalogV1.Functions implementation. Use the A2uiBasicCatalogV1.Functions(context) factory function to create the default implementations of all functions, and override methods of A2uiBasicCatalogV1.Functions to customize individual functions

text: A2uiBasicCatalogV1.Text = MaterialA2uiBasicCatalogV1Defaults.text

A2uiBasicCatalogV1.Text component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.text

icon: A2uiBasicCatalogV1.Icon = MaterialA2uiBasicCatalogV1Defaults.icon

A2uiBasicCatalogV1.Icon component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.icon

row: A2uiBasicCatalogV1.Row = MaterialA2uiBasicCatalogV1Defaults.row

A2uiBasicCatalogV1.Row component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.row

column: A2uiBasicCatalogV1.Column = MaterialA2uiBasicCatalogV1Defaults.column

A2uiBasicCatalogV1.Column component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.column

list: A2uiBasicCatalogV1.List = MaterialA2uiBasicCatalogV1Defaults.list

A2uiBasicCatalogV1.List component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.list

card: A2uiBasicCatalogV1.Card = MaterialA2uiBasicCatalogV1Defaults.card

A2uiBasicCatalogV1.Card component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.card

tabs: A2uiBasicCatalogV1.Tabs = MaterialA2uiBasicCatalogV1Defaults.tabs

A2uiBasicCatalogV1.Tabs component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.tabs

modal: A2uiBasicCatalogV1.Modal = MaterialA2uiBasicCatalogV1Defaults.modal

A2uiBasicCatalogV1.Modal component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.modal

divider: A2uiBasicCatalogV1.Divider = MaterialA2uiBasicCatalogV1Defaults.divider

A2uiBasicCatalogV1.Divider component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.divider

button: A2uiBasicCatalogV1.Button = MaterialA2uiBasicCatalogV1Defaults.button

A2uiBasicCatalogV1.Button component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.button

textField: A2uiBasicCatalogV1.TextField = MaterialA2uiBasicCatalogV1Defaults.textField

A2uiBasicCatalogV1.TextField component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.textField

checkBox: A2uiBasicCatalogV1.CheckBox = MaterialA2uiBasicCatalogV1Defaults.checkBox

A2uiBasicCatalogV1.CheckBox component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.checkBox

choicePicker: A2uiBasicCatalogV1.ChoicePicker = MaterialA2uiBasicCatalogV1Defaults.choicePicker

A2uiBasicCatalogV1.ChoicePicker component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.choicePicker

slider: A2uiBasicCatalogV1.Slider = MaterialA2uiBasicCatalogV1Defaults.slider

A2uiBasicCatalogV1.Slider component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.slider

dateTimeInput: A2uiBasicCatalogV1.DateTimeInput = MaterialA2uiBasicCatalogV1Defaults.dateTimeInput

A2uiBasicCatalogV1.DateTimeInput component implementation, defaults to MaterialA2uiBasicCatalogV1Defaults.dateTimeInput

Returns
A2uiCatalog

an A2uiCatalog configured with Material 3 basic components and functions