@mpxjs/webpack-plugin 2.10.18 → 2.10.20

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 (70) hide show
  1. package/lib/dependencies/ResolveDependency.js +2 -2
  2. package/lib/index.js +25 -6
  3. package/lib/json-compiler/helper.js +11 -10
  4. package/lib/json-compiler/index.js +7 -4
  5. package/lib/json-compiler/plugin.js +4 -4
  6. package/lib/loader.js +4 -4
  7. package/lib/native-loader.js +4 -4
  8. package/lib/platform/create-diagnostic.js +168 -0
  9. package/lib/platform/index.js +16 -3
  10. package/lib/platform/json/wx/index.js +66 -17
  11. package/lib/platform/run-rules.js +9 -5
  12. package/lib/platform/style/wx/index.js +4 -3
  13. package/lib/platform/template/normalize-component-rules.js +7 -9
  14. package/lib/platform/template/wx/component-config/camera.js +12 -0
  15. package/lib/platform/template/wx/component-config/custom-built-in-component.js +34 -0
  16. package/lib/platform/template/wx/component-config/index.js +18 -3
  17. package/lib/platform/template/wx/component-config/input.js +1 -7
  18. package/lib/platform/template/wx/component-config/movable-view.js +1 -7
  19. package/lib/platform/template/wx/component-config/text.js +1 -1
  20. package/lib/platform/template/wx/component-config/textarea.js +1 -25
  21. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  22. package/lib/platform/template/wx/index.js +48 -34
  23. package/lib/react/processJSON.js +7 -4
  24. package/lib/react/processStyles.js +22 -8
  25. package/lib/react/processTemplate.js +85 -41
  26. package/lib/react/style-helper.js +120 -85
  27. package/lib/react/template-loader.js +148 -0
  28. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +1 -1
  29. package/lib/runtime/components/react/dist/mpx-camera.d.ts +31 -0
  30. package/lib/runtime/components/react/dist/mpx-camera.jsx +270 -0
  31. package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -1
  32. package/lib/runtime/components/react/dist/mpx-image.jsx +1 -2
  33. package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +1 -1
  34. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +92 -15
  35. package/lib/runtime/components/react/dist/mpx-web-view.jsx +1 -1
  36. package/lib/runtime/components/react/dist/utils.jsx +3 -2
  37. package/lib/runtime/components/react/mpx-async-suspense.tsx +2 -1
  38. package/lib/runtime/components/react/mpx-camera.tsx +358 -0
  39. package/lib/runtime/components/react/mpx-image.tsx +1 -3
  40. package/lib/runtime/components/react/mpx-picker/type.ts +1 -1
  41. package/lib/runtime/components/react/mpx-scroll-view.tsx +106 -16
  42. package/lib/runtime/components/react/mpx-web-view.tsx +1 -1
  43. package/lib/runtime/components/react/utils.tsx +3 -2
  44. package/lib/runtime/components/wx/default-component.mpx +9 -0
  45. package/lib/runtime/components/wx/default-page.mpx +3 -11
  46. package/lib/runtime/optionProcessor.d.ts +2 -0
  47. package/lib/runtime/optionProcessor.js +77 -1
  48. package/lib/style-compiler/index.js +2 -0
  49. package/lib/style-compiler/plugins/remove-strip-conditional-comments.js +14 -0
  50. package/lib/style-compiler/strip-conditional.js +40 -26
  51. package/lib/template-compiler/compiler.js +274 -116
  52. package/lib/template-compiler/gen-node-react.js +35 -7
  53. package/lib/template-compiler/index.js +9 -7
  54. package/lib/utils/const.js +4 -1
  55. package/lib/utils/dom-tag-config.js +1 -1
  56. package/lib/utils/partial-compile-rules.js +27 -0
  57. package/lib/utils/pre-process-json.js +3 -0
  58. package/lib/utils/source-location.js +96 -0
  59. package/lib/web/compile-wx-template-fragment.js +68 -0
  60. package/lib/web/index.js +2 -0
  61. package/lib/web/processJSON.js +7 -4
  62. package/lib/web/processScript.js +41 -3
  63. package/lib/web/processTemplate.js +61 -19
  64. package/lib/web/template-loader.js +123 -0
  65. package/lib/web/template-shared.js +48 -0
  66. package/lib/wxml/loader.js +3 -2
  67. package/lib/wxss/loader.js +1 -1
  68. package/lib/wxss/utils.js +6 -4
  69. package/package.json +12 -4
  70. package/lib/platform/template/wx/component-config/component.js +0 -41
@@ -0,0 +1,270 @@
1
+ import { createElement, forwardRef, useRef, useCallback, useContext, useState, useEffect, useMemo } from 'react';
2
+ import { getCurrentPage, useTransformStyle, useLayout, extendObject } from './utils';
3
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
4
+ import { Camera, useCameraDevice, useCodeScanner, useCameraFormat } from 'react-native-vision-camera';
5
+ import { noop, warn, hasOwn } from '@mpxjs/utils';
6
+ import { RouteContext } from './context';
7
+ import { watch } from '@mpxjs/core';
8
+ const qualityValue = {
9
+ high: 90,
10
+ normal: 75,
11
+ low: 50,
12
+ original: 100
13
+ };
14
+ let RecordRes = null;
15
+ const _camera = forwardRef((props, ref) => {
16
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
17
+ const cameraRef = useRef(null);
18
+ const { mode = 'normal', resolution = 'medium', 'device-position': devicePosition = 'back', flash = 'auto', 'frame-size': frameSize = 'medium', bindinitdone, bindstop, bindscancode, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'enable-var': enableVar, 'external-var-context': externalVarContext, style = {} } = props;
19
+ const styleObj = extendObject({}, style);
20
+ const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, {
21
+ enableVar,
22
+ externalVarContext,
23
+ parentFontSize,
24
+ parentWidth,
25
+ parentHeight
26
+ });
27
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: cameraRef });
28
+ const isPhoto = useRef(false);
29
+ isPhoto.current = mode === 'normal';
30
+ const device = useCameraDevice(devicePosition || 'back');
31
+ const { navigation, pageId } = useContext(RouteContext) || {};
32
+ const [zoomValue, setZoomValue] = useState(1);
33
+ const [isActive, setIsActive] = useState(true);
34
+ const [hasPermission, setHasPermission] = useState(null);
35
+ const page = getCurrentPage(pageId);
36
+ // 先定义常量,避免在条件判断后使用
37
+ const maxZoom = device?.maxZoom || 1;
38
+ const RESOLUTION_MAPPING = {
39
+ low: { width: 1280, height: 720 },
40
+ medium: { width: 1920, height: 1080 },
41
+ high: 'max'
42
+ };
43
+ const FRAME_SIZE_MAPPING = {
44
+ small: { width: 1280, height: 720 },
45
+ medium: { width: 1920, height: 1080 },
46
+ large: 'max'
47
+ };
48
+ const format = useCameraFormat(device, [
49
+ {
50
+ photoResolution: RESOLUTION_MAPPING[resolution],
51
+ videoResolution: FRAME_SIZE_MAPPING[frameSize] || RESOLUTION_MAPPING[resolution]
52
+ }
53
+ ]);
54
+ const isScancode = useCallback((fail, complete) => {
55
+ if (!isPhoto.current) {
56
+ const result = {
57
+ errMsg: 'Not allow to invoke takePhoto in \'scanCode\' mode.'
58
+ };
59
+ fail(result);
60
+ complete(result);
61
+ return true;
62
+ }
63
+ return false;
64
+ }, []);
65
+ const codeScanner = useCodeScanner({
66
+ codeTypes: ['qr'],
67
+ onCodeScanned: (codes) => {
68
+ codes.forEach(code => {
69
+ const type = code.type === 'qr' ? 'QR_CODE' : code.type?.toUpperCase();
70
+ const frame = code.frame || {};
71
+ bindscancode && bindscancode(getCustomEvent('scancode', {}, {
72
+ detail: {
73
+ result: code.value,
74
+ type,
75
+ scanArea: [parseInt(frame.x) || 0, parseInt(frame.y) || 0, parseInt(frame.width) || 0, parseInt(frame.height) || 0]
76
+ }
77
+ }));
78
+ });
79
+ }
80
+ });
81
+ const onInitialized = useCallback(() => {
82
+ bindinitdone && bindinitdone(getCustomEvent('initdone', {}, {
83
+ detail: {
84
+ maxZoom
85
+ }
86
+ }));
87
+ }, [bindinitdone, maxZoom]);
88
+ const onStopped = useCallback(() => {
89
+ bindstop && bindstop();
90
+ }, [bindstop]);
91
+ const camera = useMemo(() => ({
92
+ setZoom: (zoom) => {
93
+ setZoomValue(zoom);
94
+ },
95
+ takePhoto: (options = {}) => {
96
+ const { success = noop, fail = noop, complete = noop } = options;
97
+ if (isScancode(fail, complete))
98
+ return;
99
+ cameraRef.current?.takePhoto?.({
100
+ quality: qualityValue[options.quality || 'normal']
101
+ }).then((res) => {
102
+ const result = {
103
+ errMsg: 'takePhoto:ok',
104
+ tempImagePath: res.path
105
+ };
106
+ success(result);
107
+ complete(result);
108
+ }).catch(() => {
109
+ const result = {
110
+ errMsg: 'takePhoto:fail'
111
+ };
112
+ fail(result);
113
+ complete(result);
114
+ });
115
+ },
116
+ startRecord: (options = {}) => {
117
+ let { timeout = 30, success = noop, fail = noop, complete = noop, timeoutCallback = noop } = options;
118
+ timeout = timeout > 300 ? 300 : timeout;
119
+ let recordTimer = null;
120
+ if (isScancode(fail, complete))
121
+ return;
122
+ try {
123
+ const result = {
124
+ errMsg: 'startRecord:ok'
125
+ };
126
+ success(result);
127
+ complete(result);
128
+ cameraRef.current?.startRecording?.({
129
+ onRecordingError: (error) => {
130
+ if (recordTimer)
131
+ clearTimeout(recordTimer);
132
+ const errorResult = {
133
+ errMsg: 'startRecord:fail during recording',
134
+ error: error
135
+ };
136
+ timeoutCallback(errorResult);
137
+ },
138
+ onRecordingFinished: (video) => {
139
+ RecordRes = video;
140
+ if (recordTimer)
141
+ clearTimeout(recordTimer);
142
+ }
143
+ });
144
+ recordTimer = setTimeout(() => {
145
+ cameraRef.current?.stopRecording().catch(() => {
146
+ // 忽略停止录制时的错误
147
+ });
148
+ }, timeout * 1000);
149
+ }
150
+ catch (error) {
151
+ if (recordTimer)
152
+ clearTimeout(recordTimer);
153
+ const result = {
154
+ errMsg: 'startRecord:fail ' + (error.message || 'unknown error')
155
+ };
156
+ fail(result);
157
+ complete(result);
158
+ }
159
+ },
160
+ stopRecord: (options = {}) => {
161
+ const { success = noop, fail = noop, complete = noop } = options;
162
+ if (isScancode(fail, complete))
163
+ return;
164
+ try {
165
+ cameraRef.current?.stopRecording().then(() => {
166
+ setTimeout(() => {
167
+ if (RecordRes) {
168
+ const result = {
169
+ errMsg: 'stopRecord:ok',
170
+ tempVideoPath: RecordRes?.path,
171
+ duration: RecordRes.duration * 1000 // 转成ms
172
+ };
173
+ RecordRes = null;
174
+ success(result);
175
+ complete(result);
176
+ }
177
+ }, 200); // 延时200ms,确保录制结果已准备好
178
+ }).catch((e) => {
179
+ const result = {
180
+ errMsg: 'stopRecord:fail ' + (e.message || 'promise rejected')
181
+ };
182
+ fail(result);
183
+ complete(result);
184
+ });
185
+ }
186
+ catch (error) {
187
+ const result = {
188
+ errMsg: 'stopRecord:fail ' + (error.message || 'unknown error')
189
+ };
190
+ fail(result);
191
+ complete(result);
192
+ }
193
+ }
194
+ }), []);
195
+ useEffect(() => {
196
+ let unWatch;
197
+ if (pageId && hasOwn(global.__mpxPageStatusMap, String(pageId))) {
198
+ unWatch = watch(() => global.__mpxPageStatusMap[pageId], (newVal) => {
199
+ if (newVal === 'show') {
200
+ if (page.id === pageId) {
201
+ setIsActive(true);
202
+ }
203
+ }
204
+ if (newVal === 'hide') {
205
+ setIsActive(false);
206
+ }
207
+ }, { sync: true });
208
+ }
209
+ const checkCameraPermission = async () => {
210
+ try {
211
+ const cameraPermission = global?.__mpx?.config?.rnConfig?.cameraPermission;
212
+ if (typeof cameraPermission === 'function') {
213
+ const permissionResult = await cameraPermission();
214
+ setHasPermission(permissionResult === true);
215
+ }
216
+ else {
217
+ setHasPermission(true);
218
+ }
219
+ }
220
+ catch (error) {
221
+ setHasPermission(false);
222
+ }
223
+ };
224
+ checkCameraPermission();
225
+ return () => {
226
+ if (navigation?.camera === camera) {
227
+ delete navigation.camera;
228
+ }
229
+ unWatch && unWatch();
230
+ };
231
+ }, []);
232
+ const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
233
+ ref: cameraRef,
234
+ style: extendObject({}, normalStyle, layoutStyle),
235
+ isActive,
236
+ photo: true,
237
+ video: true,
238
+ onInitialized,
239
+ onStopped,
240
+ device,
241
+ format,
242
+ codeScanner: !isPhoto.current ? codeScanner : undefined,
243
+ zoom: zoomValue,
244
+ torch: flash
245
+ }), [
246
+ 'mode',
247
+ 'resolution',
248
+ 'frame-size',
249
+ 'bindinitdone',
250
+ 'bindstop',
251
+ 'flash',
252
+ 'bindscancode',
253
+ 'binderror'
254
+ ], {
255
+ layoutRef
256
+ });
257
+ if (navigation && navigation.camera && navigation.camera !== camera) {
258
+ warn('<camera>: 一个页面只能插入一个');
259
+ return null;
260
+ }
261
+ else if (navigation) {
262
+ navigation.camera = camera;
263
+ }
264
+ if (!hasPermission || !device) {
265
+ return null;
266
+ }
267
+ return createElement(Camera, innerProps);
268
+ });
269
+ _camera.displayName = 'MpxCamera';
270
+ export default _camera;
@@ -5,7 +5,6 @@ export type Mode = 'scaleToFill' | 'aspectFit' | 'aspectFill' | 'widthFix' | 'he
5
5
  export interface ImageProps {
6
6
  src?: string;
7
7
  mode?: Mode;
8
- svg?: boolean;
9
8
  style?: ImageStyle & Record<string, any>;
10
9
  'enable-offset'?: boolean;
11
10
  'enable-var'?: boolean;
@@ -310,8 +310,7 @@ const Image = forwardRef((props, ref) => {
310
310
  style: extendObject({}, normalStyle, layoutStyle, isHeightFixMode ? { width: viewWidth } : {}, isWidthFixMode ? { height: viewHeight } : {})
311
311
  }), [
312
312
  'src',
313
- 'mode',
314
- 'svg'
313
+ 'mode'
315
314
  ], {
316
315
  layoutRef
317
316
  });
@@ -71,7 +71,7 @@ export interface RegionProps extends BasePickerProps {
71
71
  /** 表示选中的省市区,默认选中每一列的第一个值, 默认值 [] */
72
72
  value?: string[];
73
73
  /** 默认值 region */
74
- level?: 'province' | 'city' | 'region' | 'sub-district';
74
+ level?: 'province' | 'city' | 'region';
75
75
  /** 可为每一列的顶部添加一个自定义的项 */
76
76
  'custom-item'?: string;
77
77
  /** value 改变时触发 change 事件, event.detail = {value, code, postcode},
@@ -160,19 +160,96 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
160
160
  }
161
161
  }
162
162
  }, [refresherTriggered]);
163
- function scrollTo({ top = 0, left = 0, animated = false }) {
164
- scrollToOffset(left, top, animated);
163
+ function scrollTo({ top = 0, left = 0, animated = false, duration }) {
164
+ // 如果指定了 duration 且需要动画,使用自定义动画
165
+ if (animated && duration && duration > 0) {
166
+ // 获取当前滚动位置
167
+ const currentY = scrollOptions.current.scrollTop || 0;
168
+ const currentX = scrollOptions.current.scrollLeft || 0;
169
+ const startTime = Date.now();
170
+ const deltaY = top - currentY;
171
+ const deltaX = left - currentX;
172
+ // 缓动函数:easeInOutCubic
173
+ const easing = (t) => {
174
+ return t < 0.5
175
+ ? 4 * t * t * t
176
+ : 1 - Math.pow(-2 * t + 2, 3) / 2;
177
+ };
178
+ // 使用 requestAnimationFrame 实现平滑动画
179
+ const animate = () => {
180
+ const elapsed = Date.now() - startTime;
181
+ const progress = Math.min(elapsed / duration, 1); // 0 到 1
182
+ const easeProgress = easing(progress);
183
+ const nextY = currentY + deltaY * easeProgress;
184
+ const nextX = currentX + deltaX * easeProgress;
185
+ if (scrollViewRef.current) {
186
+ scrollViewRef.current.scrollTo({ y: nextY, x: nextX, animated: false });
187
+ }
188
+ if (progress < 1) {
189
+ requestAnimationFrame(animate);
190
+ }
191
+ else {
192
+ // 确保最终位置准确
193
+ if (scrollViewRef.current) {
194
+ scrollViewRef.current.scrollTo({ y: top, x: left, animated: false });
195
+ }
196
+ }
197
+ };
198
+ requestAnimationFrame(animate);
199
+ }
200
+ else {
201
+ // 使用原生的 scrollTo
202
+ scrollToOffset(left, top, animated);
203
+ }
165
204
  }
166
- function handleScrollIntoView(selector = '', { offset = 0, animated = true } = {}) {
167
- const refs = __selectRef(`#${selector}`, 'node');
168
- if (!refs)
169
- return;
170
- const { nodeRef } = refs.getNodeInstance();
171
- nodeRef.current?.measureLayout(scrollViewRef.current, (left, top) => {
172
- const adjustedLeft = scrollX ? left + offset : left;
173
- const adjustedTop = scrollY ? top + offset : top;
174
- scrollToOffset(adjustedLeft, adjustedTop, animated);
175
- });
205
+ function handleScrollIntoView(selector = '', { offset = 0, animated = true, duration = undefined } = {}) {
206
+ try {
207
+ const currentSelectRef = propsRef.current.__selectRef;
208
+ if (!currentSelectRef) {
209
+ const errMsg = '__selectRef is not available. Please ensure the scroll-view component is properly initialized.';
210
+ warn(errMsg);
211
+ return;
212
+ }
213
+ const targetScrollView = scrollViewRef.current;
214
+ if (!targetScrollView) {
215
+ const errMsg = 'scrollViewRef is not ready';
216
+ warn(errMsg);
217
+ return;
218
+ }
219
+ // scroll-into-view prop 按微信规范直传裸 id(如 "section-1"),而 __refs 注册时 key 带 # 或 . 前缀,需补齐才能命中;
220
+ // pageScrollTo 调用方已自带前缀(如 "#section-1")
221
+ const normalizedSelector = selector.startsWith('#') || selector.startsWith('.') ? selector : `#${selector}`;
222
+ // 调用 __selectRef 查找元素
223
+ const refs = currentSelectRef(normalizedSelector, 'node');
224
+ if (!refs) {
225
+ const errMsg = `Element not found for selector: ${normalizedSelector}`;
226
+ warn(errMsg);
227
+ return;
228
+ }
229
+ const { nodeRef } = refs.getNodeInstance();
230
+ if (!nodeRef?.current) {
231
+ const errMsg = `Node ref not available for selector: ${normalizedSelector}`;
232
+ warn(errMsg);
233
+ return;
234
+ }
235
+ nodeRef.current.measureLayout(targetScrollView, (left, top) => {
236
+ const adjustedLeft = scrollX ? left + offset : left;
237
+ const adjustedTop = scrollY ? top + offset : top;
238
+ // 使用 scrollTo 方法,支持 duration 参数
239
+ if (duration !== undefined) {
240
+ scrollTo({ left: adjustedLeft, top: adjustedTop, animated, duration });
241
+ }
242
+ else {
243
+ scrollToOffset(adjustedLeft, adjustedTop, animated);
244
+ }
245
+ }, (error) => {
246
+ warn(`Failed to measure layout for selector ${normalizedSelector}: ${error}`);
247
+ });
248
+ }
249
+ catch (error) {
250
+ const errMsg = `handleScrollIntoView error for selector ${selector}: ${error?.message || error}`;
251
+ warn(errMsg);
252
+ }
176
253
  }
177
254
  function selectLength(size) {
178
255
  return !scrollX ? size.height : size.width;
@@ -457,9 +534,9 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
457
534
  }
458
535
  // 处理下拉刷新的手势 - 使用 useMemo 避免每次渲染都创建
459
536
  const panGesture = useMemo(() => {
460
- if (!hasRefresher)
461
- return Gesture.Pan(); // 返回空手势
462
537
  return Gesture.Pan()
538
+ .activeOffsetY([-5, 5])
539
+ .failOffsetX([-5, 5])
463
540
  .onUpdate((event) => {
464
541
  'worklet';
465
542
  if (enhanced && !!bounces) {
@@ -519,7 +596,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
519
596
  }
520
597
  })
521
598
  .simultaneousWithExternalGesture(scrollViewRef);
522
- }, [hasRefresher, enhanced, bounces, refreshing, refresherThreshold]);
599
+ }, [enhanced, bounces, refreshing, refresherThreshold]);
523
600
  const scrollAdditionalProps = extendObject({
524
601
  style: extendObject(hasOwn(innerStyle, 'flex') || hasOwn(innerStyle, 'flexGrow')
525
602
  ? {}
@@ -184,7 +184,7 @@ const _WebView = forwardRef((props, ref) => {
184
184
  }
185
185
  break;
186
186
  case 'postMessage':
187
- bindmessage && bindmessage(getCustomEvent('messsage', {}, {
187
+ bindmessage && bindmessage(getCustomEvent('message', {}, {
188
188
  detail: {
189
189
  data: params[0]?.data
190
190
  }
@@ -284,8 +284,9 @@ export function parseValues(str, char = ' ') {
284
284
  // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
285
285
  function parseTransform(transformStr) {
286
286
  const values = parseValues(transformStr);
287
- // Todo transform 排序不一致时,transform动画会闪烁,故这里同样的排序输出 transform
288
- values.sort();
287
+ // Todo 2 RN下顺序不一致转换结果不一致,故这里不处理,动画前后transform 排序不一致的问题,由业务调整写法
288
+ // Todo 1 transform 排序不一致时,transform动画会闪烁,故这里同样的排序输出 transform
289
+ // values.sort()
289
290
  const transform = [];
290
291
  values.forEach(item => {
291
292
  const match = item.match(/([/\w]+)\((.+)\)/);
@@ -56,6 +56,7 @@ const styles = StyleSheet.create({
56
56
 
57
57
  interface DefaultFallbackProps {
58
58
  onReload: () => void
59
+ bindreload: () => void
59
60
  }
60
61
 
61
62
  const DefaultFallback = ({ onReload }: DefaultFallbackProps) => {
@@ -171,7 +172,7 @@ const AsyncSuspense: React.FC<AsyncSuspenseProps> = ({
171
172
  } else if (status === 'error') {
172
173
  if (type === 'page') {
173
174
  const fallback = getFallback ? getFallback() : DefaultFallback
174
- return createElement(fallback as ComponentType<DefaultFallbackProps>, { onReload: reloadPage })
175
+ return createElement(fallback as ComponentType<DefaultFallbackProps>, { onReload: reloadPage, bindreload: reloadPage })
175
176
  } else {
176
177
  return getFallback ? createElement(getFallback(), innerProps) : null
177
178
  }