XR — canonical composables
Material 3 XR canonical composables: Orbiter, SpatialPanel, SpaceToggleButton, UserSubspace, SpatialRow/Column/Box, AlertDialog spatialized. Strict extension to specs/develop/xr-preview.kmd (which retains status `preview`). Defines Koder naming + auto- spatialize defaults (TopAppBar, NavigationRail).
Spec — XR canonical composables
Strict extension to
xr-preview.kmd(R1-R4). Adds R5R10 with canonical composables list + autospatialize + percomponent XR subtab contract.
R5 — Canonical composables
Material 3 XR ships composables that have *oder-equivalent naming*
| Material 3 XR composable | Koder equivalent | Purpose |
|---|---|---|
Orbiter |
KoderOrbiter |
Floating UI element orbiting the user (always visible) |
SpatialPanel |
KoderSpatialPanel |
3D-anchored panel for content |
SpaceToggleButton |
KoderSpaceToggleButton |
Toggle entering/leaving XR space mode |
EnableXrComponentOverrides |
KoderXrOverrides |
Wrapper enabling auto-spatialize defaults |
UserSubspace |
KoderUserSubspace |
Personal space of the user (default scope) |
SpatialRow |
KoderSpatialRow |
3D row layout |
SpatialColumn |
KoderSpatialColumn |
3D column layout |
SpatialBox |
KoderSpatialBox |
3D positional container |
LayoutSpacer |
KoderLayoutSpacer |
Spacer in spatial layouts |
AlertDialog spatialized |
KoderAlertDialog w/ XR mode |
Auto-spatializes in Subspace context |
Koder prefix: ALL XR composables use Koder* prefix; underlying Jetpack XR APIs called internally per platform.
R6 — Auto-spatialize defaults
When wrapped in KoderUserSubspace (or equivalent Subspace context):
| Component | Auto-spatialize behavior |
|---|---|
| TopAppBar | Becomes Orbiter anchored to top of user view |
| NavigationRail | Becomes Orbiter anchored to left/right of user view |
| BottomAppBar / DockedToolbar | Becomes Orbiter anchored to bottom of user view |
| AlertDialog | Renders in panel anchored center-front |
| ModalBottomSheet | Renders as 3D panel sliding from bottom |
| FAB | Becomes orbiter floating to user's right (LTR) |
Component code unchanged — same widget API. Subspace context activates XR rendering automatically.
Opt-out: KoderXrOverrides(enableAutoSpatialize: false) keeps components flat.
R7 — Input handling
| Input mode | Behavior |
|---|---|
| *ye + pinch*(primary XR input) | Standard tap equivalent; gaze tracks hover |
| *and tracking* | Touch gestures supported (swipe, drag, multi-touch) |
| *oice* | Voice commands per voice/wake-word.kmd + voice-mode.kmd; XR-specific commands ("go back", "select") |
| *eyboard + mouse*(devtime) | Standard 2D interaction; spatial features dormant |
| *patial controller*(Quest, etc.) | Per-device adapter |
Click semantics preserved across all modes: a KoderButton clicked via gaze+pinch fires same callback as 2D tap.
R8 — Percomponent XR subtab contract
When a component is declared XRaware (gen renders an additional subxr.enabled: true in spec frontmatter), designtab gen#012`)./components/<slug>/xr (per `tools/design
XR sub-tab content per spec:
| Section | Content |
|---|---|
| *omposables* | KoderOrbiter / KoderSpatialPanel / etc. that this component uses or becomes |
| *uto-spatialize* | Whether KoderUserSubspace auto-spatializes this (true/false) |
| *otes* | Component-specific XR considerations (e.g., depth, anchoring, gaze focus order) |
Frontmatter declaration example:
---
name: AlertDialog
xr:
enabled: true
composables: [KoderAlertDialog]
auto_spatialize: true
notes: "Anchored center-front in user subspace; eye+pinch on actions"
---R9 — Performance budget
XR mandatory: *0fps*(16.6ms per frame). Higher tiers preferred where supported:
| Tier | Target |
|---|---|
| Tier 1 (Vision Pro) | 90fps (11.1ms) |
| Tier 2 (Quest, AndroidXR) | 90fps when supported; 72fps fallback (13.8ms) |
| Tier 3 (WebXR) | 60fps minimum |
Degradation strategy on missed frames:
- Reduce spatial panel render quality (LOD).
- Drop secondary orbiters (keep only primary nav).
- Disable shape morph animations.
- Last resort: drop to 30fps with timewarp (Vision Pro / Quest only).
R10 — Tier coverage matrix
Per surface (component / scaffold / app), declare which XR tiers supported:
| Tier | Devices | XR API surface |
|---|---|---|
| *ier 1 (premium)* | Apple Vision Pro | ARKit + RealityKit; passthrough |
| *ier 2 (consumer)* | Meta Quest 3+, AndroidXR (Samsung XR headset, etc.) | Jetpack XR SDK + OpenXR; passthrough on capable hardware |
| *ier 3 (web)* | WebXR-capable browsers (Chrome, Edge, Safari on Vision Pro) | WebXR Device API |
| *xcluded* | Mobile AR (Pixel/Vision-Lite); 2D fallback rendering only | n/a |
Koder Stack first ships Tier 2 (AndroidXR via Jetpack XR SDK) + Tier 1 (Vision Pro via SwiftUI bindings). Tier 3 WebXR is opt-in per product.
Cross-link
- Base:
xr-preview.kmdR1-R4 - Per
component XR subtab:tools/design-gen#012(#012 intools/design-gen/backlog/pending/) - Compose Android:
android-compose.kmd(XR builds on Compose) - Voice integration:
../voice/wake-word.kmd - Refs: M3 XR developer preview; AndroidXR SDK; Apple Vision Pro RealityKit