@cloudbase/weda-ui 3.6.3 → 3.7.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 (92) hide show
  1. package/dist/configs/components/form-location.d.ts +2 -2
  2. package/dist/configs/components/wd-card.d.ts +14 -14
  3. package/dist/configs/components/wd-card.js +38 -32
  4. package/dist/configs/components/wd-cascader.d.ts +276 -0
  5. package/dist/configs/components/wd-cascader.js +183 -0
  6. package/dist/configs/components/wd-code-editor.d.ts +245 -0
  7. package/dist/configs/components/wd-code-editor.js +92 -0
  8. package/dist/configs/components/wd-form-arr.d.ts +193 -0
  9. package/dist/configs/components/wd-form-arr.js +206 -0
  10. package/dist/configs/components/wd-form-obj.d.ts +181 -0
  11. package/dist/configs/components/wd-form-obj.js +107 -0
  12. package/dist/configs/components/wd-form.d.ts +2 -2
  13. package/dist/configs/components/wd-image.js +1 -1
  14. package/dist/configs/components/wd-table.d.ts +3 -3
  15. package/dist/configs/components/wd-upload-file.d.ts +1 -0
  16. package/dist/configs/components/wd-upload-file.js +4 -1
  17. package/dist/configs/components/wd-upload-image.d.ts +2 -0
  18. package/dist/configs/components/wd-upload-image.js +4 -1
  19. package/dist/configs/components/web-view.d.ts +20 -1
  20. package/dist/configs/components/web-view.js +22 -1
  21. package/dist/configs/index.d.ts +1604 -28
  22. package/dist/configs/index.js +8 -0
  23. package/dist/configs/type-utils/type-form.d.ts +22 -0
  24. package/dist/configs/type-utils/type-form.js +58 -1
  25. package/dist/configs/type-utils/x-runtime-default.d.ts +3 -0
  26. package/dist/configs/type-utils/x-runtime-default.js +3 -0
  27. package/dist/enum/index.d.ts +8 -0
  28. package/dist/enum/index.js +11 -0
  29. package/dist/style/index.scss +1 -1
  30. package/dist/web/components/container/index.js +49 -1
  31. package/dist/web/components/form/uploader/uploader.h5.js +3 -3
  32. package/dist/web/components/form/uploader/uploader.pc.js +3 -3
  33. package/dist/web/components/form-input-hooks/index.js +14 -7
  34. package/dist/web/components/form-input-hooks/validator.js +2 -2
  35. package/dist/web/components/form-location/index.d.ts +1 -1
  36. package/dist/web/components/index.d.ts +4 -0
  37. package/dist/web/components/index.js +6 -0
  38. package/dist/web/components/richTextView/index.css +2 -1
  39. package/dist/web/components/wd-cascader/cascader.d.ts +6 -0
  40. package/dist/web/components/wd-cascader/cascader.h5.d.ts +2 -0
  41. package/dist/web/components/wd-cascader/cascader.h5.js +132 -0
  42. package/dist/web/components/wd-cascader/cascader.js +97 -0
  43. package/dist/web/components/wd-cascader/index.d.ts +4 -0
  44. package/dist/web/components/wd-cascader/index.js +3 -0
  45. package/dist/web/components/wd-cascader/interface.d.ts +26 -0
  46. package/dist/web/components/wd-cascader/interface.js +1 -0
  47. package/dist/web/components/wd-cascader/utils.d.ts +6 -0
  48. package/dist/web/components/wd-cascader/utils.js +63 -0
  49. package/dist/web/components/wd-code-editor/index.d.ts +3 -0
  50. package/dist/web/components/wd-code-editor/index.js +3 -0
  51. package/dist/web/components/wd-code-editor/lang/index.d.ts +17 -0
  52. package/dist/web/components/wd-code-editor/lang/index.js +21 -0
  53. package/dist/web/components/wd-code-editor/lang/mongodb/complete.d.ts +8 -0
  54. package/dist/web/components/wd-code-editor/lang/mongodb/complete.js +222 -0
  55. package/dist/web/components/wd-code-editor/lang/mongodb/index.d.ts +2 -0
  56. package/dist/web/components/wd-code-editor/lang/mongodb/index.js +60 -0
  57. package/dist/web/components/wd-code-editor/lang/mongodb/snippets.d.ts +6 -0
  58. package/dist/web/components/wd-code-editor/lang/mongodb/snippets.js +189 -0
  59. package/dist/web/components/wd-code-editor/theme.d.ts +4 -0
  60. package/dist/web/components/wd-code-editor/theme.js +5 -0
  61. package/dist/web/components/wd-code-editor/wd-code-editor.d.ts +9 -0
  62. package/dist/web/components/wd-code-editor/wd-code-editor.js +66 -0
  63. package/dist/web/components/wd-date/elements/Modal.h5.d.ts +2 -0
  64. package/dist/web/components/wd-date/elements/Modal.h5.js +4 -2
  65. package/dist/web/components/wd-form/form-utils.js +1 -1
  66. package/dist/web/components/wd-form/index.d.ts +4 -4
  67. package/dist/web/components/wd-form-arr/index.d.ts +4 -0
  68. package/dist/web/components/wd-form-arr/index.js +3 -0
  69. package/dist/web/components/wd-form-arr/wd-form-arr.d.ts +8 -0
  70. package/dist/web/components/wd-form-arr/wd-form-arr.js +6 -0
  71. package/dist/web/components/wd-form-item/wd-form-item.js +3 -3
  72. package/dist/web/components/wd-form-obj/base-form-obj.d.ts +13 -0
  73. package/dist/web/components/wd-form-obj/base-form-obj.js +351 -0
  74. package/dist/web/components/wd-form-obj/index.d.ts +4 -0
  75. package/dist/web/components/wd-form-obj/index.js +3 -0
  76. package/dist/web/components/wd-form-obj/wd-form-obj.d.ts +9 -0
  77. package/dist/web/components/wd-form-obj/wd-form-obj.js +7 -0
  78. package/dist/web/components/wd-input/wd-input.d.ts +2 -2
  79. package/dist/web/components/wd-input-phone/wd-input-phone.js +2 -2
  80. package/dist/web/components/wd-table/utils/index.js +20 -8
  81. package/dist/web/components/wd-table/wd-table.js +4 -2
  82. package/dist/web/components/wd-tabs/tabs.d.ts +1 -1
  83. package/dist/web/components/wd-textarea/calcTextareaHeight.d.ts +1 -0
  84. package/dist/web/components/wd-textarea/calcTextareaHeight.js +45 -0
  85. package/dist/web/components/wd-textarea/wd-textarea.js +4 -6
  86. package/dist/web/components/wd-unified-link/index.js +2 -2
  87. package/dist/web/components/web-view/web-view.js +15 -4
  88. package/dist/web/utils/tool.d.ts +1 -0
  89. package/dist/web/utils/tool.js +4 -1
  90. package/dist/web/utils/widget-api/index.d.ts +20 -0
  91. package/dist/web/utils/widget-api/index.js +14 -0
  92. package/package.json +8 -1
@@ -3,11 +3,59 @@ import * as React from 'react';
3
3
  import classNames from '../../utils/classnames';
4
4
  import { emptyObject } from '../../utils/constant';
5
5
  import { useSetWidgetApi } from '../../utils/widget-api/use-set-widget-api';
6
+ import { isIOS } from '../../utils/tool';
6
7
  export default React.forwardRef(function Container({ children, title, events = emptyObject, className, style, id, data, }, ref) {
7
8
  useSetWidgetApi(() => {
8
9
  return {
9
10
  data,
10
11
  };
11
12
  }, [data], ref);
12
- return (_jsx("div", { role: "container", id: id, style: style, className: classNames({ 'weda-ui': true, [className]: className }), title: title, onClick: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.tap) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onContextMenu: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.longpress) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onTouchStart: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.touchstart) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onTouchMove: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.touchmove) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onTouchCancel: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.touchcancel) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onTouchEnd: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.touchend) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, children: children }));
13
+ const ios = isIOS();
14
+ const touchData = React.useRef({ touchStartX: 0, touchStartY: 0 });
15
+ const longpressData = React.useRef({
16
+ longpressTimed: null,
17
+ hasMockContextMenu: false,
18
+ });
19
+ function handleTouchStart(e) {
20
+ var _a, _b, _c;
21
+ (_a = events === null || events === void 0 ? void 0 : events.touchstart) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e });
22
+ if (ios && (events === null || events === void 0 ? void 0 : events.longpress)) {
23
+ const touchStartX = (_b = e.touches[0]) === null || _b === void 0 ? void 0 : _b.clientX;
24
+ const touchStartY = (_c = e.touches[0]) === null || _c === void 0 ? void 0 : _c.clientY;
25
+ touchData.current = { touchStartX, touchStartY };
26
+ // eslint-disable-next-line rulesdir/no-timer
27
+ longpressData.current.longpressTimed = setTimeout(() => {
28
+ var _a;
29
+ e.preventDefault();
30
+ (_a = events === null || events === void 0 ? void 0 : events.longpress) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e });
31
+ longpressData.current.hasMockContextMenu = true;
32
+ }, 1000);
33
+ }
34
+ }
35
+ function handleTouchMove(e) {
36
+ var _a, _b, _c;
37
+ (_a = events === null || events === void 0 ? void 0 : events.touchmove) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e });
38
+ if (ios && (events === null || events === void 0 ? void 0 : events.longpress)) {
39
+ const { touchStartX, touchStartY } = touchData.current;
40
+ const touchMoveX = (_b = e.touches[0]) === null || _b === void 0 ? void 0 : _b.clientX;
41
+ const touchMoveY = (_c = e.touches[0]) === null || _c === void 0 ? void 0 : _c.clientY;
42
+ if (Math.abs(touchMoveX - touchStartX) > 10 ||
43
+ Math.abs(touchMoveY - touchStartY) > 10) {
44
+ clearTimeout(longpressData.current.longpressTimed);
45
+ }
46
+ }
47
+ }
48
+ function handleTouchEnd(e) {
49
+ var _a;
50
+ (_a = events === null || events === void 0 ? void 0 : events.touchend) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e });
51
+ clearTimeout(longpressData.current.longpressTimed);
52
+ }
53
+ function handleContextMenu(e) {
54
+ var _a;
55
+ if (!longpressData.current.hasMockContextMenu) {
56
+ (_a = events === null || events === void 0 ? void 0 : events.longpress) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e });
57
+ clearTimeout(longpressData.current.longpressTimed);
58
+ }
59
+ }
60
+ return (_jsx("div", { role: "container", id: id, style: style, className: classNames({ 'weda-ui': true, [className]: className }), title: title, onClick: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.tap) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onContextMenu: handleContextMenu, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchCancel: (e) => { var _a; return (_a = events === null || events === void 0 ? void 0 : events.touchcancel) === null || _a === void 0 ? void 0 : _a.call(events, {}, { originEvent: e }); }, onTouchEnd: handleTouchEnd, children: children }));
13
61
  });
@@ -50,13 +50,13 @@ export function ImageUploaderH5({ title: label, maxUploadCount, maxSize = 10, ac
50
50
  const deleteFile = (url) => {
51
51
  const value = single ? '' : fileIdList.filter((f) => f !== url);
52
52
  setInputValue(value);
53
- handleChange([].concat(value));
53
+ handleChange([].concat(value), true);
54
54
  };
55
- const handleChange = (ids) => {
55
+ const handleChange = (ids, isDelete = false) => {
56
56
  const value = single ? ids[0] || '' : ids;
57
57
  setInputValue(value);
58
58
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
59
- events === null || events === void 0 ? void 0 : events.change({ value });
59
+ events === null || events === void 0 ? void 0 : events.change({ value, isDelete });
60
60
  };
61
61
  const onProgress = (progressEvent) => {
62
62
  let percentCompleted = 0;
@@ -44,12 +44,12 @@ export function UploaderPCInner(props) {
44
44
  defaultValueRef.current = defaultValue;
45
45
  setfileIDList(initialValue);
46
46
  }, [defaultValue, single]);
47
- const handleChange = (ids) => {
47
+ const handleChange = (ids, isDelete = false) => {
48
48
  var _a;
49
49
  setfileIDList(ids);
50
50
  const value = single ? ids[0] || '' : ids;
51
51
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
52
- (_a = events === null || events === void 0 ? void 0 : events.change) === null || _a === void 0 ? void 0 : _a.call(events, { value });
52
+ (_a = events === null || events === void 0 ? void 0 : events.change) === null || _a === void 0 ? void 0 : _a.call(events, { value, isDelete });
53
53
  };
54
54
  // 方法:上传前,判断图片大小、数量是否满足,取消默认组件的上传事件,用自定义的 tcb 上传方法
55
55
  const beforeHandle = async (file, fileList, isAccepted, error) => {
@@ -178,7 +178,7 @@ export function UploaderPCInner(props) {
178
178
  // 删除图片
179
179
  const deleteHandle = (fileID) => {
180
180
  const ids = fileIDList.filter((d) => d !== fileID);
181
- handleChange(ids);
181
+ handleChange(ids, true);
182
182
  };
183
183
  // 转换后的属性
184
184
  const extraProps = {};
@@ -6,7 +6,7 @@ import { debug } from '../../utils/console';
6
6
  import { useSyncValue } from '../../utils/hooks/useSyncValue';
7
7
  import isObjectEqual from '../../utils/isObjectEqual';
8
8
  import { isNil } from '../../utils/lodash';
9
- import { getParentForm, useFormDetailContext } from '../../utils/widget-api';
9
+ import { getParentForm, useFormDetailContext, useFormObjContext, } from '../../utils/widget-api';
10
10
  import { validType } from './validator';
11
11
  import { emptyArray, noop } from '../../utils/constant';
12
12
  import { useDeepCompareEffect, useRerender, useUnmountEffect, } from '@react-hookz/web';
@@ -28,16 +28,19 @@ export function useFormInputTrait(inputParams) {
28
28
  if (isNil($widget)) {
29
29
  throw new Error('$widget 没传入');
30
30
  }
31
- const [name] = useSyncValue(inputParams.name);
31
+ const formObjContext = useFormObjContext();
32
+ const [name] = useSyncValue(`${(formObjContext === null || formObjContext === void 0 ? void 0 : formObjContext.formObjName) ? `${formObjContext.formObjName}.` : ''}${inputParams.name}`);
32
33
  const formType = useFormType();
33
34
  const statusParams = useStatus(inputParams);
34
35
  const formDetailStatus = useFormDetailContext();
35
36
  const [disabled, setDisabled] = useSyncValue(((_a = statusParams.disabled) !== null && _a !== void 0 ? _a : false) ||
36
37
  formType === 'read' ||
37
- formDetailStatus === 'disabled');
38
+ formDetailStatus === 'disabled' ||
39
+ (formObjContext === null || formObjContext === void 0 ? void 0 : formObjContext.status) === 'disabled');
38
40
  const [readOnly, setReadOnly] = useSyncValue(statusParams.readOnly ||
39
41
  formType === 'read' ||
40
- formDetailStatus === 'readOnly');
42
+ formDetailStatus === 'readOnly' ||
43
+ (formObjContext === null || formObjContext === void 0 ? void 0 : formObjContext.status) === 'readOnly');
41
44
  const [validateState, setValidateState] = useState(inputParams.validateStatus);
42
45
  const [validateErrorMsg, setValidateErrorMsg] = useState('');
43
46
  const [visible, setVisible] = useState(true);
@@ -59,13 +62,15 @@ export function useFormInputTrait(inputParams) {
59
62
  // 只在暴露方法的闭包内用,别的地方别用
60
63
  valueRef,] = useSyncValue(value, isObjectEqual);
61
64
  const setSyncedValue = useCallback((newVal) => {
62
- var _a;
65
+ var _a, _b;
63
66
  logger.debug('updateFormContext', newVal);
64
67
  _setSyncedValue(newVal);
65
68
  // 发现富文本中有时序问题,form 还是拿到旧值的闭包,所以再找一次
66
69
  const f = form !== null && form !== void 0 ? form : getParentForm($widget);
67
70
  (_a = f === null || f === void 0 ? void 0 : f.updateFormContext) === null || _a === void 0 ? void 0 : _a.call(f, name, newVal);
68
- }, [$widget, _setSyncedValue, form, name]);
71
+ // 更新嵌套表单的值
72
+ (_b = formObjContext === null || formObjContext === void 0 ? void 0 : formObjContext.valueChangeFromChild) === null || _b === void 0 ? void 0 : _b.call(formObjContext, { name, value: newVal });
73
+ }, [$widget, _setSyncedValue, form, formObjContext, name]);
69
74
  useDeepCompareEffect(() => {
70
75
  var _a;
71
76
  const f = form !== null && form !== void 0 ? form : getParentForm($widget);
@@ -83,12 +88,14 @@ export function useFormInputTrait(inputParams) {
83
88
  var _a, _b;
84
89
  const removeFormItem = (_b = (_a = $widget
85
90
  .closest((w) => { var _a, _b; return ((_b = (_a = w.getConfig) === null || _a === void 0 ? void 0 : _a.call(w)) === null || _b === void 0 ? void 0 : _b.componentType) === 'form'; })) === null || _a === void 0 ? void 0 : _a.addFormItem) === null || _b === void 0 ? void 0 : _b.call(_a, name, $widget);
91
+ const removeFormObjItem = formObjContext === null || formObjContext === void 0 ? void 0 : formObjContext.addFormItem(name, $widget);
86
92
  logger.debug('addFormItem', name);
87
93
  return () => {
88
94
  logger.debug('removeFormItem', name);
89
95
  removeFormItem === null || removeFormItem === void 0 ? void 0 : removeFormItem();
96
+ removeFormObjItem === null || removeFormObjItem === void 0 ? void 0 : removeFormObjItem();
90
97
  };
91
- }, [$widget, name, form]);
98
+ }, [$widget, name, form, formObjContext]);
92
99
  const clearValidate = useCallback(() => {
93
100
  setValidateErrorMsg('');
94
101
  setValidateState(undefined);
@@ -7,8 +7,8 @@ const pattern = {
7
7
  cnName: /^[\u2E80-\uFE4F]{2,6}(?:·[\u2E80-\uFE4F]{2,6})*$/,
8
8
  userName: /^[\da-zA-Z\u2E80-\uFE4F \s]{2,}$/,
9
9
  carId: /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/,
10
- mobile: /^1[3456789]\d{9}$/,
11
- tel: /^(0\d{2,3}-)?(\d{7,8})$/,
10
+ mobile: /^(\+\d{1,4}[\s-]?)?(\(?\d{1,4}\)?[\s-]?)?(\d{1,4}[\s-]?)?(\d{1,4})?\d{1,9}(\s?(x|ext)\s?\d{1,6})?$/,
11
+ tel: /^(\+\d{1,4}[\s-]?)?(\(?\d{1,4}\)?[\s-]?)?(\d{1,4}[\s-]?)?(\d{1,4})?\d{1,9}(\s?(x|ext)\s?\d{1,6})?$/,
12
12
  address: /^[\da-zA-Z\u2E80-\uFE4F \s-]{4,400}$/,
13
13
  date: /((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)$))/,
14
14
  numVcode: /^[0-9]{4,8}$/,
@@ -26,7 +26,7 @@ declare const FormLocation: React.ForwardRefExoticComponent<CommonPropsType & im
26
26
  showLngLat: boolean;
27
27
  showMap: boolean;
28
28
  validateStatus: "success" | "error" | "warn";
29
- locationRange: 0 | -1 | 100 | 500 | 1000 | 300 | 2000;
29
+ locationRange: 0 | -1 | 100 | 1000 | 500 | 300 | 2000;
30
30
  customRange: number;
31
31
  requiredFlag: boolean;
32
32
  requiredMsg: string;
@@ -138,11 +138,15 @@ export { default as WdTabBar } from "./wd-tabbar";
138
138
  export { default as WdUnifiedLink } from "./wd-unified-link";
139
139
  export { default as WdProgress } from "./wd-progress";
140
140
  export { default as WdDepartment } from "./wd-department";
141
+ export const WdCodeEditor: any;
141
142
  export const WdMember: any;
142
143
  export const WdLocation: any;
143
144
  export const WdRichText: any;
144
145
  export { default as WdCanvas } from "./wd-canvas";
145
146
  export { default as WdAudio } from "./wd-audio";
147
+ export { default as WdFormObj } from "./wd-form-obj";
148
+ export { default as WdFormArr } from "./wd-form-arr";
146
149
  export { default as WdRating } from "./wd-rating";
150
+ export { default as WdCascader } from "./wd-cascader";
147
151
  export { default as FormDetail, default as WdFormDetail } from "./formdetail";
148
152
  export { default as WdTagSelect, WdTag } from "./wd-tag";
@@ -189,6 +189,9 @@ export { default as WdTabBar } from './wd-tabbar';
189
189
  export { default as WdUnifiedLink } from './wd-unified-link';
190
190
  export { default as WdProgress } from './wd-progress';
191
191
  export { default as WdDepartment } from './wd-department';
192
+ export const WdCodeEditor = loadable(() => import('./wd-code-editor'), {
193
+ fallback,
194
+ });
192
195
  export const WdMember = loadable(() => import('./wd-member'), {
193
196
  fallback,
194
197
  });
@@ -200,4 +203,7 @@ export const WdRichText = loadable(() => import('./wd-rich-text'), {
200
203
  });
201
204
  export { default as WdCanvas } from './wd-canvas';
202
205
  export { default as WdAudio } from './wd-audio';
206
+ export { default as WdFormObj } from './wd-form-obj';
207
+ export { default as WdFormArr } from './wd-form-arr';
203
208
  export { default as WdRating } from './wd-rating';
209
+ export { default as WdCascader } from './wd-cascader';
@@ -94,7 +94,8 @@
94
94
  background-color: #f5f7fa;
95
95
  }
96
96
  .weda-RichTextView table td {
97
- background-color: white;
97
+ background-color: #ffffff;
98
+ text-align: center;
98
99
  }
99
100
  .weda-RichTextView table th > p,
100
101
  .weda-RichTextView table td > p {
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { WdCascaderProps } from './interface';
3
+ /**
4
+ * 级联选择-标准化
5
+ */
6
+ export declare const WdCascader: React.ForwardRefExoticComponent<WdCascaderProps & React.RefAttributes<any>>;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function CascaderH5(props: any): JSX.Element;
@@ -0,0 +1,132 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /* eslint-disable @typescript-eslint/no-magic-numbers */
3
+ import { useState, useRef, useEffect } from 'react';
4
+ import { useConfig } from '../../utils/config-context';
5
+ import { Modal } from '../wd-date/elements/Modal.h5';
6
+ import { noop } from '../../utils/constant';
7
+ import { WdTabs } from '../wd-tabs';
8
+ import { WdIcon } from '../wd-icon';
9
+ import classNames from '../../utils/classnames';
10
+ import isObjectEqual from '../../utils/isObjectEqual';
11
+ import { getSelectedOptions, transformTabData, setSelectedValue, initTabData, initListOptions, } from './utils';
12
+ const placeholderItem = {
13
+ label: '请选择',
14
+ value: '__placeholderItem',
15
+ selected: true,
16
+ };
17
+ const SingleCascaderView = ({ tabData, listOptions, style, handleTabClick, handleListOptionsClick, }) => {
18
+ const { classPrefix } = useConfig();
19
+ return (_jsxs(_Fragment, { children: [_jsx(WdTabs, { isMultipleSlot: false, selectedIndex: 0, tabsDatas: tabData, events: {
20
+ change: ({ value }) => {
21
+ handleTabClick(value);
22
+ },
23
+ tap: () => { },
24
+ }, direction: 'horizontal' }), _jsx("ul", { className: `${classPrefix}-cascader-h5-view-list`, style: style, children: listOptions.map((i) => {
25
+ return (_jsxs("li", { className: classNames({
26
+ [`${classPrefix}-cascader-h5-view-list__menu`]: true,
27
+ 'is-selected': i.selected,
28
+ 'is-disabled': i.disabled,
29
+ }), onClick: () => {
30
+ handleListOptionsClick(i);
31
+ }, children: [_jsx("span", { className: `${classPrefix}-cascader-h5-view-list__menu__text`, children: i === null || i === void 0 ? void 0 : i.label }), i.selected && _jsx(WdIcon, { name: 'td:check', size: 'md' })] }, i.value));
32
+ }) })] }));
33
+ };
34
+ export function CascaderH5(props) {
35
+ const { placeholder, inputId, name, disabled, value: _value, onChange = noop, data: _data, readValue, searchable = false, } = props;
36
+ const [visible, setVisible] = useState(false);
37
+ const { classPrefix } = useConfig();
38
+ const inputCls = `${classPrefix}-form-select_input`;
39
+ const focusRef = useRef();
40
+ const [inputFocus, setInputFocus] = useState(false);
41
+ const [searchValue, setSearchValue] = useState('');
42
+ const data = transformTabData(_data);
43
+ const [tabData, setTabData] = useState(initTabData(data, _value, placeholderItem));
44
+ const [listOptions, setListOptions] = useState(initListOptions(data, _value));
45
+ const pickerValueRef = useRef(_value); // 弹窗中临时值
46
+ const handleOk = () => {
47
+ const value = tabData
48
+ .map((item) => item.value)
49
+ .filter((i) => i !== '__placeholderItem');
50
+ const options = value.map((i) => getSelectedOptions(_data, i));
51
+ onChange(value, { options });
52
+ setVisible(false);
53
+ };
54
+ const handleClick = () => {
55
+ if (disabled)
56
+ return;
57
+ setVisible(true);
58
+ };
59
+ // 搜索框
60
+ // TODO: 暂时不支持搜索
61
+ const renderSearch = () => {
62
+ return (_jsxs("div", { style: { margin: inputFocus ? '16px 16px 8px 16px' : '8px 16px' }, className: `${classPrefix}-custom-search
63
+ ${inputFocus ? 'is-focused' : ''}`, children: [_jsxs("div", { className: `${classPrefix}-custom-search-box `, "data-testid": `${classPrefix}-custom-search-box`, onClick: () => {
64
+ setInputFocus(true);
65
+ }, children: [inputFocus ? (_jsx("input", { className: `${classPrefix}-input`, ref: focusRef, value: searchValue, autoFocus: true, onChange: (e) => {
66
+ const tValue = e.target.value.trim();
67
+ setSearchValue(tValue);
68
+ } })) : (
69
+ // 此处主要为了兼容 iOS
70
+ _jsx("div", { className: `${classPrefix}-input` })), _jsxs("div", { className: `${classPrefix}-custom-search-box__label`, children: [_jsx("span", { className: `${classPrefix}-custom-search-box__search-icon` }), _jsx("span", { className: `${classPrefix}-custom-search-box__search-placeholder`, children: "\u641C\u7D22" })] }), inputFocus && searchValue !== '' && (_jsx("span", { className: `${classPrefix}-custom-search-box__dismiss-icon`, onClick: () => {
71
+ setSearchValue('');
72
+ } }))] }), _jsx("button", { className: `${classPrefix}-custom-search__btn-cancle`, onClick: () => {
73
+ setInputFocus(false);
74
+ setSearchValue('');
75
+ }, children: "\u53D6\u6D88" })] }));
76
+ };
77
+ // tab 展示值
78
+ const updateTabData = (newTabData, activeItem) => {
79
+ var _a, _b;
80
+ let _activeItem = activeItem;
81
+ // 当前选中值是否存在子选项
82
+ const hasChildItem = (_b = (_a = newTabData[newTabData.length - 1]) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.length;
83
+ let tabData = [...newTabData];
84
+ if (hasChildItem) {
85
+ _activeItem = placeholderItem;
86
+ tabData = [...tabData, placeholderItem];
87
+ }
88
+ const _tabData = setSelectedValue(tabData, _activeItem.value);
89
+ setTabData(_tabData);
90
+ };
91
+ // 点击列表选项
92
+ const handleListOptionsClick = (item) => {
93
+ if (item.disabled)
94
+ return;
95
+ if (item.children) {
96
+ setListOptions([...item.children]);
97
+ }
98
+ else {
99
+ const _listOptions = setSelectedValue(listOptions, item.value);
100
+ setListOptions(_listOptions);
101
+ }
102
+ // 更新tab数据
103
+ const newTabData = [...tabData.filter((i) => i.level < item.level), item];
104
+ updateTabData(newTabData, item);
105
+ };
106
+ // 点击tab项,更新列表选项
107
+ const handleTabClick = (value) => {
108
+ var _a;
109
+ const selectedIndex = tabData.findIndex((i) => i.value === value);
110
+ const selectedItem = tabData[selectedIndex];
111
+ updateTabData(tabData, selectedItem);
112
+ let listOptions = selectedItem.level === 0
113
+ ? data
114
+ : (_a = tabData.find((i) => i.level === selectedIndex - 1)) === null || _a === void 0 ? void 0 : _a.children;
115
+ listOptions = setSelectedValue(listOptions, value);
116
+ setListOptions(listOptions);
117
+ };
118
+ useEffect(() => {
119
+ if (!isObjectEqual(pickerValueRef.current, _value)) {
120
+ pickerValueRef.current = _value;
121
+ setTabData(initTabData(data, _value, placeholderItem));
122
+ setListOptions(initListOptions(data, _value));
123
+ }
124
+ }, [_value, data]);
125
+ return (_jsxs(_Fragment, { children: [_jsx("input", { id: inputId, className: inputCls, type: "text", name: name, placeholder: placeholder, autoComplete: "off", disabled: disabled, readOnly: true, value: readValue, onClick: handleClick }), _jsxs(Modal, { visible: visible, onClose: () => {
126
+ setVisible(false);
127
+ setTabData(initTabData(data, _value, placeholderItem));
128
+ setListOptions(initListOptions(data, _value));
129
+ }, onOk: handleOk, header: inputFocus, className: `${classPrefix}-cascader-modal`, children: [searchable && renderSearch(), _jsx("div", { className: `${classPrefix}-custom-view-content`, children: _jsx(SingleCascaderView, { tabData: tabData, listOptions: listOptions, style: inputFocus
130
+ ? { height: 'calc(100vh - 196px)' }
131
+ : { height: '260px' }, handleTabClick: handleTabClick, handleListOptionsClick: handleListOptionsClick }) })] })] }));
132
+ }
@@ -0,0 +1,97 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { forwardRef, useState, useCallback, useMemo } from 'react';
3
+ import { Cascader, ConfigProvider } from 'tea-component';
4
+ import { useHandleClear, useFixedIcon, SELECT_ICON_H5, SELECT_ICON_PC, } from '../../utils/hooks/useFormLegacy';
5
+ import { useFormInputTrait } from '../../components/form-input-hooks';
6
+ import { WdFormItem, WdInputGroup, WdInputWrap } from '../wd-form-item';
7
+ import { emptyObject } from '../../utils/constant';
8
+ import { usePlatform } from '../../utils/platform';
9
+ import { getUuid } from '../../utils/tool';
10
+ import classNames from '../../utils/classnames';
11
+ import { useDebouncedCallback, useSyncedRef } from '@react-hookz/web';
12
+ import { useSetWidgetApi } from '../../utils/widget-api/use-set-widget-api';
13
+ import { useDelayEvents } from '../../utils/hooks/use-delay-events';
14
+ import { X_RUNTIME_DEFAULT } from '../../../configs/type-utils/x-runtime-default';
15
+ import { CascaderH5 } from './cascader.h5';
16
+ import { getSelectedOptions } from './utils';
17
+ /**
18
+ * 级联选择-标准化
19
+ */
20
+ export const WdCascader = forwardRef(function WdCascader(props, ref) {
21
+ const { classRoot = 'cascader', clearable = X_RUNTIME_DEFAULT.clearable, placeholder, data, events = emptyObject, size, multiple, } = props;
22
+ const platform = usePlatform();
23
+ const [innerHandle, setInnerHandle] = useState({});
24
+ const inputId = useMemo(() => getUuid(), []);
25
+ const traitProps = {
26
+ ...props,
27
+ inputRef: ref,
28
+ setInnerHandle,
29
+ };
30
+ const trait = useFormInputTrait(traitProps);
31
+ const { value: _value, onChange, disabled, readOnly, visible } = trait;
32
+ const value = useMemo(() => {
33
+ return _value ? [].concat(_value) : [];
34
+ }, [_value]);
35
+ const [suffixType, suffixIcon] = useFixedIcon({
36
+ type: props.suffixType,
37
+ icon: props.suffixIcon,
38
+ iconH5: SELECT_ICON_H5,
39
+ iconPc: SELECT_ICON_PC,
40
+ });
41
+ const delayEvents = useDelayEvents(events);
42
+ const [selectedOptions, setSelectedOptions] = useState(value === null || value === void 0 ? void 0 : value.map((i) => getSelectedOptions(data, i)));
43
+ const readValue = useMemo(() => { var _a; return ((_a = selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.map((i) => i === null || i === void 0 ? void 0 : i.label)) === null || _a === void 0 ? void 0 : _a.join(' / ')) || value; }, [selectedOptions, value]);
44
+ const onClearChange = useCallback((v) => {
45
+ var _a;
46
+ setSelectedOptions([]);
47
+ onChange === null || onChange === void 0 ? void 0 : onChange(v);
48
+ (_a = delayEvents === null || delayEvents === void 0 ? void 0 : delayEvents.change) === null || _a === void 0 ? void 0 : _a.call(delayEvents, { value: v });
49
+ }, [onChange, delayEvents]);
50
+ const clearProps = useHandleClear({
51
+ onChange: onClearChange,
52
+ clearable,
53
+ disabled,
54
+ value,
55
+ });
56
+ const formItemProps = {
57
+ ...props,
58
+ ...trait,
59
+ classRoot,
60
+ readValue,
61
+ inputId,
62
+ };
63
+ const inputGroupProps = { ...props, classRoot, readOnly };
64
+ const inputWrapProps = {
65
+ ...props,
66
+ classRoot,
67
+ disabled,
68
+ readOnly,
69
+ suffixType,
70
+ suffixIcon,
71
+ ...clearProps,
72
+ };
73
+ const sizeClassName = classNames({
74
+ [`size-${size}`]: size,
75
+ });
76
+ useSetWidgetApi(() => ({
77
+ ...innerHandle,
78
+ selectedOptions,
79
+ value,
80
+ }), [innerHandle, selectedOptions, value], ref);
81
+ const eventsRef = useSyncedRef(delayEvents);
82
+ const debouncedTriggerSearchEvent = useDebouncedCallback((value) => {
83
+ eventsRef.current.search({ value });
84
+ }, [eventsRef],
85
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
86
+ 300);
87
+ const onSearchValueInput = React.useCallback((v) => {
88
+ debouncedTriggerSearchEvent(v);
89
+ }, [debouncedTriggerSearchEvent]);
90
+ const handleChange = (v, { options }) => {
91
+ setSelectedOptions(options);
92
+ onChange === null || onChange === void 0 ? void 0 : onChange(v);
93
+ };
94
+ if (!visible)
95
+ return null;
96
+ return (_jsx(WdFormItem, { ...formItemProps, children: _jsx(WdInputGroup, { ...inputGroupProps, children: _jsx(WdInputWrap, { ...inputWrapProps, children: _jsx(ConfigProvider, { classPrefix: "wd", children: platform === 'h5' ? (_jsx(CascaderH5, { inputId: inputId, name: props.name, data: data, multiple: multiple, onChange: handleChange, value: value !== null && value !== void 0 ? value : [], placeholder: placeholder, onSearch: onSearchValueInput, disabled: disabled || readOnly, readValue: readValue })) : (_jsx(Cascader, { clearable: true, className: sizeClassName, type: "menu", expandTrigger: "hover", data: data, multiple: multiple, onChange: handleChange, value: value !== null && value !== void 0 ? value : [], defaultValue: value !== null && value !== void 0 ? value : [], placeholder: placeholder, onSearch: onSearchValueInput, disabled: disabled || readOnly })) }) }) }) }));
97
+ });
@@ -0,0 +1,4 @@
1
+ import { WdCascader } from './cascader';
2
+ export { WdCascader } from './cascader';
3
+ export { type WdCascaderProps } from './interface';
4
+ export default WdCascader;
@@ -0,0 +1,3 @@
1
+ import { WdCascader } from './cascader';
2
+ export { WdCascader } from './cascader';
3
+ export default WdCascader;
@@ -0,0 +1,26 @@
1
+ import type { Except } from 'type-fest';
2
+ import type { DataType } from '../../../configs/components/wd-cascader';
3
+ import type { CommonPropsType } from '../../types';
4
+ export interface WdCascaderProps extends CommonPropsType, Except<DataType, 'multiple'> {
5
+ classRoot?: string;
6
+ multiple?: false;
7
+ }
8
+ export interface ICascaderItem {
9
+ label: string;
10
+ value: string;
11
+ selected?: boolean;
12
+ children?: ICascaderItem[];
13
+ level?: number;
14
+ pid?: string;
15
+ disabled?: boolean;
16
+ option?: ICascaderItem[];
17
+ }
18
+ export interface ISingleCascaderViewProps {
19
+ tabData: ICascaderItem[];
20
+ listOptions: ICascaderItem[];
21
+ style: any;
22
+ handleTabClick: (arg: {
23
+ value: string;
24
+ }) => void;
25
+ handleListOptionsClick: (arg: ICascaderItem) => void;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { ICascaderItem } from './interface';
2
+ export declare const getSelectedOptions: (data: any, value: any) => any;
3
+ export declare const transformTabData: (data: any, pid?: string, level?: number) => ICascaderItem[];
4
+ export declare const setSelectedValue: (data: any, value: any) => any[];
5
+ export declare const initTabData: (data: any, value: any, placeholderItem: any) => any[];
6
+ export declare const initListOptions: (data: any, value: any) => any;
@@ -0,0 +1,63 @@
1
+ /* eslint-disable @typescript-eslint/no-magic-numbers */
2
+ import { deepClone } from '../../utils/tool';
3
+ // 获取选中项
4
+ export const getSelectedOptions = (data, value) => {
5
+ for (const i of data) {
6
+ if (i.value === value)
7
+ return i;
8
+ if (i.children) {
9
+ const res = getSelectedOptions(i.children, value);
10
+ if (res)
11
+ return res;
12
+ }
13
+ }
14
+ };
15
+ // 组装tab数据
16
+ export const transformTabData = (data, pid = 'root', level = 0) => {
17
+ if (!Array.isArray(data))
18
+ return [];
19
+ return data.map((_item) => {
20
+ const item = deepClone(_item);
21
+ if (item.children) {
22
+ item.children = transformTabData(item.children, item.value, level + 1);
23
+ }
24
+ return { ...item, level, selected: false, pid };
25
+ });
26
+ };
27
+ // 设置选中值
28
+ export const setSelectedValue = (data, value) => {
29
+ if (!Array.isArray(data))
30
+ return [];
31
+ const _value = [].concat(value);
32
+ return data.map((item) => {
33
+ item.selected = !!_value.find((i) => i === (item === null || item === void 0 ? void 0 : item.value));
34
+ if (item.children) {
35
+ item.children = setSelectedValue(item.children, value);
36
+ }
37
+ return item;
38
+ });
39
+ };
40
+ export const initTabData = (data, value, placeholderItem) => {
41
+ if (!Array.isArray(data))
42
+ return [];
43
+ let tabDataRes = [placeholderItem];
44
+ if (value.length) {
45
+ const selectedOptions = (value === null || value === void 0 ? void 0 : value.map((i) => getSelectedOptions(data, i))) || [];
46
+ const selectedItem = selectedOptions[selectedOptions.length - 1];
47
+ tabDataRes = setSelectedValue(selectedOptions, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value);
48
+ }
49
+ return tabDataRes;
50
+ };
51
+ export const initListOptions = (data, value) => {
52
+ var _a;
53
+ if (!Array.isArray(data))
54
+ return [];
55
+ let listOptionsRes = deepClone(data);
56
+ if (value.length) {
57
+ const selectedOptions = (value === null || value === void 0 ? void 0 : value.map((i) => getSelectedOptions(data, i))) || [];
58
+ const selectedItem = selectedOptions[selectedOptions.length - 1];
59
+ listOptionsRes =
60
+ ((_a = getSelectedOptions(data, selectedItem.pid)) === null || _a === void 0 ? void 0 : _a.children) || data;
61
+ }
62
+ return listOptionsRes;
63
+ };
@@ -0,0 +1,3 @@
1
+ import { WdCodeEditor } from './wd-code-editor';
2
+ export { WdCodeEditor, type WdCodeEditorProps } from './wd-code-editor';
3
+ export default WdCodeEditor;
@@ -0,0 +1,3 @@
1
+ import { WdCodeEditor } from './wd-code-editor';
2
+ export { WdCodeEditor } from './wd-code-editor';
3
+ export default WdCodeEditor;
@@ -0,0 +1,17 @@
1
+ import { javascript } from '@codemirror/lang-javascript';
2
+ import { sql } from '@codemirror/lang-sql';
3
+ import { mongodb } from './mongodb';
4
+ export declare const langs: {
5
+ javascript: typeof javascript;
6
+ jsx: () => import("@codemirror/language").LanguageSupport;
7
+ typescript: () => import("@codemirror/language").LanguageSupport;
8
+ tsx: () => import("@codemirror/language").LanguageSupport;
9
+ mongodb: typeof mongodb;
10
+ sql: typeof sql;
11
+ mysql: () => import("@codemirror/language").LanguageSupport;
12
+ };
13
+ /** Language list */
14
+ export declare const langNames: ("javascript" | "typescript" | "mongodb" | "sql" | "mysql" | "jsx" | "tsx")[];
15
+ export type LanguageName = keyof typeof langs;
16
+ export declare function loadLanguage(name: LanguageName): import("@codemirror/language").LanguageSupport;
17
+ export declare function format(value: any): Promise<any>;