import { forwardRef, useId, useMemo, useRef, useState} from "react"; import { useAtom, useAtomValue } from "jotai"; import { autoUpdate, flip, FloatingFocusManager, FloatingPortal, size, useDismiss, useFloating, useInteractions, useListNavigation, useRole } from "@floating-ui/react"; import Fuse from "fuse.js"; import { charactersAtom, selectedTargetInventoryAtom } from "@/state/atoms"; interface AccountInventorySelectorItemProps { children: React.ReactNode; active: boolean; } const AccountInventorySelectorItem = forwardRef< HTMLDivElement, AccountInventorySelectorItemProps & React.HTMLProps >(({ children, active, ...rest }, ref) => { const id = useId(); return (
{children}
); }); export const InventoryTargetSelector = () => { const [open, setOpen] = useState(false); const [inputValue, setInputValue] = useState(""); const [activeIndex, setActiveIndex] = useState(null); const listRef = useRef>([]); const { refs, floatingStyles, context } = useFloating({ whileElementsMounted: autoUpdate, open, onOpenChange: setOpen, middleware: [ flip({ padding: 10 }), size({ apply({ rects, availableHeight, elements }) { Object.assign(elements.floating.style, { width: `${rects.reference.width}px`, maxHeight: `${availableHeight}px`, }); }, padding: 10, }), ], }); const role = useRole(context, { role: "listbox" }); const dismiss = useDismiss(context); const listNav = useListNavigation(context, { listRef, activeIndex, onNavigate: setActiveIndex, virtual: true, loop: true, }); const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions( [role, dismiss, listNav] ); function onChange(event: React.ChangeEvent) { const value = event.target.value; setInputValue(value); setSelectedTargetInventory(undefined) if (value) { setOpen(true); setActiveIndex(0); } else { setOpen(false); } } const { data: subaccounts } = useAtomValue(charactersAtom) const [selectedTargetInventory, setSelectedTargetInventory] = useAtom(selectedTargetInventoryAtom) const searcher = useMemo(()=>{ return new Fuse(subaccounts?.flatMap(x=>[ x.bank, x.character, ])||[], { keys:["path","name"], findAllMatches: true, threshold: 0.8, useExtendedSearch: true, }) }, [subaccounts]) const items = searcher.search(inputValue || "!-", {limit: 10}).map(x=>x.item) return ( <> {open && (
{items.map((item, index) => ( {item.name} ))}
)} ); }