@parkassist/pa-ui-library
Version:
INX Platform elements
298 lines • 10.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useRef, useState } from "react";
import Palette from "../../constants/Palette";
import FontStyles from "../../constants/FontStyles";
import Select from "@mui/material/Select";
import MenuItem from '@mui/material/MenuItem';
import { InputLabel } from "@mui/material";
import * as Icons from "../Icons";
import FormControl from "@mui/material/FormControl";
import CheckboxInput from "../Checkbox/CheckboxInput";
import Box from "@mui/material/Box";
import ChipItem from "../Chip";
import IconButton from "@mui/material/IconButton";
import MaterialSearchInput from "../MaterialSearchInput";
import ListItemText from "@mui/material/ListItemText";
import ListItemIcon from "@mui/material/ListItemIcon";
import { getLabel, getUniqueField, getValue, getMenuItemKey } from "../utils";
import StyledFormHelperText from "../Utils/StyledFormHelperText";
import styled from '@emotion/styled';
const MenuOptionHelperText = styled.p`
margin: 0;
font: ${FontStyles.SMALL_FONT};
font-weight: 500;
`;
const IconComponent = ({
disabled,
iconProps
}) => _jsx(Icons.OpenArrowIcon, Object.assign({
style: {
pointerEvents: 'none',
position: 'absolute',
right: '10px',
top: 'auto'
},
filter: disabled ? Palette.FILTER_VERY_LIGHT_GREY : null
}, iconProps));
const MaterialSelect = ({
label,
options,
value,
onChange,
disabled,
helperText,
error = false,
size = 'small',
fullWidth = true,
style,
multiple = false,
displayChips = false,
displaySearchInput = false,
chipsDeletable,
labelField = 'label',
uniqueField = 'id',
menuMaxHeight = 230,
chipItemSize = 'small',
showClearButton = false,
hideEmptyHelperTextSpace = false,
inputProps
}) => {
var _a, _b;
const [searchPhrase, setSearchPhrase] = useState('');
const [hover, setHover] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const selectRef = useRef(null);
const selectInputRef = useRef(null);
const filterOptions = opts => {
const regex = new RegExp(searchPhrase, 'i');
return opts.filter(item => regex.test(getLabel(item, labelField)));
};
const checkIfSelected = (option, unique) => {
return value.findIndex(item => {
if (typeof item === 'object') {
return getUniqueField(item, unique) === getUniqueField(option, unique);
}
return item === option;
}) > -1;
};
const isSomeSelected = () => {
if (multiple) {
return value.length > 0;
}
return !!value;
};
const deleteValue = (value, valueToDelete) => {
onChange(value.filter(item => getUniqueField(item, uniqueField) !== getUniqueField(valueToDelete, uniqueField)));
};
const getHelperText = (text, hideEmptySpace) => {
if (!text && !hideEmptySpace) return ' ';
return text;
};
const clearButtonVisible = (hover || isOpen) && isSomeSelected();
const filteredOptions = searchPhrase ? filterOptions(options) : options;
return _jsxs(FormControl, {
fullWidth: fullWidth,
size: size,
onMouseLeave: () => setHover(false),
onMouseEnter: () => setHover(true),
children: [_jsx(InputLabel, {
id: `select-${label}`,
sx: {
color: Palette.DIM_GREY,
font: FontStyles.INPUT_FONT,
'&.MuiInputLabel-shrink': {
color: error ? Palette.ERROR_RED : Palette.DIM_GREY,
font: FontStyles.INPUT_SHRINK_LABEL,
lineHeight: '25px'
},
'&.MuiInputLabel-shrink.Mui-focused': {
color: error ? Palette.ERROR_RED : Palette.LIGHT_BLACK
}
},
children: label
}), _jsxs(Select, {
ref: selectRef,
inputProps: Object.assign({
inputRef: selectInputRef
}, inputProps),
onClose: () => {
setIsOpen(false);
setHover(false);
},
onOpen: () => {
setIsOpen(true);
setHover(false);
},
label: label,
labelId: `select-${label}`,
value: multiple ? value.map(val => getValue(val, options, uniqueField)) : getValue(value, options, uniqueField),
onChange: event => {
const newValue = event.target.value;
newValue && onChange(newValue);
},
disabled: disabled,
error: error,
multiple: multiple,
renderValue: selected => {
return multiple ? displayChips ? _jsx(Box, {
sx: {
display: 'flex',
flexWrap: 'wrap',
gap: 0.5
},
children: selected.map(selectedValue => _jsx(ChipItem, Object.assign({
label: getLabel(selectedValue, labelField),
size: chipItemSize
}, chipsDeletable && {
onDelete: () => deleteValue(value, selectedValue)
}), getUniqueField(selectedValue, uniqueField)))
}) : selected.map(val => getLabel(val, labelField)).join(', ') : getLabel(selected, labelField);
},
endAdornment: showClearButton && _jsx(IconButton, {
disableRipple: true,
sx: {
position: 'absolute',
visibility: clearButtonVisible ? "visible" : "hidden",
height: '16px',
width: '16px',
right: '30px'
},
onMouseDown: event => {
onChange(multiple ? [] : null);
event.preventDefault();
selectInputRef.current.focus();
},
children: _jsx(Icons.CloseIcon, {})
}),
IconComponent: props => _jsx(IconComponent, {
disabled: disabled,
iconProps: props
}),
sx: Object.assign({
font: FontStyles.INPUT_FONT,
borderWidth: '1px',
paddingRight: 0,
'&.Mui-error .MuiOutlinedInput-notchedOutline': {
borderColor: Palette.ERROR_RED,
borderWidth: '1px'
},
'&.Mui-focused.Mui-error .MuiOutlinedInput-notchedOutline': {
borderColor: Palette.ERROR_RED,
borderWidth: '2px'
},
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: !disabled && Palette.LIGHT_BLACK
},
'&.Mui-error:hover .MuiOutlinedInput-notchedOutline': {
borderColor: !disabled && Palette.ERROR_RED
},
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
borderColor: Palette.LIGHT_BLACK,
borderWidth: '1px'
},
'& .MuiOutlinedInput-notchedOutline': {
borderColor: Palette.DIM_GREY,
borderWidth: '1px',
'& legend': {
fontSize: '11px'
}
},
'& .MuiOutlinedInput-input': Object.assign(Object.assign(Object.assign({
color: Palette.LIGHT_BLACK
}, showClearButton && clearButtonVisible && {
paddingRight: '45px !important'
}), displayChips && (value === null || value === void 0 ? void 0 : value.length) > 0 ? {
paddingTop: '7px',
paddingBottom: '7px'
} : {}), {
'&.MuiSelect-select': {
height: '1.4375em'
}
})
}, style),
MenuProps: {
slotProps: {
paper: {
style: {
maxWidth: (_a = selectRef === null || selectRef === void 0 ? void 0 : selectRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth,
width: (_b = selectRef === null || selectRef === void 0 ? void 0 : selectRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth,
maxHeight: menuMaxHeight
}
}
}
},
children: [displaySearchInput && multiple && _jsx("div", {
style: {
margin: '8px 16px'
},
children: _jsx(MaterialSearchInput, {
fullWidth: true,
value: searchPhrase,
onChange: event => setSearchPhrase(event.target.value),
onKeyDown: e => e.stopPropagation()
})
}), filteredOptions.length > 0 ? filteredOptions.map(option => {
return _jsxs(MenuItem, {
disableRipple: true,
disabled: (option === null || option === void 0 ? void 0 : option.disabled) || false,
value: option,
sx: {
padding: '8px 16px',
'& .MuiListItemText-root .MuiTypography-root': {
textWrap: 'wrap',
wordBreak: 'break-word',
display: 'flex',
alignItems: 'center'
},
'&:hover': {
backgroundColor: Palette.WHITE_SMOKE,
'& .MuiListItemIcon-root img': {
filter: `${Palette.FILTER_LIGHT_BLACK} !important`
}
},
'& .MuiListItemIcon-root img': {
filter: `${Palette.FILTER_LIGHT_BLACK} !important`
},
'&.Mui-selected, &.Mui-focusVisible, &.Mui-selected.Mui-focusVisible': {
backgroundColor: Palette.GREY_SMOKE,
'&:hover': {
backgroundColor: Palette.GREY_SMOKE
}
}
},
children: [(option === null || option === void 0 ? void 0 : option.iconStart) && _jsx(ListItemIcon, {
children: option.iconStart
}), _jsxs(ListItemText, {
datatestid: "select-option",
sx: {
'& .MuiTypography-root': {
font: FontStyles.INPUT_FONT,
color: Palette.LIGHT_BLACK
}
},
children: [multiple && _jsx(CheckboxInput, {
checked: checkIfSelected(option, uniqueField),
style: {
padding: '0 8px 0 0'
}
}), getLabel(option, labelField)]
}), (option === null || option === void 0 ? void 0 : option.iconEnd) && _jsx(ListItemIcon, {
children: option.iconEnd
}), (option === null || option === void 0 ? void 0 : option.helperText) && _jsx(MenuOptionHelperText, {
children: option.helperText
})]
}, getMenuItemKey(option, uniqueField));
}) : _jsx("p", {
style: {
margin: '8px 20px',
font: FontStyles.INPUT_FONT
},
children: "No results"
})]
}), helperText && _jsx(StyledFormHelperText, {
error: error,
errorText: getHelperText(helperText, hideEmptyHelperTextSpace)
})]
});
};
export default MaterialSelect;