Make typeahead results selectable

Summary: You should be able to arrow key up/down through typeahead results, and later click or press enter to add them. This diff just adds the selection UI but not confirming.

Reviewed By: quark-zju

Differential Revision: D45627731

fbshipit-source-id: 1b06b362ed340fdbadf8f78b6841eda9ec08a53d
This commit is contained in:
Evan Krause 2023-05-08 15:30:28 -07:00 committed by Facebook GitHub Bot
parent c08bc84796
commit 73bc2c3a31
2 changed files with 33 additions and 3 deletions

View File

@ -301,6 +301,15 @@
flex-direction: row;
gap: var(--pad);
align-items: center;
border-radius: var(--halfpad);
padding: var(--halfpad);
margin: calc(-1 * var(--halfpad));
cursor: pointer;
}
.commit-info-tokenized-field .typeahead-suggestions .suggestion:hover,
.commit-info-tokenized-field .typeahead-suggestions .selected-suggestion {
background-color: var(--hover-darken);
}
.commit-info-tokenized-field .typeahead-suggestions .suggestion-label {
display: flex;

View File

@ -52,6 +52,8 @@ export function CommitInfoTextField({
const [typeaheadSuggestions, setTypeaheadSuggestions] = useState<TypeaheadSuggestions>(undefined);
const [selectedSuggestionIndex, setSelectedIndex] = useState(0);
const onInput = (event: {target: EventTarget | null}) => {
const newValue = (event?.target as HTMLInputElement)?.value;
setEditedCommitMessage(tokensToString(tokens, newValue));
@ -64,7 +66,22 @@ export function CommitInfoTextField({
const fieldKey = name.toLowerCase().replace(/\s/g, '-');
return (
<div className="commit-info-tokenized-field">
<div
className="commit-info-tokenized-field"
onKeyDown={event => {
const values = (typeaheadSuggestions as TypeaheadSuggestions & {type: 'success'})?.values;
if (values == null) {
return;
}
if (event.key === 'ArrowDown') {
setSelectedIndex(last => Math.min(last + 1, values.length - 1));
event.preventDefault();
} else if (event.key === 'ArrowUp') {
// allow -1, so you can up arrow "above" the top, to make it highlight nothing
setSelectedIndex(last => Math.max(last - 1, -1));
event.preventDefault();
}
}}>
{tokens
.filter(token => token != '')
.map((token, i) => (
@ -88,8 +105,12 @@ export function CommitInfoTextField({
{typeaheadSuggestions?.type === 'loading' ? (
<Icon icon="loading" />
) : (
typeaheadSuggestions?.values.map(suggestion => (
<span key={suggestion.value} className="suggestion">
typeaheadSuggestions?.values.map((suggestion, index) => (
<span
key={suggestion.value}
className={
'suggestion' + (index === selectedSuggestionIndex ? ' selected-suggestion' : '')
}>
{suggestion.image && <img src={suggestion.image} alt={suggestion.label} />}
<span className="suggestion-label">
<span>{suggestion.label}</span>