XR — canonical composables
develop specs/develop/xr-composables.kmd
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).
Quando esta spec se aplica
Triggers primários
- Add XR support to a Koder app
Todos os triggers
- Build XR-aware surface in any Koder product
- Implement Compose XR Subspace within an existing Koder app
- Define XR variant of an existing component
Corpo da especificação
Spec — XR canonical composables
Strict extension to
xr-preview.kmd(R1-R4). Adds R5-R10 with canonical composables list + auto-spatialize + per-component XR sub-tab contract.
R5 — Canonical composables
Material 3 XR ships composables that have Koder-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 |
|---|---|
| Eye + pinch (primary XR input) | Standard tap equivalent; gaze tracks hover |
| Hand tracking | Touch gestures supported (swipe, drag, multi-touch) |
| Voice | Voice commands per voice/wake-word.kmd + voice-mode.kmd; XR-specific commands ("go back", "select") |
| Keyboard + mouse (devtime) | Standard 2D interaction; spatial features dormant |
| Spatial 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 — Per-component XR sub-tab contract
When a component is declared XR-aware (xr.enabled: true in spec frontmatter), design-gen renders an additional sub-tab /components/<slug>/xr (per tools/design-gen#012).
XR sub-tab content per spec:
| Section | Content |
|---|---|
| Composables | KoderOrbiter / KoderSpatialPanel / etc. that this component uses or becomes |
| Auto-spatialize | Whether KoderUserSubspace auto-spatializes this (true/false) |
| Notes | 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: 60fps (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 |
|---|---|---|
| Tier 1 (premium) | Apple Vision Pro | ARKit + RealityKit; passthrough |
| Tier 2 (consumer) | Meta Quest 3+, AndroidXR (Samsung XR headset, etc.) | Jetpack XR SDK + OpenXR; passthrough on capable hardware |
| Tier 3 (web) | WebXR-capable browsers (Chrome, Edge, Safari on Vision Pro) | WebXR Device API |
| Excluded | 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 sub-tab:
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
Referências
specs/develop/xr-preview.kmdspecs/develop/android-compose.kmdspecs/components/app-bars.kmdspecs/components/navigation.kmdspecs/components/dialogs.kmd