@cloudbase/weda-ui 3.7.2 → 3.7.4

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.
@@ -108,18 +108,28 @@ export function ImageUploaderH5({ title: label, maxUploadCount, maxSize = 10, ac
108
108
  return fileIdList.length < maxUploadCount;
109
109
  }, [fileIdList, single, maxUploadCount, uploading]);
110
110
  const uploadChange = async (e) => {
111
+ var _a, _b, _c, _d, _e, _f;
111
112
  let files = [...e.target.files];
112
113
  if (files.some((f) => f.size > maxSize * 1024 * 1024)) {
113
- weui.alert(`请上传不超过 ${maxSize}M 的图片`);
114
+ (_b = (_a = window === null || window === void 0 ? void 0 : window.$w) === null || _a === void 0 ? void 0 : _a.utils) === null || _b === void 0 ? void 0 : _b.showToast({
115
+ title: `请上传不超过 ${maxSize}M 的图片`,
116
+ icon: 'none',
117
+ });
114
118
  return false;
115
119
  }
116
120
  if (files.length > finalMaxImgCount) {
117
121
  // 防止一下子选择过多文件
118
- weui.alert(`最多只能上传${finalMaxImgCount}张图片,请重新选择`);
122
+ (_d = (_c = window === null || window === void 0 ? void 0 : window.$w) === null || _c === void 0 ? void 0 : _c.utils) === null || _d === void 0 ? void 0 : _d.showToast({
123
+ title: `最多只能上传${finalMaxImgCount}张图片,请重新选择`,
124
+ icon: 'none',
125
+ });
119
126
  return false;
120
127
  }
121
128
  if (fileIdList.length + files.length > finalMaxImgCount) {
122
- weui.alert(`最多只能上传${finalMaxImgCount}张图片`);
129
+ (_f = (_e = window === null || window === void 0 ? void 0 : window.$w) === null || _e === void 0 ? void 0 : _e.utils) === null || _f === void 0 ? void 0 : _f.showToast({
130
+ title: `最多只能上传${finalMaxImgCount}张图片`,
131
+ icon: 'none',
132
+ });
123
133
  return false;
124
134
  }
125
135
  let shouldUploadToCos = true;
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import weui from '../../../utils/weui';
4
3
  import isObjectEqual from '../../../utils/isObjectEqual';
5
4
  import { ConfigProvider, Button, Text, List, Progress, Tooltip, } from 'tea-component';
6
5
  import { filterStrList, isCloudFileID, isHttpFileID, transSize, transFileCloudidToName, randomStr, isInIde, isWebInMiniprogram, transFileName, } from '../../../utils/platform';
@@ -133,23 +132,36 @@ events = emptyObject, defaultValue, uploadPath = 'weda-uploader', single = true,
133
132
  events,
134
133
  fileSizeObj,
135
134
  }, children: _jsx("div", { "data-testid": "uploadFileH5", className: cls, id: id, style: style, children: _jsxs("div", { className: classNames(`${CLASS_PREFIX}`), children: [isEdit && (_jsx("div", { className: classNames(`${CLASS_PREFIX}__hd`, layout), children: _jsx("div", { children: btnDisabled ? (readOnly ? null : (_jsx(WdButton, { variant: "outline", className: classNames(`${CLASS_PREFIX}__btn--weak`), disabled: btnDisabled, text: btnTitle }))) : (_jsxs("div", { children: [_jsx("input", { id: "uploaderInput", type: "file", "data-testid": "button-up", className: "weui-uploader-mobile__input", accept: accepts.join(','), multiple: !single, onChange: async (e) => {
135
+ var _a, _b, _c, _d, _e, _f, _g, _h;
136
136
  let fileList = [...e.target.files];
137
137
  if (single && fileList.length > 1) {
138
- weui.alert(`上传文件总数不能超过1个`);
138
+ (_b = (_a = window === null || window === void 0 ? void 0 : window.$w) === null || _a === void 0 ? void 0 : _a.utils) === null || _b === void 0 ? void 0 : _b.showToast({
139
+ title: `上传文件总数不能超过1个`,
140
+ icon: 'none',
141
+ });
139
142
  return false;
140
143
  }
141
144
  if (fileList.length + fileIDList.length >
142
145
  maxUploadCount) {
143
- weui.alert(`上传文件总数不能超过${maxUploadCount}个`);
146
+ (_d = (_c = window === null || window === void 0 ? void 0 : window.$w) === null || _c === void 0 ? void 0 : _c.utils) === null || _d === void 0 ? void 0 : _d.showToast({
147
+ title: `上传文件总数不能超过${maxUploadCount}个`,
148
+ icon: 'none',
149
+ });
144
150
  return false;
145
151
  }
146
152
  if (maxSizeLimit &&
147
153
  fileList.some((f) => f.size > maxSizeLimit * 1024 * 1024)) {
148
- weui.alert(`请上传不超过${maxSizeLimit}M的文件`);
154
+ (_f = (_e = window === null || window === void 0 ? void 0 : window.$w) === null || _e === void 0 ? void 0 : _e.utils) === null || _f === void 0 ? void 0 : _f.showToast({
155
+ title: `请上传不超过${maxSizeLimit}M的文件`,
156
+ icon: 'none',
157
+ });
149
158
  return false;
150
159
  }
151
160
  if (fileList.some((f) => f.size > 1024 * 1024 * 1024)) {
152
- weui.alert(`请上传不超过1024M的文件`);
161
+ (_h = (_g = window === null || window === void 0 ? void 0 : window.$w) === null || _g === void 0 ? void 0 : _g.utils) === null || _h === void 0 ? void 0 : _h.showToast({
162
+ title: `请上传不超过1024M的文件`,
163
+ icon: 'none',
164
+ });
153
165
  return false;
154
166
  }
155
167
  let shouldUploadToCos = true;
@@ -98,6 +98,7 @@ export default React.forwardRef(function ListView(props, ref) {
98
98
  (_a = observeRef.current) === null || _a === void 0 ? void 0 : _a.disconnect();
99
99
  clearContext();
100
100
  };
101
+ // eslint-disable-next-line react-hooks/exhaustive-deps
101
102
  }, []);
102
103
  // 监听更改数据源时,清空当前列表
103
104
  useEffect(() => {
@@ -240,7 +241,9 @@ export default React.forwardRef(function ListView(props, ref) {
240
241
  clearTimeout(delayRef.current.statusTimer);
241
242
  delayRef.current.statusTimer = null;
242
243
  }
243
- delayRef.current.statusTimer = window.setTimeout(statusCb, pagination === 'bottomLoad' ? 3000 : 150);
244
+ delayRef.current.statusTimer = window.setTimeout(statusCb, pagination === 'bottomLoad' && dataSourceType === 'expression'
245
+ ? 3000
246
+ : 150);
244
247
  }
245
248
  else {
246
249
  statusCb();
@@ -39,7 +39,7 @@ export const MenuLogo = React.memo(function MenuLogo({ navigationStyle, classNam
39
39
  });
40
40
  // icon回显
41
41
  export const IconShow = ({ onIcon, menuColor, menuFontSize }) => {
42
- return (_jsx(_Fragment, { children: (onIcon === null || onIcon === void 0 ? void 0 : onIcon.includes('td:')) ? (_jsx(IconFont, { name: onIcon === null || onIcon === void 0 ? void 0 : onIcon.split(':')[1], className: `${CLASS_PREFIX}__fonticon`, style: { color: menuColor, fontSize: menuFontSize } })) : (_jsx("div", { className: `${CLASS_PREFIX}__fonticon lcap-icon lcap-icon-${onIcon}`, style: { color: menuColor, fontSize: menuFontSize } })) }));
42
+ return (_jsx(_Fragment, { children: (onIcon === null || onIcon === void 0 ? void 0 : onIcon.includes('td:')) ? (_jsx(IconFont, { name: onIcon === null || onIcon === void 0 ? void 0 : onIcon.split(':')[1], className: `${CLASS_PREFIX}__fonticon wd-icon`, style: { color: menuColor, fontSize: menuFontSize } })) : (_jsx("div", { className: `${CLASS_PREFIX}__fonticon lcap-icon lcap-icon-${onIcon}`, style: { color: menuColor, fontSize: menuFontSize } })) }));
43
43
  };
44
44
  // 菜单图标
45
45
  export const renderMenuIcon = (iconUrl, iconPath, navigationStyle) => {
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
2
+ import { useEffect, useRef, useState } from 'react';
3
3
  import classNames from '../../utils/classnames';
4
4
  import { getTempFileURL } from '../../utils/tcb';
5
5
  import { LOAD_ERR_IMG_BASE64, getWhitelist } from '../../utils/constant';
6
+ import { getOnClick } from '../wd-unified-link/utils';
6
7
  import destr from 'destr';
7
8
  import './style';
8
9
  import xss from 'xss';
@@ -48,5 +49,16 @@ export default function RichTextView({ value = '', className, style, id, }) {
48
49
  setDisplayValue(tempValue);
49
50
  }
50
51
  }, [value]);
51
- return (displayValue && (_jsx("div", { className: cls, style: style, id: id, children: _jsx("div", { dangerouslySetInnerHTML: { __html: displayValue } }) })));
52
+ const richTextRef = useRef(null);
53
+ useEffect(() => {
54
+ if (richTextRef.current) {
55
+ richTextRef.current.querySelectorAll('a').forEach((a) => {
56
+ a.addEventListener('click', (e) => {
57
+ const url = a.href;
58
+ getOnClick({ url })(e);
59
+ });
60
+ });
61
+ }
62
+ }, [displayValue]);
63
+ return (displayValue && (_jsx("div", { ref: richTextRef, className: cls, style: style, id: id, children: _jsx("div", { dangerouslySetInnerHTML: { __html: displayValue } }) })));
52
64
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useImperativeHandle, useMemo, useRef, useState } from 'react';
2
+ import React, { useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
3
3
  import CodeMirror from '@uiw/react-codemirror';
4
4
  import classNames from '../../utils/classnames';
5
5
  import { useConfig } from '../../utils/config-context';
@@ -50,16 +50,28 @@ export const WdCodeEditor = React.forwardRef(function WdCodeEditor(props, ref) {
50
50
  useSetWidgetApi(() => ({
51
51
  ...innerHandle,
52
52
  value,
53
- format: async () => {
53
+ format: async (params) => {
54
54
  try {
55
- const result = await format(value);
55
+ let _value = value;
56
+ if (params.isCustomVal) {
57
+ _value = params === null || params === void 0 ? void 0 : params.value;
58
+ }
59
+ const result = await format(_value);
56
60
  onChangeForm(result);
61
+ return result;
57
62
  }
58
63
  catch (error) {
59
64
  console.error(error);
60
65
  }
61
66
  },
62
67
  }), [innerHandle, onChangeForm, value], ref);
68
+ useEffect(() => {
69
+ if (events === null || events === void 0 ? void 0 : events.ready) {
70
+ // eslint-disable-next-line rulesdir/no-trigger-event-in-effect
71
+ events === null || events === void 0 ? void 0 : events.ready();
72
+ }
73
+ // eslint-disable-next-line react-hooks/exhaustive-deps
74
+ }, []);
63
75
  const themeExtension = themeData[theme];
64
76
  const languageExtension = loadLanguage(language);
65
77
  return (visible && (_jsx(WdFormItem, { ...props, validateErrorMsg: validateErrorMsg, validateState: validateState, readOnly: false, disabled: disabled, readValue: value, classRoot: classRoot, inputId: inputId, layout: props.layout, children: _jsx("div", { className: cls, ref: wrapRef, onFocus: () => wrapRef.current.classList.add('is-focused'), onBlur: () => wrapRef.current.classList.remove('is-focused'), "data-color-mode": theme, children: _jsxs("div", { className: `${root}__content`, "data-testid": "wd-code-editor", children: [_jsx(CodeMirror, { value: value, height: height, extensions: [languageExtension], onChange: onChange, placeholder: placeholder, editable: !readOnly && !disabled, autoFocus: focus, theme: themeExtension }), _jsx("textarea", { id: inputId, ref: textareaRef, placeholder: placeholder, name: name, value: value, autoFocus: focus, disabled: disabled, readOnly: readOnly, onChange: onChange, spellCheck: false, ...startWithOnProps })] }) }) })));
@@ -185,7 +185,7 @@ const getSearchValues = (searchValues) => {
185
185
  });
186
186
  };
187
187
  const getPageParam = ({ defaultSort, sort: _sort, params, _defaultPageSize, _defaultPageIndex, supportManyRelated, columns, isSupportMultipleSort, }) => {
188
- let sort = defaultSort;
188
+ let sort = defaultSort || [];
189
189
  // 运行态有值,以运行态为准
190
190
  if ((_sort === null || _sort === void 0 ? void 0 : _sort.length) && _sort[0].order) {
191
191
  params.orderBy = _sort[0].by;
@@ -193,7 +193,7 @@ const getPageParam = ({ defaultSort, sort: _sort, params, _defaultPageSize, _def
193
193
  sort = _sort;
194
194
  }
195
195
  // 后端根据业务字段排序
196
- sort = sort.map((n) => {
196
+ sort = sort === null || sort === void 0 ? void 0 : sort.map((n) => {
197
197
  var _a;
198
198
  return ({
199
199
  ...n,
@@ -2,12 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from 'react';
3
3
  import { ConfigProvider } from 'tea-component';
4
4
  import { useConfig } from '../../utils/config-context';
5
- import { usePlatform, alertErrorMessage } from '../../utils/platform';
5
+ import { usePlatform } from '../../utils/platform';
6
6
  import classNames from '../../utils/classnames';
7
7
  import { useSetWidgetApi } from '../../utils/widget-api/use-set-widget-api';
8
+ import { getOnClick } from './utils';
8
9
  import '../style';
9
10
  export const WdUnifiedLink = forwardRef(function WdUnifiedLink(props, ref) {
10
- const { className, id, style, children, url, options, events } = props;
11
+ const { className, id, style, children, url, options } = props;
11
12
  const platform = usePlatform();
12
13
  // 样式
13
14
  const { classPrefix } = useConfig();
@@ -19,73 +20,13 @@ export const WdUnifiedLink = forwardRef(function WdUnifiedLink(props, ref) {
19
20
  [compClassName]: true,
20
21
  [platformCss]: true,
21
22
  };
22
- const isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i);
23
23
  // Widget API,挂载组件只读属性和组件方法
24
24
  useSetWidgetApi(() => ({
25
25
  url,
26
26
  options,
27
27
  }), [url, options], ref);
28
28
  // 方法
29
- const onClick = async (e) => {
30
- var _a, _b, _c, _d, _e;
31
- events.tap && events.tap({}, { originEvent: e });
32
- // a 标签直接跳转
33
- if (/https?:\/\//.test(url)) {
34
- return;
35
- }
36
- if (!e.defaultPrevented) {
37
- e.preventDefault();
38
- const URL_REG = /^(weda-page|plugin|miniprogram):\/\/([0-9.\-A-Za-z]+)(?:\/([^?#]*))?(?:\?([^#]*))?$/;
39
- const matched = url.match(URL_REG);
40
- if (matched) {
41
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
- const [_, protocol, ...restOpts] = matched;
43
- switch (protocol) {
44
- case 'plugin':
45
- alertErrorMessage({
46
- message: '仅支持在小程序端打开插件页面',
47
- });
48
- break;
49
- case 'weda-page': {
50
- const [packageName, pageId, query] = restOpts;
51
- let params = {};
52
- if (query) {
53
- params = query.split('&').reduce((acc, param) => {
54
- const [key, value] = param.split('=');
55
- acc[key] = value;
56
- return acc;
57
- }, {});
58
- }
59
- // 页面参数,如果存在变量绑定,以绑定值为准
60
- if ((_a = props === null || props === void 0 ? void 0 : props.params) === null || _a === void 0 ? void 0 : _a[pageId]) {
61
- params = { ...params, ...(_b = props === null || props === void 0 ? void 0 : props.params) === null || _b === void 0 ? void 0 : _b[pageId] };
62
- }
63
- (_c = window === null || window === void 0 ? void 0 : window.app) === null || _c === void 0 ? void 0 : _c.navigateTo({
64
- pageId,
65
- packageName: packageName === 'main' ? '' : packageName,
66
- mode: (options === null || options === void 0 ? void 0 : options.target) === '_blank' ? 'web' : 'weDa',
67
- params,
68
- });
69
- break;
70
- }
71
- case 'miniprogram':
72
- // 打开其他小程序
73
- if (!isMobile) {
74
- alertErrorMessage({
75
- message: '仅支持在移动端打开小程序页面',
76
- });
77
- }
78
- else {
79
- (_d = window === null || window === void 0 ? void 0 : window.app) === null || _d === void 0 ? void 0 : _d.navigateTo({ url, options });
80
- }
81
- break;
82
- default:
83
- (_e = window === null || window === void 0 ? void 0 : window.app) === null || _e === void 0 ? void 0 : _e.navigateTo({ url, options });
84
- break;
85
- }
86
- }
87
- }
88
- };
29
+ const onClick = getOnClick(props);
89
30
  return (_jsx(ConfigProvider, { classPrefix: "wedatea2td", children: _jsx("a", { href: /https?:\/\//.test(url) ? url : 'javascript:void(0);', rel: "noopener noreferrer", className: classNames(classes, className), id: id, style: style, onClick: onClick, "data-testid": "wd-unified-link", ...options, children: children }) }));
90
31
  });
91
32
  export default WdUnifiedLink;
@@ -0,0 +1 @@
1
+ export declare const getOnClick: (props: any) => (e: any) => Promise<void>;
@@ -0,0 +1,66 @@
1
+ import { alertErrorMessage } from '../../utils/platform';
2
+ // ! reference in src/web/components/richTextView/index.tsx
3
+ export const getOnClick = (props) => {
4
+ const { url, options, events } = props;
5
+ const isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i);
6
+ return async (e) => {
7
+ var _a, _b, _c, _d, _e;
8
+ (events === null || events === void 0 ? void 0 : events.tap) && events.tap({}, { originEvent: e });
9
+ // a 标签直接跳转
10
+ if (/https?:\/\//.test(url)) {
11
+ return;
12
+ }
13
+ if (!e.defaultPrevented) {
14
+ e.preventDefault();
15
+ const URL_REG = /^(weda-page|plugin|miniprogram):\/\/([0-9.\-A-Za-z]+)(?:\/([^?#]*))?(?:\?([^#]*))?$/;
16
+ const matched = url.match(URL_REG);
17
+ if (matched) {
18
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
+ const [_, protocol, ...restOpts] = matched;
20
+ switch (protocol) {
21
+ case 'plugin':
22
+ alertErrorMessage({
23
+ message: '仅支持在小程序端打开插件页面',
24
+ });
25
+ break;
26
+ case 'weda-page': {
27
+ const [packageName, pageId, query] = restOpts;
28
+ let params = {};
29
+ if (query) {
30
+ params = query.split('&').reduce((acc, param) => {
31
+ const [key, value] = param.split('=');
32
+ acc[key] = value;
33
+ return acc;
34
+ }, {});
35
+ }
36
+ // 页面参数,如果存在变量绑定,以绑定值为准
37
+ if ((_a = props === null || props === void 0 ? void 0 : props.params) === null || _a === void 0 ? void 0 : _a[pageId]) {
38
+ params = { ...params, ...(_b = props === null || props === void 0 ? void 0 : props.params) === null || _b === void 0 ? void 0 : _b[pageId] };
39
+ }
40
+ (_c = window === null || window === void 0 ? void 0 : window.app) === null || _c === void 0 ? void 0 : _c.navigateTo({
41
+ pageId,
42
+ packageName: packageName === 'main' ? '' : packageName,
43
+ mode: (options === null || options === void 0 ? void 0 : options.target) === '_blank' ? 'web' : 'weDa',
44
+ params,
45
+ });
46
+ break;
47
+ }
48
+ case 'miniprogram':
49
+ // 打开其他小程序
50
+ if (!isMobile) {
51
+ alertErrorMessage({
52
+ message: '仅支持在移动端打开小程序页面',
53
+ });
54
+ }
55
+ else {
56
+ (_d = window === null || window === void 0 ? void 0 : window.app) === null || _d === void 0 ? void 0 : _d.navigateTo({ url, options });
57
+ }
58
+ break;
59
+ default:
60
+ (_e = window === null || window === void 0 ? void 0 : window.app) === null || _e === void 0 ? void 0 : _e.navigateTo({ url, options });
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ };
66
+ };
@@ -226,7 +226,11 @@ export const getWhitelist = () => {
226
226
  onTagAttr: function (tag, name, value) {
227
227
  if (((tag === 'img' && name === 'src') ||
228
228
  (tag === 'a' && name === 'href')) &&
229
- /^((http)|(https)|(cloud)|(mailto)|(ftp)|(tel)):/.test(value)) {
229
+ // Prettier -> 单行过长 分行处理
230
+ [
231
+ /^((http)|(https)|(cloud)|(mailto)|(ftp)|(tel)):/,
232
+ /^((weda-page)|(miniprogram)|(plugin)):/,
233
+ ].some((reg) => reg.test(value))) {
230
234
  return `${name}="${value}"`;
231
235
  }
232
236
  if (name === 'style') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/weda-ui",
3
- "version": "3.7.2",
3
+ "version": "3.7.4",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index",
6
6
  "miniprogram": "mpdist",