Skip to content

Commit

Permalink
Adds "useCurrentBreakpoints" hook
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Apr 6, 2020
1 parent ba295c7 commit d766304
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 0 deletions.
15 changes: 15 additions & 0 deletions examples/hooks/UseCurrentBreakpoints.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { useCurrentBreakpoints } from 'atomic-layout'

const UseCurrentBreakpointsScenario = () => {
const breakpoints = useCurrentBreakpoints()

return (
<p>
Current breakpoint:{' '}
<span data-test-id="current-breakpoints">{breakpoints.join()}</span>
</p>
)
}

export default UseCurrentBreakpointsScenario
29 changes: 29 additions & 0 deletions examples/hooks/useCurrentBreakpoints.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
describe('useCurrentBreakpoints', () => {
before(() => {
cy.loadStory(['hooks'], ['usecurrentbreakpoints'])
})

it('Returns the default breakpoint on initial render', () => {
cy.get('[data-test-id="current-breakpoints"]').should('have.text', 'xs')
})

it('Returns "sm" breakpoint name on "sm" breakpoint', () => {
cy.setBreakpoint('sm')
cy.get('[data-test-id="current-breakpoints"]').should('have.text', 'sm')
})

it('Returns "md" breakpoint name on "md" breakpoint', () => {
cy.setBreakpoint('md')
cy.get('[data-test-id="current-breakpoints"]').should('have.text', 'md')
})

it('Returns "lg" breakpoint name on "lg" breakpoint', () => {
cy.setBreakpoint('lg')
cy.get('[data-test-id="current-breakpoints"]').should('have.text', 'lg')
})

it('Returns "xl" breakpoint name on "xl" breakpoint', () => {
cy.setBreakpoint('xl')
cy.get('[data-test-id="current-breakpoints"]').should('have.text', 'xl')
})
})
2 changes: 2 additions & 0 deletions examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ storiesOf('Components|Visible', module).add(
import UseViewportChange from './hooks/UseViewportChange'
import UseResponsiveValue from './hooks/UseResponsiveValue'
import UseBreakpointChange from './hooks/UseBreakpointChange'
import UseCurrentBreakpoints from './hooks/UseCurrentBreakpoints'
import UseResponsiveProps from './hooks/UseResponsiveProps'
import UseResponsiveComponent from './hooks/UseResponsiveComponent'

storiesOf('Hooks', module)
.add('useViewportChange', () => <UseViewportChange />)
.add('useResponsiveValue', () => <UseResponsiveValue />)
.add('useBreakpointChange', () => <UseBreakpointChange />)
.add('useCurrentBreakpoints', () => <UseCurrentBreakpoints />)
.add('useResponsiveProps', () => <UseResponsiveProps />)
.add('useResponsiveComponent', () => <UseResponsiveComponent />)

Expand Down
1 change: 1 addition & 0 deletions packages/atomic-layout-emotion/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
useMediaQuery,
useViewportChange,
useBreakpointChange,
useCurrentBreakpoints,
useResponsiveValue,
useResponsiveProps,
useResponsiveComponent,
Expand Down
33 changes: 33 additions & 0 deletions packages/atomic-layout/src/hooks/useCurrentBreakpoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useState } from 'react'
import useViewportChange from './useViewportChange'
import { Layout, createMediaQuery } from '@atomic-layout/core'

/**
* Returns a list of breakpoints that match the current state of the viewport.
*/
export default function useCurrentBreakpoints(): string[] {
const [currentBreakpoints, setCurrentBreakpoints] = useState<string[]>([
Layout.defaultBreakpointName,
])

useViewportChange(() => {
const matchingBreakpoints = Object.keys(Layout.breakpoints).filter(
(breakpointName) => {
const mediaQueryObject = Layout.breakpoints[breakpointName]
/**
* @fixme Move the media query composition and matching logic
* into the `Layout` class.
* @reason It's expensive and redundant to compose strings from
* breakpoints on each viewport change. Breakpoints never change
* on runtime.
*/
const mediaQuery = createMediaQuery(mediaQueryObject, 'only')
return matchMedia(mediaQuery).matches
},
)

setCurrentBreakpoints(matchingBreakpoints)
})

return currentBreakpoints
}
1 change: 1 addition & 0 deletions packages/atomic-layout/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export { default as Visible } from './components/Visible'
export { useMediaQuery } from './hooks/useMediaQuery'
export { default as useViewportChange } from './hooks/useViewportChange'
export { default as useBreakpointChange } from './hooks/useBreakpointChange'
export { default as useCurrentBreakpoints } from './hooks/useCurrentBreakpoints'
export { default as useResponsiveValue } from './hooks/useResponsiveValue'
export { default as useResponsiveProps } from './hooks/useResponsiveProps'
export { default as useResponsiveComponent } from './hooks/useResponsiveComponent'
Expand Down

0 comments on commit d766304

Please sign in to comment.