diff --git a/src/components/menu/menu.module.css b/src/components/menu/menu.module.css index 53979f3..72b3cfa 100644 --- a/src/components/menu/menu.module.css +++ b/src/components/menu/menu.module.css @@ -24,9 +24,6 @@ } & .menu { - position: absolute; - right: 0; - bottom: calc(100% + 12px); width: 200px; padding: 4px; background-color: var(--color-neutral-100); diff --git a/src/components/menu/menu.tsx b/src/components/menu/menu.tsx index 8f8b607..66a936d 100644 --- a/src/components/menu/menu.tsx +++ b/src/components/menu/menu.tsx @@ -1,6 +1,18 @@ import { useState } from 'react'; import { IoMenu, IoClose } from 'react-icons/io5/index'; import { AnimatePresence, motion } from 'framer-motion'; +import { + useFloating, + autoUpdate, + offset, + flip, + shift, + useClick, + useDismiss, + useRole, + useInteractions, + FloatingFocusManager, +} from '@floating-ui/react'; import { useSoundStore } from '@/store'; import { slideY, fade, mix } from '@/lib/motion'; @@ -14,29 +26,57 @@ export function Menu() { const variants = mix(slideY(-20), fade()); + const { context, floatingStyles, refs } = useFloating({ + middleware: [offset(12), flip(), shift()], + onOpenChange: setIsOpen, + open: isOpen, + placement: 'top-end', + whileElementsMounted: autoUpdate, + }); + + const click = useClick(context); + const dismiss = useDismiss(context); + const role = useRole(context); + + const { getFloatingProps, getReferenceProps } = useInteractions([ + click, + dismiss, + role, + ]); + return (
{isOpen && ( - - - + +
+ + + +
+
)}