amis 1.5.8-beta.2 → 1.6.0

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 (187) hide show
  1. package/lib/components/CalendarMobile.js +5 -5
  2. package/lib/components/CalendarMobile.js.map +2 -2
  3. package/lib/components/Card.d.ts +20 -20
  4. package/lib/components/Cascader.d.ts +123 -0
  5. package/lib/components/Cascader.js +487 -0
  6. package/lib/components/Cascader.js.map +13 -0
  7. package/lib/components/CityArea.d.ts +527 -0
  8. package/lib/components/CityArea.js +177 -0
  9. package/lib/components/CityArea.js.map +13 -0
  10. package/lib/components/ColorPicker.js +4 -3
  11. package/lib/components/ColorPicker.js.map +2 -2
  12. package/lib/components/DatePicker.d.ts +85 -84
  13. package/lib/components/DatePicker.js +7 -6
  14. package/lib/components/DatePicker.js.map +2 -2
  15. package/lib/components/DateRangePicker.js +8 -11
  16. package/lib/components/DateRangePicker.js.map +2 -2
  17. package/lib/components/MonthRangePicker.js +5 -8
  18. package/lib/components/MonthRangePicker.js.map +2 -2
  19. package/lib/components/Picker.d.ts +1 -0
  20. package/lib/components/Picker.js +10 -6
  21. package/lib/components/Picker.js.map +2 -2
  22. package/lib/components/PickerColumn.d.ts +1 -0
  23. package/lib/components/PickerColumn.js +21 -17
  24. package/lib/components/PickerColumn.js.map +2 -2
  25. package/lib/components/PopOverContainer.d.ts +1 -0
  26. package/lib/components/PopOverContainer.js +5 -3
  27. package/lib/components/PopOverContainer.js.map +2 -2
  28. package/lib/components/PopUp.d.ts +1040 -28
  29. package/lib/components/PopUp.js +32 -8
  30. package/lib/components/PopUp.js.map +2 -2
  31. package/lib/components/ResultBox.d.ts +85 -84
  32. package/lib/components/ResultBox.js +7 -3
  33. package/lib/components/ResultBox.js.map +2 -2
  34. package/lib/components/Select.js +9 -6
  35. package/lib/components/Select.js.map +2 -2
  36. package/lib/components/TransferDropDown.d.ts +85 -84
  37. package/lib/components/TransferDropDown.js +9 -6
  38. package/lib/components/TransferDropDown.js.map +2 -2
  39. package/lib/components/calendar/Calendar.d.ts +14 -0
  40. package/lib/components/calendar/Calendar.js +62 -5
  41. package/lib/components/calendar/Calendar.js.map +2 -2
  42. package/lib/components/calendar/DaysView.d.ts +20 -0
  43. package/lib/components/calendar/DaysView.js +51 -4
  44. package/lib/components/calendar/DaysView.js.map +2 -2
  45. package/lib/components/calendar/MonthsView.d.ts +7 -1
  46. package/lib/components/calendar/MonthsView.js +41 -52
  47. package/lib/components/calendar/MonthsView.js.map +2 -2
  48. package/lib/components/calendar/TimeView.d.ts +27 -20
  49. package/lib/components/calendar/TimeView.js +40 -4
  50. package/lib/components/calendar/TimeView.js.map +2 -2
  51. package/lib/components/calendar/YearsView.d.ts +6 -0
  52. package/lib/components/calendar/YearsView.js +15 -6
  53. package/lib/components/calendar/YearsView.js.map +2 -2
  54. package/lib/index.js +1 -1
  55. package/lib/locale/de-DE.js +4 -0
  56. package/lib/locale/de-DE.js.map +2 -2
  57. package/lib/locale/en-US.js +4 -0
  58. package/lib/locale/en-US.js.map +2 -2
  59. package/lib/locale/zh-CN.js +4 -0
  60. package/lib/locale/zh-CN.js.map +2 -2
  61. package/lib/renderers/DropDownButton.d.ts +11 -2
  62. package/lib/renderers/DropDownButton.js +30 -12
  63. package/lib/renderers/DropDownButton.js.map +2 -2
  64. package/lib/renderers/Form/CityDB.js +526 -2
  65. package/lib/renderers/Form/CityDB.js.map +2 -2
  66. package/lib/renderers/Form/InputCity.d.ts +85 -84
  67. package/lib/renderers/Form/InputCity.js +4 -2
  68. package/lib/renderers/Form/InputCity.js.map +2 -2
  69. package/lib/renderers/Form/InputColor.js +6 -2
  70. package/lib/renderers/Form/InputColor.js.map +2 -2
  71. package/lib/renderers/Form/InputDate.js +5 -2
  72. package/lib/renderers/Form/InputDate.js.map +2 -2
  73. package/lib/renderers/Form/InputDateRange.js +6 -2
  74. package/lib/renderers/Form/InputDateRange.js.map +2 -2
  75. package/lib/renderers/Form/Item.d.ts +10 -14
  76. package/lib/renderers/Form/Item.js +7 -5
  77. package/lib/renderers/Form/Item.js.map +2 -2
  78. package/lib/renderers/Form/NestedSelect.d.ts +1 -0
  79. package/lib/renderers/Form/NestedSelect.js +7 -3
  80. package/lib/renderers/Form/NestedSelect.js.map +2 -2
  81. package/lib/renderers/Form/Select.d.ts +2 -0
  82. package/lib/renderers/Form/Select.js +7 -4
  83. package/lib/renderers/Form/Select.js.map +2 -2
  84. package/lib/renderers/Form/TreeSelect.js +4 -4
  85. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  86. package/lib/renderers/Remark.js +2 -1
  87. package/lib/renderers/Remark.js.map +2 -2
  88. package/lib/schemaExtend.js +23 -9
  89. package/lib/schemaExtend.js.map +2 -2
  90. package/lib/themes/ang-ie11.css +312 -29
  91. package/lib/themes/ang.css +312 -29
  92. package/lib/themes/ang.css.map +1 -1
  93. package/lib/themes/antd-ie11.css +312 -29
  94. package/lib/themes/antd.css +312 -29
  95. package/lib/themes/antd.css.map +1 -1
  96. package/lib/themes/cxd-ie11.css +315 -41
  97. package/lib/themes/cxd.css +315 -41
  98. package/lib/themes/cxd.css.map +1 -1
  99. package/lib/themes/dark-ie11.css +312 -29
  100. package/lib/themes/dark.css +312 -29
  101. package/lib/themes/dark.css.map +1 -1
  102. package/lib/themes/default.css +315 -41
  103. package/lib/themes/default.css.map +1 -1
  104. package/lib/utils/helper.d.ts +1 -6
  105. package/lib/utils/helper.js +6 -17
  106. package/lib/utils/helper.js.map +2 -2
  107. package/package.json +1 -2
  108. package/schema.json +2192 -20
  109. package/scss/_properties.scss +10 -6
  110. package/scss/components/_calendar.scss +9 -2
  111. package/scss/components/_cascader.scss +102 -0
  112. package/scss/components/_city-area.scss +27 -0
  113. package/scss/components/_dropdown.scss +39 -9
  114. package/scss/components/_picker-columns.scss +15 -5
  115. package/scss/components/_popup.scss +35 -12
  116. package/scss/components/_result-box.scss +31 -0
  117. package/scss/components/form/_checks.scss +2 -0
  118. package/scss/components/form/_color.scss +2 -2
  119. package/scss/components/form/_date-range.scss +1 -1
  120. package/scss/components/form/_date.scss +46 -1
  121. package/scss/components/form/_nested-select.scss +3 -0
  122. package/scss/components/form/_select.scss +32 -3
  123. package/scss/components/form/_transfer.scss +3 -0
  124. package/scss/components/form/_tree-select.scss +1 -1
  125. package/scss/themes/_common.scss +2 -0
  126. package/scss/themes/_cxd-variables.scss +3 -3
  127. package/scss/themes/cxd.scss +0 -12
  128. package/sdk/ang-ie11.css +368 -29
  129. package/sdk/ang.css +367 -30
  130. package/sdk/antd-ie11.css +368 -29
  131. package/sdk/antd.css +367 -30
  132. package/sdk/charts.js +18 -18
  133. package/sdk/codemirror.js +7 -7
  134. package/sdk/color-picker.js +65 -65
  135. package/sdk/cropperjs.js +3 -3
  136. package/sdk/cxd-ie11.css +370 -42
  137. package/sdk/cxd.css +370 -44
  138. package/sdk/dark-ie11.css +368 -29
  139. package/sdk/dark.css +367 -30
  140. package/sdk/exceljs.js +1 -1
  141. package/sdk/locale/de-DE.js +4 -0
  142. package/sdk/markdown.js +69 -69
  143. package/sdk/papaparse.js +1 -1
  144. package/sdk/renderers/Form/CityDB.js +1 -1
  145. package/sdk/rest.js +18 -18
  146. package/sdk/rich-text.js +62 -62
  147. package/sdk/sdk-ie11.css +370 -42
  148. package/sdk/sdk.css +370 -44
  149. package/sdk/sdk.js +1309 -1227
  150. package/sdk/thirds/hls.js/hls.js +18 -18
  151. package/sdk/thirds/mpegts.js/mpegts.js +2 -2
  152. package/sdk/tinymce.js +57 -57
  153. package/src/components/CalendarMobile.tsx +5 -5
  154. package/src/components/Cascader.tsx +564 -0
  155. package/src/components/CityArea.tsx +315 -0
  156. package/src/components/ColorPicker.tsx +5 -2
  157. package/src/components/DatePicker.tsx +15 -5
  158. package/src/components/DateRangePicker.tsx +52 -43
  159. package/src/components/MonthRangePicker.tsx +44 -38
  160. package/src/components/Picker.tsx +27 -12
  161. package/src/components/PickerColumn.tsx +28 -18
  162. package/src/components/PopOverContainer.tsx +31 -17
  163. package/src/components/PopUp.tsx +55 -13
  164. package/src/components/ResultBox.tsx +10 -1
  165. package/src/components/Select.tsx +20 -23
  166. package/src/components/TransferDropDown.tsx +19 -5
  167. package/src/components/calendar/Calendar.tsx +86 -9
  168. package/src/components/calendar/DaysView.tsx +86 -2
  169. package/src/components/calendar/MonthsView.tsx +56 -63
  170. package/src/components/calendar/TimeView.tsx +82 -29
  171. package/src/components/calendar/YearsView.tsx +25 -6
  172. package/src/locale/de-DE.ts +4 -0
  173. package/src/locale/en-US.ts +4 -0
  174. package/src/locale/zh-CN.ts +4 -0
  175. package/src/renderers/DropDownButton.tsx +69 -35
  176. package/src/renderers/Form/CityDB.ts +526 -2
  177. package/src/renderers/Form/InputCity.tsx +23 -3
  178. package/src/renderers/Form/InputColor.tsx +21 -2
  179. package/src/renderers/Form/InputDate.tsx +10 -1
  180. package/src/renderers/Form/InputDateRange.tsx +9 -1
  181. package/src/renderers/Form/Item.tsx +14 -4
  182. package/src/renderers/Form/NestedSelect.tsx +31 -3
  183. package/src/renderers/Form/Select.tsx +15 -2
  184. package/src/renderers/Form/TreeSelect.tsx +10 -6
  185. package/src/renderers/Remark.tsx +2 -1
  186. package/src/schemaExtend.ts +22 -10
  187. package/src/utils/helper.ts +6 -16
@@ -252,8 +252,8 @@ export class CalendarMobile extends React.Component<
252
252
  if (startDate) {
253
253
  let obj = {
254
254
  dateTime: newTime,
255
- startDate: endDate ? startDate : startDate?.clone().set({hour: newTime[0], minute: newTime[1], second: 0}),
256
- endDate: !endDate ? endDate : endDate?.clone().set({hour: newTime[0], minute: newTime[1], second: 0})
255
+ startDate: endDate ? startDate : startDate?.clone().set({hour: newTime[0], minute: newTime[1], second: newTime[2] || 0}),
256
+ endDate: !endDate ? endDate : endDate?.clone().set({hour: newTime[0], minute: newTime[1], second: newTime[2] || 0})
257
257
  };
258
258
  this.setState(obj, () => {
259
259
  onChange && onChange(this.state);
@@ -361,7 +361,7 @@ export class CalendarMobile extends React.Component<
361
361
  ) {
362
362
  return this.setState(
363
363
  {
364
- endDate: newValue.clone().endOf(precision).set({hour: dateTime[0], minute: dateTime[1], second: 0})
364
+ endDate: newValue.clone().endOf(precision).set({hour: dateTime[0], minute: dateTime[1], second: dateTime[2] || 0})
365
365
  },
366
366
  () => {
367
367
  onChange && onChange(this.state, () => embed && confirm && confirm());
@@ -371,7 +371,7 @@ export class CalendarMobile extends React.Component<
371
371
 
372
372
  this.setState(
373
373
  {
374
- startDate: newValue.clone().startOf(precision).set({hour: dateTime[0], minute: dateTime[1], second: 0}),
374
+ startDate: newValue.clone().startOf(precision).set({hour: dateTime[0], minute: dateTime[1], second: dateTime[2] || 0}),
375
375
  endDate: undefined
376
376
  },
377
377
  () => {
@@ -477,7 +477,7 @@ export class CalendarMobile extends React.Component<
477
477
  locale={locale}
478
478
  useMobileUI={true}
479
479
  showToolbar={false}
480
- viewDate={moment().set({hour: dateTime[0], minute: dateTime[1], second: 0})}
480
+ viewDate={moment().set({hour: dateTime[0], minute: dateTime[1], second: dateTime[2] || 0})}
481
481
  />
482
482
  </div>
483
483
  );
@@ -0,0 +1,564 @@
1
+ /**
2
+ * @file Cascader
3
+ * @author fex
4
+ */
5
+
6
+ import React from 'react';
7
+ import {autobind, getTreeAncestors} from '../utils/helper';
8
+ import {themeable} from '../theme';
9
+ import {NestedSelectProps} from '../renderers/Form/NestedSelect';
10
+ import {Option, Options} from './Select';
11
+ import intersectionBy from 'lodash/intersectionBy';
12
+ import compact from 'lodash/compact';
13
+ import find from 'lodash/find';
14
+ import uniqBy from 'lodash/uniqBy';
15
+ import Button from './Button';
16
+ import {flattenTree, findTree, getTreeDepth} from '../utils/helper';
17
+
18
+ export type CascaderOption = {
19
+ text?: string;
20
+ value?: string | number;
21
+ color?: string;
22
+ disabled?: boolean;
23
+ children?: Options;
24
+ className?: string;
25
+ [key: string]: any;
26
+ };
27
+ export interface CascaderProps extends NestedSelectProps {
28
+ value?: (number | string)[];
29
+ activeColor?: string;
30
+ optionRender?: ({
31
+ option,
32
+ selected
33
+ }: {
34
+ option: CascaderOption;
35
+ selected: boolean;
36
+ }) => React.ReactNode;
37
+ onClose?: () => void;
38
+ onConfirm?: (param: any) => void;
39
+ multiple?: boolean;
40
+ }
41
+ export type CascaderTab = {
42
+ options: Options;
43
+ };
44
+
45
+ export interface CascaderState {
46
+ selectedOptions: Options;
47
+ activeTab: number;
48
+ tabs: Array<{
49
+ options: Options;
50
+ }>;
51
+ }
52
+
53
+ export class Cascader extends React.Component<CascaderProps, CascaderState> {
54
+ static defaultProps = {
55
+ labelField: 'label',
56
+ valueField: 'value'
57
+ };
58
+ tabsRef: React.RefObject<HTMLDivElement> = React.createRef();
59
+ tabRef: React.RefObject<HTMLDivElement> = React.createRef();
60
+ constructor(props: CascaderProps) {
61
+ super(props);
62
+ this.state = {
63
+ selectedOptions: this.props.selectedOptions || [],
64
+ activeTab: 0,
65
+ tabs: [
66
+ {
67
+ options: this.props.options.slice() || []
68
+ }
69
+ ]
70
+ };
71
+ }
72
+ componentDidMount() {
73
+ const {multiple, options, valueField = 'value', cascade} = this.props;
74
+ let selectedOptions = this.props.selectedOptions.slice();
75
+ let parentsCount = 0;
76
+ let parentTree: Options = [];
77
+ selectedOptions.forEach((item: Option) => {
78
+ const parents = getTreeAncestors(options, item as any);
79
+ // 获取最长路径
80
+ if (parents && parents?.length > parentsCount) {
81
+ parentTree = parents;
82
+ parentsCount = parentTree.length;
83
+ }
84
+ });
85
+ const selectedValues = selectedOptions.map(
86
+ (option: Option) => option[valueField]
87
+ );
88
+ const tabs = parentTree.map((option: Option) => {
89
+ if (multiple && !cascade) {
90
+ if (
91
+ selectedValues.includes(option[valueField]) &&
92
+ option?.children?.length
93
+ ) {
94
+ option.children.forEach((option: Option) => (option.disabled = true));
95
+ }
96
+ }
97
+ return multiple
98
+ ? {
99
+ options: [
100
+ {
101
+ ...option,
102
+ isCheckAll: true
103
+ },
104
+ ...(option.children ? option.children : [])
105
+ ]
106
+ }
107
+ : {
108
+ options: option.children ? option.children : []
109
+ };
110
+ });
111
+ this.setState({
112
+ selectedOptions,
113
+ tabs: [...this.state.tabs, ...tabs]
114
+ });
115
+ }
116
+
117
+ @autobind
118
+ handleTabSelect(index: number) {
119
+ const tabs = this.state.tabs.slice(0, index + 1);
120
+ this.setState({
121
+ activeTab: index,
122
+ tabs
123
+ });
124
+ }
125
+
126
+ @autobind
127
+ getOptionParent(option: Option) {
128
+ const {options, valueField = 'value'} = this.props;
129
+ let ancestors: any[] = [];
130
+ findTree(options, (item, index, level, paths) => {
131
+ if (item[valueField] === option[valueField]) {
132
+ ancestors = paths;
133
+ return true;
134
+ }
135
+ return false;
136
+ });
137
+ return ancestors.length ? ancestors[ancestors.length - 1] : null;
138
+ }
139
+
140
+ @autobind
141
+ dealParentSelect(option: Option, selectedOptions: Options): Options {
142
+ const {valueField = 'value'} = this.props;
143
+ const parentOption = this.getOptionParent(option);
144
+ if (parentOption) {
145
+ const parentChildren = parentOption?.children;
146
+ const equalOption = intersectionBy(
147
+ selectedOptions,
148
+ parentChildren,
149
+ valueField
150
+ );
151
+ // 包含则选中父节点
152
+ const isParentSelected = find(selectedOptions, {
153
+ [valueField]: parentOption[valueField]
154
+ });
155
+ if (equalOption.length === parentChildren?.length && !isParentSelected) {
156
+ selectedOptions.push(parentOption);
157
+ }
158
+ if (equalOption.length !== parentChildren?.length && isParentSelected) {
159
+ const index = selectedOptions.findIndex(
160
+ (item: Option) => item[valueField] === parentOption[valueField]
161
+ );
162
+ selectedOptions.splice(index, 1);
163
+ }
164
+ return this.dealParentSelect(parentOption, selectedOptions);
165
+ } else {
166
+ return selectedOptions;
167
+ }
168
+ }
169
+
170
+ @autobind
171
+ flattenTreeWithLeafNodes(option: Option) {
172
+ return compact(
173
+ flattenTree(Array.isArray(option) ? option : [option], node => node)
174
+ );
175
+ }
176
+
177
+ @autobind
178
+ adjustOptionSelect(option: Option): boolean {
179
+ const {valueField = 'value'} = this.props;
180
+ const {selectedOptions} = this.state;
181
+ function loop(arr: any[]): boolean {
182
+ if (!arr.length) {
183
+ return false;
184
+ }
185
+ return arr.some((item: any) => item[valueField] === option[valueField]);
186
+ }
187
+ return loop(selectedOptions);
188
+ }
189
+
190
+ @autobind
191
+ getSelectedChildNum(option: Option): number {
192
+ let count = 0;
193
+ const loop = (arr: any[]) => {
194
+ if (!arr || !arr.length) {
195
+ return;
196
+ }
197
+ for (let item of arr) {
198
+ if (item.children) {
199
+ loop(item.children || []);
200
+ } else {
201
+ if (this.adjustOptionSelect(item)) {
202
+ count++;
203
+ }
204
+ }
205
+ }
206
+ };
207
+ loop(option.children || []);
208
+ return count;
209
+ }
210
+
211
+ @autobind
212
+ dealOptionDisable(selectedOptions: Options) {
213
+ const {
214
+ valueField = 'value',
215
+ options,
216
+ cascade,
217
+ multiple,
218
+ onlyChildren // 子节点可点击
219
+ } = this.props;
220
+ if (!multiple || cascade || onlyChildren) {
221
+ return;
222
+ }
223
+ const selectedValues = selectedOptions.map(
224
+ (option: Option) => option[valueField]
225
+ );
226
+ const loop = (option: Option) => {
227
+ if (!option.children) {
228
+ return;
229
+ }
230
+ option.children &&
231
+ option.children.forEach((childOption: Option) => {
232
+ if (
233
+ !selectedValues.includes(option[valueField]) &&
234
+ !option.disabled
235
+ ) {
236
+ childOption.disabled = false;
237
+ }
238
+
239
+ if (selectedValues.includes(option[valueField]) || option.disabled) {
240
+ childOption.disabled = true;
241
+ }
242
+ loop(childOption);
243
+ });
244
+ };
245
+ options.forEach((option: Option) => loop(option));
246
+ }
247
+
248
+ @autobind
249
+ dealChildrenSelect(option: Option, selectedOptions: Options) {
250
+ const {valueField = 'value'} = this.props;
251
+ let index = selectedOptions.findIndex(
252
+ (item: Option) => item[valueField] === option[valueField]
253
+ );
254
+ if (index !== -1) {
255
+ selectedOptions.splice(index, 1);
256
+ } else {
257
+ selectedOptions.push(option);
258
+ }
259
+ function loop(option: Option) {
260
+ if (!option.children) {
261
+ return;
262
+ }
263
+ option.children.forEach((item: Option) => {
264
+ if (index !== -1) {
265
+ // 删除选中节点及其子节点
266
+ selectedOptions = selectedOptions.filter(
267
+ (sItem: Option) => sItem[valueField] !== item[valueField]
268
+ );
269
+ } else {
270
+ // 添加节点及其子节点
271
+ selectedOptions.push(item);
272
+ }
273
+ loop(item);
274
+ });
275
+ }
276
+ loop(option);
277
+ return selectedOptions;
278
+ }
279
+
280
+ getParentTree = (option: Option, arr: Options): Options => {
281
+ const parentOption = this.getOptionParent(option);
282
+ if (parentOption) {
283
+ arr.push(parentOption);
284
+ return this.getParentTree(parentOption, arr);
285
+ }
286
+ return arr;
287
+ };
288
+
289
+ @autobind
290
+ onSelect(option: CascaderOption, tabIndex: number) {
291
+ const {multiple, valueField = 'value', cascade} = this.props;
292
+
293
+ let tabs = this.state.tabs.slice();
294
+ let {activeTab} = this.state;
295
+ let selectedOptions = this.state.selectedOptions;
296
+ const isDisable = option.disabled;
297
+ if (!isDisable) {
298
+ if (multiple) {
299
+ // 父子级分离
300
+ if (cascade) {
301
+ if (
302
+ option.isCheckAll ||
303
+ !option.children ||
304
+ !option.children.length
305
+ ) {
306
+ let index = selectedOptions.findIndex(
307
+ (item: Option) => item[valueField] === option[valueField]
308
+ );
309
+ if (index !== -1) {
310
+ selectedOptions.splice(index, 1);
311
+ } else {
312
+ selectedOptions.push(option);
313
+ }
314
+ }
315
+ } else {
316
+ if (
317
+ option.isCheckAll ||
318
+ !option.children ||
319
+ !option.children.length
320
+ ) {
321
+ selectedOptions = this.dealChildrenSelect(option, selectedOptions);
322
+ selectedOptions = this.dealParentSelect(option, selectedOptions);
323
+ }
324
+ }
325
+ } else {
326
+ // 单选
327
+ selectedOptions = this.getParentTree(option, [option]);
328
+ }
329
+ }
330
+ this.dealOptionDisable(selectedOptions);
331
+
332
+ if (tabs.length > tabIndex + 1) {
333
+ tabs = tabs.slice(0, tabIndex + 1);
334
+ }
335
+
336
+ requestAnimationFrame(() => {
337
+ const tabWidth = this.tabRef.current?.offsetWidth || 1;
338
+ const parentTree = this.getParentTree(option, [option]);
339
+ const scrollLeft = (parentTree.length - 2) * tabWidth;
340
+ if (scrollLeft !== 0) {
341
+ (this.tabsRef.current as HTMLElement).scrollTo(scrollLeft, 0);
342
+ }
343
+ });
344
+
345
+ if (option?.children && !option.isCheckAll) {
346
+ const nextTab = multiple
347
+ ? {
348
+ options: [
349
+ {
350
+ ...option,
351
+ isCheckAll: true
352
+ },
353
+ ...option.children
354
+ ]
355
+ }
356
+ : {
357
+ options: option.children
358
+ };
359
+
360
+ if (tabs[tabIndex + 1]) {
361
+ tabs[tabIndex + 1] = nextTab;
362
+ } else {
363
+ tabs.push(nextTab);
364
+ }
365
+ activeTab += 1;
366
+ }
367
+ this.setState({
368
+ tabs,
369
+ activeTab,
370
+ selectedOptions
371
+ });
372
+ }
373
+
374
+ @autobind
375
+ onNextClick(option: CascaderOption, tabIndex: number) {
376
+ let {activeTab} = this.state;
377
+ let tabs = this.state.tabs.slice();
378
+ if (option.c)
379
+ if (option?.children) {
380
+ const nextTab = {
381
+ options: option.children
382
+ };
383
+ if (tabs[tabIndex + 1]) {
384
+ tabs[tabIndex + 1] = nextTab;
385
+ } else {
386
+ tabs.push(nextTab);
387
+ }
388
+ activeTab += 1;
389
+ }
390
+ this.setState({
391
+ tabs,
392
+ activeTab
393
+ });
394
+ }
395
+
396
+ @autobind
397
+ getSubmitOptions(selectedOptions: Options): Options {
398
+ const _selectedOptions: Options = [];
399
+ const {
400
+ multiple,
401
+ options,
402
+ valueField = 'value',
403
+ cascade,
404
+ onlyChildren,
405
+ withChildren
406
+ } = this.props;
407
+ if (cascade || onlyChildren || withChildren || !multiple) {
408
+ return selectedOptions;
409
+ }
410
+ const selectedValues = selectedOptions.map(
411
+ (option: Option) => option[valueField]
412
+ );
413
+ function loop(options: Options) {
414
+ if (!options || !options.length) {
415
+ return;
416
+ }
417
+ options.forEach((option: Option) => {
418
+ if (selectedValues.includes(option[valueField])) {
419
+ _selectedOptions.push(option);
420
+ } else {
421
+ loop(option.children ? option.children : []);
422
+ }
423
+ });
424
+ }
425
+ loop(options);
426
+ return _selectedOptions;
427
+ }
428
+
429
+ @autobind
430
+ confirm() {
431
+ const {onChange, joinValues, delimiter, extractValue, valueField, onClose} =
432
+ this.props;
433
+ let {selectedOptions} = this.state;
434
+ let _selectedOptions = this.getSubmitOptions(selectedOptions);
435
+ _selectedOptions = uniqBy(_selectedOptions, valueField);
436
+ onChange(
437
+ joinValues
438
+ ? _selectedOptions
439
+ .map(item => item[valueField as string])
440
+ .join(delimiter)
441
+ : extractValue
442
+ ? _selectedOptions.map(item => item[valueField as string])
443
+ : _selectedOptions
444
+ );
445
+ onClose && onClose();
446
+ }
447
+
448
+ @autobind
449
+ renderOption(option: CascaderOption, tabIndex: number) {
450
+ const {
451
+ activeColor,
452
+ optionRender,
453
+ labelField,
454
+ valueField = 'value',
455
+ classnames: cx,
456
+ cascade,
457
+ multiple
458
+ } = this.props;
459
+ const {selectedOptions} = this.state;
460
+ const selectedValueArr = selectedOptions.map(item => item[valueField]);
461
+
462
+ let selfChecked = selectedValueArr.includes(option[valueField]);
463
+ const color = option.color || (selfChecked ? activeColor : undefined);
464
+ const Text = optionRender ? (
465
+ optionRender({option, selected: selfChecked})
466
+ ) : (
467
+ <span>{option[labelField]}</span>
468
+ );
469
+ return (
470
+ <li
471
+ className={cx(
472
+ 'Cascader-option',
473
+ {
474
+ selected: selfChecked,
475
+ disabled: option.disabled
476
+ },
477
+ option.className
478
+ )}
479
+ style={{color}}
480
+ onClick={() => this.onSelect(option, tabIndex)}
481
+ key={tabIndex + '-' + option[valueField]}
482
+ >
483
+ <span className={cx('Cascader-option--text')}>{Text}</span>
484
+ </li>
485
+ );
486
+ }
487
+
488
+ @autobind
489
+ renderOptions(options: Options, tabIndex: number) {
490
+ const {classnames: cx} = this.props;
491
+ return (
492
+ <ul key={tabIndex} className={cx('Cascader-options')}>
493
+ {options.map(option => this.renderOption(option, tabIndex))}
494
+ </ul>
495
+ );
496
+ }
497
+
498
+ @autobind
499
+ renderTabs() {
500
+ const {classnames: cx, options} = this.props;
501
+ const {tabs} = this.state;
502
+ const depth = getTreeDepth(options);
503
+ return (
504
+ <div
505
+ className={cx(`Cascader-tabs`, depth > 3 ? 'scrollable' : '')}
506
+ ref={this.tabsRef}
507
+ >
508
+ {tabs.map((tab: CascaderTab, tabIndex: number) => {
509
+ const {options} = tab;
510
+ return (
511
+ <div
512
+ className={cx(`Cascader-tab`)}
513
+ ref={this.tabRef}
514
+ key={tabIndex}
515
+ >
516
+ {this.renderOptions(options, tabIndex)}
517
+ </div>
518
+ );
519
+ })}
520
+ {depth <= 3 && options.length
521
+ ? Array(getTreeDepth(options) - tabs.length)
522
+ .fill(1)
523
+ .map((item: number, index: number) => (
524
+ <div className={cx(`Cascader-tab`)} key={index}></div>
525
+ ))
526
+ : null}
527
+ </div>
528
+ );
529
+ }
530
+
531
+ render() {
532
+ const {
533
+ classPrefix: ns,
534
+ classnames: cx,
535
+ className,
536
+ onClose,
537
+ translate: __
538
+ } = this.props;
539
+
540
+ return (
541
+ <div className={cx(`Cascader`, className)}>
542
+ <div className={cx(`Cascader-btnGroup`)}>
543
+ <Button
544
+ className={cx(`Cascader-btnCancel`)}
545
+ level="text"
546
+ onClick={onClose}
547
+ >
548
+ {__('cancel')}
549
+ </Button>
550
+ <Button
551
+ className={cx(`Cascader-btnConfirm`)}
552
+ level="text"
553
+ onClick={this.confirm}
554
+ >
555
+ {__('confirm')}
556
+ </Button>
557
+ </div>
558
+ {this.renderTabs()}
559
+ </div>
560
+ );
561
+ }
562
+ }
563
+
564
+ export default themeable(Cascader);