@symbiote-native/screen-orientation 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +65 -20
  2. package/build/angular/index.d.ts +1 -1
  3. package/build/angular/index.js +1 -1
  4. package/build/angular/services/screen-orientation.service/index.js +1 -1
  5. package/build/core/screen-orientation.js +12 -4
  6. package/build/react/index.d.ts +1 -1
  7. package/build/react/index.js +1 -1
  8. package/build/solid/index.d.ts +2 -0
  9. package/build/solid/index.js +5 -0
  10. package/build/solid/primitives/create-screen-orientation.d.ts +3 -0
  11. package/build/solid/primitives/create-screen-orientation.js +38 -0
  12. package/build/svelte/index.d.ts +2 -0
  13. package/build/svelte/index.js +5 -0
  14. package/build/svelte/runes/use-screen-orientation.svelte.d.ts +4 -0
  15. package/build/svelte/runes/use-screen-orientation.svelte.js +35 -0
  16. package/build/vue/index.d.ts +1 -1
  17. package/build/vue/index.js +1 -1
  18. package/build-ngc/angular/index.d.ts +1 -1
  19. package/build-ngc/angular/index.js +1 -1
  20. package/build-ngc/angular/index.js.map +1 -1
  21. package/build-ngc/angular/services/screen-orientation.service/index.js +4 -4
  22. package/build-ngc/angular/services/screen-orientation.service/index.js.map +1 -1
  23. package/build-ngc/core/native-module.js.map +1 -1
  24. package/build-ngc/core/screen-orientation.js +12 -4
  25. package/build-ngc/core/screen-orientation.js.map +1 -1
  26. package/package.json +42 -14
  27. package/src/angular/index.ts +1 -23
  28. package/src/angular/services/screen-orientation.service/index.ts +8 -1
  29. package/src/core/native-module.ts +12 -6
  30. package/src/core/screen-orientation.ts +52 -14
  31. package/src/react/hooks/use-screen-orientation/index.ts +7 -5
  32. package/src/react/index.ts +1 -23
  33. package/src/solid/index.ts +6 -0
  34. package/src/solid/primitives/create-screen-orientation.ts +57 -0
  35. package/src/svelte/index.ts +6 -0
  36. package/src/svelte/runes/use-screen-orientation.svelte.ts +52 -0
  37. package/src/svelte/svelte-ambient.d.ts +6 -0
  38. package/src/vue/index.ts +1 -23
package/README.md CHANGED
@@ -3,7 +3,8 @@
3
3
  Port of [`expo-screen-orientation`](https://docs.expo.dev/versions/latest/sdk/screen-orientation/)
4
4
  for [SymbioteNative](../../README.md) — orientation locking (`lockAsync`/`lockPlatformAsync`/
5
5
  `unlockAsync`), reading the current orientation and lock, and an auto-updating orientation-change
6
- subscription, reachable from every adapter (React, Vue, Angular), not just React.
6
+ subscription, reachable from every adapter (React, Vue, Svelte, Solid, Angular), not just
7
+ React.
7
8
 
8
9
  Built the same way as [`@symbiote-native/network`](../network) and
9
10
  [`@symbiote-native/device`](../device), an `expo-modules-core`-based wrapper (see the
@@ -31,12 +32,12 @@ into the native host app **once**, covering this package and every other `expo-m
31
32
  package (`@symbiote-native/network`, `@symbiote-native/device`, `@symbiote-native/sensors`, ...)
32
33
  with zero further changes:
33
34
 
34
- | Platform | Touches |
35
- |---|---|
36
- | iOS | `ios/Podfile` — add `use_expo_modules!` |
37
- | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
38
- | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
39
- | Android | `MainApplication.kt` — Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
35
+ | Platform | Touches |
36
+ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
37
+ | iOS | `ios/Podfile` — add `use_expo_modules!` |
38
+ | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
39
+ | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
40
+ | Android | `MainApplication.kt` — Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
40
41
 
41
42
  Full mechanics — the Podfile pieces that normally ship inside the `expo` package, the `expo`
42
43
  peer-dependency exclusion list — live in the `symbiote-expo-native-module` skill. Reference
@@ -55,23 +56,29 @@ src/core/ screen-orientation.ts — lock*/unlock/get* functions +
55
56
  Orientation/OrientationLock/SizeClassIOS/WebOrientationLock/WebOrientation
56
57
  enums, PlatformOrientationInfo, ScreenOrientationInfo,
57
58
  OrientationChangeEvent, hand-ported from ScreenOrientation.types.ts, plus
58
- ScreenOrientationState (this package's own hook/composable/service shape).
59
+ ScreenOrientationState (the shape every adapter's wrapper returns).
59
60
  src/react/hooks/ @symbiote-native/screen-orientation/react — useScreenOrientation
60
61
  src/vue/composables/ @symbiote-native/screen-orientation/vue — useScreenOrientation (same name)
62
+ src/svelte/runes/ @symbiote-native/screen-orientation/svelte — useScreenOrientation (same name)
63
+ src/solid/primitives/ @symbiote-native/screen-orientation/solid — createScreenOrientation
64
+ (returns an Accessor; Solid reserves `use*` for consuming existing state)
61
65
  src/angular/services/ @symbiote-native/screen-orientation/angular — ScreenOrientationService
62
66
  (`.connect()` returns a Signal)
63
67
  ```
64
68
 
65
- Each adapter's hook/composable/service is a thin lifecycle wrapper (seed from one-shot
66
- `getOrientationAsync()`/`getOrientationLockAsync()` calls, subscribe to
69
+ Each adapter's hook/composable/rune/primitive/service is a thin lifecycle wrapper (seed from
70
+ one-shot `getOrientationAsync()`/`getOrientationLockAsync()` calls, subscribe to
67
71
  `addOrientationChangeListener`, unsubscribe on unmount) over the same `core` functions — the
68
- subscription logic is written once and shared by all three.
72
+ subscription logic is written once and shared by all of them.
69
73
 
70
74
  ## Use it
71
75
 
72
76
  ```tsx
73
77
  // React — examples/expo-react/screens/ScreenOrientationScreen.tsx
74
- import { lockAsync, OrientationLock } from '@symbiote-native/screen-orientation';
78
+ import {
79
+ lockAsync,
80
+ OrientationLock,
81
+ } from '@symbiote-native/screen-orientation';
75
82
  import { useScreenOrientation } from '@symbiote-native/screen-orientation/react';
76
83
 
77
84
  function ScreenOrientationScreen() {
@@ -81,7 +88,10 @@ function ScreenOrientationScreen() {
81
88
  <>
82
89
  <Text>Orientation: {orientation}</Text>
83
90
  <Text>Lock: {orientationLock}</Text>
84
- <Button title="Lock landscape" onPress={() => lockAsync(OrientationLock.LANDSCAPE)} />
91
+ <Button
92
+ title="Lock landscape"
93
+ onPress={() => lockAsync(OrientationLock.LANDSCAPE)}
94
+ />
85
95
  </>
86
96
  );
87
97
  }
@@ -91,7 +101,10 @@ function ScreenOrientationScreen() {
91
101
  <!-- Vue — examples/expo-vue-sfc/screens/ScreenOrientationScreen.vue -->
92
102
  <script setup lang="ts">
93
103
  import { Text } from '@symbiote-native/vue';
94
- import { lockAsync, OrientationLock } from '@symbiote-native/screen-orientation';
104
+ import {
105
+ lockAsync,
106
+ OrientationLock,
107
+ } from '@symbiote-native/screen-orientation';
95
108
  import { useScreenOrientation } from '@symbiote-native/screen-orientation/vue';
96
109
 
97
110
  const screenOrientation = useScreenOrientation(); // Ref<ScreenOrientationState>
@@ -118,6 +131,31 @@ export class ScreenOrientationScreen {
118
131
  }
119
132
  ```
120
133
 
134
+ ```tsx
135
+ // Solid — the accessor is CALLED; a Solid component body runs once, so a snapshot would freeze.
136
+ import { Text } from '@symbiote-native/solid';
137
+ import {
138
+ lockAsync,
139
+ OrientationLock,
140
+ } from '@symbiote-native/screen-orientation';
141
+ import { createScreenOrientation } from '@symbiote-native/screen-orientation/solid';
142
+
143
+ function ScreenOrientationScreen() {
144
+ const screenOrientation = createScreenOrientation(); // Accessor<ScreenOrientationState>
145
+
146
+ return (
147
+ <>
148
+ <Text>Orientation: {screenOrientation().orientation}</Text>
149
+ <Text>Lock: {screenOrientation().orientationLock}</Text>
150
+ <Button
151
+ title="Lock landscape"
152
+ onPress={() => lockAsync(OrientationLock.LANDSCAPE)}
153
+ />
154
+ </>
155
+ );
156
+ }
157
+ ```
158
+
121
159
  ## API
122
160
 
123
161
  A mix of stateless async functions and one listener-based subscription
@@ -143,19 +181,26 @@ Plus `Orientation` (enum: `UNKNOWN`/`PORTRAIT_UP`/`PORTRAIT_DOWN`/`LANDSCAPE_LEF
143
181
  `OrientationChangeEvent` — ported from upstream's `ScreenOrientation.types.ts`.
144
182
 
145
183
  ```ts
146
- import { getOrientationAsync, addOrientationChangeListener } from '@symbiote-native/screen-orientation';
184
+ import {
185
+ getOrientationAsync,
186
+ addOrientationChangeListener,
187
+ } from '@symbiote-native/screen-orientation';
147
188
 
148
189
  // framework-scoped entry points re-export the same free functions, plus a lifecycle
149
190
  // hook/composable/service:
150
191
  import { useScreenOrientation } from '@symbiote-native/screen-orientation/react';
151
192
  import { useScreenOrientation } from '@symbiote-native/screen-orientation/vue';
193
+ import { useScreenOrientation } from '@symbiote-native/screen-orientation/svelte';
194
+ import { createScreenOrientation } from '@symbiote-native/screen-orientation/solid';
152
195
  import { ScreenOrientationService } from '@symbiote-native/screen-orientation/angular';
153
196
  ```
154
197
 
155
- `useScreenOrientation` seeds its initial value (`{ orientation: Orientation.UNKNOWN,
156
- orientationLock: OrientationLock.UNKNOWN }`) from one-shot `getOrientationAsync()`/
157
- `getOrientationLockAsync()` calls, then subscribes to `addOrientationChangeListener` for updates,
158
- and unsubscribes on unmount.
198
+ `useScreenOrientation` (Solid: `createScreenOrientation`) seeds its initial value
199
+ (`{ orientation: Orientation.UNKNOWN, orientationLock: OrientationLock.UNKNOWN }`) from one-shot
200
+ `getOrientationAsync()`/`getOrientationLockAsync()` calls, then subscribes to
201
+ `addOrientationChangeListener` for updates, and unsubscribes on unmount. The Solid primitive
202
+ returns an `Accessor<ScreenOrientationState>` and subscribes from its body rather than an effect,
203
+ so nothing can slip between the seed and the subscription.
159
204
 
160
205
  **Note (Android):** `expo-screen-orientation` doesn't emit its own `expoDidUpdateDimensions`
161
206
  event on Android — the module piggybacks on RN's own `Dimensions.addEventListener('change', ...)`
@@ -167,7 +212,7 @@ subscribe to the native `expoDidUpdateDimensions` event directly.
167
212
  No Fabric/Descriptor angle at all — screen-orientation is a pure async-function + `EventEmitter`
168
213
  listener surface, never a view. Tests inject a fake native-module object in place of the real
169
214
  `requireNativeModule` resolution (`src/core/screen-orientation.test.ts`,
170
- `src/{react,vue,angular}/**/*.test.{ts,tsx}`, `vitest`), the same pattern
215
+ `src/{react,vue,svelte,solid,angular}/**/*.test.{ts,tsx}`, `vitest`), the same pattern
171
216
  `@symbiote-native/network`/`@symbiote-native/device`/`@symbiote-native/sensors` use — no
172
217
  `installFabric()`, no ViewConfig. Native rendering itself is verified on-device — see the parent
173
218
  [README](../../README.md).
@@ -1,2 +1,2 @@
1
1
  export { ScreenOrientationService } from './services/screen-orientation.service';
2
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, type PlatformOrientationInfo, type ScreenOrientationInfo, type OrientationChangeEvent, type OrientationChangeListener, type ScreenOrientationState, type EventSubscription, } from '../core';
2
+ export * from '../core';
@@ -1,4 +1,4 @@
1
1
  // ScreenOrientationService is the Angular-only lifecycle half; the free functions and event
2
2
  // subscription plumbing all live in core, shared with React/Vue.
3
3
  export { ScreenOrientationService } from './services/screen-orientation.service/index.js';
4
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, } from '../core/index.js';
4
+ export * from '../core/index.js';
@@ -32,7 +32,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { effect, inject, Injectable, Injector, signal } from '@angular/core';
35
+ import { effect, inject, Injectable, Injector, signal, } from '@angular/core';
36
36
  import { addOrientationChangeListener, getOrientationAsync, getOrientationLockAsync, Orientation, OrientationLock, } from '../../../core/index.js';
37
37
  // Angular twin of React's `useScreenOrientation` hook and Vue's `useScreenOrientation`
38
38
  // composable.
@@ -1,9 +1,9 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts
2
2
  // (sdk-57). Unlike battery, upstream ScreenOrientation throws UnavailabilityError when the
3
3
  // native method is absent — same convention as packages/network/src/core/network.ts.
4
- import { Platform, UnavailabilityError } from 'expo-modules-core';
4
+ import { Platform, UnavailabilityError, } from 'expo-modules-core';
5
5
  import { Dimensions } from 'react-native';
6
- import { expoScreenOrientation } from './native-module.js';
6
+ import { expoScreenOrientation, } from './native-module.js';
7
7
  import { Orientation, OrientationLock, WebOrientationLock, } from './types.js';
8
8
  const NATIVE_MODULE_NAME = 'ScreenOrientation';
9
9
  let _orientationChangeSubscribers = [];
@@ -23,13 +23,20 @@ export async function lockAsync(orientationLock) {
23
23
  await expoScreenOrientation.lockAsync(orientationLock);
24
24
  _lastOrientationLock = orientationLock;
25
25
  }
26
+ // UPSTREAM-BUG(expo): .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts:81
27
+ // and :112 - TWO falsy traps, and Android's SCREEN_ORIENTATION_LANDSCAPE is 0: the truthiness
28
+ // check skips the assignment, and even with that one fixed, !platformOrientationParam still
29
+ // rejects the assigned 0. Fixing only the first trap changes nothing.
30
+ // The caller gets a TypeError and the call never reaches native, so landscape cannot be locked
31
+ // on Android through this API.
32
+ // Ported verbatim for parity; do NOT fix without recording a deliberate divergence.
26
33
  /** Locks the screen to a platform-specific orientation param — Android constant, iOS
27
34
  * orientation array, or web `WebOrientationLock`. */
28
35
  export async function lockPlatformAsync(options) {
29
36
  if (!expoScreenOrientation.lockPlatformAsync) {
30
37
  throw new UnavailabilityError(NATIVE_MODULE_NAME, 'lockPlatformAsync');
31
38
  }
32
- const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb } = options;
39
+ const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb, } = options;
33
40
  let platformOrientationParam;
34
41
  if (Platform.OS === 'android' && screenOrientationConstantAndroid) {
35
42
  if (isNaN(screenOrientationConstantAndroid)) {
@@ -87,7 +94,8 @@ export async function getOrientationLockAsync() {
87
94
  /** Gets the current orientation lock as a platform-specific value. */
88
95
  export async function getPlatformOrientationLockAsync() {
89
96
  const platformOrientationLock = await expoScreenOrientation.getPlatformOrientationLockAsync?.();
90
- if (Platform.OS === 'android' && typeof platformOrientationLock === 'number') {
97
+ if (Platform.OS === 'android' &&
98
+ typeof platformOrientationLock === 'number') {
91
99
  return { screenOrientationConstantAndroid: platformOrientationLock };
92
100
  }
93
101
  if (Platform.OS === 'ios' && Array.isArray(platformOrientationLock)) {
@@ -1,2 +1,2 @@
1
1
  export { useScreenOrientation } from './hooks/use-screen-orientation';
2
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, type PlatformOrientationInfo, type ScreenOrientationInfo, type OrientationChangeEvent, type OrientationChangeListener, type ScreenOrientationState, type EventSubscription, } from '../core';
2
+ export * from '../core';
@@ -1,3 +1,3 @@
1
1
  // @symbiote-native/screen-orientation/react: the React entry over the framework-agnostic core.
2
2
  export { useScreenOrientation } from './hooks/use-screen-orientation/index.js';
3
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, } from '../core/index.js';
3
+ export * from '../core/index.js';
@@ -0,0 +1,2 @@
1
+ export { createScreenOrientation } from './primitives/create-screen-orientation';
2
+ export * from '../core';
@@ -0,0 +1,5 @@
1
+ // @symbiote-native/screen-orientation/solid: the Solid entry over the framework-agnostic core —
2
+ // mirrors the lifecycle-bucket naming convention of adapters/solid/src/primitives (never
3
+ // `hooks`/`composables`/`runes`, those are React's, Vue's and Svelte's terms).
4
+ export { createScreenOrientation } from './primitives/create-screen-orientation.js';
5
+ export * from '../core/index.js';
@@ -0,0 +1,3 @@
1
+ import { type Accessor } from 'solid-js';
2
+ import { type ScreenOrientationState } from '../../core';
3
+ export declare function createScreenOrientation(): Accessor<ScreenOrientationState>;
@@ -0,0 +1,38 @@
1
+ // createScreenOrientation — the Solid twin of React's `useScreenOrientation` hook, Vue's
2
+ // composable and Svelte's rune, over the framework-agnostic core (core/screen-orientation.ts).
3
+ // Seeds with one-shot getOrientationAsync()/getOrientationLockAsync() calls before the first
4
+ // native event fires, mirroring packages/network's createNetworkState.
5
+ //
6
+ // `primitives/` and `create*`, never `hooks/`+`use*`: Solid's ecosystem calls a composable
7
+ // reactive function a PRIMITIVE and reserves `use*` for consuming something that already exists.
8
+ // Full rationale in adapters/solid/src/primitives/create-color-scheme.ts.
9
+ //
10
+ // Returns an ACCESSOR, never a snapshot: a Solid component body runs ONCE, so a returned object
11
+ // would pin the caller to the boot orientation.
12
+ //
13
+ // Outside a component or `createRoot` there is no owner for `onCleanup` — Solid warns and the
14
+ // native listener lives for the process. The accessor still tracks; only the teardown is lost.
15
+ import { createSignal, onCleanup } from 'solid-js';
16
+ import { addOrientationChangeListener, getOrientationAsync, getOrientationLockAsync, Orientation, OrientationLock, } from '../../core/index.js';
17
+ export function createScreenOrientation() {
18
+ const [screenOrientation, setScreenOrientation] = createSignal({
19
+ orientation: Orientation.UNKNOWN,
20
+ orientationLock: OrientationLock.UNKNOWN,
21
+ });
22
+ Promise.all([getOrientationAsync(), getOrientationLockAsync()]).then(([orientation, orientationLock]) => {
23
+ setScreenOrientation({ orientation, orientationLock });
24
+ });
25
+ // Subscribed from the primitive body, not from an effect: React/Vue/Svelte start listening a
26
+ // tick after their seed runs, so a rotation landing in that window is lost. Both statements
27
+ // here run in one synchronous tick and nothing can interleave.
28
+ const subscription = addOrientationChangeListener(event => {
29
+ setScreenOrientation({
30
+ orientation: event.orientationInfo.orientation,
31
+ orientationLock: event.orientationLock,
32
+ });
33
+ });
34
+ onCleanup(() => {
35
+ subscription.remove();
36
+ });
37
+ return screenOrientation;
38
+ }
@@ -0,0 +1,2 @@
1
+ export { useScreenOrientation } from './runes/use-screen-orientation.svelte';
2
+ export * from '../core';
@@ -0,0 +1,5 @@
1
+ // @symbiote-native/screen-orientation/svelte: the Svelte entry over the framework-agnostic core —
2
+ // mirrors the lifecycle-bucket naming convention of adapters/svelte/src/runes (never
3
+ // `hooks`/`composables`, those are React's and Vue's terms).
4
+ export { useScreenOrientation } from './runes/use-screen-orientation.svelte';
5
+ export * from '../core/index.js';
@@ -0,0 +1,4 @@
1
+ import { type ScreenOrientationState } from '../../core';
2
+ export declare function useScreenOrientation(): {
3
+ readonly current: ScreenOrientationState;
4
+ };
@@ -0,0 +1,35 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core (core/screen-orientation.ts). Seeds the
2
+ // initial value with one-shot getOrientationAsync()/getOrientationLockAsync() calls before the
3
+ // first native event fires, mirroring packages/network's useNetworkState.
4
+ //
5
+ // `.svelte.ts` extension: runes ($state/$effect) only work there outside a `.svelte` component;
6
+ // `runes/` is Svelte's name for the lifecycle bucket (React's `hooks/`, Vue's `composables/`).
7
+ // Returns a boxed getter, not a bare `$state`: Svelte 5 reactivity is lexically scoped to the
8
+ // declaring module and doesn't survive being returned raw from a plain function, so the caller
9
+ // reads `.current` like unwrapping Vue's `Ref` via `.value`.
10
+ import { addOrientationChangeListener, getOrientationAsync, getOrientationLockAsync, Orientation, OrientationLock, } from '../../core/index.js';
11
+ export function useScreenOrientation() {
12
+ let screenOrientation = $state({
13
+ orientation: Orientation.UNKNOWN,
14
+ orientationLock: OrientationLock.UNKNOWN,
15
+ });
16
+ $effect(() => {
17
+ // Write-only touches of `screenOrientation`, so the effect has no dependency on it and runs
18
+ // once per mount - the twin of Vue's onMounted/onUnmounted pair.
19
+ Promise.all([getOrientationAsync(), getOrientationLockAsync()]).then(([orientation, orientationLock]) => {
20
+ screenOrientation = { orientation, orientationLock };
21
+ });
22
+ const subscription = addOrientationChangeListener(event => {
23
+ screenOrientation = {
24
+ orientation: event.orientationInfo.orientation,
25
+ orientationLock: event.orientationLock,
26
+ };
27
+ });
28
+ return () => subscription.remove();
29
+ });
30
+ return {
31
+ get current() {
32
+ return screenOrientation;
33
+ },
34
+ };
35
+ }
@@ -1,2 +1,2 @@
1
1
  export { useScreenOrientation } from './composables/use-screen-orientation';
2
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, type PlatformOrientationInfo, type ScreenOrientationInfo, type OrientationChangeEvent, type OrientationChangeListener, type ScreenOrientationState, type EventSubscription, } from '../core';
2
+ export * from '../core';
@@ -1,3 +1,3 @@
1
1
  // @symbiote-native/screen-orientation/vue: the Vue entry over the framework-agnostic core.
2
2
  export { useScreenOrientation } from './composables/use-screen-orientation/index.js';
3
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, } from '../core/index.js';
3
+ export * from '../core/index.js';
@@ -1,2 +1,2 @@
1
1
  export { ScreenOrientationService } from './services/screen-orientation.service';
2
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, type PlatformOrientationInfo, type ScreenOrientationInfo, type OrientationChangeEvent, type OrientationChangeListener, type ScreenOrientationState, type EventSubscription, } from '../core';
2
+ export * from '../core';
@@ -1,5 +1,5 @@
1
1
  // ScreenOrientationService is the Angular-only lifecycle half; the free functions and event
2
2
  // subscription plumbing all live in core, shared with React/Vue.
3
3
  export { ScreenOrientationService } from './services/screen-orientation.service';
4
- export { lockAsync, lockPlatformAsync, unlockAsync, getOrientationAsync, getOrientationLockAsync, getPlatformOrientationLockAsync, supportsOrientationLockAsync, addOrientationChangeListener, removeOrientationChangeListeners, removeOrientationChangeListener, Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, WebOrientation, } from '../core';
4
+ export * from '../core';
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,iEAAiE;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,uBAAuB,EACvB,+BAA+B,EAC/B,4BAA4B,EAC5B,4BAA4B,EAC5B,gCAAgC,EAChC,+BAA+B,EAC/B,WAAW,EACX,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,cAAc,GAOf,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,iEAAiE;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,cAAc,SAAS,CAAC"}
@@ -1,4 +1,4 @@
1
- import { effect, inject, Injectable, Injector, signal } from '@angular/core';
1
+ import { effect, inject, Injectable, Injector, signal, } from '@angular/core';
2
2
  import { addOrientationChangeListener, getOrientationAsync, getOrientationLockAsync, Orientation, OrientationLock, } from '../../../core';
3
3
  import * as i0 from "@angular/core";
4
4
  // Angular twin of React's `useScreenOrientation` hook and Vue's `useScreenOrientation`
@@ -24,10 +24,10 @@ export class ScreenOrientationService {
24
24
  }, { injector: this.injector });
25
25
  return screenOrientation.asReadonly();
26
26
  }
27
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScreenOrientationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
28
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScreenOrientationService, providedIn: 'root' });
27
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ScreenOrientationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
28
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ScreenOrientationService, providedIn: 'root' });
29
29
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScreenOrientationService, decorators: [{
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ScreenOrientationService, decorators: [{
31
31
  type: Injectable,
32
32
  args: [{ providedIn: 'root' }]
33
33
  }] });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/angular/services/screen-orientation.service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AAC1F,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,EACX,eAAe,GAEhB,MAAM,eAAe,CAAC;;AAEvB,uFAAuF;AACvF,cAAc;AACd,EAAE;AACF,6EAA6E;AAC7E,uDAAuD;AAEvD,MAAM,OAAO,wBAAwB;IAClB,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE7C,OAAO;QACL,MAAM,iBAAiB,GAAG,MAAM,CAAyB;YACvD,WAAW,EAAE,WAAW,CAAC,OAAO;YAChC,eAAe,EAAE,eAAe,CAAC,OAAO;SACzC;8FAAC,CAAC;QAEH,MAAM,CACJ,SAAS,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,IAAI,CAClE,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,CACjC,iBAAiB,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAC1D,CAAC;YACF,MAAM,YAAY,GAAG,4BAA4B,CAAC,KAAK,CAAC,EAAE,CACxD,iBAAiB,CAAC,GAAG,CAAC;gBACpB,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,WAAW;gBAC9C,eAAe,EAAE,KAAK,CAAC,eAAe;aACvC,CAAC,CACH,CAAC;YACF,SAAS,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B,CAAC;QAEF,OAAO,iBAAiB,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC;uGA3BU,wBAAwB;2GAAxB,wBAAwB,cADX,MAAM;;2FACnB,wBAAwB;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/angular/services/screen-orientation.service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,GAEP,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,EACX,eAAe,GAEhB,MAAM,eAAe,CAAC;;AAEvB,uFAAuF;AACvF,cAAc;AACd,EAAE;AACF,6EAA6E;AAC7E,uDAAuD;AAEvD,MAAM,OAAO,wBAAwB;IAClB,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE7C,OAAO;QACL,MAAM,iBAAiB,GAAG,MAAM,CAAyB;YACvD,WAAW,EAAE,WAAW,CAAC,OAAO;YAChC,eAAe,EAAE,eAAe,CAAC,OAAO;SACzC;8FAAC,CAAC;QAEH,MAAM,CACJ,SAAS,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,IAAI,CAClE,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,CACjC,iBAAiB,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAC1D,CAAC;YACF,MAAM,YAAY,GAAG,4BAA4B,CAAC,KAAK,CAAC,EAAE,CACxD,iBAAiB,CAAC,GAAG,CAAC;gBACpB,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,WAAW;gBAC9C,eAAe,EAAE,KAAK,CAAC,eAAe;aACvC,CAAC,CACH,CAAC;YACF,SAAS,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B,CAAC;QAEF,OAAO,iBAAiB,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC;uGA3BU,wBAAwB;2GAAxB,wBAAwB,cADX,MAAM;;2FACnB,wBAAwB;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AASxD,MAAM,mCAAmC,GAAG,uBAAuB,CAAC;AAwBpE,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CACtD,mCAAmC,CACpC,CAAC"}
1
+ {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AASxD,MAAM,mCAAmC,GAAG,uBAAuB,CAAC;AA6BpE,MAAM,CAAC,MAAM,qBAAqB,GAChC,mBAAmB,CACjB,mCAAmC,CACpC,CAAC"}
@@ -1,9 +1,9 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts
2
2
  // (sdk-57). Unlike battery, upstream ScreenOrientation throws UnavailabilityError when the
3
3
  // native method is absent — same convention as packages/network/src/core/network.ts.
4
- import { Platform, UnavailabilityError } from 'expo-modules-core';
4
+ import { Platform, UnavailabilityError, } from 'expo-modules-core';
5
5
  import { Dimensions } from 'react-native';
6
- import { expoScreenOrientation } from './native-module';
6
+ import { expoScreenOrientation, } from './native-module';
7
7
  import { Orientation, OrientationLock, WebOrientationLock, } from './types';
8
8
  const NATIVE_MODULE_NAME = 'ScreenOrientation';
9
9
  let _orientationChangeSubscribers = [];
@@ -23,13 +23,20 @@ export async function lockAsync(orientationLock) {
23
23
  await expoScreenOrientation.lockAsync(orientationLock);
24
24
  _lastOrientationLock = orientationLock;
25
25
  }
26
+ // UPSTREAM-BUG(expo): .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts:81
27
+ // and :112 - TWO falsy traps, and Android's SCREEN_ORIENTATION_LANDSCAPE is 0: the truthiness
28
+ // check skips the assignment, and even with that one fixed, !platformOrientationParam still
29
+ // rejects the assigned 0. Fixing only the first trap changes nothing.
30
+ // The caller gets a TypeError and the call never reaches native, so landscape cannot be locked
31
+ // on Android through this API.
32
+ // Ported verbatim for parity; do NOT fix without recording a deliberate divergence.
26
33
  /** Locks the screen to a platform-specific orientation param — Android constant, iOS
27
34
  * orientation array, or web `WebOrientationLock`. */
28
35
  export async function lockPlatformAsync(options) {
29
36
  if (!expoScreenOrientation.lockPlatformAsync) {
30
37
  throw new UnavailabilityError(NATIVE_MODULE_NAME, 'lockPlatformAsync');
31
38
  }
32
- const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb } = options;
39
+ const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb, } = options;
33
40
  let platformOrientationParam;
34
41
  if (Platform.OS === 'android' && screenOrientationConstantAndroid) {
35
42
  if (isNaN(screenOrientationConstantAndroid)) {
@@ -87,7 +94,8 @@ export async function getOrientationLockAsync() {
87
94
  /** Gets the current orientation lock as a platform-specific value. */
88
95
  export async function getPlatformOrientationLockAsync() {
89
96
  const platformOrientationLock = await expoScreenOrientation.getPlatformOrientationLockAsync?.();
90
- if (Platform.OS === 'android' && typeof platformOrientationLock === 'number') {
97
+ if (Platform.OS === 'android' &&
98
+ typeof platformOrientationLock === 'number') {
91
99
  return { screenOrientationConstantAndroid: platformOrientationLock };
92
100
  }
93
101
  if (Platform.OS === 'ios' && Array.isArray(platformOrientationLock)) {
@@ -1 +1 @@
1
- {"version":3,"file":"screen-orientation.js","sourceRoot":"","sources":["../../src/core/screen-orientation.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,2FAA2F;AAC3F,qFAAqF;AACrF,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAA0B,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAkC,MAAM,iBAAiB,CAAC;AACxF,OAAO,EACL,WAAW,EACX,eAAe,EACf,kBAAkB,GAInB,MAAM,SAAS,CAAC;AAEjB,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAE/C,IAAI,6BAA6B,GAAwB,EAAE,CAAC;AAC5D,IAAI,oBAAoB,GAAoB,eAAe,CAAC,OAAO,CAAC;AAEpE,iDAAiD;AACjD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,eAAgC;IAC9D,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACxD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,6BAA6B,eAAe,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,eAAe,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,MAAM,qBAAqB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACvD,oBAAoB,GAAG,eAAe,CAAC;AACzC,CAAC;AAED;qDACqD;AACrD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAgC;IACtE,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,CAAC;QAC7C,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,GAC7F,OAAO,CAAC;IACV,IAAI,wBAA+D,CAAC;IACpE,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,gCAAgC,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,gCAAgC,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,SAAS,CACjB,8FAA8F,gCAAgC,EAAE,CACjI,CAAC;QACJ,CAAC;QACD,wBAAwB,GAAG,gCAAgC,CAAC;IAC9D,CAAC;SAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,yBAAyB,EAAE,CAAC;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,SAAS,CACjB,mFAAmF,yBAAyB,EAAE,CAC/G,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAChD,KAAK,MAAM,WAAW,IAAI,yBAAyB,EAAE,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,SAAS,CACjB,mCAAmC,WAAW,6BAA6B,CAC5E,CAAC;YACJ,CAAC;QACH,CAAC;QACD,wBAAwB,GAAG,yBAAyB,CAAC;IACvD,CAAC;SAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,wBAAwB,EAAE,CAAC;QAC7D,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC9D,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,SAAS,CAAC,iCAAiC,wBAAwB,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,wBAAwB,GAAG,wBAAwB,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,MAAM,IAAI,SAAS,CAAC,qEAAqE,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,qBAAqB,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;IACxE,oBAAoB,GAAG,eAAe,CAAC,KAAK,CAAC;AAC/C,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,qBAAqB,CAAC,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,EAAE,CAAC;QAC/C,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,qBAAqB,CAAC,mBAAmB,EAAE,CAAC;AACrD,CAAC;AAED;0EAC0E;AAC1E,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,IAAI,CAAC,qBAAqB,CAAC,uBAAuB,EAAE,CAAC;QACnD,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IACD,OAAO,qBAAqB,CAAC,uBAAuB,EAAE,CAAC;AACzD,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,+BAA+B;IACnD,MAAM,uBAAuB,GAAG,MAAM,qBAAqB,CAAC,+BAA+B,EAAE,EAAE,CAAC;IAChG,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,OAAO,uBAAuB,KAAK,QAAQ,EAAE,CAAC;QAC7E,OAAO,EAAE,gCAAgC,EAAE,uBAAuB,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACpE,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,CAAC;IAChE,CAAC;IACD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,OAAO,uBAAuB,KAAK,QAAQ,EAAE,CAAC;QACzE,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,eAAgC;IAEhC,IAAI,CAAC,qBAAqB,CAAC,4BAA4B,EAAE,CAAC;QACxD,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACxD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,6BAA6B,eAAe,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,qBAAqB,CAAC,4BAA4B,CAAC,eAAe,CAAC,CAAC;AAC7E,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,4BAA4B,CAC1C,QAAmC;IAEnC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CAAC,sDAAsD,QAAQ,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,MAAM,YAAY,GAAG,qCAAqC,CAAC,QAAQ,CAAC,CAAC;IACrE,6BAA6B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,gCAAgC;IAC9C,IAAI,CAAC,GAAG,6BAA6B,CAAC,MAAM,CAAC;IAC7C,OAAO,CAAC,EAAE,EAAE,CAAC;QACX,6BAA6B,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3C,6BAA6B,CAAC,GAAG,EAAE,CAAC;IACtC,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,+BAA+B,CAAC,YAA+B;IAC7E,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAC3D,CAAC;IACD,YAAY,CAAC,MAAM,EAAE,CAAC;IACtB,6BAA6B,GAAG,6BAA6B,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC;AACpG,CAAC;AAED,+FAA+F;AAC/F,+FAA+F;AAC/F,SAAS,qCAAqC,CAC5C,QAAmC;IAEnC,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QACnD,OAAO,qBAAqB,CAAC,WAAW,CACtC,yBAAyB,EACzB,KAAK,EAAE,MAA8B,EAAE,EAAE;YACvC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvD,uBAAuB,EAAE;YACzB,mBAAmB,EAAE;SACtB,CAAC,CAAC;QACH,QAAQ,CAAC,EAAE,eAAe,EAAE,EAAE,WAAW,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"screen-orientation.js","sourceRoot":"","sources":["../../src/core/screen-orientation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@symbiote-native/screen-orientation",
3
- "version": "0.1.0",
4
- "description": "expo-screen-orientation wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, and Angular adapters. Orientation locking (lockAsync/lockPlatformAsync/unlockAsync), the current orientation and lock, and an auto-updating orientation-change hook/composable/service.",
3
+ "version": "0.3.0",
4
+ "description": "expo-screen-orientation wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Orientation locking (lockAsync/lockPlatformAsync/unlockAsync), the current orientation and lock, and an auto-updating orientation-change hook/composable/service.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -30,6 +30,14 @@
30
30
  "types": "./build/react/index.d.ts",
31
31
  "default": "./build/react/index.js"
32
32
  },
33
+ "./svelte": {
34
+ "types": "./build/svelte/index.d.ts",
35
+ "default": "./build/svelte/index.js"
36
+ },
37
+ "./solid": {
38
+ "types": "./build/solid/index.d.ts",
39
+ "default": "./build/solid/index.js"
40
+ },
33
41
  "./angular": {
34
42
  "types": "./build-ngc/angular/index.d.ts",
35
43
  "react-native": "./build-ngc/angular/index.js",
@@ -53,15 +61,19 @@
53
61
  "expo-modules-core": "57.0.5"
54
62
  },
55
63
  "peerDependencies": {
64
+ "@symbiote-native/angular": ">=0.6.2",
56
65
  "@symbiote-native/engine": ">=0.1.7",
66
+ "@symbiote-native/react": ">=0.2.8",
67
+ "@symbiote-native/solid": ">=0.0.1",
68
+ "@symbiote-native/svelte": ">=0.1.0",
69
+ "@symbiote-native/vue": ">=0.3.8",
57
70
  "@angular/core": ">=20",
58
71
  "@vue/runtime-core": "^3.5.13",
59
72
  "react": ">=19.0.0",
60
73
  "react-native": ">=0.86",
61
- "vue": ">=3.5.0",
62
- "@symbiote-native/angular": "0.6.2",
63
- "@symbiote-native/react": "0.2.8",
64
- "@symbiote-native/vue": "0.3.8"
74
+ "solid-js": ">=1.9.0",
75
+ "svelte": ">=5.56.0",
76
+ "vue": ">=3.5.0"
65
77
  },
66
78
  "peerDependenciesMeta": {
67
79
  "@symbiote-native/angular": {
@@ -70,6 +82,12 @@
70
82
  "@symbiote-native/react": {
71
83
  "optional": true
72
84
  },
85
+ "@symbiote-native/solid": {
86
+ "optional": true
87
+ },
88
+ "@symbiote-native/svelte": {
89
+ "optional": true
90
+ },
73
91
  "@symbiote-native/vue": {
74
92
  "optional": true
75
93
  },
@@ -82,24 +100,34 @@
82
100
  "react": {
83
101
  "optional": true
84
102
  },
103
+ "solid-js": {
104
+ "optional": true
105
+ },
106
+ "svelte": {
107
+ "optional": true
108
+ },
85
109
  "vue": {
86
110
  "optional": true
87
111
  }
88
112
  },
89
113
  "devDependencies": {
90
- "@angular/compiler": "^22",
91
- "@angular/compiler-cli": "^22",
92
- "@angular/core": "^22",
114
+ "@angular/compiler": "~22.0.8",
115
+ "@angular/compiler-cli": "~22.0.8",
116
+ "@angular/core": "~22.0.8",
93
117
  "@types/node": "^26.0.0",
94
118
  "@types/react": "^19.2.0",
95
119
  "@vue/runtime-core": "^3.5.13",
96
120
  "react": "19.2.3",
121
+ "solid-js": "^1.9.14",
122
+ "svelte": "^5.56.0",
97
123
  "typescript": "~6.0.0",
98
- "@symbiote-native/angular": "0.6.2",
99
- "@symbiote-native/engine": "0.1.7",
100
- "@symbiote-native/react": "0.2.8",
101
- "@symbiote-native/test-utils": "0.1.6",
102
- "@symbiote-native/vue": "0.3.8"
124
+ "@symbiote-native/angular": "0.8.0",
125
+ "@symbiote-native/engine": "0.3.0",
126
+ "@symbiote-native/react": "0.4.0",
127
+ "@symbiote-native/solid": "0.1.0",
128
+ "@symbiote-native/svelte": "0.3.0",
129
+ "@symbiote-native/test-utils": "0.2.0",
130
+ "@symbiote-native/vue": "0.5.0"
103
131
  },
104
132
  "scripts": {
105
133
  "typecheck": "tsc --build",
@@ -1,26 +1,4 @@
1
1
  // ScreenOrientationService is the Angular-only lifecycle half; the free functions and event
2
2
  // subscription plumbing all live in core, shared with React/Vue.
3
3
  export { ScreenOrientationService } from './services/screen-orientation.service';
4
- export {
5
- lockAsync,
6
- lockPlatformAsync,
7
- unlockAsync,
8
- getOrientationAsync,
9
- getOrientationLockAsync,
10
- getPlatformOrientationLockAsync,
11
- supportsOrientationLockAsync,
12
- addOrientationChangeListener,
13
- removeOrientationChangeListeners,
14
- removeOrientationChangeListener,
15
- Orientation,
16
- OrientationLock,
17
- SizeClassIOS,
18
- WebOrientationLock,
19
- WebOrientation,
20
- type PlatformOrientationInfo,
21
- type ScreenOrientationInfo,
22
- type OrientationChangeEvent,
23
- type OrientationChangeListener,
24
- type ScreenOrientationState,
25
- type EventSubscription,
26
- } from '../core';
4
+ export * from '../core';
@@ -1,4 +1,11 @@
1
- import { effect, inject, Injectable, Injector, signal, type Signal } from '@angular/core';
1
+ import {
2
+ effect,
3
+ inject,
4
+ Injectable,
5
+ Injector,
6
+ signal,
7
+ type Signal,
8
+ } from '@angular/core';
2
9
  import {
3
10
  addOrientationChangeListener,
4
11
  getOrientationAsync,
@@ -12,7 +12,8 @@ const EXPO_SCREEN_ORIENTATION_MODULE_NAME = 'ExpoScreenOrientation';
12
12
  // The platform-specific lock param/return shape is a genuine per-platform union (Android sends/
13
13
  // returns a numeric constant, iOS an Orientation[], web a WebOrientationLock string) — never `any`,
14
14
  // so screen-orientation.ts can narrow it with typeof/Array.isArray instead of casting.
15
- export type IPlatformOrientationParam = number | Orientation[] | WebOrientationLock;
15
+ export type IPlatformOrientationParam =
16
+ number | Orientation[] | WebOrientationLock;
16
17
 
17
18
  // Every method is optional for the same reason every sibling package's native module type is
18
19
  // (network, device, battery) — each call site in screen-orientation.ts checks for the method's
@@ -20,17 +21,22 @@ export type IPlatformOrientationParam = number | Orientation[] | WebOrientationL
20
21
  // capability checks rather than assuming the native module implements the whole surface.
21
22
  export type INativeScreenOrientationModule = {
22
23
  lockAsync?(orientationLock: OrientationLock): Promise<void>;
23
- lockPlatformAsync?(platformOrientationParam: IPlatformOrientationParam): Promise<void>;
24
+ lockPlatformAsync?(
25
+ platformOrientationParam: IPlatformOrientationParam,
26
+ ): Promise<void>;
24
27
  getOrientationAsync?(): Promise<Orientation>;
25
28
  getOrientationLockAsync?(): Promise<OrientationLock>;
26
29
  getPlatformOrientationLockAsync?(): Promise<IPlatformOrientationParam>;
27
- supportsOrientationLockAsync?(orientationLock: OrientationLock): Promise<boolean>;
30
+ supportsOrientationLockAsync?(
31
+ orientationLock: OrientationLock,
32
+ ): Promise<boolean>;
28
33
  addListener(
29
34
  eventName: 'expoDidUpdateDimensions',
30
35
  listener: (event: OrientationChangeEvent) => void,
31
36
  ): EventSubscription;
32
37
  };
33
38
 
34
- export const expoScreenOrientation = requireNativeModule<INativeScreenOrientationModule>(
35
- EXPO_SCREEN_ORIENTATION_MODULE_NAME,
36
- );
39
+ export const expoScreenOrientation =
40
+ requireNativeModule<INativeScreenOrientationModule>(
41
+ EXPO_SCREEN_ORIENTATION_MODULE_NAME,
42
+ );
@@ -1,9 +1,16 @@
1
1
  // Hand-ported from .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts
2
2
  // (sdk-57). Unlike battery, upstream ScreenOrientation throws UnavailabilityError when the
3
3
  // native method is absent — same convention as packages/network/src/core/network.ts.
4
- import { Platform, UnavailabilityError, type EventSubscription } from 'expo-modules-core';
4
+ import {
5
+ Platform,
6
+ UnavailabilityError,
7
+ type EventSubscription,
8
+ } from 'expo-modules-core';
5
9
  import { Dimensions } from 'react-native';
6
- import { expoScreenOrientation, type IPlatformOrientationParam } from './native-module';
10
+ import {
11
+ expoScreenOrientation,
12
+ type IPlatformOrientationParam,
13
+ } from './native-module';
7
14
  import {
8
15
  Orientation,
9
16
  OrientationLock,
@@ -19,7 +26,9 @@ let _orientationChangeSubscribers: EventSubscription[] = [];
19
26
  let _lastOrientationLock: OrientationLock = OrientationLock.UNKNOWN;
20
27
 
21
28
  /** Locks the screen to the given orientation. */
22
- export async function lockAsync(orientationLock: OrientationLock): Promise<void> {
29
+ export async function lockAsync(
30
+ orientationLock: OrientationLock,
31
+ ): Promise<void> {
23
32
  if (!expoScreenOrientation.lockAsync) {
24
33
  throw new UnavailabilityError(NATIVE_MODULE_NAME, 'lockAsync');
25
34
  }
@@ -34,14 +43,26 @@ export async function lockAsync(orientationLock: OrientationLock): Promise<void>
34
43
  _lastOrientationLock = orientationLock;
35
44
  }
36
45
 
46
+ // UPSTREAM-BUG(expo): .vendors/expo/packages/expo-screen-orientation/src/ScreenOrientation.ts:81
47
+ // and :112 - TWO falsy traps, and Android's SCREEN_ORIENTATION_LANDSCAPE is 0: the truthiness
48
+ // check skips the assignment, and even with that one fixed, !platformOrientationParam still
49
+ // rejects the assigned 0. Fixing only the first trap changes nothing.
50
+ // The caller gets a TypeError and the call never reaches native, so landscape cannot be locked
51
+ // on Android through this API.
52
+ // Ported verbatim for parity; do NOT fix without recording a deliberate divergence.
37
53
  /** Locks the screen to a platform-specific orientation param — Android constant, iOS
38
54
  * orientation array, or web `WebOrientationLock`. */
39
- export async function lockPlatformAsync(options: PlatformOrientationInfo): Promise<void> {
55
+ export async function lockPlatformAsync(
56
+ options: PlatformOrientationInfo,
57
+ ): Promise<void> {
40
58
  if (!expoScreenOrientation.lockPlatformAsync) {
41
59
  throw new UnavailabilityError(NATIVE_MODULE_NAME, 'lockPlatformAsync');
42
60
  }
43
- const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb } =
44
- options;
61
+ const {
62
+ screenOrientationConstantAndroid,
63
+ screenOrientationArrayIOS,
64
+ screenOrientationLockWeb,
65
+ } = options;
45
66
  let platformOrientationParam: IPlatformOrientationParam | undefined;
46
67
  if (Platform.OS === 'android' && screenOrientationConstantAndroid) {
47
68
  if (isNaN(screenOrientationConstantAndroid)) {
@@ -68,12 +89,16 @@ export async function lockPlatformAsync(options: PlatformOrientationInfo): Promi
68
89
  } else if (Platform.OS === 'web' && screenOrientationLockWeb) {
69
90
  const webOrientationLocks = Object.values(WebOrientationLock);
70
91
  if (!webOrientationLocks.includes(screenOrientationLockWeb)) {
71
- throw new TypeError(`Invalid Web Orientation Lock: ${screenOrientationLockWeb}`);
92
+ throw new TypeError(
93
+ `Invalid Web Orientation Lock: ${screenOrientationLockWeb}`,
94
+ );
72
95
  }
73
96
  platformOrientationParam = screenOrientationLockWeb;
74
97
  }
75
98
  if (!platformOrientationParam) {
76
- throw new TypeError('lockPlatformAsync cannot be called with undefined option properties');
99
+ throw new TypeError(
100
+ 'lockPlatformAsync cannot be called with undefined option properties',
101
+ );
77
102
  }
78
103
  await expoScreenOrientation.lockPlatformAsync(platformOrientationParam);
79
104
  _lastOrientationLock = OrientationLock.OTHER;
@@ -106,8 +131,12 @@ export async function getOrientationLockAsync(): Promise<OrientationLock> {
106
131
 
107
132
  /** Gets the current orientation lock as a platform-specific value. */
108
133
  export async function getPlatformOrientationLockAsync(): Promise<PlatformOrientationInfo> {
109
- const platformOrientationLock = await expoScreenOrientation.getPlatformOrientationLockAsync?.();
110
- if (Platform.OS === 'android' && typeof platformOrientationLock === 'number') {
134
+ const platformOrientationLock =
135
+ await expoScreenOrientation.getPlatformOrientationLockAsync?.();
136
+ if (
137
+ Platform.OS === 'android' &&
138
+ typeof platformOrientationLock === 'number'
139
+ ) {
111
140
  return { screenOrientationConstantAndroid: platformOrientationLock };
112
141
  }
113
142
  if (Platform.OS === 'ios' && Array.isArray(platformOrientationLock)) {
@@ -124,7 +153,10 @@ export async function supportsOrientationLockAsync(
124
153
  orientationLock: OrientationLock,
125
154
  ): Promise<boolean> {
126
155
  if (!expoScreenOrientation.supportsOrientationLockAsync) {
127
- throw new UnavailabilityError(NATIVE_MODULE_NAME, 'supportsOrientationLockAsync');
156
+ throw new UnavailabilityError(
157
+ NATIVE_MODULE_NAME,
158
+ 'supportsOrientationLockAsync',
159
+ );
128
160
  }
129
161
  const orientationLocks = Object.values(OrientationLock);
130
162
  if (!orientationLocks.includes(orientationLock)) {
@@ -138,7 +170,9 @@ export function addOrientationChangeListener(
138
170
  listener: OrientationChangeListener,
139
171
  ): EventSubscription {
140
172
  if (typeof listener !== 'function') {
141
- throw new TypeError(`addOrientationChangeListener cannot be called with ${listener}`);
173
+ throw new TypeError(
174
+ `addOrientationChangeListener cannot be called with ${listener}`,
175
+ );
142
176
  }
143
177
  const subscription = createDidUpdateDimensionsSubscription(listener);
144
178
  _orientationChangeSubscribers.push(subscription);
@@ -155,12 +189,16 @@ export function removeOrientationChangeListeners(): void {
155
189
  }
156
190
 
157
191
  /** Removes a single orientation-change listener's subscription. */
158
- export function removeOrientationChangeListener(subscription: EventSubscription): void {
192
+ export function removeOrientationChangeListener(
193
+ subscription: EventSubscription,
194
+ ): void {
159
195
  if (!subscription || !subscription.remove) {
160
196
  throw new TypeError('Must pass in a valid subscription');
161
197
  }
162
198
  subscription.remove();
163
- _orientationChangeSubscribers = _orientationChangeSubscribers.filter(sub => sub !== subscription);
199
+ _orientationChangeSubscribers = _orientationChangeSubscribers.filter(
200
+ sub => sub !== subscription,
201
+ );
164
202
  }
165
203
 
166
204
  // IMPORTANT: Android doesn't emit `expoDidUpdateDimensions` — RN's own Dimensions module does,
@@ -12,14 +12,16 @@ import {
12
12
  } from '../../../core';
13
13
 
14
14
  export function useScreenOrientation(): ScreenOrientationState {
15
- const [screenOrientation, setScreenOrientation] = useState<ScreenOrientationState>({
16
- orientation: Orientation.UNKNOWN,
17
- orientationLock: OrientationLock.UNKNOWN,
18
- });
15
+ const [screenOrientation, setScreenOrientation] =
16
+ useState<ScreenOrientationState>({
17
+ orientation: Orientation.UNKNOWN,
18
+ orientationLock: OrientationLock.UNKNOWN,
19
+ });
19
20
 
20
21
  useEffect(() => {
21
22
  Promise.all([getOrientationAsync(), getOrientationLockAsync()]).then(
22
- ([orientation, orientationLock]) => setScreenOrientation({ orientation, orientationLock }),
23
+ ([orientation, orientationLock]) =>
24
+ setScreenOrientation({ orientation, orientationLock }),
23
25
  );
24
26
  const subscription = addOrientationChangeListener(event =>
25
27
  setScreenOrientation({
@@ -1,26 +1,4 @@
1
1
  // @symbiote-native/screen-orientation/react: the React entry over the framework-agnostic core.
2
2
 
3
3
  export { useScreenOrientation } from './hooks/use-screen-orientation';
4
- export {
5
- lockAsync,
6
- lockPlatformAsync,
7
- unlockAsync,
8
- getOrientationAsync,
9
- getOrientationLockAsync,
10
- getPlatformOrientationLockAsync,
11
- supportsOrientationLockAsync,
12
- addOrientationChangeListener,
13
- removeOrientationChangeListeners,
14
- removeOrientationChangeListener,
15
- Orientation,
16
- OrientationLock,
17
- SizeClassIOS,
18
- WebOrientationLock,
19
- WebOrientation,
20
- type PlatformOrientationInfo,
21
- type ScreenOrientationInfo,
22
- type OrientationChangeEvent,
23
- type OrientationChangeListener,
24
- type ScreenOrientationState,
25
- type EventSubscription,
26
- } from '../core';
4
+ export * from '../core';
@@ -0,0 +1,6 @@
1
+ // @symbiote-native/screen-orientation/solid: the Solid entry over the framework-agnostic core —
2
+ // mirrors the lifecycle-bucket naming convention of adapters/solid/src/primitives (never
3
+ // `hooks`/`composables`/`runes`, those are React's, Vue's and Svelte's terms).
4
+
5
+ export { createScreenOrientation } from './primitives/create-screen-orientation';
6
+ export * from '../core';
@@ -0,0 +1,57 @@
1
+ // createScreenOrientation — the Solid twin of React's `useScreenOrientation` hook, Vue's
2
+ // composable and Svelte's rune, over the framework-agnostic core (core/screen-orientation.ts).
3
+ // Seeds with one-shot getOrientationAsync()/getOrientationLockAsync() calls before the first
4
+ // native event fires, mirroring packages/network's createNetworkState.
5
+ //
6
+ // `primitives/` and `create*`, never `hooks/`+`use*`: Solid's ecosystem calls a composable
7
+ // reactive function a PRIMITIVE and reserves `use*` for consuming something that already exists.
8
+ // Full rationale in adapters/solid/src/primitives/create-color-scheme.ts.
9
+ //
10
+ // Returns an ACCESSOR, never a snapshot: a Solid component body runs ONCE, so a returned object
11
+ // would pin the caller to the boot orientation.
12
+ //
13
+ // Outside a component or `createRoot` there is no owner for `onCleanup` — Solid warns and the
14
+ // native listener lives for the process. The accessor still tracks; only the teardown is lost.
15
+
16
+ import { createSignal, onCleanup, type Accessor } from 'solid-js';
17
+ import {
18
+ addOrientationChangeListener,
19
+ getOrientationAsync,
20
+ getOrientationLockAsync,
21
+ Orientation,
22
+ OrientationLock,
23
+ type EventSubscription,
24
+ type ScreenOrientationState,
25
+ } from '../../core';
26
+
27
+ export function createScreenOrientation(): Accessor<ScreenOrientationState> {
28
+ const [screenOrientation, setScreenOrientation] =
29
+ createSignal<ScreenOrientationState>({
30
+ orientation: Orientation.UNKNOWN,
31
+ orientationLock: OrientationLock.UNKNOWN,
32
+ });
33
+
34
+ Promise.all([getOrientationAsync(), getOrientationLockAsync()]).then(
35
+ ([orientation, orientationLock]) => {
36
+ setScreenOrientation({ orientation, orientationLock });
37
+ },
38
+ );
39
+
40
+ // Subscribed from the primitive body, not from an effect: React/Vue/Svelte start listening a
41
+ // tick after their seed runs, so a rotation landing in that window is lost. Both statements
42
+ // here run in one synchronous tick and nothing can interleave.
43
+ const subscription: EventSubscription = addOrientationChangeListener(
44
+ event => {
45
+ setScreenOrientation({
46
+ orientation: event.orientationInfo.orientation,
47
+ orientationLock: event.orientationLock,
48
+ });
49
+ },
50
+ );
51
+
52
+ onCleanup(() => {
53
+ subscription.remove();
54
+ });
55
+
56
+ return screenOrientation;
57
+ }
@@ -0,0 +1,6 @@
1
+ // @symbiote-native/screen-orientation/svelte: the Svelte entry over the framework-agnostic core —
2
+ // mirrors the lifecycle-bucket naming convention of adapters/svelte/src/runes (never
3
+ // `hooks`/`composables`, those are React's and Vue's terms).
4
+
5
+ export { useScreenOrientation } from './runes/use-screen-orientation.svelte';
6
+ export * from '../core';
@@ -0,0 +1,52 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core (core/screen-orientation.ts). Seeds the
2
+ // initial value with one-shot getOrientationAsync()/getOrientationLockAsync() calls before the
3
+ // first native event fires, mirroring packages/network's useNetworkState.
4
+ //
5
+ // `.svelte.ts` extension: runes ($state/$effect) only work there outside a `.svelte` component;
6
+ // `runes/` is Svelte's name for the lifecycle bucket (React's `hooks/`, Vue's `composables/`).
7
+ // Returns a boxed getter, not a bare `$state`: Svelte 5 reactivity is lexically scoped to the
8
+ // declaring module and doesn't survive being returned raw from a plain function, so the caller
9
+ // reads `.current` like unwrapping Vue's `Ref` via `.value`.
10
+ import {
11
+ addOrientationChangeListener,
12
+ getOrientationAsync,
13
+ getOrientationLockAsync,
14
+ Orientation,
15
+ OrientationLock,
16
+ type EventSubscription,
17
+ type ScreenOrientationState,
18
+ } from '../../core';
19
+
20
+ export function useScreenOrientation(): {
21
+ readonly current: ScreenOrientationState;
22
+ } {
23
+ let screenOrientation = $state<ScreenOrientationState>({
24
+ orientation: Orientation.UNKNOWN,
25
+ orientationLock: OrientationLock.UNKNOWN,
26
+ });
27
+
28
+ $effect(() => {
29
+ // Write-only touches of `screenOrientation`, so the effect has no dependency on it and runs
30
+ // once per mount - the twin of Vue's onMounted/onUnmounted pair.
31
+ Promise.all([getOrientationAsync(), getOrientationLockAsync()]).then(
32
+ ([orientation, orientationLock]) => {
33
+ screenOrientation = { orientation, orientationLock };
34
+ },
35
+ );
36
+ const subscription: EventSubscription = addOrientationChangeListener(
37
+ event => {
38
+ screenOrientation = {
39
+ orientation: event.orientationInfo.orientation,
40
+ orientationLock: event.orientationLock,
41
+ };
42
+ },
43
+ );
44
+ return () => subscription.remove();
45
+ });
46
+
47
+ return {
48
+ get current(): ScreenOrientationState {
49
+ return screenOrientation;
50
+ },
51
+ };
52
+ }
@@ -0,0 +1,6 @@
1
+ // Pulls in svelte's ambient global declarations ($state/$effect/...) for this package's tsc
2
+ // program. adapters/svelte gets these for free because render.ts does a real value import from
3
+ // 'svelte' (any file in a program importing a module loads its ambient globals for the whole
4
+ // program); this package has no such import, so a triple-slash reference does the same job
5
+ // explicitly rather than relying on an incidental side-effect.
6
+ /// <reference types="svelte" />
package/src/vue/index.ts CHANGED
@@ -1,26 +1,4 @@
1
1
  // @symbiote-native/screen-orientation/vue: the Vue entry over the framework-agnostic core.
2
2
 
3
3
  export { useScreenOrientation } from './composables/use-screen-orientation';
4
- export {
5
- lockAsync,
6
- lockPlatformAsync,
7
- unlockAsync,
8
- getOrientationAsync,
9
- getOrientationLockAsync,
10
- getPlatformOrientationLockAsync,
11
- supportsOrientationLockAsync,
12
- addOrientationChangeListener,
13
- removeOrientationChangeListeners,
14
- removeOrientationChangeListener,
15
- Orientation,
16
- OrientationLock,
17
- SizeClassIOS,
18
- WebOrientationLock,
19
- WebOrientation,
20
- type PlatformOrientationInfo,
21
- type ScreenOrientationInfo,
22
- type OrientationChangeEvent,
23
- type OrientationChangeListener,
24
- type ScreenOrientationState,
25
- type EventSubscription,
26
- } from '../core';
4
+ export * from '../core';