@@ -8,17 +8,45 @@ import fnToString from '../utils/fn-to-string';
8
8
import reducer from './reducer' ;
9
9
import useIsMounted from '../hooks/use-is-mounted' ;
10
10
11
- const getSelectValue = ( stateValue , simpleValue , isMulti , allOptions ) =>
12
- simpleValue ? allOptions . filter ( ( { value } ) => ( isMulti ? stateValue . includes ( value ) : isEqual ( value , stateValue ) ) ) : stateValue ;
11
+ const getSelectValue = ( stateValue , simpleValue , isMulti , allOptions ) => {
12
+ let enhancedValue = stateValue ;
13
13
14
- const handleSelectChange = ( option , simpleValue , isMulti , onChange , allOptions ) => {
15
- const sanitizedOption = ! option && isMulti ? [ ] : option ;
14
+ let hasSelectAll = isMulti && allOptions . find ( ( { selectAll } ) => selectAll ) ;
15
+ let hasSelectNone = isMulti && allOptions . find ( ( { selectNone } ) => selectNone ) ;
16
16
17
- if ( isMulti && option . find ( ( { selectAll } ) => selectAll ) ) {
18
- return onChange ( allOptions . filter ( ( { selectAll } ) => ! selectAll ) . map ( ( { value } ) => value ) ) ;
17
+ if ( hasSelectAll || hasSelectNone ) {
18
+ enhancedValue = enhancedValue || [ ] ;
19
+ const optionsLength = allOptions . filter ( ( { selectAll, selectNone } ) => ! selectAll && ! selectNone ) . length ;
20
+
21
+ const selectedAll = optionsLength === enhancedValue . length ;
22
+ const selectedNone = enhancedValue . length === 0 ;
23
+
24
+ enhancedValue = [
25
+ ...enhancedValue ,
26
+ ...( hasSelectAll && selectedAll ? [ simpleValue ? hasSelectAll . value : hasSelectAll ] : [ ] ) ,
27
+ ...( hasSelectNone && selectedNone ? [ simpleValue ? hasSelectNone . value : hasSelectNone ] : [ ] )
28
+ ] ;
19
29
}
20
30
21
- if ( isMulti && option . find ( ( { selectNone } ) => selectNone ) ) {
31
+ return simpleValue ? allOptions . filter ( ( { value } ) => ( isMulti ? enhancedValue . includes ( value ) : isEqual ( value , enhancedValue ) ) ) : enhancedValue ;
32
+ } ;
33
+
34
+ const handleSelectChange = ( option , simpleValue , isMulti , onChange , allOptions , removeSelectAll , removeSelectNone ) => {
35
+ let enhanceOption = option ;
36
+
37
+ if ( removeSelectNone ) {
38
+ enhanceOption = enhanceOption . filter ( ( { selectNone } ) => ! selectNone ) ;
39
+ } else if ( removeSelectAll ) {
40
+ enhanceOption = enhanceOption . filter ( ( { selectAll } ) => ! selectAll ) ;
41
+ }
42
+
43
+ const sanitizedOption = ! enhanceOption && isMulti ? [ ] : enhanceOption ;
44
+
45
+ if ( isMulti && enhanceOption . find ( ( { selectAll } ) => selectAll ) ) {
46
+ return onChange ( allOptions . filter ( ( { selectAll, selectNone } ) => ! selectAll && ! selectNone ) . map ( ( { value } ) => value ) ) ;
47
+ }
48
+
49
+ if ( isMulti && enhanceOption . find ( ( { selectNone } ) => selectNone ) ) {
22
50
return onChange ( [ ] ) ;
23
51
}
24
52
@@ -145,6 +173,10 @@ const Select = ({
145
173
146
174
const selectValue = pluckSingleValue ? ( isMulti ? value : Array . isArray ( value ) && value [ 0 ] ? value [ 0 ] : value ) : value ;
147
175
176
+ const filteredLength = state . options . filter ( ( { selectAll, selectNone } ) => ! selectAll && ! selectNone ) . length ;
177
+ const shouldRemoveSelectAll = isMulti && state . options . find ( ( { selectAll } ) => selectAll ) && selectValue . length === filteredLength ;
178
+ const shouldRemoveSelectNone = isMulti && state . options . find ( ( { selectNone } ) => selectNone ) && selectValue . length === 0 ;
179
+
148
180
return (
149
181
< SelectComponent
150
182
className = { clsx ( classNamePrefix , {
@@ -156,7 +188,7 @@ const Select = ({
156
188
classNamePrefix = { classNamePrefix }
157
189
isMulti = { isMulti }
158
190
value = { getSelectValue ( selectValue , simpleValue , isMulti , state . options ) }
159
- onChange = { ( option ) => handleSelectChange ( option , simpleValue , isMulti , onChange , state . options ) }
191
+ onChange = { ( option ) => handleSelectChange ( option , simpleValue , isMulti , onChange , state . options , shouldRemoveSelectAll , shouldRemoveSelectNone ) }
160
192
onInputChange = { onInputChange }
161
193
isFetching = { Object . values ( state . promises ) . some ( ( value ) => value ) }
162
194
noOptionsMessage = { renderNoOptionsMessage ( ) }
0 commit comments