@mpxjs/webpack-plugin 2.10.14-beta.4 → 2.10.14-beta.6

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 (92) hide show
  1. package/lib/platform/template/wx/component-config/index.js +3 -1
  2. package/lib/platform/template/wx/component-config/nav-container.js +27 -0
  3. package/lib/runtime/components/ali/mpx-nav-container.mpx +3 -0
  4. package/lib/runtime/components/react/context.ts +17 -6
  5. package/lib/runtime/components/react/dist/context.d.ts +78 -0
  6. package/lib/runtime/components/react/dist/context.js +1 -0
  7. package/lib/runtime/components/react/dist/event.config.d.ts +7 -0
  8. package/lib/runtime/components/react/dist/getInnerListeners.d.ts +7 -0
  9. package/lib/runtime/components/react/dist/mpx-async-suspense.d.ts +12 -0
  10. package/lib/runtime/components/react/dist/mpx-button.d.ts +68 -0
  11. package/lib/runtime/components/react/dist/mpx-canvas/Bus.d.ts +23 -0
  12. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.d.ts +7 -0
  13. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.d.ts +6 -0
  14. package/lib/runtime/components/react/dist/mpx-canvas/Image.d.ts +20 -0
  15. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.d.ts +8 -0
  16. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.d.ts +10 -0
  17. package/lib/runtime/components/react/dist/mpx-canvas/html.d.ts +2 -0
  18. package/lib/runtime/components/react/dist/mpx-canvas/index.d.ts +32 -0
  19. package/lib/runtime/components/react/dist/mpx-canvas/utils.d.ts +52 -0
  20. package/lib/runtime/components/react/dist/mpx-checkbox-group.d.ts +20 -0
  21. package/lib/runtime/components/react/dist/mpx-checkbox.d.ts +32 -0
  22. package/lib/runtime/components/react/dist/mpx-form.d.ts +27 -0
  23. package/lib/runtime/components/react/dist/mpx-icon/index.d.ts +18 -0
  24. package/lib/runtime/components/react/dist/mpx-image.d.ts +21 -0
  25. package/lib/runtime/components/react/dist/mpx-inline-text.d.ts +7 -0
  26. package/lib/runtime/components/react/dist/mpx-input.d.ts +49 -0
  27. package/lib/runtime/components/react/dist/mpx-input.jsx +28 -9
  28. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.d.ts +12 -0
  29. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +52 -51
  30. package/lib/runtime/components/react/dist/mpx-label.d.ts +20 -0
  31. package/lib/runtime/components/react/dist/mpx-movable-area.d.ts +20 -0
  32. package/lib/runtime/components/react/dist/mpx-movable-view.d.ts +63 -0
  33. package/lib/runtime/components/react/dist/mpx-nav-container.d.ts +9 -0
  34. package/lib/runtime/components/react/dist/mpx-nav-container.jsx +23 -0
  35. package/lib/runtime/components/react/dist/mpx-navigator.d.ts +9 -0
  36. package/lib/runtime/components/react/dist/mpx-picker/date.d.ts +6 -0
  37. package/lib/runtime/components/react/dist/mpx-picker/dateData.d.ts +7 -0
  38. package/lib/runtime/components/react/dist/mpx-picker/index.d.ts +6 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.d.ts +6 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/region.d.ts +6 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/regionData.d.ts +2 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/selector.d.ts +6 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/time.d.ts +6 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +106 -0
  45. package/lib/runtime/components/react/dist/mpx-picker-view/index.d.ts +31 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view/pickerVIewContext.d.ts +8 -0
  47. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.d.ts +22 -0
  48. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.d.ts +14 -0
  49. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewFaces.d.ts +16 -0
  50. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewIndicator.d.ts +12 -0
  51. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewMask.d.ts +11 -0
  52. package/lib/runtime/components/react/dist/mpx-popup/index.d.ts +22 -0
  53. package/lib/runtime/components/react/dist/mpx-popup/popupBase.d.ts +16 -0
  54. package/lib/runtime/components/react/dist/mpx-portal/index.d.ts +15 -0
  55. package/lib/runtime/components/react/dist/mpx-portal/portal-host.d.ts +29 -0
  56. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.d.ts +9 -0
  57. package/lib/runtime/components/react/dist/mpx-radio-group.d.ts +20 -0
  58. package/lib/runtime/components/react/dist/mpx-radio.d.ts +26 -0
  59. package/lib/runtime/components/react/dist/mpx-rich-text/html.d.ts +1 -0
  60. package/lib/runtime/components/react/dist/mpx-rich-text/index.d.ts +24 -0
  61. package/lib/runtime/components/react/dist/mpx-root-portal.d.ts +14 -0
  62. package/lib/runtime/components/react/dist/mpx-scroll-view.d.ts +54 -0
  63. package/lib/runtime/components/react/dist/mpx-simple-text.d.ts +7 -0
  64. package/lib/runtime/components/react/dist/mpx-simple-view.d.ts +7 -0
  65. package/lib/runtime/components/react/dist/mpx-sticky-header.d.ts +17 -0
  66. package/lib/runtime/components/react/dist/mpx-sticky-section.d.ts +15 -0
  67. package/lib/runtime/components/react/dist/mpx-swiper-item.d.ts +18 -0
  68. package/lib/runtime/components/react/dist/mpx-swiper.d.ts +52 -0
  69. package/lib/runtime/components/react/dist/mpx-switch.d.ts +26 -0
  70. package/lib/runtime/components/react/dist/mpx-text.d.ts +21 -0
  71. package/lib/runtime/components/react/dist/mpx-textarea.d.ts +7 -0
  72. package/lib/runtime/components/react/dist/mpx-video.d.ts +101 -0
  73. package/lib/runtime/components/react/dist/mpx-view.d.ts +34 -0
  74. package/lib/runtime/components/react/dist/mpx-web-view.d.ts +22 -0
  75. package/lib/runtime/components/react/dist/nav.d.ts +8 -0
  76. package/lib/runtime/components/react/dist/nav.jsx +137 -0
  77. package/lib/runtime/components/react/dist/parser.d.ts +39 -0
  78. package/lib/runtime/components/react/dist/useAnimationHooks.d.ts +32 -0
  79. package/lib/runtime/components/react/dist/useNavShared.d.ts +2 -0
  80. package/lib/runtime/components/react/dist/useNavShared.js +6 -0
  81. package/lib/runtime/components/react/dist/useNodesRef.d.ts +11 -0
  82. package/lib/runtime/components/react/dist/utils.d.ts +122 -0
  83. package/lib/runtime/components/react/mpx-input.tsx +35 -16
  84. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +58 -59
  85. package/lib/runtime/components/react/mpx-nav-container.tsx +33 -0
  86. package/lib/runtime/components/react/nav.tsx +163 -0
  87. package/lib/runtime/components/react/types/common.d.ts +19 -0
  88. package/lib/runtime/components/react/useNavShared.ts +8 -0
  89. package/lib/runtime/components/web/mpx-nav-container.vue +13 -0
  90. package/lib/runtime/components/wx/mpx-nav-container.mpx +9 -0
  91. package/lib/utils/dom-tag-config.js +2 -2
  92. package/package.json +1 -1
@@ -0,0 +1,137 @@
1
+ /* eslint-disable space-before-function-paren */
2
+ import { useState, useMemo, memo } from 'react';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+ import { StatusBar, processColor, TouchableWithoutFeedback, Image, View, StyleSheet, Text } from 'react-native';
5
+ import { useNavShared } from './useNavShared';
6
+ function convertToHex(color) {
7
+ try {
8
+ const intColor = processColor(color);
9
+ if (intColor === null || intColor === undefined) {
10
+ return null;
11
+ }
12
+ // 将32位整数颜色值转换为RGBA
13
+ const r = (intColor >> 16) & 255;
14
+ const g = (intColor >> 8) & 255;
15
+ const b = intColor & 255;
16
+ // 转换为十六进制
17
+ const hexR = r.toString(16).padStart(2, '0');
18
+ const hexG = g.toString(16).padStart(2, '0');
19
+ const hexB = b.toString(16).padStart(2, '0');
20
+ return `#${hexR}${hexG}${hexB}`;
21
+ }
22
+ catch (error) {
23
+ return null;
24
+ }
25
+ }
26
+ const titleHeight = 44;
27
+ export function useInnerHeaderHeight(pageConfig) {
28
+ const safeArea = useSafeAreaInsets();
29
+ if (pageConfig.navigationStyle === 'custom') {
30
+ return 0;
31
+ }
32
+ else {
33
+ const safeAreaTop = safeArea?.top || 0;
34
+ const headerHeight = safeAreaTop + titleHeight;
35
+ return headerHeight;
36
+ }
37
+ }
38
+ const styles = StyleSheet.create({
39
+ header: {
40
+ elevation: 3
41
+ },
42
+ headerContent: {
43
+ flexDirection: 'row',
44
+ alignItems: 'center',
45
+ justifyContent: 'center'
46
+ },
47
+ backButton: {
48
+ position: 'absolute',
49
+ height: '100%',
50
+ width: 40,
51
+ left: 0,
52
+ top: 0,
53
+ alignItems: 'center',
54
+ justifyContent: 'center'
55
+ },
56
+ backButtonImage: {
57
+ width: 22,
58
+ height: 22
59
+ },
60
+ title: {
61
+ fontSize: 17,
62
+ fontWeight: 600,
63
+ width: '60%',
64
+ textAlign: 'center'
65
+ }
66
+ });
67
+ const NavColor = {
68
+ White: '#ffffff',
69
+ Black: '#000000'
70
+ };
71
+ // navigationBarTextStyle 只支持黑白 'white'/'black
72
+ const validBarTextStyle = (textStyle) => {
73
+ const textStyleColor = convertToHex(textStyle);
74
+ if (textStyle && textStyleColor && [NavColor.White, NavColor.Black].includes(textStyleColor)) {
75
+ return textStyleColor;
76
+ }
77
+ else {
78
+ return NavColor.White;
79
+ }
80
+ };
81
+ const BACK_ICON = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAABICAYAAACqT5alAAAA2UlEQVR4nO3bMQrCUBRE0Yla6AYEN2nnBrTL+izcitW3MRDkEUWSvPzJvfCqgMwhZbAppWhNbbIHzB1g9wATERFRVyvpkj1irlpJ5X326D7WHh1hbdFD2CLpLmmftm7kfsEe09aNHFiBrT+wAlt/YAW2/sAKbP2BFdj6Ayuwy+ufz6XPL893krZ//O6iu2n4LT8kndLWTRTo4EC7BDo40C6BDg60S6CDA+0S6OBAuwQ6uNWiD2nrJmoIfU7cNWkR2hbb1UfbY7uuWhGWiIg+a/iHuHmA3QPs3gu4JW9Gan+OJAAAAABJRU5ErkJggg==';
82
+ const MpxNav = memo(({ pageConfig, navigation }) => {
83
+ const [innerPageConfig, setPageConfig] = useState(pageConfig || {});
84
+ const [customNav] = useNavShared();
85
+ const safeAreaTop = useSafeAreaInsets()?.top || 0;
86
+ navigation.setPageConfig = (config) => {
87
+ setPageConfig(Object.assign({}, innerPageConfig, config));
88
+ };
89
+ const isCustom = innerPageConfig.navigationStyle === 'custom';
90
+ const navigationBarTextStyle = useMemo(() => validBarTextStyle(innerPageConfig.navigationBarTextStyle), [innerPageConfig.navigationBarTextStyle]);
91
+ // 状态栏的颜色
92
+ const statusBarElement = (<StatusBar translucent backgroundColor='transparent' barStyle={navigationBarTextStyle === NavColor.White ? 'light-content' : 'dark-content'}></StatusBar>);
93
+ if (isCustom)
94
+ return (<>
95
+ {statusBarElement}
96
+ {customNav}
97
+ </>);
98
+ // 假设是栈导航,获取栈的长度
99
+ const stackLength = navigation.getState()?.routes?.length;
100
+ const onStackTopBack = mpxGlobal?.__mpx?.config?.rnConfig?.onStackTopBack;
101
+ const isHandleStackTopBack = typeof onStackTopBack === 'function';
102
+ // 回退按钮与图标
103
+ // prettier-ignore
104
+ const backElement = stackLength > 1 || isHandleStackTopBack
105
+ ? (<TouchableWithoutFeedback onPress={() => {
106
+ if (stackLength <= 1 && isHandleStackTopBack) {
107
+ onStackTopBack();
108
+ return;
109
+ }
110
+ navigation.goBack();
111
+ }}>
112
+ <View style={[styles.backButton]}>
113
+ <Image style={[styles.backButtonImage, { tintColor: navigationBarTextStyle }]} source={{ uri: BACK_ICON }}></Image>
114
+ </View>
115
+ </TouchableWithoutFeedback>)
116
+ : null;
117
+ return (<View style={[
118
+ styles.header,
119
+ {
120
+ paddingTop: safeAreaTop,
121
+ backgroundColor: innerPageConfig.navigationBarBackgroundColor || '#000000'
122
+ }
123
+ ]}>
124
+ {statusBarElement}
125
+ {/* TODO: 确定 height 的有效性 */}
126
+ {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
127
+ {/* @ts-expect-error */}
128
+ <View style={styles.headerContent} height={titleHeight}>
129
+ {backElement}
130
+ <Text style={[styles.title, { color: navigationBarTextStyle }]} numberOfLines={1}>
131
+ {innerPageConfig.navigationBarTitleText?.trim() || ''}
132
+ </Text>
133
+ </View>
134
+ </View>);
135
+ });
136
+ MpxNav.displayName = 'MpxNav';
137
+ export default MpxNav;
@@ -0,0 +1,39 @@
1
+ interface Token {
2
+ type: string;
3
+ value: string | number;
4
+ }
5
+ interface ExpressionNode {
6
+ type: 'NUMBER';
7
+ value: number;
8
+ }
9
+ export declare class ExpressionParser {
10
+ private tokens;
11
+ private formatter;
12
+ private functions;
13
+ private current;
14
+ constructor(input: string, formatter?: (val: string) => number, functions?: {
15
+ [key: string]: (...args: number[]) => number;
16
+ });
17
+ tokenize(input: string): Token[];
18
+ parse(): ExpressionNode;
19
+ private expression;
20
+ private term;
21
+ private factor;
22
+ private parseArguments;
23
+ private applyOperator;
24
+ private applyFunction;
25
+ }
26
+ interface FuncInfo {
27
+ start: number;
28
+ end: number;
29
+ args: string[];
30
+ }
31
+ export declare function parseFunc(str: string, funcName: string): FuncInfo[];
32
+ export declare class ReplaceSource {
33
+ private _source;
34
+ private _replacements;
35
+ constructor(source: string);
36
+ replace(start: number, end: number, content: string): void;
37
+ source(): string;
38
+ }
39
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import type { NativeSyntheticEvent } from 'react-native';
3
+ import { ExtendedViewStyle } from './types/common';
4
+ import type { _ViewProps } from './mpx-view';
5
+ type AnimatedOption = {
6
+ duration: number;
7
+ delay: number;
8
+ useNativeDriver: boolean;
9
+ timingFunction: 'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out';
10
+ transformOrigin: string;
11
+ };
12
+ export type AnimationStepItem = {
13
+ animatedOption: AnimatedOption;
14
+ rules: Map<string, number | string>;
15
+ transform: Map<string, number>;
16
+ };
17
+ export type AnimationProp = {
18
+ id: number;
19
+ actions: AnimationStepItem[];
20
+ };
21
+ export default function useAnimationHooks<T, P>(props: _ViewProps & {
22
+ enableAnimation?: boolean;
23
+ layoutRef: MutableRefObject<any>;
24
+ transitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void;
25
+ }): {
26
+ enableStyleAnimation: boolean;
27
+ animationStyle?: undefined;
28
+ } | {
29
+ enableStyleAnimation: true;
30
+ animationStyle: ExtendedViewStyle;
31
+ };
32
+ export {};
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function useNavShared(): readonly [import("react").ReactNode, (value: import("react").ReactNode) => void];
@@ -0,0 +1,6 @@
1
+ import { useContext } from 'react';
2
+ import { NavSharedContext } from './context';
3
+ export function useNavShared() {
4
+ const navSharedValue = useContext(NavSharedContext);
5
+ return [navSharedValue.customNav, navSharedValue.setCustomNav];
6
+ }
@@ -0,0 +1,11 @@
1
+ import { RefObject, ForwardedRef } from 'react';
2
+ type Obj = Record<string, any>;
3
+ export type HandlerRef<T, P> = {
4
+ getNodeInstance(): {
5
+ props: RefObject<P>;
6
+ nodeRef: RefObject<T>;
7
+ instance: Obj;
8
+ };
9
+ };
10
+ export default function useNodesRef<T, P>(props: P, ref: ForwardedRef<HandlerRef<T, P>>, nodeRef: RefObject<T>, instance?: Obj): void;
11
+ export {};
@@ -0,0 +1,122 @@
1
+ import { ReactNode, ReactElement, Dispatch, SetStateAction, MutableRefObject } from 'react';
2
+ import { LayoutChangeEvent, TextStyle, ImageProps } from 'react-native';
3
+ import { FastImageProps } from '@d11/react-native-fast-image';
4
+ import type { AnyFunc } from './types/common';
5
+ export declare const TEXT_STYLE_REGEX: RegExp;
6
+ export declare const PERCENT_REGEX: RegExp;
7
+ export declare const URL_REGEX: RegExp;
8
+ export declare const SVG_REGEXP: RegExp;
9
+ export declare const BACKGROUND_REGEX: RegExp;
10
+ export declare const TEXT_PROPS_REGEX: RegExp;
11
+ export declare const DEFAULT_FONT_SIZE = 16;
12
+ export declare const HIDDEN_STYLE: {
13
+ opacity: number;
14
+ };
15
+ export declare const isIOS: boolean;
16
+ export declare const isAndroid: boolean;
17
+ export declare const isHarmony: boolean;
18
+ export declare function useNavigation(): Record<string, any> | undefined;
19
+ export declare function omit<T, K extends string>(obj: T, fields: K[]): Omit<T, K>;
20
+ /**
21
+ * 用法等同于 useEffect,但是会忽略首次执行,只在依赖更新时执行
22
+ */
23
+ export declare const useUpdateEffect: (effect: any, deps: any) => void;
24
+ export declare const parseUrl: (cssUrl?: string) => string | undefined;
25
+ export declare const getRestProps: (transferProps?: any, originProps?: any, deletePropsKey?: any) => any;
26
+ export declare function isText(ele: ReactNode): ele is ReactElement;
27
+ export declare function every(children: ReactNode, callback: (children: ReactNode) => boolean): boolean;
28
+ type GroupData<T> = Record<string, Partial<T>>;
29
+ export declare function groupBy<T extends Record<string, any>>(obj: T, callback: (key: string, val: T[keyof T]) => string, group?: GroupData<T>): GroupData<T>;
30
+ export declare function splitStyle<T extends Record<string, any>>(styleObj: T): {
31
+ textStyle?: Partial<T>;
32
+ backgroundStyle?: Partial<T>;
33
+ innerStyle?: Partial<T>;
34
+ };
35
+ interface TransformStyleConfig {
36
+ enableVar?: boolean;
37
+ externalVarContext?: Record<string, any>;
38
+ parentFontSize?: number;
39
+ parentWidth?: number;
40
+ parentHeight?: number;
41
+ }
42
+ export declare function useTransformStyle(styleObj: Record<string, any> | undefined, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig): {
43
+ hasVarDec: boolean;
44
+ varContextRef: MutableRefObject<{}>;
45
+ setWidth: Dispatch<SetStateAction<number>>;
46
+ setHeight: Dispatch<SetStateAction<number>>;
47
+ normalStyle: Record<string, any>;
48
+ hasSelfPercent: boolean;
49
+ hasPositionFixed: boolean;
50
+ };
51
+ export interface VisitorArg {
52
+ target: Record<string, any>;
53
+ key: string;
54
+ value: any;
55
+ keyPath: Array<string>;
56
+ }
57
+ export declare function traverseStyle(styleObj: Record<string, any>, visitors: Array<(arg: VisitorArg) => void>): void;
58
+ export declare function setStyle(styleObj: Record<string, any>, keyPath: Array<string>, setter: (arg: VisitorArg) => void): void;
59
+ export declare function splitProps<T extends Record<string, any>>(props: T): {
60
+ textProps?: Partial<T>;
61
+ innerProps?: Partial<T>;
62
+ };
63
+ interface LayoutConfig {
64
+ props: Record<string, any>;
65
+ hasSelfPercent: boolean;
66
+ setWidth?: Dispatch<SetStateAction<number>>;
67
+ setHeight?: Dispatch<SetStateAction<number>>;
68
+ onLayout?: (event?: LayoutChangeEvent) => void;
69
+ nodeRef: React.RefObject<any>;
70
+ }
71
+ export declare const useLayout: ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
72
+ layoutRef: MutableRefObject<{}>;
73
+ layoutStyle: {};
74
+ layoutProps: Record<string, any>;
75
+ };
76
+ export interface WrapChildrenConfig {
77
+ hasVarDec: boolean;
78
+ varContext?: Record<string, any>;
79
+ textStyle?: TextStyle;
80
+ textProps?: Record<string, any>;
81
+ }
82
+ export declare function wrapChildren(props: Record<string, any> | undefined, { hasVarDec, varContext, textStyle, textProps }: WrapChildrenConfig): any;
83
+ export declare const debounce: <T extends AnyFunc>(func: T, delay: number) => ((...args: Parameters<T>) => void) & {
84
+ clear: () => void;
85
+ };
86
+ export declare const useDebounceCallback: <T extends AnyFunc>(func: T, delay: number) => ((...args: Parameters<T>) => void) & {
87
+ clear: () => void;
88
+ };
89
+ export declare const useStableCallback: <T extends AnyFunc | null | undefined>(callback: T) => T extends AnyFunc ? T : () => void;
90
+ export declare function usePrevious<T>(value: T): T | undefined;
91
+ export interface GestureHandler {
92
+ nodeRefs?: Array<{
93
+ getNodeInstance: () => {
94
+ nodeRef: unknown;
95
+ };
96
+ }>;
97
+ current?: unknown;
98
+ }
99
+ export declare function flatGesture(gestures?: Array<GestureHandler>): any[];
100
+ export declare const extendObject: {
101
+ <T extends {}, U>(target: T, source: U): T & U;
102
+ <T_1 extends {}, U_1, V>(target: T_1, source1: U_1, source2: V): T_1 & U_1 & V;
103
+ <T_2 extends {}, U_2, V_1, W>(target: T_2, source1: U_2, source2: V_1, source3: W): T_2 & U_2 & V_1 & W;
104
+ (target: object, ...sources: any[]): any;
105
+ };
106
+ export declare function getCurrentPage(pageId: number | null | undefined): any;
107
+ export declare function renderImage(imageProps: ImageProps | FastImageProps, enableFastImage?: boolean): ReactElement<ImageProps | FastImageProps, string | import("react").JSXElementConstructor<any>>;
108
+ export declare function pickStyle(styleObj: Record<string, any> | undefined, pickedKeys: Array<string>, callback?: (key: string, val: number | string) => number | string): Record<string, any>;
109
+ export declare function useHover({ enableHover, hoverStartTime, hoverStayTime, disabled }: {
110
+ enableHover: boolean;
111
+ hoverStartTime: number;
112
+ hoverStayTime: number;
113
+ disabled?: boolean;
114
+ }): {
115
+ isHover: boolean;
116
+ gesture?: undefined;
117
+ } | {
118
+ isHover: boolean;
119
+ gesture: import("react-native-gesture-handler/lib/typescript/handlers/gestures/panGesture").PanGesture;
120
+ };
121
+ export declare function useRunOnJSCallback(callbackMapRef: MutableRefObject<Record<string, AnyFunc>>): (key: string, ...args: any) => any;
122
+ export {};
@@ -280,8 +280,8 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
280
280
  }
281
281
 
282
282
  const setKeyboardAvoidContext = () => {
283
- if (adjustPosition && keyboardAvoid) {
284
- keyboardAvoid.current = { cursorSpacing, ref: nodeRef }
283
+ if (keyboardAvoid) {
284
+ keyboardAvoid.current = { cursorSpacing, ref: nodeRef, adjustPosition }
285
285
  }
286
286
  }
287
287
 
@@ -295,20 +295,39 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
295
295
  }
296
296
 
297
297
  const onFocus = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {
298
- setKeyboardAvoidContext()
299
- bindfocus && bindfocus(
300
- getCustomEvent(
301
- 'focus',
302
- evt,
303
- {
304
- detail: {
305
- value: tmpValue.current || ''
306
- },
307
- layoutRef
308
- },
309
- props
310
- )
311
- )
298
+ if (!keyboardAvoid?.current) {
299
+ setKeyboardAvoidContext()
300
+ }
301
+
302
+ if (bindfocus && keyboardAvoid?.current) {
303
+ const focusAction = () => {
304
+ bindfocus(
305
+ getCustomEvent(
306
+ 'focus',
307
+ evt,
308
+ {
309
+ detail: {
310
+ value: tmpValue.current || '',
311
+ height: keyboardAvoid.current?.keyboardHeight,
312
+ },
313
+ layoutRef
314
+ },
315
+ props
316
+ )
317
+ )
318
+ if (keyboardAvoid.current?.onKeyboardShow) {
319
+ keyboardAvoid.current.onKeyboardShow = undefined
320
+ }
321
+ }
322
+ if (keyboardAvoid.current.keyboardHeight) {
323
+ // iOS: keyboard 获取高度时机 keyboardWillShow 在 input focus 之前,可以立即执行
324
+ focusAction()
325
+ } else {
326
+ // Android,Harmony: keyboard 获取高度时机 keyboardDidShow 在 input focus 之后,需要延迟回调
327
+ evt.persist()
328
+ keyboardAvoid.current.onKeyboardShow = focusAction
329
+ }
330
+ }
312
331
  }
313
332
 
314
333
  const onBlur = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {
@@ -2,7 +2,7 @@ import React, { ReactNode, useContext, useEffect, useRef } from 'react'
2
2
  import { DimensionValue, EmitterSubscription, Keyboard, View, ViewStyle, NativeSyntheticEvent, NativeTouchEvent } from 'react-native'
3
3
  import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, cancelAnimation } from 'react-native-reanimated'
4
4
  import { KeyboardAvoidContext } from './context'
5
- import { isIOS } from './utils'
5
+ import { isAndroid, isIOS } from './utils'
6
6
 
7
7
  type KeyboardAvoidViewProps = {
8
8
  children?: ReactNode
@@ -25,7 +25,8 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
25
25
  const timerRef = useRef<NodeJS.Timeout | null>(null)
26
26
 
27
27
  const animatedStyle = useAnimatedStyle(() => ({
28
- transform: [{ translateY: -offset.value }],
28
+ // translate/position top可能会导致底部渲染区域缺失
29
+ marginTop: -offset.value,
29
30
  flexBasis: basic.value as DimensionValue
30
31
  }))
31
32
 
@@ -38,6 +39,11 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
38
39
  timerRef.current && clearTimeout(timerRef.current)
39
40
 
40
41
  if (keyboardAvoid?.current) {
42
+ const inputRef = keyboardAvoid.current.ref?.current
43
+ if (inputRef && inputRef.isFocused()) {
44
+ // 修复 Android 点击键盘收起按钮时当前 input 没触发失焦的问题
45
+ inputRef.blur()
46
+ }
41
47
  keyboardAvoid.current = null
42
48
  }
43
49
 
@@ -55,64 +61,64 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
55
61
  useEffect(() => {
56
62
  let subscriptions: EmitterSubscription[] = []
57
63
 
58
- if (isIOS) {
59
- subscriptions = [
60
- Keyboard.addListener('keyboardWillShow', (evt: any) => {
61
- if (!keyboardAvoid?.current || isShow.current) {
62
- return
63
- }
64
-
65
- isShow.current = true
66
- timerRef.current && clearTimeout(timerRef.current)
67
-
68
- const { endCoordinates } = evt
69
- const { ref, cursorSpacing = 0 } = keyboardAvoid.current
70
-
71
- timerRef.current = setTimeout(() => {
72
- ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
73
- const aboveOffset = offset.value + pageY + height - endCoordinates.screenY
74
- const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
75
- const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing)
76
- const value = aboveOffset > 0 ? belowValue : aboveValue
77
- cancelAnimation(offset)
78
- offset.value = withTiming(value, { duration, easing }, (finished) => {
79
- if (finished) {
80
- // Set flexBasic after animation to trigger re-layout and reset layout information
81
- basic.value = '99.99%'
82
- }
83
- })
84
- })
85
- })
86
- }),
87
- Keyboard.addListener('keyboardWillHide', resetKeyboard)
88
- ]
89
- } else {
90
- subscriptions = [
91
- Keyboard.addListener('keyboardDidShow', (evt: any) => {
92
- if (!keyboardAvoid?.current || isShow.current) {
93
- return
94
- }
95
-
96
- isShow.current = true
64
+ function keybaordAvoding(evt: any, ios = false) {
65
+ if (!keyboardAvoid?.current || isShow.current) {
66
+ return
67
+ }
68
+
69
+ isShow.current = true
70
+
71
+ if (ios) {
72
+ timerRef.current && clearTimeout(timerRef.current)
73
+ }
74
+
75
+ const { endCoordinates } = evt
76
+ const { ref, cursorSpacing = 0, adjustPosition, onKeyboardShow } = keyboardAvoid.current
77
+ keyboardAvoid.current.keyboardHeight = endCoordinates.height
78
+ onKeyboardShow?.()
79
+ if (adjustPosition) {
80
+ // 默认沿用旧版本逻辑,在 android 原生关闭键盘避让的情况下应该将该配置设置为 false,走 mpx 的键盘避让逻辑,否则bundle内的所有input都会无法避让键盘
81
+ const enableNativeKeyboardAvoiding = mpxGlobal?.__mpx?.config?.rnConfig?.enableNativeKeyboardAvoiding ?? true
82
+ const callback = () => {
83
+ ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
84
+ function calculateOffset() {
85
+ // enableNativeKeyboardAvoding 默认开启
86
+ if (enableNativeKeyboardAvoiding && isAndroid) {
87
+ const aboveOffset = offset.value + pageY + height - endCoordinates.screenY;
88
+ const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
89
+ const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
90
+ return aboveOffset > 0 ? belowValue : aboveValue;
91
+ }
97
92
 
98
- const { endCoordinates } = evt
99
- const { ref, cursorSpacing = 0 } = keyboardAvoid.current
93
+ const aboveOffset = offset.value + pageY + height - endCoordinates.screenY;
94
+ const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
95
+ const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
96
+ return aboveOffset > 0 ? belowValue : aboveValue;
97
+ }
100
98
 
101
- ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
102
- const aboveOffset = pageY + height - endCoordinates.screenY
103
- const belowOffset = endCoordinates.height - aboveOffset
104
- const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
105
- const belowValue = Math.min(belowOffset, cursorSpacing)
106
- const value = aboveOffset > 0 ? belowValue : aboveValue
107
99
  cancelAnimation(offset)
108
- offset.value = withTiming(value, { duration, easing }, (finished) => {
100
+ offset.value = withTiming(calculateOffset(), { duration, easing }, finished => {
109
101
  if (finished) {
110
102
  // Set flexBasic after animation to trigger re-layout and reset layout information
111
103
  basic.value = '99.99%'
112
104
  }
113
105
  })
114
106
  })
107
+ };
108
+ (isIOS ? () => (timerRef.current = setTimeout(callback)) : callback)();
109
+ }
110
+ }
111
+
112
+ if (isIOS) {
113
+ subscriptions = [
114
+ Keyboard.addListener('keyboardWillShow', (evt: any) => {
115
+ keybaordAvoding(evt, true)
115
116
  }),
117
+ Keyboard.addListener('keyboardWillHide', resetKeyboard)
118
+ ]
119
+ } else {
120
+ subscriptions = [
121
+ Keyboard.addListener('keyboardDidShow', keybaordAvoding),
116
122
  Keyboard.addListener('keyboardDidHide', resetKeyboard)
117
123
  ]
118
124
  }
@@ -124,15 +130,8 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
124
130
  }, [keyboardAvoid])
125
131
 
126
132
  return (
127
- <View style={style} onTouchEnd={onTouchEnd}>
128
- <Animated.View
129
- style={[
130
- contentContainerStyle,
131
- animatedStyle
132
- ]}
133
- >
134
- {children}
135
- </Animated.View>
133
+ <View style={style} onTouchEnd={onTouchEnd} onTouchMove={onTouchEnd}>
134
+ <Animated.View style={[contentContainerStyle, animatedStyle]}>{children}</Animated.View>
136
135
  </View>
137
136
  )
138
137
  }
@@ -0,0 +1,33 @@
1
+ import { AnimatedStyle } from 'react-native-reanimated'
2
+ import { useNavShared } from './useNavShared'
3
+ import { NavSharedContext, NavSharedValue } from './context'
4
+ import { useLayoutEffect, useMemo, useState } from 'react'
5
+ import { StyleProp } from 'react-native'
6
+ import { isAndroid } from './utils'
7
+
8
+ interface MpxNavContainerProps {
9
+ children?: React.ReactNode
10
+ }
11
+
12
+ export default function MpxNavContainer(props: MpxNavContainerProps) {
13
+ const [, setCustomNav] = useNavShared()
14
+
15
+ useLayoutEffect(() => {
16
+ if (!isAndroid) return
17
+ if (props.children) {
18
+ setCustomNav(props.children)
19
+ }
20
+
21
+ return () => {
22
+ setCustomNav(undefined)
23
+ }
24
+ }, [props.children])
25
+
26
+ return isAndroid ? null : props.children
27
+ }
28
+
29
+ export function NavSharedProvider({ children }: { children?: React.ReactNode }) {
30
+ const [customNav, setCustomNav] = useState()
31
+ const value = useMemo(() => ({ customNav, setCustomNav } as NavSharedValue), [customNav])
32
+ return <NavSharedContext.Provider value={value}>{children}</NavSharedContext.Provider>
33
+ }