All files / src/components info-list.tsx

100% Statements 6/6
100% Branches 12/12
100% Functions 3/3
100% Lines 5/5

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                                                                              9x                 12x 6x     6x                   11x                                      
import { type ReactNode, type HTMLAttributes, type ReactElement } from 'react';
import cn from 'classnames';
 
import DecoratedListItem from './decorated-list-item';
 
import '../styles/components/info-list.scss';
 
export type InfoListItem = {
  title: ReactNode;
  content: ReactNode;
  key?: string;
  link?: ReactElement<{ [key: string]: unknown }>;
};
 
type Props = {
  /**
   * An array of objects each containing 'title' and 'content'
   */
  infoData?: Array<InfoListItem>;
  /**
   * A boolean indicating whether the component should span multiple
   * columns on medium to large screens or not.
   */
  columns?: boolean;
  /**
   * A boolean indicating whether the component should render
   * as a compact list
   */
  isCompact?: boolean;
  /**
   * Should the first content item in the InfoList be bold
   */
  highlightFirstItem?: boolean;
  /**
   * Display titles or not
   */
  noTitles?: boolean;
};
 
const InfoList = ({
  infoData,
  columns,
  isCompact,
  highlightFirstItem,
  noTitles,
  className,
  ...props
}: Props & HTMLAttributes<HTMLUListElement>) => {
  if (!infoData?.length || infoData.every((infoDatum) => !infoDatum.content)) {
    return null;
  }
 
  return (
    <ul
      className={cn(className, 'info-list', {
        'info-list--columns': columns,
      })}
      {...props}
    >
      {infoData.map(
        // Only draw if there is content
        ({ content, title, key, link }, index) =>
          content && (
            <li key={key || (typeof title === 'string' ? title : index)}>
              <DecoratedListItem
                title={title}
                highlight={index === 0 && highlightFirstItem}
                compact={isCompact}
                hideTitle={noTitles}
                link={link}
              >
                {content}
              </DecoratedListItem>
            </li>
          )
      )}
    </ul>
  );
};
 
export default InfoList;