1
1
import React , { useState , useEffect } from "react" ;
2
2
import Select , { components } from "react-select" ;
3
3
import "./rds-select-list.css" ;
4
+ import RdsSpinner from "../rds-spinner" ;
5
+ import { SpinnerSize } from "../rds-spinner/rds-spinner" ;
4
6
5
7
export interface RdsSelectProps {
6
8
size ?: "small" | "large" | "medium" | string ;
@@ -58,18 +60,15 @@ const RdsSelectList = (props: RdsSelectProps) => {
58
60
const [ selectedValue , setSelectedValue ] = useState < any | null > (
59
61
props . isMultiple ? [ ] : null
60
62
) ;
61
- const [ reset , setIsReset ] = useState < boolean > ( false ) ;
62
-
63
+ const [ isSearching , setIsSearching ] = useState ( false ) ;
64
+ const [ searchTimer , setSearchTimer ] = useState < NodeJS . Timeout | null > ( null ) ;
65
+ const showLabel = props . showLabel === undefined ? true : props . showLabel ;
66
+ const reset = props . reset || false ;
67
+
63
68
useEffect ( ( ) => {
64
- if ( props . reset ) {
65
- setIsReset ( true ) ;
69
+ if ( props . selectedValue !== undefined ) {
70
+ setSelectedValue ( props . selectedValue ) ;
66
71
}
67
- } , [ props . reset ] ) ;
68
-
69
- const showLabel = props . showLabel ?? true ;
70
-
71
- useEffect ( ( ) => {
72
- setSelectedValue ( props . selectedValue ) ;
73
72
} , [ props . selectedValue ] ) ;
74
73
75
74
// Create a fixed array of select items without the "Select All" option
@@ -87,8 +86,6 @@ const RdsSelectList = (props: RdsSelectProps) => {
87
86
: regularItems ;
88
87
89
88
const handleSelectChange = ( items : any ) => {
90
- setIsReset ( false ) ;
91
-
92
89
if ( props . isMultiple ) {
93
90
if ( items && items . some ( ( item : any ) => item . value === "select_all" ) ) {
94
91
const wasSelectAllAlreadySelected = selectedValue ?. includes ( "select_all" ) ;
@@ -279,6 +276,49 @@ const RdsSelectList = (props: RdsSelectProps) => {
279
276
) ;
280
277
} ;
281
278
279
+ // Added Spinner
280
+ const customComponents = {
281
+ ...props . isMultiple ? { Option } : { } ,
282
+ LoadingIndicator : ( ) => (
283
+ < div className = "custom-select__loading-indicator" data-testid = "loading-spinner" >
284
+ < RdsSpinner
285
+ spinnerType = "border"
286
+ colorVariant = "primary"
287
+ width = "16px"
288
+ height = "16px"
289
+ borderWidth = "2px"
290
+ size = { SpinnerSize . Small }
291
+ />
292
+ </ div >
293
+ ) ,
294
+ IndicatorSeparator : ( ) => null
295
+ } ;
296
+
297
+ const handleInputChange = ( inputValue : string ) => {
298
+ setIsSearching ( true ) ;
299
+ if ( searchTimer ) {
300
+ clearTimeout ( searchTimer ) ;
301
+ }
302
+ const timer = setTimeout ( ( ) => {
303
+ setIsSearching ( false ) ;
304
+ } , 500 ) ;
305
+ setSearchTimer ( timer ) ;
306
+ } ;
307
+
308
+ useEffect ( ( ) => {
309
+ return ( ) => {
310
+ if ( searchTimer ) {
311
+ clearTimeout ( searchTimer ) ;
312
+ }
313
+ } ;
314
+ } , [ searchTimer ] ) ;
315
+
316
+ useEffect ( ( ) => {
317
+ if ( reset ) {
318
+ setSelectedValue ( props . isMultiple ? [ ] : null ) ;
319
+ }
320
+ } , [ reset , props . isMultiple ] ) ;
321
+
282
322
return (
283
323
< div className = { `${ props . classes } mt-2` } >
284
324
< div className = "d-flex mb-1" >
@@ -298,8 +338,9 @@ const RdsSelectList = (props: RdsSelectProps) => {
298
338
isMulti = { props . isMultiple }
299
339
closeMenuOnSelect = { ! props . isMultiple }
300
340
hideSelectedOptions = { false }
301
- components = { props . isMultiple ? { Option } : undefined }
341
+ components = { customComponents }
302
342
onChange = { handleSelectChange }
343
+ onInputChange = { handleInputChange }
303
344
value = { reset === true ? null : selectedItem }
304
345
placeholder = { props . placeholder }
305
346
isSearchable = { props . isSearchable }
@@ -308,6 +349,7 @@ const RdsSelectList = (props: RdsSelectProps) => {
308
349
aria-label = "select example"
309
350
data-testid = { props . dataTestId }
310
351
styles = { customStyles }
352
+ isLoading = { isSearching }
311
353
/>
312
354
{ props . showHint && (
313
355
< p className = "my-1 text-black-50" >
0 commit comments