import { useEffect } from "react" ; import isPlainObject from "lodash/isPlainObject" ; export interface ViewportAttr { width : "device-width" | number | string ; height : "device-height" | number | string ; maximumScale : number ; minimumScale : number ; userScalable : "yes" | "no" ; initialScale : number ; viewportFit : "cover" | "contain" | "auto" ; } export const metaContent = { param content returns parse ( content ) { content = content . replace ( /\s+|,$/g , "" ) ; if ( ! content ) return { } ; const parts = content . split ( "," ) ; const output = { } ; for ( let part of parts ) { const arr = part . split ( "=" ) ; output [ arr [ 0 ] ] = arr [ 1 ] ; } return output ; } , param data returns stringify ( data ) { const parts = [ ] ; for ( let key in data ) { const part = `${ key }=${ data [ key ] }` ; parts . push ( part ) ; } return parts . join ( ", " ) ; } , } ; export function useViewport ( attr ? ) { let config = { width : "device-width" , initialScale : 1 , userScalable : "no" , viewportFit : "cover" , } ; if ( isPlainObject ( attr ) ) { config = { ... config , ... attr } ; } useEffect ( ( ) => { let meta = document . querySelector ( "meta[name='viewport']" ) ; if ( ! meta ) { meta = document . createElement ( "meta" ) ; meta . name = "viewport" ; document . head . prepend ( meta ) ; } const content = metaContent . parse ( meta . content || "" ) ; if ( config . width ) { content . width = config . width ; } if ( config . height ) { content . height = config . height ; } if ( config . maximumScale ) { content [ "maximum-scale" ] = config . maximumScale ; } if ( config . minimumScale ) { content [ "minimum-scale" ] = config . minimumScale ; } if ( config . initialScale ) { content [ "initial-scale" ] = config . initialScale ; } if ( config . userScalable ) { content [ "user-scalable" ] = config . userScalable ; } if ( config . viewportFit ) { content [ "viewport-fit" ] = config . viewportFit ; } meta . content = metaContent . stringify ( content ) ; } , [ config . width , config . height , config . initialScale , config . maximumScale , config . minimumScale , config . userScalable , config . viewportFit , ] ) ; }