amis 1.5.6-beta.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 (159) hide show
  1. package/lib/Schema.d.ts +1 -1
  2. package/lib/Schema.js.map +1 -1
  3. package/lib/components/AsideNav.d.ts +1 -1
  4. package/lib/components/AsideNav.js.map +1 -1
  5. package/lib/components/CodeMirror.d.ts +26 -0
  6. package/lib/components/CodeMirror.js +104 -0
  7. package/lib/components/CodeMirror.js.map +13 -0
  8. package/lib/components/Collapse.d.ts +22 -21
  9. package/lib/components/Collapse.js.map +2 -2
  10. package/lib/components/ColorPicker.d.ts +85 -84
  11. package/lib/components/ColorPicker.js +15 -3
  12. package/lib/components/ColorPicker.js.map +2 -2
  13. package/lib/components/DatePicker.js +7 -3
  14. package/lib/components/DatePicker.js.map +2 -2
  15. package/lib/components/DateRangePicker.d.ts +85 -84
  16. package/lib/components/DateRangePicker.js +5 -3
  17. package/lib/components/DateRangePicker.js.map +2 -2
  18. package/lib/components/MonthRangePicker.d.ts +85 -84
  19. package/lib/components/MonthRangePicker.js +5 -3
  20. package/lib/components/MonthRangePicker.js.map +2 -2
  21. package/lib/components/PickerContainer.d.ts +2 -1
  22. package/lib/components/PickerContainer.js +3 -3
  23. package/lib/components/PickerContainer.js.map +2 -2
  24. package/lib/components/PopUp.d.ts +93 -0
  25. package/lib/components/PopUp.js +58 -0
  26. package/lib/components/PopUp.js.map +13 -0
  27. package/lib/components/Steps.d.ts +1 -0
  28. package/lib/components/Steps.js +5 -3
  29. package/lib/components/Steps.js.map +2 -2
  30. package/lib/components/TabsTransferPicker.js +1 -1
  31. package/lib/components/TabsTransferPicker.js.map +2 -2
  32. package/lib/components/TransferPicker.d.ts +0 -1
  33. package/lib/components/TransferPicker.js +2 -15
  34. package/lib/components/TransferPicker.js.map +2 -2
  35. package/lib/components/formula/Editor.d.ts +560 -0
  36. package/lib/components/formula/Editor.js +186 -0
  37. package/lib/components/formula/Editor.js.map +13 -0
  38. package/lib/components/formula/FuncList.d.ts +67 -0
  39. package/lib/components/formula/FuncList.js +35 -0
  40. package/lib/components/formula/FuncList.js.map +13 -0
  41. package/lib/components/formula/Picker.d.ts +493 -0
  42. package/lib/components/formula/Picker.js +48 -0
  43. package/lib/components/formula/Picker.js.map +13 -0
  44. package/lib/components/formula/VariableList.d.ts +9 -0
  45. package/lib/components/formula/VariableList.js +15 -0
  46. package/lib/components/formula/VariableList.js.map +13 -0
  47. package/lib/components/formula/plugin.d.ts +18 -0
  48. package/lib/components/formula/plugin.js +136 -0
  49. package/lib/components/formula/plugin.js.map +13 -0
  50. package/lib/helper.css +57 -57
  51. package/lib/helper.css.map +1 -1
  52. package/lib/index.d.ts +1 -0
  53. package/lib/index.js +2 -1
  54. package/lib/index.js.map +2 -2
  55. package/lib/renderers/Form/InputColor.d.ts +84 -84
  56. package/lib/renderers/Form/InputColor.js +2 -2
  57. package/lib/renderers/Form/InputColor.js.map +2 -2
  58. package/lib/renderers/Form/InputDate.js +2 -2
  59. package/lib/renderers/Form/InputDate.js.map +2 -2
  60. package/lib/renderers/Form/InputDateRange.js +2 -2
  61. package/lib/renderers/Form/InputDateRange.js.map +2 -2
  62. package/lib/renderers/Form/InputFormula.d.ts +35 -0
  63. package/lib/renderers/Form/InputFormula.js +25 -0
  64. package/lib/renderers/Form/InputFormula.js.map +13 -0
  65. package/lib/renderers/Form/InputMonthRange.js +2 -2
  66. package/lib/renderers/Form/InputMonthRange.js.map +2 -2
  67. package/lib/renderers/Form/InputQuarterRange.js +2 -2
  68. package/lib/renderers/Form/InputQuarterRange.js.map +2 -2
  69. package/lib/renderers/Form/InputYearRange.js +2 -2
  70. package/lib/renderers/Form/InputYearRange.js.map +2 -2
  71. package/lib/renderers/Form/TreeSelect.d.ts +1 -0
  72. package/lib/renderers/Form/TreeSelect.js +11 -8
  73. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  74. package/lib/renderers/Steps.js +2 -2
  75. package/lib/renderers/Steps.js.map +2 -2
  76. package/lib/themes/ang-ie11.css +261 -0
  77. package/lib/themes/ang.css +261 -0
  78. package/lib/themes/ang.css.map +1 -1
  79. package/lib/themes/antd-ie11.css +261 -0
  80. package/lib/themes/antd.css +261 -0
  81. package/lib/themes/antd.css.map +1 -1
  82. package/lib/themes/cxd-ie11.css +261 -0
  83. package/lib/themes/cxd.css +261 -0
  84. package/lib/themes/cxd.css.map +1 -1
  85. package/lib/themes/dark-ie11.css +261 -0
  86. package/lib/themes/dark.css +261 -0
  87. package/lib/themes/dark.css.map +1 -1
  88. package/lib/themes/default.css +261 -0
  89. package/lib/themes/default.css.map +1 -1
  90. package/lib/utils/api.js +2 -2
  91. package/lib/utils/api.js.map +2 -2
  92. package/package.json +4 -2
  93. package/scss/_variables.scss +1 -1
  94. package/scss/components/_formula.scss +122 -0
  95. package/scss/components/_popup.scss +123 -0
  96. package/scss/components/_steps.scss +60 -0
  97. package/scss/components/form/_color.scss +4 -0
  98. package/scss/components/form/_date-range.scss +4 -0
  99. package/scss/components/form/_date.scss +3 -0
  100. package/scss/components/form/_tree-select.scss +4 -0
  101. package/scss/helper/background/_background-color.scss +1 -1
  102. package/scss/helper/border/_border-color.scss +1 -1
  103. package/scss/helper/typography/_text-color.scss +1 -1
  104. package/scss/themes/_common.scss +2 -0
  105. package/sdk/ang-ie11.css +875 -0
  106. package/sdk/ang.css +875 -0
  107. package/sdk/antd-ie11.css +875 -0
  108. package/sdk/antd.css +875 -0
  109. package/sdk/charts.js +15 -15
  110. package/sdk/codemirror.js +14 -0
  111. package/sdk/color-picker.js +65 -65
  112. package/sdk/cropperjs.js +2 -2
  113. package/sdk/cxd-ie11.css +875 -0
  114. package/sdk/cxd.css +875 -0
  115. package/sdk/dark-ie11.css +875 -0
  116. package/sdk/dark.css +875 -0
  117. package/sdk/exceljs.js +1 -1
  118. package/sdk/helper.css +57 -57
  119. package/sdk/helper.css.map +1 -1
  120. package/sdk/markdown.js +69 -69
  121. package/sdk/papaparse.js +1 -1
  122. package/sdk/renderers/Form/CityDB.js +1 -1
  123. package/sdk/rest.js +18 -18
  124. package/sdk/rich-text.js +62 -62
  125. package/sdk/sdk-ie11.css +875 -0
  126. package/sdk/sdk.css +875 -0
  127. package/sdk/sdk.js +1219 -1201
  128. package/sdk/thirds/hls.js/hls.js +1 -1
  129. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  130. package/sdk/tinymce.js +57 -57
  131. package/src/Schema.ts +1 -0
  132. package/src/components/AsideNav.tsx +1 -1
  133. package/src/components/CodeMirror.tsx +99 -0
  134. package/src/components/Collapse.tsx +2 -1
  135. package/src/components/ColorPicker.tsx +45 -3
  136. package/src/components/DatePicker.tsx +33 -3
  137. package/src/components/DateRangePicker.tsx +17 -3
  138. package/src/components/MonthRangePicker.tsx +18 -4
  139. package/src/components/PickerContainer.tsx +10 -6
  140. package/src/components/PopUp.tsx +133 -0
  141. package/src/components/Steps.tsx +8 -3
  142. package/src/components/TabsTransferPicker.tsx +1 -1
  143. package/src/components/TransferPicker.tsx +1 -11
  144. package/src/components/formula/Editor.tsx +261 -0
  145. package/src/components/formula/FuncList.tsx +82 -0
  146. package/src/components/formula/Picker.tsx +86 -0
  147. package/src/components/formula/VariableList.tsx +49 -0
  148. package/src/components/formula/plugin.ts +177 -0
  149. package/src/index.tsx +1 -0
  150. package/src/renderers/Form/InputColor.tsx +2 -3
  151. package/src/renderers/Form/InputDate.tsx +2 -0
  152. package/src/renderers/Form/InputDateRange.tsx +2 -0
  153. package/src/renderers/Form/InputFormula.tsx +75 -0
  154. package/src/renderers/Form/InputMonthRange.tsx +2 -0
  155. package/src/renderers/Form/InputQuarterRange.tsx +2 -0
  156. package/src/renderers/Form/InputYearRange.tsx +2 -0
  157. package/src/renderers/Form/TreeSelect.tsx +82 -63
  158. package/src/renderers/Steps.tsx +4 -2
  159. package/src/utils/api.ts +5 -2
@@ -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
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @file 扩展 codemirror
3
+ */
4
+
5
+ import type CodeMirror from 'codemirror';
6
+ import {eachTree} from '../../utils/helper';
7
+ import type {FormulaEditorProps, VariableItem} from './Editor';
8
+
9
+ export function editorFactory(
10
+ dom: HTMLElement,
11
+ cm: typeof CodeMirror,
12
+ props: any
13
+ ) {
14
+ registerLaunguageMode(cm);
15
+
16
+ console.log('here', props.evalMode);
17
+
18
+ return cm(dom, {
19
+ value: props.value || '',
20
+ autofocus: true,
21
+ mode: props.evalMode ? 'text/formula' : 'text/formula-template'
22
+ });
23
+ }
24
+
25
+ export class FormulaPlugin {
26
+ constructor(
27
+ readonly editor: CodeMirror.Editor,
28
+ readonly cm: typeof CodeMirror,
29
+ readonly getProps: () => FormulaEditorProps
30
+ ) {
31
+ // editor.on('change', this.autoMarkText);
32
+ this.autoMarkText();
33
+ }
34
+
35
+ autoMarkText() {
36
+ const {functions, variables, value} = this.getProps();
37
+ if (value) {
38
+ // todo functions 也需要自动替换
39
+ this.autoMark(variables);
40
+ }
41
+ }
42
+
43
+ insertContent(value: any, type: 'variable' | 'func') {
44
+ const from = this.editor.getCursor();
45
+ if (type === 'variable') {
46
+ this.editor.replaceSelection(value.key);
47
+ var to = this.editor.getCursor();
48
+
49
+ this.markText(from, to, value.name, 'cm-field');
50
+ } else if (type === 'func') {
51
+ // todo 支持 snippet,目前是不支持的
52
+
53
+ this.editor.replaceSelection(`${value}()`);
54
+ var to = this.editor.getCursor();
55
+ this.markText(
56
+ from,
57
+ {
58
+ line: to.line,
59
+ ch: to.ch - 2
60
+ },
61
+ value,
62
+ 'cm-func'
63
+ );
64
+
65
+ this.editor.setCursor({
66
+ line: to.line,
67
+ ch: to.ch - 1
68
+ });
69
+ } else if (typeof value === 'string') {
70
+ this.editor.replaceSelection(value);
71
+ }
72
+
73
+ this.editor.focus();
74
+ }
75
+
76
+ markText(
77
+ from: CodeMirror.Position,
78
+ to: CodeMirror.Position,
79
+ label: string,
80
+ className = 'cm-func'
81
+ ) {
82
+ const text = document.createElement('span');
83
+ text.className = className;
84
+ text.innerText = label;
85
+ this.editor.markText(from, to, {
86
+ atomic: true,
87
+ replacedWith: text
88
+ });
89
+ }
90
+
91
+ autoMark(variables: Array<VariableItem>) {
92
+ if (!Array.isArray(variables) || !variables.length) {
93
+ return;
94
+ }
95
+
96
+ const varMap: {
97
+ [propname: string]: string;
98
+ } = {};
99
+
100
+ eachTree(
101
+ variables,
102
+ item => item.value && (varMap[item.value] = item.label)
103
+ );
104
+ const vars = Object.keys(varMap).sort((a, b) => b.length - a.length);
105
+
106
+ const editor = this.editor;
107
+ const lines = editor.lineCount();
108
+ for (let line = 0; line < lines; line++) {
109
+ const content = editor.getLine(line);
110
+
111
+ // 标记方法调用
112
+ content.replace(/([A-Z]+)\s*\(/g, (_, func, pos) => {
113
+ this.markText(
114
+ {
115
+ line: line,
116
+ ch: pos
117
+ },
118
+ {
119
+ line: line,
120
+ ch: pos + func.length
121
+ },
122
+ func,
123
+ 'cm-func'
124
+ );
125
+ return _;
126
+ });
127
+
128
+ // 标记变量
129
+ vars.forEach(v => {
130
+ let from = 0;
131
+ let idx = -1;
132
+ while (~(idx = content.indexOf(v, from))) {
133
+ this.markText(
134
+ {
135
+ line: line,
136
+ ch: idx
137
+ },
138
+ {
139
+ line: line,
140
+ ch: idx + v.length
141
+ },
142
+ varMap[v],
143
+ 'cm-field'
144
+ );
145
+ from = idx + v.length;
146
+ }
147
+ });
148
+ }
149
+ }
150
+
151
+ dispose() {}
152
+
153
+ validate() {}
154
+ }
155
+
156
+ let modeRegisted = false;
157
+ function registerLaunguageMode(cm: typeof CodeMirror) {
158
+ if (modeRegisted) {
159
+ return;
160
+ }
161
+ modeRegisted = true;
162
+
163
+ // 对应 evalMode
164
+ cm.defineMode('formula', (config: any, parserConfig: any) => {
165
+ var formula = cm.getMode(config, 'javascript');
166
+ if (!parserConfig || !parserConfig.base) return formula;
167
+
168
+ return cm.multiplexingMode(cm.getMode(config, parserConfig.base), {
169
+ open: '${',
170
+ close: '}',
171
+ mode: formula
172
+ });
173
+ });
174
+
175
+ cm.defineMIME('text/formula', {name: 'formula'});
176
+ cm.defineMIME('text/formula-template', {name: 'formula', base: 'htmlmixed'});
177
+ }
package/src/index.tsx CHANGED
@@ -89,6 +89,7 @@ import './renderers/Form/Select';
89
89
  import './renderers/Form/Static';
90
90
  import './renderers/Form/InputDate';
91
91
  import './renderers/Form/InputDateRange';
92
+ import './renderers/Form/InputFormula';
92
93
  import './renderers/Form/InputRepeat';
93
94
  import './renderers/Form/InputTree';
94
95
  import './renderers/Form/TreeSelect';
@@ -68,12 +68,11 @@ export default class ColorControl extends React.PureComponent<
68
68
  };
69
69
 
70
70
  render() {
71
- const {className, classPrefix: ns, value, ...rest} = this.props;
72
-
71
+ const {className, classPrefix: ns, value, env, ...rest} = this.props;
73
72
  return (
74
73
  <div className={cx(`${ns}ColorControl`, className)}>
75
74
  <Suspense fallback={<div>...</div>}>
76
- <ColorPicker classPrefix={ns} {...rest} value={value || ''} />
75
+ <ColorPicker classPrefix={ns} {...rest} value={value || ''} useMobileUI={env.useMobileUI}/>
77
76
  </Suspense>
78
77
  </div>
79
78
  );
@@ -424,6 +424,7 @@ export default class DateControl extends React.PureComponent<
424
424
  format,
425
425
  timeFormat,
426
426
  valueFormat,
427
+ env,
427
428
  largeMode,
428
429
  render,
429
430
  ...rest
@@ -441,6 +442,7 @@ export default class DateControl extends React.PureComponent<
441
442
  format={valueFormat || format}
442
443
  {...this.state}
443
444
  classnames={cx}
445
+ useMobileUI={env.useMobileUI}
444
446
  schedules={this.state.schedules}
445
447
  largeMode={largeMode}
446
448
  onScheduleClick={this.onScheduleClick.bind(this)}
@@ -172,6 +172,7 @@ export default class DateRangeControl extends React.Component<DateRangeProps> {
172
172
  maxDuration,
173
173
  data,
174
174
  format,
175
+ env,
175
176
  ...rest
176
177
  } = this.props;
177
178
 
@@ -186,6 +187,7 @@ export default class DateRangeControl extends React.Component<DateRangeProps> {
186
187
  maxDate={maxDate ? filterDate(maxDate, data, format) : undefined}
187
188
  minDuration={minDuration ? parseDuration(minDuration) : undefined}
188
189
  maxDuration={maxDuration ? parseDuration(maxDuration) : undefined}
190
+ useMobileUI={env.useMobileUI}
189
191
  />
190
192
  </div>
191
193
  );