@douyinfe/semi-foundation 2.24.0 → 2.24.1-alpha.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.
- package/cascader/foundation.ts +39 -20
- package/cascader/util.ts +288 -6
- package/datePicker/yearAndMonthFoundation.ts +26 -2
- package/lib/cjs/cascader/foundation.d.ts +4 -1
- package/lib/cjs/cascader/foundation.js +33 -18
- package/lib/cjs/cascader/util.d.ts +19 -0
- package/lib/cjs/cascader/util.js +354 -5
- package/lib/cjs/datePicker/yearAndMonthFoundation.d.ts +5 -1
- package/lib/cjs/datePicker/yearAndMonthFoundation.js +56 -1
- package/lib/cjs/tree/treeUtil.d.ts +1 -0
- package/lib/cjs/tree/treeUtil.js +1 -0
- package/lib/es/cascader/foundation.d.ts +4 -1
- package/lib/es/cascader/foundation.js +28 -13
- package/lib/es/cascader/util.d.ts +19 -0
- package/lib/es/cascader/util.js +334 -5
- package/lib/es/datePicker/yearAndMonthFoundation.d.ts +5 -1
- package/lib/es/datePicker/yearAndMonthFoundation.js +55 -1
- package/lib/es/tree/treeUtil.d.ts +1 -0
- package/lib/es/tree/treeUtil.js +1 -3
- package/package.json +2 -2
- package/tree/treeUtil.ts +1 -1
package/cascader/foundation.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { isEqual, get, difference, isUndefined, assign, cloneDeep, isEmpty, isNumber, includes } from 'lodash';
|
|
2
2
|
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
3
|
+
import { filter } from '../tree/treeUtil';
|
|
4
|
+
import { Motion } from '../utils/type';
|
|
3
5
|
import {
|
|
4
|
-
|
|
6
|
+
convertDataToEntities,
|
|
7
|
+
findKeysForValues,
|
|
8
|
+
normalizedArr,
|
|
9
|
+
isValid,
|
|
10
|
+
calcMergeType,
|
|
5
11
|
findAncestorKeys,
|
|
12
|
+
|
|
6
13
|
calcCheckedKeysForUnchecked,
|
|
14
|
+
|
|
7
15
|
calcCheckedKeysForChecked,
|
|
16
|
+
|
|
8
17
|
calcCheckedKeys,
|
|
18
|
+
|
|
9
19
|
findDescendantKeys,
|
|
10
20
|
normalizeKeyList
|
|
11
|
-
} from '../tree/treeUtil';
|
|
12
|
-
import { Motion } from '../utils/type';
|
|
13
|
-
import {
|
|
14
|
-
convertDataToEntities,
|
|
15
|
-
findKeysForValues,
|
|
16
|
-
normalizedArr,
|
|
17
|
-
isValid,
|
|
18
|
-
calcMergeType
|
|
19
21
|
} from './util';
|
|
20
22
|
import { strings } from './constants';
|
|
21
23
|
import isEnterPress from '../utils/isEnterPress';
|
|
@@ -24,7 +26,8 @@ export interface BasicData {
|
|
|
24
26
|
data: BasicCascaderData;
|
|
25
27
|
disabled: boolean;
|
|
26
28
|
key: string;
|
|
27
|
-
searchText: any[]
|
|
29
|
+
searchText: any[];
|
|
30
|
+
childrenKeys?: string[]
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export interface BasicEntities {
|
|
@@ -35,6 +38,7 @@ export interface BasicEntity {
|
|
|
35
38
|
_notExist?: boolean;
|
|
36
39
|
/* children list */
|
|
37
40
|
children?: Array<BasicEntity>;
|
|
41
|
+
childrenKeys?: string[];
|
|
38
42
|
/* treedata */
|
|
39
43
|
data: BasicCascaderData;
|
|
40
44
|
/* index */
|
|
@@ -60,7 +64,8 @@ export interface BasicCascaderData {
|
|
|
60
64
|
disabled?: boolean;
|
|
61
65
|
isLeaf?: boolean;
|
|
62
66
|
loading?: boolean;
|
|
63
|
-
children?: BasicCascaderData[]
|
|
67
|
+
children?: BasicCascaderData[];
|
|
68
|
+
childrenKeys?: string[]
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
export type CascaderType = 'large' | 'small' | 'default';
|
|
@@ -262,11 +267,19 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
262
267
|
}
|
|
263
268
|
}
|
|
264
269
|
|
|
265
|
-
_isLeaf(item: BasicCascaderData) {
|
|
270
|
+
// _isLeaf(item: BasicCascaderData) {
|
|
271
|
+
// if (this.getProp('loadData')) {
|
|
272
|
+
// return Boolean(item.isLeaf);
|
|
273
|
+
// }
|
|
274
|
+
// return !item.children || !item.children.length;
|
|
275
|
+
// }
|
|
276
|
+
|
|
277
|
+
_isLeaf(item: BasicEntity | BasicData) {
|
|
278
|
+
const { data, childrenKeys } = item;
|
|
266
279
|
if (this.getProp('loadData')) {
|
|
267
|
-
return Boolean(
|
|
280
|
+
return Boolean(data.isLeaf);
|
|
268
281
|
}
|
|
269
|
-
return !
|
|
282
|
+
return !childrenKeys || !childrenKeys;
|
|
270
283
|
}
|
|
271
284
|
|
|
272
285
|
_clearInput() {
|
|
@@ -430,7 +443,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
430
443
|
* When changeOnSelect is turned on, or the target option is a leaf option,
|
|
431
444
|
* the option is considered to be selected, even if the option is disabled
|
|
432
445
|
*/
|
|
433
|
-
if (changeOnSelect || this._isLeaf(selectedItem.data)) {
|
|
446
|
+
// if (changeOnSelect || this._isLeaf(selectedItem.data)) {
|
|
447
|
+
if (changeOnSelect || this._isLeaf(selectedItem)) {
|
|
434
448
|
updateStates.selectedKeys = new Set([selectedKey]);
|
|
435
449
|
if (!loadingActive.length) {
|
|
436
450
|
updateStates.activeKeys = new Set(selectedItem.path);
|
|
@@ -574,7 +588,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
574
588
|
handleShowNextByHover(item: BasicEntity) {
|
|
575
589
|
const { keyEntities } = this.getStates();
|
|
576
590
|
const { data, key } = item;
|
|
577
|
-
const isLeaf = this._isLeaf(
|
|
591
|
+
const isLeaf = this._isLeaf(item);
|
|
578
592
|
const activeKeys = keyEntities[key].path;
|
|
579
593
|
this._adapter.updateStates({
|
|
580
594
|
activeKeys: new Set(activeKeys)
|
|
@@ -657,7 +671,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
657
671
|
notifyIfLoadData(item: BasicEntity | BasicData) {
|
|
658
672
|
const { data, key } = item;
|
|
659
673
|
this._adapter.updateStates({ loading: false });
|
|
660
|
-
if (!data.isLeaf && !data.children && this.getProp('loadData')) {
|
|
674
|
+
// if (!data.isLeaf && !data.children && this.getProp('loadData')) {
|
|
675
|
+
if (!data.isLeaf && !data.childrenKeys && this.getProp('loadData')) {
|
|
661
676
|
const { loadedKeys, loadingKeys } = this.getCopyFromState(['loadedKeys', 'loadingKeys']);
|
|
662
677
|
if (loadedKeys.has(key) || loadingKeys.has(key)) {
|
|
663
678
|
return;
|
|
@@ -676,7 +691,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
676
691
|
const filterable = this._isFilterable();
|
|
677
692
|
const { data, key } = item;
|
|
678
693
|
|
|
679
|
-
const isLeaf = this._isLeaf(data);
|
|
694
|
+
// const isLeaf = this._isLeaf(data);
|
|
695
|
+
const isLeaf = this._isLeaf(item);
|
|
680
696
|
|
|
681
697
|
const activeKeys = keyEntities[key].path;
|
|
682
698
|
const selectedKey = [key];
|
|
@@ -872,7 +888,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
872
888
|
})
|
|
873
889
|
.filter(
|
|
874
890
|
item => (filterTreeNode && !filterLeafOnly) ||
|
|
875
|
-
this._isLeaf(item
|
|
891
|
+
// this._isLeaf(item.data)
|
|
892
|
+
this._isLeaf(item)
|
|
876
893
|
)
|
|
877
894
|
.map(item => item.key);
|
|
878
895
|
}
|
|
@@ -942,6 +959,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
942
959
|
if (isSearching && isFilterable) {
|
|
943
960
|
return this.getFilteredData();
|
|
944
961
|
}
|
|
962
|
+
|
|
945
963
|
return (Object.values(keyEntities) as BasicEntity[])
|
|
946
964
|
.filter(item => item.parentKey === null && !item._notExist)
|
|
947
965
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -965,7 +983,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
965
983
|
data: item.data,
|
|
966
984
|
key,
|
|
967
985
|
disabled: isDisabled,
|
|
968
|
-
searchText: itemSearchPath
|
|
986
|
+
searchText: itemSearchPath,
|
|
987
|
+
childrenKeys: item.childrenKeys,
|
|
969
988
|
});
|
|
970
989
|
});
|
|
971
990
|
return filteredList;
|
package/cascader/util.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isNull,
|
|
3
3
|
isUndefined,
|
|
4
|
-
isEqual
|
|
4
|
+
isEqual,
|
|
5
|
+
uniq,
|
|
6
|
+
isEmpty,
|
|
7
|
+
max
|
|
5
8
|
} from 'lodash';
|
|
6
9
|
import { strings } from './constants';
|
|
7
10
|
|
|
11
|
+
import { KeyEntities, getSortedKeyList } from '../tree/treeUtil';
|
|
12
|
+
|
|
8
13
|
function getPosition(level: any, index: any) {
|
|
9
14
|
return `${level}-${index}`;
|
|
10
15
|
}
|
|
@@ -31,8 +36,9 @@ function traverseDataNodes(treeNodes: any, callback: any) {
|
|
|
31
36
|
// Process node if is not root
|
|
32
37
|
if (node) {
|
|
33
38
|
const key = parent ? getPosition(parent.key, ind) : `${ind}`;
|
|
39
|
+
const { children, ...resetInfo } = node;
|
|
34
40
|
item = {
|
|
35
|
-
data: { ...
|
|
41
|
+
data: { ...resetInfo },
|
|
36
42
|
ind,
|
|
37
43
|
key,
|
|
38
44
|
level: parent ? parent.level + 1 : 0,
|
|
@@ -65,10 +71,17 @@ export function convertDataToEntities(dataNodes: any) {
|
|
|
65
71
|
keyEntities[key] = entity;
|
|
66
72
|
|
|
67
73
|
// Fill children
|
|
68
|
-
entity.parent = keyEntities[parentKey];
|
|
69
|
-
if (entity.parent) {
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
// entity.parent = keyEntities[parentKey];
|
|
75
|
+
// if (entity.parent) {
|
|
76
|
+
// entity.parent.children = entity.parent.children || [];
|
|
77
|
+
// entity.parent.children.push(entity);
|
|
78
|
+
// }
|
|
79
|
+
const entityParent = keyEntities[parentKey];
|
|
80
|
+
if (entityParent) {
|
|
81
|
+
// entityParent.children = entityParent.children || [];
|
|
82
|
+
// entityParent.children.push(entity);
|
|
83
|
+
entityParent.childrenKeys = entityParent.childrenKeys || [];
|
|
84
|
+
entityParent.childrenKeys.push(key);
|
|
72
85
|
}
|
|
73
86
|
});
|
|
74
87
|
return keyEntities;
|
|
@@ -92,4 +105,273 @@ export function calcMergeType(autoMergeValue: boolean, leafOnly: boolean): strin
|
|
|
92
105
|
mergeType = strings.NONE_MERGE_TYPE;
|
|
93
106
|
}
|
|
94
107
|
return mergeType;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function findChildKeys(keys: string[], options: any, omitKeys: any[] = []) {
|
|
111
|
+
const res: any[] = [];
|
|
112
|
+
keys &&
|
|
113
|
+
keys.forEach(key => {
|
|
114
|
+
const opts = options[key];
|
|
115
|
+
// opts &&
|
|
116
|
+
// opts.children &&
|
|
117
|
+
// opts.children.forEach((child: any) => {
|
|
118
|
+
// if (!omitKeys.length || !omitKeys.includes(child.key)) {
|
|
119
|
+
// res.push(child.key);
|
|
120
|
+
// }
|
|
121
|
+
// });
|
|
122
|
+
opts &&
|
|
123
|
+
opts.childrenKeys &&
|
|
124
|
+
opts.childrenKeys.forEach((child: any) => {
|
|
125
|
+
if (!omitKeys.length || !omitKeys.includes(child.key)) {
|
|
126
|
+
res.push(child.key);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
return res;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function findSiblingKeys(selectedKeys: string[], options: any, self = true) {
|
|
134
|
+
const par: any[] = [];
|
|
135
|
+
// selectedKeys.forEach(item => {
|
|
136
|
+
// if (options[item] && options[item].parent) {
|
|
137
|
+
// par.push(options[item].parent.key);
|
|
138
|
+
// }
|
|
139
|
+
// });
|
|
140
|
+
selectedKeys.forEach(item => {
|
|
141
|
+
if (options[item] && options[item].parentKey) {
|
|
142
|
+
par.push(options[item].parentKey);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
const res = findChildKeys(uniq(par), options, self ? [] : selectedKeys);
|
|
148
|
+
return res;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function findAncestorKeys(selectedKeys: string[], options: any, self = true) {
|
|
152
|
+
const res: any[] = [];
|
|
153
|
+
// Recursively find the parent element
|
|
154
|
+
// const findPar = (item: any) => {
|
|
155
|
+
// if (item.parent) {
|
|
156
|
+
// res.push(item.parent.key);
|
|
157
|
+
// findPar(item.parent);
|
|
158
|
+
// }
|
|
159
|
+
// };
|
|
160
|
+
const findPar = (item: any) => {
|
|
161
|
+
if (item.parentKey) {
|
|
162
|
+
res.push(item.parentKey);
|
|
163
|
+
findPar(options[item.parentKey]);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
selectedKeys.forEach(item => {
|
|
167
|
+
options[item] && findPar(options[item]);
|
|
168
|
+
if (self) {
|
|
169
|
+
res.push(item);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return res;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function calcCheckedKeysForUnchecked(key: string, keyEntities: KeyEntities, checkedKeys: Set<string>, halfCheckedKeys: Set<string>) {
|
|
176
|
+
const descendantKeys = findDescendantKeys([key], keyEntities, true);
|
|
177
|
+
const nodeItem = keyEntities[key];
|
|
178
|
+
descendantKeys.forEach(descendantKey => {
|
|
179
|
+
if (checkedKeys.has(descendantKey)) {
|
|
180
|
+
checkedKeys.delete(descendantKey);
|
|
181
|
+
}
|
|
182
|
+
if (halfCheckedKeys.has(descendantKey)) {
|
|
183
|
+
halfCheckedKeys.delete(descendantKey);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
const calcCurrLevel = (node: any) => {
|
|
187
|
+
// const par = node.parent;
|
|
188
|
+
const par = keyEntities[node.parentKey];
|
|
189
|
+
// no parent
|
|
190
|
+
if (!par) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// Has a parent node, and the parent node is not checked or halfChecked
|
|
194
|
+
if (!checkedKeys.has(par.key) && !halfCheckedKeys.has(par.key)) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Has a parent node, and the parent node is checked or halfChecked
|
|
198
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
199
|
+
const { key } = node;
|
|
200
|
+
const siblingKeys = findSiblingKeys([key], keyEntities);
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
202
|
+
const anyChecked = siblingKeys.some(key => checkedKeys.has(key) || halfCheckedKeys.has(key));
|
|
203
|
+
const ancestorKeys = findAncestorKeys([key], keyEntities, false);
|
|
204
|
+
// If there is checked or halfChecked in the sibling node, you need to change the parent node to halfChecked
|
|
205
|
+
if (anyChecked) {
|
|
206
|
+
ancestorKeys.forEach(itemKey => {
|
|
207
|
+
if (checkedKeys.has(itemKey)) {
|
|
208
|
+
checkedKeys.delete(itemKey);
|
|
209
|
+
halfCheckedKeys.add(itemKey);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
// If there is no checked or halfChecked in the sibling node, you need to change the parent node to unchecked
|
|
213
|
+
} else {
|
|
214
|
+
if (checkedKeys.has(par.key)) {
|
|
215
|
+
checkedKeys.delete(par.key);
|
|
216
|
+
}
|
|
217
|
+
if (halfCheckedKeys.has(par.key)) {
|
|
218
|
+
halfCheckedKeys.delete(par.key);
|
|
219
|
+
}
|
|
220
|
+
calcCurrLevel(par);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
calcCurrLevel(nodeItem);
|
|
224
|
+
return {
|
|
225
|
+
checkedKeys,
|
|
226
|
+
halfCheckedKeys,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function calcCheckedKeysForChecked(key: string, keyEntities: KeyEntities, checkedKeys: Set<string>, halfCheckedKeys: Set<string>) {
|
|
231
|
+
const descendantKeys = findDescendantKeys([key], keyEntities, true);
|
|
232
|
+
const nodeItem = keyEntities[key];
|
|
233
|
+
checkedKeys = new Set([...checkedKeys, key]);
|
|
234
|
+
const calcCurrLevel = (node: any) => {
|
|
235
|
+
// if (!node.parent) {
|
|
236
|
+
// return;
|
|
237
|
+
// }
|
|
238
|
+
const par = keyEntities[node.parentKey];
|
|
239
|
+
if (!par) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
243
|
+
const { key } = node;
|
|
244
|
+
const siblingKeys = findSiblingKeys([key], keyEntities);
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
246
|
+
const allChecked = siblingKeys.every(key => checkedKeys.has(key));
|
|
247
|
+
if (!allChecked) {
|
|
248
|
+
const ancestorKeys = findAncestorKeys([key], keyEntities, false);
|
|
249
|
+
halfCheckedKeys = new Set([...halfCheckedKeys, ...ancestorKeys]);
|
|
250
|
+
} else {
|
|
251
|
+
// const par = node.parent;
|
|
252
|
+
checkedKeys.add(par.key);
|
|
253
|
+
calcCurrLevel(par);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
calcCurrLevel(nodeItem);
|
|
257
|
+
return {
|
|
258
|
+
checkedKeys: new Set([...checkedKeys, ...descendantKeys]),
|
|
259
|
+
halfCheckedKeys,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function calcCheckedKeys(values: any, keyEntities: KeyEntities) {
|
|
264
|
+
const keyList = Array.isArray(values) ? values : [values];
|
|
265
|
+
const descendantKeys = findDescendantKeys(keyList, keyEntities, true);
|
|
266
|
+
/**
|
|
267
|
+
* Recursively find the parent element. Because the incoming nodes are all checked,
|
|
268
|
+
* their descendants must be checked. That is to say, if the descendant nodes have
|
|
269
|
+
* disabled+unchecked nodes, their ancestor nodes will definitely not be checked
|
|
270
|
+
*/
|
|
271
|
+
const checkedKeys = new Set([...descendantKeys]);
|
|
272
|
+
let halfCheckedKeys = new Set([]);
|
|
273
|
+
let visited: any[] = [];
|
|
274
|
+
|
|
275
|
+
const levelMap:{[key: number]: string[]} = getSortedKeyList(keyList, keyEntities);
|
|
276
|
+
|
|
277
|
+
const calcCurrLevel = (node: any) => {
|
|
278
|
+
// const { key, parent, level } = node;
|
|
279
|
+
const { key, parentKey, level } = node;
|
|
280
|
+
const parent = keyEntities[parentKey];
|
|
281
|
+
// If the node does not have a parent node, or the node has been processed just now, no processing is done
|
|
282
|
+
if (!parent || visited.includes(key)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const siblingKeys = findSiblingKeys([key], keyEntities);
|
|
287
|
+
// visited for caching to avoid double counting
|
|
288
|
+
visited = [...visited, ...siblingKeys];
|
|
289
|
+
const allChecked = siblingKeys.every((siblingKey: string) => checkedKeys.has(siblingKey));
|
|
290
|
+
if (!allChecked) {
|
|
291
|
+
const ancestorKeys = findAncestorKeys([key], keyEntities, false);
|
|
292
|
+
halfCheckedKeys = new Set([...halfCheckedKeys, ...ancestorKeys]);
|
|
293
|
+
} else {
|
|
294
|
+
checkedKeys.add(parent.key);
|
|
295
|
+
// IMPORTANT! parent level may not exist in original level map; if add to the end directly may destroy the hierarchical order
|
|
296
|
+
if (level - 1 in levelMap && level) {
|
|
297
|
+
levelMap[level - 1].push(parent.key);
|
|
298
|
+
} else {
|
|
299
|
+
levelMap[level - 1] = [parent.key];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
// Loop keyList from deepest Level to topLevel, bottom up
|
|
304
|
+
while (!isEmpty(levelMap)) {
|
|
305
|
+
const maxLevel = max(Object.keys(levelMap).map(key => Number(key)));
|
|
306
|
+
levelMap[maxLevel].forEach((key: string) => calcCurrLevel(keyEntities[key]));
|
|
307
|
+
delete levelMap[maxLevel];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
checkedKeys,
|
|
312
|
+
halfCheckedKeys,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function findDescendantKeys(selectedKeys: string[], options: KeyEntities, self = true) {
|
|
317
|
+
const res: string[] = [];
|
|
318
|
+
const findChild = (item: any) => {
|
|
319
|
+
if (!item) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
// const { children } = item;
|
|
323
|
+
// const hasChildren = isValid(children);
|
|
324
|
+
// if (hasChildren) {
|
|
325
|
+
// children.forEach((child: any) => {
|
|
326
|
+
// res.push(child.key);
|
|
327
|
+
// findChild(options[child.key]);
|
|
328
|
+
// });
|
|
329
|
+
// }
|
|
330
|
+
const { childrenKeys } = item;
|
|
331
|
+
const hasChildren = isValid(childrenKeys);
|
|
332
|
+
if (hasChildren) {
|
|
333
|
+
childrenKeys.forEach((childKey: any) => {
|
|
334
|
+
res.push(childKey);
|
|
335
|
+
findChild(options[childKey]);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
selectedKeys.forEach(item => {
|
|
340
|
+
if (self) {
|
|
341
|
+
res.push(item);
|
|
342
|
+
}
|
|
343
|
+
findChild(options[item]);
|
|
344
|
+
});
|
|
345
|
+
return res;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export function normalizeKeyList(keyList: any, keyEntities: KeyEntities, leafOnly = false) {
|
|
349
|
+
const res: string[] = [];
|
|
350
|
+
const keyListSet = new Set(keyList);
|
|
351
|
+
if (!leafOnly) {
|
|
352
|
+
keyList.forEach((key: string) => {
|
|
353
|
+
if (!keyEntities[key]) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const { parentKey } = keyEntities[key];
|
|
357
|
+
if (parentKey && keyListSet.has(parentKey)) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
res.push(key);
|
|
361
|
+
});
|
|
362
|
+
} else {
|
|
363
|
+
keyList.forEach(key => {
|
|
364
|
+
// if (keyEntities[key] && !isValid(keyEntities[key].children)) {
|
|
365
|
+
if (keyEntities[key] && !isValid(keyEntities[key].childrenKeys)) {
|
|
366
|
+
res.push(key);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return res;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export function calcDisabledKeys(keyEntities: KeyEntities) {
|
|
374
|
+
const disabledKeys = Object.keys(keyEntities).filter(key => keyEntities[key].data.disabled);
|
|
375
|
+
const { checkedKeys } = calcCheckedKeys(disabledKeys, keyEntities);
|
|
376
|
+
return checkedKeys;
|
|
95
377
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setMonth, setYear } from 'date-fns';
|
|
1
2
|
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
3
|
import { PresetPosition } from './foundation';
|
|
3
4
|
|
|
@@ -26,7 +27,7 @@ export interface YearAndMonthFoundationState {
|
|
|
26
27
|
currentMonth: number
|
|
27
28
|
}
|
|
28
29
|
export interface YearAndMonthAdapter extends DefaultAdapter<YearAndMonthFoundationProps, YearAndMonthFoundationState> {
|
|
29
|
-
setCurrentYear: (currentYear: number) => void;
|
|
30
|
+
setCurrentYear: (currentYear: number, cb?: () => void) => void;
|
|
30
31
|
setCurrentMonth: (currentMonth: number) => void;
|
|
31
32
|
notifySelectYear: (year: number) => void;
|
|
32
33
|
notifySelectMonth: (month: number) => void;
|
|
@@ -61,7 +62,7 @@ export default class YearAndMonthFoundation extends BaseFoundation<YearAndMonthA
|
|
|
61
62
|
|
|
62
63
|
selectYear(item: YearScrollItem) {
|
|
63
64
|
const year = item.value;
|
|
64
|
-
this._adapter.setCurrentYear(year);
|
|
65
|
+
this._adapter.setCurrentYear(year, () => this.autoSelectMonth(item));
|
|
65
66
|
this._adapter.notifySelectYear(year);
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -71,6 +72,29 @@ export default class YearAndMonthFoundation extends BaseFoundation<YearAndMonthA
|
|
|
71
72
|
this._adapter.notifySelectMonth(month);
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* After selecting a year, if the currentMonth is disabled, automatically select a non-disabled month
|
|
77
|
+
*/
|
|
78
|
+
autoSelectMonth(item: YearScrollItem) {
|
|
79
|
+
const { disabledDate, locale } = this._adapter.getProps();
|
|
80
|
+
const { months, currentMonth } = this._adapter.getStates();
|
|
81
|
+
|
|
82
|
+
const currentDate = setYear(Date.now(), item.year);
|
|
83
|
+
const isCurrentMonthDisabled = disabledDate(setMonth(currentDate, currentMonth - 1));
|
|
84
|
+
if (isCurrentMonthDisabled) {
|
|
85
|
+
const currentIndex = months.findIndex(({ month }) => month === currentMonth);
|
|
86
|
+
let validMonth: typeof months[number];
|
|
87
|
+
// First look in the back, if you can't find it in the back, then look in the front
|
|
88
|
+
validMonth = months.slice(currentIndex).find(({ month }) => !disabledDate(setMonth(currentDate, month - 1)));
|
|
89
|
+
if (!validMonth) {
|
|
90
|
+
validMonth = months.slice(0, currentIndex).find(({ month }) => !disabledDate(setMonth(currentDate, month - 1)));
|
|
91
|
+
}
|
|
92
|
+
if (validMonth) {
|
|
93
|
+
this.selectMonth({ month: validMonth.month, value: locale.fullMonths[validMonth.month], disabled: false });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
74
98
|
backToMain() {
|
|
75
99
|
this._adapter.notifyBackToMain();
|
|
76
100
|
}
|
|
@@ -4,6 +4,7 @@ export interface BasicData {
|
|
|
4
4
|
disabled: boolean;
|
|
5
5
|
key: string;
|
|
6
6
|
searchText: any[];
|
|
7
|
+
childrenKeys?: string[];
|
|
7
8
|
}
|
|
8
9
|
export interface BasicEntities {
|
|
9
10
|
[idx: string]: BasicEntity;
|
|
@@ -11,6 +12,7 @@ export interface BasicEntities {
|
|
|
11
12
|
export interface BasicEntity {
|
|
12
13
|
_notExist?: boolean;
|
|
13
14
|
children?: Array<BasicEntity>;
|
|
15
|
+
childrenKeys?: string[];
|
|
14
16
|
data: BasicCascaderData;
|
|
15
17
|
ind: number;
|
|
16
18
|
key: string;
|
|
@@ -28,6 +30,7 @@ export interface BasicCascaderData {
|
|
|
28
30
|
isLeaf?: boolean;
|
|
29
31
|
loading?: boolean;
|
|
30
32
|
children?: BasicCascaderData[];
|
|
33
|
+
childrenKeys?: string[];
|
|
31
34
|
}
|
|
32
35
|
export declare type CascaderType = 'large' | 'small' | 'default';
|
|
33
36
|
export declare type BasicSimpleValueType = string | number | BasicCascaderData;
|
|
@@ -171,7 +174,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
171
174
|
_isDisabled(): any;
|
|
172
175
|
_isFilterable(): boolean;
|
|
173
176
|
_notifyChange(item: BasicEntity | BasicData | Set<string>): void;
|
|
174
|
-
_isLeaf(item:
|
|
177
|
+
_isLeaf(item: BasicEntity | BasicData): boolean;
|
|
175
178
|
_clearInput(): void;
|
|
176
179
|
_notifyBlur(e: any): void;
|
|
177
180
|
_notifyFocus(e: any): void;
|