Skip to content

Instantly share code, notes, and snippets.

@gchumillas
Last active March 17, 2024 13:41
Show Gist options
  • Select an option

  • Save gchumillas/8ff484d74a32df26ef70dba91adf6256 to your computer and use it in GitHub Desktop.

Select an option

Save gchumillas/8ff484d74a32df26ef70dba91adf6256 to your computer and use it in GitHub Desktop.

Revisions

  1. gchumillas revised this gist Mar 17, 2024. No changes.
  2. gchumillas revised this gist Mar 17, 2024. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions 1. use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -1,20 +1,20 @@
    import React from 'react'
    import { useCallback, useMemo, useEffect } from 'react'

    export const useBreakpoints = <T extends Record<string, number>>(breakpoints: T): keyof T | undefined => {
    const searchBreakpoint = React.useCallback((breakpoints: { key: string, value: number }[]) => {
    const searchBreakpoint = useCallback((breakpoints: { key: string, value: number }[]) => {
    return breakpoints.find((x) => window.innerWidth < x.value)?.key
    }, [])

    const entries = React.useMemo(() => {
    const entries = useMemo(() => {
    return Object
    .entries(breakpoints)
    .sort((a, b) => a[1] - b[1])
    .map(([key, value]) => ({ key, value }))
    }, [breakpoints])

    const [breakpoint, setBreakpoint] = React.useState(searchBreakpoint(entries))
    const [breakpoint, setBreakpoint] = useState(searchBreakpoint(entries))

    React.useEffect(() => {
    useEffect(() => {
    const onResize = () => {
    setBreakpoint(searchBreakpoint(entries))
    }
  3. gchumillas revised this gist Mar 17, 2024. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
  4. gchumillas revised this gist Mar 17, 2024. No changes.
  5. gchumillas revised this gist Mar 17, 2024. 2 changed files with 34 additions and 32 deletions.
    34 changes: 34 additions & 0 deletions example.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    import React from 'react'
    import { useBreakpoints } from './use-breakpoints.ts'

    // I recommend to declare breakpoints somewhere outside the component
    // to prevent unnecessary re-renders.
    //
    // Otherwise don't forget to wrap it around React.useMemo:
    // useBreakpoints(React.useMemo({ sm: 640, md: 768, ... }))
    const breakpoints = {
    sm: 640,
    md: 768,
    lg: 1024,
    xl: 1280
    }

    function App() {
    const size = useBreakpoints(breakpoints)

    if (size == 'sm') {
    return <p>Small device.</p>
    } else if (size == 'md') {
    return <p>Medium device.</p>
    } else if (size == 'lg') {
    return <p>Large device.</p>
    } else if (size == 'xl') {
    return <p>Very large device.</p>
    }

    return (
    <p>Extra large device!</p>
    )
    }

    export default App
    32 changes: 0 additions & 32 deletions use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -26,35 +26,3 @@ export const useBreakpoints = <T extends Record<string, number>>(breakpoints: T)

    return breakpoint
    }

    // I recommend to declare breakpoints somewhere outside the component
    // to prevent unnecessary re-renders.
    //
    // Otherwise don't forget to wrap it around React.useMemo:
    // useBreakpoints(React.useMemo({ sm: 640, md: 768, ... }))
    const breakpoints = {
    sm: 640,
    md: 768,
    lg: 1024,
    xl: 1280
    }

    function App() {
    const size = useBreakpoints(breakpoints)

    if (size == 'sm') {
    return <p>Small device.</p>
    } else if (size == 'md') {
    return <p>Medium device.</p>
    } else if (size == 'lg') {
    return <p>Large device.</p>
    } else if (size == 'xl') {
    return <p>Very large device.</p>
    }

    return (
    <p>Extra large device!</p>
    )
    }

    export default App
  6. gchumillas revised this gist Jul 14, 2023. 1 changed file with 38 additions and 20 deletions.
    58 changes: 38 additions & 20 deletions use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -1,29 +1,15 @@
    import React from 'react'

    const searchBreakpoint = (breakpoints: { key: string, value: number, index: number }[]) => {
    return breakpoints.find((x) => window.innerWidth < x.value)
    }
    export const useBreakpoints = <T extends Record<string, number>>(breakpoints: T): keyof T | undefined => {
    const searchBreakpoint = React.useCallback((breakpoints: { key: string, value: number }[]) => {
    return breakpoints.find((x) => window.innerWidth < x.value)?.key
    }, [])

    // Example:
    //
    // const breakpoints = React.useMemo(() => ({ sm: 640, md: 769, lg: 1024, xl: 1280 }), [])
    // const breakpoint = useBreakpoints(breakpoints)
    //
    // ... later ...
    //
    // if (breakpoint.index < 1) {
    // return <MobileVersion />
    // } else if (breakpoint.index < 2) {
    // return <TabletVersion />
    // } else {
    // return <DesktopVersion />
    // }
    export const useBreakpoints = (breakpoints: Record<string, number>) => {
    const entries = React.useMemo(() => {
    return Object
    .entries(breakpoints)
    .sort((a, b) => a[1] - b[1])
    .map(([key, value], index) => ({ key, value, index }))
    .map(([key, value]) => ({ key, value }))
    }, [breakpoints])

    const [breakpoint, setBreakpoint] = React.useState(searchBreakpoint(entries))
    @@ -36,7 +22,39 @@ export const useBreakpoints = (breakpoints: Record<string, number>) => {
    return () => {
    window.removeEventListener('resize', onResize)
    }
    }, [entries])
    }, [entries, searchBreakpoint])

    return breakpoint
    }

    // I recommend to declare breakpoints somewhere outside the component
    // to prevent unnecessary re-renders.
    //
    // Otherwise don't forget to wrap it around React.useMemo:
    // useBreakpoints(React.useMemo({ sm: 640, md: 768, ... }))
    const breakpoints = {
    sm: 640,
    md: 768,
    lg: 1024,
    xl: 1280
    }

    function App() {
    const size = useBreakpoints(breakpoints)

    if (size == 'sm') {
    return <p>Small device.</p>
    } else if (size == 'md') {
    return <p>Medium device.</p>
    } else if (size == 'lg') {
    return <p>Large device.</p>
    } else if (size == 'xl') {
    return <p>Very large device.</p>
    }

    return (
    <p>Extra large device!</p>
    )
    }

    export default App
  7. gchumillas revised this gist Jul 10, 2023. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,8 @@ const searchBreakpoint = (breakpoints: { key: string, value: number, index: numb

    // Example:
    //
    // const breakpoint = useBreakpoints({ sm: 640, md: 769, lg: 1024, xl: 1280 })
    // const breakpoints = React.useMemo(() => ({ sm: 640, md: 769, lg: 1024, xl: 1280 }), [])
    // const breakpoint = useBreakpoints(breakpoints)
    //
    // ... later ...
    //
  8. gchumillas revised this gist Jul 10, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ const searchBreakpoint = (breakpoints: { key: string, value: number, index: numb
    // if (breakpoint.index < 1) {
    // return <MobileVersion />
    // } else if (breakpoint.index < 2) {
    // return <MobileVersion />
    // return <TabletVersion />
    // } else {
    // return <DesktopVersion />
    // }
  9. gchumillas created this gist Jul 10, 2023.
    41 changes: 41 additions & 0 deletions use-breakpoints.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    import React from 'react'

    const searchBreakpoint = (breakpoints: { key: string, value: number, index: number }[]) => {
    return breakpoints.find((x) => window.innerWidth < x.value)
    }

    // Example:
    //
    // const breakpoint = useBreakpoints({ sm: 640, md: 769, lg: 1024, xl: 1280 })
    //
    // ... later ...
    //
    // if (breakpoint.index < 1) {
    // return <MobileVersion />
    // } else if (breakpoint.index < 2) {
    // return <MobileVersion />
    // } else {
    // return <DesktopVersion />
    // }
    export const useBreakpoints = (breakpoints: Record<string, number>) => {
    const entries = React.useMemo(() => {
    return Object
    .entries(breakpoints)
    .sort((a, b) => a[1] - b[1])
    .map(([key, value], index) => ({ key, value, index }))
    }, [breakpoints])

    const [breakpoint, setBreakpoint] = React.useState(searchBreakpoint(entries))

    React.useEffect(() => {
    const onResize = () => {
    setBreakpoint(searchBreakpoint(entries))
    }
    window.addEventListener('resize', onResize)
    return () => {
    window.removeEventListener('resize', onResize)
    }
    }, [entries])

    return breakpoint
    }