amis 1.8.0-beta.13 → 1.8.0-beta.17

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 (120) hide show
  1. package/lib/WithStore.js +1 -1
  2. package/lib/WithStore.js.map +2 -2
  3. package/lib/components/DatePicker.js +3 -1
  4. package/lib/components/DatePicker.js.map +2 -2
  5. package/lib/components/Progress.js +3 -4
  6. package/lib/components/Progress.js.map +2 -2
  7. package/lib/components/TabsTransfer.d.ts +22 -3
  8. package/lib/components/TabsTransfer.js +149 -42
  9. package/lib/components/TabsTransfer.js.map +2 -2
  10. package/lib/components/Tree.js +3 -1
  11. package/lib/components/Tree.js.map +2 -2
  12. package/lib/components/formula/Editor.js +4 -4
  13. package/lib/components/formula/Editor.js.map +2 -2
  14. package/lib/components/formula/VariableList.d.ts +63 -4
  15. package/lib/components/formula/VariableList.js +23 -8
  16. package/lib/components/formula/VariableList.js.map +2 -2
  17. package/lib/helper.css +1 -1
  18. package/lib/helper.css.map +1 -1
  19. package/lib/index.js +1 -1
  20. package/lib/renderers/Date.js +6 -1
  21. package/lib/renderers/Date.js.map +2 -2
  22. package/lib/renderers/Form/NestedSelect.d.ts +1 -1
  23. package/lib/renderers/Form/NestedSelect.js +7 -2
  24. package/lib/renderers/Form/NestedSelect.js.map +2 -2
  25. package/lib/renderers/Form/TabsTransfer.d.ts +6 -1
  26. package/lib/renderers/Form/TabsTransfer.js +155 -6
  27. package/lib/renderers/Form/TabsTransfer.js.map +2 -2
  28. package/lib/renderers/Form/TabsTransferPicker.d.ts +2 -2
  29. package/lib/renderers/Form/TabsTransferPicker.js +4 -4
  30. package/lib/renderers/Form/TabsTransferPicker.js.map +2 -2
  31. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  32. package/lib/renderers/Form/index.js +6 -2
  33. package/lib/renderers/Form/index.js.map +2 -2
  34. package/lib/renderers/Markdown.js +4 -3
  35. package/lib/renderers/Markdown.js.map +2 -2
  36. package/lib/renderers/Nav.d.ts +21 -20
  37. package/lib/renderers/Nav.js +8 -1
  38. package/lib/renderers/Nav.js.map +2 -2
  39. package/lib/renderers/Page.js +1 -1
  40. package/lib/renderers/Page.js.map +2 -2
  41. package/lib/renderers/Service.js +1 -1
  42. package/lib/renderers/Service.js.map +2 -2
  43. package/lib/renderers/Table/exportExcel.d.ts +6 -0
  44. package/lib/renderers/Table/exportExcel.js +288 -0
  45. package/lib/renderers/Table/exportExcel.js.map +13 -0
  46. package/lib/renderers/Table/index.d.ts +1 -1
  47. package/lib/renderers/Table/index.js +4 -251
  48. package/lib/renderers/Table/index.js.map +2 -2
  49. package/lib/themes/ang-ie11.css +112 -36
  50. package/lib/themes/ang.css +100 -21
  51. package/lib/themes/ang.css.map +1 -1
  52. package/lib/themes/antd-ie11.css +112 -36
  53. package/lib/themes/antd.css +100 -21
  54. package/lib/themes/antd.css.map +1 -1
  55. package/lib/themes/cxd-ie11.css +97 -21
  56. package/lib/themes/cxd.css +100 -21
  57. package/lib/themes/cxd.css.map +1 -1
  58. package/lib/themes/dark-ie11.css +112 -36
  59. package/lib/themes/dark.css +100 -21
  60. package/lib/themes/dark.css.map +1 -1
  61. package/lib/themes/default-ie11.css +97 -21
  62. package/lib/themes/default.css +100 -21
  63. package/lib/themes/default.css.map +1 -1
  64. package/lib/utils/api.js +35 -6
  65. package/lib/utils/api.js.map +2 -2
  66. package/package.json +1 -1
  67. package/schema.json +1 -1
  68. package/scss/_properties.scss +4 -0
  69. package/scss/components/_formula.scss +77 -12
  70. package/scss/components/_progress.scss +2 -7
  71. package/scss/components/form/_date.scss +1 -0
  72. package/scss/components/form/_transfer.scss +21 -0
  73. package/scss/helper/layout/_display.scss +1 -1
  74. package/sdk/ang-ie11.css +130 -36
  75. package/sdk/ang.css +118 -21
  76. package/sdk/antd-ie11.css +130 -36
  77. package/sdk/antd.css +118 -21
  78. package/sdk/barcode.js +51 -51
  79. package/sdk/charts.js +14 -14
  80. package/sdk/codemirror.js +7 -7
  81. package/sdk/color-picker.js +65 -65
  82. package/sdk/cropperjs.js +2 -2
  83. package/sdk/cxd-ie11.css +115 -21
  84. package/sdk/cxd.css +118 -21
  85. package/sdk/dark-ie11.css +130 -36
  86. package/sdk/dark.css +118 -21
  87. package/sdk/exceljs.js +1 -1
  88. package/sdk/helper.css +1 -1
  89. package/sdk/helper.css.map +1 -1
  90. package/sdk/markdown.js +69 -69
  91. package/sdk/papaparse.js +1 -1
  92. package/sdk/renderers/Form/CityDB.js +1 -1
  93. package/sdk/rest.js +17 -17
  94. package/sdk/rich-text.js +62 -62
  95. package/sdk/sdk-ie11.css +115 -21
  96. package/sdk/sdk.css +118 -21
  97. package/sdk/sdk.js +1270 -1268
  98. package/sdk/thirds/hls.js/hls.js +1 -1
  99. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  100. package/sdk/tinymce.js +57 -57
  101. package/src/WithStore.tsx +1 -1
  102. package/src/components/DatePicker.tsx +2 -1
  103. package/src/components/Progress.tsx +6 -4
  104. package/src/components/TabsTransfer.tsx +253 -143
  105. package/src/components/Tree.tsx +3 -1
  106. package/src/components/formula/Editor.tsx +12 -5
  107. package/src/components/formula/VariableList.tsx +55 -21
  108. package/src/renderers/Date.tsx +14 -1
  109. package/src/renderers/Form/NestedSelect.tsx +11 -2
  110. package/src/renderers/Form/TabsTransfer.tsx +174 -11
  111. package/src/renderers/Form/TabsTransferPicker.tsx +5 -10
  112. package/src/renderers/Form/TreeSelect.tsx +15 -12
  113. package/src/renderers/Form/index.tsx +37 -16
  114. package/src/renderers/Markdown.tsx +4 -5
  115. package/src/renderers/Nav.tsx +7 -1
  116. package/src/renderers/Page.tsx +9 -2
  117. package/src/renderers/Service.tsx +8 -2
  118. package/src/renderers/Table/exportExcel.ts +289 -0
  119. package/src/renderers/Table/index.tsx +5 -252
  120. package/src/utils/api.ts +42 -10
package/src/WithStore.tsx CHANGED
@@ -201,7 +201,7 @@ export function HocStoreFactory(renderer: {
201
201
  store.initData(
202
202
  extendObject(
203
203
  props.data,
204
- store.hasRemoteData
204
+ store.hasRemoteData || store.path === 'page'
205
205
  ? {
206
206
  ...store.data,
207
207
  ...props.data
@@ -371,7 +371,8 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
371
371
  value: normalizeValue(props.value, props.format)
372
372
  };
373
373
 
374
- newState.inputValue = newState.value.format(this.props.inputFormat) || '';
374
+ newState.inputValue =
375
+ newState.value?.format(this.props.inputFormat) || '';
375
376
 
376
377
  this.setState(newState);
377
378
  }
@@ -110,16 +110,15 @@ export class Progress extends React.Component<ProgressProps, Object> {
110
110
  if (typeof value !== 'number') {
111
111
  viewValue = <span className="text-muted">{placeholder}</span>;
112
112
  } else if (type === 'line') {
113
- const style: any = {};
114
113
  const barStyle: any = {
115
114
  width: `${value}%`
116
115
  };
117
- strokeWidth && (style.height = strokeWidth);
116
+ strokeWidth && (barStyle.height = strokeWidth);
118
117
  !isColorClass && (barStyle.backgroundColor = bgColor);
119
118
 
120
119
  viewValue = [
121
120
  <div key="progress" className={cx(prefixCls, progressClassName)}>
122
- <div className={cx(`${prefixCls}-inter`)} style={style}>
121
+ <div className={cx(`${prefixCls}-inter`)}>
123
122
  <div
124
123
  className={cx(
125
124
  `${prefixCls}-bar`,
@@ -149,7 +148,10 @@ export class Progress extends React.Component<ProgressProps, Object> {
149
148
  };
150
149
 
151
150
  viewValue = [
152
- <div className={cx(prefixCls, progressClassName)} key="circle">
151
+ <div
152
+ className={cx(prefixCls, progressClassName || 'w-ssm')}
153
+ key="circle"
154
+ >
153
155
  <Circle
154
156
  percent={value}
155
157
  strokeColor={!isColorClass ? bgColor : ''}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import {autobind} from '../utils/helper';
3
3
  import Tabs, {Tab} from './Tabs';
4
- import SearchBox from './SearchBox';
4
+ import InputBox from './InputBox';
5
5
  import TableCheckboxes from './TableSelection';
6
6
  import TreeCheckboxes from './TreeSelection';
7
7
  import ChainedCheckboxes from './ChainedSelection';
@@ -12,6 +12,8 @@ import {themeable} from '../theme';
12
12
  import AssociatedCheckboxes from './AssociatedSelection';
13
13
  import {localeable} from '../locale';
14
14
  import {ItemRenderStates} from './Selection';
15
+ import {Icon} from './icons';
16
+ import debounce from 'lodash/debounce';
15
17
 
16
18
  export interface TabsTransferProps
17
19
  extends Omit<
@@ -20,8 +22,14 @@ export interface TabsTransferProps
20
22
  | 'columns'
21
23
  | 'selectRender'
22
24
  | 'statistics'
25
+ | 'onSearch'
23
26
  | 'optionItemRender'
24
27
  > {
28
+ onSearch: (
29
+ term: string,
30
+ option: Option,
31
+ setCancel: (cancel: () => void) => void
32
+ ) => Promise<Options | void>;
25
33
  optionItemRender?: (
26
34
  option: Option,
27
35
  states: ItemRenderStates,
@@ -39,7 +47,97 @@ export interface TabsTransferProps
39
47
  ) => JSX.Element;
40
48
  }
41
49
 
42
- export class TabsTransfer extends React.Component<TabsTransferProps> {
50
+ export interface TabsTransferState {
51
+ inputValue: string;
52
+ searchResult: Options | null;
53
+ }
54
+
55
+ export class TabsTransfer extends React.Component<
56
+ TabsTransferProps,
57
+ TabsTransferState
58
+ > {
59
+ state = {
60
+ inputValue: '',
61
+ searchResult: null
62
+ };
63
+
64
+ unmounted = false;
65
+ cancelSearch?: () => void;
66
+
67
+ componentWillUnmount() {
68
+ this.lazySearch.cancel();
69
+ this.unmounted = true;
70
+ }
71
+
72
+ @autobind
73
+ handleSearch(text: string, option: Option) {
74
+ // text 有值的时候,走搜索否则直接走 handleSeachCancel ,等同于右侧的 clear 按钮
75
+ if (text) {
76
+ this.setState(
77
+ {
78
+ inputValue: text
79
+ },
80
+ () => {
81
+ // 如果有取消搜索,先取消掉。
82
+ this.cancelSearch && this.cancelSearch();
83
+ this.lazySearch(text, option);
84
+ }
85
+ );
86
+ } else {
87
+ this.handleSeachCancel();
88
+ }
89
+ }
90
+
91
+ @autobind
92
+ handleSeachCancel() {
93
+ this.setState({
94
+ inputValue: '',
95
+ searchResult: null
96
+ });
97
+ }
98
+
99
+ lazySearch = debounce(
100
+ (text: string, option: Option) => {
101
+ (async (text: string) => {
102
+ const onSearch = this.props.onSearch;
103
+ let result = await onSearch(
104
+ text,
105
+ option,
106
+ (cancelExecutor: () => void) => (this.cancelSearch = cancelExecutor)
107
+ );
108
+
109
+ if (this.unmounted) {
110
+ return;
111
+ }
112
+
113
+ if (!Array.isArray(result)) {
114
+ throw new Error('onSearch 需要返回数组');
115
+ }
116
+
117
+ this.setState({
118
+ searchResult: result
119
+ });
120
+ })(text).catch(e => console.error(e));
121
+ },
122
+ 250,
123
+ {
124
+ trailing: true,
125
+ leading: false
126
+ }
127
+ );
128
+
129
+ @autobind
130
+ handleSearchKeyDown(e: React.KeyboardEvent<any>) {
131
+ if (e.key === 'Enter') {
132
+ e.preventDefault();
133
+ }
134
+ }
135
+
136
+ @autobind
137
+ handleTabChange() {
138
+ this.handleSeachCancel();
139
+ }
140
+
43
141
  renderSearchResult(searchResult: Options | null) {
44
142
  const {
45
143
  searchResultMode,
@@ -126,22 +224,9 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
126
224
  }
127
225
 
128
226
  @autobind
129
- renderSelect({onSearch, onSearchCancel, searchResult}: any) {
130
- const {
131
- options,
132
- placeholder,
133
- classnames: cx,
134
- value,
135
- disabled,
136
- onChange,
137
- onSearch: searchable,
138
- option2value,
139
- onDeferLoad,
140
- onLeftDeferLoad,
141
- cellRender,
142
- translate: __,
143
- optionItemRender
144
- } = this.props;
227
+ renderSelect() {
228
+ const {options, placeholder, classnames: cx, translate: __} = this.props;
229
+ const showOptions = options.filter(item => item.visible !== false);
145
230
 
146
231
  if (!Array.isArray(options) || !options.length) {
147
232
  return (
@@ -153,138 +238,163 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
153
238
 
154
239
  return (
155
240
  <Tabs
156
- mode="card"
241
+ mode="line"
157
242
  className={cx('TabsTransfer-tabs')}
158
- activeKey={searchResult !== null ? 0 : undefined}
159
- toolbar={
160
- searchable ? (
161
- <>
162
- <span className={cx('TabsTransfer-tabsMid')}></span>
163
- <SearchBox onSearch={onSearch} onCancel={onSearchCancel} />
164
- </>
165
- ) : null
166
- }
243
+ onSelect={this.handleTabChange}
167
244
  >
168
- {searchResult !== null
169
- ? [
170
- <Tab
171
- className="TabsTransfer-tab"
172
- title={__('searchResult')}
173
- key={0}
174
- eventKey={0}
175
- >
176
- {this.renderSearchResult(searchResult)}
177
- </Tab>
178
- ]
179
- : options.map((option, index) => (
180
- <Tab
181
- eventKey={index}
182
- key={index}
183
- title={option.label || option.title}
184
- className="TabsTransfer-tab"
185
- >
186
- {option.selectMode === 'table' ? (
187
- <TableCheckboxes
188
- className={cx('Transfer-checkboxes')}
189
- columns={option.columns as any}
190
- options={option.children || []}
191
- value={value}
192
- disabled={disabled}
193
- onChange={onChange}
194
- option2value={option2value}
195
- onDeferLoad={onDeferLoad}
196
- cellRender={cellRender}
197
- />
198
- ) : option.selectMode === 'tree' ? (
199
- <TreeCheckboxes
200
- className={cx('Transfer-checkboxes')}
201
- options={option.children || []}
202
- value={value}
203
- disabled={disabled}
204
- onChange={onChange}
205
- option2value={option2value}
206
- onDeferLoad={onDeferLoad}
207
- itemRender={
208
- optionItemRender
209
- ? (item: Option, states: ItemRenderStates) =>
210
- optionItemRender(item, states, {
211
- panel: 'tab',
212
- tag: option
213
- })
214
- : undefined
215
- }
216
- />
217
- ) : option.selectMode === 'chained' ? (
218
- <ChainedCheckboxes
219
- className={cx('Transfer-checkboxes')}
220
- options={option.children || []}
221
- value={value}
222
- disabled={disabled}
223
- onChange={onChange}
224
- option2value={option2value}
225
- onDeferLoad={onDeferLoad}
226
- defaultSelectedIndex={option.defaultSelectedIndex}
227
- itemRender={
228
- optionItemRender
229
- ? (item: Option, states: ItemRenderStates) =>
230
- optionItemRender(item, states, {
231
- panel: 'tab',
232
- tag: option
233
- })
234
- : undefined
235
- }
236
- />
237
- ) : option.selectMode === 'associated' ? (
238
- <AssociatedCheckboxes
239
- className={cx('Transfer-checkboxes')}
240
- options={option.children || []}
241
- value={value}
242
- disabled={disabled}
243
- onChange={onChange}
244
- option2value={option2value}
245
- onDeferLoad={onDeferLoad}
246
- onLeftDeferLoad={onLeftDeferLoad}
247
- leftMode={option.leftMode}
248
- leftOptions={option.leftOptions}
249
- leftDefaultValue={option.leftDefaultValue}
250
- itemRender={
251
- optionItemRender
252
- ? (item: Option, states: ItemRenderStates) =>
253
- optionItemRender(item, states, {
254
- panel: 'tab',
255
- tag: option
256
- })
257
- : undefined
258
- }
259
- />
260
- ) : (
261
- <ListCheckboxes
262
- className={cx('Transfer-checkboxes')}
263
- options={option.children || []}
264
- value={value}
265
- disabled={disabled}
266
- onChange={onChange}
267
- option2value={option2value}
268
- onDeferLoad={onDeferLoad}
269
- itemRender={
270
- optionItemRender
271
- ? (item: Option, states: ItemRenderStates) =>
272
- optionItemRender(item, states, {
273
- panel: 'tab',
274
- tag: option
275
- })
276
- : undefined
277
- }
278
- />
279
- )}
280
- </Tab>
281
- ))}
245
+ {showOptions.map((option, index) => (
246
+ <Tab
247
+ eventKey={index}
248
+ key={index}
249
+ title={option.label || option.title}
250
+ className="TabsTransfer-tab"
251
+ >
252
+ {option.searchable ? (
253
+ <div className={cx('TabsTransfer-search')}>
254
+ <InputBox
255
+ value={this.state.inputValue}
256
+ onChange={(text: string) => this.handleSearch(text, option)}
257
+ placeholder={__('Transfer.searchKeyword')}
258
+ clearable={false}
259
+ onKeyDown={this.handleSearchKeyDown}
260
+ >
261
+ {this.state.searchResult !== null ? (
262
+ <a onClick={this.handleSeachCancel}>
263
+ <Icon icon="close" className="icon" />
264
+ </a>
265
+ ) : (
266
+ <Icon icon="search" className="icon" />
267
+ )}
268
+ </InputBox>
269
+ </div>
270
+ ) : null}
271
+ {this.state.searchResult !== null
272
+ ? this.renderSearchResult(this.state.searchResult)
273
+ : this.renderOptions(option)}
274
+ </Tab>
275
+ ))}
282
276
  </Tabs>
283
277
  );
284
278
  }
285
279
 
280
+ @autobind
281
+ renderOptions(option: Option) {
282
+ const {
283
+ classnames: cx,
284
+ value,
285
+ disabled,
286
+ onChange,
287
+ option2value,
288
+ onDeferLoad,
289
+ onLeftDeferLoad,
290
+ cellRender,
291
+ translate: __,
292
+ optionItemRender
293
+ } = this.props;
294
+ return option.selectMode === 'table' ? (
295
+ <TableCheckboxes
296
+ className={cx('Transfer-checkboxes')}
297
+ columns={option.columns as any}
298
+ options={option.children || []}
299
+ value={value}
300
+ disabled={disabled}
301
+ onChange={onChange}
302
+ option2value={option2value}
303
+ onDeferLoad={onDeferLoad}
304
+ cellRender={cellRender}
305
+ />
306
+ ) : option.selectMode === 'tree' ? (
307
+ <TreeCheckboxes
308
+ className={cx('Transfer-checkboxes')}
309
+ options={option.children || []}
310
+ value={value}
311
+ disabled={disabled}
312
+ onChange={onChange}
313
+ option2value={option2value}
314
+ onDeferLoad={onDeferLoad}
315
+ itemRender={
316
+ optionItemRender
317
+ ? (item: Option, states: ItemRenderStates) =>
318
+ optionItemRender(item, states, {
319
+ panel: 'tab',
320
+ tag: option
321
+ })
322
+ : undefined
323
+ }
324
+ />
325
+ ) : option.selectMode === 'chained' ? (
326
+ <ChainedCheckboxes
327
+ className={cx('Transfer-checkboxes')}
328
+ options={option.children || []}
329
+ value={value}
330
+ disabled={disabled}
331
+ onChange={onChange}
332
+ option2value={option2value}
333
+ onDeferLoad={onDeferLoad}
334
+ defaultSelectedIndex={option.defaultSelectedIndex}
335
+ itemRender={
336
+ optionItemRender
337
+ ? (item: Option, states: ItemRenderStates) =>
338
+ optionItemRender(item, states, {
339
+ panel: 'tab',
340
+ tag: option
341
+ })
342
+ : undefined
343
+ }
344
+ />
345
+ ) : option.selectMode === 'associated' ? (
346
+ <AssociatedCheckboxes
347
+ className={cx('Transfer-checkboxes')}
348
+ options={option.children || []}
349
+ value={value}
350
+ disabled={disabled}
351
+ onChange={onChange}
352
+ option2value={option2value}
353
+ onDeferLoad={onDeferLoad}
354
+ onLeftDeferLoad={onLeftDeferLoad}
355
+ leftMode={option.leftMode}
356
+ leftOptions={option.leftOptions}
357
+ leftDefaultValue={option.leftDefaultValue}
358
+ itemRender={
359
+ optionItemRender
360
+ ? (item: Option, states: ItemRenderStates) =>
361
+ optionItemRender(item, states, {
362
+ panel: 'tab',
363
+ tag: option
364
+ })
365
+ : undefined
366
+ }
367
+ />
368
+ ) : (
369
+ <ListCheckboxes
370
+ className={cx('Transfer-checkboxes')}
371
+ options={option.children || []}
372
+ value={value}
373
+ disabled={disabled}
374
+ onChange={onChange}
375
+ option2value={option2value}
376
+ onDeferLoad={onDeferLoad}
377
+ itemRender={
378
+ optionItemRender
379
+ ? (item: Option, states: ItemRenderStates) =>
380
+ optionItemRender(item, states, {
381
+ panel: 'tab',
382
+ tag: option
383
+ })
384
+ : undefined
385
+ }
386
+ />
387
+ );
388
+ }
389
+
286
390
  render() {
287
- const {className, classnames: cx, optionItemRender, ...reset} = this.props;
391
+ const {
392
+ className,
393
+ classnames: cx,
394
+ optionItemRender,
395
+ onSearch,
396
+ ...reset
397
+ } = this.props;
288
398
 
289
399
  return (
290
400
  <Transfer
@@ -210,7 +210,9 @@ export class TreeSelector extends React.Component<
210
210
 
211
211
  componentDidMount() {
212
212
  const {enableNodePath} = this.props;
213
- this.props.onRef(this)
213
+
214
+ // onRef只有渲染器的情况才会使用
215
+ this.props.onRef?.(this);
214
216
  enableNodePath && this.expandLazyLoadNodes();
215
217
  }
216
218
 
@@ -8,7 +8,7 @@ import {doc} from 'amis-formula/dist/doc';
8
8
 
9
9
  import {FormulaPlugin, editorFactory} from './plugin';
10
10
  import FuncList from './FuncList';
11
- import {VariableList} from './VariableList';
11
+ import VariableList from './VariableList';
12
12
  import CodeMirrorEditor from '../CodeMirror';
13
13
  import {autobind, eachTree} from '../../utils/helper';
14
14
  import {themeable, ThemeProps} from '../../theme';
@@ -283,10 +283,17 @@ export class FormulaEditor extends React.Component<
283
283
 
284
284
  <section className={cx('FormulaEditor-settings')}>
285
285
  <div className={cx('FormulaEditor-panel')}>
286
- <div className={cx('FormulaEditor-panel-header')}>
287
- {__('FormulaEditor.variable')}
288
- </div>
289
- <div className={cx('FormulaEditor-panel-body')}>
286
+ {variableMode !== 'tabs' ? (
287
+ <div className={cx('FormulaEditor-panel-header')}>
288
+ {__('FormulaEditor.variable')}
289
+ </div>
290
+ ) : null}
291
+ <div
292
+ className={cx(
293
+ 'FormulaEditor-panel-body',
294
+ variableMode && `FormulaEditor-panel-body--${variableMode}`
295
+ )}
296
+ >
290
297
  <VariableList
291
298
  classPrefix={classPrefix}
292
299
  className={cx(
@@ -1,19 +1,20 @@
1
1
  import React from 'react';
2
- import cx from 'classnames';
3
2
 
3
+ import {themeable, ThemeProps} from '../../theme';
4
4
  import GroupedSelection from '../GroupedSelection';
5
5
  import Tabs, {Tab} from '../Tabs';
6
6
  import TreeSelection from '../TreeSelection';
7
+ import SearchBox from '../SearchBox';
8
+ import {filterTree, flattenTree} from '../../utils/helper';
7
9
 
8
10
  import type {VariableItem} from './Editor';
9
11
  import type {ItemRenderStates} from '../Selection';
10
12
  import type {Option} from '../Select';
11
13
  import type {TabsMode} from '../Tabs';
12
14
 
13
- export interface VariableListProps {
15
+ export interface VariableListProps extends ThemeProps {
14
16
  className?: string;
15
17
  itemClassName?: string;
16
- classPrefix?: string;
17
18
  data: Array<VariableItem>;
18
19
  selectMode?: 'list' | 'tree' | 'tabs';
19
20
  tabsMode?: TabsMode;
@@ -21,16 +22,18 @@ export interface VariableListProps {
21
22
  onSelect?: (item: VariableItem) => void;
22
23
  }
23
24
 
24
- export function VariableList(props: VariableListProps) {
25
+ function VariableList(props: VariableListProps) {
25
26
  const {
26
27
  data: list,
27
28
  className,
28
- tabsMode = 'card',
29
+ classnames: cx,
30
+ tabsMode = 'line',
29
31
  classPrefix: themePrefix,
30
32
  itemClassName,
31
33
  selectMode,
32
34
  onSelect
33
35
  } = props;
36
+ const [filterVars, setFilterVars] = React.useState(list);
34
37
  const classPrefix = `${themePrefix}FormulaEditor-VariableList`;
35
38
  const itemRender =
36
39
  props.itemRender && typeof props.itemRender === 'function'
@@ -48,14 +51,35 @@ export function VariableList(props: VariableListProps) {
48
51
  );
49
52
  };
50
53
 
54
+ function onSearch(term: string) {
55
+ const flatten = flattenTree(list);
56
+ const filtered = flatten.filter(item => ~item.label.indexOf(term));
57
+
58
+ setFilterVars(!term ? list : filtered);
59
+ }
60
+
61
+ function renderSearchBox() {
62
+ return (
63
+ <div className={cx('FormulaEditor-VariableList-searchBox')}>
64
+ <SearchBox mini={false} onSearch={onSearch} />
65
+ </div>
66
+ );
67
+ }
68
+
51
69
  return (
52
- <div className={cx(className, {'is-scrollable': selectMode !== 'tabs'})}>
70
+ <div
71
+ className={cx(
72
+ className,
73
+ 'FormulaEditor-VariableList',
74
+ selectMode && `FormulaEditor-VariableList-${selectMode}`
75
+ )}
76
+ >
53
77
  {selectMode === 'tabs' ? (
54
78
  <Tabs
55
79
  tabsMode={tabsMode}
56
80
  className={cx(`${classPrefix}-base ${classPrefix}-tabs`)}
57
81
  >
58
- {list.map((item, index) => (
82
+ {filterVars.map((item, index) => (
59
83
  <Tab
60
84
  className={cx(`${classPrefix}-tab`)}
61
85
  eventKey={index}
@@ -63,6 +87,8 @@ export function VariableList(props: VariableListProps) {
63
87
  title={item.label}
64
88
  >
65
89
  <VariableList
90
+ classnames={cx}
91
+ classPrefix={`${classPrefix}-sub-`}
66
92
  className={cx(`${classPrefix}-sub`)}
67
93
  itemRender={itemRender}
68
94
  selectMode={item.selectMode}
@@ -73,22 +99,30 @@ export function VariableList(props: VariableListProps) {
73
99
  ))}
74
100
  </Tabs>
75
101
  ) : selectMode === 'tree' ? (
76
- <TreeSelection
77
- itemRender={itemRender}
78
- className={cx(`${classPrefix}-base`)}
79
- multiple={false}
80
- options={list}
81
- onChange={(item: any) => onSelect?.(item)}
82
- />
102
+ <div className={cx('FormulaEditor-VariableList-body')}>
103
+ {renderSearchBox()}
104
+ <TreeSelection
105
+ itemRender={itemRender}
106
+ className={cx(`${classPrefix}-base`, 'is-scrollable')}
107
+ multiple={false}
108
+ options={filterVars}
109
+ onChange={(item: any) => onSelect?.(item)}
110
+ />
111
+ </div>
83
112
  ) : (
84
- <GroupedSelection
85
- itemRender={itemRender}
86
- className={cx(`${classPrefix}-base`)}
87
- multiple={false}
88
- options={list}
89
- onChange={(item: any) => onSelect?.(item)}
90
- />
113
+ <div className={cx('FormulaEditor-VariableList-body')}>
114
+ {renderSearchBox()}
115
+ <GroupedSelection
116
+ itemRender={itemRender}
117
+ className={cx(`${classPrefix}-base`, 'is-scrollable')}
118
+ multiple={false}
119
+ options={filterVars}
120
+ onChange={(item: any) => onSelect?.(item)}
121
+ />
122
+ </div>
91
123
  )}
92
124
  </div>
93
125
  );
94
126
  }
127
+
128
+ export default themeable(VariableList);