Files
Checkmate/Client/src/Components/Inputs/Select/index.jsx
T

148 lines
3.9 KiB
React
Raw Normal View History

2024-07-24 13:16:43 -04:00
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
2024-07-24 14:09:24 -04:00
import {
MenuItem,
Select as MuiSelect,
Stack,
Typography,
} from "@mui/material";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import "./index.css";
2024-07-24 13:16:43 -04:00
/**
* @component
* @param {object} props
* @param {string} props.id - The ID attribute for the select element.
2024-07-24 14:09:24 -04:00
* @param {string} props.placeholder - The label of the select element.
2024-07-24 13:16:43 -04:00
* @param {string} props.placeholder - The placeholder text when no option is selected.
* @param {boolean} props.isHidden - Whether the placeholder should be hidden.
* @param {string} props.value - The currently selected value.
* @param {object[]} props.items - The array of items to populate in the select dropdown.
2024-07-24 14:33:25 -04:00
* @param {(string | number)} props.items._id - The unique identifier of each item.
2024-07-24 13:16:43 -04:00
* @param {string} props.items.name - The display name of each item.
* @param {function} props.onChange - The function to handle onChange event.
* @param {object} props.sx - The custom styles object for MUI Select component.
* @returns {JSX.Element}
2024-07-24 14:28:32 -04:00
*
* @example
* const frequencies = [
* { _id: 1, name: "1 minute" },
* { _id: 2, name: "2 minutes" },
* { _id: 3, name: "3 minutes" },
* ];
*
* <Select
* id="frequency-id"
2024-10-03 15:24:22 +08:00
* name="my-name"
2024-07-24 14:28:32 -04:00
* label="Check frequency"
2024-07-24 14:35:00 -04:00
* placeholder="Select frequency"
2024-07-24 14:28:32 -04:00
* value={value}
* onChange={handleChange}
* items={frequencies}
* />
2024-07-24 13:16:43 -04:00
*/
2024-07-24 14:09:24 -04:00
const Select = ({
id,
label,
placeholder,
isHidden,
value,
items,
onChange,
sx,
2024-10-03 15:24:22 +08:00
name = "",
2024-07-24 14:09:24 -04:00
}) => {
const theme = useTheme();
const itemStyles = {
fontSize: "var(--env-var-font-size-medium)",
2024-08-27 17:01:28 -04:00
color: theme.palette.text.tertiary,
borderRadius: theme.shape.borderRadius,
margin: theme.spacing(2),
};
return (
2024-08-27 17:01:28 -04:00
<Stack gap={theme.spacing(2)} className="select-wrapper">
{label && (
<Typography
component="h3"
color={theme.palette.text.secondary}
fontWeight={500}
fontSize={13}
2024-08-27 17:01:28 -04:00
>
{label}
</Typography>
)}
2024-07-24 14:09:24 -04:00
<MuiSelect
className="select-component"
value={value}
onChange={onChange}
displayEmpty
2024-10-03 15:24:22 +08:00
name={name}
2024-07-24 14:09:24 -04:00
inputProps={{ id: id }}
IconComponent={KeyboardArrowDownIcon}
MenuProps={{ disableScrollLock: true }}
2024-08-27 17:01:28 -04:00
sx={{
fontSize: 13,
2024-08-27 17:01:28 -04:00
minWidth: "125px",
"& fieldset": {
borderRadius: theme.shape.borderRadius,
borderColor: theme.palette.border.dark,
},
"&:not(.Mui-focused):hover fieldset": {
borderColor: theme.palette.border.dark,
},
2024-08-28 22:14:55 -04:00
"& svg path": {
fill: theme.palette.other.icon,
},
2024-08-27 17:01:28 -04:00
...sx,
}}
2024-07-24 14:09:24 -04:00
>
{placeholder && (
<MenuItem
className="select-placeholder"
value="0"
sx={{
display: isHidden ? "none" : "flex",
visibility: isHidden ? "none" : "visible",
...itemStyles,
}}
>
{placeholder}
</MenuItem>
)}
{items.map((item) => (
<MenuItem
value={item._id}
key={`${id}-${item._id}`}
sx={{
...itemStyles,
}}
>
{item.name}
</MenuItem>
))}
</MuiSelect>
</Stack>
);
};
2024-07-24 13:16:43 -04:00
Select.propTypes = {
id: PropTypes.string.isRequired,
2024-10-03 15:24:22 +08:00
name: PropTypes.string,
2024-07-24 14:09:24 -04:00
label: PropTypes.string,
2024-07-24 13:16:43 -04:00
placeholder: PropTypes.string,
isHidden: PropTypes.bool,
2024-07-24 14:09:24 -04:00
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
2024-07-24 13:16:43 -04:00
items: PropTypes.arrayOf(
PropTypes.shape({
2024-07-24 14:09:24 -04:00
_id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
2024-07-24 13:16:43 -04:00
name: PropTypes.string.isRequired,
})
).isRequired,
onChange: PropTypes.func.isRequired,
sx: PropTypes.object,
};
export default Select;