React useBreakpoint
hook to have different values for a variable
based on a breakpoints.
https://wintercounter.github.io/use-breakpoint
npm i @w11r/use-breakpoint
Add BreakpointProvider
in your React tree.
import { BreakpointProvider } from '@w11r/use-breakpoint'
...
<BreakpointProvider>
...
</BreakpointProvider>
...
The following default breakpoints are being used, including several shorthands.
const breakpoints = {
micro: [0, 375],
mi: [0, 375],
mobile: [376, 639],
m: [376, 639],
tablet: [640, 1023],
t: [640, 1023],
small: [1024, 1439],
s: [1024, 1439],
medium: [1440, 1919],
med: [1440, 1919],
large: [1920, 10000],
l: [1920, 10000],
// Multi range
device: [0, 1023],
d: [0, 1023],
smallDevice: [0, 639],
sd: [0, 639]
}
import { setup, breakpoints } from '@w11r/use-breakpoint'
setup({
breakpoints: {
// Extend default values
...breakpoints,
alienDevice: [342, 43534] // from, to
}
})
useBreakpoint(defaultValue, breakpointValues)
// breakpointValues: array of breakpoint based values
[
['mobile', 300],
['tablet', 400]
]
// In case you have a single breakpoint value, `['mobile', 300]` is enough instead of `[['mobile', 300]]`
In case you don't specify any value to the hook, it'll return a generated object including boolean values for each breakpoint keys that's being defined in options.
It'll return the following object with the basic setup.
{
isLandscape: false,
isPortrait: true,
isHDPI: false,
isMicro: false,
isMobile: true,
isTablet: false,
isSmall: false,
isMedium: false,
isLarge: false,
'is-Micro': false,
'is|Micro': false,
'isMicro+': true,
'is-Micro+': true,
'is|Micro+': true,
'isMicro-': false,
'is-Micro-': false,
'is|Micro-': false,
'is-Mobile': true,
'is|Mobile': true,
'isMobile+': true,
'is-Mobile+': true,
'is|Mobile+': true,
'isMobile-': true,
'is-Mobile-': true,
'is|Mobile-': true,
'is-Tablet': false,
'is|Tablet': false,
'isTablet+': false,
'is-Tablet+': false,
'is|Tablet+': false,
'isTablet-': true,
'is-Tablet-': true,
'is|Tablet-': true,
'is-Small': false,
'is|Small': false,
'isSmall+': false,
'is-Small+': false,
'is|Small+': false,
'isSmall-': true,
'is-Small-': true,
'is|Small-': true,
'is-Medium': false,
'is|Medium': false,
'isMedium+': false,
'is-Medium+': false,
'is|Medium+': false,
'isMedium-': true,
'is-Medium-': true,
'is|Medium-': true,
'is-Large': false,
'is|Large': false,
'isLarge+': false,
'is-Large+': false,
'is|Large+': false,
'isLarge-': true,
'is-Large-': true,
'is|Large-': true
}
Usage
const { isMobile } = useBreakpoint()
// The above is basically a replacement for
const isMobile = useBreakpoint(false, ['mobile', true])
You can also access the values with suffix and prefix, but you need to rename the variables because it contains invalid character:
const { 'isMobile+': isMobile } = useBreakpoint()
Component example
import useBreakpoint from '@w11r/use-breakpoint'
const MyCmp = () => {
const columns = useBreakpoint([1,2], ['mobile', [2,1]])
return <Grid cols={columns} />
}
// Or using inline
const MyCmp = () => {
return <Grid cols={useBreakpoint([1,2], ['mobile', [2,1]])} />
}
Rules-of-Hooks are still true in this case as well. Make sure your component will ALWAYS run it without any condition!
All breakpoint names coming with modifiers included.
- `` (none): all
-
: Landscape|
: Portrait
You can also control your value to behave as and up
and and down
.
- `` (none): all
+
:and up
-
:and down
['|mobile', 300]
: on mobile, on portrait['|mobile+', 300]
: on mobile and up, on portrait['mobile+', 300]
: on mobile and up, both portrait and landscape['mobile', 300]
: on mobile, both portrait and landscape['tablet-', 300]
: on tablet and below, both portrait and landscape['mobile-', 300]
: on mobile and down, both portrait and landscape
It is useful when you just need simple CSS. For example with styled-components
:
import styled from 'styled-components'
import { mediaQuery } from '@w11r/use-breakpoint'
const mediaQueryString = mediaQuery(
['mobile-', `width: 100%;`]
)
const Box = styled.div`
${mediaQuery(
['mobile-', `width: 100%;`]
)}
`
// You can still use multiple queries at once just like with the hook:
mediaQuery([['mobile-', `width: 100%`], ['medium+', `width: 50%`]])
This utility comes with additional support for shorthands
which is configurable through options
.
setup({
shorthands: {
foo: '@media (wow: bar) and (hmm: khm)'
}
})
mediaQuery(['foo', value])
Additionally, it supports dark
and light
mode prefixes:
(
: Light mode)
: Dark mode
mediaQuery([')mobile', 'content'])
// @media screen and (min-width: 376px) and (max-width: 639px) and (prefers-color-scheme: dark) { content }
mediaQuery([')', 'content'])
// @media screen and (prefers-color-scheme: dark) { content }
Yes! Use as fewer hooks as possible. It's always faster to have a single
isMobile
variable and have simple conditions based on it. It's even better
if you can solve your size related cases using pure CSS Media Queries.
Object's cannot guarantee the order of the defined keys. It is crucial
to check for values in the correct order because useBreakpoint
uses
eager evaluation and mediaQuery
must maintain the defined order of
the generated Media Queries.
The hook uses eager evaluation, so the first truthy breakpoint value gets returned.