import PropTypes from "prop-types"; import { Box, ListItem, Autocomplete, TextField, Stack, Typography } from "@mui/material"; import { useTheme } from "@emotion/react"; import SearchIcon from "../../../assets/icons/search.svg?react"; /** * Search component using Material UI's Autocomplete. * * @param {Object} props * @param {string} props.id - Unique identifier for the Autocomplete component * @param {Array} props.options - Options to display in the Autocomplete dropdown * @param {string} props.filteredBy - Key to access the option label from the options * @param {string} props.value - Current input value for the Autocomplete * @param {Function} props.handleChange - Function to call when the input changes * @param {Object} props.sx - Additional styles to apply to the component * @returns {JSX.Element} The rendered Search component */ const SearchAdornment = () => { const theme = useTheme(); return ( ); }; //TODO keep search state inside of component const Search = ({ id, options, filteredBy, secondaryLabel, value, inputValue, handleInputChange, handleChange, sx, multiple = false, isAdorned = true, error, disabled, }) => { const theme = useTheme(); return ( { handleInputChange(newValue); }} onChange={(_, newValue) => { handleChange && handleChange(newValue); }} fullWidth freeSolo disabled={disabled} disableClearable options={options} getOptionLabel={(option) => option[filteredBy]} renderInput={(params) => ( }), }} sx={{ "& fieldset": { borderColor: theme.palette.border.light, borderRadius: theme.shape.borderRadius, }, "& .MuiOutlinedInput-root:hover:not(:has(input:focus)):not(:has(textarea:focus)) fieldset": { borderColor: theme.palette.border.light, }, }} /> {error && ( {error} )} )} filterOptions={(options, { inputValue }) => { const filtered = options.filter((option) => option[filteredBy].toLowerCase().includes(inputValue.toLowerCase()) ); if (filtered.length === 0) { return [{ [filteredBy]: "No monitors found", noOptions: true }]; } return filtered; }} renderOption={(props, option) => { const { key, ...optionProps } = props; return ( {option[filteredBy] + (secondaryLabel ? ` (${option[secondaryLabel]})` : "")} ); }} slotProps={{ popper: { keepMounted: true, sx: { "& ul": { p: 2 }, "& li.MuiAutocomplete-option": { color: theme.palette.text.secondary, px: 4, borderRadius: theme.shape.borderRadius, }, "& .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true'], & .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true'].Mui-focused, & .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected='true']:hover": { backgroundColor: theme.palette.background.fill, }, "& .MuiAutocomplete-noOptions": { px: theme.spacing(6), py: theme.spacing(5), }, }, }, }} sx={{ /* height: 34,*/ "&.MuiAutocomplete-root .MuiAutocomplete-input": { p: 0 }, ...sx, }} /> ); }; Search.propTypes = { id: PropTypes.string, multiple: PropTypes.bool, options: PropTypes.array.isRequired, filteredBy: PropTypes.string.isRequired, secondaryLabel: PropTypes.string, value: PropTypes.array, inputValue: PropTypes.string.isRequired, handleInputChange: PropTypes.func.isRequired, handleChange: PropTypes.func, isAdorned: PropTypes.bool, sx: PropTypes.object, error: PropTypes.string, disabled: PropTypes.bool, }; export default Search;