AR Components
ARView
The base AR scene container. Renders a live camera feed with an AR overlay. All other AR components can be composed inside an ARView.
| Prop | Type | Default | Description |
|---|---|---|---|
renderAR? | RenderARFn | — | Renderer from createViroARView() |
showInstructions | boolean | true | Show a surface-detection instruction banner |
instructionText | string | 'Move your phone to detect surfaces' | Custom instruction text |
showReticle | boolean | false | Show a reticle at the centre of the view |
onReady? | () => void | — | Called when AR initialisation completes |
accessibilityLabel? | string | 'AR View' | Accessibility label |
testID? | string | — | Test identifier |
import { ARView } from '@objectifthunes/limestone-sdk';
import { createViroARView } from '@objectifthunes/limestone-sdk/viro';
<ARView
renderAR={createViroARView()}
showInstructions
showReticle
onReady={() => console.log('AR ready')}
/>
ARTryOn
Overlays a virtual product on the user’s face, head, wrist, or hand for virtual try-on experiences.
| Prop | Type | Default | Description |
|---|---|---|---|
renderTryOn? | RenderTryOnFn | — | Renderer from createViroARTryOn() |
modelUri | string | — | URI of the GLTF/GLB model to overlay |
target | 'face' | 'head' | 'wrist' | 'hand' | 'face' | Body target for the overlay |
showGuide | boolean | true | Show a positioning guide overlay |
guideText | string | — | Custom guide instruction text |
onTracking? | (isTracking: boolean) => void | — | Called when tracking state changes |
accessibilityLabel? | string | 'AR Try-On' | Accessibility label |
testID? | string | — | Test identifier |
import { ARTryOn } from '@objectifthunes/limestone-sdk';
import { createViroARTryOn } from '@objectifthunes/limestone-sdk/viro';
<ARTryOn
renderTryOn={createViroARTryOn()}
modelUri="https://example.com/sunglasses.glb"
target="face"
showGuide
/>
ARPlacement
Lets the user detect a flat surface and place a 3D model on it with a tap.
| Prop | Type | Default | Description |
|---|---|---|---|
renderPlacement? | RenderPlacementFn | — | Renderer from createViroARPlacement() |
modelUri | string | — | URI of the model to place |
showSurfaceIndicator | boolean | true | Show a surface-detection grid |
confirmPlacement | boolean | false | Require a confirmation tap before finalising |
onPlaced? | (position: ARPosition) => void | — | Called with world coordinates when the model is placed |
accessibilityLabel? | string | 'AR Placement' | Accessibility label |
testID? | string | — | Test identifier |
import { ARPlacement } from '@objectifthunes/limestone-sdk';
import { createViroARPlacement } from '@objectifthunes/limestone-sdk/viro';
<ARPlacement
renderPlacement={createViroARPlacement()}
modelUri="https://example.com/sofa.glb"
showSurfaceIndicator
confirmPlacement
onPlaced={(pos) => console.log('Placed at', pos)}
/>
ARMeasure
Point-and-tap measurement tool that calculates real-world distances between two points.
| Prop | Type | Default | Description |
|---|---|---|---|
renderMeasure? | RenderMeasureFn | — | Renderer from createViroARMeasure() |
unit | 'cm' | 'm' | 'in' | 'ft' | 'cm' | Unit for displayed measurements |
onMeasurement? | (value: number, unit: string) => void | — | Called each time a measurement is computed |
accessibilityLabel? | string | 'AR Measure' | Accessibility label |
testID? | string | — | Test identifier |
import { ARMeasure } from '@objectifthunes/limestone-sdk';
import { createViroARMeasure } from '@objectifthunes/limestone-sdk/viro';
<ARMeasure
renderMeasure={createViroARMeasure()}
unit="cm"
onMeasurement={(value, unit) => console.log(`${value} ${unit}`)}
/>
ARAnnotation
Attaches floating text labels to real-world surfaces or objects detected in the scene.
| Prop | Type | Default | Description |
|---|---|---|---|
renderAnnotation? | RenderAnnotationFn | — | Renderer from createViroARAnnotation() |
annotations | ARAnnotationItem[] | [] | Each item: { id, position, label, description? } |
onAnnotationPress? | (annotation: ARAnnotationItem) => void | — | Called when the user taps an annotation |
showLabels | boolean | true | Toggle label visibility |
accessibilityLabel? | string | 'AR Annotations' | Accessibility label |
testID? | string | — | Test identifier |
import { ARAnnotation } from '@objectifthunes/limestone-sdk';
import { createViroARAnnotation } from '@objectifthunes/limestone-sdk/viro';
<ARAnnotation
renderAnnotation={createViroARAnnotation()}
annotations={[
{ id: 'pipe', position: [0.5, 1.2, -1.0], label: 'Water pipe', description: 'Main supply line' },
]}
showLabels
onAnnotationPress={(a) => console.log('Tapped', a.label)}
/>
ARWorldObject
Anchors one or more 3D objects to GPS coordinates in the real world, visible through the camera.
| Prop | Type | Default | Description |
|---|---|---|---|
renderWorld? | RenderWorldFn | — | Renderer from createViroARWorldObject() |
objects | ARWorldItem[] | [] | Each item: { id, coordinate, modelUri, label? } |
maxDistance | number | 500 | Maximum distance in metres to render objects |
showDistanceLabels | boolean | false | Show metres-away labels below each object |
accessibilityLabel? | string | 'AR World Objects' | Accessibility label |
testID? | string | — | Test identifier |
import { ARWorldObject } from '@objectifthunes/limestone-sdk';
import { createViroARWorldObject } from '@objectifthunes/limestone-sdk/viro';
<ARWorldObject
renderWorld={createViroARWorldObject()}
objects={[
{ id: 'shop', coordinate: { latitude: 48.8566, longitude: 2.3522 }, modelUri: 'https://example.com/pin.glb', label: 'Coffee shop' },
]}
maxDistance={200}
showDistanceLabels
/>
ARNavigation
Turn-by-turn AR navigation overlay with floating waypoints and directional arrows.
| Prop | Type | Default | Description |
|---|---|---|---|
renderNavigation? | RenderNavigationFn | — | Renderer from createViroARNavigation() |
waypoints | ARWaypoint[] | [] | Each waypoint: { id, coordinate, label? } |
distanceRemaining | number | 0 | Distance remaining in metres |
etaSeconds | number | 0 | Estimated seconds to destination |
arrived | boolean | false | Show an arrival overlay when true |
accessibilityLabel? | string | 'AR Navigation' | Accessibility label |
testID? | string | — | Test identifier |
import { ARNavigation } from '@objectifthunes/limestone-sdk';
import { createViroARNavigation } from '@objectifthunes/limestone-sdk/viro';
<ARNavigation
renderNavigation={createViroARNavigation()}
waypoints={[
{ id: 'turn1', coordinate: { latitude: 48.8570, longitude: 2.3530 }, label: 'Turn left' },
{ id: 'dest', coordinate: { latitude: 48.8580, longitude: 2.3550 }, label: 'Destination' },
]}
distanceRemaining={320}
etaSeconds={240}
/>
ARBodyMeasure
Guides the user through a body-scanning flow and extracts clothing/fit measurements.
| Prop | Type | Default | Description |
|---|---|---|---|
renderBodyMeasure? | RenderBodyMeasureFn | — | Renderer from createViroARBodyMeasure() |
currentStep | 'front' | 'side' | 'arms-out' | 'front' | Active scanning step |
measurements | BodyMeasurements | {} | Partial measurements computed so far |
showGuide | boolean | true | Show a silhouette guide overlay |
onStepComplete? | (step: string, partial: BodyMeasurements) => void | — | Called when a scanning step finishes |
onComplete? | (measurements: BodyMeasurements) => void | — | Called when all steps are finished |
accessibilityLabel? | string | 'AR Body Measure' | Accessibility label |
testID? | string | — | Test identifier |
import { ARBodyMeasure } from '@objectifthunes/limestone-sdk';
import { createViroARBodyMeasure } from '@objectifthunes/limestone-sdk/viro';
<ARBodyMeasure
renderBodyMeasure={createViroARBodyMeasure()}
currentStep="front"
showGuide
onComplete={(m) => console.log('Measurements:', m)}
/>
Using the dev adapter
All eight AR components work without @reactvision/react-viro installed. Switch the import to ./dev for Expo Go, simulators, and CI:
import {
createViroARView,
createViroARTryOn,
createViroARPlacement,
createViroARMeasure,
createViroARAnnotation,
createViroARWorldObject,
createViroARNavigation,
createViroARBodyMeasure,
} from '@objectifthunes/limestone-sdk/dev';
The factory names are identical. No other code changes required.