1880 Refactored Dropdown components (#1884)

* updated DropdownButton props

* refactoring in progress

* working but layout is wrong

* fixed bug

* wip on ColumnHeadWithDropdown

* fix bug

* fix bug

* remove unused styled component

* fix z-index bug

* add an optional argument to DropdownMenu to control the offset of the menu

* add an optional argument to DropdownMenu to control the offset of the menu

* modify files after PR comments

* clean the way the offset is handled

* fix lint
This commit is contained in:
bosiraphael
2023-10-05 18:11:54 +02:00
committed by GitHub
parent b8282e6789
commit 922f8eca0e
23 changed files with 213 additions and 182 deletions

View File

@ -8,13 +8,13 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useDropdownButton } from '../hooks/useDropdownButton';
import { useDropdown } from '../hooks/useDropdown';
import { useInternalHotkeyScopeManagement } from '../hooks/useInternalHotkeyScopeManagement';
import { DropdownToggleEffect } from './DropdownToggleEffect';
type OwnProps = {
buttonComponents?: JSX.Element | JSX.Element[];
type DropdownMenuProps = {
clickableComponent?: JSX.Element | JSX.Element[];
dropdownComponents: JSX.Element | JSX.Element[];
dropdownId: string;
hotkey?: {
@ -23,36 +23,40 @@ type OwnProps = {
};
dropdownHotkeyScope: HotkeyScope;
dropdownPlacement?: Placement;
dropdownOffset?: { x: number; y: number };
onClickOutside?: () => void;
onClose?: () => void;
onOpen?: () => void;
};
export const DropdownButton = ({
buttonComponents,
export const DropdownMenu = ({
clickableComponent,
dropdownComponents,
dropdownId,
hotkey,
dropdownHotkeyScope,
dropdownPlacement = 'bottom-end',
dropdownOffset = { x: 0, y: 0 },
onClickOutside,
onClose,
onOpen,
}: OwnProps) => {
}: DropdownMenuProps) => {
const containerRef = useRef<HTMLDivElement>(null);
const { isDropdownButtonOpen, toggleDropdownButton, closeDropdownButton } =
useDropdownButton({
dropdownId,
});
const { isDropdownOpen, toggleDropdown, closeDropdown } = useDropdown({
dropdownId,
});
const { refs, floatingStyles } = useFloating({
placement: dropdownPlacement,
middleware: [flip(), offset({ mainAxis: 8, crossAxis: 0 })],
middleware: [
flip(),
offset({ mainAxis: dropdownOffset.y, crossAxis: dropdownOffset.x }),
],
});
const handleHotkeyTriggered = () => {
toggleDropdownButton();
toggleDropdown();
};
useListenClickOutside({
@ -60,8 +64,8 @@ export const DropdownButton = ({
callback: () => {
onClickOutside?.();
if (isDropdownButtonOpen) {
closeDropdownButton();
if (isDropdownOpen) {
closeDropdown();
}
},
});
@ -74,24 +78,25 @@ export const DropdownButton = ({
useScopedHotkeys(
Key.Escape,
() => {
closeDropdownButton();
closeDropdown();
},
dropdownHotkeyScope.scope,
[closeDropdownButton],
[closeDropdown],
);
return (
<div ref={containerRef}>
{clickableComponent && (
<div ref={refs.setReference} onClick={toggleDropdown}>
{clickableComponent}
</div>
)}
{hotkey && (
<HotkeyEffect
hotkey={hotkey}
onHotkeyTriggered={handleHotkeyTriggered}
/>
)}
{buttonComponents && (
<div ref={refs.setReference}>{buttonComponents}</div>
)}
{isDropdownButtonOpen && (
{isDropdownOpen && (
<div data-select-disable ref={refs.setFloating} style={floatingStyles}>
{dropdownComponents}
</div>

View File

@ -1,6 +1,6 @@
import { useEffect } from 'react';
import { useDropdownButton } from '../hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
export const DropdownToggleEffect = ({
dropdownId,
@ -11,15 +11,15 @@ export const DropdownToggleEffect = ({
onDropdownClose?: () => void;
onDropdownOpen?: () => void;
}) => {
const { isDropdownButtonOpen } = useDropdownButton({ dropdownId });
const { isDropdownOpen } = useDropdown({ dropdownId });
useEffect(() => {
if (isDropdownButtonOpen) {
if (isDropdownOpen) {
onDropdownOpen?.();
} else {
onDropdownClose?.();
}
}, [isDropdownButtonOpen, onDropdownClose, onDropdownOpen]);
}, [isDropdownOpen, onDropdownClose, onDropdownOpen]);
return null;
};