Skip to content

Commit 25e8ff4

Browse files
committed
fix(CDropdown): incorrect menu positioning when the toggler is re-rendered
1 parent bb614f2 commit 25e8ff4

File tree

6 files changed

+38
-22
lines changed

6 files changed

+38
-22
lines changed

packages/coreui-react/src/components/dropdown/CDropdown.tsx

+32-16
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,7 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
207207
ref
208208
) => {
209209
const dropdownRef = useRef<HTMLDivElement>(null)
210-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
211-
const dropdownToggleRef = useRef<any>(null)
210+
const dropdownToggleRef = useRef<HTMLElement>(null)
212211
const dropdownMenuRef = useRef<HTMLDivElement | HTMLUListElement>(null)
213212
const forkedRef = useForkedRef(ref, dropdownRef)
214213
const [_visible, setVisible] = useState(visible)
@@ -256,28 +255,45 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
256255
}, [visible])
257256

258257
useEffect(() => {
259-
if (_visible && dropdownToggleRef.current && dropdownMenuRef.current) {
260-
dropdownToggleRef.current.focus()
261-
popper &&
262-
initPopper(dropdownToggleRef.current, dropdownMenuRef.current, computedPopperConfig)
258+
const toggleElement = dropdownToggleRef.current
259+
const menuElement = dropdownMenuRef.current
260+
261+
if (_visible && toggleElement && menuElement) {
262+
if (popper) {
263+
initPopper(toggleElement, menuElement, computedPopperConfig)
264+
}
265+
266+
toggleElement.focus()
267+
toggleElement.addEventListener('keydown', handleKeydown)
268+
menuElement.addEventListener('keydown', handleKeydown)
269+
263270
window.addEventListener('mouseup', handleMouseUp)
264271
window.addEventListener('keyup', handleKeyup)
265-
dropdownToggleRef.current.addEventListener('keydown', handleKeydown)
266-
dropdownMenuRef.current.addEventListener('keydown', handleKeydown)
267-
onShow && onShow()
272+
273+
onShow?.()
268274
}
269275

270276
return () => {
271-
popper && destroyPopper()
277+
if (popper) {
278+
destroyPopper()
279+
}
280+
281+
toggleElement?.removeEventListener('keydown', handleKeydown)
282+
menuElement?.removeEventListener('keydown', handleKeydown)
283+
272284
window.removeEventListener('mouseup', handleMouseUp)
273285
window.removeEventListener('keyup', handleKeyup)
274-
dropdownToggleRef.current &&
275-
dropdownToggleRef.current.removeEventListener('keydown', handleKeydown)
276-
dropdownMenuRef.current &&
277-
dropdownMenuRef.current.removeEventListener('keydown', handleKeydown)
278-
onHide && onHide()
286+
287+
onHide?.()
279288
}
280-
}, [_visible])
289+
}, [
290+
computedPopperConfig,
291+
destroyPopper,
292+
dropdownMenuRef,
293+
dropdownToggleRef,
294+
initPopper,
295+
_visible,
296+
])
281297

282298
const handleKeydown = (event: KeyboardEvent) => {
283299
if (

packages/coreui-react/src/components/dropdown/CDropdownDivider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface CDropdownDividerProps extends HTMLAttributes<HTMLHRElement> {
1212
export const CDropdownDivider = forwardRef<HTMLHRElement, CDropdownDividerProps>(
1313
({ className, ...rest }, ref) => {
1414
return <hr className={classNames('dropdown-divider', className)} {...rest} ref={ref} />
15-
},
15+
}
1616
)
1717

1818
CDropdownDivider.propTypes = {

packages/coreui-react/src/components/dropdown/CDropdownHeader.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const CDropdownHeader: PolymorphicRefForwardingComponent<'h6', CDropdownH
2323
{children}
2424
</Component>
2525
)
26-
},
26+
}
2727
)
2828

2929
CDropdownHeader.propTypes = {

packages/coreui-react/src/components/dropdown/CDropdownItemPlain.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const CDropdownItemPlain: PolymorphicRefForwardingComponent<
2525
{children}
2626
</Component>
2727
)
28-
},
28+
}
2929
)
3030

3131
CDropdownItemPlain.propTypes = {

packages/coreui-react/src/components/dropdown/CDropdownMenu.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const CDropdownMenu: PolymorphicRefForwardingComponent<'ul', CDropdownMen
3838
show: visible,
3939
},
4040
alignment && getAlignmentClassNames(alignment),
41-
className,
41+
className
4242
)}
4343
ref={forkedRef}
4444
role="menu"
@@ -57,7 +57,7 @@ export const CDropdownMenu: PolymorphicRefForwardingComponent<'ul', CDropdownMen
5757
</Component>
5858
</CConditionalPortal>
5959
)
60-
},
60+
}
6161
)
6262

6363
CDropdownMenu.propTypes = {

packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
6969
'dropdown-toggle-split': split,
7070
show: visible,
7171
},
72-
className,
72+
className
7373
),
7474
'aria-expanded': visible,
7575
...(!rest.disabled && { ...triggers }),

0 commit comments

Comments
 (0)