dashboard/src/components/searchBar.tsx

139 lines
3 KiB
TypeScript
Raw Normal View History

import React, { useEffect, useState } from "react";
2020-07-08 19:36:36 +02:00
import styled from "styled-components";
import { Button } from "./elements";
const Search = styled.form`
width: 100%;
height: 2rem;
display: flex;
padding-top: 0.25rem;
`;
2020-07-08 19:36:36 +02:00
const SearchInput = styled.input`
width: 100%;
2021-06-14 11:29:03 +02:00
margin: 0px;
2020-07-08 19:36:36 +02:00
font-size: 1rem;
2020-07-08 19:36:36 +02:00
border: none;
2021-07-10 23:57:08 +02:00
border-bottom: 1px solid ${(props) => props.theme.accentColor};
2021-06-14 11:29:03 +02:00
border-radius: 0;
2020-07-08 19:36:36 +02:00
background: none;
2021-07-10 23:57:08 +02:00
color: ${(props) => props.theme.mainColor};
2021-03-11 13:54:38 +01:00
:focus {
outline: none;
}
2020-07-08 19:36:36 +02:00
`;
const SearchButton = styled(Button)`
margin: 0px 2px;
min-height: 0;
`;
export interface ISearchProviderProps {
name: string;
url: string;
prefix: string;
}
2020-07-08 19:36:36 +02:00
2021-04-22 11:15:41 +02:00
export interface ISearchProps {
placeholder: string;
2021-04-22 11:15:41 +02:00
defaultProvider: string;
autoFocus?: boolean;
providers: Array<ISearchProviderProps> | undefined;
}
2020-07-08 19:36:36 +02:00
2021-04-22 11:15:41 +02:00
interface ISearchBarProps {
2022-02-13 20:57:26 +01:00
search?: ISearchProps;
2021-04-22 11:15:41 +02:00
}
2021-06-21 16:52:16 +02:00
export const handleQueryWithProvider = (
search: ISearchProps,
2021-06-21 16:52:16 +02:00
query: string,
) => {
2022-04-10 21:31:40 +02:00
const queryArray: Array<string> = query.split(" ");
const prefix: string = queryArray[0];
2021-06-21 16:52:16 +02:00
queryArray.shift();
2022-04-10 21:31:40 +02:00
const searchQuery: string = queryArray.join(" ");
2021-06-21 16:52:16 +02:00
2022-04-10 21:31:40 +02:00
let providerFound = false;
if (search.providers) {
search.providers.forEach((provider: ISearchProviderProps) => {
2021-06-21 16:52:16 +02:00
if (provider.prefix === prefix) {
providerFound = true;
window.location.href = provider.url + searchQuery;
}
});
}
if (!providerFound) window.location.href = search.defaultProvider + query;
2021-06-21 16:52:16 +02:00
};
2021-03-21 19:59:18 +01:00
/**
* Renders a search bar
* @param {ISearchBarProps} search - The search providers for the search bar to use
2021-03-21 19:59:18 +01:00
*/
const SearchBar = ({ search }: ISearchBarProps) => {
2022-04-10 21:31:40 +02:00
const [input, setInput] = useState<string>("");
const [buttonsHidden, setButtonsHidden] = useState<boolean>(true);
2021-03-23 16:26:14 +01:00
useEffect(() => setButtonsHidden(input === ""), [input]);
2020-07-08 19:36:36 +02:00
2022-02-13 20:57:26 +01:00
if (search === undefined) return <></>;
2020-07-08 19:36:36 +02:00
const handleSearchQuery = (e: React.FormEvent) => {
2022-04-10 21:31:40 +02:00
const query: string = input || "";
2020-07-08 19:36:36 +02:00
if (query.split(" ")[0].includes("/")) {
handleQueryWithProvider(search, query);
2020-07-08 19:36:36 +02:00
} else {
2021-04-22 11:15:41 +02:00
window.location.href = search.defaultProvider + query;
2020-07-08 19:36:36 +02:00
}
e.preventDefault();
};
const autoFocus = () => {
return search.autoFocus !== undefined ? search.autoFocus : false;
};
2020-07-08 19:36:36 +02:00
return (
<Search onSubmit={(e) => handleSearchQuery(e)}>
2020-07-08 19:36:36 +02:00
<SearchInput
type="text"
2021-06-21 16:52:16 +02:00
data-testid="search-input"
value={input}
placeholder={search.placeholder}
autoFocus={autoFocus()}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setInput(e.target.value)
}
2020-07-08 19:36:36 +02:00
></SearchInput>
<SearchButton
type="button"
2021-06-21 16:52:16 +02:00
data-testid="search-clear"
onClick={() => setInput("")}
hidden={buttonsHidden}
>
Clear
</SearchButton>
2021-06-21 16:52:16 +02:00
<SearchButton
type="submit"
data-testid="search-submit"
hidden={buttonsHidden}
>
Search
</SearchButton>
</Search>
2020-07-08 19:36:36 +02:00
);
};
export default SearchBar;