useTypeahead
提供匹配的回调,可用于在用户键入时聚焦项目,与 useListNavigation()
一起使用。
¥Provides a matching callback that can be used to focus an item as
the user types, used in tandem with useListNavigation()
.
import {useTypeahead} from '@floating-ui/react';
这对于创建具有预先输入支持的菜单非常有用,用户可以在其中键入以聚焦某个项目,然后立即选择它,特别是当它包含大量项目时。
¥This is useful for creating a menu with typeahead support, where the user can type to focus an item and then immediately select it, especially if it contains a large number of items.
有关创建可组合子 API 组件的信息,请参阅 FloatingList
。
¥See FloatingList
for creating composable
children API components.
用法
¥Usage
该 Hook 返回事件处理程序 props。
¥This Hook returns event handler props.
要使用它,请将 useFloating()
返回的 context
对象传递给它,然后将其结果输入 useInteractions()
数组。然后将返回的 prop getter 传播到元素上进行渲染。
¥To use it, pass it the context
object returned from
useFloating()
, and then feed its result into the
useInteractions()
array. The returned prop getters are
then spread onto the elements for rendering.
useListNavigation()
负责同步焦点索引。
¥useListNavigation()
is responsible for synchronizing the
index for focus.
function App() {
const [activeIndex, setActiveIndex] = useState(null);
const {refs, floatingStyles, context} = useFloating({
open: true,
});
const items = ['one', 'two', 'three'];
const listRef = useRef(items);
const typeahead = useTypeahead(context, {
listRef,
activeIndex,
onMatch: setActiveIndex,
});
const {getReferenceProps, getFloatingProps, getItemProps} =
useInteractions([typeahead]);
return (
<>
<div ref={refs.setReference} {...getReferenceProps()}>
Reference element
</div>
<div
ref={refs.setFloating}
style={floatingStyles}
{...getFloatingProps()}
>
{items.map((item, index) => (
<div
key={item}
// Make these elements focusable using a roving tabIndex.
tabIndex={activeIndex === index ? 0 : -1}
{...getItemProps()}
>
{item}
</div>
))}
</div>
</>
);
}
属性
¥Props
interface UseTypeaheadProps {
listRef: React.MutableRefObject<Array<string | null>>;
activeIndex: number | null;
onMatch?(index: number): void;
enabled?: boolean;
resetMs?: number;
ignoreKeys?: Array<string>;
selectedIndex?: number | null;
onTypingChange?(isTyping: boolean): void;
findMatch?:
| null
| ((
list: Array<string | null>,
typedString: string,
) => string | null | undefined);
}
listRef
默认:空列表
¥default: empty list
包含索引与列表的 HTML 元素匹配的字符串数组的 ref。
¥A ref which contains an array of strings whose indices match the HTML elements of the list.
const listRef = useRef(['one', 'two', 'three']);
useTypeahead(context, {
listRef,
});
如果字符串预先不可用,你可以在分配节点时派生这些字符串:
¥You can derive these strings when assigning the node if the strings are not available up front:
// Array<HTMLElement | null> for `useListNavigation`
const listItemsRef = useRef([]);
// Array<string | null> for `useTypeahead`
const listContentRef = useRef([]);
<li
ref={(node) => {
listItemsRef.current[index] = node;
listContentRef.current[index] = node?.textContent ?? null;
}}
/>
禁用的项目可以由数组中相关索引处的 null
值表示,并且将被跳过。
¥Disabled items can be represented by null
values in the
array at the relevant index, and will be skipped.
activeIndex
默认:null
¥default: null
当前活跃的索引。这指定了预输入的开始位置。
¥The currently active index. This specifies where the typeahead starts.
const [activeIndex, setActiveIndex] = useState(null);
useTypeahead(context, {
activeIndex,
});
onMatch
默认:no-op
¥default: no-op
如果在用户键入时找到匹配的索引,则会调用回调。
¥Callback invoked with the matching index if found as the user types.
const [isOpen, setIsOpen] = useState(false);
const [activeIndex, setActiveIndex] = useState(null);
const [selectedIndex, setSelectedIndex] = useState(null);
useTypeahead(context, {
onMatch: isOpen ? setActiveIndex : setSelectedIndex,
});
enabled
默认:true
¥default: true
有条件地启用/禁用 Hook。
¥Conditionally enable/disable the Hook.
useTypeahead(context, {
enabled: false,
});
findMatch
默认:小写查找器
¥default: lowercase finder
如果你想实现自定义查找逻辑(例如 模糊搜索),你可以使用此回调。
¥If you’d like to implement custom finding logic (for example fuzzy search), you can use this callback.
useTypeahead(context, {
findMatch: (list, typedString) =>
list.find(
(itemString) =>
itemString?.toLowerCase().indexOf(typedString) === 0,
),
});
resetMs
默认:750
¥default: 750
反跳超时将在用户键入时重置瞬态字符串。
¥Debounce timeout which will reset the transient string as the user types.
useTypeahead(context, {
resetMs: 500,
});
ignoreKeys
默认:[]
¥default: []
要忽略的可选键。
¥Optional keys to ignore.
useTypeahead(context, {
ignoreKeys: ['I', 'G', 'N', 'O', 'R', 'E'],
});
selectedIndex
默认:null
¥default: null
当前选择的索引(如果可用)。
¥The currently selected index, if available.
const [selectedIndex, setSelectedIndex] = useState(null);
useTypeahead(context, {
selectedIndex,
});
onTypingChange
默认:no-op
¥default: no-op
当用户键入时,使用键入状态调用回调。
¥Callback invoked with the typing state as the user types.
useTypeahead(context, {
onTypingChange(isTyping) {
// ...
},
});