import React, {useContext} from "react"
import {ResponsiveLayoutContext} from "../../components";
/**
* @typedef
*/
type WidthCheckReturn = {
/**
* Whether the screen width is below {@link NARROW_UPPER_BOUND} (exclusive)
*/
wide: boolean
/**
* Whether the screen width is above {@link NARROW_UPPER_BOUND} (inclusive) and below {@link MEDIUM_UPPER_BOUND} (exclusive)
*/
medium: boolean
/**
* Whether the screen width is above {@link MEDIUM_UPPER_BOUND} (inclusive)
*/
narrow: boolean
}
/**
* Width (in pixels) that represents the upper boundary (exclusive) of the `narrow` value.
* Since this is an _exclusive_ boundary, this is the first width that is NOT considered narrow.
*
* Until doc auto renders, value is set to `575`
*
* @constant
* @type {number}
* @default
*/
export const NARROW_UPPER_BOUND = 575
/**
* Width (in pixels) that represents the upper boundary (exclusive) of the `medium` value
* Since this is an _exclusive_ boundary, this is the first width that is NOT considered medium.
*
* Until doc auto renders, value is set to `1000`
*
* @constant
* @type {number}
* @default
*/
export const MEDIUM_UPPER_BOUND = 1000
/**
* Custom hook for classifying the current width of the app's
* viewport into `narrow`, `medium`, and `wide` categories.
*
* The hook doesn't take any parameters and returns a boolean
* for each category.
*
* - `narrow`: will be `true` if the screen width is below {@link NARROW_UPPER_BOUND} (exclusive)
* - `medium`: will be `true` if the screen width is above {@link NARROW_UPPER_BOUND} (inclusive) and below {@link MEDIUM_UPPER_BOUND} (exclusive)
* - `wide`: will be `true` if the screen width is above {@link MEDIUM_UPPER_BOUND} (inclusive)
*
* Note that using this hook will re-render your component when
* the viewport width changes; that means your layout can adapt
* as the user resizes their browser or rotates their phone.
*
* ### Hook Usage
*
* #### Checking the current width
* ```
* const {narrow, medium, wide} = useWidthCheck()
*
* ...
*
* if (narrow) { return 'Your browser window is narrow like a phone' }
* else if (medium) { return 'Your browser window is medium like a tablet (or you resized it)' }
* else if (wide) { return 'Your browser window is on a nice wide screen' }
* ```
*
* It's quick and easy to determine what the current screen
* width is and display accordingly.
*
* Because they are all booleans, you can also use logic
* operations like:
* ```
* const {narrow, medium} = useWidthCheck()
*
* if (narrow || medium) { return 'not wide' }
* ```
*
* ```
* const {narrow} = useWidthCheck()
*
* if (!narrow) { return 'probably not a phone' }
* ```
*
* @category Hooks
* @return {WidthCheckReturn}
*/
export function useWidthCheck() : WidthCheckReturn {
// Load responsive layout context and read current screen width
const responsiveLayout = useContext(ResponsiveLayoutContext)
const width = responsiveLayout.width
let narrow = false
let medium = false
let wide = false
// Check the width vs defined breakpoints
if (width < NARROW_UPPER_BOUND) {
narrow = true
} else if (width < MEDIUM_UPPER_BOUND && width >= NARROW_UPPER_BOUND) {
medium = true
} else if (width >= MEDIUM_UPPER_BOUND) {
wide = true
}
return {wide, medium, narrow}
}
Source