All files / elements/typography/Header styled.js

100% Statements 31/31
50% Branches 4/8
100% Functions 5/5
100% Lines 30/30

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                                          8x   8x 48x 48x 48x 26x 26x       26x   48x     8x     26x 26x       26x   8x             8x 48x 48x   26x   48x     48x 48x                             8x   8x   8x 40x 40x   40x       40x                 8x         8x                    
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { fontWeight, space } from 'styled-system';
import {
  colorCore,
  defaultStylesBase,
  ellipsisCore,
  fontFamilyCore,
  fontSizeCore,
  fontStyleCore,
  letterSpacingCore,
  lineHeightCore,
  spaceProps,
  textAlignCore,
  textDecorationCore,
  typography,
} from 'src/utils/styledHelpers';
import { getGlobalStyles } from 'src/global-styles';
import { removeSomeProps } from 'src/utils/componentHelpers';
 
const { fontSize: fontSizeSchema, grid: gridSchema } = getGlobalStyles();
 
const getHeaderFontSizeFromTag = factoryProps => {
  const { tag: factoryPropsTag } = factoryProps;
  const tag = factoryPropsTag || 'h1';
  const getHeaderFontSizeMemoized = props => {
    const { displayHeader } = props;
    const overrides = {
      ...props,
      fontSize: displayHeader ? fontSizeSchema.displayHeader[tag] : fontSizeSchema[tag],
    };
    return fontSizeCore(overrides);
  };
  return getHeaderFontSizeMemoized;
};
 
const getHeaderFontWeight = props => {
  const {
    displayHeader, fontWeight: fontWeightFromProps,
  } = props;
  const overrides = {
    ...props,
    fontWeight: displayHeader ? '300' : fontWeightFromProps || defaultStylesBase.fontWeight,
  };
  return fontWeight(overrides);
};
const propsToTrim = {
  ...spaceProps.propTypes,
  ...typography.propTypes,
  children: PropTypes.any.isRequired,
  displayHeader: PropTypes.bool,
};
 
const headerFactory = factoryProps => {
  const { tag } = factoryProps;
  const HeaderComponent = ({
    children, ...props
  }) => React.createElement(tag, removeSomeProps(props, Object.keys(propsToTrim)), children);
  // This is stated here strictly as a interface reference. Unfortunately as this component is dynamically created there is no propType required or defaultProps enforced.
  HeaderComponent.propTypes = {
    children: PropTypes.any.isRequired,
  };
  const getHeaderFontSize = getHeaderFontSizeFromTag(factoryProps);
  return styled(HeaderComponent)`
    ${colorCore}
    ${ellipsisCore}
    ${fontFamilyCore}
    ${fontStyleCore}
    ${getHeaderFontSize}
    ${getHeaderFontWeight}
    ${letterSpacingCore}
    ${lineHeightCore}
    ${textAlignCore}
    ${textDecorationCore}
    ${space}
  `;
};
 
const Header = headerFactory({ tag: 'h1' });
 
Header.h1 = Header;
 
for (let i = 2; i <= 6; i++) {
  const subHeaderTag = `h${i}`;
  Header[subHeaderTag] = headerFactory({ tag: subHeaderTag });
 
  Header[subHeaderTag].propTypes = {
    displayHeader: PropTypes.bool,
    ...typography.propTypes,
  };
  Header[subHeaderTag].defaultProps = {
    ...defaultStylesBase,
    displayHeader: false,
    fontWeight: defaultStylesBase.fontWeight,
    mb: gridSchema.gutter,
    mt: 0,
  };
}
 
Header.propTypes = {
  ...typography.propTypes,
  displayHeader: PropTypes.bool,
};
 
Header.defaultProps = {
  ...defaultStylesBase,
  displayHeader: false,
  fontWeight: defaultStylesBase.fontWeight,
  mb: gridSchema.gutter,
  mt: 0,
};
 
/** @component */
export { Header };