HeadlessUI 有一个很棒的 Combobox 组件。查看使用活动(突出显示)选项的此示例。我已成功将此示例转换为打字稿:
activeOption
import * as Headless from '@headlessui/react'
import { useState } from 'react'
interface Person {
id: number
name: string
}
const people: Person[] = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
function Example() {
const [selectedPerson, setSelectedPerson] = useState<Person | null>(people[0])
const [query, setQuery] = useState<string>('')
const filteredPeople: Person[] =
query === ''
? people
: people.filter((person) => {
return person.name.toLowerCase().includes(query.toLowerCase())
})
return (
<Headless.Combobox
value={selectedPerson}
onChange={setSelectedPerson}
onClose={() => setQuery('')}
>
{({ activeOption }) => (
<>
<Headless.ComboboxInput
aria-label="Assignee"
displayValue={(person: Person | null) => person?.name ?? ''}
onChange={(event) => setQuery(event.target.value)}
/>
<Headless.ComboboxOptions
anchor="bottom"
className="border empty:invisible"
>
{filteredPeople.map((person) => (
<Headless.ComboboxOption
key={person.id}
value={person}
className="data-[focus]:bg-blue-100"
>
{person.name}
</Headless.ComboboxOption>
))}
</Headless.ComboboxOptions>
{activeOption && <div>The currently focused user is: {activeOption.name}</div>}
</>
)}
</Headless.Combobox>
)
}
现在,我的目标是创建我自己的“SuperBox”组件,它基本上只是
Combobox
以及一些额外的道具。这是我的尝试...
import * as Headless from '@headlessui/react'
import { ComponentProps, ReactNode } from 'react'
interface SuperBoxProps extends ComponentProps<typeof Headless.Combobox> {
className?: string
children?: ReactNode
}
export function SuperBox({ className, children, ...props }: SuperBoxProps) {
return (
<Headless.Combobox
data-slot="control"
className={className}
{...props}
>
<div className="relative">{children}</div>
</Headless.Combobox>
)
}
不幸的是,当我在上面的示例中将
Headless.Combobox
替换为 SuperBox
时,我收到以下打字稿错误:
类型 '({ activeOption }: { activeOption: any; }) => Element' 不可分配给类型 'ReactNode'
我知道在这种情况下
children
是一个函数,而不是 ReactNode
,但我不知道如何调整我的类型定义来支持这一点。
我认为这是你必须做的。 将您的界面更改为:
interface SuperBoxProps extends ComponentProps<typeof Headless.Combobox> { className?: string children?: ReactNode | ((options: { activeOption: any }) => ReactNode) }interface SuperBoxProps extends ComponentProps<typeof Headless.Combobox> { className?: string children?: ReactNode | ((options: { activeOption: any }) => ReactNode) }
并且您应该传递以下内容而不是 {children} :
{typeof children === 'function'
? children({ activeOption: null })
: children}
然后,你就可以开始了。