gilbarbara/styled-minimal

View on GitHub
src/Table.jsx

Summary

Maintainability
A
0 mins
Test Coverage
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components';

import { getTheme, px } from './utils/helpers';
import { sizesPropTypes } from './utils/system';

import Box, { basePropTypes } from './Box';

const styles = props => {
  const { bordered, borderless, inverted } = props;
  const { borderColors, colors } = getTheme(props, 'table');

  return css`
    background-color: ${colors[inverted ? 'secondary' : 'primary']};
    ${bordered && !borderless
      ? `border: 1px solid ${borderColors[inverted ? 'secondary' : 'primary']};`
      : ''};
    border-collapse: collapse;
    color: ${colors[inverted ? 'primary' : 'secondary']};
    width: 100%;
  `;
};
const stylesCaption = props => {
  const { captionColor, captionPadding } = getTheme(props, 'table');

  return css`
    caption-side: bottom;
    color: ${captionColor};
    font-size: 90%;
    padding-bottom: ${px(captionPadding)};
    padding-top: ${px(captionPadding)};
    text-align: left;
  `;
};
const stylesCellBorder = props => {
  const { bordered, borderless, inverted } = props;
  const { borderColors } = getTheme(props, 'table');

  if (borderless) {
    return '';
  }

  return css`
    ${bordered ? 'border' : 'border-top'}: 1px solid
      ${borderColors[inverted ? 'secondary' : 'primary']};
  `;
};
const stylesHeadBackgroundColor = props => {
  const { head } = props;
  const { headColors } = getTheme(props, 'table');

  return css`
    background-color: ${headColors[head] || 'transparent'};
  `;
};
const stylesHeadCellBorder = props => {
  const { bordered, borderless, inverted } = props;
  const { borderColors } = getTheme(props, 'table');
  const colorProp = borderColors[inverted ? 'secondary' : 'primary'];

  if (borderless) {
    return '';
  }

  return css`
    ${bordered ? `border: 1px solid ${colorProp}` : `border-bottom: 2px solid ${colorProp}`};
    ${bordered && 'border-bottom-width: 2px'};
  `;
};
const stylesHeadColor = props => {
  const { head } = props;
  const { colors } = getTheme(props, 'table');

  if (head) {
    return css`
      color: ${colors[head === 'dark' ? 'primary' : 'secondary']};
    `;
  }

  return '';
};
const stylesPadding = props => {
  const { size } = props;
  const { padding } = getTheme(props, 'table');

  return css`
    padding: ${px(padding[size])};
  `;
};
const stylesStriped = props => {
  const { inverted, striped } = props;
  const { stripedColors } = getTheme(props, 'table');

  if (striped) {
    return css`
      background-color: ${stripedColors[inverted ? 'secondary' : 'primary']};
    `;
  }

  return '';
};

const Table = styled(Box)`
  ${styles};

  th {
    text-align: inherit;
  }

  th,
  td {
    ${stylesCellBorder};
    ${stylesPadding};
    vertical-align: top;
  }

  thead {
    ${stylesHeadBackgroundColor};
    ${stylesHeadColor};
  }

  thead th {
    ${stylesHeadCellBorder};
    vertical-align: bottom;
  }

  tbody tr:nth-of-type(odd) {
    ${stylesStriped};
  }

  caption {
    ${stylesCaption};
  }
`;

Table.displayName = 'Table';

Table.propTypes = {
  as: PropTypes.string,
  bordered: PropTypes.bool,
  borderless: PropTypes.bool,
  children: PropTypes.node.isRequired,
  head: PropTypes.oneOf(['light', 'dark']),
  inverted: PropTypes.bool,
  size: sizesPropTypes,
  striped: PropTypes.bool,
  ...basePropTypes,
};

Table.defaultProps = {
  as: 'table',
  bordered: false,
  borderless: false,
  inverted: false,
  size: 'md',
  striped: false,
};

export default Table;