@momo-kits/foundation 0.154.2-beta.1 → 0.154.2-beta.4
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.
|
@@ -29,8 +29,8 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
29
29
|
const { width: screenWidth } = Dimensions.get('window');
|
|
30
30
|
|
|
31
31
|
const animated = useRef(new Animated.Value(0));
|
|
32
|
-
const leftPosition = props?.leftPosition
|
|
33
|
-
const headerRightWidth = props?.headerRightWidth
|
|
32
|
+
const leftPosition = props?.leftPosition || BACK_WIDTH + 20;
|
|
33
|
+
const headerRightWidth = props?.headerRightWidth || 73;
|
|
34
34
|
|
|
35
35
|
useEffect(() => {
|
|
36
36
|
const listener = animatedValue?.addListener(({ value }) => {
|
|
@@ -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
|
|
|
@@ -111,6 +112,11 @@ const StackScreen: React.FC<any> = props => {
|
|
|
111
112
|
);
|
|
112
113
|
}
|
|
113
114
|
});
|
|
115
|
+
} else {
|
|
116
|
+
navigator?.maxApi?.setDataObserver?.('current_screen', {
|
|
117
|
+
screenName,
|
|
118
|
+
startTime,
|
|
119
|
+
});
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
navigator?.maxApi?.startTraceScreenLoad?.(
|
|
@@ -407,8 +413,11 @@ const StackScreen: React.FC<any> = props => {
|
|
|
407
413
|
},
|
|
408
414
|
}}
|
|
409
415
|
>
|
|
410
|
-
<
|
|
411
|
-
|
|
416
|
+
<TooltipPortalProvider>
|
|
417
|
+
<Component heightHeader={heightHeader} {...data} />
|
|
418
|
+
{showGrid && <GridSystem />}
|
|
419
|
+
<TooltipPortalHost />
|
|
420
|
+
</TooltipPortalProvider>
|
|
412
421
|
</ScreenContext.Provider>
|
|
413
422
|
);
|
|
414
423
|
};
|
|
@@ -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<NodeJS.Timeout | null>(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
|
+
});
|
package/Application/index.ts
CHANGED
|
@@ -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
|
};
|