@tarojs/components-advanced 3.6.0-canary.9 → 3.6.1-alpha.0

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 (61) hide show
  1. package/LICENSE +119 -1
  2. package/dist/components/index.d.ts +1 -0
  3. package/dist/components/index.js +2 -0
  4. package/dist/components/index.js.map +1 -0
  5. package/dist/components/virtual-list/constants.d.ts +2 -0
  6. package/dist/components/virtual-list/constants.js +4 -0
  7. package/dist/components/virtual-list/constants.js.map +1 -0
  8. package/dist/components/virtual-list/dom-helpers.d.ts +2 -0
  9. package/dist/components/virtual-list/dom-helpers.js +41 -0
  10. package/dist/components/virtual-list/dom-helpers.js.map +1 -0
  11. package/dist/components/virtual-list/index.d.ts +193 -0
  12. package/dist/components/virtual-list/index.js +6 -0
  13. package/dist/components/virtual-list/index.js.map +1 -0
  14. package/dist/components/virtual-list/list-set.d.ts +27 -0
  15. package/dist/components/virtual-list/list-set.js +183 -0
  16. package/dist/components/virtual-list/list-set.js.map +1 -0
  17. package/dist/components/virtual-list/preset.d.ts +49 -0
  18. package/dist/components/virtual-list/preset.js +135 -0
  19. package/dist/components/virtual-list/preset.js.map +1 -0
  20. package/dist/components/virtual-list/react/index.d.ts +4 -0
  21. package/dist/components/virtual-list/react/index.js +35 -0
  22. package/dist/components/virtual-list/react/index.js.map +1 -0
  23. package/dist/components/virtual-list/react/list.d.ts +44 -0
  24. package/dist/components/virtual-list/react/list.js +399 -0
  25. package/dist/components/virtual-list/react/list.js.map +1 -0
  26. package/dist/components/virtual-list/react/validate.d.ts +4 -0
  27. package/dist/components/virtual-list/react/validate.js +64 -0
  28. package/dist/components/virtual-list/react/validate.js.map +1 -0
  29. package/dist/components/virtual-list/utils.d.ts +13 -0
  30. package/dist/components/virtual-list/utils.js +36 -0
  31. package/dist/components/virtual-list/utils.js.map +1 -0
  32. package/dist/components/virtual-list/vue/index.d.ts +17 -0
  33. package/dist/components/virtual-list/vue/index.js +12 -0
  34. package/dist/components/virtual-list/vue/index.js.map +1 -0
  35. package/dist/components/virtual-list/vue/list.d.ts +120 -0
  36. package/dist/components/virtual-list/vue/list.js +468 -0
  37. package/dist/components/virtual-list/vue/list.js.map +1 -0
  38. package/dist/components/virtual-list/vue/render.d.ts +4 -0
  39. package/dist/components/virtual-list/vue/render.js +18 -0
  40. package/dist/components/virtual-list/vue/render.js.map +1 -0
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.js +8 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/utils/convert.d.ts +6 -0
  45. package/dist/utils/convert.js +20 -0
  46. package/dist/utils/convert.js.map +1 -0
  47. package/dist/utils/index.d.ts +4 -0
  48. package/dist/utils/index.js +5 -0
  49. package/dist/utils/index.js.map +1 -0
  50. package/dist/utils/lodash.d.ts +2 -0
  51. package/dist/utils/lodash.js +10 -0
  52. package/dist/utils/lodash.js.map +1 -0
  53. package/dist/utils/math.d.ts +3 -0
  54. package/dist/utils/math.js +15 -0
  55. package/dist/utils/math.js.map +1 -0
  56. package/dist/utils/timer.d.ts +6 -0
  57. package/dist/utils/timer.js +24 -0
  58. package/dist/utils/timer.js.map +1 -0
  59. package/package.json +18 -9
  60. package/typings/global.d.ts +1 -0
  61. package/typings/vue.d.ts +7 -0
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2018
3
+ Copyright (c) 2018 O2Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,121 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ ========================================================================
24
+
25
+ MIT (react-devtools):
26
+ The following files embed [react-devtools](https://github.com/facebook/react) MIT:
27
+ `/packages/taro-plugin-react-devtools/src/backend/index.js`
28
+ See `/LICENSE` for details of the license.
29
+
30
+ ==================
31
+
32
+ MIT (vue-devtools):
33
+ The following files embed [vue-devtools](https://github.com/vuejs/devtools) MIT:
34
+ `/packages/taro-plugin-vue-devtools/src/backend/*`
35
+ See `/LICENSE` for details of the license.
36
+
37
+ ==================
38
+
39
+ MIT (vite):
40
+ The following files embed [vite](https://github.com/vitejs/vite) MIT:
41
+ `/packages/taro-webpack5-prebundle/src/prebundle/scanImport.ts`,
42
+ `/packages/taro-webpack5-prebundle/src/prebundle/bundle.ts`,
43
+ `/packages/taro-webpack5-prebundle/src/h5.ts`,
44
+ `/packages/taro-webpack5-prebundle/src/min.ts`
45
+ See `/LICENSE` for details of the license.
46
+
47
+ ==================
48
+
49
+ MIT (webpack):
50
+ The following files embed [webpack](https://github.com/webpack/webpack) MIT:
51
+ `/packages/taro-webpack5-prebundle/src/webpack/TaroContainerEntryModule.ts`,
52
+ `/packages/taro-webpack5-prebundle/src/webpack/TaroContainerPlugin.ts`,
53
+ `/packages/taro-webpack5-prebundle/src/webpack/TaroContainerReferencePlugin.ts`,
54
+ `/packages/taro-webpack5-prebundle/src/webpack/TaroModuleFederationPlugin.ts`
55
+ See `/LICENSE` for details of the license.
56
+
57
+ ==================
58
+
59
+ MIT (sizzle):
60
+ The following files embed [sizzle](https://github.com/jquery/sizzle) MIT:
61
+ `/packages/taro-extends/src/jquery/sizzle.js`
62
+ See `/LICENSE.txt` for details of the license.
63
+
64
+ ==================
65
+
66
+ MIT (zepto):
67
+ The following files embed [zepto](https://github.com/madrobby/zepto) MIT:
68
+ `/packages/taro-extends/src/jquery/zepto.js`,
69
+ `/packages/taro-extends/src/jquery/event.js`
70
+ See `/MIT-LICENSE` for details of the license.
71
+
72
+ ==================
73
+
74
+ MIT (css-to-react-native):
75
+ The following files embed [css-to-react-native](https://github.com/styled-components/css-to-react-native) MIT:
76
+ `/packages/css-to-react-native/src/css-to-react-native/*`
77
+ See `/LICENSE.md` for details of the license.
78
+
79
+ ==================
80
+
81
+ MIT (reactify-wc):
82
+ The following files embed [reactify-wc](https://github.com/BBKolton/reactify-wc) MIT:
83
+ `/packages/taro-components-library-react/src/component-lib/reactify-wc.ts`
84
+ See `/LICENSE` for details of the license.
85
+
86
+ ==================
87
+
88
+ MIT (ant-design-mobile-rn):
89
+ The following files embed [ant-design-mobile-rn](https://github.com/ant-design/ant-design-mobile-rn) MIT:
90
+ `/packages/taro-components-rn/src/components/Swiper/carousel.tsx`
91
+ See `/LICENSE` for details of the license.
92
+
93
+ ==================
94
+
95
+ MIT (react-wx-images-viewer):
96
+ The following files embed [react-wx-images-viewer](https://github.com/react-ld/react-wx-images-viewer) MIT:
97
+ `/packages/taro-h5/src/api/media/image/previewImage.ts`
98
+ See `/LICENSE` for details of the license.
99
+
100
+ ==================
101
+
102
+ MIT (webpack-contrib/css-loader):
103
+ The following files embed [webpack-contrib/css-loader](https://github.com/webpack-contrib/css-loader) MIT:
104
+ `/packages/taro-rn-style-transformer/src/utils/index.ts`
105
+ See `/LICENSE` for details of the license.
106
+
107
+ ==================
108
+
109
+ MIT (react-native):
110
+ The following files embed [react-native](https://github.com/facebook/react-native) MIT:
111
+ `/packages/taro-rn-style-transformer/src/transforms/StyleSheet/*`
112
+ See `/LICENSE` for details of the license.
113
+
114
+ ==================
115
+
116
+ MIT (myrne/performance-now):
117
+ The following files embed [myrne/performance-now](https://github.com/myrne/performance-now) MIT:
118
+ `/packages/taro-runtime/src/bom/raf.ts`
119
+ See `/LICENSE` for details of the license.
120
+
121
+ ==================
122
+
123
+ Apache (chameleon-api):
124
+ The following files embed [chameleon-api](https://github.com/chameleon-team/chameleon-api) Apache:
125
+ `/packages/taro-h5/src/api/device/clipboard.ts`
126
+
127
+ ==================
128
+
129
+ MIT (uni-app):
130
+ The following files embed [uni-app](https://github.com/dcloudio/uni-app) MIT:
131
+ `/packages/taro-components-rn/src/components/Video/index.tsx`
132
+ See `/LICENSE` for details of the license.
133
+
134
+ ==================
135
+
136
+ MIT (miniprogram-render):
137
+ The following files embed [miniprogram-render](https://github.com/Tencent/kbone) MIT:
138
+ `/packages/taro-plugin-http/src/runtime/Cookie.ts`
139
+ See `/LICENSE` for details of the license.
@@ -0,0 +1 @@
1
+ export * from "./virtual-list/index";
@@ -0,0 +1,2 @@
1
+ export { VirtualList } from './virtual-list/index.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ declare const IS_SCROLLING_DEBOUNCE_INTERVAL = 200;
2
+ export { IS_SCROLLING_DEBOUNCE_INTERVAL };
@@ -0,0 +1,4 @@
1
+ const IS_SCROLLING_DEBOUNCE_INTERVAL = 200;
2
+
3
+ export { IS_SCROLLING_DEBOUNCE_INTERVAL };
4
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/components/virtual-list/constants.ts"],"sourcesContent":["export const IS_SCROLLING_DEBOUNCE_INTERVAL = 200\n"],"names":[],"mappings":"AAAO,MAAM,8BAA8B,GAAG;;;;"}
@@ -0,0 +1,2 @@
1
+ declare function getRTLOffsetType(recalculate?: boolean): any;
2
+ export { getRTLOffsetType };
@@ -0,0 +1,41 @@
1
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
2
+ // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
3
+ // Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
4
+ // The safest way to check this is to intentionally set a negative offset,
5
+ // and then verify that the subsequent "scroll" event matches the negative offset.
6
+ // If it does not match, then we can assume a non-standard RTL scroll implementation.
7
+ let cachedRTLResult = null;
8
+ function getRTLOffsetType(recalculate = false) {
9
+ if (cachedRTLResult === null || recalculate) {
10
+ const outerDiv = document.createElement('div');
11
+ const outerStyle = outerDiv.style;
12
+ outerStyle.width = '50px';
13
+ outerStyle.height = '50px';
14
+ outerStyle.overflow = 'scroll';
15
+ outerStyle.direction = 'rtl';
16
+ const innerDiv = document.createElement('div');
17
+ const innerStyle = innerDiv.style;
18
+ innerStyle.width = '100px';
19
+ innerStyle.height = '100px';
20
+ outerDiv.appendChild(innerDiv);
21
+ document.body.appendChild(outerDiv);
22
+ if (outerDiv.scrollLeft > 0) {
23
+ cachedRTLResult = 'positive-descending';
24
+ }
25
+ else {
26
+ outerDiv.scrollLeft = 1;
27
+ if (outerDiv.scrollLeft === 0) {
28
+ cachedRTLResult = 'negative';
29
+ }
30
+ else {
31
+ cachedRTLResult = 'positive-ascending';
32
+ }
33
+ }
34
+ document.body.removeChild(outerDiv);
35
+ return cachedRTLResult;
36
+ }
37
+ return cachedRTLResult;
38
+ }
39
+
40
+ export { getRTLOffsetType };
41
+ //# sourceMappingURL=dom-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-helpers.js","sources":["../../../src/components/virtual-list/dom-helpers.ts"],"sourcesContent":["// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.\n// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).\n// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.\n// The safest way to check this is to intentionally set a negative offset,\n// and then verify that the subsequent \"scroll\" event matches the negative offset.\n// If it does not match, then we can assume a non-standard RTL scroll implementation.\n\nlet cachedRTLResult = null\n\nexport function getRTLOffsetType (recalculate = false) {\n if (cachedRTLResult === null || recalculate) {\n const outerDiv = document.createElement('div')\n const outerStyle = outerDiv.style\n outerStyle.width = '50px'\n outerStyle.height = '50px'\n outerStyle.overflow = 'scroll'\n outerStyle.direction = 'rtl'\n const innerDiv = document.createElement('div')\n const innerStyle = innerDiv.style\n innerStyle.width = '100px'\n innerStyle.height = '100px'\n outerDiv.appendChild(innerDiv)\n document.body.appendChild(outerDiv)\n\n if (outerDiv.scrollLeft > 0) {\n cachedRTLResult = 'positive-descending'\n } else {\n outerDiv.scrollLeft = 1\n\n if (outerDiv.scrollLeft === 0) {\n cachedRTLResult = 'negative'\n } else {\n cachedRTLResult = 'positive-ascending'\n }\n }\n\n document.body.removeChild(outerDiv)\n return cachedRTLResult\n }\n\n return cachedRTLResult\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AAEA,IAAI,eAAe,GAAG,IAAI,CAAA;AAEV,SAAA,gBAAgB,CAAE,WAAW,GAAG,KAAK,EAAA;AACnD,IAAA,IAAI,eAAe,KAAK,IAAI,IAAI,WAAW,EAAE;QAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AAC9C,QAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAA;AACjC,QAAA,UAAU,CAAC,KAAK,GAAG,MAAM,CAAA;AACzB,QAAA,UAAU,CAAC,MAAM,GAAG,MAAM,CAAA;AAC1B,QAAA,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAA;AAC9B,QAAA,UAAU,CAAC,SAAS,GAAG,KAAK,CAAA;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AAC9C,QAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAA;AACjC,QAAA,UAAU,CAAC,KAAK,GAAG,OAAO,CAAA;AAC1B,QAAA,UAAU,CAAC,MAAM,GAAG,OAAO,CAAA;AAC3B,QAAA,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC9B,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;AAEnC,QAAA,IAAI,QAAQ,CAAC,UAAU,GAAG,CAAC,EAAE;YAC3B,eAAe,GAAG,qBAAqB,CAAA;AACxC,SAAA;AAAM,aAAA;AACL,YAAA,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAA;AAEvB,YAAA,IAAI,QAAQ,CAAC,UAAU,KAAK,CAAC,EAAE;gBAC7B,eAAe,GAAG,UAAU,CAAA;AAC7B,aAAA;AAAM,iBAAA;gBACL,eAAe,GAAG,oBAAoB,CAAA;AACvC,aAAA;AACF,SAAA;AAED,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;AACnC,QAAA,OAAO,eAAe,CAAA;AACvB,KAAA;AAED,IAAA,OAAO,eAAe,CAAA;AACxB;;;;"}
@@ -0,0 +1,193 @@
1
+ import { BaseEventOrig, BaseEventOrigFunction, ScrollViewProps, StandardProps } from '@tarojs/components';
2
+ import { Component, ComponentType, CSSProperties, ReactNode } from 'react';
3
+ interface VirtualListProps extends Omit<StandardProps, 'children'> {
4
+ /** 列表的高度。 */
5
+ height: string | number;
6
+ /** 列表的宽度。 */
7
+ width: string | number;
8
+ /** 子组件 */
9
+ item: ComponentType<{
10
+ /** 组件 ID */
11
+ id: string;
12
+ /** 单项的样式,样式必须传入组件的 style 中 */
13
+ style?: CSSProperties;
14
+ /** 组件渲染的数据 */
15
+ data: any;
16
+ /** 组件渲染数据的索引 */
17
+ index: number;
18
+ /** 组件是否正在滚动,当 useIsScrolling 值为 true 时返回布尔值,否则返回 undefined */
19
+ isScrolling?: boolean;
20
+ }>;
21
+ /** 列表的长度 */
22
+ itemCount: number;
23
+ /** 渲染数据 */
24
+ itemData: any[];
25
+ /** 列表单项的大小,垂直滚动时为高度,水平滚动时为宽度。
26
+ *
27
+ * > Note:
28
+ * > - unlimitedSize 模式下如果传入函数,只会调用一次用于设置初始值
29
+ * > - 非 unlimitedSize 模式下如果传入函数,为避免性能问题,每个节点只会调用一次用于设置初始值
30
+ */
31
+ itemSize: number | ((index?: number, itemData?: any[]) => number);
32
+ /** 解开高度列表单项大小限制,默认值使用: itemSize (请注意,初始高度与实际高度差异过大会导致隐患)。
33
+ *
34
+ * > Note: 通过 itemSize 设置的初始高度与子节点实际高度差异过大会导致隐患
35
+ * @default false
36
+ */
37
+ unlimitedSize?: boolean;
38
+ /** 布局方式
39
+ * @default "absolute"
40
+ */
41
+ position?: 'absolute' | 'relative';
42
+ /** 初始滚动偏移值,水平滚动影响 scrollLeft,垂直滚动影响 scrollTop。 */
43
+ initialScrollOffset?: number;
44
+ /** 列表内部容器组件类型。
45
+ * @default View
46
+ */
47
+ innerElementType?: ComponentType;
48
+ /** 通过 ScrollViewContext 优化组件滚动性能
49
+ * @default false
50
+ * @note 部分平台不支持,使用时请注意甄别
51
+ */
52
+ enhanced?: boolean;
53
+ /** 顶部区域 */
54
+ renderTop?: ReactNode;
55
+ /** 底部区域 */
56
+ renderBottom?: ReactNode;
57
+ /** 滚动方向。vertical 为垂直滚动,horizontal 为平行滚动。
58
+ * @default "vertical"
59
+ */
60
+ layout?: 'vertical' | 'horizontal';
61
+ /** 列表滚动时调用函数 */
62
+ onScroll?: (event: VirtualListProps.IVirtualListEvent<VirtualListProps.IVirtualListEventDetail>) => void;
63
+ /** 调用平台原生的滚动监听函数。 */
64
+ onScrollNative?: BaseEventOrigFunction<ScrollViewProps.onScrollDetail>;
65
+ /** 在可视区域之外渲染的列表单项数量,值设置得越高,快速滚动时出现白屏的概率就越小,相应地,每次滚动的性能会变得越差。 */
66
+ overscanCount?: number;
67
+ /** 上下滚动预占位节点 */
68
+ placeholderCount?: number;
69
+ /** 是否注入 isScrolling 属性到 item 组件。这个参数一般用于实现滚动骨架屏(或其它 placeholder) 时比较有用。 */
70
+ useIsScrolling?: boolean;
71
+ style?: CSSProperties;
72
+ }
73
+ declare namespace VirtualListProps {
74
+ interface IVirtualListEventDetail extends ScrollViewProps.onScrollDetail {
75
+ scrollLeft: number;
76
+ scrollTop: number;
77
+ scrollHeight: number;
78
+ scrollWidth: number;
79
+ }
80
+ interface IVirtualListEvent<T extends ScrollViewProps.onScrollDetail = ScrollViewProps.onScrollDetail> extends BaseEventOrig {
81
+ /** 滚动方向,可能值为 forward 往前, backward 往后。 */
82
+ scrollDirection: 'forward' | 'backward';
83
+ /** 滚动距离 */
84
+ scrollOffset: number;
85
+ /** 当滚动是由 scrollTo() 或 scrollToItem() 调用时返回 true,否则返回 false */
86
+ scrollUpdateWasRequested: boolean;
87
+ /** 当前只有 React 支持 */
88
+ detail: T;
89
+ }
90
+ }
91
+ /** 虚拟列表
92
+ * @classification viewContainer
93
+ * @supported weapp, swan, alipay, tt, qq, jd, h5
94
+ * @example_react
95
+ * ```tsx
96
+ * import VirtualList from `@tarojs/components/virtual-list`
97
+ *
98
+ * function buildData (offset = 0) {
99
+ * return Array(100).fill(0).map((_, i) => i + offset);
100
+ * }
101
+ *
102
+ * const Row = React.memo(({ id, index, style, data }) => {
103
+ * return (
104
+ * <View id={id} className={index % 2 ? 'ListItemOdd' : 'ListItemEven'} style={style}>
105
+ * Row {index}
106
+ * </View>
107
+ * );
108
+ * })
109
+ *
110
+ * export default class Index extends Component {
111
+ * state = {
112
+ * data: buildData(0),
113
+ * }
114
+ *
115
+ * render() {
116
+ * const { data } = this.state
117
+ * const dataLen = data.length
118
+ * return (
119
+ * <VirtualList
120
+ * height={500} // 列表的高度
121
+ * width='100%' // 列表的宽度
122
+ * item={Row} // 列表单项组件,这里只能传入一个组件
123
+ * itemData={data} // 渲染列表的数据
124
+ * itemCount={dataLen} // 渲染列表的长度
125
+ * itemSize={100} // 列表单项的高度
126
+ * />
127
+ * );
128
+ * }
129
+ * }
130
+ * ```
131
+ * @example_vue
132
+ * ```js
133
+ * // app.js 入口文件
134
+ * import Vue from 'vue'
135
+ * import VirtualList from '@tarojs/components/virtual-list'
136
+ *
137
+ * Vue.use(VirtualList)
138
+ * ```
139
+ * ```js
140
+ * <! –– row.vue 单项组件 ––>
141
+ * <template>
142
+ * <view
143
+ * :class="index % 2 ? 'ListItemOdd' : 'ListItemEven'"
144
+ * :style="css"
145
+ * >
146
+ * Row {{ index }} : {{ data[index] }}
147
+ * </view>
148
+ * </template>
149
+ *
150
+ * <script>
151
+ * export default {
152
+ * props: ['index', 'data', 'css']
153
+ * }
154
+ * </script>
155
+ * ```
156
+ * ```js
157
+ * <! –– page.vue 页面组件 ––>
158
+ * <template>
159
+ * <virtual-list
160
+ * wclass="List"
161
+ * :height="500"
162
+ * :item-data="list"
163
+ * :item-count="list.length"
164
+ * :item-size="100"
165
+ * :item="Row"
166
+ * width="100%"
167
+ * />
168
+ * </template>
169
+ *
170
+ * <script>
171
+ * import Row from './row.vue'
172
+ * import { markRaw } from 'vue'
173
+ *
174
+ * function buildData (offset = 0) {
175
+ * return Array(100).fill(0).map((_, i) => i + offset)
176
+ * }
177
+ *
178
+ * export default {
179
+ * data() {
180
+ * return {
181
+ * Row: markRaw(Row),
182
+ * list: buildData(0)
183
+ * }
184
+ * },
185
+ * }
186
+ * </script>
187
+ * ```
188
+ * @see https://taro-docs.jd.com/docs/virtual-list
189
+ */
190
+ declare class VirtualListComponent extends Component<VirtualListProps> {
191
+ }
192
+ declare const VirtualList: typeof VirtualListComponent;
193
+ export { VirtualList as default, VirtualList, VirtualListProps };
@@ -0,0 +1,6 @@
1
+ const VirtualList = (process.env.FRAMEWORK === 'vue' || process.env.FRAMEWORK === 'vue3')
2
+ ? require('./vue').default
3
+ : require('./react').default;
4
+
5
+ export { VirtualList, VirtualList as default };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/virtual-list/index.ts"],"sourcesContent":["import type { BaseEventOrig, BaseEventOrigFunction, ScrollViewProps, StandardProps } from '@tarojs/components'\nimport type { Component, ComponentType, CSSProperties, ReactNode } from 'react'\n\ninterface VirtualListProps extends Omit<StandardProps, 'children'> {\n /** 列表的高度。 */\n height: string | number\n /** 列表的宽度。 */\n width: string | number\n /** 子组件 */\n item: ComponentType<{\n /** 组件 ID */\n id: string\n /** 单项的样式,样式必须传入组件的 style 中 */\n style?: CSSProperties\n /** 组件渲染的数据 */\n data: any\n /** 组件渲染数据的索引 */\n index: number\n /** 组件是否正在滚动,当 useIsScrolling 值为 true 时返回布尔值,否则返回 undefined */\n isScrolling?: boolean\n }>\n /** 列表的长度 */\n itemCount: number\n /** 渲染数据 */\n itemData: any[]\n /** 列表单项的大小,垂直滚动时为高度,水平滚动时为宽度。\n *\n * > Note:\n * > - unlimitedSize 模式下如果传入函数,只会调用一次用于设置初始值\n * > - 非 unlimitedSize 模式下如果传入函数,为避免性能问题,每个节点只会调用一次用于设置初始值\n */\n itemSize: number | ((index?: number, itemData?: any[]) => number)\n /** 解开高度列表单项大小限制,默认值使用: itemSize (请注意,初始高度与实际高度差异过大会导致隐患)。\n *\n * > Note: 通过 itemSize 设置的初始高度与子节点实际高度差异过大会导致隐患\n * @default false\n */\n unlimitedSize?: boolean\n /** 布局方式\n * @default \"absolute\"\n */\n position?: 'absolute' | 'relative'\n /** 初始滚动偏移值,水平滚动影响 scrollLeft,垂直滚动影响 scrollTop。 */\n initialScrollOffset?: number\n /** 列表内部容器组件类型。\n * @default View\n */\n innerElementType?: ComponentType\n /** 通过 ScrollViewContext 优化组件滚动性能\n * @default false\n * @note 部分平台不支持,使用时请注意甄别\n */\n enhanced?: boolean\n /** 顶部区域 */\n renderTop?: ReactNode\n /** 底部区域 */\n renderBottom?: ReactNode\n /** 滚动方向。vertical 为垂直滚动,horizontal 为平行滚动。\n * @default \"vertical\"\n */\n layout?: 'vertical' | 'horizontal'\n /** 列表滚动时调用函数 */\n onScroll?: (event: VirtualListProps.IVirtualListEvent<VirtualListProps.IVirtualListEventDetail>) => void\n /** 调用平台原生的滚动监听函数。 */\n onScrollNative?: BaseEventOrigFunction<ScrollViewProps.onScrollDetail>\n /** 在可视区域之外渲染的列表单项数量,值设置得越高,快速滚动时出现白屏的概率就越小,相应地,每次滚动的性能会变得越差。 */\n overscanCount?: number\n /** 上下滚动预占位节点 */\n placeholderCount?: number\n /** 是否注入 isScrolling 属性到 item 组件。这个参数一般用于实现滚动骨架屏(或其它 placeholder) 时比较有用。 */\n useIsScrolling?: boolean\n style?: CSSProperties\n}\n\ndeclare namespace VirtualListProps {\n interface IVirtualListEventDetail extends ScrollViewProps.onScrollDetail {\n scrollLeft: number\n scrollTop: number\n scrollHeight: number\n scrollWidth: number\n }\n\n interface IVirtualListEvent<T extends ScrollViewProps.onScrollDetail = ScrollViewProps.onScrollDetail> extends BaseEventOrig {\n /** 滚动方向,可能值为 forward 往前, backward 往后。 */\n scrollDirection: 'forward' | 'backward'\n /** 滚动距离 */\n scrollOffset: number\n /** 当滚动是由 scrollTo() 或 scrollToItem() 调用时返回 true,否则返回 false */\n scrollUpdateWasRequested: boolean\n /** 当前只有 React 支持 */\n detail: T\n }\n}\n\n/** 虚拟列表\n * @classification viewContainer\n * @supported weapp, swan, alipay, tt, qq, jd, h5\n * @example_react\n * ```tsx\n * import VirtualList from `@tarojs/components/virtual-list`\n *\n * function buildData (offset = 0) {\n * return Array(100).fill(0).map((_, i) => i + offset);\n * }\n *\n * const Row = React.memo(({ id, index, style, data }) => {\n * return (\n * <View id={id} className={index % 2 ? 'ListItemOdd' : 'ListItemEven'} style={style}>\n * Row {index}\n * </View>\n * );\n * })\n *\n * export default class Index extends Component {\n * state = {\n * data: buildData(0),\n * }\n *\n * render() {\n * const { data } = this.state\n * const dataLen = data.length\n * return (\n * <VirtualList\n * height={500} // 列表的高度\n * width='100%' // 列表的宽度\n * item={Row} // 列表单项组件,这里只能传入一个组件\n * itemData={data} // 渲染列表的数据\n * itemCount={dataLen} // 渲染列表的长度\n * itemSize={100} // 列表单项的高度\n * />\n * );\n * }\n * }\n * ```\n * @example_vue\n * ```js\n * // app.js 入口文件\n * import Vue from 'vue'\n * import VirtualList from '@tarojs/components/virtual-list'\n *\n * Vue.use(VirtualList)\n * ```\n * ```js\n * <! –– row.vue 单项组件 ––>\n * <template>\n * <view\n * :class=\"index % 2 ? 'ListItemOdd' : 'ListItemEven'\"\n * :style=\"css\"\n * >\n * Row {{ index }} : {{ data[index] }}\n * </view>\n * </template>\n *\n * <script>\n * export default {\n * props: ['index', 'data', 'css']\n * }\n * </script>\n * ```\n * ```js\n * <! –– page.vue 页面组件 ––>\n * <template>\n * <virtual-list\n * wclass=\"List\"\n * :height=\"500\"\n * :item-data=\"list\"\n * :item-count=\"list.length\"\n * :item-size=\"100\"\n * :item=\"Row\"\n * width=\"100%\"\n * />\n * </template>\n *\n * <script>\n * import Row from './row.vue'\n * import { markRaw } from 'vue'\n *\n * function buildData (offset = 0) {\n * return Array(100).fill(0).map((_, i) => i + offset)\n * }\n *\n * export default {\n * data() {\n * return {\n * Row: markRaw(Row),\n * list: buildData(0)\n * }\n * },\n * }\n * </script>\n * ```\n * @see https://taro-docs.jd.com/docs/virtual-list\n */\ndeclare class VirtualListComponent extends Component<VirtualListProps> {}\n\nconst VirtualList: typeof VirtualListComponent = (process.env.FRAMEWORK === 'vue' || process.env.FRAMEWORK === 'vue3')\n ? require('./vue').default\n : require('./react').default\n\nexport { VirtualList, VirtualListProps }\nexport default VirtualList\n"],"names":[],"mappings":"AAmMA,MAAM,WAAW,GAAgC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM;AACnH,MAAE,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO;AAC1B,MAAE,OAAO,CAAC,SAAS,CAAC,CAAC;;;;"}
@@ -0,0 +1,27 @@
1
+ import { IProps } from "./preset";
2
+ type TProps = Pick<IProps, 'width' | 'height' | 'unlimitedSize' | 'itemCount' | 'itemData' | 'itemSize' | 'overscanCount' | 'direction' | 'layout'>;
3
+ declare class ListSet {
4
+ protected props: TProps;
5
+ protected refresh?: TFunc;
6
+ list: number[];
7
+ mode?: 'normal' | 'function' | 'unlimited';
8
+ defaultSize: number;
9
+ constructor(props: TProps, refresh?: TFunc);
10
+ get isNormalMode(): boolean;
11
+ get isFunctionMode(): boolean;
12
+ get isUnlimitedMode(): boolean;
13
+ get length(): number;
14
+ get overscan(): number;
15
+ get wrapperSize(): number;
16
+ update(props: TProps): void;
17
+ setSize(i?: number, size?: number): void;
18
+ getSize(i?: number): number;
19
+ getOffsetSize(i?: number): number;
20
+ getSizeCount(offset?: number): number;
21
+ getStartIndex(scrollOffset?: number): number;
22
+ getStopIndex(wrapperSize?: number, scrollOffset?: number, startIndex?: number): number;
23
+ getRangeToRender(direction: 'forward' | 'backward', scrollOffset?: number, block?: boolean): number[];
24
+ getOffsetForIndexAndAlignment(index: number, align: string, scrollOffset: number): number;
25
+ compareSize(i?: number, size?: number): boolean;
26
+ }
27
+ export { ListSet as default };
@@ -0,0 +1,183 @@
1
+ import { isFunction } from '@tarojs/shared';
2
+ import { isHorizontalFunc } from './utils.js';
3
+
4
+ class ListSet {
5
+ constructor(props, refresh) {
6
+ this.props = props;
7
+ this.refresh = refresh;
8
+ this.list = [];
9
+ this.defaultSize = 1;
10
+ this.update(props);
11
+ // Note: 不考虑列表模式切换情况,可能会导致列表抖动体验过差
12
+ if (this.props.unlimitedSize) {
13
+ this.mode = 'unlimited';
14
+ }
15
+ else if (isFunction(this.props.itemSize)) {
16
+ this.mode = 'function';
17
+ }
18
+ else {
19
+ this.mode = 'normal';
20
+ }
21
+ this.defaultSize = (isFunction(this.props.itemSize) ? this.props.itemSize() : this.props.itemSize) || 1;
22
+ if (!this.isNormalMode) {
23
+ this.list = new Array(this.length).fill(-1);
24
+ }
25
+ }
26
+ get isNormalMode() {
27
+ return this.mode === 'normal';
28
+ }
29
+ get isFunctionMode() {
30
+ return this.mode === 'function';
31
+ }
32
+ get isUnlimitedMode() {
33
+ return this.mode === 'unlimited';
34
+ }
35
+ get length() {
36
+ return this.props.itemCount || 100;
37
+ }
38
+ get overscan() {
39
+ return this.props.overscanCount || 0;
40
+ }
41
+ get wrapperSize() {
42
+ const { height, width } = this.props;
43
+ const isHorizontal = isHorizontalFunc(this.props);
44
+ const size = (isHorizontal ? width : height);
45
+ if (process.env.NODE_ENV !== 'production' && typeof size !== 'number') {
46
+ console.warn(`In mode ${isHorizontal ? 'horizontal, width' : 'vertical, height'} parameter should be a number, but got ${typeof size}.`);
47
+ }
48
+ return size;
49
+ }
50
+ update(props) {
51
+ this.props = props;
52
+ if (this.length > this.list.length) {
53
+ const arr = new Array(this.length - this.list.length).fill(-1);
54
+ this.list.push(...arr);
55
+ }
56
+ else if (this.length < this.list.length) {
57
+ this.list.length = this.length;
58
+ }
59
+ }
60
+ setSize(i = 0, size = this.defaultSize) {
61
+ var _a;
62
+ this.list[i] = size;
63
+ (_a = this.refresh) === null || _a === void 0 ? void 0 : _a.call(this);
64
+ }
65
+ getSize(i = 0) {
66
+ const size = this.props.itemSize;
67
+ const item = this.list[i];
68
+ if (item >= 0)
69
+ return item;
70
+ if (this.isFunctionMode && isFunction(size)) {
71
+ const itemSize = size(i, this.props.itemData);
72
+ this.setSize(i, itemSize);
73
+ return itemSize;
74
+ }
75
+ return this.defaultSize;
76
+ }
77
+ getOffsetSize(i = this.list.length) {
78
+ if (this.isNormalMode)
79
+ return i * this.defaultSize;
80
+ return this.list.slice(0, i).reduce((sum, _, idx) => sum + this.getSize(idx), 0);
81
+ }
82
+ getSizeCount(offset = 0) {
83
+ if (offset === 0) {
84
+ return 0;
85
+ }
86
+ // if (this.isNormalMode) {
87
+ // return Math.min(this.length - 1, Math.floor(offset / this.length))
88
+ // }
89
+ let offsetSize = 0;
90
+ const count = this.list.reduce((sum, _, idx) => {
91
+ if (offsetSize < offset) {
92
+ offsetSize += this.getSize(idx);
93
+ return ++sum;
94
+ }
95
+ return sum;
96
+ }, 0);
97
+ return count - 1;
98
+ }
99
+ getStartIndex(scrollOffset = 0) {
100
+ return Math.max(0, this.getSizeCount(scrollOffset) - 1);
101
+ }
102
+ getStopIndex(wrapperSize = 0, scrollOffset = 0, startIndex = 0) {
103
+ // const visibleOffset = this.getOffsetSize(startIndex)
104
+ // if (this.isNormalMode) {
105
+ // const numVisibleItems = Math.ceil((wrapperSize + scrollOffset - visibleOffset) / this.length)
106
+ // /** -1 is because stop index is inclusive */
107
+ // return Math.max(startIndex, Math.min(this.length - 1, startIndex + numVisibleItems - 1))
108
+ // }
109
+ return Math.max(startIndex, Math.min(this.length - 1, this.getSizeCount(wrapperSize + scrollOffset)));
110
+ }
111
+ getRangeToRender(direction, scrollOffset = 0, block = false) {
112
+ if (this.length === 0) {
113
+ return [0, 0, 0, 0];
114
+ }
115
+ const wrapperSize = this.wrapperSize;
116
+ const startIndex = this.getStartIndex(scrollOffset);
117
+ const stopIndex = this.getStopIndex(wrapperSize, scrollOffset, startIndex);
118
+ // Overscan by one item in each direction so that tab/focus works. If there isn't at least one extra item, tab loops back around.
119
+ const overscanBackward = !block || direction === 'backward' ? Math.max(1, this.overscan) : 1;
120
+ const overscanForward = !block || direction === 'forward' ? Math.max(1, this.overscan) : 1;
121
+ return [
122
+ Math.max(0, startIndex - overscanBackward),
123
+ Math.max(0, Math.min(this.length - 1, stopIndex + overscanForward)),
124
+ startIndex,
125
+ stopIndex
126
+ ];
127
+ }
128
+ getOffsetForIndexAndAlignment(index, align, scrollOffset) {
129
+ const wrapperSize = this.wrapperSize;
130
+ const itemSize = this.getSize(index);
131
+ const lastItemOffset = Math.max(0, this.getOffsetSize(this.props.itemCount) - wrapperSize);
132
+ const maxOffset = Math.min(lastItemOffset, this.getOffsetSize(index));
133
+ const minOffset = Math.max(0, this.getOffsetSize(index) - wrapperSize + itemSize);
134
+ if (align === 'smart') {
135
+ if (scrollOffset >= minOffset - wrapperSize && scrollOffset <= maxOffset + wrapperSize) {
136
+ align = 'auto';
137
+ }
138
+ else {
139
+ align = 'center';
140
+ }
141
+ }
142
+ switch (align) {
143
+ case 'start':
144
+ return maxOffset;
145
+ case 'end':
146
+ return minOffset;
147
+ case 'center':
148
+ {
149
+ // "Centered" offset is usually the average of the min and max.
150
+ // But near the edges of the list, this doesn't hold true.
151
+ const middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
152
+ if (middleOffset < Math.ceil(wrapperSize / 2)) {
153
+ return 0; // near the beginning
154
+ }
155
+ else if (middleOffset > lastItemOffset + Math.floor(wrapperSize / 2)) {
156
+ return lastItemOffset; // near the end
157
+ }
158
+ else {
159
+ return middleOffset;
160
+ }
161
+ }
162
+ case 'auto':
163
+ default:
164
+ if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
165
+ return scrollOffset;
166
+ }
167
+ else if (scrollOffset < minOffset) {
168
+ return minOffset;
169
+ }
170
+ else {
171
+ return maxOffset;
172
+ }
173
+ }
174
+ }
175
+ compareSize(i = 0, size = 0) {
176
+ if (this.isNormalMode)
177
+ return true;
178
+ return this.getSize(i) === size;
179
+ }
180
+ }
181
+
182
+ export { ListSet as default };
183
+ //# sourceMappingURL=list-set.js.map