@momo-kits/foundation 0.163.1-beta.12 → 0.163.1-beta.14
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/Layout/Screen.tsx +47 -7
- package/package.json +1 -1
package/Layout/Screen.tsx
CHANGED
|
@@ -25,7 +25,12 @@ import {
|
|
|
25
25
|
View,
|
|
26
26
|
ViewProps,
|
|
27
27
|
} from 'react-native';
|
|
28
|
-
import
|
|
28
|
+
import Reanimated, {
|
|
29
|
+
useAnimatedKeyboard,
|
|
30
|
+
useAnimatedStyle,
|
|
31
|
+
useSharedValue,
|
|
32
|
+
withTiming,
|
|
33
|
+
} from 'react-native-reanimated';
|
|
29
34
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
30
35
|
import { ApplicationContext, ScreenContext } from '../Context';
|
|
31
36
|
import Navigation from '../Application/Navigation';
|
|
@@ -198,6 +203,24 @@ const Screen = forwardRef(
|
|
|
198
203
|
const insets = useSafeAreaInsets();
|
|
199
204
|
const heightHeader = useHeaderHeight();
|
|
200
205
|
|
|
206
|
+
/**
|
|
207
|
+
* On Android, the native root view already pads for the full IME inset
|
|
208
|
+
* (which itself includes the navigation bar's height) as soon as the
|
|
209
|
+
* keyboard shows. `useSafeAreaInsets()`'s own bottom recompute is JS-thread
|
|
210
|
+
* work (its own native listener, then a bridge crossing, then a React
|
|
211
|
+
* re-render) and always lands at least one frame after that native padding
|
|
212
|
+
* change, so any JS-driven correction (state + re-render, regardless of
|
|
213
|
+
* which event triggers it) has the same lag — the nav bar height gets
|
|
214
|
+
* counted twice for that window, visible as the footer overshooting
|
|
215
|
+
* before settling back down.
|
|
216
|
+
* `useAnimatedKeyboard()` sidesteps this: its worklet callback updates a
|
|
217
|
+
* shared value directly from the same native WindowInsetsAnimation
|
|
218
|
+
* callback driving the keyboard's own motion, on the UI thread, with no
|
|
219
|
+
* bridge crossing — so the footer's compensating style below can react
|
|
220
|
+
* in the same frame instead of a JS tick later.
|
|
221
|
+
*/
|
|
222
|
+
const keyboard = useAnimatedKeyboard();
|
|
223
|
+
|
|
201
224
|
/**
|
|
202
225
|
* Dual animation source:
|
|
203
226
|
* - `animatedValue` is a react-native `Animated.Value` driven natively by the
|
|
@@ -244,6 +267,25 @@ const Screen = forwardRef(
|
|
|
244
267
|
keyboardOffset = -bottomInset;
|
|
245
268
|
}
|
|
246
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Android only: while the keyboard is up, MainActivity's own native inset
|
|
272
|
+
* listener already accounts for the full space it needs (keyboard height
|
|
273
|
+
* plus nav bar) on the root view, so the footer here should only add its
|
|
274
|
+
* usual Spacing.S gap — not `bottomInset` on top, which would double-count
|
|
275
|
+
* the nav bar for as long as the keyboard is visible.
|
|
276
|
+
*
|
|
277
|
+
* `isAndroid` is read here (not inside the worklet) because referencing
|
|
278
|
+
* `Platform.OS` directly inside `useAnimatedStyle` captures the whole
|
|
279
|
+
* `Platform` module into the worklet closure — Reanimated then fails
|
|
280
|
+
* trying to serialize that module object for the UI thread.
|
|
281
|
+
*/
|
|
282
|
+
const isAndroid = Platform.OS === 'android';
|
|
283
|
+
const footerAnimatedStyle = useAnimatedStyle(() => {
|
|
284
|
+
const paddingBottom =
|
|
285
|
+
isAndroid && keyboard.height.value > 0 ? Spacing.S : bottomInset + Spacing.S;
|
|
286
|
+
return { paddingBottom };
|
|
287
|
+
});
|
|
288
|
+
|
|
247
289
|
/**
|
|
248
290
|
* inject params for screen tracking
|
|
249
291
|
*/
|
|
@@ -670,17 +712,15 @@ const Screen = forwardRef(
|
|
|
670
712
|
)}
|
|
671
713
|
|
|
672
714
|
{Footer && (
|
|
673
|
-
<View
|
|
715
|
+
<Reanimated.View
|
|
674
716
|
style={[
|
|
675
717
|
styles.shadow,
|
|
676
|
-
{
|
|
677
|
-
|
|
678
|
-
backgroundColor: theme.colors.background.surface,
|
|
679
|
-
},
|
|
718
|
+
{ backgroundColor: theme.colors.background.surface },
|
|
719
|
+
footerAnimatedStyle,
|
|
680
720
|
]}
|
|
681
721
|
>
|
|
682
722
|
<Section>{Footer}</Section>
|
|
683
|
-
</View>
|
|
723
|
+
</Reanimated.View>
|
|
684
724
|
)}
|
|
685
725
|
</KeyboardAvoidingView>
|
|
686
726
|
</View>
|