Skip to content

Commit

Permalink
refactor(responsive): Use Responsive component in Heading component t…
Browse files Browse the repository at this point in the history
…o replace media queries respons

Applicable to h1 and h2 WIP
  • Loading branch information
lzcabrera committed Nov 17, 2017
1 parent b284238 commit d7508a9
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 95 deletions.
46 changes: 37 additions & 9 deletions src/components/Typography/Heading/Heading.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,60 @@ import React from 'react'
import PropTypes from 'prop-types'

import safeRest from '../../../utils/safeRest'
import joinClassNames from '../../../utils/joinClassNames'

import Responsive from '../../Responsive/Responsive'
import HeadingSup from './HeadingSup/HeadingSup'
import HeadingSub from './HeadingSub/HeadingSub'

import styles from './Heading.modules.scss'

const getColorClassName = level =>
level === 'h1' || level === 'h2' ? styles.secondary : styles.default

const getClassName = (level, invert) => {
const colorClassName = invert ? styles.inverted : getColorClassName(level)
const getDesktopClassName = (level, desktop) =>
desktop ? styles[`${level}Desktop`] : styles[level]

return `${styles[level]} ${colorClassName}`
const getColorClassName = (level, invert) => {
if (invert) {
return styles.inverted
}
return level === 'h1' || level === 'h2' ? styles.secondary : styles.default
}

/**
* Page headings. Renders an HTML `<h1-h4>` element.
*/
const Heading = ({level, invert, children, ...rest}) =>
React.createElement(
const Heading = ({ level, invert, children, ...rest }) => {
if (level === 'h1' || level === 'h2') {
return (
<Responsive minWidth="md">
{matches => {
const desktop = !!matches

return React.createElement(
level,
{
...safeRest(rest),
className: joinClassNames(
getDesktopClassName(level, desktop),
getColorClassName(level, invert)
),
},
children
)
}}
</Responsive>
)
}

return React.createElement(
level,
{
...safeRest(rest),
className: getClassName(level, invert),
className: joinClassNames(styles[level], getColorClassName(level, invert)),
},
children
)
}

Heading.propTypes = {
/**
* The heading level.
Expand Down
90 changes: 31 additions & 59 deletions src/components/Typography/Heading/Heading.modules.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,96 +42,68 @@
font-size: 1.75rem;
line-height: 1.29; // 36px
letter-spacing: -1.6px;
}

.sup,
.sub {
font-size: 1.25rem;
}

.sup {
top: -1em;
}

.sub {
bottom: -0.4em;
}
.h1 .sup {
font-size: 1.25rem; // ???
top: -1em;
}

@include from-breakpoint(medium) {
font-weight: 300;
font-size: 2.75rem;
line-height: 1.18; // 52px
letter-spacing: 0;
.h1Desktop {
composes: largeHeading;
font-weight: 300;
font-size: 2.75rem;
line-height: 1.18; // 52px
letter-spacing: 0;
}

.sup {
top: -1.3em;
}
}
.h1Desktop .sup {
font-size: 1.25rem; // ???
top: -1.3em;
}

.h2 {
composes: largeHeading;
font-size: 1.5rem;
line-height: 1.33; // 30px
letter-spacing: -0.4px;
}

.sup,
.sub {
font-size: 1rem;
}

.sup {
top: -0.8em;
}

.sub {
bottom: -0.4em;
}
.h2 .sup {
font-size: 1rem; // ???
top: -0.8em;
}

@include from-breakpoint(medium) {
font-size: 1.75rem;
line-height: 1.29; // 36px
letter-spacing: -0.8px;
.h2Desktop {
composes: largeHeading;
font-size: 1.75rem;
line-height: 1.29; // 36px
letter-spacing: -0.8px;
}

.sup {
top: -0.7em;
}
}
.h2Desktop .sup {
font-size: 1rem; // ???
top: -0.7em;
}

.h3 {
composes: smallHeading;
font-size: 1.25rem;
line-height: 1.4; // 28px

.sup,
.sub {
font-size: 0.875rem;
}

.sup {
font-size: 0.875rem;
top: -0.5em;
}

.sub {
bottom: -0.5em;
}
}

.h4 {
composes: smallHeading;
font-size: 1rem;
line-height: 1.25; // 20px

.sup,
.sub {
font-size: 0.875rem;
}

.sup {
font-size: 0.875rem;
top: -0.5em;
}

.sub {
bottom: -0.5em;
}
}
69 changes: 42 additions & 27 deletions src/components/Typography/Heading/__tests__/Heading.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,86 @@
import React from 'react'
import { shallow } from 'enzyme'


import Heading from '../Heading'

describe('Heading', () => {
const defaultProps = {
level: 'h1'
level: 'h1',
}
const doShallow = (overrides = {}) => shallow(
<Heading {...defaultProps} {...overrides}>Go home</Heading>
)

const doShallow = (overrides = {}) =>
shallow(
<Heading {...defaultProps} {...overrides}>
Go home
</Heading>
)

const doShallowResponsive = (overrides = {}) =>
shallow(
<Heading {...defaultProps} {...overrides}>
Go home
</Heading>
)
.dive()
.dive()

it('renders', () => {
const heading = doShallow()
const responsiveHeading = doShallowResponsive()

expect(heading).toMatchSnapshot()
expect(responsiveHeading).toMatchSnapshot()
})

it('renders text', () => {
const heading = doShallow()
const responsiveHeading = doShallowResponsive()

expect(heading).toHaveText('Go home')
expect(responsiveHeading).toHaveText('Go home')
})

it('renders a heading in four levels', () => {
let heading = doShallow({ level: 'h1' })
expect(heading).toHaveTagName('h1')
let responsiveHeading = doShallowResponsive({ level: 'h1' })
expect(responsiveHeading).toHaveTagName('h1')

heading = doShallow({ level: 'h2' })
expect(heading).toHaveTagName('h2')
responsiveHeading = doShallowResponsive({ level: 'h2' })
expect(responsiveHeading).toHaveTagName('h2')

heading = doShallow({ level: 'h3' })
let heading = doShallow({ level: 'h3' })
expect(heading).toHaveTagName('h3')

heading = doShallow({ level: 'h4' })
expect(heading).toHaveTagName('h4')
})

it('has appropriate colour', () => {
let heading = doShallow({ invert: true })
expect(heading).toHaveClassName('inverted')
let responsiveHeading = doShallowResponsive({ invert: true })
expect(responsiveHeading).toHaveClassName('inverted')

heading = doShallow({ level: 'h1' })
expect(heading).toHaveClassName('secondary')
responsiveHeading = doShallowResponsive({ level: 'h1' })
expect(responsiveHeading).toHaveClassName('secondary')

heading = doShallow({ level: 'h2' })
expect(heading).toHaveClassName('secondary')
responsiveHeading = doShallowResponsive({ level: 'h2' })
expect(responsiveHeading).toHaveClassName('secondary')

heading = doShallow({ level: 'h3' })
let heading = doShallow({ level: 'h3' })
expect(heading).toHaveClassName('default')

heading = doShallow({ level: 'h4' })
expect(heading).toHaveClassName('default')
})

it('passes additional attributes to heading element', () => {
const heading = doShallow({ id: 'the-heading', tabindex: 1 })
const responsiveHeading = doShallowResponsive({ id: 'the-heading', tabindex: 1 })

expect(heading).toHaveProp('id', 'the-heading')
expect(heading).toHaveProp('tabindex', 1)
expect(responsiveHeading).toHaveProp('id', 'the-heading')
expect(responsiveHeading).toHaveProp('tabindex', 1)
})

it('does not allow custom CSS', () => {
const heading = doShallow({ className: 'my-custom-class', style: { color: 'hotpink' } })
const responsiveHeading = doShallowResponsive({
className: 'my-custom-class',
style: { color: 'hotpink' },
})

expect(heading).not.toHaveProp('className', 'my-custom-class')
expect(heading).not.toHaveProp('style')
expect(responsiveHeading).not.toHaveProp('className', 'my-custom-class')
expect(responsiveHeading).not.toHaveProp('style')
})
})

0 comments on commit d7508a9

Please sign in to comment.