@momo-kits/foundation 0.167.1-duotest.2 → 0.167.1
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/Application/BottomSheet.tsx +14 -115
- package/Application/BottomTab/BottomTabBar.tsx +3 -6
- package/Application/BottomTab/index.tsx +135 -162
- package/Application/Components/HeaderExtendHeader.tsx +28 -75
- package/Application/Components/HeaderLeft.tsx +0 -38
- package/Application/Components/HeaderRight.tsx +9 -142
- package/Application/Components/HeaderTitle.tsx +7 -43
- package/Application/Components/SearchHeader.tsx +15 -22
- package/Application/ModalScreen.tsx +2 -16
- package/Application/NavigationContainer.tsx +38 -22
- package/Application/Navigator.ts +3 -1
- package/Application/StackScreen.tsx +9 -63
- package/Application/types.ts +1 -27
- package/Application/utils.tsx +6 -242
- package/Consts/theme.ts +4 -3
- package/Input/Input.tsx +4 -3
- package/Input/InputMoney.tsx +8 -5
- package/Input/InputPhoneNumber.tsx +4 -3
- package/Input/InputSearch.tsx +4 -3
- package/Input/InputTextArea.tsx +4 -3
- package/Layout/Card.tsx +26 -8
- package/Layout/FloatingButton.tsx +3 -3
- package/Layout/GridSystem.tsx +137 -0
- package/Layout/Item.tsx +10 -1
- package/Layout/Screen.tsx +52 -199
- package/Layout/Section.tsx +18 -5
- package/Layout/index.ts +4 -4
- package/Layout/styles.ts +0 -5
- package/Layout/utils.ts +5 -465
- package/Popup/PopupNotify.tsx +22 -33
- package/Popup/PopupPromotion.tsx +8 -20
- package/Text/utils.ts +2 -1
- package/package.json +2 -3
- package/Application/BottomTab/DuoBarCompression.tsx +0 -135
- package/Application/BottomTab/DuoTabBar.tsx +0 -462
- package/Application/Components/DuoGlassBackground.tsx +0 -179
- package/Application/Components/DuoQuickReturnHeader.tsx +0 -42
- package/Application/Components/OptionalGlassView.ts +0 -11
- package/Application/Components/OptionalScrollObserver.ts +0 -12
- package/Application/Components/SideBarButton.tsx +0 -139
- package/Application/device.ts +0 -29
- package/Layout/ReservedRegions.tsx +0 -47
- package/Popup/utils.ts +0 -32
package/Layout/Screen.tsx
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
ScrollViewProps,
|
|
22
22
|
StatusBar,
|
|
23
23
|
StatusBarStyle,
|
|
24
|
+
useWindowDimensions,
|
|
24
25
|
View,
|
|
25
26
|
ViewProps,
|
|
26
27
|
} from 'react-native';
|
|
@@ -42,12 +43,8 @@ import { FloatingButton, FloatingButtonProps } from './FloatingButton';
|
|
|
42
43
|
import styles from './styles';
|
|
43
44
|
import { HeaderType } from './types';
|
|
44
45
|
import { InputRef } from '../Input';
|
|
45
|
-
import {
|
|
46
|
-
|
|
47
|
-
getOptions,
|
|
48
|
-
useDuoQuickReturn,
|
|
49
|
-
} from '../Application/utils';
|
|
50
|
-
import { getHeaderMargin, useScreenLayout, validateChildren } from './utils';
|
|
46
|
+
import { exportHeaderTitle, getOptions } from '../Application/utils';
|
|
47
|
+
import { validateChildren } from './utils';
|
|
51
48
|
import Section from './Section';
|
|
52
49
|
import {
|
|
53
50
|
HeaderBackground,
|
|
@@ -56,11 +53,6 @@ import {
|
|
|
56
53
|
HeaderTitle,
|
|
57
54
|
SearchHeader,
|
|
58
55
|
} from '../Application';
|
|
59
|
-
import {
|
|
60
|
-
DuoGlassBackground,
|
|
61
|
-
DuoScrollGradient,
|
|
62
|
-
} from '../Application/Components/DuoGlassBackground';
|
|
63
|
-
import { useDuoTabBarInset } from '../Application/BottomTab/DuoTabBar';
|
|
64
56
|
|
|
65
57
|
export interface ScreenProps extends ViewProps {
|
|
66
58
|
/**
|
|
@@ -126,8 +118,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
126
118
|
layoutOffset?: -8 | -24 | -56 | number;
|
|
127
119
|
|
|
128
120
|
/**
|
|
129
|
-
* Optional. Width of the right header.
|
|
130
|
-
* iPhone Duo floats the toolkit into its side bar.
|
|
121
|
+
* Optional. Width of the right header.
|
|
131
122
|
*/
|
|
132
123
|
headerRightWidth?: 0 | 73 | 110 | number;
|
|
133
124
|
|
|
@@ -196,7 +187,7 @@ const Screen = forwardRef(
|
|
|
196
187
|
footerComponent: Footer,
|
|
197
188
|
marginFooter = true,
|
|
198
189
|
layoutOffset = -56,
|
|
199
|
-
headerRightWidth,
|
|
190
|
+
headerRightWidth = 73,
|
|
200
191
|
backgroundColor,
|
|
201
192
|
headerType = 'default',
|
|
202
193
|
floatingButtonProps,
|
|
@@ -213,8 +204,8 @@ const Screen = forwardRef(
|
|
|
213
204
|
ref: any,
|
|
214
205
|
) => {
|
|
215
206
|
const screenRef = useRef<View | ScrollView>(null);
|
|
216
|
-
const
|
|
217
|
-
const { theme } = useContext(ApplicationContext);
|
|
207
|
+
const { width: widthDevice } = useWindowDimensions();
|
|
208
|
+
const { theme, navigator } = useContext(ApplicationContext);
|
|
218
209
|
const screen: any = useContext(ScreenContext);
|
|
219
210
|
const insets = useSafeAreaInsets();
|
|
220
211
|
const frame = useSafeAreaFrame();
|
|
@@ -254,37 +245,15 @@ const Screen = forwardRef(
|
|
|
254
245
|
}, [customAnimatedValue, internalShared]);
|
|
255
246
|
|
|
256
247
|
const currentTint = useRef<string | undefined>(undefined);
|
|
257
|
-
|
|
248
|
+
|
|
258
249
|
const isTab = !!screen?.bottomTab;
|
|
259
|
-
// Duo floating tab bar overlays the tab content instead of taking layout space
|
|
260
|
-
const duoTabInset = useDuoTabBarInset();
|
|
261
250
|
|
|
262
251
|
let handleScroll;
|
|
263
252
|
let Component: any = View;
|
|
264
253
|
|
|
265
|
-
const bottomInset =
|
|
266
|
-
Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
|
|
267
|
-
const hasSideBar = !!layout.sideBar;
|
|
268
|
-
// iPhone Duo: content scrolls under a glass header instead of starting below it
|
|
269
|
-
const useDuoGlass =
|
|
270
|
-
hasSideBar &&
|
|
271
|
-
(headerType === 'default' || headerType === 'extended') &&
|
|
272
|
-
!animatedHeader &&
|
|
273
|
-
!inputSearchProps;
|
|
274
|
-
|
|
275
|
-
// iPhone Duo: the header leaves with the content and returns on a reverse scroll
|
|
276
|
-
const useQuickReturn =
|
|
277
|
-
hasSideBar && scrollable && (useDuoGlass || !!animatedHeader);
|
|
278
|
-
const { quickReturnOptions, snap: snapQuickReturnHeader } =
|
|
279
|
-
useDuoQuickReturn(sharedValue, useQuickReturn, heightHeader);
|
|
280
|
-
|
|
254
|
+
const bottomInset = Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
|
|
281
255
|
let keyboardOffset = heightHeader - bottomInset;
|
|
282
|
-
if (
|
|
283
|
-
headerType === 'extended' ||
|
|
284
|
-
animatedHeader ||
|
|
285
|
-
inputSearchProps ||
|
|
286
|
-
useDuoGlass
|
|
287
|
-
) {
|
|
256
|
+
if (headerType === 'extended' || animatedHeader || inputSearchProps) {
|
|
288
257
|
keyboardOffset = -bottomInset;
|
|
289
258
|
}
|
|
290
259
|
|
|
@@ -292,12 +261,6 @@ const Screen = forwardRef(
|
|
|
292
261
|
* inject params for screen tracking
|
|
293
262
|
*/
|
|
294
263
|
screen?.onSetParams?.(trackingParams);
|
|
295
|
-
// the screen drives its header, the stack screen's scroll observer stays off
|
|
296
|
-
screen?.claimHeader?.();
|
|
297
|
-
useEffect(() => {
|
|
298
|
-
screen?.syncHeader?.();
|
|
299
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
300
|
-
}, []);
|
|
301
264
|
|
|
302
265
|
/**
|
|
303
266
|
* export options for screen
|
|
@@ -317,13 +280,9 @@ const Screen = forwardRef(
|
|
|
317
280
|
|
|
318
281
|
case 'extended':
|
|
319
282
|
options = {
|
|
320
|
-
...quickReturnOptions,
|
|
321
283
|
headerShown: true,
|
|
322
284
|
headerTransparent: true,
|
|
323
|
-
headerBackground: () =>
|
|
324
|
-
hasSideBar ? (
|
|
325
|
-
<DuoGlassBackground animatedValue={sharedValue} />
|
|
326
|
-
) : null,
|
|
285
|
+
headerBackground: () => null,
|
|
327
286
|
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
328
287
|
};
|
|
329
288
|
if (inputSearchProps) {
|
|
@@ -346,19 +305,6 @@ const Screen = forwardRef(
|
|
|
346
305
|
break;
|
|
347
306
|
|
|
348
307
|
default:
|
|
349
|
-
if (hasSideBar && !inputSearchProps) {
|
|
350
|
-
options = {
|
|
351
|
-
...quickReturnOptions,
|
|
352
|
-
headerTransparent: true,
|
|
353
|
-
headerTintColor: Colors.black_17,
|
|
354
|
-
headerShown: true,
|
|
355
|
-
headerBackground: () => (
|
|
356
|
-
<DuoGlassBackground animatedValue={sharedValue} />
|
|
357
|
-
),
|
|
358
|
-
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
359
|
-
};
|
|
360
|
-
break;
|
|
361
|
-
}
|
|
362
308
|
options = {
|
|
363
309
|
headerTransparent: false,
|
|
364
310
|
headerTintColor: Colors.black_17,
|
|
@@ -393,7 +339,7 @@ const Screen = forwardRef(
|
|
|
393
339
|
}
|
|
394
340
|
}
|
|
395
341
|
|
|
396
|
-
navigation?.instance?.setOptions(
|
|
342
|
+
navigation?.instance?.setOptions(options);
|
|
397
343
|
},
|
|
398
344
|
[
|
|
399
345
|
gradientColor,
|
|
@@ -402,8 +348,6 @@ const Screen = forwardRef(
|
|
|
402
348
|
navigation?.instance,
|
|
403
349
|
sharedValue,
|
|
404
350
|
useShadowHeader,
|
|
405
|
-
hasSideBar,
|
|
406
|
-
quickReturnOptions,
|
|
407
351
|
],
|
|
408
352
|
);
|
|
409
353
|
|
|
@@ -419,26 +363,18 @@ const Screen = forwardRef(
|
|
|
419
363
|
}
|
|
420
364
|
|
|
421
365
|
options = {
|
|
422
|
-
...quickReturnOptions,
|
|
423
366
|
headerTintColor: currentTint.current ?? Colors.black_17,
|
|
424
367
|
headerTransparent: true,
|
|
425
|
-
headerBackground: (props: any) =>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
animatedValue={sharedValue}
|
|
436
|
-
useGradient={false}
|
|
437
|
-
useShadowHeader={useShadowHeader}
|
|
438
|
-
headerBackground={headerBackground}
|
|
439
|
-
gradientColor={gradientColor}
|
|
440
|
-
/>
|
|
441
|
-
),
|
|
368
|
+
headerBackground: (props: any) => (
|
|
369
|
+
<HeaderBackground
|
|
370
|
+
{...props}
|
|
371
|
+
animatedValue={sharedValue}
|
|
372
|
+
useGradient={false}
|
|
373
|
+
useShadowHeader={useShadowHeader}
|
|
374
|
+
headerBackground={headerBackground}
|
|
375
|
+
gradientColor={gradientColor}
|
|
376
|
+
/>
|
|
377
|
+
),
|
|
442
378
|
headerTitle: (props: any) => {
|
|
443
379
|
return <HeaderTitle {...props} />;
|
|
444
380
|
},
|
|
@@ -459,10 +395,6 @@ const Screen = forwardRef(
|
|
|
459
395
|
navigation?.instance,
|
|
460
396
|
sharedValue,
|
|
461
397
|
useShadowHeader,
|
|
462
|
-
hasSideBar,
|
|
463
|
-
layoutOffset,
|
|
464
|
-
heightHeader,
|
|
465
|
-
quickReturnOptions,
|
|
466
398
|
],
|
|
467
399
|
);
|
|
468
400
|
|
|
@@ -486,24 +418,14 @@ const Screen = forwardRef(
|
|
|
486
418
|
),
|
|
487
419
|
};
|
|
488
420
|
|
|
489
|
-
navigation?.instance?.setOptions(
|
|
421
|
+
navigation?.instance?.setOptions(options);
|
|
490
422
|
}, [navigation?.instance, sharedValue]);
|
|
491
423
|
|
|
492
424
|
/**
|
|
493
425
|
* export search header
|
|
494
426
|
*/
|
|
495
427
|
const setSearchHeader = (params: SearchHeaderProps) => {
|
|
496
|
-
|
|
497
|
-
let searchLeft = Spacing.M;
|
|
498
|
-
if (layout.sideBar) {
|
|
499
|
-
// back floats in the side bar: the search spans the content width
|
|
500
|
-
searchWidth = layout.contentWidth - Spacing.M * 2;
|
|
501
|
-
searchLeft = Spacing.M - getHeaderMargin(layout.width);
|
|
502
|
-
}
|
|
503
|
-
if (layout.statusBarClearance) {
|
|
504
|
-
searchWidth -=
|
|
505
|
-
layout.statusBarClearance.left + layout.statusBarClearance.right;
|
|
506
|
-
}
|
|
428
|
+
const searchWidth = widthDevice - 24;
|
|
507
429
|
const options: StackNavigationOptions = {
|
|
508
430
|
headerRight: undefined,
|
|
509
431
|
headerTitleContainerStyle: {
|
|
@@ -515,10 +437,10 @@ const Screen = forwardRef(
|
|
|
515
437
|
marginHorizontal: 0,
|
|
516
438
|
marginVertical: 0,
|
|
517
439
|
margin: 0,
|
|
518
|
-
left:
|
|
440
|
+
left: Spacing.M,
|
|
519
441
|
},
|
|
520
442
|
headerLeft: (props: any) =>
|
|
521
|
-
params?.hiddenBack ? null : <HeaderLeft {...props}
|
|
443
|
+
params?.hiddenBack ? null : <HeaderLeft {...props} />,
|
|
522
444
|
headerTitle: () => (
|
|
523
445
|
<SearchHeader {...params} animatedValue={sharedValue} />
|
|
524
446
|
),
|
|
@@ -614,16 +536,12 @@ const Screen = forwardRef(
|
|
|
614
536
|
);
|
|
615
537
|
}
|
|
616
538
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
scrollViewProps?.onMomentumScrollEnd?.(e);
|
|
622
|
-
};
|
|
623
|
-
|
|
539
|
+
/**
|
|
540
|
+
* handle scroll end
|
|
541
|
+
* @param e
|
|
542
|
+
*/
|
|
624
543
|
const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
625
544
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
626
|
-
snapQuickReturnHeader(offsetY);
|
|
627
545
|
if (inputSearchProps && offsetY < 100 && offsetY > 0) {
|
|
628
546
|
Animated.timing(animatedValue.current, {
|
|
629
547
|
toValue: 0,
|
|
@@ -673,8 +591,6 @@ const Screen = forwardRef(
|
|
|
673
591
|
key={`ScreenItem${index}`}
|
|
674
592
|
style={{
|
|
675
593
|
marginTop: space,
|
|
676
|
-
marginLeft: layout.insetLeft,
|
|
677
|
-
marginRight: layout.insetRight,
|
|
678
594
|
flex: item.props?.expanded ? 1 : undefined,
|
|
679
595
|
}}
|
|
680
596
|
onLayout={item.props?.onLayout}
|
|
@@ -695,8 +611,6 @@ const Screen = forwardRef(
|
|
|
695
611
|
key={`ScreenItem`}
|
|
696
612
|
style={{
|
|
697
613
|
marginTop: space,
|
|
698
|
-
marginLeft: layout.insetLeft,
|
|
699
|
-
marginRight: layout.insetRight,
|
|
700
614
|
flex: item?.props?.expanded ? 1 : undefined,
|
|
701
615
|
}}
|
|
702
616
|
onLayout={item?.props?.onLayout}
|
|
@@ -723,15 +637,6 @@ const Screen = forwardRef(
|
|
|
723
637
|
return newHeight;
|
|
724
638
|
};
|
|
725
639
|
|
|
726
|
-
// without the grid, the content container keeps clear of the horizontal insets.
|
|
727
|
-
// Only set when there are insets, so a caller's paddingHorizontal is never overridden.
|
|
728
|
-
const hasContentInset = layout.insetLeft > 0 || layout.insetRight > 0;
|
|
729
|
-
const contentInsetStyle = !useGridLayout &&
|
|
730
|
-
hasContentInset && {
|
|
731
|
-
paddingLeft: layout.insetLeft,
|
|
732
|
-
paddingRight: layout.insetRight,
|
|
733
|
-
};
|
|
734
|
-
|
|
735
640
|
return (
|
|
736
641
|
<View
|
|
737
642
|
style={[
|
|
@@ -744,36 +649,21 @@ const Screen = forwardRef(
|
|
|
744
649
|
},
|
|
745
650
|
]}
|
|
746
651
|
>
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
heightHeader={heightHeader}
|
|
760
|
-
headerRightWidth={headerRightWidth}
|
|
761
|
-
animatedValue={sharedValue}
|
|
762
|
-
inputSearchProps={inputSearchProps}
|
|
763
|
-
navigation={navigation}
|
|
764
|
-
inputSearchRef={inputSearchRef}
|
|
765
|
-
useShadowHeader={useShadowHeader}
|
|
766
|
-
gradientColor={gradientColor}
|
|
767
|
-
headerBackground={headerBackground}
|
|
768
|
-
/>
|
|
769
|
-
)}
|
|
652
|
+
<HeaderExtendHeader
|
|
653
|
+
headerType={headerType}
|
|
654
|
+
heightHeader={heightHeader}
|
|
655
|
+
headerRightWidth={headerRightWidth}
|
|
656
|
+
animatedValue={sharedValue}
|
|
657
|
+
inputSearchProps={inputSearchProps}
|
|
658
|
+
navigation={navigation}
|
|
659
|
+
inputSearchRef={inputSearchRef}
|
|
660
|
+
useShadowHeader={useShadowHeader}
|
|
661
|
+
gradientColor={gradientColor}
|
|
662
|
+
headerBackground={headerBackground}
|
|
663
|
+
/>
|
|
770
664
|
|
|
771
665
|
<KeyboardAvoidingView
|
|
772
|
-
style={
|
|
773
|
-
Styles.flex,
|
|
774
|
-
useDuoGlass &&
|
|
775
|
-
(!scrollable || !!Header) && { paddingTop: heightHeader },
|
|
776
|
-
]}
|
|
666
|
+
style={Styles.flex}
|
|
777
667
|
enabled={enableKeyboardAvoidingView}
|
|
778
668
|
keyboardVerticalOffset={keyboardVerticalOffset ?? keyboardOffset}
|
|
779
669
|
behavior={Platform.select({
|
|
@@ -789,24 +679,10 @@ const Screen = forwardRef(
|
|
|
789
679
|
showsVerticalScrollIndicator={false}
|
|
790
680
|
onScroll={handleScroll}
|
|
791
681
|
onScrollEndDrag={handleScrollEnd}
|
|
792
|
-
onMomentumScrollEnd={handleMomentumScrollEnd}
|
|
793
682
|
scrollEventThrottle={16}
|
|
794
|
-
style={[
|
|
795
|
-
Styles.flex,
|
|
796
|
-
!scrollable && contentInsetStyle,
|
|
797
|
-
!scrollable &&
|
|
798
|
-
!Footer &&
|
|
799
|
-
isTab &&
|
|
800
|
-
!!duoTabInset && { paddingBottom: duoTabInset },
|
|
801
|
-
]}
|
|
683
|
+
style={[Styles.flex]}
|
|
802
684
|
contentContainerStyle={[
|
|
803
685
|
scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
|
|
804
|
-
scrollable &&
|
|
805
|
-
!Footer &&
|
|
806
|
-
isTab &&
|
|
807
|
-
!!duoTabInset && { paddingBottom: duoTabInset },
|
|
808
|
-
scrollable && contentInsetStyle,
|
|
809
|
-
useDuoGlass && !Header && { paddingTop: heightHeader },
|
|
810
686
|
scrollViewProps?.contentContainerStyle,
|
|
811
687
|
]}
|
|
812
688
|
>
|
|
@@ -816,51 +692,28 @@ const Screen = forwardRef(
|
|
|
816
692
|
</Component>
|
|
817
693
|
|
|
818
694
|
{floatingButtonProps && (
|
|
819
|
-
<View
|
|
820
|
-
style={{
|
|
821
|
-
marginLeft: layout.insetLeft,
|
|
822
|
-
marginRight: layout.insetRight,
|
|
823
|
-
}}
|
|
824
|
-
>
|
|
695
|
+
<View>
|
|
825
696
|
<FloatingButton
|
|
826
697
|
{...floatingButtonProps}
|
|
827
698
|
animatedValue={sharedValue}
|
|
828
|
-
bottom={
|
|
829
|
-
Footer || isTab
|
|
830
|
-
? 12 + (Footer ? 0 : duoTabInset)
|
|
831
|
-
: bottomInset + Spacing.S
|
|
832
|
-
}
|
|
699
|
+
bottom={Footer || isTab ? 12 : bottomInset + Spacing.S}
|
|
833
700
|
/>
|
|
834
701
|
</View>
|
|
835
702
|
)}
|
|
836
703
|
|
|
837
704
|
{Footer && (
|
|
838
|
-
// with side insets, the clip keeps the shadow off the side bar, only the top one shows
|
|
839
705
|
<View
|
|
840
|
-
pointerEvents={'box-none'}
|
|
841
706
|
style={[
|
|
842
|
-
|
|
707
|
+
styles.shadow,
|
|
843
708
|
{
|
|
844
|
-
|
|
845
|
-
|
|
709
|
+
paddingBottom: bottomInset + Spacing.S,
|
|
710
|
+
backgroundColor: theme.colors.background.surface,
|
|
846
711
|
},
|
|
847
712
|
]}
|
|
848
713
|
>
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
{
|
|
853
|
-
paddingBottom:
|
|
854
|
-
(isTab && duoTabInset ? duoTabInset : bottomInset) +
|
|
855
|
-
Spacing.S,
|
|
856
|
-
backgroundColor: theme.colors.background.surface,
|
|
857
|
-
},
|
|
858
|
-
]}
|
|
859
|
-
>
|
|
860
|
-
{/* The footer inset is a caller decision, not a platform one — a footer
|
|
861
|
-
that carries its own horizontal padding passes `marginFooter={false}`. */}
|
|
862
|
-
<Section useMargin={marginFooter}>{Footer}</Section>
|
|
863
|
-
</View>
|
|
714
|
+
{/* The footer inset is a caller decision, not a platform one — a footer
|
|
715
|
+
that carries its own horizontal padding passes `marginFooter={false}`. */}
|
|
716
|
+
<Section useMargin={marginFooter}>{Footer}</Section>
|
|
864
717
|
</View>
|
|
865
718
|
)}
|
|
866
719
|
</KeyboardAvoidingView>
|
package/Layout/Section.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { View, ViewProps } from 'react-native';
|
|
3
|
-
import { useGridSystem
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { Dimensions, View, ViewProps } from 'react-native';
|
|
3
|
+
import { useGridSystem } from './utils';
|
|
4
4
|
import { GridContextProps } from './types';
|
|
5
5
|
import { GridContext } from './index';
|
|
6
|
+
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
6
7
|
import styles from './styles';
|
|
7
8
|
import { Image } from '../Image';
|
|
8
9
|
import { Spacing } from '../Consts';
|
|
@@ -33,15 +34,18 @@ const Section: React.FC<SectionProps> = ({
|
|
|
33
34
|
style,
|
|
34
35
|
...props
|
|
35
36
|
}) => {
|
|
37
|
+
const { showGrid } = useContext(ApplicationContext);
|
|
36
38
|
const { numberOfColumns } = useGridSystem();
|
|
37
|
-
const { contentWidth } = useScreenLayout();
|
|
38
39
|
|
|
39
40
|
const gutterSize = 12;
|
|
40
41
|
let margin = 0;
|
|
41
42
|
if (useMargin) {
|
|
42
43
|
margin = 12;
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
let widthSection = Dimensions.get('window').width;
|
|
46
|
+
if (useMargin) {
|
|
47
|
+
widthSection = widthSection - margin * 2;
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
const sizePerSpan =
|
|
47
51
|
(widthSection - gutterSize * (numberOfColumns - 1)) / numberOfColumns -
|
|
@@ -56,6 +60,13 @@ const Section: React.FC<SectionProps> = ({
|
|
|
56
60
|
},
|
|
57
61
|
};
|
|
58
62
|
|
|
63
|
+
/**
|
|
64
|
+
* render overlay only dev mode
|
|
65
|
+
*/
|
|
66
|
+
const renderOverlay = () => {
|
|
67
|
+
return <View pointerEvents={'none'} style={styles.boxGridSection} />;
|
|
68
|
+
};
|
|
69
|
+
|
|
59
70
|
return (
|
|
60
71
|
<GridContext.Provider value={gridContext}>
|
|
61
72
|
<View
|
|
@@ -79,7 +90,9 @@ const Section: React.FC<SectionProps> = ({
|
|
|
79
90
|
style={styles.imageBackground}
|
|
80
91
|
/>
|
|
81
92
|
)}
|
|
93
|
+
{/* Render only allowed children as valid React elements */}
|
|
82
94
|
{children}
|
|
95
|
+
{showGrid && renderOverlay()}
|
|
83
96
|
</View>
|
|
84
97
|
</GridContext.Provider>
|
|
85
98
|
);
|
package/Layout/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Card from './Card';
|
|
2
2
|
import Section from './Section';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import GridSystem from './GridSystem';
|
|
4
|
+
import { validateChildren } from './utils';
|
|
5
5
|
import { createContext } from 'react';
|
|
6
6
|
import { GridContextProps } from './types';
|
|
7
7
|
import Item from './Item';
|
|
@@ -18,14 +18,14 @@ const GridContext = createContext<GridContextProps>({
|
|
|
18
18
|
getSizeSpan: () => 0,
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
export type { ScreenProps
|
|
21
|
+
export type { ScreenProps };
|
|
22
22
|
|
|
23
23
|
export {
|
|
24
24
|
GridContext,
|
|
25
25
|
Card,
|
|
26
26
|
Section,
|
|
27
|
+
GridSystem,
|
|
27
28
|
validateChildren,
|
|
28
|
-
useScreenLayout,
|
|
29
29
|
Item,
|
|
30
30
|
ItemList,
|
|
31
31
|
ItemSectionList,
|
package/Layout/styles.ts
CHANGED