import { Rect , Transform } from '../../types/utils' ; import { isInBody } from '../../utils/isInBody' ; import { canIUseAnimation } from '../../utils/env' ; import { State } from '../../types/store' ; import { objectKeys } from '../../utils/objectKeys' ; import { has } from '../../utils/typeOf' ; function transform ( offset ) { offset = offset + 'px' ; return { top : `translate(0,calc(-100% - ${ offset }))` , left : `translate(calc(-100% - ${ offset }),0)` , bottom : `translate(0,${ offset })` , right : `translate(${ offset },0)` , } ; } const animations = [ 'hidden 0.3s' , 'show 0.3s' ] ; const sheetRule = [ ( orn ) => `@keyframes hidden { 0% {opacity: 1;transform: ${ orn } scaleY(1);} 100% {opacity: 0;visibility: hidden;transform: ${ orn } scaleY(.8);} }` , ( orn ) => `@keyframes show { 0% {display: block;opacity: 0;transform:scaleY(.8) ${ orn };} 100% {display: block;opacity: 1;transform: scaleY(1) ${ orn };} }` , ] ; function deleteRules ( sheet = document . styleSheets [ 0 ] ) { const ruleSheet = sheet . rules ; if ( ruleSheet && ruleSheet . length > 0 ) { for ( let i = 1 ; i >= 0 ; i -- ) { if ( ! ruleSheet [ i ] ) return ; const { name , type } = ruleSheet [ i ] ; if ( has ( [ 'show' , 'hidden' ] , name ) && type === 7 ) { sheet . deleteRule ( i ) ; } } } } function getPosition ( { top , left , height , width } , offset ) { const _tTop = top + window . scrollY - offset ; const _bTop = top + height + window . scrollY + offset ; const _tLeft = left + window . scrollX ; const _rLeft = left + width + window . scrollX ; return { top : { top : _tTop , left : _tLeft } , left : { top : _tTop , left : _tLeft } , bottom : { top : _bTop , left : _rLeft - width } , right : { top : _tTop , left : _rLeft } , } ; } function resetRangStatus ( self ) { const { range , start , end } = self ; range . status = 'complete' ; if ( start . date && start . date ) { range . start = start . date ; range . end = end . date ; } else { range . start = range . end = null ; } } export function updatePicker ( ) { const { visible , popover } = this ; if ( ! popover ) return ; if ( visible ) { popover . style . display = '' ; setPopoverLocation . call ( this ) ; } const ss = document . styleSheets [ 0 ] ; const animation = animations [ Number ( visible ) ] ; if ( canIUseAnimation ( ) ) { deleteRules ( ) ; sheetRule . forEach ( ( r , idx ) => ss . insertRule ( r ( popover . style . transform ) , idx ) ) ; popover . style . animation = animation ; } else { popover . style . display = visible ? '' : 'none' ; } resetRangStatus ( this ) ; } export function setPopoverLocation ( ) { if ( ! this . visible ) return ; function setTransform ( ) { popover . style . transform = transform ( offset ) [ placement as 'left' ] ; } function setPosition ( ) { const position = getPosition ( rect , offset ) ; Array . from ( [ 'left' , 'top' ] as const ) . forEach ( ( attr ) => ( popover . style [ attr ] = position [ placement as 'left' ] [ attr ] + 'px' ) ) ; } function fixReferencePosition ( ) { const { parentNode } = reference ; if ( parentNode && parentNode . style ) parentNode . style . position = 'relative' ; } function setCloseToReference ( ) { const { offsetWidth , offsetHeight } = reference ; const x = offsetWidth + offset + 'px' ; const transform = { bottom : { top : offsetHeight + offset + 'px' , left : 0 , } , top : { top : `calc(-100% - ${ offset }px)` , left : 0 , } , left : { top : 0 , right : x + offset , } , right : { top : 0 , left : x + offset , } , } ; const tp = transform [ placement as 'top' ] ; objectKeys ( tp ) . forEach ( ( key ) => ( popover . style [ key ] = tp [ key ] ) ) ; } const { popover , reference , offset , placement } = this ; const rect = reference . getBoundingClientRect ( ) ; const popInBody = isInBody ( popover ) ; if ( popInBody ) { setPosition ( ) ; setTransform ( ) ; } else { setCloseToReference ( ) ; fixReferencePosition ( ) ; } }