@momo-kits/foundation 0.169.3 → 0.169.4-beta.2

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.
@@ -17,7 +17,7 @@ import { CurvedContainer } from './CurvedContainer';
17
17
  import { ActiveIndicator } from './ActiveIndicator';
18
18
  import { getHorizontalBarWidth, TabBarMetrics, TabBarMotion } from './metrics';
19
19
  import { getTabItems, TabItem } from './tabItems';
20
- import { FixedScaleText } from './TabBarIcon';
20
+ import { CappedScaleText } from './TabBarIcon';
21
21
  import { styles } from './BottomTabBar.styles';
22
22
 
23
23
  type Props = BottomTabBarProps & {
@@ -114,7 +114,7 @@ const CenterAction: React.FC<{
114
114
  </Animated.View>
115
115
  <View style={styles.ctaLabel}>
116
116
  {fixedFontScale ? (
117
- <FixedScaleText>{labelText}</FixedScaleText>
117
+ <CappedScaleText>{labelText}</CappedScaleText>
118
118
  ) : (
119
119
  labelText
120
120
  )}
@@ -194,21 +194,17 @@ const HorizontalTabBar: React.FC<{
194
194
  return renderItems(items);
195
195
  };
196
196
 
197
- const customContainer = withCta && floatingButton?.container;
198
-
199
197
  return (
200
198
  <View
201
199
  style={[styles.container, { width }]}
202
200
  accessibilityLabel={'bottom_tab_bar'}
203
201
  >
204
- {customContainer || (
205
- <CurvedContainer
206
- width={width}
207
- height={TabBarMetrics.height}
208
- radius={TabBarMetrics.height / 2}
209
- notchCenterX={withCta ? width / 2 : undefined}
210
- />
211
- )}
202
+ <CurvedContainer
203
+ width={width}
204
+ height={TabBarMetrics.height}
205
+ radius={TabBarMetrics.height / 2}
206
+ notchCenterX={withCta ? width / 2 : undefined}
207
+ />
212
208
  <View style={styles.content}>
213
209
  <ActiveIndicator
214
210
  axis={'x'}
@@ -258,6 +254,7 @@ export default function BottomTabBar(props: Props) {
258
254
  ]}
259
255
  >
260
256
  <HorizontalTabBar
257
+ fixedFontScale
261
258
  items={getTabItems(props)}
262
259
  width={width}
263
260
  floatingButton={floatingButton}
@@ -10,7 +10,7 @@ import Animated, {
10
10
  useSharedValue,
11
11
  withTiming,
12
12
  } from 'react-native-reanimated';
13
- import { FixedScaleText, TabBarIcon } from './TabBarIcon';
13
+ import { CappedScaleText, TabBarIcon } from './TabBarIcon';
14
14
  import { Text } from '../../Text';
15
15
  import { MiniAppContext } from '../../Context';
16
16
  import { Colors, Spacing } from '../../Consts';
@@ -98,7 +98,7 @@ const TabItemContent: React.FC<TabItemContentProps> = ({
98
98
  />
99
99
  </View>
100
100
  {!hideLabel &&
101
- (fixedFontScale ? <FixedScaleText>{text}</FixedScaleText> : text)}
101
+ (fixedFontScale ? <CappedScaleText>{text}</CappedScaleText> : text)}
102
102
  </>
103
103
  );
104
104
  };
@@ -166,6 +166,11 @@ const styles = StyleSheet.create({
166
166
  },
167
167
  labelBox: {
168
168
  alignSelf: 'stretch',
169
+ // fixed to the design line height so a capped-scale label overflows downward and the
170
+ // icon above it stays put
171
+ height: TabBarMetrics.labelHeight,
172
+ justifyContent: 'flex-start',
173
+ overflow: 'visible',
169
174
  },
170
175
  label: {
171
176
  textAlign: 'center',
@@ -13,7 +13,7 @@ import { TabItemContent } from './CustomBottomTabItem';
13
13
  import { CurvedContainer } from './CurvedContainer';
14
14
  import { TabBarMetrics } from './metrics';
15
15
  import { getTabItems, TabItem } from './tabItems';
16
- import { FixedScaleText } from './TabBarIcon';
16
+ import { CappedScaleText } from './TabBarIcon';
17
17
  import { usePressLift } from './usePressLift';
18
18
  import { ActiveIndicator } from './ActiveIndicator';
19
19
  import {
@@ -116,7 +116,7 @@ const RailCenterAction: React.FC<{ floatingButton: FloatingButtonProps }> = ({
116
116
  <CtaIcon icon={floatingButton.icon} />
117
117
  </Animated.View>
118
118
  <View style={styles.railCtaLabel}>
119
- <FixedScaleText>
119
+ <CappedScaleText>
120
120
  <Text
121
121
  numberOfLines={1}
122
122
  typography={'label_xs_medium'}
@@ -124,7 +124,7 @@ const RailCenterAction: React.FC<{ floatingButton: FloatingButtonProps }> = ({
124
124
  >
125
125
  {floatingButton.label}
126
126
  </Text>
127
- </FixedScaleText>
127
+ </CappedScaleText>
128
128
  {floatingButton.labelContent && (
129
129
  <View pointerEvents={'none'} style={styles.railCtaLabelOverlay}>
130
130
  {floatingButton.labelContent}
@@ -71,6 +71,30 @@ export const FixedScaleText: React.FC<{ children: React.ReactNode }> = ({
71
71
  );
72
72
  };
73
73
 
74
+ // the tab labels follow the OS/host font scale but never grow past this, so the fixed-height
75
+ // container and the notch stay aligned
76
+ const TAB_LABEL_MAX_SCALE = 1.2;
77
+
78
+ /**
79
+ * caps the label scale at `TAB_LABEL_MAX_SCALE`: it keeps following the host/OS font scale but
80
+ * stops growing past 1.2× so it fits the fixed bar geometry
81
+ */
82
+ export const CappedScaleText: React.FC<{ children: React.ReactNode }> = ({
83
+ children,
84
+ }) => {
85
+ const context = useContext<any>(MiniAppContext);
86
+ return (
87
+ <MiniAppContext.Provider
88
+ value={{
89
+ ...context,
90
+ fontScale: { ...context?.fontScale, maxScaleRate: TAB_LABEL_MAX_SCALE },
91
+ }}
92
+ >
93
+ {children}
94
+ </MiniAppContext.Provider>
95
+ );
96
+ };
97
+
74
98
  /**
75
99
  * numbers use the error color, text the warning color (Figma Badge round numeric / text)
76
100
  */
@@ -20,6 +20,9 @@ const TabBarMetrics = {
20
20
  indicatorPaddingHorizontal: Spacing.M,
21
21
  indicatorRadius: Radius.XL,
22
22
  indicatorHeight: 32,
23
+ // label_s_medium line height: the label box keeps this height so a scaled label grows
24
+ // downward instead of pushing the icon up
25
+ labelHeight: 18,
23
26
  // home indicator / gesture bar area under the container
24
27
  systemIndicatorHeight: 24,
25
28
  // unfolded foldables (short side from 600, the smallest in the spec) use 65% of the short
@@ -36,7 +36,6 @@ export type BottomTabProps = {
36
36
  };
37
37
 
38
38
  export type FloatingButtonProps = {
39
- container?: React.ReactNode;
40
39
  icon: string | React.ReactNode;
41
40
  label: string;
42
41
  onPress: () => void;
package/Text/utils.ts CHANGED
@@ -9,13 +9,18 @@ const MAX_DEVICE_SCALE = 5;
9
9
  const useScaleSize = (size: number, scaleRate?: number) => {
10
10
  const { width } = useWindowDimensions();
11
11
  const context = useContext<any>(MiniAppContext);
12
+ // opt-in ceiling: when set (arg or context), the final size never exceeds size × capRate,
13
+ // in both the mini-app userScaleRate path and the OS path. Undefined keeps the old behavior.
14
+ const capRate = scaleRate ?? context?.fontScale?.maxScaleRate;
15
+ const cap = (scaled: number) =>
16
+ capRate != null ? Math.min(scaled, size * capRate) : scaled;
12
17
  if (context?.fontScale?.useOSScaleRate === false) {
13
- return size * (context.fontScale.userScaleRate ?? 1);
18
+ return cap(size * (context.fontScale.userScaleRate ?? 1));
14
19
  }
15
20
  const fontScale = PixelRatio.getFontScale();
16
21
  const deviceScale = width / DEFAULT_SCREEN_SIZE;
17
22
 
18
- const maxScaleRate = scaleRate ?? MAX_FONT_SCALE;
23
+ const maxScaleRate = capRate ?? MAX_FONT_SCALE;
19
24
 
20
25
  let fontSizeDeviceScale = size;
21
26
  let fontSizeOSScale = size;
@@ -34,7 +39,7 @@ const useScaleSize = (size: number, scaleRate?: number) => {
34
39
  );
35
40
  }
36
41
 
37
- return Math.max(fontSizeDeviceScale, fontSizeOSScale);
42
+ return cap(Math.max(fontSizeDeviceScale, fontSizeOSScale));
38
43
  };
39
44
 
40
45
  const scaleSize = (size: number) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.169.3",
3
+ "version": "0.169.4-beta.2",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},