@@ -6,19 +6,27 @@ import Input from '@uiw/react-input';
6
6
import TreeChecked from '@uiw/react-tree-checked' ;
7
7
import { TreeData } from '@uiw/react-tree' ;
8
8
import './style/index.less' ;
9
+ import Checkbox from '@uiw/react-checkbox' ;
9
10
10
11
export interface TransferOptionType {
11
12
key : string | number ;
12
13
label : string ;
13
14
}
14
15
16
+ enum CheckedStatus {
17
+ UnChecked = 0 ,
18
+ AllChecked = 1 ,
19
+ Indeterminate = 2 ,
20
+ }
21
+
15
22
interface TransferProps extends IProps {
16
23
placeholder ?: string ;
17
24
bodyStyle ?: React . CSSProperties ;
18
25
19
26
onChange ?: ( transfer : string , selectedAll : Array < TransferOptionType > ) => void ;
20
27
onSearch ?: ( transfer : string , seachValue : string ) => void ;
21
28
showSearch ?: boolean ;
29
+ selectedAll ?: boolean ;
22
30
value ?: Array < TransferOptionType > ;
23
31
options ?: TreeData [ ] ;
24
32
// emptyOption?: React.ReactNode;
@@ -30,6 +38,7 @@ function Transfer(props: TransferProps) {
30
38
options,
31
39
value,
32
40
showSearch = false ,
41
+ selectedAll = false ,
33
42
34
43
bodyStyle,
35
44
style,
@@ -46,12 +55,17 @@ function Transfer(props: TransferProps) {
46
55
const [ leftSelectedKeys , leftSelectedKeySet ] = useState < Array < string | number | undefined > > ( [ ] ) ;
47
56
const [ rightSelectedKeys , rightSelectedKeySet ] = useState < Array < string | number | undefined > > ( [ ] ) ;
48
57
const [ rightOpions , rightOpionSet ] = useState < Array < TreeData > > ( [ ] ) ;
58
+ const [ selectAllChecked , selectAllCheckedSet ] = useState < { left : CheckedStatus ; right : CheckedStatus } > ( {
59
+ left : CheckedStatus . UnChecked ,
60
+ right : CheckedStatus . UnChecked ,
61
+ } ) ;
49
62
50
63
useEffect ( ( ) => {
51
64
leftSelectedKeySet ( [ ] ) ;
52
65
rightSelectedKeySet ( [ ] ) ;
53
66
54
67
rightOpionSet ( value || [ ] ) ;
68
+
55
69
value ?. forEach ( ( selectd ) => selectOption . set ( selectd . key , selectd . label ) ) ;
56
70
hiddenNode ( ( child ) => ! ! value ?. find ( ( selectd ) => child . key === selectd . key ) ) ;
57
71
} , [ JSON . stringify ( value ) ] ) ;
@@ -63,7 +77,7 @@ function Transfer(props: TransferProps) {
63
77
const isHide = callBackfn ( child ) ; // && parentIsHide;
64
78
if ( ! ! child . children ?. length ) {
65
79
hiddenNodeForSeach ( child . children ) ;
66
- const find = child . children . find ( ( item ) => ! item . hideNode ) ;
80
+ const find = child . children . find ( ( item : TreeData ) => ! item . hideNode ) ;
67
81
child . hideNode = isHide && ! find ;
68
82
} else {
69
83
child . hideNode = isHide ;
@@ -83,19 +97,38 @@ function Transfer(props: TransferProps) {
83
97
isChecked : boolean ,
84
98
evn : TreeData ,
85
99
) => {
100
+ selectedAllActive ( selectedKeys , 'left' ) ;
101
+
86
102
leftSelectedKeySet ( selectedKeys ) ;
87
103
const selectOptionTemp = getOptionsRecursion ( [ evn ] , selectOption , isChecked ) ;
88
104
selectOptionSet ( selectOptionTemp ) ;
89
105
} ;
90
106
91
107
const rightTreeOnSelected = ( selectedKeys : Array < string | number | undefined > ) => {
108
+ selectedAllActive ( selectedKeys , 'right' ) ;
109
+
92
110
rightSelectedKeySet ( selectedKeys ) ;
93
111
selectedKeys . forEach ( ( key ) => {
94
112
selectOption . delete ( key ! ) ;
95
113
} ) ;
96
114
selectOptionSet ( selectOption ) ;
97
115
} ;
98
116
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
+
99
132
const getOptionsRecursion = ( childrens : TreeData [ ] , selectOption : Map < string | number , string > , isAdd : boolean ) => {
100
133
const addOrDel = ( key : string | number , label : string , isAdd : boolean ) => {
101
134
if ( isAdd ) {
@@ -123,6 +156,9 @@ function Transfer(props: TransferProps) {
123
156
} ;
124
157
125
158
const transferClick = ( transferType : string ) => {
159
+ selectAllChecked . right = CheckedStatus . UnChecked ;
160
+ selectAllCheckedSet ( selectAllChecked ) ;
161
+
126
162
const option : Array < TransferOptionType > = [ ] ;
127
163
selectOption . forEach ( ( label , key ) => option . push ( { key, label } ) ) ;
128
164
props . onChange ?.( transferType , option ) ;
@@ -150,12 +186,28 @@ function Transfer(props: TransferProps) {
150
186
const isHide = ! ( option . label as string ) . includes ( searchValue . trim ( ) ) ;
151
187
option . hideNode = isHide ;
152
188
} ) ;
153
- console . log ( 'rightOpions' , rightOpions ) ;
154
189
rightOpionSet ( rightOpions ) ;
155
190
156
191
props . onSearch ?.( 'right' , searchValue ) ;
157
192
} ;
158
193
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
+
159
211
const Arrow = ( props : { click : ( ) => void ; style : React . CSSProperties } ) => (
160
212
< Icon
161
213
onClick = { ( ) => props . click ( ) }
@@ -169,7 +221,18 @@ function Transfer(props: TransferProps) {
169
221
< div className = { cls } style = { { width : 400 , ...style } } >
170
222
< Card
171
223
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
+ }
173
236
className = { `${ prefixCls } -card` }
174
237
>
175
238
{ showSearch && (
@@ -190,13 +253,26 @@ function Transfer(props: TransferProps) {
190
253
</ div >
191
254
</ Card >
192
255
< 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)' } } />
195
258
</ div >
196
259
< Card
197
260
bodyStyle = { { padding : 5 } }
198
261
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
+ }
200
276
>
201
277
{ showSearch && (
202
278
< Input
0 commit comments