UNPKG

@parkassist/pa-ui-library

Version:
298 lines 10.3 kB
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;