@sigx/lynx-safe-area 0.4.3 → 0.4.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,MAAM,EAEX,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAiBjD,MAAM,MAAM,qBAAqB,GAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,GACnC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,GAC5D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,gBAAgB;;EA2F3B,CAAC;AAkDH,YAAY,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,MAAM,EAEX,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAwBjD,MAAM,MAAM,qBAAqB,GAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,GACnC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,GAC5D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,gBAAgB;;EAiI3B,CAAC;AAiDH,YAAY,EAAE,WAAW,EAAE,CAAC"}
package/dist/provider.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
2
- import { component, defineProvide, computed, signal, onMounted, onUnmounted, useSharedValue, useMainThreadRef, runOnMainThread, } from '@sigx/lynx';
2
+ import { component, effect, defineProvide, computed, signal, onMounted, onUnmounted, useSharedValue, useMainThreadRef, runOnMainThread, } from '@sigx/lynx';
3
3
  import { useSafeAreaContext } from './injectable.js';
4
4
  import { readGlobalSafeArea } from './globals.js';
5
5
  /**
@@ -13,6 +13,9 @@ import { readGlobalSafeArea } from './globals.js';
13
13
  * churned across Lynx releases).
14
14
  */
15
15
  export const SAFE_AREA_EVENT = 'safeAreaChanged';
16
+ // Unique host id per provider instance so the runtime `setProperty` call can
17
+ // target this provider's own view.
18
+ let safeAreaIdSeq = 0;
16
19
  /**
17
20
  * Mount once at the root of an app. Responsibilities:
18
21
  *
@@ -85,8 +88,12 @@ export const SafeAreaProvider = component(({ props, slots }) => {
85
88
  // Hold the elRef purely so consumers can extend the provider's host view
86
89
  // via the published CSS variables. Not used internally for any MT writes.
87
90
  const elRef = useMainThreadRef(null);
91
+ // Host id for the runtime `setProperty` CSS-variable application (below).
92
+ const hostId = `safe-area-${++safeAreaIdSeq}`;
88
93
  let listener;
89
94
  let emitter;
95
+ let varsEffect;
96
+ let insetsGen = 0;
90
97
  onMounted(() => {
91
98
  // `lynx` is a closure-injected identifier (provided by
92
99
  // `@lynx-js/runtime-wrapper-webpack-plugin`'s `__init_card_bundle__`
@@ -95,6 +102,39 @@ export const SafeAreaProvider = component(({ props, slots }) => {
95
102
  const lynxObj = typeof lynx !== 'undefined'
96
103
  ? lynx
97
104
  : undefined;
105
+ // Publish insets as real, inheritable CSS custom properties via the runtime
106
+ // `setProperty` API. Lynx does NOT honor custom properties declared through
107
+ // the inline `style` attribute, so `class="pt-[var(--sat)]"` consumers rely
108
+ // on this. On cold start the host view isn't queryable from the background
109
+ // thread the instant this runs, so retry on a short timer until it resolves
110
+ // (`insetsGen` drops a superseded retry). Reactive on `insets.value`.
111
+ const pushInsets = () => {
112
+ const i = insets.value;
113
+ if (!lynxObj?.getElementById)
114
+ return;
115
+ const vars = {
116
+ '--sat': `${i.top}px`,
117
+ '--sar': `${i.right}px`,
118
+ '--sab': `${i.bottom}px`,
119
+ '--sal': `${i.left}px`,
120
+ '--safe-area-keyboard': `${i.keyboard}px`,
121
+ };
122
+ const gen = ++insetsGen;
123
+ let tries = 0;
124
+ const attempt = () => {
125
+ if (gen !== insetsGen)
126
+ return;
127
+ const el = lynxObj.getElementById(hostId);
128
+ if (el) {
129
+ el.setProperty(vars);
130
+ return;
131
+ }
132
+ if (tries++ < 30)
133
+ setTimeout(attempt, 16);
134
+ };
135
+ attempt();
136
+ };
137
+ varsEffect = effect(() => { pushInsets(); });
98
138
  emitter = lynxObj?.getJSModule?.('GlobalEventEmitter');
99
139
  if (!emitter)
100
140
  return;
@@ -112,8 +152,11 @@ export const SafeAreaProvider = component(({ props, slots }) => {
112
152
  onUnmounted(() => {
113
153
  if (emitter && listener)
114
154
  emitter.removeListener(SAFE_AREA_EVENT, listener);
155
+ varsEffect?.stop();
156
+ varsEffect = undefined;
157
+ ++insetsGen; // cancel any pending setProperty retry
115
158
  });
116
- return () => (_jsx("view", { class: props.class, "main-thread:ref": elRef, style: cssVarStyle(insets.value, props.style), children: slots.default?.() }));
159
+ return () => (_jsx("view", { id: hostId, class: props.class, "main-thread:ref": elRef, style: rootStyle(props.style), children: slots.default?.() }));
117
160
  });
118
161
  function normaliseInsets(raw, fallback) {
119
162
  if (!raw || typeof raw !== 'object')
@@ -132,22 +175,22 @@ function normaliseInsets(raw, fallback) {
132
175
  function numOr(v, fallback) {
133
176
  return typeof v === 'number' && Number.isFinite(v) ? v : fallback;
134
177
  }
135
- function cssVarStyle(i, user) {
178
+ function rootStyle(user) {
136
179
  // Defaults make the provider fill the device viewport and act as a
137
180
  // flex-column ancestor. Without these, every Lynx app re-rolls inline
138
181
  // `style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}`
139
182
  // because `<view>` defaults to auto height and the lynx-tailwind
140
183
  // preset (as of 0.4.0) doesn't ship an `h-screen` rule. Consumers can
141
184
  // override any of these via `props.style`.
185
+ //
186
+ // The safe-area CSS variables (`--sat`/`--sar`/`--sab`/`--sal`/
187
+ // `--safe-area-keyboard`) are NOT set here: Lynx ignores custom properties
188
+ // declared via inline `style`. They're published via the runtime
189
+ // `setProperty` API in the provider's mount effect instead.
142
190
  const base = {
143
191
  height: '100vh',
144
192
  display: 'flex',
145
193
  flexDirection: 'column',
146
- '--sat': `${i.top}px`,
147
- '--sar': `${i.right}px`,
148
- '--sab': `${i.bottom}px`,
149
- '--sal': `${i.left}px`,
150
- '--safe-area-keyboard': `${i.keyboard}px`,
151
194
  };
152
195
  return user ? { ...base, ...user } : base;
153
196
  }
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigx/lynx-safe-area",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Safe area insets (notch, home indicator, status bar, keyboard) for sigx-lynx",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,15 +31,15 @@
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
33
  "@sigx/reactivity": "^0.4.8",
34
- "@sigx/lynx": "^0.4.3",
35
- "@sigx/lynx-runtime-internal": "^0.4.3"
34
+ "@sigx/lynx": "^0.4.5",
35
+ "@sigx/lynx-runtime-internal": "^0.4.5"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@typescript/native-preview": "7.0.0-dev.20260521.1",
39
39
  "typescript": "^6.0.3",
40
- "@sigx/lynx-runtime-main": "^0.4.3",
41
- "@sigx/lynx-plugin": "^0.4.3",
42
- "@sigx/lynx-testing": "^0.4.3"
40
+ "@sigx/lynx-runtime-main": "^0.4.5",
41
+ "@sigx/lynx-plugin": "^0.4.5",
42
+ "@sigx/lynx-testing": "^0.4.5"
43
43
  },
44
44
  "repository": {
45
45
  "type": "git",
package/src/provider.tsx CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  component,
3
+ effect,
3
4
  defineProvide,
4
5
  computed,
5
6
  signal,
@@ -35,6 +36,9 @@ interface GlobalEventEmitterLike {
35
36
 
36
37
  interface LynxLike {
37
38
  getJSModule?: (name: string) => GlobalEventEmitterLike | undefined;
39
+ getElementById?: (
40
+ id: string,
41
+ ) => { setProperty(props: Record<string, string>): void } | null;
38
42
  }
39
43
 
40
44
  // Closure-injected identifier provided by
@@ -43,6 +47,10 @@ interface LynxLike {
43
47
  // have to depend on lynx-runtime-internal just for the ambient.
44
48
  declare const lynx: unknown | undefined;
45
49
 
50
+ // Unique host id per provider instance so the runtime `setProperty` call can
51
+ // target this provider's own view.
52
+ let safeAreaIdSeq = 0;
53
+
46
54
  export type SafeAreaProviderProps =
47
55
  & Define.Prop<'class', string, false>
48
56
  & Define.Prop<'style', Record<string, string | number>, false>
@@ -127,8 +135,13 @@ export const SafeAreaProvider = component<SafeAreaProviderProps>(({ props, slots
127
135
  // via the published CSS variables. Not used internally for any MT writes.
128
136
  const elRef = useMainThreadRef<MainThread.Element | null>(null);
129
137
 
138
+ // Host id for the runtime `setProperty` CSS-variable application (below).
139
+ const hostId = `safe-area-${++safeAreaIdSeq}`;
140
+
130
141
  let listener: ((...a: unknown[]) => void) | undefined;
131
142
  let emitter: GlobalEventEmitterLike | undefined;
143
+ let varsEffect: { stop: () => void } | undefined;
144
+ let insetsGen = 0;
132
145
 
133
146
  onMounted(() => {
134
147
  // `lynx` is a closure-injected identifier (provided by
@@ -138,6 +151,35 @@ export const SafeAreaProvider = component<SafeAreaProviderProps>(({ props, slots
138
151
  const lynxObj: LynxLike | undefined = typeof lynx !== 'undefined'
139
152
  ? (lynx as unknown as LynxLike)
140
153
  : undefined;
154
+
155
+ // Publish insets as real, inheritable CSS custom properties via the runtime
156
+ // `setProperty` API. Lynx does NOT honor custom properties declared through
157
+ // the inline `style` attribute, so `class="pt-[var(--sat)]"` consumers rely
158
+ // on this. On cold start the host view isn't queryable from the background
159
+ // thread the instant this runs, so retry on a short timer until it resolves
160
+ // (`insetsGen` drops a superseded retry). Reactive on `insets.value`.
161
+ const pushInsets = (): void => {
162
+ const i = insets.value;
163
+ if (!lynxObj?.getElementById) return;
164
+ const vars: Record<string, string> = {
165
+ '--sat': `${i.top}px`,
166
+ '--sar': `${i.right}px`,
167
+ '--sab': `${i.bottom}px`,
168
+ '--sal': `${i.left}px`,
169
+ '--safe-area-keyboard': `${i.keyboard}px`,
170
+ };
171
+ const gen = ++insetsGen;
172
+ let tries = 0;
173
+ const attempt = (): void => {
174
+ if (gen !== insetsGen) return;
175
+ const el = lynxObj!.getElementById!(hostId);
176
+ if (el) { el.setProperty(vars); return; }
177
+ if (tries++ < 30) setTimeout(attempt, 16);
178
+ };
179
+ attempt();
180
+ };
181
+ varsEffect = effect(() => { pushInsets(); });
182
+
141
183
  emitter = lynxObj?.getJSModule?.('GlobalEventEmitter');
142
184
  if (!emitter) return;
143
185
  listener = (raw: unknown) => {
@@ -154,13 +196,17 @@ export const SafeAreaProvider = component<SafeAreaProviderProps>(({ props, slots
154
196
 
155
197
  onUnmounted(() => {
156
198
  if (emitter && listener) emitter.removeListener(SAFE_AREA_EVENT, listener);
199
+ varsEffect?.stop();
200
+ varsEffect = undefined;
201
+ ++insetsGen; // cancel any pending setProperty retry
157
202
  });
158
203
 
159
204
  return () => (
160
205
  <view
206
+ id={hostId}
161
207
  class={props.class}
162
208
  main-thread:ref={elRef}
163
- style={cssVarStyle(insets.value, props.style)}
209
+ style={rootStyle(props.style)}
164
210
  >
165
211
  {slots.default?.()}
166
212
  </view>
@@ -191,8 +237,7 @@ function numOr(v: unknown, fallback: number): number {
191
237
  return typeof v === 'number' && Number.isFinite(v) ? v : fallback;
192
238
  }
193
239
 
194
- function cssVarStyle(
195
- i: EdgeInsets,
240
+ function rootStyle(
196
241
  user: Record<string, string | number> | undefined,
197
242
  ): Record<string, string | number> {
198
243
  // Defaults make the provider fill the device viewport and act as a
@@ -201,15 +246,15 @@ function cssVarStyle(
201
246
  // because `<view>` defaults to auto height and the lynx-tailwind
202
247
  // preset (as of 0.4.0) doesn't ship an `h-screen` rule. Consumers can
203
248
  // override any of these via `props.style`.
249
+ //
250
+ // The safe-area CSS variables (`--sat`/`--sar`/`--sab`/`--sal`/
251
+ // `--safe-area-keyboard`) are NOT set here: Lynx ignores custom properties
252
+ // declared via inline `style`. They're published via the runtime
253
+ // `setProperty` API in the provider's mount effect instead.
204
254
  const base: Record<string, string | number> = {
205
255
  height: '100vh',
206
256
  display: 'flex',
207
257
  flexDirection: 'column',
208
- '--sat': `${i.top}px`,
209
- '--sar': `${i.right}px`,
210
- '--sab': `${i.bottom}px`,
211
- '--sal': `${i.left}px`,
212
- '--safe-area-keyboard': `${i.keyboard}px`,
213
258
  };
214
259
  return user ? { ...base, ...user } : base;
215
260
  }