@momo-kits/foundation 0.169.6 → 0.169.7-beta.10

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 (143) hide show
  1. package/Application/BottomSheet.hooks.ts +8 -8
  2. package/Application/BottomSheet.parts.tsx +34 -44
  3. package/Application/BottomSheet.tsx +37 -40
  4. package/Application/BottomTab/ActiveIndicator.tsx +14 -15
  5. package/Application/BottomTab/BottomTabBar.tsx +62 -49
  6. package/Application/BottomTab/BottomTabInset.tsx +4 -8
  7. package/Application/BottomTab/CurvedContainer.tsx +12 -14
  8. package/Application/BottomTab/CustomBottomTabItem.tsx +13 -13
  9. package/Application/BottomTab/DuoBarCompression.tsx +19 -13
  10. package/Application/BottomTab/DuoRailTabBar.tsx +24 -20
  11. package/Application/BottomTab/DuoTabBar.tsx +10 -8
  12. package/Application/BottomTab/TabBarIcon.tsx +29 -15
  13. package/Application/BottomTab/TabScreen.tsx +5 -1
  14. package/Application/BottomTab/index.tsx +30 -33
  15. package/Application/BottomTab/metrics.ts +23 -23
  16. package/Application/BottomTab/tabItems.ts +1 -1
  17. package/Application/BottomTab/usePressLift.ts +2 -2
  18. package/Application/Components/BackgroundImageView.tsx +0 -4
  19. package/Application/Components/DuoGlassBackground.tsx +4 -5
  20. package/Application/Components/HeaderAnimated.tsx +0 -4
  21. package/Application/Components/HeaderBackground.tsx +0 -4
  22. package/Application/Components/HeaderExtendHeader.tsx +10 -11
  23. package/Application/Components/HeaderLeft.tsx +1 -2
  24. package/Application/Components/HeaderRight.tsx +1 -2
  25. package/Application/Components/HeaderTitle.shared.ts +9 -11
  26. package/Application/Components/HeaderTitle.tsx +3 -4
  27. package/Application/Components/HeaderToolkitAction.tsx +20 -17
  28. package/Application/Components/NavigationButton.tsx +1 -2
  29. package/Application/Components/SearchHeader.tsx +10 -17
  30. package/Application/Components/TitleJourney.tsx +2 -2
  31. package/Application/Components/TitleLocation.tsx +2 -2
  32. package/Application/Components/TitleUser.tsx +2 -2
  33. package/Application/Components/useToolkitActions.tsx +32 -17
  34. package/Application/KitAdoption/AdoptionBadge.tsx +119 -0
  35. package/Application/KitAdoption/AdoptionProbe.tsx +166 -0
  36. package/Application/KitAdoption/AdoptionStore.ts +80 -0
  37. package/Application/KitAdoption/Authorship/utils.ts +137 -0
  38. package/Application/KitAdoption/Slots/utils.ts +68 -0
  39. package/Application/KitAdoption/constants.ts +120 -0
  40. package/Application/KitAdoption/index.ts +12 -0
  41. package/Application/KitAdoption/styles.ts +55 -0
  42. package/Application/KitAdoption/types.ts +61 -0
  43. package/Application/KitAdoption/utils.ts +376 -0
  44. package/Application/Localize.ts +0 -7
  45. package/Application/ModalScreen.tsx +10 -10
  46. package/Application/Navigation.ts +16 -14
  47. package/Application/NavigationContainer.tsx +18 -19
  48. package/Application/Navigator.ts +48 -20
  49. package/Application/ScaleSizeProvider.tsx +6 -13
  50. package/Application/StackScreen.tracking.ts +33 -11
  51. package/Application/StackScreen.tsx +54 -10
  52. package/Application/TooltipPortal.tsx +5 -12
  53. package/Application/WidgetContainer.tsx +4 -10
  54. package/Application/__tests__/KitAdoption.integration.test.tsx +253 -0
  55. package/Application/__tests__/KitAdoption.test.ts +283 -0
  56. package/Application/__tests__/KitAdoptionAuthorship.test.ts +132 -0
  57. package/Application/__tests__/KitAdoptionStore.test.ts +110 -0
  58. package/Application/__tests__/KitAdoptionStructural.test.ts +193 -0
  59. package/Application/__tests__/modalLayout.test.ts +128 -0
  60. package/Application/modalLayout.ts +14 -13
  61. package/Application/navigationOptions.tsx +17 -21
  62. package/Badge/Badge.tsx +0 -5
  63. package/Badge/BadgeDot.tsx +0 -1
  64. package/Badge/BadgeDotAnimation.tsx +7 -15
  65. package/Badge/BadgeRibbon.tsx +38 -46
  66. package/Badge/Shape.tsx +0 -2
  67. package/Badge/types.ts +2 -2
  68. package/Button/index.tsx +16 -5
  69. package/Button/utils.ts +15 -9
  70. package/CheckBox/index.tsx +0 -4
  71. package/Consts/theme.ts +10 -10
  72. package/Context/index.ts +1 -5
  73. package/Divider/DashDivider.tsx +0 -1
  74. package/Divider/index.tsx +0 -4
  75. package/FoundationList/index.tsx +0 -4
  76. package/Icon/index.tsx +6 -6
  77. package/Icon/types.ts +1 -1
  78. package/IconButton/index.tsx +12 -4
  79. package/Image/index.tsx +7 -9
  80. package/Input/Input.tsx +9 -8
  81. package/Input/InputDropDown.tsx +12 -10
  82. package/Input/InputMoney.tsx +8 -12
  83. package/Input/InputMoneyView.tsx +7 -14
  84. package/Input/InputOTP.tsx +33 -35
  85. package/Input/InputPhoneNumber.tsx +9 -8
  86. package/Input/InputSearch.tsx +6 -4
  87. package/Input/InputTextArea.tsx +0 -4
  88. package/Input/SearchTextTyping.tsx +0 -4
  89. package/Input/SystemTextInput.tsx +2 -7
  90. package/Input/TextTyping.tsx +0 -4
  91. package/Input/common.tsx +12 -26
  92. package/Input/index.tsx +20 -17
  93. package/Input/moneyUtils.ts +4 -10
  94. package/Input/styles.ts +5 -0
  95. package/Input/utils.ts +12 -14
  96. package/Layout/Card.tsx +13 -16
  97. package/Layout/FloatingButton.tsx +0 -4
  98. package/Layout/Item.tsx +2 -6
  99. package/Layout/ItemList.tsx +7 -9
  100. package/Layout/ItemSectionList.tsx +1 -2
  101. package/Layout/ReservedRegions.tsx +25 -25
  102. package/Layout/Screen.tsx +58 -56
  103. package/Layout/Section.tsx +13 -17
  104. package/Layout/TrackingScope.tsx +0 -1
  105. package/Layout/constants.ts +19 -0
  106. package/Layout/screenContent.tsx +2 -4
  107. package/Layout/screenFooter.tsx +18 -28
  108. package/Layout/screenHeader.tsx +31 -34
  109. package/Layout/screenQuickReturn.tsx +20 -17
  110. package/Layout/screenScroll.ts +7 -4
  111. package/Layout/screenTypes.ts +2 -3
  112. package/Layout/types.ts +41 -3
  113. package/Layout/useGridSystem.ts +49 -0
  114. package/Layout/utils.ts +37 -38
  115. package/Loader/DotLoader.tsx +0 -4
  116. package/Loader/Loader.tsx +0 -4
  117. package/Loader/ProgressBar.tsx +0 -1
  118. package/Loader/Spinner.tsx +0 -4
  119. package/Loader/utils.ts +7 -11
  120. package/Pagination/Dot.tsx +0 -4
  121. package/Pagination/PaginationDot.tsx +0 -1
  122. package/Pagination/PaginationNumber.tsx +3 -5
  123. package/Pagination/PaginationScroll.tsx +0 -5
  124. package/Pagination/PaginationWhiteDot.tsx +0 -1
  125. package/Pagination/index.tsx +0 -4
  126. package/Pagination/types.ts +2 -2
  127. package/Popup/PopupNotify.tsx +48 -44
  128. package/Popup/PopupPromotion.tsx +7 -4
  129. package/Popup/types.ts +4 -4
  130. package/Popup/utils.ts +0 -4
  131. package/Radio/index.tsx +0 -4
  132. package/Skeleton/index.tsx +0 -8
  133. package/Switch/index.tsx +0 -1
  134. package/Tag/index.tsx +1 -5
  135. package/Tag/types.ts +3 -3
  136. package/Text/index.tsx +3 -14
  137. package/Text/styles.ts +1 -1
  138. package/Text/types.ts +6 -1
  139. package/Text/utils.ts +4 -20
  140. package/Title/index.tsx +32 -41
  141. package/ViewBoundary/index.tsx +2 -4
  142. package/index.ts +6 -0
  143. package/package.json +1 -1
@@ -31,10 +31,6 @@ type ScreenHeaderParams = {
31
31
  layoutOffset: number;
32
32
  };
33
33
 
34
- /**
35
- * Applies the Screen's navigation header (plain, extended, animated banner or search) and
36
- * re-applies it when those props change. Returns the search header setter and the tint.
37
- */
38
34
  export const useScreenHeader = ({
39
35
  navigation,
40
36
  layout,
@@ -52,7 +48,10 @@ export const useScreenHeader = ({
52
48
  const currentTint = useRef<string | undefined>(undefined);
53
49
  const appliedHeaderMode = useRef<string | undefined>(undefined);
54
50
 
55
- // keepTitle leaves a title the screen set itself when the same type is re-applied
51
+ /**
52
+ * export options for screen
53
+ * @param type
54
+ */
56
55
  const setHeaderType = useCallback(
57
56
  (type: HeaderType, keepTitle = false) => {
58
57
  let options: StackNavigationOptions;
@@ -70,12 +69,10 @@ export const useScreenHeader = ({
70
69
  ...quickReturnOptions,
71
70
  headerShown: true,
72
71
  headerTransparent: true,
73
- headerBackground: () => {
74
- if (!hasSideBar) {
75
- return null;
76
- }
77
- return <DuoGlassBackground animatedValue={sharedValue} />;
78
- },
72
+ headerBackground: () =>
73
+ hasSideBar ? (
74
+ <DuoGlassBackground animatedValue={sharedValue} />
75
+ ) : null,
79
76
  headerTitle: (props: any) => <HeaderTitle {...props} />,
80
77
  };
81
78
  if (inputSearchProps) {
@@ -163,7 +160,10 @@ export const useScreenHeader = ({
163
160
  ],
164
161
  );
165
162
 
166
- // the first tint the animated header sets is kept for later scroll updates
163
+ /**
164
+ * export animatedHeader options for screen
165
+ * @param nextAnimatedHeader
166
+ */
167
167
  const setAnimatedHeader = useCallback(
168
168
  (nextAnimatedHeader: AnimatedHeader) => {
169
169
  let options: StackNavigationOptions;
@@ -175,16 +175,13 @@ export const useScreenHeader = ({
175
175
  ...quickReturnOptions,
176
176
  headerTintColor: currentTint.current ?? Colors.black_17,
177
177
  headerTransparent: true,
178
- headerBackground: (props: any) => {
179
- if (hasSideBar) {
180
- return (
181
- <DuoGlassBackground
182
- animatedValue={sharedValue}
183
- bannerBottom={ANIMATED_BANNER_HEIGHT + layoutOffset}
184
- />
185
- );
186
- }
187
- return (
178
+ headerBackground: (props: any) =>
179
+ hasSideBar ? (
180
+ <DuoGlassBackground
181
+ animatedValue={sharedValue}
182
+ bannerBottom={ANIMATED_BANNER_HEIGHT + layoutOffset}
183
+ />
184
+ ) : (
188
185
  <HeaderBackground
189
186
  {...props}
190
187
  animatedValue={sharedValue}
@@ -193,8 +190,7 @@ export const useScreenHeader = ({
193
190
  headerBackground={headerBackground}
194
191
  gradientColor={gradientColor}
195
192
  />
196
- );
197
- },
193
+ ),
198
194
  headerTitle: (props: any) => {
199
195
  return <HeaderTitle {...props} />;
200
196
  },
@@ -221,6 +217,9 @@ export const useScreenHeader = ({
221
217
  ],
222
218
  );
223
219
 
220
+ /**
221
+ * export animatedHeader options for screen
222
+ */
224
223
  const setAnimatedSearch = useCallback(() => {
225
224
  const options: StackNavigationOptions = {
226
225
  headerShown: true,
@@ -241,7 +240,9 @@ export const useScreenHeader = ({
241
240
  navigation?.instance?.setOptions({ header: undefined, ...options });
242
241
  }, [navigation?.instance, sharedValue]);
243
242
 
244
- // the search field spans the content, clear of the side bar and status bar clusters
243
+ /**
244
+ * export search header
245
+ */
245
246
  const setSearchHeader = (params: SearchHeaderProps) => {
246
247
  let searchWidth = layout.width - 24;
247
248
  let searchLeft = Spacing.M;
@@ -249,9 +250,9 @@ export const useScreenHeader = ({
249
250
  searchWidth = layout.contentWidth - Spacing.M * 2;
250
251
  searchLeft = Spacing.M - getHeaderMargin(layout.width);
251
252
  }
252
- const clearance = layout.statusBarClearance;
253
- if (clearance) {
254
- searchWidth -= clearance.left + clearance.right;
253
+ if (layout.statusBarClearance) {
254
+ searchWidth -=
255
+ layout.statusBarClearance.left + layout.statusBarClearance.right;
255
256
  }
256
257
  const options: StackNavigationOptions = {
257
258
  headerRight: undefined,
@@ -266,12 +267,8 @@ export const useScreenHeader = ({
266
267
  margin: 0,
267
268
  left: searchLeft,
268
269
  },
269
- headerLeft: (props: any) => {
270
- if (params?.hiddenBack) {
271
- return null;
272
- }
273
- return <HeaderLeft {...props} floating />;
274
- },
270
+ headerLeft: (props: any) =>
271
+ params?.hiddenBack ? null : <HeaderLeft {...props} floating />,
275
272
  headerTitle: () => (
276
273
  <SearchHeader {...params} animatedValue={sharedValue} />
277
274
  ),
@@ -8,10 +8,6 @@ import {
8
8
  } from 'react-native-reanimated';
9
9
  import { DuoQuickReturnHeader } from '../Application/Components/DuoQuickReturnHeader';
10
10
 
11
- /**
12
- * iPhone Duo quick return header: it slides out while the content scrolls down and back
13
- * on scroll up. Returns the header options and a snap to call when scrolling ends.
14
- */
15
11
  export const useScreenQuickReturn = (
16
12
  sharedValue: SharedValue<number>,
17
13
  useQuickReturn: boolean,
@@ -37,22 +33,29 @@ export const useScreenQuickReturn = (
37
33
  [useQuickReturn, heightHeader],
38
34
  );
39
35
 
40
- const quickReturnOptions: StackNavigationOptions = useMemo(() => {
41
- if (!useQuickReturn) {
42
- return { header: undefined };
43
- }
44
- return {
45
- header: (props: any) => (
46
- <DuoQuickReturnHeader {...props} offset={headerHide} />
47
- ),
48
- };
49
- }, [useQuickReturn, headerHide]);
36
+ const quickReturnOptions: StackNavigationOptions = useMemo(
37
+ () =>
38
+ useQuickReturn
39
+ ? {
40
+ header: (props: any) => (
41
+ <DuoQuickReturnHeader {...props} offset={headerHide} />
42
+ ),
43
+ }
44
+ : { header: undefined },
45
+ [useQuickReturn, headerHide],
46
+ );
50
47
 
51
- // a half-shown quick return header settles fully in or out
48
+ /**
49
+ * a half-shown quick return header settles fully in or out
50
+ */
52
51
  const snapQuickReturnHeader = (offsetY: number) => {
53
52
  const hide = headerHide.value;
54
- const isSettled = hide <= 0 || hide >= heightHeader;
55
- if (!useQuickReturn || offsetY < heightHeader || isSettled) {
53
+ if (
54
+ !useQuickReturn ||
55
+ offsetY < heightHeader ||
56
+ hide <= 0 ||
57
+ hide >= heightHeader
58
+ ) {
56
59
  return;
57
60
  }
58
61
  headerHide.value = withTiming(hide > heightHeader / 2 ? heightHeader : 0, {
@@ -25,10 +25,6 @@ type ScrollHandlerParams = {
25
25
  ref: any;
26
26
  };
27
27
 
28
- /**
29
- * Scroll handlers for Screen: feed the header animated values, retint an animated header
30
- * past 50pt, snap the quick return header and reset a search screen scrolled under 100pt.
31
- */
32
28
  export const createScrollHandlers = ({
33
29
  scrollable,
34
30
  animatedValue,
@@ -43,6 +39,9 @@ export const createScrollHandlers = ({
43
39
  }: ScrollHandlerParams) => {
44
40
  let handleScroll;
45
41
 
42
+ /**
43
+ * animated when use scroll && animated value
44
+ */
46
45
  if (scrollable) {
47
46
  handleScroll = Animated.event(
48
47
  [
@@ -81,6 +80,10 @@ export const createScrollHandlers = ({
81
80
  );
82
81
  }
83
82
 
83
+ /**
84
+ * handle scroll end
85
+ * @param e
86
+ */
84
87
  const handleMomentumScrollEnd = (
85
88
  e: NativeSyntheticEvent<NativeScrollEvent>,
86
89
  ) => {
@@ -38,7 +38,7 @@ export interface ScreenProps extends ViewProps {
38
38
  headerType?: HeaderType;
39
39
 
40
40
  /**
41
- * Optional. Animated banner header: its component, tint and title.
41
+ * Optional. Props for the animated component or bool used top navigation animated.
42
42
  */
43
43
  animatedHeader?: AnimatedHeader;
44
44
 
@@ -71,8 +71,7 @@ export interface ScreenProps extends ViewProps {
71
71
  backgroundColor?: string;
72
72
 
73
73
  /**
74
- * Optional. Shift of the content against the animated header banner bottom; negative
75
- * values overlap the banner.
74
+ * Optional. layout card offset overlap header banner.
76
75
  */
77
76
  layoutOffset?: -8 | -24 | -56 | number;
78
77
 
package/Layout/types.ts CHANGED
@@ -4,16 +4,54 @@ export type HeaderType = 'default' | 'extended' | 'none';
4
4
 
5
5
  export type ScreenRef = {
6
6
  /**
7
- * Applies navigation options to the screen's header.
7
+ * Set options for screen
8
+ * @param params
8
9
  */
9
10
  setOptions: (params: NavigationOptions) => void;
10
11
 
11
12
  /**
12
- * Replaces the header title with a search field.
13
+ * Show search header
14
+ * @param params
13
15
  */
14
16
  setSearchHeader: (params: SearchHeaderProps) => void;
15
17
  };
16
- export type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
18
+ export type SpanNumber =
19
+ | 1
20
+ | 2
21
+ | 3
22
+ | 4
23
+ | 5
24
+ | 6
25
+ | 7
26
+ | 8
27
+ | 9
28
+ | 10
29
+ | 11
30
+ | 12
31
+ | 13
32
+ | 14
33
+ | 15
34
+ | 16
35
+ | 17
36
+ | 18
37
+ | 19
38
+ | 20
39
+ | 21
40
+ | 22
41
+ | 23
42
+ | 24
43
+ | 25
44
+ | 26
45
+ | 27
46
+ | 28
47
+ | 29
48
+ | 30
49
+ | 31
50
+ | 32
51
+ | 33
52
+ | 34
53
+ | 35
54
+ | 36;
17
55
 
18
56
  export type GridContextProps = {
19
57
  /**
@@ -0,0 +1,49 @@
1
+ import {
2
+ GRID_DESKTOP_COLUMNS,
3
+ GRID_DESKTOP_MIN_WIDTH,
4
+ GRID_PHONE_COLUMNS,
5
+ GRID_PHONE_MAX_WIDTH,
6
+ GRID_TABLET_COLUMNS,
7
+ GRID_TABLET_MIN_WIDTH,
8
+ } from './constants';
9
+ import { useScreenLayout } from './utils';
10
+
11
+ /**
12
+ * Column count for a content width: 12 below 800pt, 24 below 1100pt, 36 from there
13
+ */
14
+ const getGridColumns = (width: number) => {
15
+ if (width >= GRID_DESKTOP_MIN_WIDTH) {
16
+ return GRID_DESKTOP_COLUMNS;
17
+ }
18
+ if (width >= GRID_TABLET_MIN_WIDTH) {
19
+ return GRID_TABLET_COLUMNS;
20
+ }
21
+ return GRID_PHONE_COLUMNS;
22
+ };
23
+
24
+ /**
25
+ * Grid width for a content width: the 12-column grid stops at 600pt and is centered,
26
+ * the wider grids fill the content
27
+ */
28
+ const getGridWidth = (width: number) => {
29
+ if (width < GRID_TABLET_MIN_WIDTH) {
30
+ return Math.min(width, GRID_PHONE_MAX_WIDTH);
31
+ }
32
+ return width;
33
+ };
34
+
35
+ /**
36
+ * Grid for the current content width: column count, grid width and the horizontal
37
+ * offset that centers a grid narrower than the content
38
+ */
39
+ const useGridSystem = () => {
40
+ const { contentWidth } = useScreenLayout();
41
+ const gridWidth = getGridWidth(contentWidth);
42
+ return {
43
+ numberOfColumns: getGridColumns(contentWidth),
44
+ gridWidth,
45
+ gridOffset: (contentWidth - gridWidth) / 2,
46
+ };
47
+ };
48
+
49
+ export { useGridSystem };
package/Layout/utils.ts CHANGED
@@ -15,8 +15,9 @@ import {
15
15
  import { ReservedRegion, ReservedRegionsContext } from './ReservedRegions';
16
16
 
17
17
  /**
18
- * Warns when a child is not one of `childrenTypes` (Fragments pass) and returns the
19
- * children, flattened to the valid elements when given an array.
18
+ * validate children type
19
+ * @param children
20
+ * @param childrenTypes
20
21
  */
21
22
  const validateChildren = (
22
23
  children: React.ReactNode | React.ReactNode[],
@@ -53,20 +54,20 @@ const validateChildren = (
53
54
  const NO_INSETS: EdgeInsets = { top: 0, right: 0, bottom: 0, left: 0 };
54
55
 
55
56
  /**
56
- * How far system regions (e.g. the camera, at either end depending on the rotation) reach
57
- * into a side strip from its top and bottom ends, plus the center y of the region reaching
58
- * furthest from the top.
57
+ * how far system regions reach into a side strip from its top and from its bottom end
58
+ * (e.g. the camera, which sits at either end depending on the rotation), and the center
59
+ * y of the region reaching furthest from the top
59
60
  */
60
61
  const getStripOcclusion = (
61
62
  regions: ReservedRegion[],
62
63
  stripLeft: number,
63
64
  stripRight: number,
64
65
  windowHeight: number,
65
- ) => {
66
- return regions.reduce(
66
+ ) =>
67
+ regions.reduce(
67
68
  (occlusion, region) => {
68
- const regionRight = region.x + region.width;
69
- const overlapsStrip = region.x < stripRight && regionRight > stripLeft;
69
+ const overlapsStrip =
70
+ region.x < stripRight && region.x + region.width > stripLeft;
70
71
  if (!overlapsStrip) {
71
72
  return occlusion;
72
73
  }
@@ -83,11 +84,10 @@ const getStripOcclusion = (
83
84
  },
84
85
  { top: 0, topCenter: 0, bottom: 0 },
85
86
  );
86
- };
87
87
 
88
88
  /**
89
- * How far the clock and battery clusters of a status bar on the top edge reach in from
90
- * each side. `undefined` without reserved regions there.
89
+ * how far the clock and battery clusters of a status bar on the top edge reach in from
90
+ * each side. `undefined` without reserved regions there
91
91
  */
92
92
  const getStatusBarClusters = (
93
93
  regions: ReservedRegion[],
@@ -95,11 +95,12 @@ const getStatusBarClusters = (
95
95
  topInset: number,
96
96
  ) => {
97
97
  const midX = windowWidth / 2;
98
- const clusters = regions.filter(region => {
99
- const isInTopInset = region.y + region.height <= topInset;
100
- const isOnOneSide = region.x + region.width <= midX || region.x >= midX;
101
- return region.y < topInset && isInTopInset && isOnOneSide;
102
- });
98
+ const clusters = regions.filter(
99
+ region =>
100
+ region.y < topInset &&
101
+ region.y + region.height <= topInset &&
102
+ (region.x + region.width <= midX || region.x >= midX),
103
+ );
103
104
  if (!clusters.length) {
104
105
  return undefined;
105
106
  }
@@ -117,10 +118,8 @@ const getStatusBarClusters = (
117
118
  );
118
119
  };
119
120
 
120
- /** iOS phone idiom: iPad keeps the plain header and is never treated as iPhone Duo. */
121
- const isIPhone = () => {
122
- return Platform.OS === 'ios' && Platform.constants.interfaceIdiom === 'phone';
123
- };
121
+ const isIPhone = () =>
122
+ Platform.OS === 'ios' && Platform.constants.interfaceIdiom === 'phone';
124
123
 
125
124
  /**
126
125
  * Header height and the room it keeps above the bar row for the status bar. On iPhone the
@@ -142,7 +141,7 @@ const getHeaderLayout = (topInset: number) => {
142
141
 
143
142
  /**
144
143
  * Header whose bar row is centered on a window y, at least iPhoneMinHeight tall and
145
- * reaching 8pt below a side bar control centered there.
144
+ * reaching 8pt below a side bar control centered there
146
145
  */
147
146
  const getCenteredHeaderLayout = (centerY: number) => {
148
147
  const headerHeight = Math.max(
@@ -222,7 +221,8 @@ const useScreenLayout = (): ScreenLayout => {
222
221
  if (sideInset >= DuoMetrics.controlSize + Spacing.M) {
223
222
  const edge = insets.right >= insets.left ? 'right' : 'left';
224
223
  const stripLeft = edge === 'right' ? width - sideInset : 0;
225
- // clear the camera and status bar cluster; region frames include the system margin
224
+ // keep controls clear of the camera and of the status bar cluster, which grows for
225
+ // calls and Live Activities. Region frames already include the system's margin
226
226
  const occlusion = getStripOcclusion(
227
227
  reservedRegions,
228
228
  stripLeft,
@@ -242,7 +242,8 @@ const useScreenLayout = (): ScreenLayout => {
242
242
  } else if (height >= DuoMetrics.innerMinHeight) {
243
243
  top = DuoMetrics.firstItemTopLandscape;
244
244
  } else {
245
- // outer landscape: title row centers on a camera at the top end, else on back
245
+ // outer display in landscape: no status bar in the strip, the title row centers
246
+ // on the camera when it sits at the top end, otherwise on the back button
246
247
  top = DuoMetrics.edgeInset;
247
248
  const cameraAtTop = occlusion.top > top;
248
249
  const backCenterY = top + DuoMetrics.controlSize / 2;
@@ -284,7 +285,7 @@ const useScreenLayout = (): ScreenLayout => {
284
285
 
285
286
  /**
286
287
  * Header row options for react-navigation: its height, the room for the status bar, and
287
- * on iPhone Duo inner portrait the buttons kept clear of the clock and battery clusters.
288
+ * on iPhone Duo inner portrait the buttons kept clear of the clock and battery clusters
288
289
  */
289
290
  const getHeaderRowOptions = ({
290
291
  headerHeight,
@@ -304,7 +305,9 @@ const getHeaderRowOptions = ({
304
305
  };
305
306
  };
306
307
 
307
- /** Side margin @react-navigation/elements Header adds to its content row. */
308
+ /**
309
+ * Side margin @react-navigation/elements Header adds to its content row
310
+ */
308
311
  const getHeaderMargin = (width: number) => {
309
312
  if (Platform.OS === 'ios' && width >= HeaderMetrics.largeWidth) {
310
313
  return HeaderMetrics.largeMargin;
@@ -318,9 +321,11 @@ const InnerEdgeStyles: Record<SideBarEdge, ViewStyle> = {
318
321
  };
319
322
 
320
323
  /**
321
- * Absolute style floating a header item into the side bar, 12pt from the strip's inner
322
- * edge, relative to the `container` rendering it; `slot` 0 is back, 1 the toolkit below.
324
+ * Absolute style that floats a header item into the side bar, relative to the header
325
+ * container (left or right) rendering it, 12pt from the strip's inner edge.
323
326
  * `undefined` while there is no side bar.
327
+ * @param container header container rendering the item
328
+ * @param slot position in the side bar, 0 for back, 1 for the toolkit below it
324
329
  */
325
330
  const useSideBarItemStyle = (
326
331
  container: 'left' | 'right',
@@ -333,8 +338,10 @@ const useSideBarItemStyle = (
333
338
 
334
339
  const margin = getHeaderMargin(width);
335
340
  const columnLeft = sideBar.edge === 'left' ? 0 : width - sideBar.width;
336
- const slotOffset = slot * (DuoMetrics.controlSize + Spacing.M);
337
- const top = sideBar.top - headerStatusBarHeight + slotOffset;
341
+ const top =
342
+ sideBar.top -
343
+ headerStatusBarHeight +
344
+ slot * (DuoMetrics.controlSize + Spacing.M);
338
345
  const innerEdgeStyle = InnerEdgeStyles[sideBar.edge];
339
346
 
340
347
  if (container === 'left') {
@@ -357,13 +364,6 @@ const useSideBarItemStyle = (
357
364
  };
358
365
  };
359
366
 
360
- /** Column count of the content grid: 24 on content wider than 600pt, otherwise 12. */
361
- const useGridSystem = () => {
362
- const { contentWidth } = useScreenLayout();
363
- const numberOfColumns = contentWidth > 600 ? 24 : 12;
364
- return { numberOfColumns };
365
- };
366
-
367
367
  export type { ScreenLayout, SideBarEdge, SideBarLayout, StatusBarClearance };
368
368
 
369
369
  export {
@@ -372,7 +372,6 @@ export {
372
372
  InnerEdgeStyles,
373
373
  getHeaderMargin,
374
374
  getHeaderRowOptions,
375
- useGridSystem,
376
375
  useScreenLayout,
377
376
  useSideBarItemStyle,
378
377
  validateChildren,
@@ -6,10 +6,6 @@ import { ApplicationContext } from '../Context';
6
6
  import { hexToRGBA } from './utils';
7
7
  import { LoaderProps } from './types';
8
8
 
9
- /**
10
- * Three-dot Lottie loader recolored to `color` (theme primary by default).
11
- * Recoloring mutates the shared animation JSON, so `Loader` remounts on change.
12
- */
13
9
  const DotLoader: FC<LoaderProps> = ({ color, style }) => {
14
10
  const { theme } = useContext(ApplicationContext);
15
11
 
package/Loader/Loader.tsx CHANGED
@@ -3,10 +3,6 @@ import {LoaderProps} from './types';
3
3
  import DotLoader from './DotLoader';
4
4
  import Spinner from './Spinner';
5
5
 
6
- /**
7
- * Dot (default) or spinner loader. Keyed by `color` so a color change remounts
8
- * the Lottie view with the recolored source.
9
- */
10
6
  const Loader: FC<LoaderProps> = ({type = 'dot', ...props}) => {
11
7
  if (type === 'spinner') {
12
8
  return <Spinner {...props} key={props.color} />;
@@ -9,7 +9,6 @@ import styles from './styles';
9
9
  import { ProgressBarProps } from './types';
10
10
  import { ApplicationContext } from '../Context';
11
11
 
12
- /** Full-width bar that animates its fill to `percent`, clamped to 0–100. */
13
12
  const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
14
13
  const { theme } = useContext(ApplicationContext);
15
14
  const animation = useSharedValue(0);
@@ -6,10 +6,6 @@ import { hexToRGBA } from './utils';
6
6
  import { ApplicationContext } from '../Context';
7
7
  import { LoaderProps } from './types';
8
8
 
9
- /**
10
- * Lottie spinner recolored to `color` (theme primary by default).
11
- * Recoloring mutates the shared animation JSON, so `Loader` remounts on change.
12
- */
13
9
  const Spinner: FC<LoaderProps> = ({ color, style }) => {
14
10
  const { theme } = useContext(ApplicationContext);
15
11
 
package/Loader/utils.ts CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * Converts `#rgb`/`#rrggbb` (the `#` is optional) to Lottie's `[r, g, b]` in
3
- * 0–1, rounded to 3 decimals. Throws on an invalid hex.
4
- */
5
1
  export const hexToRGBA = (hex: string) => {
6
2
  const normalizedHex = hex.startsWith('#') ? hex.slice(1) : hex;
7
3
 
@@ -9,13 +5,13 @@ export const hexToRGBA = (hex: string) => {
9
5
  throw new Error('Invalid HEX color.');
10
6
  }
11
7
 
12
- let expandedHex = normalizedHex;
13
- if (normalizedHex.length === 3) {
14
- expandedHex = normalizedHex
15
- .split('')
16
- .map(val => val + val)
17
- .join('');
18
- }
8
+ const expandedHex =
9
+ normalizedHex.length === 3
10
+ ? normalizedHex
11
+ .split('')
12
+ .map(val => val + val)
13
+ .join('')
14
+ : normalizedHex;
19
15
 
20
16
  const hexMatch = expandedHex.match(/.{2}/g);
21
17
 
@@ -4,10 +4,6 @@ import styles from './styles';
4
4
  import { DotProps } from './types';
5
5
  import { ApplicationContext } from '../Context';
6
6
 
7
- /**
8
- * One pagination dot: a wide bar in the caller's color when active, otherwise
9
- * a small dot in the theme pressed color.
10
- */
11
7
  const Dot: FC<DotProps> = ({ active, style }) => {
12
8
  const { theme } = useContext(ApplicationContext);
13
9
  const pressedColor = theme.colors.background.pressed;
@@ -6,7 +6,6 @@ import styles from './styles';
6
6
  import { Spacing } from '../Consts';
7
7
  import { ApplicationContext, MiniAppContext } from '../Context';
8
8
 
9
- /** Row of primary-color dots with the `activeIndex` dot widened. */
10
9
  const PaginationDot: FC<ChildPaginationProps> = ({
11
10
  dataLength = 2,
12
11
  activeIndex = 0,
@@ -6,7 +6,6 @@ import { Text } from '../Text';
6
6
  import { Colors } from '../Consts';
7
7
  import { MiniAppContext } from '../Context';
8
8
 
9
- /** `n/total` counter on a translucent dark pill. */
10
9
  const PaginationNumber: FC<ChildPaginationProps> = ({
11
10
  activeIndex = 0,
12
11
  dataLength = 2,
@@ -15,16 +14,15 @@ const PaginationNumber: FC<ChildPaginationProps> = ({
15
14
  const context = useContext<any>(MiniAppContext);
16
15
 
17
16
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
18
- const pageLabel = `${activeIndex + 1}/${dataLength}`;
19
17
 
20
18
  return (
21
19
  <View
22
20
  style={[style, styles.row, showBaseLineDebug && styles.debugBaseLine]}
23
21
  >
24
22
  <View style={styles.paginationNumberContainer}>
25
- <Text color={Colors.black_01} typography={'label_default_medium'}>
26
- {pageLabel}
27
- </Text>
23
+ <Text color={Colors.black_01} typography={'label_default_medium'}>{`${
24
+ activeIndex + 1
25
+ }/${dataLength}`}</Text>
28
26
  </View>
29
27
  </View>
30
28
  );
@@ -13,11 +13,6 @@ import { ApplicationContext, MiniAppContext } from '../Context';
13
13
 
14
14
  const INDICATOR_WIDTH = 24;
15
15
  const INDICATOR_CONTAINER_WIDTH = 72;
16
-
17
- /**
18
- * Horizontal scroll view with a small indicator that tracks the scroll offset.
19
- * The indicator shows only when the content is wider than the view.
20
- */
21
16
  const PaginationScroll: FC<ScrollIndicatorProps> = ({
22
17
  style,
23
18
  children,
@@ -6,7 +6,6 @@ import Dot from './Dot';
6
6
  import { Colors, Spacing } from '../Consts';
7
7
  import { MiniAppContext } from '../Context';
8
8
 
9
- /** Pagination dots on a translucent dark pill, for use over images. */
10
9
  const PaginationWhiteDot: FC<ChildPaginationProps> = ({
11
10
  dataLength = 2,
12
11
  activeIndex = 0,