fix(launch_bar): dynamic dropdown not repositioning

This commit is contained in:
Elian Doran 2025-12-05 17:11:53 +02:00
parent 3a8dcae53a
commit a107c126e4
No known key found for this signature in database

View File

@ -36,6 +36,8 @@ export interface DropdownProps extends Pick<HTMLProps<HTMLDivElement>, "id" | "c
export default function Dropdown({ id, className, buttonClassName, isStatic, children, title, text, dropdownContainerStyle, dropdownContainerClassName, dropdownContainerRef: externalContainerRef, hideToggleArrow, iconAction, disabled, noSelectButtonStyle, noDropdownListStyle, forceShown, onShown: externalOnShown, onHidden: externalOnHidden, dropdownOptions, buttonProps, dropdownRef, titlePosition, titleOptions }: DropdownProps) { export default function Dropdown({ id, className, buttonClassName, isStatic, children, title, text, dropdownContainerStyle, dropdownContainerClassName, dropdownContainerRef: externalContainerRef, hideToggleArrow, iconAction, disabled, noSelectButtonStyle, noDropdownListStyle, forceShown, onShown: externalOnShown, onHidden: externalOnHidden, dropdownOptions, buttonProps, dropdownRef, titlePosition, titleOptions }: DropdownProps) {
const containerRef = useRef<HTMLDivElement | null>(null); const containerRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null); const triggerRef = useRef<HTMLButtonElement | null>(null);
const dropdownContainerRef = useRef<HTMLUListElement | null>(null);
const { showTooltip, hideTooltip } = useTooltip(containerRef, { const { showTooltip, hideTooltip } = useTooltip(containerRef, {
...titleOptions, ...titleOptions,
placement: titlePosition ?? "bottom", placement: titlePosition ?? "bottom",
@ -46,7 +48,7 @@ export default function Dropdown({ id, className, buttonClassName, isStatic, chi
const [ shown, setShown ] = useState(false); const [ shown, setShown ] = useState(false);
useEffect(() => { useEffect(() => {
if (!triggerRef.current) return; if (!triggerRef.current || !dropdownContainerRef) return;
const dropdown = BootstrapDropdown.getOrCreateInstance(triggerRef.current, dropdownOptions); const dropdown = BootstrapDropdown.getOrCreateInstance(triggerRef.current, dropdownOptions);
if (dropdownRef) { if (dropdownRef) {
@ -56,8 +58,19 @@ export default function Dropdown({ id, className, buttonClassName, isStatic, chi
dropdown.show(); dropdown.show();
setShown(true); setShown(true);
} }
return () => dropdown.dispose();
}, []); const dropdownContainer = dropdownContainerRef.current;
if (!dropdownContainer) return;
// React to popup container size changes, which can affect the positioning.
const resizeObserver = new ResizeObserver(() => dropdown.update());
resizeObserver.observe(dropdownContainer);
return () => {
resizeObserver.disconnect();
dropdown.dispose();
}
}, [ triggerRef, dropdownContainerRef ]);
const onShown = useCallback(() => { const onShown = useCallback(() => {
setShown(true); setShown(true);
@ -119,6 +132,7 @@ export default function Dropdown({ id, className, buttonClassName, isStatic, chi
class={`dropdown-menu ${isStatic ? "static" : ""} ${dropdownContainerClassName ?? ""} ${!noDropdownListStyle ? "tn-dropdown-list" : ""}`} class={`dropdown-menu ${isStatic ? "static" : ""} ${dropdownContainerClassName ?? ""} ${!noDropdownListStyle ? "tn-dropdown-list" : ""}`}
style={dropdownContainerStyle} style={dropdownContainerStyle}
aria-labelledby={ariaId} aria-labelledby={ariaId}
ref={dropdownContainerRef}
> >
{shown && children} {shown && children}
</ul> </ul>