@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.
- package/README.md +43 -32
- 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)
|
|
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
|
|
30
|
+
automatically - see [`@symbiote-native/cli`](../cli).
|
|
31
31
|
|
|
32
32
|
<details>
|
|
33
|
-
<summary>Manual install (no CLI
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
56
|
-
| iOS | `AppDelegate.swift`
|
|
57
|
-
| Android | `settings.gradle` / `app/build.gradle`
|
|
58
|
-
| Android | `MainApplication.kt`
|
|
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
|
|
61
|
-
peer-dependency exclusion list
|
|
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
|
|
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
|
|
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
|
|
81
|
-
src/vue/composables/ @symbiote-native/screen-orientation/vue
|
|
82
|
-
src/svelte/runes/ @symbiote-native/screen-orientation/svelte
|
|
83
|
-
src/solid/primitives/ @symbiote-native/screen-orientation/solid
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
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
|
|
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
|
|
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
|
|
253
|
-
`installFabric()`, no ViewConfig. Native rendering itself is verified on-device
|
|
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.
|
|
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.
|
|
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.
|
|
84
|
-
"@symbiote-native/engine": "^1.
|
|
85
|
-
"@symbiote-native/react": "^3.0
|
|
86
|
-
"@symbiote-native/solid": "^3.0
|
|
87
|
-
"@symbiote-native/svelte": "^3.0
|
|
88
|
-
"@symbiote-native/vue": "^3.0
|
|
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.
|
|
137
|
-
"@symbiote-native/engine": "1.
|
|
138
|
-
"@symbiote-native/react": "3.0
|
|
139
|
-
"@symbiote-native/solid": "3.0
|
|
140
|
-
"@symbiote-native/svelte": "3.0
|
|
141
|
-
"@symbiote-native/test-utils": "0.4.
|
|
142
|
-
"@symbiote-native/vue": "3.0
|
|
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",
|