# 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>
      );
    };