remaxjs / remax
1 1
import * as React from 'react';
2 1
import memoizeOne from 'memoize-one';
3 1
import { formatDisplayName } from '@remax/framework-shared';
4
import {
5
  TapEvent,
6
  TouchEvent,
7
  EventTarget,
8
  EventCurrentTarget,
9
  ImageLoadEvent,
10
  ImageErrorEvent,
11
  InputEvent,
12
  FormEvent,
13
} from './types';
14

15 1
export function createTarget(target: any, detail: any): EventTarget {
16 1
  return {
17
    id: target.id,
18
    offsetLeft: target.offsetLeft,
19
    offsetTop: target.offsetTop,
20 1
    dataset: target.targetDataset || target.dataset,
21 1
    value: detail?.value,
22
  };
23
}
24

25 1
export function createCurrentTarget(currentTarget: any): EventCurrentTarget {
26 1
  return {
27
    id: currentTarget.id,
28
    offsetLeft: currentTarget.offsetLeft,
29
    offsetTop: currentTarget.offsetTop,
30
    dataset: currentTarget.dataset,
31
  };
32
}
33

34 1
export const createTapEvent = (originalEvent: any): TapEvent => ({
35
  type: originalEvent.type,
36
  stopPropagation: originalEvent.stopPropagation,
37
  target: createTarget(originalEvent.target, originalEvent.detail),
38
  currentTarget: createCurrentTarget(originalEvent.currentTarget),
39
  originalEvent,
40
  nativeEvent: originalEvent,
41
});
42

43 1
export const createTouchEvent = (originalEvent: any): TouchEvent => ({
44
  type: originalEvent.type,
45
  stopPropagation: originalEvent.stopPropagation,
46
  target: createTarget(originalEvent.target, originalEvent.detail),
47
  currentTarget: createCurrentTarget(originalEvent.currentTarget),
48
  touches: originalEvent.touches,
49
  changedTouches: originalEvent.touches,
50
  originalEvent,
51
  nativeEvent: originalEvent,
52
});
53

54 1
export const createImageEvent = (originalEvent: any): ImageLoadEvent | ImageErrorEvent => ({
55
  type: originalEvent.type,
56
  target: createTarget(originalEvent.target, originalEvent.detail),
57
  currentTarget: createCurrentTarget(originalEvent.currentTarget),
58
  originalEvent,
59
  nativeEvent: originalEvent,
60
});
61

62 1
export function createCallback(fn: ((event: any) => void) | undefined, eventCreator: (event: any) => any) {
63 1
  if (typeof fn !== 'function') {
64 1
    return undefined;
65
  }
66

67 1
  return (originalEvent: any) => fn(eventCreator(originalEvent));
68
}
69

70 1
export const createInputEvent = (originalEvent: any): InputEvent => ({
71
  type: originalEvent.type,
72
  target: createTarget(originalEvent.target, originalEvent.detail),
73
  currentTarget: createCurrentTarget(originalEvent.currentTarget),
74
  originalEvent,
75
  nativeEvent: originalEvent,
76
});
77

78 1
export const createFormEvent = (originalEvent: any): FormEvent => ({
79
  type: originalEvent.type,
80
  target: createTarget(originalEvent.target, originalEvent.detail),
81
  currentTarget: createCurrentTarget(originalEvent.currentTarget),
82
  originalEvent,
83
  nativeEvent: originalEvent,
84
});
85

86 1
function assignDefaultProps(inputProps: any, defaultProps: any) {
87 1
  if (defaultProps) {
88 1
    Object.keys(defaultProps).forEach(key => {
89 1
      inputProps[key] = inputProps[key] ?? defaultProps[key];
90
    });
91
  }
92
}
93

94 1
export function aliasProps(props: any, alias: { [key: string]: string }) {
95 1
  if (!alias) {
96 0
    return props;
97
  }
98

99 1
  const nextProps: any = {};
100

101 1
  for (const key in props) {
102 1
    nextProps[alias[key] ?? key] = props[key];
103
  }
104

105 1
  return nextProps;
106
}
107

108 1
const createLongTapCallback = memoizeOne(createCallback);
109 1
const createTapCallback = memoizeOne(createCallback);
110 1
const createTouchStartCallback = memoizeOne(createCallback);
111 1
const createTouchMoveCallback = memoizeOne(createCallback);
112 1
const createTouchEndCallback = memoizeOne(createCallback);
113 1
const createTouchCancelCallback = memoizeOne(createCallback);
114 1
const createChangeCallback = memoizeOne(createCallback);
115 1
const createInputCallback = memoizeOne(createCallback);
116 1
const createConfirmCallback = memoizeOne(createCallback);
117 1
const createFocusCallback = memoizeOne(createCallback);
118 1
const createBlurCallback = memoizeOne(createCallback);
119 1
const createSubmitCallback = memoizeOne(createCallback);
120 1
const createResetCallback = memoizeOne(createCallback);
121 1
const createImageLoadCallback = memoizeOne(createCallback);
122 1
const createImageErrorCallback = memoizeOne(createCallback);
123

124 1
export default function createHostComponent<P = any>(
125
  name: string,
126
  alias: {
127
    [key: string]: string;
128
  } | null,
129
  defaults?: {
130
    [key: string]: any;
131 1
  }
132
) {
133 1
  const Component: React.ForwardRefRenderFunction<any, P> = (props: any, ref: React.Ref<any>) => {
134 1
    const inputProps = {
135
      ...props,
136
    };
137

138
    // 默认属性根据平台在这里设置
139 1
    if (defaults) {
140 1
      assignDefaultProps(inputProps, defaults);
141
    }
142

143 1
    if (props.onLongTap) {
144 1
      inputProps.onLongTap = createLongTapCallback(inputProps.onLongTap, createTapEvent);
145
    }
146 1
    if (inputProps.onTap) {
147 1
      inputProps.onTap = createTapCallback(inputProps.onTap, createTapEvent);
148
    }
149

150 1
    if (inputProps.onTouchStart) {
151 1
      inputProps.onTouchStart = createTouchStartCallback(inputProps.onTouchStart, createTouchEvent);
152
    }
153

154 1
    if (inputProps.onTouchMove) {
155 1
      inputProps.onTouchMove = createTouchMoveCallback(inputProps.onTouchMove, createTouchEvent);
156
    }
157

158 1
    if (inputProps.onTouchEnd) {
159 1
      inputProps.onTouchEnd = createTouchEndCallback(inputProps.onTouchEnd, createTouchEvent);
160
    }
161

162 1
    if (inputProps.onTouchCancel) {
163 1
      inputProps.onTouchCancel = createTouchCancelCallback(inputProps.onTouchCancel, createTouchEvent);
164
    }
165

166 1
    if (inputProps.onChange) {
167 0
      inputProps.onChange = createChangeCallback(inputProps.onChange, createInputEvent);
168
    }
169

170 1
    if (inputProps.onInput) {
171 0
      inputProps.onInput = createInputCallback(inputProps.onInput, createInputEvent);
172
    }
173

174 1
    if (inputProps.onConfirm) {
175 0
      inputProps.onConfirm = createConfirmCallback(inputProps.onConfirm, createInputEvent);
176
    }
177

178 1
    if (inputProps.onFocus) {
179 0
      inputProps.onFocus = createFocusCallback(inputProps.onFocus, createInputEvent);
180
    }
181

182 1
    if (inputProps.onBlur) {
183 0
      inputProps.onBlur = createBlurCallback(inputProps.onBlur, createInputEvent);
184
    }
185

186 1
    if (inputProps.onSubmit) {
187 1
      inputProps.onSubmit = createSubmitCallback(inputProps.onSubmit, createFormEvent);
188
    }
189

190 1
    if (inputProps.onReset) {
191 1
      inputProps.onReset = createResetCallback(inputProps.onReset, createFormEvent);
192
    }
193

194 1
    if (name === 'image') {
195 1
      if (inputProps.onLoad) {
196 1
        inputProps.onLoad = createImageLoadCallback(props.onLoad, createImageEvent);
197
      }
198 1
      if (inputProps.onError) {
199 1
        inputProps.onError = createImageErrorCallback(props.onError, createImageEvent);
200
      }
201
    }
202

203 1
    let nextProps = inputProps;
204

205 1
    if (alias) {
206 1
      nextProps = aliasProps(inputProps, alias);
207
    }
208 1
    nextProps.ref = ref;
209

210 1
    return React.createElement(name, nextProps);
211
  };
212

213 1
  if (process.env.NODE_ENV === 'development') {
214 0
    Component.displayName = formatDisplayName(name);
215
  }
216

217 1
  return React.forwardRef<any, React.PropsWithChildren<P>>(Component);
218
}

Read our documentation on viewing source code .

Loading