import {act, cleanup, fireEvent, render, screen} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import {useLayoutEffect, useRef, useState} from 'react'; import {vi} from 'vitest'; import { FloatingFocusManager, FloatingList, useClick, useDismiss, useFloating, useInteractions, useListItem, useListNavigation, } from '../../src'; import type {UseListNavigationProps} from '../../src/hooks/useListNavigation'; import {Main as ComplexGrid} from '../visual/components/ComplexGrid'; import {Main as Grid} from '../visual/components/Grid'; function App(props: Omit, 'listRef'>) { const [open, setOpen] = useState(false); const listRef = useRef>([]); const [activeIndex, setActiveIndex] = useState(null); const {refs, context} = useFloating({ open, onOpenChange: setOpen, }); const {getReferenceProps, getFloatingProps, getItemProps} = useInteractions([ useClick(context), useListNavigation(context, { ...props, listRef, activeIndex, onNavigate(index) { setActiveIndex(index); props.onNavigate?.(index); }, }), ]); return ( <> {isOpen && (
{['one', 'two', 'three'].map((option, index) => (
)} ); } render(); fireEvent.keyDown(screen.getByRole('button'), {key: 'ArrowUp'}); await act(async () => {}); expect(screen.getAllByRole('option')[2]).toHaveFocus(); fireEvent.click(screen.getByRole('button')); fireEvent.keyDown(screen.getByRole('button'), {key: 'ArrowDown'}); await act(async () => {}); expect(screen.getAllByRole('option')[0]).toHaveFocus(); }); test('async selectedIndex', async () => { const options = ['core', 'dom', 'react', 'react-dom', 'vue', 'react-native']; function Option({ option, activeIndex, selectedIndex, }: { option: string; activeIndex: number | null; selectedIndex: number | null; }) { const {ref, index} = useListItem(); return ( ); } function Select() { const [activeIndex, setActiveIndex] = useState(null); const [selectedIndex, setSelectedIndex] = useState(null); const [isOpen, setIsOpen] = useState(false); if (selectedIndex !== 2) { setSelectedIndex(2); } const {refs, floatingStyles, context} = useFloating({ open: isOpen, onOpenChange: setIsOpen, }); const elementsRef = useRef([]); const click = useClick(context); const listNav = useListNavigation(context, { listRef: elementsRef, activeIndex, selectedIndex, onNavigate: setActiveIndex, }); const {getReferenceProps, getFloatingProps} = useInteractions([ listNav, click, ]); return ( <> {isOpen && (
{options.map((option) => (
)} ); } render(