browser-device-motion

Wraps the devicemotion event as global atoms — linear acceleration and rotation rate, plus derived selectors. Values are usually null on desktop.

Permission
iOS gates motion behind a user gesture — call requestMotionPermission() from a click before subscribing.

Install

bun add @valdres/browser-device-motion

Live example

Loading demo…

Usage

import { useValue } from "valdres-react"
import {
    accelerationSelector,
    rotationRateSelector,
    requestMotionPermission,
} from "@valdres/browser-device-motion"

function Motion() {
    const accel = useValue(accelerationSelector) // Vector3 | null
    const rot = useValue(rotationRateSelector)   // RotationRateSnapshot | null
    return (
        <div>
            <button onClick={() => requestMotionPermission()}>Enable</button>
            <pre>{JSON.stringify({ accel, rot }, null, 2)}</pre>
        </div>
    )
}

Exports

ExportKindType
motionAtomatom (read-only)MotionSnapshot | null
permissionAtomatom (read-only)PermissionValue
motionStatusAtomatom (read-only)MotionStatus
accelerationSelectorselectorVector3 | null
accelerationIncludingGravitySelectorselectorVector3 | null
accelerationMagnitudeSelectorselectornumber | null
rotationRateSelectorselectorRotationRateSnapshot | null
intervalSelectorselectornumber | null
requestMotionPermissionutil fn() => Promise<PermissionValue>
MotionSnapshottype{ acceleration, accelerationIncludingGravity, rotationRate: ... | null; interval: number; timeStamp: number }
Vector3type{ x, y, z: number | null }
RotationRateSnapshottype{ alpha, beta, gamma: number | null }
MotionStatustype"unsupported" | "idle" | "active"
PermissionValuetype"granted" | "denied" | "prompt" | "unsupported"

Cross-framework

The devicemotion subscription starts on the first subscriber across all stores and stops when the last one leaves. Read primitive per framework: useValue (React/Vue), createValue (Solid), injectValue (Angular), watch (Svelte), or store.get / store.sub.