如何为HeadlessUI的Combobox添加hover悬浮信息展示功能?
实现Combobox选项悬浮展示附加信息
完全可以实现这个需求,只需要通过跟踪鼠标悬浮的选项,再渲染对应的附加信息即可,以下是修改后的完整代码:
import { Fragment, useState } from 'react' import { Combobox, Transition } from '@headlessui/react' import { CheckIcon, SelectorIcon } from '@heroicons/react/solid' const people = [ { id: 1, name: 'Wade Cooper', info: 'test1' }, { id: 2, name: 'Arlene Mccoy', info: 'test2' }, { id: 3, name: 'Devon Webb', info: 'test3' }, { id: 4, name: 'Tom Cook', info: 'test4' }, { id: 5, name: 'Tanya Fox', info: 'test5' }, { id: 6, name: 'Hellen Schmidt', info: 'test6' }, ] export default function Example() { const [selected, setSelected] = useState(people[0]) const [query, setQuery] = useState('') // 跟踪当前悬浮的选项 const [hoveredPerson, setHoveredPerson] = useState(null) const filteredPeople = query === '' ? people : people.filter((person) => person.name .toLowerCase() .replace(/\s+/g, '') .includes(query.toLowerCase().replace(/\s+/g, '')) ) return ( <div className="fixed top-16 w-72"> <Combobox value={selected} onChange={setSelected}> <div className="relative mt-1"> <div className="relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm"> <Combobox.Input className="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0" displayValue={(person) => person.name} onChange={(event) => setQuery(event.target.value)} /> <Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2"> <SelectorIcon className="h-5 w-5 text-gray-400" aria-hidden="true" /> </Combobox.Button> </div> <Transition as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0" afterLeave={() => setQuery('')} > <Combobox.Options className="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"> {filteredPeople.length === 0 && query !== '' ? ( <div className="relative cursor-default select-none py-2 px-4 text-gray-700"> Nothing found. </div> ) : ( filteredPeople.map((person) => ( <Combobox.Option key={person.id} className={({ active }) => `relative cursor-default select-none py-2 pl-10 pr-4 ${active ? 'bg-teal-600 text-white' : 'text-gray-900'}` } value={person} // 添加悬浮事件跟踪当前选项 onMouseEnter={() => setHoveredPerson(person)} onMouseLeave={() => setHoveredPerson(null)} > {({ selected, active }) => ( <> <span className={`block truncate ${selected ? 'font-medium' : 'font-normal'}`} > {person.name} </span> {/* 显示附加信息,仅当当前选项悬浮时展示 */} {hoveredPerson?.id === person.id && ( <span className={`absolute right-4 top-1/2 -translate-y-1/2 ${active ? 'text-white' : 'text-gray-500'}`}> {person.info} </span> )} {selected ? ( <span className={`absolute inset-y-0 left-0 flex items-center pl-3 ${active ? 'text-white' : 'text-teal-600'}`} > <CheckIcon className="h-5 w-5" aria-hidden="true" /> </span> ) : null} </> )} </Combobox.Option> )) )} </Combobox.Options> </Transition> </div> </Combobox> </div> ) }
关键修改点:
- 添加
hoveredPerson状态,记录当前鼠标悬浮的选项对象 - 在
Combobox.Option上绑定onMouseEnter和onMouseLeave事件,更新悬浮状态 - 在选项内部判断当前悬浮项是否为当前渲染项,若是则展示对应的
info内容(示例中放在选项右侧,可根据需求调整为弹窗tooltip等样式)
内容的提问来源于stack exchange,提问作者Leo Messi
相关产品推荐
相关产品推荐

