@zamlia/mini-ui 0.0.1

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 (148) hide show
  1. package/es/components/common/BottomPopup/index.d.ts +78 -0
  2. package/es/components/common/BottomPopup/index.d.ts.map +1 -0
  3. package/es/components/common/Card/index.d.ts +33 -0
  4. package/es/components/common/Card/index.d.ts.map +1 -0
  5. package/es/components/common/CardItem/index.d.ts +60 -0
  6. package/es/components/common/CardItem/index.d.ts.map +1 -0
  7. package/es/components/common/DataSelect/index.d.ts +15 -0
  8. package/es/components/common/DataSelect/index.d.ts.map +1 -0
  9. package/es/components/common/Modal/index.d.ts +31 -0
  10. package/es/components/common/Modal/index.d.ts.map +1 -0
  11. package/es/components/common/NavBar/index.d.ts +38 -0
  12. package/es/components/common/NavBar/index.d.ts.map +1 -0
  13. package/es/components/common/Page/index.d.ts +16 -0
  14. package/es/components/common/Page/index.d.ts.map +1 -0
  15. package/es/components/common/PullToPushRefresh/index.d.ts +94 -0
  16. package/es/components/common/PullToPushRefresh/index.d.ts.map +1 -0
  17. package/es/components/common/Radio/index.d.ts +26 -0
  18. package/es/components/common/Radio/index.d.ts.map +1 -0
  19. package/es/components/common/TabPane/index.d.ts +9 -0
  20. package/es/components/common/TabPane/index.d.ts.map +1 -0
  21. package/es/components/common/Tabs/index.d.ts +27 -0
  22. package/es/components/common/Tabs/index.d.ts.map +1 -0
  23. package/es/components/common/UploadFile/index.d.ts +50 -0
  24. package/es/components/common/UploadFile/index.d.ts.map +1 -0
  25. package/es/components/common/UploadFile/upload.d.ts +11 -0
  26. package/es/components/common/UploadFile/upload.d.ts.map +1 -0
  27. package/es/components/common/UploadFile/utils.d.ts +20 -0
  28. package/es/components/common/UploadFile/utils.d.ts.map +1 -0
  29. package/es/components/common/VideoView/index.d.ts +14 -0
  30. package/es/components/common/VideoView/index.d.ts.map +1 -0
  31. package/es/components/common/index.d.ts +23 -0
  32. package/es/components/common/index.d.ts.map +1 -0
  33. package/es/components/industry/CitySelectButton/index.d.ts +17 -0
  34. package/es/components/industry/CitySelectButton/index.d.ts.map +1 -0
  35. package/es/components/industry/CitySelectModal/index.d.ts +13 -0
  36. package/es/components/industry/CitySelectModal/index.d.ts.map +1 -0
  37. package/es/components/industry/PaymentMethodSelect/index.d.ts +59 -0
  38. package/es/components/industry/PaymentMethodSelect/index.d.ts.map +1 -0
  39. package/es/components/industry/index.d.ts +5 -0
  40. package/es/components/industry/index.d.ts.map +1 -0
  41. package/es/config/classPrefix.d.ts +36 -0
  42. package/es/config/classPrefix.d.ts.map +1 -0
  43. package/es/index.d.ts +4 -0
  44. package/es/index.d.ts.map +1 -0
  45. package/es/index.js +5334 -0
  46. package/es/index.js.map +1 -0
  47. package/es/styles/_base.scss +4 -0
  48. package/es/styles/index.scss +19 -0
  49. package/es/styles/mixins.scss +15 -0
  50. package/es/styles/variables.scss +2 -0
  51. package/es/utils/city.d.ts +4005 -0
  52. package/es/utils/city.d.ts.map +1 -0
  53. package/es/utils/index.d.ts +50 -0
  54. package/es/utils/index.d.ts.map +1 -0
  55. package/lib/components/common/BottomPopup/index.d.ts +78 -0
  56. package/lib/components/common/BottomPopup/index.d.ts.map +1 -0
  57. package/lib/components/common/Card/index.d.ts +33 -0
  58. package/lib/components/common/Card/index.d.ts.map +1 -0
  59. package/lib/components/common/CardItem/index.d.ts +60 -0
  60. package/lib/components/common/CardItem/index.d.ts.map +1 -0
  61. package/lib/components/common/DataSelect/index.d.ts +15 -0
  62. package/lib/components/common/DataSelect/index.d.ts.map +1 -0
  63. package/lib/components/common/Modal/index.d.ts +31 -0
  64. package/lib/components/common/Modal/index.d.ts.map +1 -0
  65. package/lib/components/common/NavBar/index.d.ts +38 -0
  66. package/lib/components/common/NavBar/index.d.ts.map +1 -0
  67. package/lib/components/common/Page/index.d.ts +16 -0
  68. package/lib/components/common/Page/index.d.ts.map +1 -0
  69. package/lib/components/common/PullToPushRefresh/index.d.ts +94 -0
  70. package/lib/components/common/PullToPushRefresh/index.d.ts.map +1 -0
  71. package/lib/components/common/Radio/index.d.ts +26 -0
  72. package/lib/components/common/Radio/index.d.ts.map +1 -0
  73. package/lib/components/common/TabPane/index.d.ts +9 -0
  74. package/lib/components/common/TabPane/index.d.ts.map +1 -0
  75. package/lib/components/common/Tabs/index.d.ts +27 -0
  76. package/lib/components/common/Tabs/index.d.ts.map +1 -0
  77. package/lib/components/common/UploadFile/index.d.ts +50 -0
  78. package/lib/components/common/UploadFile/index.d.ts.map +1 -0
  79. package/lib/components/common/UploadFile/upload.d.ts +11 -0
  80. package/lib/components/common/UploadFile/upload.d.ts.map +1 -0
  81. package/lib/components/common/UploadFile/utils.d.ts +20 -0
  82. package/lib/components/common/UploadFile/utils.d.ts.map +1 -0
  83. package/lib/components/common/VideoView/index.d.ts +14 -0
  84. package/lib/components/common/VideoView/index.d.ts.map +1 -0
  85. package/lib/components/common/index.d.ts +23 -0
  86. package/lib/components/common/index.d.ts.map +1 -0
  87. package/lib/components/industry/CitySelectButton/index.d.ts +17 -0
  88. package/lib/components/industry/CitySelectButton/index.d.ts.map +1 -0
  89. package/lib/components/industry/CitySelectModal/index.d.ts +13 -0
  90. package/lib/components/industry/CitySelectModal/index.d.ts.map +1 -0
  91. package/lib/components/industry/PaymentMethodSelect/index.d.ts +59 -0
  92. package/lib/components/industry/PaymentMethodSelect/index.d.ts.map +1 -0
  93. package/lib/components/industry/index.d.ts +5 -0
  94. package/lib/components/industry/index.d.ts.map +1 -0
  95. package/lib/config/classPrefix.d.ts +36 -0
  96. package/lib/config/classPrefix.d.ts.map +1 -0
  97. package/lib/index.d.ts +585 -0
  98. package/lib/index.d.ts.map +1 -0
  99. package/lib/index.js +5349 -0
  100. package/lib/index.js.map +1 -0
  101. package/lib/styles/_base.scss +4 -0
  102. package/lib/styles/index.scss +19 -0
  103. package/lib/styles/mixins.scss +15 -0
  104. package/lib/styles/variables.scss +2 -0
  105. package/lib/utils/city.d.ts +4005 -0
  106. package/lib/utils/city.d.ts.map +1 -0
  107. package/lib/utils/index.d.ts +50 -0
  108. package/lib/utils/index.d.ts.map +1 -0
  109. package/package.json +81 -0
  110. package/src/components/common/BottomPopup/index.scss +34 -0
  111. package/src/components/common/BottomPopup/index.tsx +129 -0
  112. package/src/components/common/Card/index.scss +160 -0
  113. package/src/components/common/Card/index.tsx +72 -0
  114. package/src/components/common/CardItem/index.tsx +153 -0
  115. package/src/components/common/DataSelect/index.tsx +86 -0
  116. package/src/components/common/Modal/index.scss +49 -0
  117. package/src/components/common/Modal/index.tsx +105 -0
  118. package/src/components/common/NavBar/index.scss +26 -0
  119. package/src/components/common/NavBar/index.tsx +81 -0
  120. package/src/components/common/Page/index.scss +19 -0
  121. package/src/components/common/Page/index.tsx +56 -0
  122. package/src/components/common/PullToPushRefresh/index.scss +38 -0
  123. package/src/components/common/PullToPushRefresh/index.tsx +338 -0
  124. package/src/components/common/Radio/index.scss +15 -0
  125. package/src/components/common/Radio/index.tsx +56 -0
  126. package/src/components/common/TabPane/index.tsx +26 -0
  127. package/src/components/common/Tabs/index.scss +60 -0
  128. package/src/components/common/Tabs/index.tsx +107 -0
  129. package/src/components/common/UploadFile/index.scss +59 -0
  130. package/src/components/common/UploadFile/index.tsx +321 -0
  131. package/src/components/common/UploadFile/upload.ts +63 -0
  132. package/src/components/common/UploadFile/utils.ts +81 -0
  133. package/src/components/common/VideoView/index.tsx +50 -0
  134. package/src/components/common/index.ts +23 -0
  135. package/src/components/industry/CitySelectButton/index.tsx +76 -0
  136. package/src/components/industry/CitySelectModal/index.scss +122 -0
  137. package/src/components/industry/CitySelectModal/index.tsx +121 -0
  138. package/src/components/industry/PaymentMethodSelect/index.scss +146 -0
  139. package/src/components/industry/PaymentMethodSelect/index.tsx +316 -0
  140. package/src/components/industry/index.ts +5 -0
  141. package/src/config/classPrefix.ts +44 -0
  142. package/src/index.ts +9 -0
  143. package/src/styles/_base.scss +4 -0
  144. package/src/styles/index.scss +19 -0
  145. package/src/styles/mixins.scss +15 -0
  146. package/src/styles/variables.scss +2 -0
  147. package/src/utils/city.ts +4072 -0
  148. package/src/utils/index.ts +155 -0
@@ -0,0 +1,338 @@
1
+ import Taro, { useDidShow } from '@tarojs/taro';
2
+ import
3
+ React, {
4
+ MutableRefObject,
5
+ PropsWithChildren,
6
+ useEffect,
7
+ useImperativeHandle,
8
+ useRef,
9
+ useState
10
+ } from 'react';
11
+ import { Utils } from '@utils';
12
+ import { View, Text, ScrollView } from '@tarojs/components';
13
+ import { Loading } from '@nutui/nutui-react-taro';
14
+ import './index.scss';
15
+
16
+ export type PullToPushRefreshProps<T = Record<string, any>> = {
17
+ pageSize?: number
18
+ /** 没有数据展示内容 */
19
+ emptyRender?: React.ReactElement
20
+ /** 加载文案
21
+ * @default 加载中...
22
+ */
23
+ loadingText?: string
24
+ /**
25
+ * 错误文案
26
+ * @default 加载失败,请点击重试
27
+ */
28
+ errorText?: string
29
+ /**
30
+ * 没有数据文案
31
+ * @default emptyText
32
+ * */
33
+ emptyText?: string
34
+ /**
35
+ * 底部文案
36
+ * @default 没有更多了
37
+ * */
38
+ bottomText?: string
39
+ /**
40
+ * 是否展示底部文案
41
+ * @default true
42
+ */
43
+ showBottomText?: boolean
44
+ /**
45
+ * 是否展示加载图标
46
+ * @default true
47
+ */
48
+ showLoding?: boolean
49
+ /**
50
+ * 下拉刷新文案
51
+ * @default '松开即可刷新'
52
+ */
53
+ refreshText?: string
54
+ /**
55
+ * show页面是否加载数据
56
+ * @default false
57
+ */
58
+ showPageRequest?: boolean
59
+ /**
60
+ * 是否首次进入页面自动掉接口
61
+ * @default true
62
+ */
63
+ hasFirstPageAutoRequest?: boolean
64
+ /**
65
+ * 自定义每条数据的内容
66
+ * @param {T} item 当前条数据
67
+ * @param {number} index
68
+ */
69
+ renderItem: (item: T, index: number) => React.ReactElement
70
+ /**
71
+ * 请求方法
72
+ * @param {T} skip 当前页码
73
+ * @param {T} first pageSize
74
+ * @param {Record<string, any>} restParams 可以传其余的饿默认参数
75
+ */
76
+ // request: (skip: number, first: number, restParams?: Record<string, any>) => Promise<PullToPushRefreshRequestType
77
+ request: (skip: number, first: number, restParams?: Record<string, any>) => void
78
+ }
79
+
80
+ export type PullToPushRefreshRef = {
81
+ /**
82
+ * 刷新
83
+ * @param isFirst 是否是第一次调用
84
+ * @param restParams 可以传其余的饿默认参数
85
+ */
86
+ reload: (isFirst?: boolean, restParams?: Record<string, any>) => void
87
+ /**
88
+ * 设置是否可以页面show刷新
89
+ * @param {boolean}bol
90
+ */
91
+ showPageRequest: (bol: boolean) => void
92
+ } | undefined
93
+
94
+ export type PullToPushRefreshRequestType<T> = {
95
+ data: Array<T>
96
+ total: number
97
+ success: boolean
98
+ }
99
+
100
+ export type ListInfoType<T> = {
101
+ loading: boolean,
102
+ error: boolean,
103
+ skip: number,
104
+ list: Array<T>,
105
+ total: number
106
+ }
107
+
108
+ const PullToPushRefresh = React.forwardRef<PullToPushRefreshRef, PropsWithChildren<PullToPushRefreshProps<any>>>((props, ref) => {
109
+ const {
110
+ pageSize: _pageSize = 10,
111
+ emptyRender,
112
+ loadingText = '加载中...',
113
+ errorText = '加载失败,请点击重试',
114
+ emptyText = '没有数据',
115
+ bottomText = '没有更多了',
116
+ showBottomText = true,
117
+ showLoding = true,
118
+ showPageRequest: _showPageRequest = false,
119
+ // refreshText = '松开即可刷新',
120
+ hasFirstPageAutoRequest = true,
121
+ renderItem,
122
+ request = () => { console.error('PullToPushRefresh组件props没有传入handleQuery') },
123
+ } = props;
124
+ const flatlistRef: MutableRefObject<any> = useRef(null);
125
+
126
+ const [, setHasMore] = useState<boolean>(true);
127
+ const [pageSize] = useState<number>(_pageSize)
128
+ const [refreshing, setRefreshing] = useState<boolean>(false);
129
+ const [firstEnter, setFirstEnter] = useState<boolean>(true);
130
+ const [scrollY,] = useState<boolean>(true)
131
+ const [showPageRequest, setShowPageRequest] = useState<boolean>(_showPageRequest);
132
+
133
+ const [listInfo, setListInfo] = useState<ListInfoType<any>>({
134
+ loading: false,
135
+ error: true,
136
+ skip: 0,
137
+ list: [],
138
+ total: 0
139
+ })
140
+
141
+ useEffect(() => {
142
+ setFirstEnter(false)
143
+ hasFirstPageAutoRequest && handleFetchMore(true)
144
+ }, [])
145
+
146
+ // 使用 useImperativeHandle 定义向外暴露的方法或属性
147
+ useImperativeHandle(ref, () => ({
148
+ // 这里返回您希望向外暴露的方法或属性
149
+ reload: handleFetchMore,
150
+ showPageRequest: setShowPageRequest
151
+ }));
152
+
153
+ useDidShow(() => {
154
+ showPageRequest && !firstEnter && handleFetchMore(true)
155
+ })
156
+
157
+ /**
158
+ * 请求
159
+ * @param isFirst 是否是第一次调用
160
+ * @param restParams 可以传其余的饿默认参数
161
+ */
162
+ const handleFetchMore = async (isFirst: any = false, restParams = {}) => {
163
+ showLoding && Taro.showLoading({ title: loadingText })
164
+
165
+ let currentPage: number
166
+ if (isFirst) {
167
+ currentPage = 0
168
+ setListInfo({
169
+ ...listInfo,
170
+ loading: true,
171
+ skip: 0,
172
+ list: [],
173
+ total: 0,
174
+ })
175
+ } else {
176
+ currentPage = listInfo.skip
177
+ setListInfo({
178
+ ...listInfo,
179
+ loading: true,
180
+ })
181
+ }
182
+ const dataSource: any = await request(currentPage, pageSize, restParams);
183
+ let cloneDataSource = Utils.cloneDeep(dataSource);
184
+
185
+ showLoding && Taro.hideLoading()
186
+ // 刷新完成后,将刷新状态设置为 false
187
+ setRefreshing(false)
188
+ if (!cloneDataSource) {
189
+ setListInfo({
190
+ ...listInfo,
191
+ loading: false,
192
+ error: true
193
+ })
194
+ } else if (isFirst) {
195
+ setListInfo({
196
+ ...listInfo,
197
+ loading: false,
198
+ error: false,
199
+ list: [...(cloneDataSource?.data || [])],
200
+ skip: listInfo?.skip + pageSize!!,
201
+ total: cloneDataSource?.total || 0
202
+ })
203
+ } else {
204
+ setListInfo({
205
+ ...listInfo,
206
+ loading: false,
207
+ error: false,
208
+ list: [...listInfo.list, ...(cloneDataSource?.data || [])],
209
+ skip: listInfo.skip + pageSize!!,
210
+ total: cloneDataSource?.total || 0
211
+ })
212
+ }
213
+ }
214
+
215
+
216
+ // /**
217
+ // * 下拉刷新
218
+ // */
219
+ // const handleRefresh = () => {
220
+ // // 将刷新状态设置为 true
221
+ // setRefreshing(true)
222
+
223
+ // // 进行刷新操作,例如重新请求数据
224
+ // handleFetchMore(true)
225
+ // };
226
+
227
+ /**
228
+ * 上拉加载
229
+ */
230
+ const handleLoadMore = () => {
231
+ if (
232
+ !listInfo?.loading &&
233
+ !refreshing &&
234
+ listInfo.skip <= listInfo.total
235
+ ) {
236
+ if (firstEnter && !hasFirstPageAutoRequest) return
237
+
238
+ handleFetchMore();
239
+ } else {
240
+ setHasMore(true)
241
+ }
242
+ };
243
+
244
+ const renderFooter = () => {
245
+ const isBottom = listInfo.skip > listInfo.total;
246
+
247
+ let textRender: any = null;
248
+
249
+ if (!listInfo?.loading) {
250
+ if (!listInfo.error && listInfo.total !== 0) {
251
+ textRender = (
252
+ !isBottom ? null : (
253
+ !showBottomText ? null : (
254
+ <Text className='we-list__text'>{bottomText}</Text>
255
+ )
256
+ )
257
+ )
258
+ }
259
+ } else {
260
+ textRender = (
261
+ <>
262
+ {!refreshing && (
263
+ <Loading type='circular'>加载中...</Loading>
264
+ )}
265
+ </>
266
+ );
267
+ }
268
+
269
+ return (
270
+ <View className='we-list__ptpr'>
271
+ {textRender}
272
+ </View>
273
+ )
274
+ }
275
+
276
+ /** 没有数据展示内容 */
277
+ const renderEmpty = (): React.ReactElement | null => {
278
+ if (listInfo?.loading || refreshing || firstEnter) return null
279
+ let textRender: any = null;
280
+
281
+ if (listInfo?.error) {
282
+ textRender = (
283
+ <Text
284
+ onClick={() => { handleFetchMore(true) }}
285
+ className='we-list__bottom_text'
286
+ >
287
+ {errorText}
288
+ </Text>
289
+ )
290
+ } else if (listInfo.total === 0) {
291
+ textRender = !!emptyRender ? emptyRender : (
292
+ <Text className='we-list__bottom-text'>{emptyText}</Text>
293
+ )
294
+ }
295
+ if (!!textRender) {
296
+ return (
297
+ <View className='we-list__bottom'>
298
+ {textRender}
299
+ </View>
300
+ )
301
+ } else {
302
+ return null
303
+ }
304
+ };
305
+
306
+ return (
307
+ <View className='we-list' ref={flatlistRef}>
308
+ <ScrollView
309
+ className='scroll'
310
+ scrollWithAnimation
311
+ enableBackToTop
312
+ lowerThreshold={20}
313
+ onScrollToLower={handleLoadMore}
314
+ scrollY={scrollY}
315
+ // onTouchStart={this.handleTouchStart.bind(this)}
316
+ // onTouchEnd={this.handleTouchEnd.bind(this)}
317
+ // onTouchMove={this.handleTouchMove.bind(this)}
318
+ >
319
+ {props.children}
320
+ {listInfo?.list?.map((it, index) => (renderItem(it, index)))}
321
+ {renderEmpty()}
322
+ {renderFooter()}
323
+ </ScrollView>
324
+ </View>
325
+ )
326
+ })
327
+
328
+ type WrappedPullToPushRefreshProps<T> = {
329
+ actionRef: MutableRefObject<PullToPushRefreshRef>;
330
+ } & PullToPushRefreshProps<T>;
331
+
332
+ const WrappedPullToPushRefresh = <T extends Record<string, any>>(props: WrappedPullToPushRefreshProps<T>) => {
333
+ const { actionRef, ...restPorps } = props;
334
+
335
+ return <PullToPushRefresh ref={actionRef} {...restPorps} />;
336
+ }
337
+
338
+ export default WrappedPullToPushRefresh
@@ -0,0 +1,15 @@
1
+ // 样式基础文件(变量和 mixin)已通过 Taro 配置自动注入,无需手动导入
2
+ .we-radio {
3
+ display: flex;
4
+ justify-content: center;
5
+ align-items: center;
6
+ width: 31px;
7
+ height: 31px;
8
+ border: 2px solid #D7D7D7;
9
+ border-radius: 50%;
10
+ }
11
+
12
+ .we-radio--select {
13
+ border-color: transparent !important;
14
+ background: $primary-color;
15
+ }
@@ -0,0 +1,56 @@
1
+ import { Check } from '@nutui/icons-react-taro';
2
+ import { View } from '@tarojs/components';
3
+ import React, { useMemo } from 'react';
4
+ import classNames from 'classnames';
5
+ import './index.scss';
6
+
7
+ export type RadioProps = {
8
+ /**
9
+ * 是否选中
10
+ * @default false
11
+ */
12
+ visible: boolean
13
+ /**
14
+ * 大小 大小等同于圆圈宽度
15
+ * @default 10
16
+ */
17
+ size?: number
18
+ /**
19
+ * 边框颜色
20
+ * @default '#AAAAAA'
21
+ */
22
+ borderColor?: string
23
+ /**
24
+ * 边框宽度
25
+ * @default 1
26
+ */
27
+ borderWidth?: number
28
+ };
29
+
30
+ const Radio: React.FC<RadioProps> = (props) => {
31
+ const {
32
+ visible = false,
33
+ size = 10,
34
+ borderColor = '#D7D7D7',
35
+ borderWidth = 1,
36
+ } = props
37
+
38
+ const circleStyles = useMemo(() => ({
39
+ width: size * 1.5,
40
+ height: size * 1.5,
41
+ borderWidth,
42
+ borderColor: visible ? '#3b4eae' : borderColor,
43
+ }), [])
44
+
45
+ return (
46
+ <View style={circleStyles}
47
+ className={classNames(
48
+ 'we-radio',
49
+ { 'we-radio--select': visible }
50
+ )}>
51
+ {visible ? (<Check size={size} color='#ffffff' />) : null}
52
+ </View>
53
+ );
54
+ };
55
+
56
+ export default Radio;
@@ -0,0 +1,26 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { View } from '@tarojs/components';
3
+ import classNames from 'classnames'
4
+ /** 和Tabs共用样式 */
5
+ import '../Tabs/index.scss';
6
+
7
+ export type TabPaneProps = {
8
+ /** 标题 */
9
+ title: string
10
+ };
11
+
12
+ const TabPane: React.FC<PropsWithChildren<TabPaneProps>> = (props) => {
13
+ const {
14
+ children
15
+ } = props
16
+
17
+ return (
18
+ <View
19
+ className={classNames('bd-tabs__pane')}
20
+ >
21
+ {children}
22
+ </View>
23
+ );
24
+ };
25
+
26
+ export default TabPane;
@@ -0,0 +1,60 @@
1
+ // 样式基础文件(变量和 mixin)已通过 Taro 配置自动注入,无需手动导入
2
+ $tabs-header-height: 92px;
3
+ $tabs-header-title-color: #333333;
4
+
5
+ .we-tabs {
6
+ &__header {
7
+ padding-inline: 20px;
8
+ box-sizing: border-box;
9
+ height: $tabs-header-height;
10
+ background-color: #ffffff;
11
+ overflow: hidden;
12
+
13
+ &-item {
14
+ position: relative;
15
+ font-size: 28px;
16
+ line-height: $tabs-header-height;
17
+ text-align: center;
18
+
19
+ &__text {
20
+ color: $tabs-header-title-color;
21
+ }
22
+
23
+ &__line {
24
+ position: absolute;
25
+ left: 0;
26
+ right: 0;
27
+ bottom: 0px;
28
+ margin: auto;
29
+ width: 59px;
30
+ height: 14px;
31
+ background: $primary-color;
32
+ border-radius: 7px;
33
+ opacity: 0;
34
+ }
35
+ }
36
+
37
+ &-item--active {
38
+ font-weight: bold;
39
+
40
+ .bd-tabs__header-item__line {
41
+ overflow: hidden;
42
+ opacity: 1;
43
+ }
44
+ }
45
+ }
46
+
47
+ &__list {
48
+ height: 100%;
49
+ display: flex;
50
+ align-items: center;
51
+ }
52
+
53
+ &__header-border {
54
+ border-bottom: 1px solid #F0F0F0;
55
+ }
56
+
57
+ &__body {
58
+ overflow: hidden;
59
+ }
60
+ }
@@ -0,0 +1,107 @@
1
+ import React, { CSSProperties, PropsWithChildren, useMemo } from 'react';
2
+ import { ScrollView, View } from '@tarojs/components';
3
+ import TabPane, { TabPaneProps } from '../TabPane';
4
+ import classNames from 'classnames';
5
+ import './index.scss';
6
+
7
+ export type TabsProps = {
8
+ /**
9
+ * 标签栏样式
10
+ * @default {}
11
+ */
12
+ tabStyle?: CSSProperties
13
+ /**
14
+ * 当前激活 tab 面板的值
15
+ * @default 0
16
+ */
17
+ value: number
18
+ className?: string;
19
+ /** 是否需要滚动 */
20
+ scroll?: boolean
21
+ tabsRender?: (dom: { tabsDom: React.ReactNode }) => React.ReactNode
22
+ // style?: CSSProperties;
23
+ onChange: (value: number) => void
24
+ };
25
+
26
+ interface TabsComponent extends React.FC<PropsWithChildren<TabsProps>> {
27
+ TabPane: React.FC<PropsWithChildren<TabPaneProps>>;
28
+ }
29
+
30
+ const Tabs: TabsComponent = (props) => {
31
+ const {
32
+ value = 0,
33
+ onChange,
34
+ className,
35
+ // style,
36
+ scroll,
37
+ tabStyle = {},
38
+ tabsRender: tabsRenderProps,
39
+ children
40
+ } = props;
41
+
42
+ const titles = useMemo(() => {
43
+ return React.Children.map(children, (child: any) => {
44
+ return child?.props?.title;
45
+ }) || [];
46
+ }, [children])
47
+
48
+ const tabsDom = () => {
49
+ const tabListDom = (
50
+ <>
51
+ {titles?.map((it: string, index: number) => (
52
+ <View
53
+ className={classNames(
54
+ 'we-tabs__header-item',
55
+ { 'we-tabs__header-item--active': value === index }
56
+ )}
57
+ key={index}
58
+ style={{ width: `calc(100vw / ${titles?.length})` }}
59
+ onClick={() => { onChange(index) }}
60
+ >
61
+ <View className='we-tabs__header-item__line' />
62
+ <View className='we-tabs__header-item__text'>{it}</View>
63
+ </View>
64
+ ))}
65
+ </>
66
+ )
67
+ if (scroll) {
68
+ return (
69
+ <ScrollView style={{ whiteSpace: 'nowrap' }} scrollX className='we-tabs__scroll'>
70
+ <View className='we-tabs__list'>
71
+ {tabListDom}
72
+ </View>
73
+ </ScrollView>
74
+ )
75
+ }
76
+ return (
77
+ <View className='we-tabs__list'>
78
+ {tabListDom}
79
+ </View>
80
+ )
81
+ }
82
+
83
+ const tabsRender = () => {
84
+ return tabsRenderProps ? tabsRenderProps({ tabsDom: tabsDom() }) : tabsDom()
85
+ }
86
+
87
+ return (
88
+ <View className={classNames('we-tabs', className)}>
89
+ <View className={classNames('we-tabs__header')} style={tabStyle}>
90
+ {tabsRender()}
91
+ </View>
92
+ <View className='we-card__body'>
93
+ {React.Children.map(children, (child, index) => {
94
+ if (index === value) {
95
+ return child;
96
+ } else {
97
+ return null;
98
+ }
99
+ })}
100
+ </View>
101
+ </View>
102
+ );
103
+ };
104
+
105
+ Tabs.TabPane = TabPane
106
+
107
+ export default Tabs;
@@ -0,0 +1,59 @@
1
+ .uploadImg {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+
5
+ &__item {
6
+ position: relative;
7
+ margin-right: 9px;
8
+ margin-bottom: 10px;
9
+ width: 140px;
10
+ height: 142px;
11
+ border-radius: 10px;
12
+ overflow: hidden;
13
+
14
+ .deleteImg{
15
+ position: absolute;
16
+ top: 0;
17
+ right: 0;
18
+ width: 31px;
19
+ height: 31px;
20
+ // @include bgImg('/aliyunOSSUpload_deleteIcon.png');
21
+ }
22
+
23
+ image {
24
+ width: 100%;
25
+ height: 100%;
26
+ }
27
+ }
28
+
29
+ &__item:nth-child(4n) {
30
+ margin-right: 0;
31
+ }
32
+
33
+ &__add {
34
+ position: relative;
35
+ width: 140px;
36
+ height: 142px;
37
+ background: #f0f0f0;
38
+ border-radius: 10px;
39
+
40
+ .add_icon {
41
+ position: absolute;
42
+ top: 0;
43
+ bottom: 0;
44
+ left: 0;
45
+ right: 0;
46
+ margin: auto;
47
+ width: 30px;
48
+ height: 30px;
49
+ // @include bgImg('/aliyunOSSUpload_addIcon.png')
50
+ }
51
+
52
+ .add_icon:nth-child(2) {
53
+ top: 25%;
54
+ left: 51%;
55
+ width: 2px;
56
+ height: 60px;
57
+ }
58
+ }
59
+ }