All files / src/components Dropdown.tsx

0% Statements 0/19
0% Branches 0/12
0% Functions 0/12
0% Lines 0/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                                                                                                                                                                                                                                           
import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent, SxProps, TooltipProps } from '@mui/material';
import { DropdownItem } from './types';
import SelectT, { SelectStyles } from './Select/SelectT';
import Autocomplete, { ValueType } from './Autocomplete/Autocomplete';
import React from 'react';
 
export interface Props {
  id: string;
  label: string;
  values?: DropdownItem[];
  onChange: (value: string) => void;
  selected: string | undefined;
  disabled?: boolean;
}
 
export function DropdownV1({ id, label, values, onChange, selected, disabled }: Props): JSX.Element {
  const onChangeH = (event: SelectChangeEvent<string>) => {
    onChange(event.target.value);
  };
 
  return (
    <FormControl variant='outlined' size='small' disabled={disabled} sx={{ width: '100%' }}>
      <InputLabel id={`${id}-outlined-label`}>{label}</InputLabel>
      <Select labelId={`${id}-outlined-label`} id={id} label={label} onChange={onChangeH} value={selected}>
        {values?.map(({ label: inLabel, value }) => (
          <MenuItem id={value} key={value} value={value}>
            {inLabel}
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}
 
export interface DropdownProps {
  onChange: (newValue: string) => void;
  id?: string;
  label?: string;
  options?: DropdownItem[];
  selectedValue?: any;
  disabled?: boolean;
  className?: string;
  placeholder?: string;
  errorText?: string;
  tooltipTitle?: TooltipProps['title'];
  sx?: SxProps;
 
  // select props
  helperText?: string | string[];
  warningText?: string | string[];
  readonly?: boolean;
  fullWidth?: boolean;
  hideArrow?: boolean;
  onBlur?: () => void;
  onFocus?: () => void;
  fixedMenu?: boolean;
  selectStyles?: SelectStyles;
 
  // auto complete props
  freeSolo?: boolean;
  hideClearIcon?: boolean;
 
  autocomplete?: boolean;
  required?: boolean;
}
 
/**
 * This is a simple dropdwn that takes in a tuple { label, value }
 * for list of options.
 * The label is used for display, the value is passed back in onChange, and used to set selectedValue.
 *
 * Example:
 * <Dropdown
 *   options=[{ label: 'label', value: 'value'}, { label: 'label1': value: 'value1'} ]
 *   onChange={(value: string) => setSomeValue(value)}
 *   selectedValue={'value1'}
 * />
 */
export default function Dropdown(props: DropdownProps): JSX.Element {
  const { selectedValue, onChange, options, autocomplete, ...remainingProps } = props;
 
  const selectedItem = options?.find((option) => option.value === selectedValue);
 
  const renderOption = (option: DropdownItem): React.ReactNode => {
    const styles = {
      fontWeight: option.fontWeight || 'normal',
      fontStyle: option.fontStyle || 'normal',
    };
 
    return <span style={styles}>{option.label}</span>;
  };
 
  if (autocomplete) {
    return (
      <Autocomplete
        {...remainingProps}
        options={options ?? []}
        selected={selectedItem || ''}
        isEqual={(A: ValueType, B: ValueType) => (A as DropdownItem).value === (B as DropdownItem).value}
        onChange={(option: ValueType) => onChange((option as DropdownItem).value)}
      />
    );
  }
 
  return (
    <SelectT<DropdownItem>
      {...remainingProps}
      options={options}
      selectedValue={selectedItem}
      isEqual={(A: DropdownItem, B: DropdownItem) => A.value === B.value}
      renderOption={renderOption}
      toT={(str: string) => ({ label: str, value: str } as DropdownItem)}
      displayLabel={(option: DropdownItem) => option?.label || ''}
      onChange={(option: DropdownItem) => onChange(option.value)}
    />
  );
}