amis 1.5.4 → 1.5.6-beta.5

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 (231) hide show
  1. package/lib/Root.js +1 -1
  2. package/lib/Root.js.map +2 -2
  3. package/lib/RootRenderer.d.ts +1 -1
  4. package/lib/RootRenderer.js +4 -3
  5. package/lib/RootRenderer.js.map +2 -2
  6. package/lib/Schema.d.ts +1 -1
  7. package/lib/Schema.js.map +1 -1
  8. package/lib/SchemaRenderer.js +4 -4
  9. package/lib/SchemaRenderer.js.map +2 -2
  10. package/lib/components/AsideNav.d.ts +1 -1
  11. package/lib/components/AsideNav.js.map +1 -1
  12. package/lib/components/Card.d.ts +20 -20
  13. package/lib/components/CodeMirror.d.ts +26 -0
  14. package/lib/components/CodeMirror.js +104 -0
  15. package/lib/components/CodeMirror.js.map +13 -0
  16. package/lib/components/Collapse.d.ts +22 -21
  17. package/lib/components/Collapse.js +4 -6
  18. package/lib/components/Collapse.js.map +2 -2
  19. package/lib/components/CollapseGroup.d.ts +20 -20
  20. package/lib/components/CollapseGroup.js +5 -3
  21. package/lib/components/CollapseGroup.js.map +2 -2
  22. package/lib/components/ColorPicker.d.ts +85 -84
  23. package/lib/components/ColorPicker.js +15 -3
  24. package/lib/components/ColorPicker.js.map +2 -2
  25. package/lib/components/DatePicker.d.ts +84 -84
  26. package/lib/components/DatePicker.js +7 -3
  27. package/lib/components/DatePicker.js.map +2 -2
  28. package/lib/components/DateRangePicker.d.ts +85 -84
  29. package/lib/components/DateRangePicker.js +5 -3
  30. package/lib/components/DateRangePicker.js.map +2 -2
  31. package/lib/components/LocationPicker.d.ts +84 -84
  32. package/lib/components/MonthRangePicker.d.ts +85 -84
  33. package/lib/components/MonthRangePicker.js +5 -3
  34. package/lib/components/MonthRangePicker.js.map +2 -2
  35. package/lib/components/PickerContainer.d.ts +2 -1
  36. package/lib/components/PickerContainer.js +3 -3
  37. package/lib/components/PickerContainer.js.map +2 -2
  38. package/lib/components/PopUp.d.ts +93 -0
  39. package/lib/components/PopUp.js +58 -0
  40. package/lib/components/PopUp.js.map +13 -0
  41. package/lib/components/Progress.js +1 -1
  42. package/lib/components/Progress.js.map +2 -2
  43. package/lib/components/Select.d.ts +237 -237
  44. package/lib/components/Steps.d.ts +1 -0
  45. package/lib/components/Steps.js +5 -3
  46. package/lib/components/Steps.js.map +2 -2
  47. package/lib/components/Tabs.d.ts +20 -20
  48. package/lib/components/TabsTransferPicker.js +1 -1
  49. package/lib/components/TabsTransferPicker.js.map +2 -2
  50. package/lib/components/TransferPicker.d.ts +0 -1
  51. package/lib/components/TransferPicker.js +2 -15
  52. package/lib/components/TransferPicker.js.map +2 -2
  53. package/lib/components/formula/Editor.d.ts +560 -0
  54. package/lib/components/formula/Editor.js +186 -0
  55. package/lib/components/formula/Editor.js.map +13 -0
  56. package/lib/components/formula/FuncList.d.ts +67 -0
  57. package/lib/components/formula/FuncList.js +35 -0
  58. package/lib/components/formula/FuncList.js.map +13 -0
  59. package/lib/components/formula/Picker.d.ts +493 -0
  60. package/lib/components/formula/Picker.js +48 -0
  61. package/lib/components/formula/Picker.js.map +13 -0
  62. package/lib/components/formula/VariableList.d.ts +9 -0
  63. package/lib/components/formula/VariableList.js +15 -0
  64. package/lib/components/formula/VariableList.js.map +13 -0
  65. package/lib/components/formula/plugin.d.ts +18 -0
  66. package/lib/components/formula/plugin.js +136 -0
  67. package/lib/components/formula/plugin.js.map +13 -0
  68. package/lib/components/index.d.ts +2 -1
  69. package/lib/components/index.js +4 -2
  70. package/lib/components/index.js.map +2 -2
  71. package/lib/helper.css +57 -57
  72. package/lib/helper.css.map +1 -1
  73. package/lib/index.d.ts +1 -0
  74. package/lib/index.js +2 -1
  75. package/lib/index.js.map +2 -2
  76. package/lib/renderers/CRUD.d.ts +1 -1
  77. package/lib/renderers/CRUD.js +4 -3
  78. package/lib/renderers/CRUD.js.map +2 -2
  79. package/lib/renderers/Collapse.js +8 -2
  80. package/lib/renderers/Collapse.js.map +2 -2
  81. package/lib/renderers/CollapseGroup.js.map +2 -2
  82. package/lib/renderers/Dialog.d.ts +2 -2
  83. package/lib/renderers/Dialog.js +7 -7
  84. package/lib/renderers/Dialog.js.map +2 -2
  85. package/lib/renderers/Drawer.js +2 -2
  86. package/lib/renderers/Drawer.js.map +2 -2
  87. package/lib/renderers/Form/InputCity.d.ts +84 -84
  88. package/lib/renderers/Form/InputColor.d.ts +84 -84
  89. package/lib/renderers/Form/InputColor.js +2 -2
  90. package/lib/renderers/Form/InputColor.js.map +2 -2
  91. package/lib/renderers/Form/InputDate.js +2 -2
  92. package/lib/renderers/Form/InputDate.js.map +2 -2
  93. package/lib/renderers/Form/InputDateRange.js +2 -2
  94. package/lib/renderers/Form/InputDateRange.js.map +2 -2
  95. package/lib/renderers/Form/InputFile.js +1 -1
  96. package/lib/renderers/Form/InputFile.js.map +2 -2
  97. package/lib/renderers/Form/InputFormula.d.ts +35 -0
  98. package/lib/renderers/Form/InputFormula.js +25 -0
  99. package/lib/renderers/Form/InputFormula.js.map +13 -0
  100. package/lib/renderers/Form/InputImage.js +1 -1
  101. package/lib/renderers/Form/InputImage.js.map +2 -2
  102. package/lib/renderers/Form/InputMonthRange.js +2 -2
  103. package/lib/renderers/Form/InputMonthRange.js.map +2 -2
  104. package/lib/renderers/Form/InputQuarterRange.js +2 -2
  105. package/lib/renderers/Form/InputQuarterRange.js.map +2 -2
  106. package/lib/renderers/Form/InputYearRange.js +2 -2
  107. package/lib/renderers/Form/InputYearRange.js.map +2 -2
  108. package/lib/renderers/Form/Item.d.ts +1 -1
  109. package/lib/renderers/Form/Item.js +4 -3
  110. package/lib/renderers/Form/Item.js.map +2 -2
  111. package/lib/renderers/Form/TreeSelect.d.ts +1 -0
  112. package/lib/renderers/Form/TreeSelect.js +11 -8
  113. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  114. package/lib/renderers/Form/index.d.ts +1 -1
  115. package/lib/renderers/Form/index.js +3 -2
  116. package/lib/renderers/Form/index.js.map +2 -2
  117. package/lib/renderers/Page.d.ts +3 -3
  118. package/lib/renderers/Page.js +4 -3
  119. package/lib/renderers/Page.js.map +2 -2
  120. package/lib/renderers/Steps.js +2 -2
  121. package/lib/renderers/Steps.js.map +2 -2
  122. package/lib/renderers/Wizard.d.ts +1 -1
  123. package/lib/renderers/Wizard.js +93 -36
  124. package/lib/renderers/Wizard.js.map +2 -2
  125. package/lib/store/formItem.js +11 -1
  126. package/lib/store/formItem.js.map +2 -2
  127. package/lib/themes/ang-ie11.css +261 -0
  128. package/lib/themes/ang.css +261 -0
  129. package/lib/themes/ang.css.map +1 -1
  130. package/lib/themes/antd-ie11.css +261 -0
  131. package/lib/themes/antd.css +261 -0
  132. package/lib/themes/antd.css.map +1 -1
  133. package/lib/themes/cxd-ie11.css +261 -0
  134. package/lib/themes/cxd.css +261 -0
  135. package/lib/themes/cxd.css.map +1 -1
  136. package/lib/themes/dark-ie11.css +261 -0
  137. package/lib/themes/dark.css +261 -0
  138. package/lib/themes/dark.css.map +1 -1
  139. package/lib/themes/default.css +261 -0
  140. package/lib/themes/default.css.map +1 -1
  141. package/lib/utils/api.js +2 -2
  142. package/lib/utils/api.js.map +2 -2
  143. package/lib/utils/helper.js +2 -7
  144. package/lib/utils/helper.js.map +2 -2
  145. package/package.json +5 -3
  146. package/scss/_variables.scss +1 -1
  147. package/scss/components/_formula.scss +122 -0
  148. package/scss/components/_popup.scss +123 -0
  149. package/scss/components/_steps.scss +60 -0
  150. package/scss/components/form/_color.scss +4 -0
  151. package/scss/components/form/_date-range.scss +4 -0
  152. package/scss/components/form/_date.scss +3 -0
  153. package/scss/components/form/_tree-select.scss +4 -0
  154. package/scss/helper/background/_background-color.scss +1 -1
  155. package/scss/helper/border/_border-color.scss +1 -1
  156. package/scss/helper/typography/_text-color.scss +1 -1
  157. package/scss/themes/_common.scss +2 -0
  158. package/sdk/ang-ie11.css +875 -0
  159. package/sdk/ang.css +875 -0
  160. package/sdk/antd-ie11.css +875 -0
  161. package/sdk/antd.css +875 -0
  162. package/sdk/charts.js +18 -18
  163. package/sdk/codemirror.js +14 -0
  164. package/sdk/color-picker.js +65 -65
  165. package/sdk/cropperjs.js +3 -3
  166. package/sdk/cxd-ie11.css +875 -0
  167. package/sdk/cxd.css +875 -0
  168. package/sdk/dark-ie11.css +875 -0
  169. package/sdk/dark.css +875 -0
  170. package/sdk/exceljs.js +1 -1
  171. package/sdk/helper.css +57 -57
  172. package/sdk/helper.css.map +1 -1
  173. package/sdk/markdown.js +69 -69
  174. package/sdk/papaparse.js +1 -1
  175. package/sdk/renderers/Form/CityDB.js +1 -1
  176. package/sdk/rest.js +18 -18
  177. package/sdk/rich-text.js +62 -62
  178. package/sdk/sdk-ie11.css +875 -0
  179. package/sdk/sdk.css +875 -0
  180. package/sdk/sdk.js +1315 -1207
  181. package/sdk/thirds/hls.js/hls.js +18 -18
  182. package/sdk/thirds/mpegts.js/mpegts.js +2 -2
  183. package/sdk/tinymce.js +57 -57
  184. package/src/Root.tsx +1 -0
  185. package/src/RootRenderer.tsx +3 -3
  186. package/src/Schema.ts +1 -0
  187. package/src/SchemaRenderer.tsx +4 -0
  188. package/src/components/AsideNav.tsx +1 -1
  189. package/src/components/CodeMirror.tsx +99 -0
  190. package/src/components/Collapse.tsx +21 -13
  191. package/src/components/CollapseGroup.tsx +9 -11
  192. package/src/components/ColorPicker.tsx +45 -3
  193. package/src/components/DatePicker.tsx +33 -3
  194. package/src/components/DateRangePicker.tsx +17 -3
  195. package/src/components/MonthRangePicker.tsx +18 -4
  196. package/src/components/PickerContainer.tsx +10 -6
  197. package/src/components/PopUp.tsx +133 -0
  198. package/src/components/Progress.tsx +1 -1
  199. package/src/components/Steps.tsx +8 -3
  200. package/src/components/TabsTransferPicker.tsx +1 -1
  201. package/src/components/TransferPicker.tsx +1 -11
  202. package/src/components/formula/Editor.tsx +261 -0
  203. package/src/components/formula/FuncList.tsx +82 -0
  204. package/src/components/formula/Picker.tsx +86 -0
  205. package/src/components/formula/VariableList.tsx +49 -0
  206. package/src/components/formula/plugin.ts +177 -0
  207. package/src/components/index.tsx +2 -0
  208. package/src/index.tsx +1 -0
  209. package/src/renderers/CRUD.tsx +3 -3
  210. package/src/renderers/Collapse.tsx +27 -27
  211. package/src/renderers/CollapseGroup.tsx +13 -12
  212. package/src/renderers/Dialog.tsx +8 -8
  213. package/src/renderers/Drawer.tsx +2 -2
  214. package/src/renderers/Form/InputColor.tsx +2 -3
  215. package/src/renderers/Form/InputDate.tsx +2 -0
  216. package/src/renderers/Form/InputDateRange.tsx +2 -0
  217. package/src/renderers/Form/InputFile.tsx +1 -1
  218. package/src/renderers/Form/InputFormula.tsx +75 -0
  219. package/src/renderers/Form/InputImage.tsx +1 -1
  220. package/src/renderers/Form/InputMonthRange.tsx +2 -0
  221. package/src/renderers/Form/InputQuarterRange.tsx +2 -0
  222. package/src/renderers/Form/InputYearRange.tsx +2 -0
  223. package/src/renderers/Form/Item.tsx +2 -2
  224. package/src/renderers/Form/TreeSelect.tsx +82 -63
  225. package/src/renderers/Form/index.tsx +2 -2
  226. package/src/renderers/Page.tsx +11 -10
  227. package/src/renderers/Steps.tsx +4 -2
  228. package/src/renderers/Wizard.tsx +52 -12
  229. package/src/store/formItem.ts +15 -0
  230. package/src/utils/api.ts +5 -2
  231. package/src/utils/helper.ts +5 -14
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @file PopUp
3
+ * @description
4
+ * @author fex
5
+ */
6
+
7
+ import React from 'react';
8
+ import {ClassNamesFn, themeable} from '../theme';
9
+ import Transition, {
10
+ ENTERED,
11
+ EXITING,
12
+ EXITED,
13
+ ENTERING
14
+ } from 'react-transition-group/Transition';
15
+ import Portal from 'react-overlays/Portal';
16
+ import { Icon } from './icons';
17
+
18
+
19
+ export interface PopUpPorps {
20
+ className?: string;
21
+ style?: {
22
+ [styleName: string]: string;
23
+ };
24
+ overlay?: boolean;
25
+ onHide?: () => void;
26
+ classPrefix: string;
27
+ classnames: ClassNamesFn;
28
+ [propName: string]: any;
29
+ isShow?: boolean;
30
+ container?: any;
31
+ hideClose?: boolean;
32
+ placement?: 'left' | 'center' | 'right';
33
+ }
34
+
35
+ const fadeStyles: {
36
+ [propName: string]: string;
37
+ } = {
38
+ [ENTERED]: '',
39
+ [EXITING]: 'out',
40
+ [EXITED]: '',
41
+ [ENTERING]: 'in'
42
+ };
43
+ export class PopUp extends React.PureComponent<PopUpPorps> {
44
+ static defaultProps = {
45
+ className: '',
46
+ overlay: true,
47
+ isShow: false,
48
+ container: document.body,
49
+ hideClose: false,
50
+ };
51
+
52
+ componentDidMount() {
53
+
54
+ }
55
+ handleClick(e: React.MouseEvent) {
56
+ e.stopPropagation();
57
+ }
58
+
59
+ render() {
60
+ const {
61
+ style,
62
+ children,
63
+ overlay,
64
+ onHide,
65
+ classPrefix: ns,
66
+ classnames: cx,
67
+ className,
68
+ isShow,
69
+ container,
70
+ hideClose,
71
+ placement='center',
72
+ ...rest
73
+ } = this.props;
74
+
75
+ const outerStyle: any = {
76
+ ...style,
77
+ };
78
+ delete outerStyle.top;
79
+ return (
80
+ <Portal container={container}>
81
+ <Transition
82
+ mountOnEnter
83
+ unmountOnExit
84
+ in={isShow}
85
+ timeout={500}
86
+ appear
87
+ >
88
+ {(status: string) => {
89
+ return (
90
+ <div
91
+ className={cx(
92
+ `${ns}PopUp`,
93
+ className,
94
+ fadeStyles[status]
95
+ )}
96
+ style={outerStyle}
97
+ {...rest}
98
+ onClick={this.handleClick}
99
+ >
100
+ {overlay && (
101
+ <div className={`${ns}PopUp-overlay`} onClick={onHide}/>
102
+ )}
103
+ <div className={cx(
104
+ `${ns}PopUp-inner`
105
+ )}
106
+ >
107
+ {
108
+ !hideClose && (
109
+ <div className={cx(`${ns}PopUp-closeWrap`, 'text-right')}>
110
+ <Icon
111
+ icon="close"
112
+ className={cx('icon', `${ns}PopUp-close`)}
113
+ onClick={onHide}
114
+ />
115
+ </div>
116
+ )
117
+ }
118
+ <div
119
+ className={cx(`${ns}PopUp-content`, `justify-${placement}`)}
120
+ >
121
+ {children}
122
+ </div>
123
+ </div>
124
+ </div>
125
+ )
126
+ }}
127
+ </Transition>
128
+ </Portal>
129
+ )
130
+ }
131
+ }
132
+
133
+ export default themeable(PopUp);
@@ -118,7 +118,7 @@ export class Progress extends React.Component<ProgressProps, Object> {
118
118
  };
119
119
 
120
120
  viewValue = [
121
- <div className={cx(prefixCls)}>
121
+ <div className={cx(prefixCls)} key="circle">
122
122
  <Circle
123
123
  percent={value}
124
124
  strokeColor=""
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import {themeable, ThemeProps} from '../theme';
3
3
  import {Icon} from './icons';
4
4
  import {BaseSchema} from '../Schema';
5
+ import { isMobile } from '../utils/helper';
5
6
 
6
7
  export enum StepStatus {
7
8
  wait = 'wait',
@@ -78,6 +79,7 @@ export interface StepsProps extends ThemeProps {
78
79
  [propName: string]: StepStatus;
79
80
  };
80
81
  mode?: 'horizontal' | 'vertical';
82
+ useMobileUI?: boolean;
81
83
  }
82
84
 
83
85
  export function Steps(props: StepsProps) {
@@ -87,7 +89,8 @@ export function Steps(props: StepsProps) {
87
89
  className,
88
90
  current,
89
91
  status,
90
- mode = 'horizontal'
92
+ mode = 'horizontal',
93
+ useMobileUI
91
94
  } = props;
92
95
  const FINISH_ICON = 'check';
93
96
  const ERROR_ICON = 'close';
@@ -122,8 +125,9 @@ export function Steps(props: StepsProps) {
122
125
  };
123
126
  }
124
127
 
128
+ const mobileUI = useMobileUI && isMobile();
125
129
  return (
126
- <ul className={cx('Steps', `Steps--${mode}`, className)}>
130
+ <ul className={cx('Steps', `Steps--${mode}`, mobileUI ? 'Steps-mobile' : '', className)}>
127
131
  {stepsRow.map((step, i) => {
128
132
  const {stepStatus, icon} = getStepStatus(step, i);
129
133
 
@@ -133,7 +137,8 @@ export function Steps(props: StepsProps) {
133
137
  className={cx('StepsItem', `is-${stepStatus}`, step.className)}
134
138
  >
135
139
  <div className={cx('StepsItem-container')}>
136
- <div className={cx('StepsItem-containerIcon')}>
140
+ <div className={cx('StepsItem-containerIcon',
141
+ i < current && 'is-success')}>
137
142
  <span className={cx('StepsItem-icon')}>
138
143
  {icon ? <Icon icon={icon} className="icon" /> : i + 1}
139
144
  </span>
@@ -44,7 +44,7 @@ export class TransferPicker extends React.Component<TabsTransferPickerProps> {
44
44
  return (
45
45
  <PickerContainer
46
46
  title={__('Select.placeholder')}
47
- popOverRender={({onClose, value, onChange}) => {
47
+ bodyRender={({onClose, value, onChange}) => {
48
48
  return <TabsTransfer {...rest} value={value} onChange={onChange} />;
49
49
  }}
50
50
  value={value}
@@ -19,18 +19,9 @@ export interface TransferPickerProps extends Omit<TransferProps, 'itemRender'> {
19
19
  }
20
20
 
21
21
  export class TransferPicker extends React.Component<TransferPickerProps> {
22
- @autobind
23
- handleClose() {
24
- this.setState({
25
- inputValue: '',
26
- searchResult: null
27
- });
28
- }
29
-
30
22
  @autobind
31
23
  handleConfirm(value: any) {
32
24
  this.props.onChange?.(value);
33
- this.handleClose();
34
25
  }
35
26
 
36
27
  render() {
@@ -49,12 +40,11 @@ export class TransferPicker extends React.Component<TransferPickerProps> {
49
40
  return (
50
41
  <PickerContainer
51
42
  title={__('Select.placeholder')}
52
- popOverRender={({onClose, value, onChange}) => {
43
+ bodyRender={({onClose, value, onChange}) => {
53
44
  return <Transfer {...rest} value={value} onChange={onChange} />;
54
45
  }}
55
46
  value={value}
56
47
  onConfirm={this.handleConfirm}
57
- onCancel={this.handleClose}
58
48
  size={size}
59
49
  >
60
50
  {({onClick, isOpened}) => (
@@ -0,0 +1,261 @@
1
+ /**
2
+ * @file 公式编辑器
3
+ */
4
+ import React from 'react';
5
+ import {uncontrollable} from 'uncontrollable';
6
+ import {FormulaPlugin, editorFactory} from './plugin';
7
+ import {doc} from 'amis-formula/dist/doc';
8
+ import FuncList from './FuncList';
9
+ import {VariableList} from './VariableList';
10
+ import {parse} from 'amis-formula';
11
+ import {autobind} from '../../utils/helper';
12
+ import CodeMirrorEditor from '../CodeMirror';
13
+ import {themeable, ThemeProps} from '../../theme';
14
+ import {localeable, LocaleProps} from '../../locale';
15
+
16
+ export interface VariableItem {
17
+ label: string;
18
+ value?: string;
19
+ children?: Array<VariableItem>;
20
+ selectMode?: 'tree' | 'tabs';
21
+ }
22
+
23
+ export interface FuncGroup {
24
+ groupName: string;
25
+ items: Array<FuncItem>;
26
+ }
27
+
28
+ export interface FuncItem {
29
+ name: string;
30
+ [propName: string]: any;
31
+ }
32
+
33
+ export interface FormulaEditorProps extends ThemeProps, LocaleProps {
34
+ onChange?: (value: string) => void;
35
+ value: string;
36
+ /**
37
+ * evalMode 即直接就是表达式,否则
38
+ * 需要 ${这里面才是表达式}
39
+ * 默认为 true
40
+ */
41
+ evalMode?: boolean;
42
+
43
+ /**
44
+ * 用于提示的变量集合,默认为空
45
+ */
46
+ variables: Array<VariableItem>;
47
+
48
+ variableMode?: 'tabs' | 'tree';
49
+
50
+ /**
51
+ * 函数集合,默认不需要传,即 amis-formula 里面那个函数
52
+ * 如果有扩充,则需要传。
53
+ */
54
+ functions: Array<FuncGroup>;
55
+
56
+ /**
57
+ * 顶部标题,默认为表达式
58
+ */
59
+ header: string;
60
+ }
61
+
62
+ export interface FunctionsProps {
63
+ name: string;
64
+ items: FunctionProps[];
65
+ }
66
+
67
+ export interface FunctionProps {
68
+ name: string;
69
+ intro: string;
70
+ usage: string;
71
+ example: string;
72
+ }
73
+
74
+ export interface FormulaState {
75
+ focused: boolean;
76
+ }
77
+
78
+ export class FormulaEditor extends React.Component<
79
+ FormulaEditorProps,
80
+ FormulaState
81
+ > {
82
+ state: FormulaState = {
83
+ focused: false
84
+ };
85
+ editorPlugin?: FormulaPlugin;
86
+
87
+ static buildDefaultFunctions(
88
+ doc: Array<{
89
+ namespace: string;
90
+ name: string;
91
+ [propName: string]: any;
92
+ }>
93
+ ) {
94
+ const funcs: Array<FuncGroup> = [];
95
+
96
+ doc.forEach(item => {
97
+ const namespace = item.namespace || 'Others';
98
+ let exists = funcs.find(item => item.groupName === namespace);
99
+ if (!exists) {
100
+ exists = {
101
+ groupName: namespace,
102
+ items: []
103
+ };
104
+ funcs.push(exists);
105
+ }
106
+ exists.items.push(item);
107
+ });
108
+
109
+ return funcs;
110
+ }
111
+
112
+ static defaultProps: Pick<
113
+ FormulaEditorProps,
114
+ 'functions' | 'variables' | 'evalMode'
115
+ > = {
116
+ functions: this.buildDefaultFunctions(doc),
117
+ variables: [],
118
+ evalMode: true
119
+ };
120
+
121
+ static highlightValue(
122
+ value: string,
123
+ variables: Array<VariableItem>,
124
+ functions: Array<FuncGroup>
125
+ ) {
126
+ // todo 高亮原始文本
127
+ return value;
128
+ }
129
+
130
+ componentWillUnmount() {
131
+ this.editorPlugin?.dispose();
132
+ }
133
+
134
+ @autobind
135
+ handleFocus() {
136
+ this.setState({
137
+ focused: true
138
+ });
139
+ }
140
+
141
+ @autobind
142
+ handleBlur() {
143
+ this.setState({
144
+ focused: false
145
+ });
146
+ }
147
+
148
+ @autobind
149
+ insertValue(value: any, type: 'variable' | 'func') {
150
+ this.editorPlugin?.insertContent(value, type);
151
+ }
152
+
153
+ @autobind
154
+ handleEditorMounted(cm: any, editor: any) {
155
+ this.editorPlugin = new FormulaPlugin(editor, cm, () => this.props);
156
+ }
157
+
158
+ @autobind
159
+ validate() {
160
+ const value = this.props.value;
161
+
162
+ try {
163
+ value
164
+ ? parse(value, {
165
+ evalMode: this.props.evalMode
166
+ })
167
+ : null;
168
+ } catch (e) {
169
+ return e.message;
170
+ }
171
+
172
+ return;
173
+ }
174
+
175
+ @autobind
176
+ handleFunctionSelect(item: FuncItem) {
177
+ this.editorPlugin?.insertContent(`${item.name}`, 'func');
178
+ }
179
+
180
+ @autobind
181
+ handleVariableSelect(item: VariableItem) {
182
+ this.editorPlugin?.insertContent(
183
+ {
184
+ key: item.value,
185
+ name: item.label
186
+ },
187
+ 'variable'
188
+ );
189
+ }
190
+
191
+ @autobind
192
+ handleOnChange(value: any) {
193
+ const onChange = this.props.onChange;
194
+ onChange?.(value);
195
+ }
196
+
197
+ @autobind
198
+ editorFactory(dom: HTMLElement, cm: any) {
199
+ return editorFactory(dom, cm, this.props);
200
+ }
201
+
202
+ render() {
203
+ const {
204
+ variables,
205
+ header,
206
+ value,
207
+ functions,
208
+ variableMode,
209
+ classnames: cx
210
+ } = this.props;
211
+ const {focused} = this.state;
212
+
213
+ return (
214
+ <div
215
+ className={cx(`FormulaEditor`, {
216
+ 'is-focused': focused
217
+ })}
218
+ >
219
+ <div className={cx(`FormulaEditor-header`)}>{header ?? '表达式'}</div>
220
+
221
+ <CodeMirrorEditor
222
+ className={cx('FormulaEditor-editor')}
223
+ value={value}
224
+ onChange={this.handleOnChange}
225
+ editorFactory={this.editorFactory}
226
+ editorDidMount={this.handleEditorMounted}
227
+ onFocus={this.handleFocus}
228
+ onBlur={this.handleBlur}
229
+ ></CodeMirrorEditor>
230
+
231
+ <div className={cx('FormulaEditor-settings')}>
232
+ {Array.isArray(functions) && functions.length ? (
233
+ <div>
234
+ <h3>变量</h3>
235
+ <VariableList
236
+ className={cx('VariableList')}
237
+ selectMode={variableMode}
238
+ data={variables}
239
+ onSelect={this.handleVariableSelect}
240
+ />
241
+ </div>
242
+ ) : null}
243
+ {Array.isArray(variables) && variables.length ? (
244
+ <div>
245
+ <h3>函数</h3>
246
+ <FuncList data={functions} onSelect={this.handleFunctionSelect} />
247
+ </div>
248
+ ) : null}
249
+ </div>
250
+ </div>
251
+ );
252
+ }
253
+ }
254
+
255
+ export default uncontrollable(
256
+ themeable(localeable(FormulaEditor)),
257
+ {
258
+ value: 'onChange'
259
+ },
260
+ ['validate']
261
+ );
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import {themeable, ThemeProps} from '../../theme';
3
+ import Collapse from '../Collapse';
4
+ import CollapseGroup from '../CollapseGroup';
5
+ import SearchBox from '../SearchBox';
6
+ import type {FuncGroup, FuncItem} from './Editor';
7
+
8
+ export interface FuncListProps extends ThemeProps {
9
+ data: Array<FuncGroup>;
10
+ onSelect?: (item: FuncItem) => void;
11
+ }
12
+
13
+ export function FuncList(props: FuncListProps) {
14
+ const cx = props.classnames;
15
+ const [filteredFuncs, setFiteredFuncs] = React.useState(props.data);
16
+ const [activeFunc, setActiveFunc] = React.useState<any>(null);
17
+ function onSearch(term: string) {
18
+ const filtered = props.data
19
+ .map(item => {
20
+ return {
21
+ ...item,
22
+ items: term
23
+ ? item.items.filter(item => ~item.name.indexOf(term.toUpperCase()))
24
+ : item.items
25
+ };
26
+ })
27
+ .filter(item => item.items.length);
28
+ setFiteredFuncs(filtered);
29
+ }
30
+
31
+ return (
32
+ <div className={cx('FormulaFuncList')}>
33
+ <SearchBox
34
+ className="FormulaFuncList-searchBox"
35
+ mini={false}
36
+ onSearch={onSearch}
37
+ />
38
+ <div className={cx('FormulaFuncList-columns')}>
39
+ <CollapseGroup
40
+ className="FormulaFuncList-group"
41
+ defaultActiveKey={filteredFuncs[0]?.groupName}
42
+ accordion
43
+ >
44
+ {filteredFuncs.map(item => (
45
+ <Collapse
46
+ headingClassName="FormulaFuncList-groupTitle"
47
+ bodyClassName="FormulaFuncList-groupBody"
48
+ propKey={item.groupName}
49
+ header={item.groupName}
50
+ key={item.groupName}
51
+ >
52
+ {item.items.map(item => (
53
+ <div
54
+ className={cx(
55
+ `FormulaFuncList-funcItem ${
56
+ item.name === activeFunc?.name ? 'is-active' : ''
57
+ }`
58
+ )}
59
+ onMouseEnter={() => setActiveFunc(item)}
60
+ onClick={() => props.onSelect?.(item)}
61
+ key={item.name}
62
+ >
63
+ {item.name}
64
+ </div>
65
+ ))}
66
+ </Collapse>
67
+ ))}
68
+ </CollapseGroup>
69
+ <div className={cx('FormulaFuncList-column')}>
70
+ {activeFunc ? (
71
+ <div className={cx('FormulaFuncList-funcDetail')}>
72
+ <p>{activeFunc.example}</p>
73
+ <div>{activeFunc.description}</div>
74
+ </div>
75
+ ) : null}
76
+ </div>
77
+ </div>
78
+ </div>
79
+ );
80
+ }
81
+
82
+ export default themeable(FuncList);
@@ -0,0 +1,86 @@
1
+ import {uncontrollable} from 'uncontrollable';
2
+ import React from 'react';
3
+ import {FormulaEditor, FormulaEditorProps} from './Editor';
4
+ import {autobind} from '../../utils/helper';
5
+ import PickerContainer from '../PickerContainer';
6
+ import Editor from './Editor';
7
+ import ResultBox from '../ResultBox';
8
+ import {Icon} from '../icons';
9
+ import {themeable} from '../../theme';
10
+ import {localeable} from '../../locale';
11
+
12
+ export interface FormulaPickerProps extends FormulaEditorProps {
13
+ // 新的属性?
14
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
15
+
16
+ /**
17
+ * 边框模式,全边框,还是半边框,或者没边框。
18
+ */
19
+ borderMode?: 'full' | 'half' | 'none';
20
+
21
+ disabled?: boolean;
22
+ }
23
+
24
+ export class FormulaPicker extends React.Component<FormulaPickerProps> {
25
+ @autobind
26
+ handleConfirm(value: any) {
27
+ this.props.onChange?.(value);
28
+ }
29
+
30
+ render() {
31
+ const {
32
+ classnames: cx,
33
+ value,
34
+ translate: __,
35
+ disabled,
36
+ className,
37
+ onChange,
38
+ size,
39
+ borderMode,
40
+ ...rest
41
+ } = this.props;
42
+
43
+ return (
44
+ <PickerContainer
45
+ showTitle={false}
46
+ bodyRender={({onClose, value, onChange}) => {
47
+ return <Editor {...rest} value={value} onChange={onChange} />;
48
+ }}
49
+ value={value}
50
+ onConfirm={this.handleConfirm}
51
+ size={'md'}
52
+ >
53
+ {({onClick, isOpened}) => (
54
+ <ResultBox
55
+ className={cx(
56
+ 'FormulaPicker',
57
+ className,
58
+ isOpened ? 'is-active' : ''
59
+ )}
60
+ allowInput={false}
61
+ result={FormulaEditor.highlightValue(
62
+ value,
63
+ rest.variables,
64
+ rest.functions
65
+ )}
66
+ onResultClick={onClick}
67
+ disabled={disabled}
68
+ borderMode={borderMode}
69
+ >
70
+ <span className={cx('FormulaPicker-icon')}>
71
+ <Icon icon="pencil" className="icon" />
72
+ </span>
73
+ </ResultBox>
74
+ )}
75
+ </PickerContainer>
76
+ );
77
+ }
78
+ }
79
+
80
+ export default themeable(
81
+ localeable(
82
+ uncontrollable(FormulaPicker, {
83
+ value: 'onChange'
84
+ })
85
+ )
86
+ );
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import GroupedSelection from '../GroupedSelection';
3
+ import Tabs, {Tab} from '../Tabs';
4
+ import TreeSelection from '../TreeSelection';
5
+ import type {VariableItem} from './Editor';
6
+
7
+ export interface VariableListProps {
8
+ className?: string;
9
+ data: Array<VariableItem>;
10
+ selectMode?: 'list' | 'tree' | 'tabs';
11
+ onSelect?: (item: VariableItem) => void;
12
+ }
13
+
14
+ export function VariableList({
15
+ data: list,
16
+ className,
17
+ selectMode,
18
+ onSelect
19
+ }: VariableListProps) {
20
+ return (
21
+ <div className={className}>
22
+ {selectMode === 'tabs' ? (
23
+ <Tabs tabsMode="radio">
24
+ {list.map((item, index) => (
25
+ <Tab eventKey={index} key={index} title={item.label}>
26
+ <VariableList
27
+ selectMode={item.selectMode}
28
+ data={item.children!}
29
+ onSelect={onSelect}
30
+ />
31
+ </Tab>
32
+ ))}
33
+ </Tabs>
34
+ ) : selectMode === 'tree' ? (
35
+ <TreeSelection
36
+ multiple={false}
37
+ options={list}
38
+ onChange={(item: any) => onSelect?.(item)}
39
+ />
40
+ ) : (
41
+ <GroupedSelection
42
+ multiple={false}
43
+ options={list}
44
+ onChange={(item: any) => onSelect?.(item)}
45
+ />
46
+ )}
47
+ </div>
48
+ );
49
+ }