diff options
Diffstat (limited to 'FrontEnd/src/views/common/SearchInput.tsx')
-rw-r--r-- | FrontEnd/src/views/common/SearchInput.tsx | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/FrontEnd/src/views/common/SearchInput.tsx b/FrontEnd/src/views/common/SearchInput.tsx new file mode 100644 index 00000000..ccb6dad6 --- /dev/null +++ b/FrontEnd/src/views/common/SearchInput.tsx @@ -0,0 +1,78 @@ +import React, { useCallback } from "react"; +import classnames from "classnames"; +import { useTranslation } from "react-i18next"; +import { Spinner, Form, Button } from "react-bootstrap"; + +export interface SearchInputProps { + value: string; + onChange: (value: string) => void; + onButtonClick: () => void; + className?: string; + loading?: boolean; + buttonText?: string; + placeholder?: string; + additionalButton?: React.ReactNode; + alwaysOneline?: boolean; +} + +const SearchInput: React.FC<SearchInputProps> = (props) => { + const { onChange, onButtonClick, alwaysOneline } = props; + + const { t } = useTranslation(); + + const onInputChange = useCallback( + (event: React.ChangeEvent<HTMLInputElement>): void => { + onChange(event.currentTarget.value); + }, + [onChange] + ); + + const onInputKeyPress = useCallback( + (event: React.KeyboardEvent<HTMLInputElement>): void => { + if (event.key === "Enter") { + onButtonClick(); + event.preventDefault(); + } + }, + [onButtonClick] + ); + + return ( + <Form + className={classnames( + "cru-search-input", + alwaysOneline ? "flex-nowrap" : "flex-sm-nowrap", + props.className + )} + > + <Form.Control + className="me-sm-2 flex-grow-1" + value={props.value} + onChange={onInputChange} + onKeyPress={onInputKeyPress} + placeholder={props.placeholder} + /> + {props.additionalButton ? ( + <div className="mt-2 mt-sm-0 flex-shrink-0 order-sm-last ms-sm-2"> + {props.additionalButton} + </div> + ) : null} + <div + className={classnames( + alwaysOneline ? "mt-0 ms-2" : "mt-2 mt-sm-0 ms-auto ms-sm-0", + "flex-shrink-0" + )} + > + {props.loading ? ( + <Spinner variant="primary" animation="border" /> + ) : ( + <Button variant="outline-primary" onClick={props.onButtonClick}> + {props.buttonText ?? t("search")} + </Button> + )} + </div> + </Form> + ); +}; + +export default SearchInput; |