ihealth-kit-registration/src/components/Breakpoint/useBreakpoint.ts
2023-04-22 23:00:38 +08:00

82 lines
2.2 KiB
TypeScript

import { useContext } from 'react';
import { BreakpointContext } from './BreakpointProvider'
import { uaParser } from '../../utils/uaParser'
export interface DeviceType {
mobile?: boolean;
tablet?: boolean;
desktop?: boolean;
}
export interface OrientationType {
landscape?: boolean
portrait?: boolean
}
export interface Breakpoints {
xs?: boolean
s?: boolean
m?: boolean
l?: boolean
xl?: boolean
// greater than the width
up?: boolean
// less than the width
down?: boolean
width?: {
min?: number
max?: number
}
}
export type BreakpointProps = DeviceType & Breakpoints & OrientationType
const deviceType = ['mobile', 'tablet', 'desktop']
const currentDeviceType = ['mobile', 'tablet'].includes(uaParser.device.model || '') ? uaParser.device.model : 'desktop'
function matchWidth(width: number, min?: number, max?: number): boolean {
if (typeof min === 'number' && typeof max === 'number') {
return width >= min && width <= max
}
if (typeof min === 'number') {
return width >= min
}
if (typeof max === 'number') {
return width <= max
}
return false
}
export const useBreakpoint = (props: BreakpointProps): boolean => {
const { breakpointList, size: { orientation, ...size } } = useContext(BreakpointContext)
let enabled: boolean
const allKeys = Object.keys(props)
const keysWithoutDeviceType = allKeys.filter(key => !deviceType.includes(key))
const keysWithDeviceType = allKeys.filter(key => deviceType.includes(key))
enabled = keysWithoutDeviceType.every(key => {
if (typeof breakpointList[key as keyof typeof breakpointList] === 'number' && !props.width) {
if (props.up) {
return size.width > breakpointList[key as keyof typeof breakpointList]
}
if (props.down) {
return size.width <= breakpointList[key as keyof typeof breakpointList]
}
return size.width === breakpointList[key as keyof typeof breakpointList]
}
if (key === 'width') {
return matchWidth(3000, props.width?.min, props.width?.max)
}
if (key === 'landscape' || key === 'portrait') {
return key === orientation
}
return true
}) && (keysWithDeviceType.length ? keysWithDeviceType.some(key => currentDeviceType === key) : true)
return enabled
}