51 lines
1.2 KiB
TypeScript
51 lines
1.2 KiB
TypeScript
import {
|
|
autoUpdate,
|
|
flip,
|
|
useClick,
|
|
useDismiss,
|
|
useFloating,
|
|
useInteractions,
|
|
useListNavigation,
|
|
useRole,
|
|
useTypeahead,
|
|
type Placement,
|
|
} from "@floating-ui/react";
|
|
import { useRef, useState } from "react";
|
|
import type { CommonProps } from "../../utils/CommonProps";
|
|
|
|
export type MenuProps = CommonProps;
|
|
|
|
export const Menu = (props: MenuProps) => {
|
|
const { children } = props;
|
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [activeIndex, setActiveIndex] = useState<number | null>(null);
|
|
const [hasFocusInside, setHasFocusInside] = useState(false);
|
|
|
|
const { refs, floatingStyles, context } = useFloating({
|
|
placement: "bottom-start",
|
|
open: isOpen,
|
|
onOpenChange: setIsOpen,
|
|
whileElementsMounted: autoUpdate,
|
|
middleware: [flip()],
|
|
});
|
|
|
|
const elementsRef = useRef([]);
|
|
|
|
const listNav = useListNavigation(context, {
|
|
listRef: elementsRef,
|
|
activeIndex,
|
|
onNavigate: setActiveIndex,
|
|
});
|
|
|
|
const click = useClick(context);
|
|
const dismiss = useDismiss(context);
|
|
const role = useRole(context, { role: "listbox" });
|
|
|
|
const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
|
|
[listNav, click, dismiss, role],
|
|
);
|
|
|
|
return;
|
|
};
|