Skip to content

Instantly share code, notes, and snippets.

@HeavenOSK
Last active September 20, 2021 08:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HeavenOSK/18bdda3e657f27bd038a23b3659b1daf to your computer and use it in GitHub Desktop.
Save HeavenOSK/18bdda3e657f27bd038a23b3659b1daf to your computer and use it in GitHub Desktop.
Switch components responsively with Chakra UI display props
import React, { ReactNode } from 'react'
import { BoxProps, chakra } from '@chakra-ui/react'
import { ResponsiveObject } from '@chakra-ui/styled-system/dist/types/utils/types'
type ResponsiveItems = ResponsiveObject<ReactNode>
type Props = {
items: ResponsiveItems
} & BoxProps
const breakpoints = ['base', 'sm', 'md', 'lg', 'xl', '2xl']
const ChakraDiv = chakra('div')
const ResponsiveComponent = (props: Props) => {
const effectiveBPs = breakpoints
.map(p => {
return props.items[p] ? p : null
})
.filter(p => p !== null)
return (
<>
{effectiveBPs.map(p => {
if (!p || !props.items[p]) {
return <></>
}
const displayConfig = {
base: 'none',
[p]: 'block',
}
const indexP = effectiveBPs.indexOf(p)
if (indexP < effectiveBPs.length - 1) {
const nextBP = effectiveBPs[indexP + 1]
displayConfig[nextBP!] = 'none'
}
return (
<ChakraDiv {...(props as BoxProps)} key={p} display={displayConfig}>
{props.items[p]}
</ChakraDiv>
)
})}
</>
)
}
export default ResponsiveComponent
@HeavenOSK
Copy link
Author

HeavenOSK commented Sep 20, 2021

Usage

import { Center, Heading } from '@chakra-ui/react'
import ResponsiveComponent from '../../components/ResponsiveComponent'

const Home = () => {
  return (
    <Center height={'100vh'} width={'100vw'}>
      <ResponsiveComponent
        items={{
          base: <Heading color={'blue'}> This is base</Heading>,
          sm: <Heading color={'yellow'}>This is sm</Heading>,
          md: <Heading color={'red'}>This is md</Heading>,
          lg: <Heading color={'green'}>This is lg</Heading>,
          xl: <Heading color={'pink'}>This is xl</Heading>,
          '2xl': <Heading color={'black'}>This is 2xl</Heading>,
        }}
      />
    </Center>
  )
}

export default Home

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment