В моем компоненте ReactBootstrapTypeahead я могу щелкнуть любую опцию, чтобы выбрать ее, но использование Tab выберет только первую опцию, если она совпадает в начале строки. Если первый параметр совпадает в середине, нажатие Tab просто перемещает фокус без выбора параметра. работает , если вы впервые используете клавиши со стрелками, чтобы выделить параметр.
Каждая опция содержит id
, make
и model
, и я объединяю последние два в name
(например, 'Toyota Prius'
) для использования labelKey
. Все работает, кроме выбора первого элемента без его выделения с помощью клавиш со стрелками.
<AsyncTypeahead
id="search"
selectHintOnEnter
labelKey="name"
filterBy={startsWith}
renderMenu={renderMenu}
options={results}
/>
Я использую пользовательскую функцию renderMenu
для группировки параметров ...
const renderMenu = (results, menuProps) => {
const items = [];
let makesHeader, lastMake, idx = 0;
results.forEach(result => {
const { id, make, model } = result;
if (!make) {
// skip "click to load more..." text
items.push(
<Menu.Header key="more-header">
More Results Hidden…
</Menu.Header>
);
}
else if (!model) {
if (!makesHeader) {
items.push(
<Menu.Header key="makes-header">
Makes
</Menu.Header>
);
makesHeader = true;
}
items.push(
<MenuItem key={id} option={result} position={idx}>
<WordHighlighter search={menuProps.text}>
{make}
</WordHighlighter>
</MenuItem>
);
}
else {
if (make !== lastMake) {
items.push(
<Menu.Header key={`${make}-header`}>
{make}
</Menu.Header>
);
lastMake = make;
}
items.push(
<MenuItem key={id} option={result} position={idx}>
<WordHighlighter search={menuProps.text}>
{model}
</WordHighlighter>
</MenuItem>
);
}
idx++;
});
return <Menu {...menuProps}>{items}</Menu>;
};
... и выделять совпадения только в начале любого слова.
const WordHighlighter = props => {
const search = props.search.toLowerCase(),
len = search.length,
parts = [];
let count = 0;
props.children.split(' ').forEach(word => {
if (word.toLowerCase().startsWith(search)) {
parts.push(<mark className="rbt-highlight-text"
key={++count}>{word.substr(0, len)}</mark>);
parts.push(<span key={++count}>{word.substr(len) + ' '}</span>);
}
else {
parts.push(<span key={++count}>{word + ' '}</span>);
}
});
return <span>{parts}</span>;
};