@momo-kits/foundation 0.155.1-ds365.1 → 0.156.1-alpha.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.
@@ -7,6 +7,7 @@ import { ApplicationContext, MiniAppContext, ScreenContext } from '../Context';
7
7
  import { GridSystem } from '../Layout';
8
8
  import { version } from '../package.json';
9
9
  import { useAppState } from './utils';
10
+ import { TooltipPortalHost, TooltipPortalProvider } from './TooltipPortal.tsx';
10
11
 
11
12
  const runAfterInteractions = InteractionManager.runAfterInteractions;
12
13
 
@@ -407,8 +408,11 @@ const StackScreen: React.FC<any> = props => {
407
408
  },
408
409
  }}
409
410
  >
410
- <Component heightHeader={heightHeader} {...data} />
411
- {showGrid && <GridSystem />}
411
+ <TooltipPortalProvider>
412
+ <Component heightHeader={heightHeader} {...data} />
413
+ {showGrid && <GridSystem />}
414
+ <TooltipPortalHost />
415
+ </TooltipPortalProvider>
412
416
  </ScreenContext.Provider>
413
417
  );
414
418
  };
@@ -0,0 +1,125 @@
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useCallback,
5
+ ReactNode,
6
+ useMemo,
7
+ useReducer,
8
+ useRef,
9
+ RefObject,
10
+ } from 'react';
11
+ import { View, StyleSheet } from 'react-native';
12
+
13
+ interface TooltipPortalContextValue {
14
+ register: (id: string, content: ReactNode) => void;
15
+ unregister: (id: string, immediate?: boolean) => void;
16
+ portals: Map<string, ReactNode>;
17
+ hostRef: RefObject<View | null>;
18
+ }
19
+
20
+ const TooltipPortalContext = createContext<TooltipPortalContextValue | null>(
21
+ null,
22
+ );
23
+
24
+ export const TooltipPortalProvider: React.FC<{ children: ReactNode }> = ({
25
+ children,
26
+ }) => {
27
+ // Use ref for synchronous updates + reducer for manual re-renders
28
+ const portalsRef = useRef<Map<string, ReactNode>>(new Map());
29
+ const hostRef = useRef<View>(null);
30
+ const [updateCounter, forceUpdate] = useReducer((x: number) => x + 1, 0);
31
+ const pendingUpdateRef = useRef<any>(null);
32
+
33
+ const register = useCallback((id: string, content: ReactNode) => {
34
+ portalsRef.current.set(id, content);
35
+ forceUpdate(); // Trigger re-render to show new content
36
+ }, []);
37
+
38
+ const unregister = useCallback((id: string, immediate = false) => {
39
+ const hasItem = portalsRef.current.has(id);
40
+ if (!hasItem) return; // Already removed
41
+
42
+ portalsRef.current.delete(id);
43
+
44
+ // Clear any pending updates
45
+ if (pendingUpdateRef.current) {
46
+ clearTimeout(pendingUpdateRef.current);
47
+ pendingUpdateRef.current = null;
48
+ }
49
+
50
+ if (immediate) {
51
+ forceUpdate();
52
+ } else {
53
+ // Debounce normal updates to avoid excessive re-renders
54
+ pendingUpdateRef.current = setTimeout(() => {
55
+ forceUpdate();
56
+ pendingUpdateRef.current = null;
57
+ }, 0) as unknown as NodeJS.Timeout;
58
+ }
59
+ }, []);
60
+
61
+ const value = useMemo(
62
+ () => ({ register, unregister, portals: portalsRef.current, hostRef }),
63
+ [register, unregister, updateCounter], // Include updateCounter to refresh context
64
+ );
65
+
66
+ return (
67
+ <TooltipPortalContext.Provider value={value}>
68
+ {children}
69
+ </TooltipPortalContext.Provider>
70
+ );
71
+ };
72
+
73
+ export const TooltipPortalHost: React.FC = () => {
74
+ const context = useContext(TooltipPortalContext);
75
+
76
+ if (!context) {
77
+ if (__DEV__) {
78
+ console.warn(
79
+ 'TooltipPortalHost must be used within TooltipPortalProvider',
80
+ );
81
+ }
82
+ return null;
83
+ }
84
+
85
+ const { portals, hostRef } = context;
86
+
87
+ return (
88
+ <View ref={hostRef} style={styles.hostContainer} pointerEvents="box-none">
89
+ {Array.from(portals.entries()).map(([id, content]) => (
90
+ <React.Fragment key={id}>{content}</React.Fragment>
91
+ ))}
92
+ </View>
93
+ );
94
+ };
95
+
96
+ export const useTooltipPortal = () => {
97
+ const context = useContext(TooltipPortalContext);
98
+
99
+ if (!context) {
100
+ if (__DEV__) {
101
+ console.warn(
102
+ 'useTooltipPortal must be used within TooltipPortalProvider. Tooltips may not appear correctly.',
103
+ );
104
+ }
105
+ // Return no-op functions if context is missing
106
+ return {
107
+ register: () => {},
108
+ unregister: () => {},
109
+ hostRef: null,
110
+ };
111
+ }
112
+
113
+ return context;
114
+ };
115
+
116
+ const styles = StyleSheet.create({
117
+ hostContainer: {
118
+ position: 'absolute',
119
+ top: 0,
120
+ left: 0,
121
+ right: 0,
122
+ bottom: 0,
123
+ zIndex: 9999,
124
+ },
125
+ });
@@ -17,6 +17,7 @@ import { exportHeaderTitle, setAutomationID, useComponentId } from './utils';
17
17
  import Navigation from './Navigation';
18
18
  import Navigator from './Navigator';
19
19
  import ScaleSizeProvider from './ScaleSizeProvider';
20
+ import { useTooltipPortal } from './TooltipPortal';
20
21
 
21
22
  export {
22
23
  NavigationContainer,
@@ -29,4 +30,5 @@ export {
29
30
  Navigator,
30
31
  exportHeaderTitle,
31
32
  ScaleSizeProvider,
33
+ useTooltipPortal,
32
34
  };
package/Input/Input.tsx CHANGED
@@ -194,7 +194,7 @@ const Input = forwardRef(
194
194
  color: textColor,
195
195
  fontFamily: exportFontFamily(fontWeight ?? 'regular'),
196
196
  },
197
- secure && haveValue && { fontSize: scaledFontSize },
197
+ secure && haveValue && { fontSize: size === 'small' ? 18 : 22 },
198
198
  ]}
199
199
  defaultValue={defaultValue}
200
200
  allowFontScaling={false}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.155.1-ds365.1",
3
+ "version": "0.156.1-alpha.1",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},