All files / atom/table/src index.js

78.94% Statements 15/19
63.63% Branches 7/11
42.85% Functions 3/7
88.23% Lines 15/17

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 119 120 121 122 123 124 125 126          1x 3x 3x 3x 3x     3x     3x         3x   3x                               6x   6x 6x           6x                                                 1x   1x                                                                                                      
import cx from 'classnames'
import PropTypes from 'prop-types'
 
import {BASE_CLASS, CELL_BASE_CLASS, ROW_BASE_CLASS, TABLE_CELL_PADDING, TABLE_CELL_TYPE} from './settings.js'
 
const AtomTable = ({head = [], body, foot = [], fullWidth, cellPadding, borderBottom, onRowClick, zebraStriped}) => {
  const hasHead = Boolean(head.length)
  const hasFoot = Boolean(foot.length)
  const isRowActionable = Boolean(onRowClick)
  const tableClass = cx(`${BASE_CLASS}`, {
    [`${BASE_CLASS}--fullWidth`]: Boolean(fullWidth)
  })
  const headerClass = cx(`${CELL_BASE_CLASS}`, `${BASE_CLASS}-headerCell`, {
    [`${CELL_BASE_CLASS}--${cellPadding}`]: Boolean(cellPadding)
  })
  const rowClass = cx(`${ROW_BASE_CLASS}`, {
    [`${ROW_BASE_CLASS}--actionable`]: isRowActionable,
    [`${ROW_BASE_CLASS}--zebraStriped`]: zebraStriped
  })
 
  const handleOnRowClick = index => onRowClick(index)
 
  return (
    <table className={tableClass}>
      {hasHead && (
        <thead>
          <tr>
            {head.map((element, index) => (
              <th key={index} className={headerClass}>
                {element}
              </th>
            ))}
          </tr>
        </thead>
      )}
 
      <tbody>
        {body.map((row, index) => (
          <tr key={index} className={rowClass} {...(isRowActionable && {onClick: () => handleOnRowClick(index)})}>
            {row.map((cell, index) => {
              const {type: Element = TABLE_CELL_TYPE.data, content = '', isNowrap, colspan = 1} = cell
              const cellClassName = cx(`${CELL_BASE_CLASS}`, {
                [`${CELL_BASE_CLASS}--noWrap`]: isNowrap,
                [`${CELL_BASE_CLASS}--${cellPadding}`]: Boolean(cellPadding),
                [`${CELL_BASE_CLASS}--borderBottom`]: Boolean(borderBottom)
              })
 
              return (
                <Element key={index} className={cellClassName} colSpan={colspan}>
                  {content}
                </Element>
              )
            })}
          </tr>
        ))}
      </tbody>
 
      {hasFoot && (
        <tfoot>
          <tr>
            {foot.map((element, index) => (
              <td key={index} className={`${CELL_BASE_CLASS}`}>
                {element}
              </td>
            ))}
          </tr>
        </tfoot>
      )}
    </table>
  )
}
 
AtomTable.displayName = 'AtomTable'
 
AtomTable.propTypes = {
  /**
   * Table head content
   */
  head: PropTypes.array,
  /**
   * Table body content.
   * You can define per row:
   *  - colspan: as a number
   *  - content: as a string or React component
   *  - type: of cell (th,td)
   *  - isNowrap: to add no-wrap behavior to the cell
   */
  body: PropTypes.arrayOf(
    PropTypes.arrayOf(
      PropTypes.shape({
        colspan: PropTypes.number,
        content: PropTypes.string.isRequired,
        type: PropTypes.oneOf(Object.values(TABLE_CELL_TYPE)),
        isNowrap: PropTypes.bool
      })
    )
  ).isRequired,
  /**
   * Cell padding size (xs,x,m,l,xl)
   */
  cellPadding: PropTypes.oneOf(Object.values(TABLE_CELL_PADDING)),
  /**
   * Table foot conntent
   */
  foot: PropTypes.array,
  /**
   * With fullWith you have a full width behavior
   */
  fullWidth: PropTypes.bool,
  /**
   * Add a default border bootom to all cells
   */
  borderBottom: PropTypes.bool,
  /**
   * Trigger callback with row index clicked
   */
  onRowClick: PropTypes.func,
  /**
   * Add interspersed stripes to rows
   */
  zebraStriped: PropTypes.bool
}
 
export {TABLE_CELL_TYPE as atomTableCellTypes, TABLE_CELL_PADDING as atomTableCellPadding}
export default AtomTable