All files / src/Dropdown Dropdown.tsx

0% Statements 0/20
0% Branches 0/6
0% Functions 0/4
0% Lines 0/19

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                                                                                                                                                                 
import cn from 'classnames';
import * as React from 'react';
 
import { Menu, MenuItem } from '..';
import { FixedSizeList } from '../ScrollList';
import { ISelectProps, ItemListRenderer, ItemRenderer, Select } from '../Select';
 
export interface IDropdown extends Omit<ISelectProps<string>, 'itemRenderer'> {
  baseComponent: new (props: ISelectProps<string>) => Select<string>;
  itemRenderer?: ISelectProps<string>['itemRenderer'];
  itemSize?: number;
  maxRows?: number;
}
 
export const Dropdown: React.FunctionComponent<IDropdown> = ({
  children,
  baseComponent,
  items,
  maxRows = 10,
  itemSize = 30,
  activeItem,
  className,
  popoverProps,
  ...props
}) => {
  const itemListRenderer = React.useCallback<ItemListRenderer<string>>(
    ({ filteredItems, renderItem }) => {
      if (filteredItems.length === 0) {
        return <span className="inline-block px-5 py-3">No results found</span>;
      }
 
      return (
        <Menu className="Dropdown__select">
          <FixedSizeList
            className={className}
            maxRows={maxRows}
            itemSize={itemSize}
            itemCount={filteredItems.length}
            itemData={{ filteredItems, renderItem }}
          >
            {Item}
          </FixedSizeList>
        </Menu>
      );
    },
    [maxRows, itemSize],
  );
 
  return React.createElement(
    baseComponent as React.ComponentClass<ISelectProps<string>>,
    {
      filterable: false,
      items,
      itemRenderer,
      itemListRenderer,
      popoverProps: {
        ...popoverProps,
        portalClassName: cn('Dropdown__popover', popoverProps ? popoverProps.portalClassName : ''),
      },
      ...props,
    },
    children,
  );
};
Dropdown.displayName = 'Dropdown';
 
const itemRenderer: ItemRenderer<string> = (value, { handleClick, modifiers }) => (
  <MenuItem active={modifiers.active} key={value} onClick={handleClick} text={value} />
);
 
const Item = (props: any) => {
  const { data, index, style } = props;
  const { filteredItems, renderItem } = data;
 
  return (
    <div key={index} style={style}>
      {renderItem(filteredItems[index])}
    </div>
  );
};