@cloudbase/weda-ui 0.2.6 → 0.2.10

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 (158) hide show
  1. package/package.json +3 -4
  2. package/src/configs/components/container.json +2 -1
  3. package/src/configs/components/form/input.json +6 -0
  4. package/src/configs/components/form/richText.json +2 -1
  5. package/src/configs/components/form/uploader.json +4 -5
  6. package/src/configs/components/image.json +2 -1
  7. package/src/configs/components/link.json +2 -1
  8. package/src/configs/components/richtextview.json +2 -1
  9. package/src/configs/components/scrollVeiw.json +2 -1
  10. package/src/configs/components/swiper.json +2 -1
  11. package/src/configs/components/tabs.json +31 -86
  12. package/src/configs/components/text.json +2 -1
  13. package/src/configs/index.js +4 -7
  14. package/src/mp/components/form/input/index.js +5 -1
  15. package/src/mp/components/form/input/index.wxml +2 -1
  16. package/src/mp/components/form/select/index.js +2 -2
  17. package/src/mp/components/form/textarea/index.wxml +1 -0
  18. package/src/mp/components/form/uploader/index.js +48 -14
  19. package/src/mp/components/form/uploader/index.wxml +9 -2
  20. package/src/mp/components/image/index.js +57 -8
  21. package/src/mp/components/image/index.json +4 -1
  22. package/src/mp/components/image/index.wxml +4 -2
  23. package/src/mp/components/image/index.wxss +14 -0
  24. package/src/mp/components/richText/index.wxml +1 -1
  25. package/src/mp/components/tabs/index.js +14 -1
  26. package/src/mp/utils/deepEqual.js +42 -0
  27. package/src/web/components/form/enumSelect/MultipleSelect.jsx +94 -0
  28. package/src/web/components/form/enumSelect/NormalSelect.jsx +105 -0
  29. package/src/web/components/form/enumSelect/SelectContainer.jsx +43 -0
  30. package/src/web/components/form/enumSelect/hooks/index.js +49 -0
  31. package/src/web/components/form/enumSelect/index.jsx +9 -0
  32. package/src/web/components/form/enumSelect/props/defaultProps.js +39 -0
  33. package/src/web/components/form/enumSelect/props/propsTypes.js +50 -0
  34. package/src/web/components/form/input/index.jsx +14 -10
  35. package/src/web/components/form/radio/index.jsx +1 -1
  36. package/src/web/components/form/select/h5.jsx +1 -1
  37. package/src/web/components/form/select/region/{cities.json → cities.js} +2 -2
  38. package/src/web/components/form/select/region/index.js +3 -3
  39. package/src/web/components/form/select/region/{provinces.json → provinces.js} +2 -2
  40. package/src/web/components/form/select/region/{regions.json → regions.js} +2 -2
  41. package/src/web/components/form/switch/index.jsx +1 -0
  42. package/src/web/components/form/uploader/index.css +15 -0
  43. package/src/web/components/form/uploader/index.jsx +2 -2
  44. package/src/web/components/form/uploader/uploader.h5.jsx +237 -0
  45. package/src/web/components/form/uploader/{uploaderPc.jsx → uploader.pc.jsx} +69 -59
  46. package/src/web/components/image/image.jsx +79 -5
  47. package/src/web/components/image/index.css +17 -0
  48. package/src/web/components/image/index.jsx +1 -0
  49. package/src/web/components/index.js +1 -1
  50. package/src/web/components/link/test/__snapshots__/storybook.test.js.snap +754 -0
  51. package/src/web/components/modal/index.jsx +3 -2
  52. package/src/web/components/richTextView/index.css +0 -10
  53. package/src/web/components/richTextView/index.jsx +1 -12
  54. package/src/web/components/tabs/index.jsx +3 -3
  55. package/src/web/components/tabs/{tabsH5.jsx → tabs.h5.jsx} +9 -47
  56. package/src/web/components/tabs/{tabsPc.jsx → tabs.pc.jsx} +13 -47
  57. package/src/web/components/uploaderView/index.jsx +1 -1
  58. package/src/web/utils/tcb.js +8 -0
  59. package/CHANGELOG.md +0 -240
  60. package/src/.DS_Store +0 -0
  61. package/src/configs/components/markdown.json +0 -17
  62. package/src/mp/.gitignore +0 -10
  63. package/src/mp/components/markdown/index.js +0 -27
  64. package/src/mp/components/markdown/index.json +0 -6
  65. package/src/mp/components/markdown/index.wxml +0 -1
  66. package/src/mp/components/markdown/towxml/audio-player/Audio.js +0 -99
  67. package/src/mp/components/markdown/towxml/audio-player/audio-player.js +0 -102
  68. package/src/mp/components/markdown/towxml/audio-player/audio-player.json +0 -5
  69. package/src/mp/components/markdown/towxml/audio-player/audio-player.wxml +0 -14
  70. package/src/mp/components/markdown/towxml/audio-player/audio-player.wxss +0 -175
  71. package/src/mp/components/markdown/towxml/audio-player/loading.svg +0 -1
  72. package/src/mp/components/markdown/towxml/config.js +0 -285
  73. package/src/mp/components/markdown/towxml/decode.js +0 -26
  74. package/src/mp/components/markdown/towxml/decode.json +0 -12
  75. package/src/mp/components/markdown/towxml/decode.wxml +0 -1
  76. package/src/mp/components/markdown/towxml/decode.wxss +0 -0
  77. package/src/mp/components/markdown/towxml/img/img.js +0 -98
  78. package/src/mp/components/markdown/towxml/img/img.json +0 -3
  79. package/src/mp/components/markdown/towxml/img/img.wxml +0 -1
  80. package/src/mp/components/markdown/towxml/img/img.wxss +0 -0
  81. package/src/mp/components/markdown/towxml/index.js +0 -19
  82. package/src/mp/components/markdown/towxml/latex/latex.js +0 -53
  83. package/src/mp/components/markdown/towxml/latex/latex.json +0 -5
  84. package/src/mp/components/markdown/towxml/latex/latex.wxml +0 -1
  85. package/src/mp/components/markdown/towxml/latex/latex.wxss +0 -0
  86. package/src/mp/components/markdown/towxml/parse/highlight/highlight.js +0 -729
  87. package/src/mp/components/markdown/towxml/parse/highlight/index.js +0 -7
  88. package/src/mp/components/markdown/towxml/parse/highlight/languages/bash.js +0 -91
  89. package/src/mp/components/markdown/towxml/parse/highlight/languages/c-like.js +0 -244
  90. package/src/mp/components/markdown/towxml/parse/highlight/languages/c.js +0 -20
  91. package/src/mp/components/markdown/towxml/parse/highlight/languages/css.js +0 -138
  92. package/src/mp/components/markdown/towxml/parse/highlight/languages/dart.js +0 -135
  93. package/src/mp/components/markdown/towxml/parse/highlight/languages/go.js +0 -57
  94. package/src/mp/components/markdown/towxml/parse/highlight/languages/htmlbars.js +0 -79
  95. package/src/mp/components/markdown/towxml/parse/highlight/languages/java.js +0 -126
  96. package/src/mp/components/markdown/towxml/parse/highlight/languages/javascript.js +0 -263
  97. package/src/mp/components/markdown/towxml/parse/highlight/languages/json.js +0 -51
  98. package/src/mp/components/markdown/towxml/parse/highlight/languages/less.js +0 -177
  99. package/src/mp/components/markdown/towxml/parse/highlight/languages/nginx.js +0 -103
  100. package/src/mp/components/markdown/towxml/parse/highlight/languages/php.js +0 -152
  101. package/src/mp/components/markdown/towxml/parse/highlight/languages/python-repl.js +0 -27
  102. package/src/mp/components/markdown/towxml/parse/highlight/languages/python.js +0 -146
  103. package/src/mp/components/markdown/towxml/parse/highlight/languages/scss.js +0 -137
  104. package/src/mp/components/markdown/towxml/parse/highlight/languages/shell.js +0 -23
  105. package/src/mp/components/markdown/towxml/parse/highlight/languages/typescript.js +0 -198
  106. package/src/mp/components/markdown/towxml/parse/highlight/languages/xml.js +0 -143
  107. package/src/mp/components/markdown/towxml/parse/highlight/style/github.wxss +0 -99
  108. package/src/mp/components/markdown/towxml/parse/highlight/style/monokai.wxss +0 -70
  109. package/src/mp/components/markdown/towxml/parse/index.js +0 -106
  110. package/src/mp/components/markdown/towxml/parse/markdown/index.js +0 -53
  111. package/src/mp/components/markdown/towxml/parse/markdown/markdown.js +0 -5834
  112. package/src/mp/components/markdown/towxml/parse/markdown/plugins/emoji.js +0 -1773
  113. package/src/mp/components/markdown/towxml/parse/markdown/plugins/ins.js +0 -120
  114. package/src/mp/components/markdown/towxml/parse/markdown/plugins/latex.js +0 -193
  115. package/src/mp/components/markdown/towxml/parse/markdown/plugins/mark.js +0 -120
  116. package/src/mp/components/markdown/towxml/parse/markdown/plugins/sub.js +0 -95
  117. package/src/mp/components/markdown/towxml/parse/markdown/plugins/sup.js +0 -95
  118. package/src/mp/components/markdown/towxml/parse/markdown/plugins/todo.js +0 -220
  119. package/src/mp/components/markdown/towxml/parse/markdown/plugins/yuml.js +0 -18
  120. package/src/mp/components/markdown/towxml/parse/parse2/Parser.js +0 -263
  121. package/src/mp/components/markdown/towxml/parse/parse2/Tokenizer.js +0 -507
  122. package/src/mp/components/markdown/towxml/parse/parse2/domhandler/index.js +0 -104
  123. package/src/mp/components/markdown/towxml/parse/parse2/domhandler/node.js +0 -169
  124. package/src/mp/components/markdown/towxml/parse/parse2/entities/decode.js +0 -54
  125. package/src/mp/components/markdown/towxml/parse/parse2/entities/decode_codepoint.js +0 -19
  126. package/src/mp/components/markdown/towxml/parse/parse2/entities/encode.js +0 -54
  127. package/src/mp/components/markdown/towxml/parse/parse2/entities/index.js +0 -30
  128. package/src/mp/components/markdown/towxml/parse/parse2/entities/maps/decode.js +0 -31
  129. package/src/mp/components/markdown/towxml/parse/parse2/entities/maps/entities.js +0 -2128
  130. package/src/mp/components/markdown/towxml/parse/parse2/entities/maps/legacy.js +0 -109
  131. package/src/mp/components/markdown/towxml/parse/parse2/entities/maps/xml.js +0 -2
  132. package/src/mp/components/markdown/towxml/parse/parse2/index.js +0 -8
  133. package/src/mp/components/markdown/towxml/style/main.wxss +0 -378
  134. package/src/mp/components/markdown/towxml/style/theme/dark.wxss +0 -73
  135. package/src/mp/components/markdown/towxml/style/theme/light.wxss +0 -63
  136. package/src/mp/components/markdown/towxml/table/table.js +0 -11
  137. package/src/mp/components/markdown/towxml/table/table.json +0 -6
  138. package/src/mp/components/markdown/towxml/table/table.wxml +0 -24
  139. package/src/mp/components/markdown/towxml/table/table.wxss +0 -0
  140. package/src/mp/components/markdown/towxml/todogroup/todogroup.js +0 -19
  141. package/src/mp/components/markdown/towxml/todogroup/todogroup.json +0 -6
  142. package/src/mp/components/markdown/towxml/todogroup/todogroup.wxml +0 -13
  143. package/src/mp/components/markdown/towxml/todogroup/todogroup.wxss +0 -3
  144. package/src/mp/components/markdown/towxml/towxml.js +0 -17
  145. package/src/mp/components/markdown/towxml/towxml.json +0 -6
  146. package/src/mp/components/markdown/towxml/towxml.wxml +0 -5
  147. package/src/mp/components/markdown/towxml/towxml.wxss +0 -8
  148. package/src/mp/components/markdown/towxml/yuml/yuml.js +0 -51
  149. package/src/mp/components/markdown/towxml/yuml/yuml.json +0 -5
  150. package/src/mp/components/markdown/towxml/yuml/yuml.wxml +0 -5
  151. package/src/mp/components/markdown/towxml/yuml/yuml.wxss +0 -0
  152. package/src/web/.DS_Store +0 -0
  153. package/src/web/components/form/uploader/uploaderH5.jsx +0 -208
  154. package/src/web/components/markdown/index.jsx +0 -40
  155. package/src/web/wedatheme/.git +0 -1
  156. package/src/web/wedatheme/.gitignore +0 -5
  157. package/src/web/wedatheme/.npmrc +0 -1
  158. package/src/web/wedatheme/package-lock.json +0 -14335
@@ -0,0 +1,237 @@
1
+ import * as PropTypes from 'prop-types';
2
+ import * as React from 'react';
3
+ import weui from '../../../utils/weui';
4
+ import classNames from '../../../utils/classnames';
5
+ import { getCloudInstance, getTempFileURL } from '../../../utils/tcb';
6
+ import isObjectEqual from '../../../utils/isObjectEqual';
7
+ import { useSyncValue } from '../../../utils/useSyncValue';
8
+ import { isCloudFileID } from '../../../utils/platform';
9
+ import { IMAGE_TYPES } from './uploader.pc';
10
+
11
+ const uploadPath = 'weda-uploader';
12
+ /**
13
+ * H5端
14
+ */
15
+ export function ImageUploaderH5({
16
+ title,
17
+ maxUploadCount,
18
+ maxSize = 10,
19
+ acceptTypes,
20
+ className,
21
+ id,
22
+ events,
23
+ layout,
24
+ defaultValue,
25
+ single = false,
26
+ onChange,
27
+ style,
28
+ }) {
29
+ const cls = classNames({
30
+ 'weda-ui': true,
31
+ 'weui-cells': true,
32
+ 'weui-cells_form': true,
33
+ [className]: className,
34
+ });
35
+
36
+ // 上传中
37
+ const [uploading, setUploading] = React.useState(false);
38
+ //上传进度
39
+ const [progress, setProgress] = React.useState(0);
40
+ const [inputValue, setInputValue] = useSyncValue(defaultValue, isObjectEqual);
41
+ const fileIdList = React.useMemo(() => {
42
+ if( typeof inputValue === 'string') {
43
+ // single = true 传入的是字符串
44
+ return [inputValue].filter(i => i.length > 0); // 排除空串
45
+ }
46
+ if(Array.isArray(inputValue)) {
47
+ return inputValue;
48
+ }
49
+ return [];
50
+ }, [inputValue]);
51
+
52
+ const finalMaxImgCount = React.useMemo(() => {
53
+ if(single) return 1;
54
+ return maxUploadCount;
55
+ }, [single, maxUploadCount]);
56
+
57
+ const deleteFile = (url) => {
58
+ if(single) {
59
+ setInputValue('');
60
+ return;
61
+ }
62
+ setInputValue((list) => list.filter(f => f !== url));
63
+ };
64
+ React.useEffect(() => {
65
+ if (single) {
66
+ const file = fileIdList[0] || '';
67
+ file && onChange && onChange(file);
68
+ events.change && events.change({ value: file });
69
+ } else {
70
+ onChange && onChange(fileIdList);
71
+ events.change && events.change({ value: fileIdList });
72
+ }
73
+ }, [fileIdList]);
74
+ const onProgress = (progressEvent) => {
75
+ let percentCompleted = 0;
76
+ try {
77
+ percentCompleted = Math.round(
78
+ (progressEvent.loaded * 100) / progressEvent.total
79
+ );
80
+ percentCompleted < 100 ? percentCompleted : 100;
81
+ } catch (e) {}
82
+ setProgress(percentCompleted);
83
+ };
84
+ const uploadToTcb = (file) => {
85
+ setUploading(true);
86
+ getCloudInstance().then(async (tcb) => {
87
+ try {
88
+ const fileType = file.type.split('/')?.[1];
89
+ const cloudPath = `${uploadPath}/uploader-${Date.now()}.${fileType}`;
90
+ const { fileID } = await tcb.uploadFile({
91
+ cloudPath,
92
+ filePath: file,
93
+ onUploadProgress: onProgress,
94
+
95
+ });
96
+ fileID && setInputValue((list) => [...list, fileID]);
97
+ fileID && events.success && events.success({ value: fileID, file });
98
+ } catch (err) {
99
+ events.error && events.error(err);
100
+ } finally {
101
+ setUploading(false);
102
+ setProgress(0);
103
+ }
104
+ });
105
+ };
106
+
107
+ const accepts = React.useMemo(() => {
108
+ return acceptTypes.includes('image/*') || acceptTypes.length === 0
109
+ ? IMAGE_TYPES
110
+ : Array.from(new Set(acceptTypes));
111
+ }, [acceptTypes]);
112
+
113
+ return (
114
+ <div className={cls} id={id} style={style}>
115
+ <div className="weui-cell">
116
+ <div className="weui-cell__bd">
117
+ <div className={classNames("weui-uploader", layout)}>
118
+ <div className={classNames("weui-uploader__hd", layout)}>
119
+ <p className="weui-uploader__title">{title}</p>
120
+ <div className="weui-uploader__info">
121
+ <span id="uploadCount">{fileIdList.length}</span>
122
+ {`/${finalMaxImgCount}`}
123
+ </div>
124
+ </div>
125
+ <div className="weui-uploader__bd">
126
+ <ul className="weui-uploader__files" id="uploaderFiles">
127
+ {(fileIdList ?? []).map(f => <SingleImage key={f} src={f} deleteBySrc={deleteFile} />)}
128
+ {uploading &&
129
+ <li className="weui-uploader__file weui-uploader__file_status" >
130
+ <div className="weui-uploader__file-content">
131
+ {progress}%
132
+ </div>
133
+ </li>}
134
+ </ul>
135
+ {(fileIdList.length < maxUploadCount ||
136
+ (single && fileIdList.length < 1)) && ( // single 模式时,仅当数组为空时显示
137
+ <div className="weui-uploader__input-box">
138
+ <input
139
+ id="uploaderInput"
140
+ className="weui-uploader__input"
141
+ type="file"
142
+ accept={accepts.join(',')}
143
+ multiple
144
+ onChange={e => {
145
+ const files = [...e.target.files];
146
+ if (files.some(f => f.size > maxSize * 1024 * 1024)) {
147
+ weui.alert('请上传不超过10M的图片');
148
+ return false;
149
+ }
150
+
151
+ if (files.length > finalMaxImgCount) {
152
+ // 防止一下子选择过多文件
153
+ weui.alert(`最多只能上传${finalMaxImgCount}张图片,请重新选择`);
154
+ return false;
155
+ }
156
+ if (fileIdList.length + files.length > finalMaxImgCount) {
157
+ weui.alert(`最多只能上传${finalMaxImgCount}张图片`);
158
+ return false;
159
+ }
160
+ files.forEach(f => uploadToTcb(f));
161
+ }}
162
+ />
163
+ </div>
164
+ )}
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ );
171
+ }
172
+
173
+ function SingleImage({src, deleteBySrc}) {
174
+ const [error, setError] = React.useState(false);
175
+ const cls = classNames({
176
+ 'weui-uploader__file': true,
177
+ });
178
+ const [realSrc, setRealSrc] = React.useState('');
179
+ React.useEffect(() => {
180
+ const getSrc = async () => {
181
+ try {
182
+ const _src = await getTempFileURL(src);
183
+ setRealSrc(_src);
184
+ return _src;
185
+ } catch (e) {
186
+ setError(true);
187
+ console.error('图片加载失败');
188
+ }
189
+ };
190
+ if(isCloudFileID(src)) {
191
+ getSrc();
192
+ } else {
193
+ setRealSrc(src);
194
+ }
195
+ }, [src]);
196
+ const imgStyle = {
197
+ backgroundImage: `url(${realSrc})`
198
+ };
199
+ const showGallery = () => {
200
+ const gallery = weui.gallery(realSrc, {
201
+ onDelete: function() {
202
+ deleteBySrc(src);
203
+ gallery.hide();
204
+ }
205
+ });
206
+ };
207
+
208
+ return (
209
+ <li className={cls} style={imgStyle} onClick={showGallery}>
210
+ {
211
+ error || status ?
212
+ <div className="weui-uploader__file-content">
213
+ { error ? <i role="img" aria-label="错误" className="weui-icon-warn"></i> : <i className="weui-loading" style={{width: 30, height: 30}}></i> }
214
+ </div>
215
+ : false
216
+ }
217
+ </li>
218
+ );
219
+ }
220
+ SingleImage.propTypes = {
221
+ src: PropTypes.string,
222
+ deleteBySrc: PropTypes.func
223
+ };
224
+ ImageUploaderH5.propTypes = {
225
+ id: PropTypes.string,
226
+ title: PropTypes.string,
227
+ className: PropTypes.string, // 传入类
228
+ maxSize: PropTypes.number,
229
+ acceptTypes: PropTypes.array,
230
+ maxUploadCount: PropTypes.number, // 【上传图片最大数量】
231
+ events: PropTypes.objectOf(PropTypes.func), // 事件
232
+ style: PropTypes.object,
233
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
234
+ defaultValue: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), // 初始值,该参数需配合 formily 使用
235
+ single: PropTypes.bool, // 单张上传还是多张上传,对应 onChange 参数为字符串还是字符串数组,value 在处理过程统一转为字符串数组
236
+ onChange: PropTypes.objectOf(PropTypes.func), // 值变化,该参数需配合 formily 使用
237
+ };
@@ -18,7 +18,7 @@ import * as PropTypes from 'prop-types';
18
18
  // 默认组件类前缀
19
19
  export const CLASS_PREFIX = 'weda-uploader-pc';
20
20
  // 默认图片类型
21
- const IMAGE_TYPES = [
21
+ export const IMAGE_TYPES = [
22
22
  'image/jpg',
23
23
  'image/png',
24
24
  'image/tif',
@@ -31,7 +31,15 @@ const IMAGE_TYPES = [
31
31
  * 上传图片-官方组件
32
32
  */
33
33
  // eslint-disable-next-line react/prop-types
34
- export function UploaderPC({layout, className, id, style,title,tips, ...props }) {
34
+ export function UploaderPC({
35
+ layout,
36
+ className,
37
+ id,
38
+ style,
39
+ title,
40
+ tips,
41
+ ...props
42
+ }) {
35
43
  const cls = classNames({
36
44
  'weda-ui': true,
37
45
  [CLASS_PREFIX]: true,
@@ -40,25 +48,24 @@ export function UploaderPC({layout, className, id, style,title,tips, ...props })
40
48
  });
41
49
  return (
42
50
  <div className={cls} id={id} style={style}>
43
- <div className={`${CLASS_PREFIX}__header`}>
44
- {title && <div className={`${CLASS_PREFIX}__title`}>{title}</div>}
45
- {tips && (
46
- <div className={`${CLASS_PREFIX}__description`}>{tips || ''}</div>
47
- )}
48
- </div>
49
- <UploaderPCInner {...props} />
51
+ <div className={`${CLASS_PREFIX}__header`}>
52
+ {title && <div className={`${CLASS_PREFIX}__title`}>{title}</div>}
53
+ {tips && (
54
+ <div className={`${CLASS_PREFIX}__description`}>{tips || ''}</div>
55
+ )}
56
+ </div>
57
+ <UploaderPCInner {...props} />
50
58
  </div>
51
- );
59
+ );
52
60
  }
53
61
 
54
-
55
62
  export function UploaderPCInner(props) {
56
63
  let {
57
64
  tips = '',
58
65
  btnTitle = '上传图片',
59
66
  maxUploadCount = 9,
60
67
  maxSize = 10,
61
- defaultValue, // 需要兼容 cloud:和https: 协议,需要兼容 字符串和字符串数组
68
+ value: defaultValue, // 需要兼容 cloud:和https: 协议,需要兼容 字符串和字符串数组
62
69
  acceptTypes = IMAGE_TYPES,
63
70
  uploadPath = 'weda-uploader',
64
71
  uploadFileName = 'image',
@@ -67,8 +74,6 @@ export function UploaderPCInner(props) {
67
74
  onChange,
68
75
  } = props;
69
76
 
70
-
71
-
72
77
  // 上传中
73
78
  const [uploading, setUploading] = React.useState(false);
74
79
  //上传进度
@@ -77,13 +82,11 @@ export function UploaderPCInner(props) {
77
82
  const [fileIDList, setfileIDList] = React.useState([]);
78
83
  const prevValueRef = React.useRef();
79
84
  React.useEffect(() => {
80
- if(prevValueRef.current !== defaultValue) {
81
-
85
+ if (prevValueRef.current !== defaultValue) {
82
86
  let initialValue = []
83
- .concat(defaultValue)
84
- .filter((d) => typeof d === 'string' && d !== '');
87
+ .concat(defaultValue)
88
+ .filter((d) => typeof d === 'string' && d !== '');
85
89
  if (single) {
86
- maxUploadCount = 1;
87
90
  initialValue = initialValue[0] ? [initialValue[0]] : [];
88
91
  }
89
92
  setfileIDList(initialValue);
@@ -164,7 +167,7 @@ export function UploaderPCInner(props) {
164
167
  const deleteHandle = (fileID) => {
165
168
  setfileIDList((list) => list.filter((d) => d !== fileID));
166
169
  };
167
-
170
+
168
171
  // 转换后的属性
169
172
  const extraProps = {};
170
173
  extraProps['accept'] =
@@ -176,45 +179,52 @@ export function UploaderPCInner(props) {
176
179
 
177
180
  return (
178
181
  <ConfigProvider classPrefix="wedatea2td">
179
- <div className="_weda-fn-upload-result">
180
- {fileIDList.map((d) => (
181
- <div className="_weda-fn-upload-result__item" key={d}>
182
- <TcbImage fileID={d} />
183
- <div className="_weda-fn-upload-result__op">
184
- <Button
185
- onClick={() => deleteHandle(d)}
186
- className={`${CLASS_PREFIX}__btn`}
187
- >
188
- 删除
189
- </Button>
190
- </div>
182
+ <div className="_weda-fn-upload-result">
183
+ {fileIDList.map((d) => (
184
+ <div className="_weda-fn-upload-result__item" key={d}>
185
+ <TcbImage fileID={d} />
186
+ <div className="_weda-fn-upload-result__op">
187
+ <Button
188
+ onClick={() => deleteHandle(d)}
189
+ className={`${CLASS_PREFIX}__btn`}
190
+ >
191
+ 删除
192
+ </Button>
191
193
  </div>
192
- ))}
193
- {uploading && (
194
- <div className="_weda-fn-upload-result__item">
195
- <div className="_weda-fn-upload-result__status" key="_place_image">
196
- <Icon type="loading" />
197
- {!!progress && <span className="wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset">上传{progress}%...</span>}
198
- </div>
194
+ </div>
195
+ ))}
196
+ {uploading && (
197
+ <div className="_weda-fn-upload-result__item">
198
+ <div className="_weda-fn-upload-result__status" key="_place_image">
199
+ <Icon type="loading" />
200
+ {!!progress && (
201
+ <span className="wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset">
202
+ 上传{progress}%...
203
+ </span>
204
+ )}
199
205
  </div>
200
- )}
201
- <div className={`${CLASS_PREFIX}__input-box`}>
202
- {(
203
- (fileIDList.length < maxUploadCount) ||
204
- (single && fileIDList.length < 1) // single 模式时,仅当数组为空时显示
205
- ) &&
206
- <Upload {...extraProps} beforeUpload={beforeHandle}>
206
+ </div>
207
+ )}
208
+ <div className={`${CLASS_PREFIX}__input-box`}>
209
+ {(fileIDList.length < maxUploadCount ||
210
+ (single && fileIDList.length < 1)) && ( // single 模式时,仅当数组为空时显示
211
+ <Upload {...extraProps} beforeUpload={beforeHandle}>
207
212
  <li className="_weda-fn-upload-result__item _weda-fn-upload-result__item--upload">
208
- <div className="_weda-fn-upload-result__status">
209
- <i className="wedatea2td-icon wedatea2td-icon-plus" role="img" aria-label="plus"></i>
210
- <span className="wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset">{btnTitle}</span>
211
- </div>
212
- </li>
213
- </Upload>
214
- }
215
- </div>
213
+ <div className="_weda-fn-upload-result__status">
214
+ <i
215
+ className="wedatea2td-icon wedatea2td-icon-plus"
216
+ role="img"
217
+ aria-label="plus"
218
+ ></i>
219
+ <span className="wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset">
220
+ {btnTitle}
221
+ </span>
222
+ </div>
223
+ </li>
224
+ </Upload>
225
+ )}
216
226
  </div>
217
-
227
+ </div>
218
228
  </ConfigProvider>
219
229
  );
220
230
  }
@@ -232,7 +242,7 @@ export const TcbImage = (props) => {
232
242
  const _src = await getTempFileURL(fileID);
233
243
  _src ? setSrc(_src) : setIsError(true);
234
244
  } catch (e) {
235
- message.error('图片加载失败');
245
+ message.error({ content: '图片加载失败' });
236
246
  }
237
247
  };
238
248
  isCloudFileID(fileID) ? getSrc() : setSrc(fileID);
@@ -281,16 +291,16 @@ UploaderPCInner.propTypes = {
281
291
  uploadFileName: PropTypes.string, // 上传文件名称
282
292
  single: PropTypes.bool, // 单张上传还是多张上传,对应 onChange 参数为字符串还是字符串数组,value 在处理过程统一转为字符串数组
283
293
  events: PropTypes.objectOf(PropTypes.func), // 事件
284
- defaultValue: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), // 初始值,该参数需配合 formily 使用
294
+ value: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), // 初始值,该参数需配合 formily 使用
285
295
  onChange: PropTypes.objectOf(PropTypes.func), // 值变化,该参数需配合 formily 使用
286
296
  style: PropTypes.object,
287
297
  id: PropTypes.string,
288
298
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
289
- disabled: PropTypes.bool
299
+ disabled: PropTypes.bool,
290
300
  };
291
301
 
292
302
  TcbImage.propTypes = {
293
303
  fileID: PropTypes.string, // 云存储id
294
304
  isZoom: PropTypes.bool, // 是否点击放大
295
305
  onError: PropTypes.func, // 图片显示错误事件
296
- };
306
+ };
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import * as PropTypes from 'prop-types';
3
- import { usePlatform } from '../../utils/platform';
4
3
  import { ConfigProvider, ImagePreview } from 'tea-component';
4
+ import { usePlatform } from '../../utils/platform';
5
+ import { useGesture } from '@use-gesture/react';
5
6
 
6
7
  ImageInner.propTypes = {
7
8
  objectFit: PropTypes.string,
@@ -11,17 +12,21 @@ ImageInner.propTypes = {
11
12
  src: PropTypes.string,
12
13
  alt: PropTypes.string,
13
14
  lazyLoad: PropTypes.bool,
15
+ isError: PropTypes.bool,
14
16
  setIsError: PropTypes.func,
15
17
  maskClosable: PropTypes.bool,
16
18
  imgPreview: PropTypes.bool
17
19
  };
18
20
 
21
+ const failImgBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSJub25lIj4KICA8cGF0aCBkPSJNMjUuMzIgMTYuMzU5N0MyNi4wNzY0IDE2LjM1OTcgMjYuODI1NCAxNi41MDg3IDI3LjUyNDMgMTYuNzk4MUMyOC4yMjMxIDE3LjA4NzYgMjguODU4MSAxNy41MTE5IDI5LjM5MjkgMTguMDQ2OEMyOS45Mjc4IDE4LjU4MTYgMzAuMzUyMSAxOS4yMTY2IDMwLjY0MTYgMTkuOTE1NEMzMC45MzEgMjAuNjE0MyAzMS4wOCAyMS4zNjMzIDMxLjA4IDIyLjExOTdDMzEuMDggMjIuODc2MSAzMC45MzEgMjMuNjI1MSAzMC42NDE2IDI0LjMyMzlDMzAuMzUyMSAyNS4wMjI4IDI5LjkyNzggMjUuNjU3OCAyOS4zOTI5IDI2LjE5MjZDMjguODU4MSAyNi43Mjc1IDI4LjIyMzEgMjcuMTUxOCAyNy41MjQzIDI3LjQ0MTJDMjYuODI1NCAyNy43MzA3IDI2LjA3NjQgMjcuODc5NyAyNS4zMiAyNy44Nzk3QzIzLjc5MjQgMjcuODc5NyAyMi4zMjczIDI3LjI3MjggMjEuMjQ3MSAyNi4xOTI2QzIwLjE2NjkgMjUuMTEyNCAxOS41NiAyMy42NDczIDE5LjU2IDIyLjExOTdDMTkuNTYgMjAuNTkyIDIwLjE2NjkgMTkuMTI3IDIxLjI0NzEgMTguMDQ2OEMyMi4zMjczIDE2Ljk2NjUgMjMuNzkyNCAxNi4zNTk3IDI1LjMyIDE2LjM1OTdaTTI4IDMuNTU5NjlWMTQuODc2OEMyNy4xNzc3IDE0LjU4NjYgMjYuMTkyIDE0LjQzODggMjUuMzIgMTQuNDM5N0MyNC4wMzEgMTQuNDM5NyAyMi44MTU3IDE0Ljc1NzEgMjEuNzQ4OCAxNS4zMTg0TDIwLjc5NTIgMTMuMTU5N0wxNi4wMjU5IDIwLjAyNzVMOC40NDU3NiAxNi40NDFMMy41NiAyMy4zOTk3SDE3Ljc0NjJDMTcuOTg2NyAyNC44MjkgMTguNjI4MiAyNi4xNjA2IDE5LjU5NTggMjcuMjM5N0gxVjMuNTU5NjlIMjhaTTI1Ljk2IDI0LjAzOTdIMjQuNjhWMjUuMzE5N0gyNS45NlYyNC4wMzk3Wk0yNS45NiAxOC45MTk3SDI0LjY4VjIzLjM5OTdIMjUuOTZWMTguOTE5N1pNNi4xMiAxMC41OTk3QzYuMTIgMTEuOTk4MSA3LjE5OTA0IDEzLjEwODUgOC42MDc2OCAxMy4xNTg0QzEwLjAyMDggMTMuMjA3NyAxMS4yNCAxMi4wNDggMTEuMjQgMTAuNTk5N0MxMS4yNCA5LjI0NjA5IDEwLjA2NDMgOC4wODU3NyA4Ljc1MjMyIDguMDQwOTdDNy4yOTU2OCA3Ljk5MTY5IDYuMTIgOS4xNTEzNyA2LjEyIDEwLjU5OTdaIiBmaWxsPSIjQkNDNEQwIj48L3BhdGg+Cjwvc3ZnPgo=';
22
+
19
23
  export function ImageInner({
20
24
  objectFit,
21
25
  style,
22
26
  className,
23
27
  alt,
24
28
  src,
29
+ isError,
25
30
  setIsError,
26
31
  events,
27
32
  lazyLoad,
@@ -35,7 +40,55 @@ export function ImageInner({
35
40
  setImgShow(false);
36
41
  }
37
42
  };
38
- if(platform === 'h5' || !imgPreview) {
43
+
44
+ const [showHeight, setShowHeight] = React.useState(0);
45
+ const realWidth = React.useRef(0);
46
+ const realHeight = React.useRef(0);
47
+ const [offsetHeight, setOffsetHeight] = React.useState(0);
48
+ const [translateX, setTranslateX]= React.useState(0);
49
+ const [translateY, setTranslateY]= React.useState(0);
50
+ const [previewScale, setPreviewScale] = React.useState(1);
51
+ React.useEffect(() => {
52
+ // 防止触发浏览器的放大缩小
53
+ const handler = e => e.preventDefault();
54
+ document.addEventListener('gesturestart', handler);
55
+ document.addEventListener('gesturechange', handler);
56
+ return () => {
57
+ document.removeEventListener('gesturestart', handler);
58
+ document.removeEventListener('gesturechange', handler);
59
+ };
60
+ }, []);
61
+
62
+ const bind = useGesture({
63
+ onClick: ({event}) => {
64
+ // 防止冒泡出发关闭预览
65
+ event.stopPropagation();
66
+ },
67
+ onPinch: ({offset}) => {
68
+ const [s] = offset;
69
+ setPreviewScale(s);
70
+ },
71
+ onDrag: ({offset, event}) => {
72
+ event.stopPropagation();
73
+ const [x, y] = offset;
74
+ setTranslateX(x);
75
+ setTranslateY(y);
76
+
77
+ },
78
+ }, {
79
+ drag: {
80
+ delay: true,
81
+ preventDefault: true,
82
+ },
83
+ pinch: {
84
+ scaleBounds: {min: 0.6, max: 5},
85
+ pointer: {
86
+ touch: true
87
+ }
88
+ }
89
+ });
90
+
91
+ if(platform === 'h5' || !imgPreview || isError) {
39
92
  return (
40
93
  <>
41
94
  <img
@@ -47,6 +100,11 @@ export function ImageInner({
47
100
  alt={alt}
48
101
  src={src}
49
102
  onLoad={(e) => {
103
+ /* @type {HTMLImageElement} */
104
+ const img = e.target;
105
+ const {naturalHeight, naturalWidth} = img;
106
+ realHeight.current = naturalHeight;
107
+ realWidth.current = naturalWidth;
50
108
  setIsError(false);
51
109
  events.load && events.load({}, { originEvent: e });
52
110
  }}
@@ -56,7 +114,16 @@ export function ImageInner({
56
114
  }}
57
115
  onClick={
58
116
  () => {
59
- if(imgPreview) {
117
+ if(imgPreview && !isError) {
118
+ setTranslateX(0);
119
+ setTranslateY(0);
120
+ setPreviewScale(1);
121
+ const windowHeight = window.innerHeight;
122
+ const windowWidth = window.innerWidth;
123
+ const ratio = (realWidth.current / realHeight.current);
124
+ const height = windowWidth / ratio;
125
+ setOffsetHeight(windowHeight / 2 - (height / 2));
126
+ setShowHeight(height);
60
127
  setImgShow(true);
61
128
  }
62
129
  }
@@ -68,8 +135,15 @@ export function ImageInner({
68
135
  <div onClick={() => setImgShow(false)} className="weda-img-modal-close-btn">
69
136
  <i className="weui-icon-clear" style={{color: 'white'}}></i>
70
137
  </div>
71
- <div className="weda-img-preview" style={{
72
- backgroundImage: `url(${src})`
138
+
139
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */}
140
+ <div {...bind()} className="weda-img-preview" style={{
141
+ touchAction: 'none',
142
+ backgroundImage: `url(${src})`,
143
+ width: '100%',
144
+ height: showHeight,
145
+ marginTop: offsetHeight,
146
+ transform: `translate(${translateX}px, ${translateY}px) scale(${previewScale})`
73
147
  }}></div>
74
148
  </div>
75
149
  }
@@ -23,6 +23,7 @@
23
23
  right: 0;
24
24
  top: 0;
25
25
  bottom: 0;
26
+ z-index: 150;
26
27
  }
27
28
 
28
29
  .weda-img-modal-close-btn {
@@ -33,3 +34,19 @@
33
34
  z-index: 99;
34
35
  color: white;
35
36
  }
37
+
38
+ .weda-image.weda-image-error {
39
+ position: relative;
40
+ display: inline-block;
41
+ }
42
+
43
+ .weda-image:not([src]):before,
44
+ .weda-image-error::before {
45
+ content: '';
46
+ background: #f5f5f5 url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSJub25lIj4KICA8cGF0aCBkPSJNMjUuMzIgMTYuMzU5N0MyNi4wNzY0IDE2LjM1OTcgMjYuODI1NCAxNi41MDg3IDI3LjUyNDMgMTYuNzk4MUMyOC4yMjMxIDE3LjA4NzYgMjguODU4MSAxNy41MTE5IDI5LjM5MjkgMTguMDQ2OEMyOS45Mjc4IDE4LjU4MTYgMzAuMzUyMSAxOS4yMTY2IDMwLjY0MTYgMTkuOTE1NEMzMC45MzEgMjAuNjE0MyAzMS4wOCAyMS4zNjMzIDMxLjA4IDIyLjExOTdDMzEuMDggMjIuODc2MSAzMC45MzEgMjMuNjI1MSAzMC42NDE2IDI0LjMyMzlDMzAuMzUyMSAyNS4wMjI4IDI5LjkyNzggMjUuNjU3OCAyOS4zOTI5IDI2LjE5MjZDMjguODU4MSAyNi43Mjc1IDI4LjIyMzEgMjcuMTUxOCAyNy41MjQzIDI3LjQ0MTJDMjYuODI1NCAyNy43MzA3IDI2LjA3NjQgMjcuODc5NyAyNS4zMiAyNy44Nzk3QzIzLjc5MjQgMjcuODc5NyAyMi4zMjczIDI3LjI3MjggMjEuMjQ3MSAyNi4xOTI2QzIwLjE2NjkgMjUuMTEyNCAxOS41NiAyMy42NDczIDE5LjU2IDIyLjExOTdDMTkuNTYgMjAuNTkyIDIwLjE2NjkgMTkuMTI3IDIxLjI0NzEgMTguMDQ2OEMyMi4zMjczIDE2Ljk2NjUgMjMuNzkyNCAxNi4zNTk3IDI1LjMyIDE2LjM1OTdaTTI4IDMuNTU5NjlWMTQuODc2OEMyNy4xNzc3IDE0LjU4NjYgMjYuMTkyIDE0LjQzODggMjUuMzIgMTQuNDM5N0MyNC4wMzEgMTQuNDM5NyAyMi44MTU3IDE0Ljc1NzEgMjEuNzQ4OCAxNS4zMTg0TDIwLjc5NTIgMTMuMTU5N0wxNi4wMjU5IDIwLjAyNzVMOC40NDU3NiAxNi40NDFMMy41NiAyMy4zOTk3SDE3Ljc0NjJDMTcuOTg2NyAyNC44MjkgMTguNjI4MiAyNi4xNjA2IDE5LjU5NTggMjcuMjM5N0gxVjMuNTU5NjlIMjhaTTI1Ljk2IDI0LjAzOTdIMjQuNjhWMjUuMzE5N0gyNS45NlYyNC4wMzk3Wk0yNS45NiAxOC45MTk3SDI0LjY4VjIzLjM5OTdIMjUuOTZWMTguOTE5N1pNNi4xMiAxMC41OTk3QzYuMTIgMTEuOTk4MSA3LjE5OTA0IDEzLjEwODUgOC42MDc2OCAxMy4xNTg0QzEwLjAyMDggMTMuMjA3NyAxMS4yNCAxMi4wNDggMTEuMjQgMTAuNTk5N0MxMS4yNCA5LjI0NjA5IDEwLjA2NDMgOC4wODU3NyA4Ljc1MjMyIDguMDQwOTdDNy4yOTU2OCA3Ljk5MTY5IDYuMTIgOS4xNTEzNyA2LjEyIDEwLjU5OTdaIiBmaWxsPSIjQkNDNEQwIj48L3BhdGg+Cjwvc3ZnPgo=') no-repeat center / 50% 50%;
47
+ position: absolute;
48
+ left: 0;
49
+ top: 0;
50
+ width: 100%;
51
+ height: 100%;
52
+ }
@@ -54,6 +54,7 @@ export default function Image({
54
54
  className={cls}
55
55
  alt={alt}
56
56
  src={realSrc}
57
+ isError={isError}
57
58
  setIsError={setIsError}
58
59
  events={events}
59
60
  lazyLoad={lazyLoad}
@@ -1,7 +1,6 @@
1
1
  import '../wedatheme/style-package/index.css';
2
2
 
3
3
  export { default as Button } from './button';
4
- export { default as Markdown } from './markdown';
5
4
  export { default as Text } from './text';
6
5
  export { default as Container } from './container';
7
6
  export { default as Image } from './image';
@@ -29,6 +28,7 @@ export { default as Select } from './form/select';
29
28
  export { default as Uploader } from './form/uploader';
30
29
  export { default as Tips } from './form/tips';
31
30
  export { default as Tabs } from './tabs';
31
+ export { default as EnumSelect } from './form/enumSelect';
32
32
  // open
33
33
  // import Auth from './auth';
34
34