Leave search suggestions open on blur
Someone wrote in how, when your search query ends with a string that creates Advanced Search suggestions, clicking on items in the list requires two clicks: one to blur and dismiss the suggestions, and one to actually click the item. Here, I'm experimenting with just leaving the suggestions open. It doesn't feel _great_, but it definitely feels _better_ than before on this edge case, and I thiiink this only affects this edge case in practice? We'll see if it feels goofy in some cases I forgot tho!
This commit is contained in:
parent
94efb80e65
commit
0333b47c05
1 changed files with 86 additions and 91 deletions
|
@ -142,101 +142,96 @@ function SearchToolbar({
|
||||||
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClassNames>
|
<Autosuggest
|
||||||
{({ css }) => (
|
suggestions={suggestions}
|
||||||
<Autosuggest
|
onSuggestionsFetchRequested={({ value }) =>
|
||||||
suggestions={suggestions}
|
setSuggestions(getSuggestions(value, query, zoneLabels))
|
||||||
onSuggestionsFetchRequested={({ value }) =>
|
}
|
||||||
setSuggestions(getSuggestions(value, query, zoneLabels))
|
onSuggestionSelected={(e, { suggestion }) => {
|
||||||
|
const valueWithoutLastWord = query.value.match(/^(.*?)\s*\S+$/)[1];
|
||||||
|
onChange({
|
||||||
|
...query,
|
||||||
|
value: valueWithoutLastWord,
|
||||||
|
filterToZoneLabel: suggestion.zoneLabel || query.filterToZoneLabel,
|
||||||
|
filterToItemKind: suggestion.itemKind || query.filterToItemKind,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
getSuggestionValue={(zl) => zl}
|
||||||
|
alwaysRenderSuggestions={true}
|
||||||
|
highlightFirstSuggestion={true}
|
||||||
|
renderSuggestion={renderSuggestion}
|
||||||
|
renderSuggestionsContainer={renderSuggestionsContainer}
|
||||||
|
renderInputComponent={(inputProps) => (
|
||||||
|
<InputGroup boxShadow={boxShadow} borderRadius="md">
|
||||||
|
{queryFilterText ? (
|
||||||
|
<InputLeftAddon>
|
||||||
|
<SearchIcon color="gray.400" marginRight="3" />
|
||||||
|
<Box fontSize="sm">{queryFilterText}</Box>
|
||||||
|
</InputLeftAddon>
|
||||||
|
) : (
|
||||||
|
<InputLeftElement>
|
||||||
|
<SearchIcon color="gray.400" />
|
||||||
|
</InputLeftElement>
|
||||||
|
)}
|
||||||
|
<Input background={background} {...inputProps} />
|
||||||
|
{(query.value || queryFilterText) && (
|
||||||
|
<InputRightElement>
|
||||||
|
<IconButton
|
||||||
|
icon={<CloseIcon />}
|
||||||
|
color="gray.400"
|
||||||
|
variant="ghost"
|
||||||
|
colorScheme="green"
|
||||||
|
aria-label="Clear search"
|
||||||
|
onClick={() => {
|
||||||
|
setSuggestions([]);
|
||||||
|
onChange(emptySearchQuery);
|
||||||
|
}}
|
||||||
|
// Big style hacks here!
|
||||||
|
height="calc(100% - 2px)"
|
||||||
|
marginRight="2px"
|
||||||
|
/>
|
||||||
|
</InputRightElement>
|
||||||
|
)}
|
||||||
|
</InputGroup>
|
||||||
|
)}
|
||||||
|
inputProps={{
|
||||||
|
// placeholder: "Search for items to add…",
|
||||||
|
"aria-label": "Search for items to add…",
|
||||||
|
focusBorderColor: focusBorderColor,
|
||||||
|
value: query.value || "",
|
||||||
|
ref: searchQueryRef,
|
||||||
|
minWidth: 0,
|
||||||
|
onChange: (e, { newValue, method }) => {
|
||||||
|
// The Autosuggest tries to change the _entire_ value of the element
|
||||||
|
// when navigating suggestions, which isn't actually what we want.
|
||||||
|
// Only accept value changes that are typed by the user!
|
||||||
|
if (method === "type") {
|
||||||
|
onChange({ ...query, value: newValue });
|
||||||
}
|
}
|
||||||
onSuggestionsClearRequested={() => setSuggestions([])}
|
},
|
||||||
onSuggestionSelected={(e, { suggestion }) => {
|
onKeyDown: (e) => {
|
||||||
const valueWithoutLastWord = query.value.match(/^(.*?)\s*\S+$/)[1];
|
if (e.key === "Escape") {
|
||||||
|
if (suggestions.length > 0) {
|
||||||
|
setSuggestions([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onChange(null);
|
||||||
|
e.target.blur();
|
||||||
|
} else if (e.key === "ArrowDown") {
|
||||||
|
if (suggestions.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onMoveFocusDownToResults(e);
|
||||||
|
} else if (e.key === "Backspace" && e.target.selectionStart === 0) {
|
||||||
onChange({
|
onChange({
|
||||||
...query,
|
...query,
|
||||||
value: valueWithoutLastWord,
|
filterToItemKind: null,
|
||||||
filterToZoneLabel:
|
filterToZoneLabel: null,
|
||||||
suggestion.zoneLabel || query.filterToZoneLabel,
|
|
||||||
filterToItemKind: suggestion.itemKind || query.filterToItemKind,
|
|
||||||
});
|
});
|
||||||
}}
|
}
|
||||||
getSuggestionValue={(zl) => zl}
|
},
|
||||||
highlightFirstSuggestion={true}
|
}}
|
||||||
renderSuggestion={renderSuggestion}
|
/>
|
||||||
renderSuggestionsContainer={renderSuggestionsContainer}
|
|
||||||
renderInputComponent={(inputProps) => (
|
|
||||||
<InputGroup boxShadow={boxShadow} borderRadius="md">
|
|
||||||
{queryFilterText ? (
|
|
||||||
<InputLeftAddon>
|
|
||||||
<SearchIcon color="gray.400" marginRight="3" />
|
|
||||||
<Box fontSize="sm">{queryFilterText}</Box>
|
|
||||||
</InputLeftAddon>
|
|
||||||
) : (
|
|
||||||
<InputLeftElement>
|
|
||||||
<SearchIcon color="gray.400" />
|
|
||||||
</InputLeftElement>
|
|
||||||
)}
|
|
||||||
<Input background={background} {...inputProps} />
|
|
||||||
{(query.value || queryFilterText) && (
|
|
||||||
<InputRightElement>
|
|
||||||
<IconButton
|
|
||||||
icon={<CloseIcon />}
|
|
||||||
color="gray.400"
|
|
||||||
variant="ghost"
|
|
||||||
colorScheme="green"
|
|
||||||
aria-label="Clear search"
|
|
||||||
onClick={() => onChange(emptySearchQuery)}
|
|
||||||
// Big style hacks here!
|
|
||||||
height="calc(100% - 2px)"
|
|
||||||
marginRight="2px"
|
|
||||||
/>
|
|
||||||
</InputRightElement>
|
|
||||||
)}
|
|
||||||
</InputGroup>
|
|
||||||
)}
|
|
||||||
inputProps={{
|
|
||||||
// placeholder: "Search for items to add…",
|
|
||||||
"aria-label": "Search for items to add…",
|
|
||||||
focusBorderColor: focusBorderColor,
|
|
||||||
value: query.value || "",
|
|
||||||
ref: searchQueryRef,
|
|
||||||
minWidth: 0,
|
|
||||||
onChange: (e, { newValue, method }) => {
|
|
||||||
// The Autosuggest tries to change the _entire_ value of the element
|
|
||||||
// when navigating suggestions, which isn't actually what we want.
|
|
||||||
// Only accept value changes that are typed by the user!
|
|
||||||
if (method === "type") {
|
|
||||||
onChange({ ...query, value: newValue });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onKeyDown: (e) => {
|
|
||||||
if (e.key === "Escape") {
|
|
||||||
if (suggestions.length > 0) {
|
|
||||||
setSuggestions([]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onChange(null);
|
|
||||||
e.target.blur();
|
|
||||||
} else if (e.key === "ArrowDown") {
|
|
||||||
if (suggestions.length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onMoveFocusDownToResults(e);
|
|
||||||
} else if (
|
|
||||||
e.key === "Backspace" &&
|
|
||||||
e.target.selectionStart === 0
|
|
||||||
) {
|
|
||||||
onChange({
|
|
||||||
...query,
|
|
||||||
filterToItemKind: null,
|
|
||||||
filterToZoneLabel: null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ClassNames>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue