# browser-device-orientation

Wraps `DeviceOrientationEvent` as global atoms, exposing the raw tilt snapshot plus `alpha` / `beta` / `gamma` and a compass-heading selector.

> **Permission**
>
>
> iOS requires a user gesture: call `requestOrientationPermission()` from a click handler before subscribing. Other browsers grant on subscribe.

## Install

```bash
bun add @valdres/browser-device-orientation
```

## Live example

▶ Live example: [https://valdres.dev/angular/plugins/browser-device-orientation](https://valdres.dev/angular/plugins/browser-device-orientation)

## Usage

```ts
import { Component } from "@angular/core"
import { injectValue } from "valdres-angular"
import { compassHeadingSelector } from "@valdres/browser-device-orientation"

@Component({
    selector: "compass-view",
    template: `{{ heading() == null ? "—" : (heading() | number: "1.0-0") + "°" }}`,
})
export class CompassView {
    heading = injectValue(compassHeadingSelector) // Signal<number | null>
}
```

## Exports

| Export                         | Kind             | Type                                                                                                                                        |
| ------------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `orientationAtom`              | atom (read-only) | `OrientationSnapshot \| null`                                                                                                               |
| `permissionAtom`               | atom (settable)  | `PermissionValue`                                                                                                                           |
| `orientationStatusAtom`        | atom (read-only) | `OrientationStatus`                                                                                                                         |
| `alphaSelector`                | selector         | `number \| null`                                                                                                                            |
| `betaSelector`                 | selector         | `number \| null`                                                                                                                            |
| `gammaSelector`                | selector         | `number \| null`                                                                                                                            |
| `absoluteSelector`             | selector         | `boolean \| null`                                                                                                                           |
| `compassHeadingSelector`       | selector         | `number \| null`                                                                                                                            |
| `requestOrientationPermission` | util fn          | `() => Promise<PermissionValue>`                                                                                                            |
| `OrientationSnapshot`          | type             | `{ alpha, beta, gamma: number \| null; absolute: boolean; webkitCompassHeading, webkitCompassAccuracy: number \| null; timeStamp: number }` |
| `OrientationStatus`            | type             | `"unsupported" \| "idle" \| "active"`                                                                                                       |
| `PermissionValue`              | type             | `"granted" \| "denied" \| "prompt" \| "unsupported"`                                                                                        |

## Cross-framework

Global atoms/selectors — works in every framework, only the read primitive differs. The `deviceorientation` listener starts on the first subscriber and stops on the last.
