UNPKG

react-searchable-select

Version:
487 lines (476 loc) 16.7 kB
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import { MenuItem, Box, TextField, InputAdornment, IconButton, InputLabel, Typography, Chip, Menu, Checkbox } from '@mui/material'; import { makeStyles } from '@mui/styles'; import React, { useState, useEffect } from 'react'; import styled from '@emotion/styled'; import PropTypes from 'prop-types'; var SELECT_CARET = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iNiIgdmlld0JveD0iMCAwIDEwIDYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik04LjY2NjcxIDAuNzVMNS4wMDAwNCA0LjQxNjY3TDEuMzMzMzcgMC43NSIgc3Ryb2tlPSIjMUUxQzFCIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04LjY2NjcxIDAuNzVMNS4wMDAwNCA0LjQxNjY3TDEuMzMzMzcgMC43NSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLW9wYWNpdHk9IjAuNSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K"; var StyledMenuItem = styled(MenuItem)(function (_ref) { _ref.theme; return { "&.MuiButtonBase-root": { fontFamily: "Lato", fontSize: "15px", fontWeight: 400, lineHeight: "22px", letterSpacing: "0px", textAlign: "left", padding: "8px 16px 8px 16px", borderRadius: "6px", gap: "8px", margin: "2px 5px" } // "&.MuiButtonBase-root:hover": { // background: "orange", // color: "white", // }, }; }); var SearchMenuItem = styled(MenuItem)(function (_ref2) { _ref2.theme; return { "&.MuiButtonBase-root": { background: "transparent" }, "&.MuiButtonBase-root:hover": { background: "transparent" } }; }); var ScrollBox = styled(Box)(function (_ref3) { _ref3.theme; return { "&.MuiBox-root": { overflowY: "auto", scrollbarColor: "grey", scrollbarWidth: "thin" }, "&.MuiBox-root::-webkit-scrollbar": { width: "3px !important", borderRadius: "5px" }, "&.MuiBox-root::-webkit-scrollbar-track": { background: "transparent" }, "&.MuiBox-root::-webkit-scrollbar-thumb": { background: "#888 !important" } }; }); var Search = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAxOCAxOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iNy41IiBjeT0iNy41IiByPSI1LjI1IiBzdHJva2U9IiMxRTFDMUIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPGNpcmNsZSBjeD0iNy41IiBjeT0iNy41IiByPSI1LjI1IiBzdHJva2U9IndoaXRlIiBzdHJva2Utb3BhY2l0eT0iMC41IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xNS43NSAxNS43NUwxMS4yNSAxMS4yNSIgc3Ryb2tlPSIjMUUxQzFCIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xNS43NSAxNS43NUwxMS4yNSAxMS4yNSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLW9wYWNpdHk9IjAuNSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K"; var CrossIcon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE1IDVMNSAxNSIgc3Ryb2tlPSIjMUUxQzFCIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTUgNUw1IDE1IiBzdHJva2U9IndoaXRlIiBzdHJva2Utb3BhY2l0eT0iMC41IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNNSA1TDE1IDE1IiBzdHJva2U9IiMxRTFDMUIiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik01IDVMMTUgMTUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS1vcGFjaXR5PSIwLjUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo="; /** @format */ function SearchBar(_ref) { var value = _ref.value, onChange = _ref.onChange, placeholder = _ref.placeholder; _ref.isValid; var onClear = _ref.onClear, style = _ref.style, _ref$disabled = _ref.disabled, disabled = _ref$disabled === void 0 ? false : _ref$disabled; return /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(TextField, { value: value, style: style, sx: { width: "100%" }, onChange: onChange, disabled: disabled, placeholder: placeholder, isValid: true, InputProps: { endAdornment: /*#__PURE__*/React.createElement(InputAdornment, { position: "end" }, value === "" ? /*#__PURE__*/React.createElement("img", { src: Search, alt: "search" }) : /*#__PURE__*/React.createElement(IconButton, { onClick: onClear, sx: { p: "8px 0" } }, /*#__PURE__*/React.createElement("img", { src: CrossIcon, alt: "clear" }))) } })); } var useStyles = makeStyles(function (theme) { return { DropDownButton: { margin: "50px 50px", fontSize: "1.125rem", width: "inherit", height: "60px", display: "flex", alignItems: "center", justifyContent: "space-between", border: "2px solid #007bff", borderRadius: "10px", backgroundColor: "white", cursor: "pointer", padding: "0px 20px" }, inputRoot: { color: "inherit", width: "100%" }, search: { position: "relative", marginLeft: 0, width: "100%" }, searchIcon: { // padding: theme.spacing(0, 2), height: "100%", position: "absolute", pointerEvents: "none", display: "flex", alignItems: "center", justifyContent: "center" }, inputInput: { // padding: theme.spacing(1, 1, 1, 0), // paddingLeft: `calc(1em + ${theme.spacing(4)}px)`, // transition: theme.transitions.create("width"), width: "100%" }, searchBarContainer: { minWidth: "inherit", display: "flex", justifyContent: "space-evenly", cursor: "default", "&.MuiListItem-button": { "&:hover": { backgroundColor: "white" } } }, menuDivider: { margin: "0 20px" }, dashboardSelectMenu: { "& .MuiPopover-paper": { minWidth: "inherit", maxWidth: "fit-content", borderRadius: "6px" } }, externalLinkIcon: { borderLeft: "1px solid var(--color-gray-eighty-five)", padding: "10px 0px 10px 10px", color: "var(--color-primary)", cursor: "pointer" } }; }); function containsObject(obj, list) { var i; for (i = 0; i < list.length; i++) { if (list[i].value === obj.value) { return true; } } return false; } function SearchBoxSelect(props) { var classes = useStyles(); var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), anchorEl = _useState2[0], setAnchorEl = _useState2[1]; var _useState3 = useState(""), _useState4 = _slicedToArray(_useState3, 2), searchText = _useState4[0], setSearchText = _useState4[1]; var _useState5 = useState(), _useState6 = _slicedToArray(_useState5, 2), selection = _useState6[0], setSelection = _useState6[1]; var _useState7 = useState([]), _useState8 = _slicedToArray(_useState7, 2), selectOptions = _useState8[0], setSelectOptions = _useState8[1]; var _useState9 = useState([]), _useState10 = _slicedToArray(_useState9, 2), multiSelection = _useState10[0], setMultiSelection = _useState10[1]; useEffect(function () { var array = []; if (props.autoFormat) { array = props.selectionList.map(function (tag) { var label = []; props.labelKeys.map(function (w) { label.push(tag[w]); }); return { value: tag[props.valueKey], label: label.join(" ") }; }); } else { array = _toConsumableArray(props.selectionList); } setSelectOptions(array); }, [props.selectionList]); useEffect(function () { if (props.isMultiSelect) { setMultiSelection(props.value); } else { setSelection(props.value); } }, [props.selectionList]); var handleMenuOpen = function handleMenuOpen(event) { setAnchorEl(event.currentTarget); }; var handleClose = function handleClose(e) { setSearchText(""); setAnchorEl(null); }; var handleSelect = function handleSelect(e) { props.onChange(e); setSelection(e); setSearchText(""); setAnchorEl(null); }; var handleMultiSelect = function handleMultiSelect(e) { var MultiSelection = _toConsumableArray(multiSelection); if (MultiSelection.indexOf(e) > -1) { MultiSelection.splice(MultiSelection.indexOf(e), 1); } else { MultiSelection.push(e); } setMultiSelection(MultiSelection); props.onChange(MultiSelection); }; var handleMultiSelectDelete = function handleMultiSelectDelete(e) { var MultiSelection = _toConsumableArray(multiSelection); MultiSelection.splice(MultiSelection.indexOf(e), 1); setMultiSelection(MultiSelection); props.onChange(MultiSelection); }; return /*#__PURE__*/React.createElement("div", null, props.label && /*#__PURE__*/React.createElement(InputLabel, { htmlFor: props.name, required: props.isRequired, className: "select-box-label" }, props.label), /*#__PURE__*/React.createElement("div", { className: "select-box", id: props.name, onClick: handleMenuOpen, style: { cursor: "pointer", border: "1px solid #8e8d8d", padding: "10px", borderRadius: "6px", display: "flex", height: "38px", justifyContent: "space-between", alignItems: "center" } }, /*#__PURE__*/React.createElement("div", { className: "label-value-div" }, selection ? /*#__PURE__*/React.createElement(Typography, null, " ", selection.label) : /*#__PURE__*/React.createElement(Typography, { color: "grey" }, " ", props.placeholder)), /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement("img", { src: SELECT_CARET, alt: "", style: { width: "14px", transition: "all .2s ease", transform: anchorEl ? "rotate(180deg)" : null } }))), props.isMultiSelect ? renderMultiSelectMenu() : renderSelectMenu(), /*#__PURE__*/React.createElement(Box, { className: "chip-group", sx: { mt: 1 } }, props.isMultiSelect && multiSelection.length && props.withChips > 0 ? multiSelection.map(function (select, key) { return /*#__PURE__*/React.createElement(Chip, { disabled: props.isDisabled, label: select.label, key: select.value, deleteIcon: props.chipDeleteIcon, onDelete: function onDelete() { return handleMultiSelectDelete(select); } }); }) : null)); function renderSelectMenu() { var displayOptions = selectOptions.map(function (item) { if (item.label.toLowerCase().includes(searchText.toLowerCase())) { return item; } return undefined; }).filter(function (item) { return item !== undefined; }); function renderOption(value) { if ((selection === null || selection === void 0 ? void 0 : selection.value) === (value === null || value === void 0 ? void 0 : value.value)) { return /*#__PURE__*/React.createElement("div", { className: classes.checkedItem }, value.label); } return value.label; } return /*#__PURE__*/React.createElement(Menu, { sx: { p: 0, mt: 0.7 }, anchorEl: anchorEl, keepMounted: true, open: !!anchorEl, onClose: handleClose, className: classes.dashboardSelectMenu }, props.isSearch && /*#__PURE__*/React.createElement(SearchMenuItem, { className: classes.searchBarContainer, sx: { px: 1, mt: 0 }, disableTouchRipple: true }, /*#__PURE__*/React.createElement("div", { className: classes.search }, /*#__PURE__*/React.createElement(SearchBar, { onClear: function onClear() { return setSearchText(""); }, placeholder: "Search by keyword..", isValid: true, value: searchText, onChange: function onChange(e) { return setSearchText(e.target.value.trim()); } }))), /*#__PURE__*/React.createElement(ScrollBox, { sx: { maxHeight: "200px" } }, displayOptions.length > 0 ? displayOptions.map(function (item, index) { return /*#__PURE__*/React.createElement("div", { key: index }, /*#__PURE__*/React.createElement(StyledMenuItem, { className: "list-single-item", sx: { background: (selection === null || selection === void 0 ? void 0 : selection.value) === item.value && "orange", color: (selection === null || selection === void 0 ? void 0 : selection.value) === item.value && "white" }, onClick: function onClick() { return handleSelect(item); } }, renderOption(item))); }) : /*#__PURE__*/React.createElement("div", { className: "no-options-text", style: { textAlign: "center", my: 1 } }, /*#__PURE__*/React.createElement(Typography, { variant: "hl_paragraphBold" }, "No Options")))); } function renderMultiSelectMenu() { var displayOptions = selectOptions.map(function (item) { if (item.label.toLowerCase().includes(searchText.toLowerCase())) { return item; } return undefined; }).filter(function (item) { return item !== undefined; }); function renderOption(value) { if ((selection === null || selection === void 0 ? void 0 : selection.value) === (value === null || value === void 0 ? void 0 : value.value)) { return /*#__PURE__*/React.createElement("div", { className: classes.checkedItem }, value.label); } return value.label; } return /*#__PURE__*/React.createElement(Menu, { sx: { p: 0, mt: 0.7 }, anchorEl: anchorEl, keepMounted: true, open: !!anchorEl, onClose: handleClose, className: classes.dashboardSelectMenu // anchorReference="anchorOrigin" // anchorPosition={{ top: 0, left: 0 }} // anchorOrigin={{ // vertical: "bottom", // horizontal: "center", // }} // transformOrigin={{ // vertical: "top", // horizontal: "center", // }} }, /*#__PURE__*/React.createElement(SearchMenuItem, { className: classes.searchBarContainer, sx: { px: 1, mt: 0 }, disableTouchRipple: true }, /*#__PURE__*/React.createElement("div", { className: classes.search }, /*#__PURE__*/React.createElement(SearchBar, { onClear: function onClear() { return setSearchText(""); }, placeholder: "Search by keyword..", isValid: true, value: searchText, onChange: function onChange(e) { return setSearchText(e.target.value.trim()); } }))), /*#__PURE__*/React.createElement(ScrollBox, { sx: { maxHeight: "200px" } }, displayOptions.length > 0 ? displayOptions.map(function (item, index) { return /*#__PURE__*/React.createElement("div", { key: index }, !containsObject(item, multiSelection) && /*#__PURE__*/React.createElement(StyledMenuItem, { onClick: function onClick() { return handleMultiSelect(item); } }, props.withCheckBox && /*#__PURE__*/React.createElement(Checkbox, { sx: { padding: 0 }, checked: multiSelection.indexOf(item) > -1 }), renderOption(item))); }) : /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Typography, { variant: "paragraph" }, "No Options")))); } } SearchBoxSelect.propTypes = { selectionList: PropTypes.array.isRequired, placeholder: PropTypes.string, labelKey: PropTypes.array, valueKeys: PropTypes.string, value: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), onChange: PropTypes.func, autoFormat: PropTypes.bool, name: PropTypes.string, isRequired: PropTypes.bool, label: PropTypes.string, isSearch: PropTypes.bool, isMultiSelect: PropTypes.bool, withCheckBox: PropTypes.bool, withChips: PropTypes.bool, isDisabled: PropTypes.bool, chipDeleteIcon: PropTypes.string }; var returnLibrary = function returnLibrary() { return { SelectInput: SearchBoxSelect }; }; var index = returnLibrary(); export { index as default };