mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-04-23 22:07:07 -04:00
Fix issues with Floating UI
This commit is contained in:
parent
b103005aa2
commit
50286cc9ce
5 changed files with 74 additions and 60 deletions
|
@ -93,9 +93,10 @@ function AutoSuggestInput<T = any>(props: AutoSuggestInputProps<T>) {
|
|||
mainAxis: true,
|
||||
}),
|
||||
size({
|
||||
apply({ rects, elements }) {
|
||||
apply({ availableHeight, elements, rects }) {
|
||||
Object.assign(elements.floating.style, {
|
||||
width: `${rects.reference.width}px`,
|
||||
minWidth: `${rects.reference.width}px`,
|
||||
maxHeight: `${Math.max(0, availableHeight)}px`,
|
||||
});
|
||||
},
|
||||
}),
|
||||
|
|
|
@ -42,15 +42,10 @@
|
|||
color: var(--disabledInputColor);
|
||||
}
|
||||
|
||||
.optionsContainer {
|
||||
z-index: $popperZIndex;
|
||||
max-height: vh(50);
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.options {
|
||||
composes: scroller from '~Components/Scroller/Scroller.css';
|
||||
|
||||
z-index: $popperZIndex;
|
||||
border: 1px solid var(--inputBorderColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--inputBackgroundColor);
|
||||
|
|
|
@ -13,7 +13,6 @@ interface CssExports {
|
|||
'mobileCloseButton': string;
|
||||
'mobileCloseButtonContainer': string;
|
||||
'options': string;
|
||||
'optionsContainer': string;
|
||||
'optionsInnerModalBody': string;
|
||||
'optionsModal': string;
|
||||
'optionsModalBody': string;
|
||||
|
|
|
@ -14,6 +14,7 @@ import React, {
|
|||
KeyboardEvent,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
@ -180,15 +181,21 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
|
|||
mainAxis: true,
|
||||
}),
|
||||
size({
|
||||
apply({ rects, elements }) {
|
||||
apply({ availableHeight, elements, rects }) {
|
||||
Object.assign(elements.floating.style, {
|
||||
'min-width': `${rects.reference.width}px`,
|
||||
minWidth: `${rects.reference.width}px`,
|
||||
maxHeight: `${Math.max(
|
||||
0,
|
||||
Math.min(window.innerHeight / 2, availableHeight)
|
||||
)}px`,
|
||||
});
|
||||
},
|
||||
}),
|
||||
],
|
||||
open: isOpen,
|
||||
placement: 'bottom-start',
|
||||
whileElementsMounted: autoUpdate,
|
||||
onOpenChange: setIsOpen,
|
||||
});
|
||||
|
||||
const click = useClick(context);
|
||||
|
@ -214,12 +221,8 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
|
|||
}, [value, values, isMultiSelect]);
|
||||
|
||||
const handlePress = useCallback(() => {
|
||||
if (!isOpen && onOpen) {
|
||||
onOpen();
|
||||
}
|
||||
|
||||
setIsOpen(!isOpen);
|
||||
}, [isOpen, setIsOpen, onOpen]);
|
||||
setIsOpen((prevIsOpen) => !prevIsOpen);
|
||||
}, []);
|
||||
|
||||
const handleSelect = useCallback(
|
||||
(newValue: ArrayElement<V>) => {
|
||||
|
@ -372,6 +375,12 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
|
|||
[onChange]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
onOpen?.();
|
||||
}
|
||||
}, [isOpen, onOpen]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={refs.setReference} {...getReferenceProps()}>
|
||||
|
@ -443,46 +452,43 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
|
|||
</Link>
|
||||
)}
|
||||
</div>
|
||||
{isOpen ? (
|
||||
|
||||
{!isMobile && isOpen ? (
|
||||
<FloatingPortal id="portal-root">
|
||||
<div
|
||||
<Scroller
|
||||
ref={refs.setFloating}
|
||||
className={styles.optionsContainer}
|
||||
className={styles.options}
|
||||
style={floatingStyles}
|
||||
{...getFloatingProps()}
|
||||
>
|
||||
{isOpen && !isMobile ? (
|
||||
<Scroller className={styles.options}>
|
||||
{values.map((v, index) => {
|
||||
const hasParent = v.parentKey !== undefined;
|
||||
const depth = hasParent ? 1 : 0;
|
||||
const parentSelected =
|
||||
v.parentKey !== undefined &&
|
||||
Array.isArray(value) &&
|
||||
value.includes(v.parentKey);
|
||||
{values.map((v, index) => {
|
||||
const hasParent = v.parentKey !== undefined;
|
||||
const depth = hasParent ? 1 : 0;
|
||||
const parentSelected =
|
||||
v.parentKey !== undefined &&
|
||||
Array.isArray(value) &&
|
||||
value.includes(v.parentKey);
|
||||
|
||||
const { key, ...other } = v;
|
||||
const { key, ...other } = v;
|
||||
|
||||
return (
|
||||
<OptionComponent
|
||||
key={v.key}
|
||||
id={v.key}
|
||||
depth={depth}
|
||||
isSelected={isSelectedItem(index, value, values)}
|
||||
isDisabled={parentSelected}
|
||||
isMultiSelect={isMultiSelect}
|
||||
{...valueOptions}
|
||||
{...other}
|
||||
isMobile={false}
|
||||
onSelect={handleSelect}
|
||||
>
|
||||
{v.value}
|
||||
</OptionComponent>
|
||||
);
|
||||
})}
|
||||
</Scroller>
|
||||
) : null}
|
||||
</div>
|
||||
return (
|
||||
<OptionComponent
|
||||
key={v.key}
|
||||
id={v.key}
|
||||
depth={depth}
|
||||
isSelected={isSelectedItem(index, value, values)}
|
||||
isDisabled={parentSelected}
|
||||
isMultiSelect={isMultiSelect}
|
||||
{...valueOptions}
|
||||
{...other}
|
||||
isMobile={false}
|
||||
onSelect={handleSelect}
|
||||
>
|
||||
{v.value}
|
||||
</OptionComponent>
|
||||
);
|
||||
})}
|
||||
</Scroller>
|
||||
</FloatingPortal>
|
||||
) : null}
|
||||
|
||||
|
|
|
@ -58,16 +58,6 @@ function Menu({
|
|||
onPress: handleMenuButtonPress,
|
||||
});
|
||||
|
||||
const handleFloaterPress = useCallback((_event: MouseEvent) => {
|
||||
// TODO: Menu items should handle closing when they are clicked.
|
||||
// This is handled before the menu item click event is handled, so wait 100ms before closing.
|
||||
setTimeout(() => {
|
||||
setIsMenuOpen(false);
|
||||
}, 100);
|
||||
|
||||
return true;
|
||||
}, []);
|
||||
|
||||
const handleWindowResize = useCallback(() => {
|
||||
updateMaxHeight();
|
||||
}, [updateMaxHeight]);
|
||||
|
@ -118,8 +108,31 @@ function Menu({
|
|||
onOpenChange: setIsMenuOpen,
|
||||
});
|
||||
|
||||
const handleFloaterPress = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
if (
|
||||
refs.reference &&
|
||||
(refs.reference.current as HTMLElement).contains(
|
||||
event.target as HTMLElement
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Menu items should handle closing when they are clicked.
|
||||
// This is handled before the menu item click event is handled, so wait 100ms before closing.
|
||||
setTimeout(() => {
|
||||
setIsMenuOpen(false);
|
||||
}, 100);
|
||||
|
||||
return true;
|
||||
},
|
||||
[refs.reference]
|
||||
);
|
||||
|
||||
const click = useClick(context);
|
||||
const dismiss = useDismiss(context, {
|
||||
outsidePressEvent: 'click',
|
||||
outsidePress: handleFloaterPress,
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue