Skip to content

Commit 7f8c2d9

Browse files
authoredMar 16, 2022
feat(Transfer): 增加选项栏全选功能 (#676)
1 parent 211f4fe commit 7f8c2d9

File tree

2 files changed

+118
-6
lines changed

2 files changed

+118
-6
lines changed
 

‎packages/react-transfer/README.md

+36
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,41 @@ function Demo() {
4343
ReactDOM.render(<Demo />, _mount_);
4444
```
4545

46+
## 全部选择
47+
48+
<!--rehype:bgWhite=true&codeSandbox=true&codePen=true-->
49+
```jsx
50+
import React from 'react';
51+
import { Transfer } from 'uiw';
52+
53+
function Demo() {
54+
55+
const options = [
56+
{ label: '武汉市', key: 1 },
57+
{ label: '汉南区1', key: 5 },
58+
{ label: '汉南区2', key: 6 },
59+
{ label: '汉南区3', key: 7 },
60+
]
61+
62+
const [value,valueSet] = React.useState([{ label: '武汉市', key: 1 }, { label: '汉南区1', key: 5 }])
63+
64+
return (
65+
<Row style={{ flexDirection:'column' }} >
66+
<Transfer
67+
options={options}
68+
selectedAll={true}
69+
value={value}
70+
onChange={(transfer,option)=>{
71+
valueSet(option)
72+
}}
73+
/>
74+
</Row>
75+
);
76+
}
77+
78+
ReactDOM.render(<Demo />, _mount_);
79+
```
80+
4681
## 树形节点
4782

4883
<!--rehype:bgWhite=true&codeSandbox=true&codePen=true-->
@@ -248,3 +283,4 @@ ReactDOM.render(<Demo />, _mount_);
248283
| showSearch | 启用搜索 | boolean | false |
249284
| placeholder | 搜索输入框文字 | string | - |
250285
| onSearch | 搜索时回调函数 | (arrow, searchValue) => void | - |
286+
| selectedAll | 启用全部勾选 | boolean | false |

‎packages/react-transfer/src/index.tsx

+82-6
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,27 @@ import Input from '@uiw/react-input';
66
import TreeChecked from '@uiw/react-tree-checked';
77
import { TreeData } from '@uiw/react-tree';
88
import './style/index.less';
9+
import Checkbox from '@uiw/react-checkbox';
910

1011
export interface TransferOptionType {
1112
key: string | number;
1213
label: string;
1314
}
1415

16+
enum CheckedStatus {
17+
UnChecked = 0,
18+
AllChecked = 1,
19+
Indeterminate = 2,
20+
}
21+
1522
interface TransferProps extends IProps {
1623
placeholder?: string;
1724
bodyStyle?: React.CSSProperties;
1825

1926
onChange?: (transfer: string, selectedAll: Array<TransferOptionType>) => void;
2027
onSearch?: (transfer: string, seachValue: string) => void;
2128
showSearch?: boolean;
29+
selectedAll?: boolean;
2230
value?: Array<TransferOptionType>;
2331
options?: TreeData[];
2432
// emptyOption?: React.ReactNode;
@@ -30,6 +38,7 @@ function Transfer(props: TransferProps) {
3038
options,
3139
value,
3240
showSearch = false,
41+
selectedAll = false,
3342

3443
bodyStyle,
3544
style,
@@ -46,12 +55,17 @@ function Transfer(props: TransferProps) {
4655
const [leftSelectedKeys, leftSelectedKeySet] = useState<Array<string | number | undefined>>([]);
4756
const [rightSelectedKeys, rightSelectedKeySet] = useState<Array<string | number | undefined>>([]);
4857
const [rightOpions, rightOpionSet] = useState<Array<TreeData>>([]);
58+
const [selectAllChecked, selectAllCheckedSet] = useState<{ left: CheckedStatus; right: CheckedStatus }>({
59+
left: CheckedStatus.UnChecked,
60+
right: CheckedStatus.UnChecked,
61+
});
4962

5063
useEffect(() => {
5164
leftSelectedKeySet([]);
5265
rightSelectedKeySet([]);
5366

5467
rightOpionSet(value || []);
68+
5569
value?.forEach((selectd) => selectOption.set(selectd.key, selectd.label));
5670
hiddenNode((child) => !!value?.find((selectd) => child.key === selectd.key));
5771
}, [JSON.stringify(value)]);
@@ -63,7 +77,7 @@ function Transfer(props: TransferProps) {
6377
const isHide = callBackfn(child); // && parentIsHide;
6478
if (!!child.children?.length) {
6579
hiddenNodeForSeach(child.children);
66-
const find = child.children.find((item) => !item.hideNode);
80+
const find = child.children.find((item: TreeData) => !item.hideNode);
6781
child.hideNode = isHide && !find;
6882
} else {
6983
child.hideNode = isHide;
@@ -83,19 +97,38 @@ function Transfer(props: TransferProps) {
8397
isChecked: boolean,
8498
evn: TreeData,
8599
) => {
100+
selectedAllActive(selectedKeys, 'left');
101+
86102
leftSelectedKeySet(selectedKeys);
87103
const selectOptionTemp = getOptionsRecursion([evn], selectOption, isChecked);
88104
selectOptionSet(selectOptionTemp);
89105
};
90106

91107
const rightTreeOnSelected = (selectedKeys: Array<string | number | undefined>) => {
108+
selectedAllActive(selectedKeys, 'right');
109+
92110
rightSelectedKeySet(selectedKeys);
93111
selectedKeys.forEach((key) => {
94112
selectOption.delete(key!);
95113
});
96114
selectOptionSet(selectOption);
97115
};
98116

117+
function selectedAllActive(selectedKeys: (string | number | undefined)[], key: 'left' | 'right') {
118+
let selectedAll = true;
119+
rightOpions.forEach((selected) => {
120+
const find = selectedKeys.find((key) => key === selected.key);
121+
selectedAll = selectedAll && !!find;
122+
});
123+
selectAllChecked[key] = selectedAll
124+
? CheckedStatus.AllChecked
125+
: selectedKeys.length
126+
? CheckedStatus.Indeterminate
127+
: CheckedStatus.UnChecked;
128+
129+
selectAllCheckedSet(selectAllChecked);
130+
}
131+
99132
const getOptionsRecursion = (childrens: TreeData[], selectOption: Map<string | number, string>, isAdd: boolean) => {
100133
const addOrDel = (key: string | number, label: string, isAdd: boolean) => {
101134
if (isAdd) {
@@ -123,6 +156,9 @@ function Transfer(props: TransferProps) {
123156
};
124157

125158
const transferClick = (transferType: string) => {
159+
selectAllChecked.right = CheckedStatus.UnChecked;
160+
selectAllCheckedSet(selectAllChecked);
161+
126162
const option: Array<TransferOptionType> = [];
127163
selectOption.forEach((label, key) => option.push({ key, label }));
128164
props.onChange?.(transferType, option);
@@ -150,12 +186,28 @@ function Transfer(props: TransferProps) {
150186
const isHide = !(option.label as string).includes(searchValue.trim());
151187
option.hideNode = isHide;
152188
});
153-
console.log('rightOpions', rightOpions);
154189
rightOpionSet(rightOpions);
155190

156191
props.onSearch?.('right', searchValue);
157192
};
158193

194+
const selectAllCheckedChange = (e: React.ChangeEvent<HTMLInputElement>) => {
195+
const isChecked = e.target.checked;
196+
197+
selectAllChecked.right = isChecked ? 1 : 0;
198+
if (isChecked) {
199+
const keys = rightOpions.map((selected) => {
200+
selectOption.delete(selected.key!);
201+
return selected.key;
202+
});
203+
rightSelectedKeySet(keys);
204+
} else {
205+
rightSelectedKeySet([]);
206+
}
207+
selectOptionSet(selectOption);
208+
selectAllCheckedSet(selectAllChecked);
209+
};
210+
159211
const Arrow = (props: { click: () => void; style: React.CSSProperties }) => (
160212
<Icon
161213
onClick={() => props.click()}
@@ -169,7 +221,18 @@ function Transfer(props: TransferProps) {
169221
<div className={cls} style={{ width: 400, ...style }}>
170222
<Card
171223
bodyStyle={{ padding: 5 }}
172-
title={`${leftSelectedKeys.length}/${selectedOptionsShowCount.current}`}
224+
title={
225+
<div>
226+
{/* <Checkbox
227+
indeterminate={selectAllChecked.left === CheckedStatus.Indeterminate}
228+
checked={selectAllChecked.left === CheckedStatus.AllChecked}
229+
onChange={selectAllCheckedChange}
230+
/> */}
231+
<span style={{ marginLeft: 10 }}>
232+
{leftSelectedKeys.length}/{selectedOptionsShowCount.current}
233+
</span>
234+
</div>
235+
}
173236
className={`${prefixCls}-card`}
174237
>
175238
{showSearch && (
@@ -190,13 +253,26 @@ function Transfer(props: TransferProps) {
190253
</div>
191254
</Card>
192255
<div className={`${prefixCls}-arrow-content`}>
193-
<Arrow click={() => transferClick('left')} style={{ transform: 'rotate(90deg)' }} />
194-
<Arrow click={() => transferClick('right')} style={{ transform: 'rotate(-90deg)' }} />
256+
<Arrow click={() => transferClick('left')} style={{ transform: 'rotate(-90deg)' }} />
257+
<Arrow click={() => transferClick('right')} style={{ transform: 'rotate(90deg)' }} />
195258
</div>
196259
<Card
197260
bodyStyle={{ padding: 5 }}
198261
className={`${prefixCls}-card`}
199-
title={`${rightSelectedKeys.length}/${rightOpions.length}`}
262+
title={
263+
<div>
264+
{selectedAll && (
265+
<Checkbox
266+
indeterminate={selectAllChecked.right === CheckedStatus.Indeterminate}
267+
checked={selectAllChecked.right === CheckedStatus.AllChecked}
268+
onChange={selectAllCheckedChange}
269+
/>
270+
)}
271+
<span style={{ marginLeft: 10 }}>
272+
{rightSelectedKeys.length}/{rightOpions.length}
273+
</span>
274+
</div>
275+
}
200276
>
201277
{showSearch && (
202278
<Input

0 commit comments

Comments
 (0)
Please sign in to comment.