@momo-kits/foundation 0.167.1-duo.1 → 0.167.1-duo.13

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 (45) hide show
  1. package/Application/BottomSheet.tsx +115 -14
  2. package/Application/BottomTab/DuoBarCompression.tsx +135 -0
  3. package/Application/BottomTab/DuoTabBar.tsx +462 -0
  4. package/Application/BottomTab/index.tsx +150 -134
  5. package/Application/Components/DuoGlassBackground.tsx +179 -0
  6. package/Application/Components/DuoQuickReturnHeader.tsx +42 -0
  7. package/Application/Components/HeaderExtendHeader.tsx +75 -28
  8. package/Application/Components/HeaderLeft.tsx +38 -0
  9. package/Application/Components/HeaderRight.tsx +142 -9
  10. package/Application/Components/HeaderTitle.tsx +67 -17
  11. package/Application/Components/OptionalGlassView.ts +11 -0
  12. package/Application/Components/SearchHeader.tsx +22 -15
  13. package/Application/Components/SideBarButton.tsx +139 -0
  14. package/Application/ModalScreen.tsx +16 -2
  15. package/Application/NavigationContainer.tsx +36 -45
  16. package/Application/Navigator.ts +1 -3
  17. package/Application/StackScreen.tsx +2 -5
  18. package/Application/WidgetContainer.tsx +9 -7
  19. package/Application/device.ts +29 -0
  20. package/Application/types.ts +10 -1
  21. package/Application/utils.tsx +10 -3
  22. package/Consts/index.ts +0 -1
  23. package/Consts/theme.ts +5 -6
  24. package/Input/Input.tsx +3 -4
  25. package/Input/InputMoney.tsx +31 -51
  26. package/Input/InputPhoneNumber.tsx +3 -4
  27. package/Input/InputSearch.tsx +3 -4
  28. package/Input/InputTextArea.tsx +3 -4
  29. package/Layout/Card.tsx +8 -26
  30. package/Layout/FloatingButton.tsx +3 -3
  31. package/Layout/Item.tsx +1 -10
  32. package/Layout/ReservedRegions.tsx +47 -0
  33. package/Layout/Screen.tsx +244 -48
  34. package/Layout/Section.tsx +5 -18
  35. package/Layout/index.ts +4 -4
  36. package/Layout/styles.ts +5 -0
  37. package/Layout/utils.ts +465 -5
  38. package/Popup/PopupNotify.tsx +33 -22
  39. package/Popup/PopupPromotion.tsx +20 -8
  40. package/Popup/utils.ts +32 -0
  41. package/Text/index.tsx +2 -11
  42. package/Text/utils.ts +1 -2
  43. package/package.json +4 -3
  44. package/Consts/designSystemFont.ts +0 -38
  45. package/Layout/GridSystem.tsx +0 -137
package/Layout/Screen.tsx CHANGED
@@ -9,6 +9,7 @@ import React, {
9
9
  useContext,
10
10
  useEffect,
11
11
  useImperativeHandle,
12
+ useMemo,
12
13
  useRef,
13
14
  } from 'react';
14
15
  import {
@@ -21,11 +22,14 @@ import {
21
22
  ScrollViewProps,
22
23
  StatusBar,
23
24
  StatusBarStyle,
24
- useWindowDimensions,
25
25
  View,
26
26
  ViewProps,
27
27
  } from 'react-native';
28
- import { useSharedValue, withTiming } from 'react-native-reanimated';
28
+ import {
29
+ useAnimatedReaction,
30
+ useSharedValue,
31
+ withTiming,
32
+ } from 'react-native-reanimated';
29
33
  import {
30
34
  useSafeAreaFrame,
31
35
  useSafeAreaInsets,
@@ -44,7 +48,7 @@ import styles from './styles';
44
48
  import { HeaderType } from './types';
45
49
  import { InputRef } from '../Input';
46
50
  import { exportHeaderTitle, getOptions } from '../Application/utils';
47
- import { validateChildren } from './utils';
51
+ import { getHeaderMargin, useScreenLayout, validateChildren } from './utils';
48
52
  import Section from './Section';
49
53
  import {
50
54
  HeaderBackground,
@@ -53,6 +57,12 @@ import {
53
57
  HeaderTitle,
54
58
  SearchHeader,
55
59
  } from '../Application';
60
+ import {
61
+ DuoGlassBackground,
62
+ DuoScrollGradient,
63
+ } from '../Application/Components/DuoGlassBackground';
64
+ import { DuoQuickReturnHeader } from '../Application/Components/DuoQuickReturnHeader';
65
+ import { useDuoTabBarInset } from '../Application/BottomTab/DuoTabBar';
56
66
 
57
67
  export interface ScreenProps extends ViewProps {
58
68
  /**
@@ -118,7 +128,8 @@ export interface ScreenProps extends ViewProps {
118
128
  layoutOffset?: -8 | -24 | -56 | number;
119
129
 
120
130
  /**
121
- * Optional. Width of the right header.
131
+ * Optional. Width of the right header. Defaults to the toolkit width (73), or 0 when
132
+ * iPhone Duo floats the toolkit into its side bar.
122
133
  */
123
134
  headerRightWidth?: 0 | 73 | 110 | number;
124
135
 
@@ -187,7 +198,7 @@ const Screen = forwardRef(
187
198
  footerComponent: Footer,
188
199
  marginFooter = true,
189
200
  layoutOffset = -56,
190
- headerRightWidth = 73,
201
+ headerRightWidth,
191
202
  backgroundColor,
192
203
  headerType = 'default',
193
204
  floatingButtonProps,
@@ -204,8 +215,8 @@ const Screen = forwardRef(
204
215
  ref: any,
205
216
  ) => {
206
217
  const screenRef = useRef<View | ScrollView>(null);
207
- const { width: widthDevice } = useWindowDimensions();
208
- const { theme, navigator } = useContext(ApplicationContext);
218
+ const layout = useScreenLayout();
219
+ const { theme } = useContext(ApplicationContext);
209
220
  const screen: any = useContext(ScreenContext);
210
221
  const insets = useSafeAreaInsets();
211
222
  const frame = useSafeAreaFrame();
@@ -245,15 +256,66 @@ const Screen = forwardRef(
245
256
  }, [customAnimatedValue, internalShared]);
246
257
 
247
258
  const currentTint = useRef<string | undefined>(undefined);
248
-
259
+
249
260
  const isTab = !!screen?.bottomTab;
261
+ // Duo floating tab bar overlays the tab content instead of taking layout space
262
+ const duoTabInset = useDuoTabBarInset();
250
263
 
251
264
  let handleScroll;
252
265
  let Component: any = View;
253
266
 
254
- const bottomInset = Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
267
+ const bottomInset =
268
+ Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
269
+ const hasSideBar = !!layout.sideBar;
270
+ // iPhone Duo: content scrolls under a glass header instead of starting below it
271
+ const useDuoGlass =
272
+ hasSideBar &&
273
+ (headerType === 'default' || headerType === 'extended') &&
274
+ !animatedHeader &&
275
+ !inputSearchProps;
276
+
277
+ // iPhone Duo: the header leaves with the content and returns on a reverse scroll
278
+ const useQuickReturn =
279
+ hasSideBar && scrollable && (useDuoGlass || !!animatedHeader);
280
+ const headerHide = useSharedValue(0);
281
+ const lastScrollY = useSharedValue(0);
282
+
283
+ useAnimatedReaction(
284
+ () => sharedValue.value,
285
+ y => {
286
+ const delta = y - lastScrollY.value;
287
+ lastScrollY.value = y;
288
+ if (!useQuickReturn || y <= 0) {
289
+ headerHide.value = 0;
290
+ return;
291
+ }
292
+ headerHide.value = Math.min(
293
+ Math.max(headerHide.value + delta, 0),
294
+ heightHeader,
295
+ );
296
+ },
297
+ [useQuickReturn, heightHeader],
298
+ );
299
+
300
+ const quickReturnOptions: StackNavigationOptions = useMemo(
301
+ () =>
302
+ useQuickReturn
303
+ ? {
304
+ header: (props: any) => (
305
+ <DuoQuickReturnHeader {...props} offset={headerHide} />
306
+ ),
307
+ }
308
+ : { header: undefined },
309
+ [useQuickReturn, headerHide],
310
+ );
311
+
255
312
  let keyboardOffset = heightHeader - bottomInset;
256
- if (headerType === 'extended' || animatedHeader || inputSearchProps) {
313
+ if (
314
+ headerType === 'extended' ||
315
+ animatedHeader ||
316
+ inputSearchProps ||
317
+ useDuoGlass
318
+ ) {
257
319
  keyboardOffset = -bottomInset;
258
320
  }
259
321
 
@@ -280,9 +342,13 @@ const Screen = forwardRef(
280
342
 
281
343
  case 'extended':
282
344
  options = {
345
+ ...quickReturnOptions,
283
346
  headerShown: true,
284
347
  headerTransparent: true,
285
- headerBackground: () => null,
348
+ headerBackground: () =>
349
+ hasSideBar ? (
350
+ <DuoGlassBackground animatedValue={sharedValue} />
351
+ ) : null,
286
352
  headerTitle: (props: any) => <HeaderTitle {...props} />,
287
353
  };
288
354
  if (inputSearchProps) {
@@ -305,6 +371,19 @@ const Screen = forwardRef(
305
371
  break;
306
372
 
307
373
  default:
374
+ if (hasSideBar && !inputSearchProps) {
375
+ options = {
376
+ ...quickReturnOptions,
377
+ headerTransparent: true,
378
+ headerTintColor: Colors.black_17,
379
+ headerShown: true,
380
+ headerBackground: () => (
381
+ <DuoGlassBackground animatedValue={sharedValue} />
382
+ ),
383
+ headerTitle: (props: any) => <HeaderTitle {...props} />,
384
+ };
385
+ break;
386
+ }
308
387
  options = {
309
388
  headerTransparent: false,
310
389
  headerTintColor: Colors.black_17,
@@ -339,7 +418,7 @@ const Screen = forwardRef(
339
418
  }
340
419
  }
341
420
 
342
- navigation?.instance?.setOptions(options);
421
+ navigation?.instance?.setOptions({ header: undefined, ...options });
343
422
  },
344
423
  [
345
424
  gradientColor,
@@ -348,6 +427,8 @@ const Screen = forwardRef(
348
427
  navigation?.instance,
349
428
  sharedValue,
350
429
  useShadowHeader,
430
+ hasSideBar,
431
+ quickReturnOptions,
351
432
  ],
352
433
  );
353
434
 
@@ -363,18 +444,26 @@ const Screen = forwardRef(
363
444
  }
364
445
 
365
446
  options = {
447
+ ...quickReturnOptions,
366
448
  headerTintColor: currentTint.current ?? Colors.black_17,
367
449
  headerTransparent: true,
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
- ),
450
+ headerBackground: (props: any) =>
451
+ hasSideBar ? (
452
+ // glass shows once the banner has scrolled under the header
453
+ <DuoGlassBackground
454
+ animatedValue={sharedValue}
455
+ fadeStart={Math.max(210 + layoutOffset - heightHeader, 0)}
456
+ />
457
+ ) : (
458
+ <HeaderBackground
459
+ {...props}
460
+ animatedValue={sharedValue}
461
+ useGradient={false}
462
+ useShadowHeader={useShadowHeader}
463
+ headerBackground={headerBackground}
464
+ gradientColor={gradientColor}
465
+ />
466
+ ),
378
467
  headerTitle: (props: any) => {
379
468
  return <HeaderTitle {...props} />;
380
469
  },
@@ -395,6 +484,10 @@ const Screen = forwardRef(
395
484
  navigation?.instance,
396
485
  sharedValue,
397
486
  useShadowHeader,
487
+ hasSideBar,
488
+ layoutOffset,
489
+ heightHeader,
490
+ quickReturnOptions,
398
491
  ],
399
492
  );
400
493
 
@@ -418,14 +511,24 @@ const Screen = forwardRef(
418
511
  ),
419
512
  };
420
513
 
421
- navigation?.instance?.setOptions(options);
514
+ navigation?.instance?.setOptions({ header: undefined, ...options });
422
515
  }, [navigation?.instance, sharedValue]);
423
516
 
424
517
  /**
425
518
  * export search header
426
519
  */
427
520
  const setSearchHeader = (params: SearchHeaderProps) => {
428
- const searchWidth = widthDevice - 24;
521
+ let searchWidth = layout.width - 24;
522
+ let searchLeft = Spacing.M;
523
+ if (layout.sideBar) {
524
+ // back floats in the side bar: the search spans the content width
525
+ searchWidth = layout.contentWidth - Spacing.M * 2;
526
+ searchLeft = Spacing.M - getHeaderMargin(layout.width);
527
+ }
528
+ if (layout.statusBarClearance) {
529
+ searchWidth -=
530
+ layout.statusBarClearance.left + layout.statusBarClearance.right;
531
+ }
429
532
  const options: StackNavigationOptions = {
430
533
  headerRight: undefined,
431
534
  headerTitleContainerStyle: {
@@ -437,10 +540,10 @@ const Screen = forwardRef(
437
540
  marginHorizontal: 0,
438
541
  marginVertical: 0,
439
542
  margin: 0,
440
- left: Spacing.M,
543
+ left: searchLeft,
441
544
  },
442
545
  headerLeft: (props: any) =>
443
- params?.hiddenBack ? null : <HeaderLeft {...props} />,
546
+ params?.hiddenBack ? null : <HeaderLeft {...props} floating />,
444
547
  headerTitle: () => (
445
548
  <SearchHeader {...params} animatedValue={sharedValue} />
446
549
  ),
@@ -540,8 +643,36 @@ const Screen = forwardRef(
540
643
  * handle scroll end
541
644
  * @param e
542
645
  */
646
+ /**
647
+ * a half-shown quick return header settles fully in or out
648
+ */
649
+ const snapQuickReturnHeader = (offsetY: number) => {
650
+ const hide = headerHide.value;
651
+ // above heightHeader the header still sits on the content
652
+ if (
653
+ !useQuickReturn ||
654
+ offsetY < heightHeader ||
655
+ hide <= 0 ||
656
+ hide >= heightHeader
657
+ ) {
658
+ return;
659
+ }
660
+ headerHide.value = withTiming(
661
+ hide > heightHeader / 2 ? heightHeader : 0,
662
+ { duration: 200 },
663
+ );
664
+ };
665
+
666
+ const handleMomentumScrollEnd = (
667
+ e: NativeSyntheticEvent<NativeScrollEvent>,
668
+ ) => {
669
+ snapQuickReturnHeader(e.nativeEvent.contentOffset.y);
670
+ scrollViewProps?.onMomentumScrollEnd?.(e);
671
+ };
672
+
543
673
  const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
544
674
  const offsetY = e.nativeEvent.contentOffset.y;
675
+ snapQuickReturnHeader(offsetY);
545
676
  if (inputSearchProps && offsetY < 100 && offsetY > 0) {
546
677
  Animated.timing(animatedValue.current, {
547
678
  toValue: 0,
@@ -591,6 +722,8 @@ const Screen = forwardRef(
591
722
  key={`ScreenItem${index}`}
592
723
  style={{
593
724
  marginTop: space,
725
+ marginLeft: layout.insetLeft,
726
+ marginRight: layout.insetRight,
594
727
  flex: item.props?.expanded ? 1 : undefined,
595
728
  }}
596
729
  onLayout={item.props?.onLayout}
@@ -611,6 +744,8 @@ const Screen = forwardRef(
611
744
  key={`ScreenItem`}
612
745
  style={{
613
746
  marginTop: space,
747
+ marginLeft: layout.insetLeft,
748
+ marginRight: layout.insetRight,
614
749
  flex: item?.props?.expanded ? 1 : undefined,
615
750
  }}
616
751
  onLayout={item?.props?.onLayout}
@@ -637,6 +772,15 @@ const Screen = forwardRef(
637
772
  return newHeight;
638
773
  };
639
774
 
775
+ // without the grid, the content container keeps clear of the horizontal insets.
776
+ // Only set when there are insets, so a caller's paddingHorizontal is never overridden.
777
+ const hasContentInset = layout.insetLeft > 0 || layout.insetRight > 0;
778
+ const contentInsetStyle = !useGridLayout &&
779
+ hasContentInset && {
780
+ paddingLeft: layout.insetLeft,
781
+ paddingRight: layout.insetRight,
782
+ };
783
+
640
784
  return (
641
785
  <View
642
786
  style={[
@@ -649,21 +793,36 @@ const Screen = forwardRef(
649
793
  },
650
794
  ]}
651
795
  >
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
- />
796
+ {useDuoGlass ? (
797
+ <DuoScrollGradient
798
+ animatedValue={sharedValue}
799
+ gradientColor={gradientColor}
800
+ headerBackground={headerBackground}
801
+ heightHeader={heightHeader}
802
+ extended={headerType === 'extended'}
803
+ followScroll={useQuickReturn}
804
+ />
805
+ ) : (
806
+ <HeaderExtendHeader
807
+ headerType={headerType}
808
+ heightHeader={heightHeader}
809
+ headerRightWidth={headerRightWidth}
810
+ animatedValue={sharedValue}
811
+ inputSearchProps={inputSearchProps}
812
+ navigation={navigation}
813
+ inputSearchRef={inputSearchRef}
814
+ useShadowHeader={useShadowHeader}
815
+ gradientColor={gradientColor}
816
+ headerBackground={headerBackground}
817
+ />
818
+ )}
664
819
 
665
820
  <KeyboardAvoidingView
666
- style={Styles.flex}
821
+ style={[
822
+ Styles.flex,
823
+ useDuoGlass &&
824
+ (!scrollable || !!Header) && { paddingTop: heightHeader },
825
+ ]}
667
826
  enabled={enableKeyboardAvoidingView}
668
827
  keyboardVerticalOffset={keyboardVerticalOffset ?? keyboardOffset}
669
828
  behavior={Platform.select({
@@ -679,10 +838,24 @@ const Screen = forwardRef(
679
838
  showsVerticalScrollIndicator={false}
680
839
  onScroll={handleScroll}
681
840
  onScrollEndDrag={handleScrollEnd}
841
+ onMomentumScrollEnd={handleMomentumScrollEnd}
682
842
  scrollEventThrottle={16}
683
- style={[Styles.flex]}
843
+ style={[
844
+ Styles.flex,
845
+ !scrollable && contentInsetStyle,
846
+ !scrollable &&
847
+ !Footer &&
848
+ isTab &&
849
+ !!duoTabInset && { paddingBottom: duoTabInset },
850
+ ]}
684
851
  contentContainerStyle={[
685
852
  scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
853
+ scrollable &&
854
+ !Footer &&
855
+ isTab &&
856
+ !!duoTabInset && { paddingBottom: duoTabInset },
857
+ scrollable && contentInsetStyle,
858
+ useDuoGlass && !Header && { paddingTop: heightHeader },
686
859
  scrollViewProps?.contentContainerStyle,
687
860
  ]}
688
861
  >
@@ -692,28 +865,51 @@ const Screen = forwardRef(
692
865
  </Component>
693
866
 
694
867
  {floatingButtonProps && (
695
- <View>
868
+ <View
869
+ style={{
870
+ marginLeft: layout.insetLeft,
871
+ marginRight: layout.insetRight,
872
+ }}
873
+ >
696
874
  <FloatingButton
697
875
  {...floatingButtonProps}
698
876
  animatedValue={sharedValue}
699
- bottom={Footer || isTab ? 12 : bottomInset + Spacing.S}
877
+ bottom={
878
+ Footer || isTab
879
+ ? 12 + (Footer ? 0 : duoTabInset)
880
+ : bottomInset + Spacing.S
881
+ }
700
882
  />
701
883
  </View>
702
884
  )}
703
885
 
704
886
  {Footer && (
887
+ // with side insets, the clip keeps the shadow off the side bar, only the top one shows
705
888
  <View
889
+ pointerEvents={'box-none'}
706
890
  style={[
707
- styles.shadow,
891
+ hasContentInset && styles.footerClip,
708
892
  {
709
- paddingBottom: bottomInset + Spacing.S,
710
- backgroundColor: theme.colors.background.surface,
893
+ marginLeft: layout.insetLeft,
894
+ marginRight: layout.insetRight,
711
895
  },
712
896
  ]}
713
897
  >
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>
898
+ <View
899
+ style={[
900
+ styles.shadow,
901
+ {
902
+ paddingBottom:
903
+ (isTab && duoTabInset ? duoTabInset : bottomInset) +
904
+ Spacing.S,
905
+ backgroundColor: theme.colors.background.surface,
906
+ },
907
+ ]}
908
+ >
909
+ {/* The footer inset is a caller decision, not a platform one — a footer
910
+ that carries its own horizontal padding passes `marginFooter={false}`. */}
911
+ <Section useMargin={marginFooter}>{Footer}</Section>
912
+ </View>
717
913
  </View>
718
914
  )}
719
915
  </KeyboardAvoidingView>
@@ -1,9 +1,8 @@
1
- import React, { useContext } from 'react';
2
- import { Dimensions, View, ViewProps } from 'react-native';
3
- import { useGridSystem } from './utils';
1
+ import React from 'react';
2
+ import { View, ViewProps } from 'react-native';
3
+ import { useGridSystem, useScreenLayout } from './utils';
4
4
  import { GridContextProps } from './types';
5
5
  import { GridContext } from './index';
6
- import { ApplicationContext, MiniAppContext } from '../Context';
7
6
  import styles from './styles';
8
7
  import { Image } from '../Image';
9
8
  import { Spacing } from '../Consts';
@@ -34,18 +33,15 @@ const Section: React.FC<SectionProps> = ({
34
33
  style,
35
34
  ...props
36
35
  }) => {
37
- const { showGrid } = useContext(ApplicationContext);
38
36
  const { numberOfColumns } = useGridSystem();
37
+ const { contentWidth } = useScreenLayout();
39
38
 
40
39
  const gutterSize = 12;
41
40
  let margin = 0;
42
41
  if (useMargin) {
43
42
  margin = 12;
44
43
  }
45
- let widthSection = Dimensions.get('window').width;
46
- if (useMargin) {
47
- widthSection = widthSection - margin * 2;
48
- }
44
+ const widthSection = contentWidth - margin * 2;
49
45
 
50
46
  const sizePerSpan =
51
47
  (widthSection - gutterSize * (numberOfColumns - 1)) / numberOfColumns -
@@ -60,13 +56,6 @@ const Section: React.FC<SectionProps> = ({
60
56
  },
61
57
  };
62
58
 
63
- /**
64
- * render overlay only dev mode
65
- */
66
- const renderOverlay = () => {
67
- return <View pointerEvents={'none'} style={styles.boxGridSection} />;
68
- };
69
-
70
59
  return (
71
60
  <GridContext.Provider value={gridContext}>
72
61
  <View
@@ -90,9 +79,7 @@ const Section: React.FC<SectionProps> = ({
90
79
  style={styles.imageBackground}
91
80
  />
92
81
  )}
93
- {/* Render only allowed children as valid React elements */}
94
82
  {children}
95
- {showGrid && renderOverlay()}
96
83
  </View>
97
84
  </GridContext.Provider>
98
85
  );
package/Layout/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import Card from './Card';
2
2
  import Section from './Section';
3
- import GridSystem from './GridSystem';
4
- import { validateChildren } from './utils';
3
+ import { useScreenLayout, validateChildren } from './utils';
4
+ import type { ScreenLayout, SideBarEdge, SideBarLayout } 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, ScreenLayout, SideBarEdge, SideBarLayout };
22
22
 
23
23
  export {
24
24
  GridContext,
25
25
  Card,
26
26
  Section,
27
- GridSystem,
28
27
  validateChildren,
28
+ useScreenLayout,
29
29
  Item,
30
30
  ItemList,
31
31
  ItemSectionList,
package/Layout/styles.ts CHANGED
@@ -91,5 +91,10 @@ export default StyleSheet.create({
91
91
  },
92
92
  }),
93
93
  },
94
+ footerClip: {
95
+ marginTop: -Spacing.XL,
96
+ paddingTop: Spacing.XL,
97
+ overflow: 'hidden',
98
+ },
94
99
  debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
95
100
  });