-
-
Notifications
You must be signed in to change notification settings - Fork 267
/
valueUtil.ts
141 lines (123 loc) · 4 KB
/
valueUtil.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import getValue from 'rc-util/lib/utils/get';
import setValue from 'rc-util/lib/utils/set';
import type { InternalNamePath, NamePath, Store, EventArgs } from '../interface';
import { toArray } from './typeUtil';
export { getValue, setValue };
/**
* Convert name to internal supported format.
* This function should keep since we still thinking if need support like `a.b.c` format.
* 'a' => ['a']
* 123 => [123]
* ['a', 123] => ['a', 123]
*/
export function getNamePath(path: NamePath | null): InternalNamePath {
return toArray(path);
}
export function cloneByNamePathList(store: Store, namePathList: InternalNamePath[]): Store {
let newStore = {};
namePathList.forEach(namePath => {
const value = getValue(store, namePath);
newStore = setValue(newStore, namePath, value);
});
return newStore;
}
/**
* Check if `namePathList` includes `namePath`.
* @param namePathList A list of `InternalNamePath[]`
* @param namePath Compare `InternalNamePath`
* @param partialMatch True will make `[a, b]` match `[a, b, c]`
*/
export function containsNamePath(
namePathList: InternalNamePath[],
namePath: InternalNamePath,
partialMatch = false,
) {
return namePathList && namePathList.some(path => matchNamePath(namePath, path, partialMatch));
}
/**
* Check if `namePath` is super set or equal of `subNamePath`.
* @param namePath A list of `InternalNamePath[]`
* @param subNamePath Compare `InternalNamePath`
* @param partialMatch True will make `[a, b]` match `[a, b, c]`
*/
export function matchNamePath(
namePath: InternalNamePath,
subNamePath: InternalNamePath | null,
partialMatch = false,
) {
if (!namePath || !subNamePath) {
return false;
}
if (!partialMatch && namePath.length !== subNamePath.length) {
return false;
}
return subNamePath.every((nameUnit, i) => namePath[i] === nameUnit);
}
// Like `shallowEqual`, but we not check the data which may cause re-render
type SimilarObject = string | number | object;
export function isSimilar(source: SimilarObject, target: SimilarObject) {
if (source === target) {
return true;
}
if ((!source && target) || (source && !target)) {
return false;
}
if (!source || !target || typeof source !== 'object' || typeof target !== 'object') {
return false;
}
const sourceKeys = Object.keys(source);
const targetKeys = Object.keys(target);
const keys = new Set([...sourceKeys, ...targetKeys]);
return [...keys].every(key => {
const sourceValue = source[key];
const targetValue = target[key];
if (typeof sourceValue === 'function' && typeof targetValue === 'function') {
return true;
}
return sourceValue === targetValue;
});
}
export function defaultGetValueFromEvent(valuePropName: string, ...args: EventArgs) {
const event = args[0];
if (event && event.target && typeof event.target === 'object' && valuePropName in event.target) {
return (event.target as HTMLInputElement)[valuePropName];
}
return event;
}
/**
* Moves an array item from one position in an array to another.
*
* Note: This is a pure function so a new array will be returned, instead
* of altering the array argument.
*
* @param array Array in which to move an item. (required)
* @param moveIndex The index of the item to move. (required)
* @param toIndex The index to move item at moveIndex to. (required)
*/
export function move<T>(array: T[], moveIndex: number, toIndex: number) {
const { length } = array;
if (moveIndex < 0 || moveIndex >= length || toIndex < 0 || toIndex >= length) {
return array;
}
const item = array[moveIndex];
const diff = moveIndex - toIndex;
if (diff > 0) {
// move left
return [
...array.slice(0, toIndex),
item,
...array.slice(toIndex, moveIndex),
...array.slice(moveIndex + 1, length),
];
}
if (diff < 0) {
// move right
return [
...array.slice(0, moveIndex),
...array.slice(moveIndex + 1, toIndex + 1),
item,
...array.slice(toIndex + 1, length),
];
}
return array;
}