@mpxjs/webpack-plugin 2.10.18-beta.1 → 2.10.19

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 (29) hide show
  1. package/LICENSE +433 -0
  2. package/lib/index.js +0 -12
  3. package/lib/runtime/components/react/dist/mpx-camera.d.ts +4 -4
  4. package/lib/runtime/components/react/dist/mpx-camera.jsx +75 -41
  5. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +92 -15
  6. package/lib/runtime/components/react/dist/mpx-swiper.d.ts +0 -1
  7. package/lib/runtime/components/react/dist/mpx-swiper.jsx +24 -43
  8. package/lib/runtime/components/react/mpx-camera.tsx +78 -47
  9. package/lib/runtime/components/react/mpx-scroll-view.tsx +106 -16
  10. package/lib/runtime/components/react/mpx-swiper.tsx +23 -43
  11. package/lib/runtime/components/web/mpx-scroll-view.vue +2 -5
  12. package/lib/template-compiler/compiler.js +3 -7
  13. package/lib/utils/const.js +0 -29
  14. package/package.json +4 -3
  15. package/lib/resolver/ExtendComponentsPlugin.js +0 -60
  16. package/lib/runtime/components/ali/mpx-section-list.mpx +0 -566
  17. package/lib/runtime/components/ali/mpx-sticky-header.mpx +0 -212
  18. package/lib/runtime/components/ali/mpx-sticky-section.mpx +0 -17
  19. package/lib/runtime/components/react/dist/mpx-section-list.d.ts +0 -48
  20. package/lib/runtime/components/react/dist/mpx-section-list.jsx +0 -292
  21. package/lib/runtime/components/react/mpx-section-list.tsx +0 -439
  22. package/lib/runtime/components/web/mpx-section-list.vue +0 -551
  23. package/lib/runtime/components/wx/mpx-section-list-default/list-footer.mpx +0 -26
  24. package/lib/runtime/components/wx/mpx-section-list-default/list-header.mpx +0 -26
  25. package/lib/runtime/components/wx/mpx-section-list-default/list-item.mpx +0 -26
  26. package/lib/runtime/components/wx/mpx-section-list-default/section-header.mpx +0 -26
  27. package/lib/runtime/components/wx/mpx-section-list.mpx +0 -209
  28. package/lib/runtime/components/wx/mpx-sticky-header.mpx +0 -40
  29. package/lib/runtime/components/wx/mpx-sticky-section.mpx +0 -31
@@ -1,439 +0,0 @@
1
- import React, { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, useCallback, memo } from 'react'
2
- import { SectionList, RefreshControl, NativeSyntheticEvent, NativeScrollEvent } from 'react-native'
3
- import useInnerProps, { getCustomEvent } from './getInnerListeners'
4
- import { extendObject, useLayout, useTransformStyle } from './utils'
5
- interface ListItem {
6
- isSectionHeader?: boolean;
7
- _originalItemIndex?: number;
8
- [key: string]: any;
9
- }
10
-
11
- interface Section {
12
- headerData: ListItem | null;
13
- data: ListItem[];
14
- hasSectionHeader?: boolean;
15
- _originalItemIndex?: number;
16
- }
17
-
18
- interface ItemHeightType {
19
- value?: number;
20
- getter?: (item: any, index: number) => number;
21
- }
22
-
23
- interface SectionListProps {
24
- enhanced?: boolean;
25
- bounces?: boolean;
26
- scrollEventThrottle?: number;
27
- height?: number | string;
28
- width?: number | string;
29
- listData?: ListItem[];
30
- generichash?: string;
31
- style?: Record<string, any>;
32
- itemHeight?: ItemHeightType;
33
- sectionHeaderHeight?: ItemHeightType;
34
- listHeaderData?: any;
35
- listHeaderHeight?: ItemHeightType;
36
- useListHeader?: boolean;
37
- listFooterData?: any;
38
- useListFooter?: boolean;
39
- 'genericrecycle-item'?: string;
40
- 'genericsection-header'?: string;
41
- 'genericlist-header'?: string;
42
- 'genericlist-footer'?: string;
43
- 'enable-var'?: boolean;
44
- 'external-var-context'?: any;
45
- 'parent-font-size'?: number;
46
- 'parent-width'?: number;
47
- 'parent-height'?: number;
48
- 'enable-sticky'?: boolean;
49
- 'enable-back-to-top'?: boolean;
50
- 'end-reached-threshold'?: number;
51
- 'refresher-enabled'?: boolean;
52
- 'show-scrollbar'?: boolean;
53
- 'refresher-triggered'?: boolean;
54
- bindrefresherrefresh?: (event: any) => void;
55
- bindscrolltolower?: (event: any) => void;
56
- bindscroll?: (event: any) => void;
57
- [key: string]: any;
58
- }
59
-
60
- interface ScrollPositionParams {
61
- index: number;
62
- animated?: boolean;
63
- viewOffset?: number;
64
- viewPosition?: number;
65
- }
66
-
67
- const getGeneric = (generichash: string, generickey: string) => {
68
- if (!generichash || !generickey) return null
69
- const GenericComponent = global.__mpxGenericsMap?.[generichash]?.[generickey]?.()
70
- if (!GenericComponent) return null
71
-
72
- return memo(forwardRef((props: any, ref: any) => {
73
- return createElement(GenericComponent, extendObject({}, {
74
- ref: ref
75
- }, props))
76
- }))
77
- }
78
-
79
- const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
80
- const {
81
- enhanced = false,
82
- bounces = true,
83
- scrollEventThrottle = 0,
84
- height,
85
- width,
86
- listData,
87
- generichash,
88
- style = {},
89
- itemHeight = {},
90
- sectionHeaderHeight = {},
91
- listHeaderHeight = {},
92
- listHeaderData = null,
93
- useListHeader = false,
94
- listFooterData = null,
95
- useListFooter = false,
96
- 'genericrecycle-item': genericrecycleItem,
97
- 'genericsection-header': genericsectionHeader,
98
- 'genericlist-header': genericListHeader,
99
- 'genericlist-footer': genericListFooter,
100
- 'enable-var': enableVar,
101
- 'external-var-context': externalVarContext,
102
- 'parent-font-size': parentFontSize,
103
- 'parent-width': parentWidth,
104
- 'parent-height': parentHeight,
105
- 'enable-sticky': enableSticky = false,
106
- 'enable-back-to-top': enableBackToTop = false,
107
- 'end-reached-threshold': onEndReachedThreshold = 0.1,
108
- 'refresher-enabled': refresherEnabled,
109
- 'show-scrollbar': showScrollbar = true,
110
- 'refresher-triggered': refresherTriggered
111
- } = props
112
-
113
- const [refreshing, setRefreshing] = useState(!!refresherTriggered)
114
-
115
- const scrollViewRef = useRef<any>(null)
116
-
117
- const indexMap = useRef<{ [key: string]: string | number }>({})
118
-
119
- const reverseIndexMap = useRef<{ [key: string]: number }>({})
120
-
121
- const {
122
- hasSelfPercent,
123
- setWidth,
124
- setHeight
125
- } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
126
-
127
- const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef })
128
-
129
- useEffect(() => {
130
- if (refreshing !== refresherTriggered) {
131
- setRefreshing(!!refresherTriggered)
132
- }
133
- }, [refresherTriggered])
134
-
135
- const onRefresh = () => {
136
- const { bindrefresherrefresh } = props
137
- bindrefresherrefresh &&
138
- bindrefresherrefresh(
139
- getCustomEvent('refresherrefresh', {}, { layoutRef }, props)
140
- )
141
- }
142
-
143
- const onEndReached = () => {
144
- const { bindscrolltolower } = props
145
- bindscrolltolower &&
146
- bindscrolltolower(
147
- getCustomEvent('scrolltolower', {}, { layoutRef }, props)
148
- )
149
- }
150
-
151
- const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
152
- const { bindscroll } = props
153
- bindscroll &&
154
- bindscroll(
155
- getCustomEvent('scroll', event.nativeEvent, { layoutRef }, props)
156
- )
157
- }
158
-
159
- // 通过sectionIndex和rowIndex获取原始索引
160
- const getOriginalIndex = (sectionIndex: number, rowIndex: number | 'header'): number => {
161
- const key = `${sectionIndex}_${rowIndex}`
162
- return reverseIndexMap.current[key] ?? -1 // 如果找不到,返回-1
163
- }
164
-
165
- const scrollToIndex = ({ index, animated, viewOffset = 0, viewPosition = 0 }: ScrollPositionParams) => {
166
- if (scrollViewRef.current) {
167
- // 通过索引映射表快速定位位置
168
- const position = indexMap.current[index]
169
- const [sectionIndex, itemIndex] = (position as string).split('_')
170
- scrollViewRef.current.scrollToLocation?.({
171
- itemIndex: itemIndex === 'header' ? 0 : Number(itemIndex) + 1,
172
- sectionIndex: Number(sectionIndex) || 0,
173
- animated,
174
- viewOffset,
175
- viewPosition
176
- })
177
- }
178
- }
179
-
180
- const getItemHeight = ({ sectionIndex, rowIndex }: { sectionIndex: number, rowIndex: number }) => {
181
- if (!itemHeight) {
182
- return 0
183
- }
184
- if ((itemHeight as ItemHeightType).getter) {
185
- const item = convertedListData[sectionIndex].data[rowIndex]
186
- // 使用getOriginalIndex获取原始索引
187
- const originalIndex = getOriginalIndex(sectionIndex, rowIndex)
188
- return (itemHeight as ItemHeightType).getter?.(item, originalIndex) || 0
189
- } else {
190
- return (itemHeight as ItemHeightType).value || 0
191
- }
192
- }
193
-
194
- const getSectionHeaderHeight = ({ sectionIndex }: { sectionIndex: number }) => {
195
- const item = convertedListData[sectionIndex]
196
- const { hasSectionHeader } = item
197
- // 使用getOriginalIndex获取原始索引
198
- const originalIndex = getOriginalIndex(sectionIndex, 'header')
199
- if (!hasSectionHeader) return 0
200
- if ((sectionHeaderHeight as ItemHeightType).getter) {
201
- return (sectionHeaderHeight as ItemHeightType).getter?.(item, originalIndex) || 0
202
- } else {
203
- return (sectionHeaderHeight as ItemHeightType).value || 0
204
- }
205
- }
206
-
207
- const convertedListData = useMemo(() => {
208
- const sections: Section[] = []
209
- let currentSection: Section | null = null
210
- // 清空之前的索引映射
211
- indexMap.current = {}
212
- // 清空反向索引映射
213
- reverseIndexMap.current = {}
214
-
215
- // 处理 listData 为空的情况
216
- if (!listData || !listData.length) {
217
- return sections
218
- }
219
-
220
- listData.forEach((item: ListItem, index: number) => {
221
- if (item.isSectionHeader) {
222
- // 如果已经存在一个 section,先把它添加到 sections 中
223
- if (currentSection) {
224
- sections.push(currentSection)
225
- }
226
- // 创建新的 section
227
- currentSection = {
228
- headerData: item,
229
- data: [],
230
- hasSectionHeader: true,
231
- _originalItemIndex: index
232
- }
233
- // 为 section header 添加索引映射
234
- const sectionIndex = sections.length
235
- indexMap.current[index] = `${sectionIndex}_header`
236
- // 添加反向索引映射
237
- reverseIndexMap.current[`${sectionIndex}_header`] = index
238
- } else {
239
- // 如果没有当前 section,创建一个默认的
240
- if (!currentSection) {
241
- // 创建默认section (无header的section)
242
- currentSection = {
243
- headerData: null,
244
- data: [],
245
- hasSectionHeader: false,
246
- _originalItemIndex: -1
247
- }
248
- }
249
- // 将 item 添加到当前 section 的 data 中
250
- const itemIndex = currentSection.data.length
251
- currentSection.data.push(extendObject({}, item, {
252
- _originalItemIndex: index
253
- }))
254
- let sectionIndex
255
- // 为 item 添加索引映射 - 存储格式为: "sectionIndex_itemIndex"
256
- if (!currentSection.hasSectionHeader && sections.length === 0) {
257
- // 在默认section中(第一个且无header)
258
- sectionIndex = 0
259
- indexMap.current[index] = `${sectionIndex}_${itemIndex}`
260
- } else {
261
- // 在普通section中
262
- sectionIndex = sections.length
263
- indexMap.current[index] = `${sectionIndex}_${itemIndex}`
264
- }
265
- // 添加反向索引映射
266
- reverseIndexMap.current[`${sectionIndex}_${itemIndex}`] = index
267
- }
268
- })
269
- // 添加最后一个 section
270
- if (currentSection) {
271
- sections.push(currentSection)
272
- }
273
- return sections
274
- }, [listData])
275
-
276
- const { getItemLayout } = useMemo(() => {
277
- const layouts: Array<{ length: number, offset: number, index: number }> = []
278
- let offset = 0
279
-
280
- if (useListHeader) {
281
- // 计算列表头部的高度
282
- offset += listHeaderHeight.getter?.() || listHeaderHeight.value || 0
283
- }
284
-
285
- // 遍历所有 sections
286
- convertedListData.forEach((section: Section, sectionIndex: number) => {
287
- // 添加 section header 的位置信息
288
- const headerHeight = getSectionHeaderHeight({ sectionIndex })
289
- layouts.push({
290
- length: headerHeight,
291
- offset,
292
- index: layouts.length
293
- })
294
- offset += headerHeight
295
-
296
- // 添加该 section 中所有 items 的位置信息
297
- section.data.forEach((item: ListItem, itemIndex: number) => {
298
- const contenteight = getItemHeight({ sectionIndex, rowIndex: itemIndex })
299
- layouts.push({
300
- length: contenteight,
301
- offset,
302
- index: layouts.length
303
- })
304
- offset += contenteight
305
- })
306
-
307
- // 添加该 section 尾部位置信息
308
- // 因为即使 sectionList 没传 renderSectionFooter,getItemLayout 中的 index 的计算也会包含尾部节点
309
- layouts.push({
310
- length: 0,
311
- offset,
312
- index: layouts.length
313
- })
314
- })
315
- return {
316
- itemLayouts: layouts,
317
- getItemLayout: (data: any, index: number) => layouts[index]
318
- }
319
- }, [convertedListData, useListHeader, itemHeight.value, itemHeight.getter, sectionHeaderHeight.value, sectionHeaderHeight.getter, listHeaderHeight.value, listHeaderHeight.getter])
320
-
321
- const scrollAdditionalProps = extendObject(
322
- {
323
- alwaysBounceVertical: false,
324
- alwaysBounceHorizontal: false,
325
- scrollEventThrottle: scrollEventThrottle,
326
- scrollsToTop: enableBackToTop,
327
- showsHorizontalScrollIndicator: showScrollbar,
328
- onEndReachedThreshold,
329
- ref: scrollViewRef,
330
- bounces: false,
331
- stickySectionHeadersEnabled: enableSticky,
332
- onScroll: onScroll,
333
- onEndReached: onEndReached
334
- },
335
- layoutProps
336
- )
337
-
338
- if (enhanced) {
339
- Object.assign(scrollAdditionalProps, {
340
- bounces
341
- })
342
- }
343
- if (refresherEnabled) {
344
- Object.assign(scrollAdditionalProps, {
345
- refreshing: refreshing
346
- })
347
- }
348
-
349
- useImperativeHandle(ref, () => {
350
- return {
351
- ...props,
352
- scrollToIndex
353
- }
354
- })
355
-
356
- const innerProps = useInnerProps(extendObject({}, props, scrollAdditionalProps), [
357
- 'id',
358
- 'show-scrollbar',
359
- 'lower-threshold',
360
- 'refresher-triggered',
361
- 'refresher-enabled',
362
- 'bindrefresherrefresh'
363
- ], { layoutRef })
364
-
365
- // 使用 ref 保存最新的数据,避免数据变化时组件销毁重建
366
- const listHeaderDataRef = useRef(listHeaderData)
367
- listHeaderDataRef.current = listHeaderData
368
-
369
- const listFooterDataRef = useRef(listFooterData)
370
- listFooterDataRef.current = listFooterData
371
-
372
- // 使用 useMemo 获取 GenericComponent 并创建渲染函数,避免每次组件更新都重新创建函数引用导致不必要的重新渲染
373
- const renderItem = useMemo(
374
- () => {
375
- const ItemComponent = getGeneric(generichash, genericrecycleItem)
376
- if (!ItemComponent) return undefined
377
- return ({ item }: { item: any }) => createElement(ItemComponent, { itemData: item })
378
- },
379
- [generichash, genericrecycleItem]
380
- )
381
-
382
- const renderSectionHeader = useMemo(
383
- () => {
384
- const SectionHeaderComponent = getGeneric(generichash, genericsectionHeader)
385
- if (!SectionHeaderComponent) return undefined
386
- return (sectionData: { section: Section }) => {
387
- if (!sectionData.section.hasSectionHeader) return null
388
- return createElement(SectionHeaderComponent, { itemData: sectionData.section.headerData })
389
- }
390
- },
391
- [generichash, genericsectionHeader]
392
- )
393
-
394
- const ListHeaderComponent = useMemo(
395
- () => {
396
- if (!useListHeader) return null
397
- const ListHeaderGenericComponent = getGeneric(generichash, genericListHeader)
398
- if (!ListHeaderGenericComponent) return null
399
- return () => createElement(ListHeaderGenericComponent, { listHeaderData: listHeaderDataRef.current })
400
- },
401
- [useListHeader, generichash, genericListHeader]
402
- )
403
-
404
- const ListFooterComponent = useMemo(
405
- () => {
406
- if (!useListFooter) return null
407
- const ListFooterGenericComponent = getGeneric(generichash, genericListFooter)
408
- if (!ListFooterGenericComponent) return null
409
- return () => createElement(ListFooterGenericComponent, { listFooterData: listFooterDataRef.current })
410
- },
411
- [useListFooter, generichash, genericListFooter]
412
- )
413
-
414
- return createElement(
415
- SectionList,
416
- extendObject(
417
- {
418
- style: [{ height, width }, style, layoutStyle],
419
- sections: convertedListData,
420
- renderItem: renderItem,
421
- getItemLayout: getItemLayout,
422
- ListHeaderComponent: useListHeader ? ListHeaderComponent : null,
423
- ListFooterComponent: useListFooter ? ListFooterComponent : null,
424
- renderSectionHeader: renderSectionHeader,
425
- refreshControl: refresherEnabled
426
- ? React.createElement(RefreshControl, {
427
- onRefresh: onRefresh,
428
- refreshing: refreshing
429
- })
430
- : undefined
431
- },
432
- innerProps
433
- )
434
- )
435
- })
436
-
437
- _SectionList.displayName = 'MpxSectionList'
438
-
439
- export default _SectionList