SearchFooter visual tweaks
Finally playing with this, now that we've been doing paginated search results in the main element! Let's see how it goes 😳
I made a thing to make the pagination toolbar smaller (might want to do that on the mobile view too?), and also to put the search suggestions in a popover floating at the top of the search box.
This commit is contained in:
parent
78d8cf3739
commit
eb18fd54b6
3 changed files with 39 additions and 7 deletions
|
@ -3,6 +3,7 @@ import * as Sentry from "@sentry/react";
|
||||||
import { Box, Flex } from "@chakra-ui/react";
|
import { Box, Flex } from "@chakra-ui/react";
|
||||||
import SearchToolbar, { emptySearchQuery } from "./SearchToolbar";
|
import SearchToolbar, { emptySearchQuery } from "./SearchToolbar";
|
||||||
import { MajorErrorMessage, TestErrorSender, useLocalStorage } from "../util";
|
import { MajorErrorMessage, TestErrorSender, useLocalStorage } from "../util";
|
||||||
|
import PaginationToolbar from "../components/PaginationToolbar";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SearchFooter appears on large screens only, to let you search for new items
|
* SearchFooter appears on large screens only, to let you search for new items
|
||||||
|
@ -35,8 +36,23 @@ function SearchFooter() {
|
||||||
<Box fontWeight="600" flex="0 0 auto">
|
<Box fontWeight="600" flex="0 0 auto">
|
||||||
Add new items:
|
Add new items:
|
||||||
</Box>
|
</Box>
|
||||||
<Box width="4" />
|
<Box width="8" />
|
||||||
<SearchToolbar query={query} onChange={setQuery} flex="0 1 100%" />
|
<SearchToolbar
|
||||||
|
query={query}
|
||||||
|
onChange={setQuery}
|
||||||
|
flex="0 1 100%"
|
||||||
|
suggestionsPlacement="top"
|
||||||
|
/>
|
||||||
|
<Box width="8" />
|
||||||
|
<Box flex="0 0 auto">
|
||||||
|
<PaginationToolbar
|
||||||
|
numTotalPages={1}
|
||||||
|
currentPageNumber={1}
|
||||||
|
goToPageNumber={() => alert("TODO")}
|
||||||
|
buildPageUrl={() => null}
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Sentry.ErrorBoundary>
|
</Sentry.ErrorBoundary>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -35,6 +35,17 @@ export function searchQueryIsEmpty(query) {
|
||||||
return Object.values(query).every((value) => !value);
|
return Object.values(query).every((value) => !value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SUGGESTIONS_PLACEMENT_PROPS = {
|
||||||
|
inline: {
|
||||||
|
borderBottomRadius: "md",
|
||||||
|
},
|
||||||
|
top: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "100%",
|
||||||
|
borderTopRadius: "md",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SearchToolbar is rendered above both the ItemsPanel and the SearchPanel,
|
* SearchToolbar is rendered above both the ItemsPanel and the SearchPanel,
|
||||||
* and contains the search field where the user types their query.
|
* and contains the search field where the user types their query.
|
||||||
|
@ -53,6 +64,7 @@ function SearchToolbar({
|
||||||
showItemsLabel = false,
|
showItemsLabel = false,
|
||||||
background = null,
|
background = null,
|
||||||
boxShadow = null,
|
boxShadow = null,
|
||||||
|
suggestionsPlacement = "inline",
|
||||||
...props
|
...props
|
||||||
}) {
|
}) {
|
||||||
const [suggestions, setSuggestions] = React.useState([]);
|
const [suggestions, setSuggestions] = React.useState([]);
|
||||||
|
@ -84,7 +96,7 @@ function SearchToolbar({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const suggestionBgColor = useColorModeValue("transparent", "whiteAlpha.100");
|
const suggestionBgColor = useColorModeValue("white", "whiteAlpha.100");
|
||||||
const highlightedBgColor = useColorModeValue("gray.100", "whiteAlpha.300");
|
const highlightedBgColor = useColorModeValue("gray.100", "whiteAlpha.300");
|
||||||
|
|
||||||
const renderSuggestion = React.useCallback(
|
const renderSuggestion = React.useCallback(
|
||||||
|
@ -110,11 +122,11 @@ function SearchToolbar({
|
||||||
{({ css, cx }) => (
|
{({ css, cx }) => (
|
||||||
<Box
|
<Box
|
||||||
{...otherContainerProps}
|
{...otherContainerProps}
|
||||||
borderBottomRadius="md"
|
|
||||||
boxShadow="md"
|
boxShadow="md"
|
||||||
overflow="auto"
|
overflow="auto"
|
||||||
transition="all 0.4s"
|
transition="all 0.4s"
|
||||||
maxHeight="48"
|
maxHeight="48"
|
||||||
|
width="100%"
|
||||||
className={cx(
|
className={cx(
|
||||||
className,
|
className,
|
||||||
css`
|
css`
|
||||||
|
@ -123,6 +135,7 @@ function SearchToolbar({
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
{...SUGGESTIONS_PLACEMENT_PROPS[suggestionsPlacement]}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{!children && advancedSearchIsOpen && (
|
{!children && advancedSearchIsOpen && (
|
||||||
|
@ -140,7 +153,7 @@ function SearchToolbar({
|
||||||
</ClassNames>
|
</ClassNames>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[advancedSearchIsOpen]
|
[advancedSearchIsOpen, suggestionsPlacement]
|
||||||
);
|
);
|
||||||
|
|
||||||
// When we change the query filters, clear out the suggestions.
|
// When we change the query filters, clear out the suggestions.
|
||||||
|
@ -183,7 +196,7 @@ function SearchToolbar({
|
||||||
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box {...props}>
|
<Box position="relative" {...props}>
|
||||||
<Autosuggest
|
<Autosuggest
|
||||||
suggestions={advancedSearchIsOpen ? allSuggestions : suggestions}
|
suggestions={advancedSearchIsOpen ? allSuggestions : suggestions}
|
||||||
onSuggestionsFetchRequested={({ value }) => {
|
onSuggestionsFetchRequested={({ value }) => {
|
||||||
|
|
|
@ -9,6 +9,7 @@ function PaginationToolbar({
|
||||||
currentPageNumber,
|
currentPageNumber,
|
||||||
goToPageNumber,
|
goToPageNumber,
|
||||||
buildPageUrl,
|
buildPageUrl,
|
||||||
|
size = "md",
|
||||||
...props
|
...props
|
||||||
}) {
|
}) {
|
||||||
const pagesAreLoaded = currentPageNumber != null && numTotalPages != null;
|
const pagesAreLoaded = currentPageNumber != null && numTotalPages != null;
|
||||||
|
@ -32,11 +33,12 @@ function PaginationToolbar({
|
||||||
opacity: 0.4,
|
opacity: 0.4,
|
||||||
}}
|
}}
|
||||||
isDisabled={!hasPrevPage}
|
isDisabled={!hasPrevPage}
|
||||||
|
size={size}
|
||||||
>
|
>
|
||||||
← Prev
|
← Prev
|
||||||
</LinkOrButton>
|
</LinkOrButton>
|
||||||
{numTotalPages > 0 && (
|
{numTotalPages > 0 && (
|
||||||
<Flex align="center">
|
<Flex align="center" paddingX="4" fontSize={size}>
|
||||||
<Box flex="0 0 auto">Page</Box>
|
<Box flex="0 0 auto">Page</Box>
|
||||||
<Box width="1" />
|
<Box width="1" />
|
||||||
<PageNumberSelect
|
<PageNumberSelect
|
||||||
|
@ -61,6 +63,7 @@ function PaginationToolbar({
|
||||||
opacity: 0.4,
|
opacity: 0.4,
|
||||||
}}
|
}}
|
||||||
isDisabled={!hasNextPage}
|
isDisabled={!hasNextPage}
|
||||||
|
size={size}
|
||||||
>
|
>
|
||||||
Next →
|
Next →
|
||||||
</LinkOrButton>
|
</LinkOrButton>
|
||||||
|
|
Loading…
Reference in a new issue