@symbiote-native/screen-orientation 3.0.1 → 3.0.3

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 (2) hide show
  1. package/README.md +43 -32
  2. package/package.json +15 -15
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @symbiote-native/screen-orientation
2
2
 
3
3
  Port of [`expo-screen-orientation`](https://docs.expo.dev/versions/latest/sdk/screen-orientation/)
4
- for [SymbioteNative](../../README.md) — orientation locking (`lockAsync`/`lockPlatformAsync`/
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
6
  subscription, reachable from every adapter (React, Vue, Svelte, Solid, Angular), not just
7
7
  React.
@@ -27,42 +27,42 @@ npx @symbiote-native/cli add --screen-orientation
27
27
  ```
28
28
 
29
29
  Either way: installs `@symbiote-native/screen-orientation` and wires the native autolinking
30
- automatically — see [`@symbiote-native/cli`](../cli).
30
+ automatically - see [`@symbiote-native/cli`](../cli).
31
31
 
32
32
  <details>
33
- <summary>Manual install (no CLI — installing and wiring native autolinking by hand)</summary>
33
+ <summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
34
34
 
35
35
  ```bash
36
36
  npm install @symbiote-native/screen-orientation
37
37
  ```
38
38
 
39
39
  Depends on `expo-screen-orientation` and `expo-modules-core` directly (regular dependencies,
40
- pinned to exact versions — never a caret range, since this package's `core/` is hand-ported against
40
+ pinned to exact versions - never a caret range, since this package's `core/` is hand-ported against
41
41
  one specific native API shape and a newer resolve could silently drift the two apart). Never
42
- install `expo-screen-orientation` yourself, and never add the `expo` package to this project — it
42
+ install `expo-screen-orientation` yourself, and never add the `expo` package to this project - it
43
43
  bundles its own Metro/Babel pipeline that conflicts with this project's own.
44
44
 
45
45
  ### Required one-time step: native autolinking wiring
46
46
 
47
47
  Unlike a plain RN native module, `expo-screen-orientation`'s native code is discovered by
48
- `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism — this needs wiring
48
+ `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism - this needs wiring
49
49
  into the native host app **once**, covering this package and every other `expo-modules-core`
50
50
  package (`@symbiote-native/network`, `@symbiote-native/device`, `@symbiote-native/sensors`, ...)
51
51
  with zero further changes:
52
52
 
53
53
  | Platform | Touches |
54
54
  | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
55
- | iOS | `ios/Podfile` — add `use_expo_modules!` |
56
- | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
57
- | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
58
- | 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) |
55
+ | iOS | `ios/Podfile` - add `use_expo_modules!` |
56
+ | iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
57
+ | Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
58
+ | 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) |
59
59
 
60
- Full mechanics — the Podfile pieces that normally ship inside the `expo` package, the `expo`
61
- peer-dependency exclusion list — live in the `symbiote-expo-native-module` skill. Reference
60
+ Full mechanics - the Podfile pieces that normally ship inside the `expo` package, the `expo`
61
+ peer-dependency exclusion list - live in the `symbiote-expo-native-module` skill. Reference
62
62
  implementation: `examples/expo-react/ios/Podfile` and
63
63
  `examples/expo-react/android/app/src/main/java/com/canaryexpo/MainApplication.kt`.
64
64
 
65
- No platform permission string is needed for screen-orientation's surface — locking and reading the
65
+ No platform permission string is needed for screen-orientation's surface - locking and reading the
66
66
  current orientation read/write system state with no runtime permission prompt on either platform.
67
67
 
68
68
  </details>
@@ -70,31 +70,31 @@ current orientation read/write system state with no runtime permission prompt on
70
70
  ## Shape
71
71
 
72
72
  ```
73
- src/core/ screen-orientation.ts — lock*/unlock/get* functions +
73
+ src/core/ screen-orientation.ts - lock*/unlock/get* functions +
74
74
  addOrientationChangeListener subscription. native-module.ts resolves the
75
- native module through expo-modules-core's requireNativeModule. types.ts —
75
+ native module through expo-modules-core's requireNativeModule. types.ts:
76
76
  Orientation/OrientationLock/SizeClassIOS/WebOrientationLock/WebOrientation
77
77
  enums, PlatformOrientationInfo, ScreenOrientationInfo,
78
78
  OrientationChangeEvent, hand-ported from ScreenOrientation.types.ts, plus
79
79
  ScreenOrientationState (the shape every adapter's wrapper returns).
80
- src/react/hooks/ @symbiote-native/screen-orientation/react — useScreenOrientation
81
- src/vue/composables/ @symbiote-native/screen-orientation/vue — useScreenOrientation (same name)
82
- src/svelte/runes/ @symbiote-native/screen-orientation/svelte — useScreenOrientation (same name)
83
- src/solid/primitives/ @symbiote-native/screen-orientation/solid — createScreenOrientation
80
+ src/react/hooks/ @symbiote-native/screen-orientation/react - useScreenOrientation
81
+ src/vue/composables/ @symbiote-native/screen-orientation/vue - useScreenOrientation (same name)
82
+ src/svelte/runes/ @symbiote-native/screen-orientation/svelte - useScreenOrientation (same name)
83
+ src/solid/primitives/ @symbiote-native/screen-orientation/solid - createScreenOrientation
84
84
  (returns an Accessor; Solid reserves `use*` for consuming existing state)
85
- src/angular/services/ @symbiote-native/screen-orientation/angular — ScreenOrientationService
85
+ src/angular/services/ @symbiote-native/screen-orientation/angular - ScreenOrientationService
86
86
  (`.connect()` returns a Signal)
87
87
  ```
88
88
 
89
89
  Each adapter's hook/composable/rune/primitive/service is a thin lifecycle wrapper (seed from
90
90
  one-shot `getOrientationAsync()`/`getOrientationLockAsync()` calls, subscribe to
91
- `addOrientationChangeListener`, unsubscribe on unmount) over the same `core` functions — the
91
+ `addOrientationChangeListener`, unsubscribe on unmount) over the same `core` functions - the
92
92
  subscription logic is written once and shared by all of them.
93
93
 
94
94
  ## Use it
95
95
 
96
96
  ```tsx
97
- // React — examples/expo-react/screens/ScreenOrientationScreen.tsx
97
+ // React - examples/expo-react/screens/ScreenOrientationScreen.tsx
98
98
  import {
99
99
  lockAsync,
100
100
  OrientationLock,
@@ -118,7 +118,7 @@ function ScreenOrientationScreen() {
118
118
  ```
119
119
 
120
120
  ```vue
121
- <!-- Vue — examples/expo-vue-sfc/screens/ScreenOrientationScreen.vue -->
121
+ <!-- Vue - examples/expo-vue-sfc/screens/ScreenOrientationScreen.vue -->
122
122
  <script setup lang="ts">
123
123
  import {
124
124
  lockAsync,
@@ -135,7 +135,7 @@ const screenOrientation = useScreenOrientation(); // Ref<ScreenOrientationState>
135
135
  ```
136
136
 
137
137
  ```svelte
138
- <!-- Svelte — examples/expo-svelte/screens/ScreenOrientationScreen.svelte -->
138
+ <!-- Svelte - examples/expo-svelte/screens/ScreenOrientationScreen.svelte -->
139
139
  <script lang="ts">
140
140
  import {
141
141
  lockAsync,
@@ -143,7 +143,7 @@ const screenOrientation = useScreenOrientation(); // Ref<ScreenOrientationState>
143
143
  } from '@symbiote-native/screen-orientation';
144
144
  import { useScreenOrientation } from '@symbiote-native/screen-orientation/svelte';
145
145
 
146
- // The rune hands back a boxed getter, so `.current` is what a `$derived` subscribes to —
146
+ // The rune hands back a boxed getter, so `.current` is what a `$derived` subscribes to:
147
147
  // Svelte's twin of unwrapping Vue's Ref via `.value`.
148
148
  const screenOrientation = useScreenOrientation();
149
149
  </script>
@@ -153,7 +153,7 @@ const screenOrientation = useScreenOrientation(); // Ref<ScreenOrientationState>
153
153
  ```
154
154
 
155
155
  ```ts
156
- // Angular — examples/expo-angular/src/screens/ScreenOrientationScreen.ts
156
+ // Angular - examples/expo-angular/src/screens/ScreenOrientationScreen.ts
157
157
  import { Component, inject } from '@angular/core';
158
158
  import { SYMBIOTE_ELEMENTS } from '@symbiote-native/angular';
159
159
  import { ScreenOrientationService } from '@symbiote-native/screen-orientation/angular';
@@ -169,7 +169,7 @@ export class ScreenOrientationScreen {
169
169
  ```
170
170
 
171
171
  ```tsx
172
- // Solid — the accessor is CALLED; a Solid component body runs once, so a snapshot would freeze.
172
+ // Solid - the accessor is CALLED; a Solid component body runs once, so a snapshot would freeze.
173
173
  import {
174
174
  lockAsync,
175
175
  OrientationLock,
@@ -214,7 +214,7 @@ Plus `Orientation` (enum: `UNKNOWN`/`PORTRAIT_UP`/`PORTRAIT_DOWN`/`LANDSCAPE_LEF
214
214
  `LANDSCAPE_RIGHT`), `OrientationLock` (enum: `DEFAULT`/`ALL`/`PORTRAIT`/`PORTRAIT_UP`/
215
215
  `PORTRAIT_DOWN`/`LANDSCAPE`/`LANDSCAPE_LEFT`/`LANDSCAPE_RIGHT`/`OTHER`/`UNKNOWN`), `SizeClassIOS`,
216
216
  `WebOrientationLock`, `WebOrientation`, `PlatformOrientationInfo`, `ScreenOrientationInfo`,
217
- `OrientationChangeEvent` — ported from upstream's `ScreenOrientation.types.ts`.
217
+ `OrientationChangeEvent` - ported from upstream's `ScreenOrientation.types.ts`.
218
218
 
219
219
  ```ts
220
220
  import {
@@ -239,16 +239,27 @@ returns an `Accessor<ScreenOrientationState>` and subscribes from its body rathe
239
239
  so nothing can slip between the seed and the subscription.
240
240
 
241
241
  **Note (Android):** `expo-screen-orientation` doesn't emit its own `expoDidUpdateDimensions`
242
- event on Android — the module piggybacks on RN's own `Dimensions.addEventListener('change', ...)`
242
+ event on Android - the module piggybacks on RN's own `Dimensions.addEventListener('change', ...)`
243
243
  there instead, re-fetching the lock and orientation on every dimensions change. iOS and web both
244
244
  subscribe to the native `expoDidUpdateDimensions` event directly.
245
245
 
246
+ ## Common questions
247
+
248
+ - **`lockAsync` ignored on tablets (Android 16+).** Locks are ignored on screens 600dp or wider;
249
+ design the layout to rotate and resize.
250
+ - **Lock only one screen?** Leave the app unlocked, `lockAsync` on that screen, `unlockAsync` on exit.
251
+ - **iPad.** Locking needs the app declared as full screen.
252
+ - **Initial orientation.** Upstream uses a config plugin; set it in the native project here.
253
+
254
+ Sources: [Expo docs: ScreenOrientation](https://docs.expo.dev/versions/latest/sdk/screen-orientation/),
255
+ [Android 17 will ignore your portrait lock](https://rorklab.net/en/articles/rork-dev/rork-android-17-large-screen-resizability-preparation).
256
+
246
257
  ## Test it
247
258
 
248
- No Fabric/Descriptor angle at all — screen-orientation is a pure async-function + `EventEmitter`
259
+ No Fabric/Descriptor angle at all - screen-orientation is a pure async-function + `EventEmitter`
249
260
  listener surface, never a view. Tests inject a fake native-module object in place of the real
250
261
  `requireNativeModule` resolution (`src/core/screen-orientation.test.ts`,
251
262
  `src/{react,vue,svelte,solid,angular}/**/*.test.{ts,tsx}`, `vitest`), the same pattern
252
- `@symbiote-native/network`/`@symbiote-native/device`/`@symbiote-native/sensors` use — no
253
- `installFabric()`, no ViewConfig. Native rendering itself is verified on-device — see the parent
263
+ `@symbiote-native/network`/`@symbiote-native/device`/`@symbiote-native/sensors` use - no
264
+ `installFabric()`, no ViewConfig. Native rendering itself is verified on-device - see the parent
254
265
  [README](../../README.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/screen-orientation",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
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
  "keywords": [
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "expo-screen-orientation": "57.0.1",
73
- "expo-modules-core": "57.0.5"
73
+ "expo-modules-core": "57.0.20"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@angular/core": ">=20",
@@ -80,12 +80,12 @@
80
80
  "solid-js": ">=1.9.0",
81
81
  "svelte": ">=5.56.0",
82
82
  "vue": ">=3.5.0",
83
- "@symbiote-native/angular": "^3.1.1",
84
- "@symbiote-native/engine": "^1.3.0",
85
- "@symbiote-native/react": "^3.0.3",
86
- "@symbiote-native/solid": "^3.0.3",
87
- "@symbiote-native/svelte": "^3.0.3",
88
- "@symbiote-native/vue": "^3.0.3"
83
+ "@symbiote-native/angular": "^3.2.0",
84
+ "@symbiote-native/engine": "^1.5.0",
85
+ "@symbiote-native/react": "^3.2.0",
86
+ "@symbiote-native/solid": "^3.1.0",
87
+ "@symbiote-native/svelte": "^3.1.0",
88
+ "@symbiote-native/vue": "^3.2.0"
89
89
  },
90
90
  "peerDependenciesMeta": {
91
91
  "@symbiote-native/angular": {
@@ -133,13 +133,13 @@
133
133
  "solid-js": "^1.9.14",
134
134
  "svelte": "^5.56.0",
135
135
  "typescript": "~6.0.0",
136
- "@symbiote-native/angular": "3.1.1",
137
- "@symbiote-native/engine": "1.3.0",
138
- "@symbiote-native/react": "3.0.3",
139
- "@symbiote-native/solid": "3.0.3",
140
- "@symbiote-native/svelte": "3.0.3",
141
- "@symbiote-native/test-utils": "0.4.3",
142
- "@symbiote-native/vue": "3.0.3"
136
+ "@symbiote-native/angular": "3.2.0",
137
+ "@symbiote-native/engine": "1.5.0",
138
+ "@symbiote-native/react": "3.2.0",
139
+ "@symbiote-native/solid": "3.1.0",
140
+ "@symbiote-native/svelte": "3.1.0",
141
+ "@symbiote-native/test-utils": "0.4.6",
142
+ "@symbiote-native/vue": "3.2.0"
143
143
  },
144
144
  "scripts": {
145
145
  "typecheck": "tsc --build",