Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useEffect, useState } from 'react';
- import {
- Autocomplete,
- FormControl,
- FormControlProps,
- InputLabel,
- InputLabelProps,
- ListItemText,
- ListItemTextProps,
- MenuItem,
- MenuItemProps,
- MenuProps,
- OutlinedInput,
- Select,
- SelectChangeEvent,
- TextField,
- } from '@mui/material';
- import styled, { ThemeProps, useTheme } from 'styled-components';
- import { CustomTheme } from '../../style/themes/themes';
- import Checkbox from './Checkbox';
- import SelectButton from './SelectButton';
- import { KeyValuePair } from '../types';
- interface MultiSelectProps {
- isVisible: boolean;
- placement?: Placement;
- disabled?: boolean;
- label?: string;
- options: KeyValuePair[];
- initiallySelectedOptions?: string[];
- onClick: () => void;
- onChangeHandler: (selectedValues: KeyValuePair[]) => void;
- isAbsolute?: boolean;
- renderInput?: () => void;
- }
- interface AutocompleteMultipleProps {
- renderInput?: ()=> void;
- multiply?: boolean;
- }
- export enum Placement {
- left = 'left',
- right = 'right',
- }
- const definePlacement = (placement?: string) => {
- switch (placement) {
- case Placement.right:
- return '0';
- case Placement.left:
- default:
- return 'unset';
- }
- };
- const MultiSelectWithAutocomplete = ({
- isVisible,
- placement,
- options,
- onClick,
- onChangeHandler,
- label,
- initiallySelectedOptions = [],
- isAbsolute = true,
- renderInput,
- }: MultiSelectProps) => {
- const currentTheme = useTheme();
- const CustomMenuProps: Partial<MenuProps> = {
- PaperProps: {
- style: {
- maxHeight: '365px',
- backgroundColor: currentTheme.lightAccentBackground,
- boxShadow: 'none',
- width: '360px',
- display: isVisible ? 'block' : 'none',
- padding: '0 16px',
- },
- },
- disablePortal: true,
- variant: 'menu',
- disableAutoFocusItem: true,
- };
- const [selectedValue, setSelectedValue] = useState<KeyValuePair[]>(
- options.filter((option) => initiallySelectedOptions?.indexOf(option.key) !== -1)
- );
- const [isCollapsed, setIsCollapsed] = useState<boolean>(false);
- const handleChange = (event: SelectChangeEvent<string[]>) => {
- const values = event.target.value as string[];
- const selectedItems: KeyValuePair[] = [];
- for (let i = 0; i < values.length; ++i) {
- const item = options.find((x) => x.value === values.at(i));
- if (item) {
- selectedItems.push(item);
- }
- }
- setSelectedValue(selectedItems);
- onChangeHandler(selectedItems);
- };
- const collapseClickHandler = (e: React.MouseEvent) => {
- const target = e.target as HTMLButtonElement;
- if (!target.closest('.MuiPaper-root')) {
- setIsCollapsed(!isCollapsed);
- }
- };
- const applyButtonClickHandler = () => {
- setIsCollapsed(false);
- onClick();
- };
- useEffect(() => {
- setIsCollapsed(isVisible);
- }, [isVisible]);
- useEffect(() => {
- setSelectedValue(options.filter((option) => initiallySelectedOptions?.indexOf(option.key) !== -1));
- }, [initiallySelectedOptions]);
- useEffect(() => {
- const trackCollapseHandler = (e: MouseEvent): void => {
- const target = e.target as HTMLButtonElement;
- if (target) {
- if (!target.closest('.MuiPaper-root') && !target.closest('.selectRootWrapper')) {
- if (isCollapsed) {
- setIsCollapsed(false);
- }
- }
- }
- };
- document.addEventListener('click', trackCollapseHandler);
- return function cleanup() {
- document.removeEventListener('click', trackCollapseHandler);
- };
- }, [isCollapsed]);
- return (
- <MultiSelectWrapper
- isCollapsed={isCollapsed}
- className="selectRootWrapper"
- isVisible={isVisible}
- placement={placement}
- isAbsolute={isAbsolute}
- >
- <CustomFormControl onClick={collapseClickHandler}>
- <CustomInputLabel id="demo-multiple-checkbox-label">{label}</CustomInputLabel>
- <Autocomplete
- multiple
- renderInput={(params) => <TextField {...params} label="Players" />}
- options={options}
- getOptionLabel={(option: KeyValuePair) => option.value}
- />
- {/*<Select*/}
- {/* labelId="demo-multiple-checkbox-label"*/}
- {/* id="demo-multiple-checkbox"*/}
- {/* multiple*/}
- {/* value={selectedValue.map((x) => x.value)}*/}
- {/* onChange={handleChange}*/}
- {/* renderValue={params => <TextField {...params} label="Players"/>}*/}
- {/* MenuProps={CustomMenuProps}*/}
- {/* open={isCollapsed}*/}
- {/*>*/}
- {/* {options.map((option) => (*/}
- {/* <CustomMenuItem key={option.key} value={option.value}>*/}
- {/* <Checkbox*/}
- {/* onChange={() => {*/}
- {/* return null;*/}
- {/* }}*/}
- {/* checked={selectedValue.findIndex((item) => item.key === option.key) !== -1}*/}
- {/* />*/}
- {/* <CustomListItemText primary={option.value} />*/}
- {/* </CustomMenuItem>*/}
- {/* ))}*/}
- {/*</Select>*/}
- </CustomFormControl>
- <SelectButton isVisible={isCollapsed} onClick={applyButtonClickHandler} disabled={false}>
- Apply
- </SelectButton>
- </MultiSelectWrapper>
- );
- };
- export const SelectWrapper = styled.div<{
- theme: ThemeProps<CustomTheme>;
- placement?: string;
- }>`
- padding: 0;
- width: 360px;
- background: ${(props) => props.theme.lightAccentBackground};
- border-radius: 8px;
- transition: height 3s linear;
- right: ${(props) => definePlacement(props.placement)};
- flex-direction: column;
- justify-content: space-between;
- `;
- export const MultiSelectWrapper = styled(SelectWrapper)<{
- theme: ThemeProps<CustomTheme>;
- isVisible?: boolean;
- placement?: string;
- isCollapsed?: boolean;
- isAbsolute?: boolean;
- }>`
- position: ${(props) => (props.isAbsolute ? 'absolute' : 'unset')};
- padding: ${(props) => (props.isAbsolute ? '16px;' : '0')};
- background: ${(props) => props.theme.lightAccentBackground};
- display: ${(props) => (props.isVisible ? 'flex' : 'none')};
- top: 115%;
- z-index: 500;
- height: ${(props) => (props.isCollapsed ? '495px' : 'unset')};
- `;
- export const CustomFormControl = styled(FormControl)<FormControlProps>(({ theme }: ThemeProps<CustomTheme>) => ({
- width: '100%',
- '& .MuiInputBase-root': {
- maxHeight: 56,
- '& .MuiOutlinedInput-notchedOutline': {
- borderColor: theme.addColor,
- borderRadius: 8,
- '& legend': {
- width: '35%',
- },
- },
- '&:hover': {
- '& .MuiOutlinedInput-notchedOutline': {
- borderColor: theme.addColor,
- },
- },
- '&.Mui-focused': {
- '& .MuiOutlinedInput-notchedOutline': {
- borderColor: theme.addColor,
- '& legend': {
- width: '35%',
- },
- },
- },
- '& .MuiSelect-icon': {
- color: theme.addColor,
- },
- },
- '.MuiOutlinedInput-input': {
- color: theme.basicColor,
- },
- '& .MuiPopover-root': {
- bottom: '65%',
- '& .MuiBackdrop-root': {
- bottom: '65%',
- },
- },
- }));
- export const CustomInputLabel = styled(InputLabel)<InputLabelProps>(({ theme }: ThemeProps<CustomTheme>) => ({
- '&.MuiInputLabel-root': {
- color: theme.addColor,
- '&.Mui-focused': {
- color: theme.addColor,
- },
- },
- }));
- export const CustomMenuItem = styled(MenuItem)<MenuItemProps>(({ theme }: ThemeProps<CustomTheme>) => ({
- '&.MuiMenuItem-root': {
- backgroundColor: 'inherit',
- paddingLeft: 3,
- '&.Mui-selected': {
- backgroundColor: 'inherit',
- },
- '&:hover': {
- backgroundColor: theme.selectItemHover,
- },
- },
- }));
- export const CustomListItemText = styled(ListItemText)<ListItemTextProps>(({ theme }: ThemeProps<CustomTheme>) => ({
- '&.MuiListItemText-root': {
- color: theme.basicColor,
- fontFamily: 'Quicksand',
- '& .MuiTypography-root': {
- fontFamily: 'Quicksand',
- },
- },
- }));
- export default MultiSelectWithAutocomplete;
Advertisement
Advertisement