Spatial panels

Applicable XR devices
This guidance helps you build experiences for these types of XR devices.
XR Headsets
Wired XR Glasses

A SpatialPanel is a subspace composable that lets you display your app's content–for example, you could display video playback, still images, or any other content in a spatial panel.

Figure 1.: Example of a spatial UI panel.

You can use SubspaceModifier to change the size, behavior, and positioning of the spatial panel

Create a spatial panel

The following example shows how to create a spatial panel.

Subspace {
    SpatialPanel(
        SubspaceModifier
            .height(824.dp)
            .width(1400.dp)
            .movable()
            .resizable(),
    ) {
        SpatialPanelContent()
    }
}

@Composable
fun SpatialPanelContent() {
    Box(
        Modifier
            .background(color = Color.Black)
            .height(500.dp)
            .width(500.dp),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "Spatial Panel",
            color = Color.White,
            fontSize = 25.sp
        )
    }
}

Key points about the code

  • Because SpatialPanel APIs are subspace composables, you must call them inside Subspace. Calling them outside of a subspace throws an exception.
  • The size of the SpatialPanel has been set using the height and width specifications on the SubspaceModifier. Omitting these specifications lets the size of the panel be determined by the measurements of its contents.
  • Allow the user to move a panel by adding a movable subspace modifier.
  • Allow the user to resize a panel by adding a resizable subspace modifier.
  • See our spatial panel design guidance for details on sizing and positioning. See our reference documentation for more specifics on code implementation.

How the movable modifier works

As a user moves a panel away from them, by default, the movable modifier scales the panel in a similar way to how panels are resized by the system in home space. All children content inherit this behavior. To disable this, set the shouldScaleWithDistance parameter to false.

Add multiple spatial panels to a spatial layout

You can create multiple spatial panels and place them within a spatial layout using SpatialRow, SpatialColumn, SpatialBox, and SpatialSpacer.

Figure 2.: Example of multiple spatial panels in a spatial layout.

The following code example shows how to do this.

Subspace {
    SpatialRow {
        SpatialColumn {
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Top Left")
            }
            SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
                SpatialPanelContent("Middle Left")
            }
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Bottom Left")
            }
        }
        SpatialColumn {
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Top Right")
            }
            SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
                SpatialPanelContent("Middle Right")
            }
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Bottom Right")
            }
        }
    }
}

@Composable
fun SpatialPanelContent(text: String) {
    Column(
        Modifier
            .background(color = Color.Black)
            .fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "Panel",
            color = Color.White,
            fontSize = 15.sp
        )
        Text(
            text = text,
            color = Color.White,
            fontSize = 25.sp,
            fontWeight = FontWeight.Bold
        )
    }
}

Key points about the code

Create custom panels and layouts

To create custom panels that are not supported by Compose for XR, you can work directly with PanelEntity instances and the scene graph using the SceneCore APIs.