1
- import React , { useState , useRef , memo } from 'react'
1
+ import React , { useState , memo } from 'react'
2
2
import CloseIcon from './CloseIcon' ;
3
3
import DownIcon from './DownIcon' ;
4
4
5
5
MultiSelectDropdown . defaultProps = {
6
6
clearable : true ,
7
- downArrow : true
7
+ downArrow : true ,
8
+ width : 300 ,
9
+ singleSelect : false ,
10
+ jsonValue : false ,
11
+ defaultValue : '' ,
12
+ disableChip : false ,
13
+ placeholder : 'Select...' ,
14
+ onChange : ( ) => { } ,
15
+ options : [ { label : 'Empty' , value : '' , disabled : true , style : { textAlign : 'center' } } ] ,
8
16
}
9
17
10
- function MultiSelectDropdown ( props ) {
11
- const { options, width, downArrowIcon, clearable, downArrow, onChange } = props ;
12
- const mslInputRef = useRef ( null ) ;
18
+ function MultiSelectDropdown ( { options, width, downArrowIcon, clearable, downArrow, onChange, singleSelect, jsonValue, defaultValue, className, placeholder, disableChip } ) {
19
+
13
20
const [ menuOpen , setMenuOpen ] = useState ( false ) ;
14
- const [ value , setValue ] = useState ( [ ] ) ;
21
+
22
+ let preDefinedValue = [ ]
23
+ if ( defaultValue !== '' || defaultValue . length > 0 ) {
24
+ if ( typeof defaultValue === 'string' ) {
25
+ const valueArr = defaultValue . split ( "," )
26
+ preDefinedValue = options . filter ( itm => - 1 !== valueArr . indexOf ( itm . value ) )
27
+ if ( singleSelect && preDefinedValue . length > 1 ) {
28
+ preDefinedValue = [ preDefinedValue [ 0 ] ]
29
+ }
30
+ } else if ( Array . isArray ( preDefinedValue ) ) {
31
+ preDefinedValue = options . filter ( opt => defaultValue . some ( pval => opt . value === pval . value ) ) ;
32
+ if ( singleSelect && preDefinedValue . length > 1 ) {
33
+ preDefinedValue = [ preDefinedValue [ 0 ] ]
34
+ }
35
+ }
36
+ }
37
+ const [ value , setValue ] = useState ( preDefinedValue ) ;
15
38
let stopPropagation = true
16
39
17
40
const setNewValue = val => {
18
41
setValue ( val )
19
- onChange ( val )
42
+ if ( jsonValue ) {
43
+ onChange ( val )
44
+ } else {
45
+ let stringvalue = ''
46
+ stringvalue += val . map ( itm => itm . value )
47
+ onChange ( stringvalue )
48
+ }
20
49
}
21
50
22
51
const inputRefFocus = ( e , focus ) => {
23
52
let parentNode = null
24
53
let inputNode = null
25
- if ( e . target . hasAttribute ( 'data-msl' ) ) {
54
+ if ( e . target . hasAttribute ( 'data-msl' ) ) {
26
55
parentNode = e . target
27
- } else if ( e . target . parentNode . hasAttribute ( 'data-msl' ) ) {
56
+ } else if ( e . target . parentNode . hasAttribute ( 'data-msl' ) ) {
28
57
parentNode = e . target . parentNode
29
58
} else if ( e . target . parentNode . parentNode . hasAttribute ( 'data-msl' ) ) {
30
59
parentNode = e . target . parentNode . parentNode
@@ -38,7 +67,6 @@ function MultiSelectDropdown(props) {
38
67
}
39
68
40
69
if ( inputNode !== null ) {
41
- console . log ( '----------' , inputNode )
42
70
focus ? inputNode . focus ( ) : inputNode . blur ( )
43
71
}
44
72
}
@@ -98,13 +126,17 @@ function MultiSelectDropdown(props) {
98
126
}
99
127
100
128
const addValue = ( i ) => {
101
- const tmp = [ ...value ]
102
- if ( ! checkValueExist ( options [ i ] , value ) ) {
103
- tmp . push ( options [ i ] )
104
- setNewValue ( tmp )
129
+ let tmp = [ ...value ]
130
+ if ( singleSelect ) {
131
+ tmp = [ options [ i ] ]
105
132
} else {
106
- deleteValue ( i )
133
+ if ( ! checkValueExist ( options [ i ] , value ) ) {
134
+ tmp . push ( options [ i ] )
135
+ } else {
136
+ tmp = tmp . filter ( itm => itm . value !== options [ i ] . value )
137
+ }
107
138
}
139
+ setNewValue ( tmp )
108
140
}
109
141
110
142
const deleteValue = i => {
@@ -116,18 +148,28 @@ function MultiSelectDropdown(props) {
116
148
const clearValue = ( ) => {
117
149
setNewValue ( [ ] )
118
150
}
151
+ const showSearchOption = ( ) => {
152
+ if ( ! singleSelect && ! disableChip ) {
153
+ return true
154
+ } else if ( singleSelect && ! value . length ) {
155
+ return true
156
+ } else if ( ! singleSelect && disableChip && ! value . length ) {
157
+ return true
158
+ }
159
+ return false
160
+ }
119
161
120
162
return (
121
163
< >
122
164
{ console . log ( '----------mounted' ) }
123
- < div onClick = { handleClickInput } style = { { width } } className = " msl-wrp" >
165
+ < div onClick = { handleClickInput } style = { { width } } className = { ` msl-wrp msl-vars ${ className } ` } >
124
166
< div
125
167
data-msl
126
- className = { `msl ${ menuOpen ? "msl-active" : "" } ` }
168
+ className = { `msl ${ menuOpen ? "msl-active" : "" } ` }
127
169
>
128
170
< div data-msl className = "msl-input-wrp"
129
- style = { { marginRight : clearable && downArrow ? 60 : downArrow || clearable ? 40 : 0 } } >
130
- { value . map ( ( val , i ) => (
171
+ style = { { marginRight : clearable && downArrow ? 60 : downArrow || clearable ? 40 : 5 } } >
172
+ { ( ! singleSelect && ! disableChip ) && value . map ( ( val , i ) => (
131
173
< div key = { `chip-${ i + 11 } ` } className = "msl-chip" >
132
174
{ val . label }
133
175
< button onClick = { ( ) => deleteValue ( i ) } className = "msl-btn msl-chip-delete flx" >
@@ -136,7 +178,9 @@ function MultiSelectDropdown(props) {
136
178
< span />
137
179
</ div >
138
180
) ) }
139
- < div data-msl /* onBlur={onInputBlur} */ ref = { mslInputRef } className = "msl-input" contentEditable />
181
+ { ! singleSelect && disableChip && value . length === 1 ? < span className = "msl-single-value" data-msl style = { { width : width - ( clearable && downArrow ? 60 : downArrow || clearable ? 40 : 5 ) } } > { value [ 0 ] . label } d</ span > : disableChip && value . length > 1 && < span className = "msl-single-value" data-msl style = { { width : width - ( clearable && downArrow ? 60 : downArrow || clearable ? 40 : 5 ) } } > { value . length } Selected</ span > }
182
+ { singleSelect && value . length === 1 && < span className = "msl-single-value" data-msl style = { { width : width - ( clearable && downArrow ? 60 : downArrow || clearable ? 40 : 5 ) } } > { value [ 0 ] . label } </ span > }
183
+ { showSearchOption ( ) && < div data-msl data-placeholder = { placeholder } className = "msl-input" contentEditable /> }
140
184
</ div >
141
185
{ ( clearable || downArrow ) && (
142
186
< div className = "msl-actions flx" >
@@ -160,11 +204,12 @@ function MultiSelectDropdown(props) {
160
204
< div className = "msl-options" >
161
205
{ options . map ( ( opt , i ) => (
162
206
< option
163
- data-msl
164
- onClick = { ( ) => addValue ( i ) }
207
+ { ...! singleSelect && { 'data-msl' : true } }
208
+ style = { { ...opt . style && opt . style } }
209
+ onClick = { ( ) => { ! opt . disabled && addValue ( i ) } }
165
210
title = { opt . label }
166
211
key = { opt . value + i + 10 }
167
- className = { `msl-option ${ checkValueExist ( opt , value ) && 'msl-option-active' } ` }
212
+ className = { `msl-option ${ checkValueExist ( opt , value ) && 'msl-option-active' } ${ opt . disabled && 'msl-option-disable' } ${ opt . classes } ` }
168
213
value = { opt . value } >
169
214
{ opt . label }
170
215
</ option >
0 commit comments