@@ -5,6 +5,7 @@ import React, {
55 KeyboardEvent ,
66 Ref ,
77 useRef ,
8+ useContext ,
89 useState ,
910 useEffect ,
1011 ReactNode ,
@@ -19,10 +20,11 @@ import { Button } from './Button';
1920import { FormElement , FormElementProps } from './FormElement' ;
2021import { Icon , IconCategory } from './Icon' ;
2122import { Spinner } from './Spinner' ;
23+ import { isElInChildren , registerStyle } from './util' ;
24+ import { ComponentSettingsContext } from './ComponentSettings' ;
2225import { useControlledValue , useEventCallback , useMergeRefs } from './hooks' ;
2326import { createFC } from './common' ;
2427import { Bivariant } from './typeUtils' ;
25- import { registerStyle } from './util' ;
2628
2729/**
2830 *
@@ -185,6 +187,7 @@ const LookupSelectedState: FC<LookupSelectedStateProps> = ({
185187 */
186188type LookupScopeSelectorContainerProps = {
187189 scopeListboxId : string ;
190+ dropdownRef : React . MutableRefObject < HTMLDivElement | null > ;
188191 children : React . ReactNode ;
189192} & AutoAlignInjectedProps ;
190193
@@ -193,6 +196,7 @@ type LookupScopeSelectorContainerProps = {
193196 */
194197const LookupScopeSelectorContainer : FC < LookupScopeSelectorContainerProps > = ( {
195198 scopeListboxId,
199+ dropdownRef,
196200 children,
197201 alignment,
198202 autoAlignContentRef,
@@ -212,7 +216,7 @@ const LookupScopeSelectorContainer: FC<LookupScopeSelectorContainerProps> = ({
212216 className = { dropdownClassNames }
213217 role = 'listbox'
214218 aria-label = 'Scope Options'
215- ref = { useMergeRefs ( [ autoAlignContentRef ] ) }
219+ ref = { useMergeRefs ( [ dropdownRef , autoAlignContentRef ] ) }
216220 >
217221 { children }
218222 </ div >
@@ -246,6 +250,8 @@ const LookupScopeSelector: FC<LookupScopeSelectorProps> = ({
246250 onScopeMenuClick : onScopeMenuClick_ ,
247251 onScopeSelect : onScopeSelect_ ,
248252} ) => {
253+ const dropdownRef = useRef < HTMLDivElement | null > ( null ) ;
254+
249255 const [ scopeOpened , setScopeOpened ] = useState ( false ) ;
250256 const [ scopeFocusedIndex , setScopeFocusedIndex ] = useState < number > ( - 1 ) ;
251257
@@ -377,10 +383,18 @@ const LookupScopeSelector: FC<LookupScopeSelectorProps> = ({
377383 }
378384
379385 setTimeout ( ( ) => {
380- setScopeOpened ( false ) ;
386+ if ( ! isFocusedInComponent ( ) ) {
387+ setScopeOpened ( false ) ;
388+ }
381389 } , 10 ) ;
382390 } ) ;
383391
392+ const { getActiveElement } = useContext ( ComponentSettingsContext ) ;
393+ const isFocusedInComponent = useEventCallback ( ( ) => {
394+ const targetEl = getActiveElement ( ) ;
395+ return isElInChildren ( dropdownRef . current , targetEl ) ;
396+ } ) ;
397+
384398 return (
385399 < div className = 'react-slds-lookup-scope-selector slds-combobox_object-switcher slds-combobox-addon_start' >
386400 < div className = 'slds-form-element' >
@@ -440,6 +454,7 @@ const LookupScopeSelector: FC<LookupScopeSelectorProps> = ({
440454 { ( injectedProps ) => (
441455 < LookupScopeSelectorContainer
442456 scopeListboxId = { scopeListboxId }
457+ dropdownRef = { dropdownRef }
443458 { ...injectedProps }
444459 >
445460 < ul
@@ -1126,6 +1141,11 @@ export const Lookup = createFC<LookupProps, { isFormElement: boolean }>(
11261141 const dropdownElRef = useRef < HTMLDivElement | null > ( null ) ;
11271142 const dropdownRef = useMergeRefs ( [ dropdownElRef , dropdownRef_ ] ) ;
11281143
1144+ const onScopeMenuClick = useEventCallback ( ( ) => {
1145+ setOpened ( false ) ;
1146+ onScopeMenuClick_ ?.( ) ;
1147+ } ) ;
1148+
11291149 const onSelect = useEventCallback ( ( selectedEntry : LookupEntry | null ) => {
11301150 const currValue = selectedEntry ?. value ?? null ;
11311151 setValue ( currValue ) ;
@@ -1175,18 +1195,24 @@ export const Lookup = createFC<LookupProps, { isFormElement: boolean }>(
11751195 }
11761196 }
11771197
1178- const isComplete = ! containerRef . current ?. contains ( e . relatedTarget ) ;
1179-
11801198 setTimeout ( ( ) => {
1181- setOpened ( false ) ;
1182- onBlur_ ?.( ) ;
1183-
1184- if ( isComplete ) {
1199+ if ( ! isFocusedInComponent ( ) ) {
1200+ setOpened ( false ) ;
1201+ onBlur_ ?.( ) ;
11851202 onComplete ?.( true ) ;
11861203 }
11871204 } , 10 ) ;
11881205 } ) ;
11891206
1207+ const { getActiveElement } = useContext ( ComponentSettingsContext ) ;
1208+ const isFocusedInComponent = useEventCallback ( ( ) => {
1209+ const targetEl = getActiveElement ( ) ;
1210+ return (
1211+ isElInChildren ( containerRef . current , targetEl ) ||
1212+ isElInChildren ( dropdownElRef . current , targetEl )
1213+ ) ;
1214+ } ) ;
1215+
11901216 const onInputKeyDown = useKeyHandler ( {
11911217 type : 'search' ,
11921218 opened,
@@ -1358,7 +1384,7 @@ export const Lookup = createFC<LookupProps, { isFormElement: boolean }>(
13581384 disabled = { disabled }
13591385 scopeListboxId = { scopeListboxId }
13601386 getScopeOptionId = { getScopeOptionId }
1361- onScopeMenuClick = { onScopeMenuClick_ }
1387+ onScopeMenuClick = { onScopeMenuClick }
13621388 onScopeSelect = { ( scope ) => {
13631389 setTargetScope ( scope ) ;
13641390 onScopeSelect_ ?.( scope ) ;
0 commit comments