@w11r/use-breakpoint
    TypeScript icon, indicating that this package has built-in type declarations

    2.0.0 • Public • Published

    Intro

    React useBreakpoint hook to have different values for a variable based on a breakpoints.

    Demo

    https://wintercounter.github.io/use-breakpoint

    Install

    npm i @w11r/use-breakpoint

    Setup

    Add provider

    Add BreakpointProvider in your React tree.

    import { BreakpointProvider } from '@w11r/use-breakpoint'
    
    ...
        <BreakpointProvider>
            ...
        </BreakpointProvider>
    ...

    Default breakpoints

    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]
    }

    Override default settings

    import { setup, breakpoints } from '@w11r/use-breakpoint'
    
    setup({
        breakpoints: {
            // Extend default values
            ...breakpoints,
            alienDevice: [342, 43534] // from, to
        }
    })

    Usage

    With passing values

    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]]`

    Without passing values

    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!

    Modifiers

    All breakpoint names coming with modifiers included.

    Orientation prefix

    • `` (none): all
    • -: Landscape
    • |: Portrait

    Range suffix

    You can also control your value to behave as and up and and down.

    • `` (none): all
    • +: and up
    • -: and down

    Examples

    • ['|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

    Generate Media Query strings using the same logic

    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 }

    FAQ

    Is there any best practice suggestion?

    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.

    Why not using an Object? Why the Array structure?

    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.

    Which rule is being prioritized?

    The hook uses eager evaluation, so the first truthy breakpoint value gets returned.

    Install

    npm i @w11r/use-breakpoint

    DownloadsWeekly Downloads

    788

    Version

    2.0.0

    License

    MIT

    Unpacked Size

    58.8 kB

    Total Files

    40

    Last publish

    Collaborators

    • wintercounter