import { isArray , isFunction , isObject } from '../../_utils/is' ; import { Option , OptionData , OptionInfo , GroupOption , FilterOption , OptionNode , } from '../../select/interface' ; const isGroupOption = ( option ) : option is GroupOption => { return isObject ( option ) && 'isGroup' in option ; } ; export const getOptionNodes = ( { options , extraOptions , inputValue , filterOption , showExtraOptions , optionInfoMap , enabledOptionSet , } ) => { optionInfoMap . clear ( ) ; enabledOptionSet . clear ( ) ; const getAndSaveOptionInfo = ( option , origin ) : OptionInfo | undefined => { const index = optionInfoMap . size ; const optionInfo = isObject ( option ) ? { ... option , index , key : `option-${ typeof option . value }-${ option . value }` , value : option . value , label : option . label ?? String ( option . value ) , disabled : Boolean ( option . disabled ) , origin } : { index , key : `option-${ typeof option }-${ option }` , value : option , label : String ( option ) , disabled : false , origin } ; if ( optionInfoMap . get ( optionInfo . value ) ) { return undefined ; } optionInfoMap . set ( optionInfo . value , optionInfo ) ; return optionInfo ; } ; const isValidOption = ( optionInfo ) => { if ( isFunction ( filterOption ) ) { return ! inputValue || filterOption ( inputValue , optionInfo ) ; } if ( filterOption ) { return optionInfo . label . toLowerCase ( ) . includes ( ( inputValue ?? '' ) . toLowerCase ( ) ) ; } return true ; } ; const travelOptions = ( options , origin ) => { const result = [ ] ; for ( const item of options ) { if ( isGroupOption ( item ) ) { if ( isArray ( item . options ) && item . options . length > 0 ) { result . push ( { ... item , key : `group-${ item . label }` , options : travelOptions ( item . options , origin ) } ) ; } } else { const optionInfo = getAndSaveOptionInfo ( item , origin ) ; if ( optionInfo && isValidOption ( optionInfo ) && ( origin !== 'extraOptions' || showExtraOptions ) ) { result . push ( { ... ( isObject ( item ) ? item : undefined ) , key : optionInfo . key , value : optionInfo . value , label : optionInfo . label } ) ; if ( ! optionInfo . disabled ) { enabledOptionSet . add ( optionInfo . value ) ; } } } } return result ; } ; const nodes = [ ] ; if ( options ) { nodes . push ( ... travelOptions ( options , 'options' ) ) ; } if ( extraOptions ) { nodes . push ( ... travelOptions ( extraOptions , 'extraOptions' ) ) ; } return nodes ; } ;