extract SearchToolbar into a separate file
This is in preparation for extending it with more UI stuff to auto-suggest zones!
This commit is contained in:
parent
bf465d802e
commit
612e549ddc
2 changed files with 78 additions and 75 deletions
|
@ -1,17 +1,8 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import { Box, Flex } from "@chakra-ui/core";
|
||||||
Box,
|
|
||||||
Flex,
|
|
||||||
IconButton,
|
|
||||||
Input,
|
|
||||||
InputGroup,
|
|
||||||
InputLeftElement,
|
|
||||||
InputRightElement,
|
|
||||||
useColorModeValue,
|
|
||||||
} from "@chakra-ui/core";
|
|
||||||
import { CloseIcon, SearchIcon } from "@chakra-ui/icons";
|
|
||||||
|
|
||||||
import ItemsPanel from "./ItemsPanel";
|
import ItemsPanel from "./ItemsPanel";
|
||||||
|
import SearchToolbar from "./SearchToolbar";
|
||||||
import SearchPanel from "./SearchPanel";
|
import SearchPanel from "./SearchPanel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,68 +73,4 @@ function ItemsAndSearchPanels({ loading, outfitState, dispatchToOutfit }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SearchToolbar is rendered above both the ItemsPanel and the SearchPanel,
|
|
||||||
* and contains the search field where the user types their query.
|
|
||||||
*
|
|
||||||
* It has some subtle keyboard interaction support, like DownArrow to go to the
|
|
||||||
* first search result, and Escape to clear the search and go back to the
|
|
||||||
* ItemsPanel. (The SearchPanel can also send focus back to here, with Escape
|
|
||||||
* from anywhere, or UpArrow from the first result!)
|
|
||||||
*/
|
|
||||||
function SearchToolbar({
|
|
||||||
query,
|
|
||||||
searchQueryRef,
|
|
||||||
firstSearchResultRef,
|
|
||||||
onChange,
|
|
||||||
}) {
|
|
||||||
const onMoveFocusDownToResults = (e) => {
|
|
||||||
if (firstSearchResultRef.current) {
|
|
||||||
firstSearchResultRef.current.focus();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<InputGroup>
|
|
||||||
<InputLeftElement>
|
|
||||||
<SearchIcon color="gray.400" />
|
|
||||||
</InputLeftElement>
|
|
||||||
<Input
|
|
||||||
placeholder="Search for items to add…"
|
|
||||||
aria-label="Search for items to add…"
|
|
||||||
focusBorderColor={focusBorderColor}
|
|
||||||
value={query}
|
|
||||||
ref={searchQueryRef}
|
|
||||||
onChange={(e) => onChange(e.target.value)}
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.key === "Escape") {
|
|
||||||
onChange("");
|
|
||||||
e.target.blur();
|
|
||||||
} else if (e.key === "ArrowDown") {
|
|
||||||
onMoveFocusDownToResults(e);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{query && (
|
|
||||||
<InputRightElement>
|
|
||||||
<IconButton
|
|
||||||
icon={<CloseIcon />}
|
|
||||||
color="gray.400"
|
|
||||||
variant="ghost"
|
|
||||||
colorScheme="green"
|
|
||||||
aria-label="Clear search"
|
|
||||||
onClick={() => onChange("")}
|
|
||||||
// Big style hacks here!
|
|
||||||
height="calc(100% - 2px)"
|
|
||||||
marginRight="2px"
|
|
||||||
/>
|
|
||||||
</InputRightElement>
|
|
||||||
)}
|
|
||||||
</InputGroup>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ItemsAndSearchPanels;
|
export default ItemsAndSearchPanels;
|
||||||
|
|
76
src/app/WardrobePage/SearchToolbar.js
Normal file
76
src/app/WardrobePage/SearchToolbar.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
InputGroup,
|
||||||
|
InputLeftElement,
|
||||||
|
InputRightElement,
|
||||||
|
useColorModeValue,
|
||||||
|
} from "@chakra-ui/core";
|
||||||
|
import { CloseIcon, SearchIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SearchToolbar is rendered above both the ItemsPanel and the SearchPanel,
|
||||||
|
* and contains the search field where the user types their query.
|
||||||
|
*
|
||||||
|
* It has some subtle keyboard interaction support, like DownArrow to go to the
|
||||||
|
* first search result, and Escape to clear the search and go back to the
|
||||||
|
* ItemsPanel. (The SearchPanel can also send focus back to here, with Escape
|
||||||
|
* from anywhere, or UpArrow from the first result!)
|
||||||
|
*/
|
||||||
|
function SearchToolbar({
|
||||||
|
query,
|
||||||
|
searchQueryRef,
|
||||||
|
firstSearchResultRef,
|
||||||
|
onChange,
|
||||||
|
}) {
|
||||||
|
const onMoveFocusDownToResults = (e) => {
|
||||||
|
if (firstSearchResultRef.current) {
|
||||||
|
firstSearchResultRef.current.focus();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InputGroup>
|
||||||
|
<InputLeftElement>
|
||||||
|
<SearchIcon color="gray.400" />
|
||||||
|
</InputLeftElement>
|
||||||
|
<Input
|
||||||
|
placeholder="Search for items to add…"
|
||||||
|
aria-label="Search for items to add…"
|
||||||
|
focusBorderColor={focusBorderColor}
|
||||||
|
value={query}
|
||||||
|
ref={searchQueryRef}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
onChange("");
|
||||||
|
e.target.blur();
|
||||||
|
} else if (e.key === "ArrowDown") {
|
||||||
|
onMoveFocusDownToResults(e);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{query && (
|
||||||
|
<InputRightElement>
|
||||||
|
<IconButton
|
||||||
|
icon={<CloseIcon />}
|
||||||
|
color="gray.400"
|
||||||
|
variant="ghost"
|
||||||
|
colorScheme="green"
|
||||||
|
aria-label="Clear search"
|
||||||
|
onClick={() => onChange("")}
|
||||||
|
// Big style hacks here!
|
||||||
|
height="calc(100% - 2px)"
|
||||||
|
marginRight="2px"
|
||||||
|
/>
|
||||||
|
</InputRightElement>
|
||||||
|
)}
|
||||||
|
</InputGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SearchToolbar;
|
Loading…
Reference in a new issue