SearchBar.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import React, { useEffect, useRef, useState } from "react";
  2. import Button from "./Button";
  3. import styled from "styled-components";
  4. interface Props {
  5. setSearchFilter: (x: string) => void;
  6. disabled: boolean;
  7. prompt?: string;
  8. fullWidth?: boolean;
  9. }
  10. const SearchBar: React.FC<Props> = ({
  11. setSearchFilter,
  12. disabled,
  13. prompt,
  14. fullWidth,
  15. }) => {
  16. const [searchInput, setSearchInput] = useState("");
  17. const inputRef = useRef(null);
  18. // hack for deferring the focus call to the next tick of the event loop, giving the browser enough time to render the input element before setting focus on it
  19. useEffect(() => {
  20. setTimeout(() => {
  21. inputRef.current.focus();
  22. }, 0);
  23. }, []);
  24. return (
  25. <SearchRowWrapper fullWidth={fullWidth}>
  26. <SearchBarWrapper>
  27. <i className="material-icons">search</i>
  28. <SearchInput
  29. value={searchInput}
  30. onChange={(e: any) => {
  31. setSearchInput(e.target.value);
  32. setSearchFilter(e.target.value);
  33. }}
  34. onKeyPress={({ key }) => {
  35. if (key === "Enter") {
  36. setSearchFilter(searchInput);
  37. }
  38. }}
  39. placeholder={prompt}
  40. ref={inputRef}
  41. />
  42. </SearchBarWrapper>
  43. <ButtonWrapper disabled={disabled}>
  44. <Button
  45. onClick={() => setSearchFilter(searchInput)}
  46. disabled={disabled}
  47. >
  48. Search
  49. </Button>
  50. </ButtonWrapper>
  51. </SearchRowWrapper>
  52. );
  53. };
  54. export default SearchBar;
  55. const SearchRow = styled.div`
  56. display: flex;
  57. align-items: center;
  58. height: 40px;
  59. background: #ffffff11;
  60. border-bottom: 1px solid #606166;
  61. margin-bottom: 10px;
  62. `;
  63. const SearchRowWrapper = styled(SearchRow)`
  64. border-bottom: 0;
  65. border: 1px solid #ffffff55;
  66. border-radius: 3px;
  67. ${(props: { fullWidth: boolean }) => {
  68. if (props.fullWidth) {
  69. return "width: 100%;";
  70. }
  71. }}
  72. `;
  73. const ButtonWrapper = styled.div`
  74. background: ${(props: { disabled?: boolean }) =>
  75. props.disabled ? "#aaaabbee" : "#616FEEcc"};
  76. :hover {
  77. background: ${(props: { disabled?: boolean }) =>
  78. props.disabled ? "" : "#505edddd"};
  79. }
  80. height: 40px;
  81. display: flex;
  82. align-items: center;
  83. `;
  84. const SearchBarWrapper = styled.div`
  85. display: flex;
  86. flex: 1;
  87. > i {
  88. color: #aaaabb;
  89. padding-top: 1px;
  90. margin-left: 13px;
  91. font-size: 18px;
  92. margin-right: 8px;
  93. }
  94. `;
  95. const SearchInput = styled.input`
  96. outline: none;
  97. border: none;
  98. font-size: 13px;
  99. background: none;
  100. width: 100%;
  101. color: white;
  102. height: 20px;
  103. `;