@@ -158,7 +158,6 @@ class Sheet extends Modal {
158158 let isMoved = false ;
159159 let isTopSheetModal ;
160160 let swipeStepTranslate ;
161- let breakpointsTranslate = [ ] ;
162161 let startTranslate ;
163162 let currentTranslate ;
164163 let sheetElOffsetHeight ;
@@ -170,6 +169,9 @@ class Sheet extends Modal {
170169 let sheetPageContentScrollTop ;
171170 let sheetPageContentScrollHeight ;
172171 let sheetPageContentOffsetHeight ;
172+ let breakpointsTranslate = [ ] ;
173+ let currentBreakpointIndex ;
174+ let backdropBreakpointSet = true ;
173175
174176 function handleTouchStart ( e ) {
175177 if ( isTouched || ! ( sheet . params . swipeToClose || sheet . params . swipeToStep ) || ! e . isTrusted )
@@ -259,7 +261,18 @@ class Sheet extends Modal {
259261 currentTranslate = startTranslate - touchesDiff ;
260262 currentTranslate = Math . min ( Math . max ( currentTranslate , minTranslate ) , maxTranslate ) ;
261263 e . preventDefault ( ) ;
262- if ( sheet . push && pushOffset ) {
264+ if ( useBreakpoints ) {
265+ let progress = isTopSheetModal
266+ ? 1 + currentTranslate / sheetElOffsetHeight
267+ : 1 - currentTranslate / sheetElOffsetHeight ;
268+ progress = Math . abs ( progress ) ;
269+ progress = Math . min ( Math . max ( progress , 0 ) , 1 ) ;
270+ // eslint-disable-next-line
271+ setBackdropBreakpoint ( progress ) ;
272+ // eslint-disable-next-line
273+ setPushBreakpoint ( progress ) ;
274+ }
275+ if ( sheet . push && pushOffset && ! useBreakpoints ) {
263276 let progress = ( currentTranslate - startTranslate ) / sheetElOffsetHeight ;
264277 if ( sheet . params . swipeToStep ) {
265278 if ( isTopSheetModal ) {
@@ -300,8 +313,11 @@ class Sheet extends Modal {
300313 isMoved = false ;
301314 $el . transform ( '' ) . transition ( '' ) ;
302315 if ( sheet . push && pushOffset ) {
303- $pushViewEl . transition ( '' ) . transform ( '' ) ;
304- $pushViewEl . css ( 'border-radius' , '' ) ;
316+ $pushViewEl . transition ( '' ) ;
317+ if ( ! useBreakpoints ) {
318+ $pushViewEl . transform ( '' ) ;
319+ $pushViewEl . css ( 'border-radius' , '' ) ;
320+ }
305321 }
306322
307323 const direction = touchesDiff < 0 ? 'to-bottom' : 'to-top' ;
@@ -311,7 +327,7 @@ class Sheet extends Modal {
311327
312328 const timeDiff = new Date ( ) . getTime ( ) - touchStartTime ;
313329
314- if ( ! sheet . params . swipeToStep ) {
330+ if ( ! sheet . params . swipeToStep && ! useBreakpoints ) {
315331 if ( direction !== ( isTopSheetModal ? 'to-top' : 'to-bottom' ) ) {
316332 return ;
317333 }
@@ -325,8 +341,37 @@ class Sheet extends Modal {
325341 const closeDirection = isTopSheetModal ? 'to-top' : 'to-bottom' ;
326342 const absCurrentTranslate = Math . abs ( currentTranslate ) ;
327343 const absSwipeStepTranslate = Math . abs ( swipeStepTranslate ) ;
328-
329- if ( timeDiff < 300 && diff > 10 ) {
344+ if ( timeDiff < 300 && diff > 10 && useBreakpoints ) {
345+ // SHORT SWIPES BREAKPOINTS
346+ if ( direction === openDirection && typeof currentBreakpointIndex !== 'undefined' ) {
347+ if ( currentBreakpointIndex === params . breakpoints . length - 1 ) {
348+ // open
349+ sheet . setBreakpoint ( 1 ) ;
350+ } else {
351+ // move to next breakpoint
352+ currentBreakpointIndex = Math . min (
353+ breakpointsTranslate . length - 1 ,
354+ currentBreakpointIndex + 1 ,
355+ ) ;
356+ sheet . setBreakpoint ( params . breakpoints [ currentBreakpointIndex ] ) ;
357+ }
358+ }
359+ if ( direction === closeDirection ) {
360+ if ( currentBreakpointIndex === 0 ) {
361+ // close
362+ sheet . close ( ) ;
363+ } else {
364+ // move to prev breakpoint
365+ if ( typeof currentBreakpointIndex === 'undefined' ) {
366+ currentBreakpointIndex = params . breakpoints . length - 1 ;
367+ } else {
368+ currentBreakpointIndex = Math . max ( 0 , currentBreakpointIndex - 1 ) ;
369+ }
370+ sheet . setBreakpoint ( params . breakpoints [ currentBreakpointIndex ] ) ;
371+ }
372+ }
373+ } else if ( timeDiff < 300 && diff > 10 ) {
374+ // SHORT SWIPES SWIPE STEP
330375 if ( direction === openDirection && absCurrentTranslate < absSwipeStepTranslate ) {
331376 // open step
332377 $el . removeClass ( 'modal-in-swipe-step' ) ;
@@ -373,7 +418,28 @@ class Sheet extends Modal {
373418 }
374419 return ;
375420 }
376- if ( timeDiff >= 300 ) {
421+ if ( timeDiff >= 300 && useBreakpoints ) {
422+ // LONG SWIPES BREAKPOINTS
423+ const allBreakpoints = [ sheetElOffsetHeight , ...breakpointsTranslate , 0 ] ;
424+ const closestTranslate = allBreakpoints . reduce ( ( prev , curr ) => {
425+ return Math . abs ( curr - currentTranslate ) < Math . abs ( prev - currentTranslate )
426+ ? curr
427+ : prev ;
428+ } ) ;
429+ const closestIndex = allBreakpoints . indexOf ( closestTranslate ) ;
430+ if ( closestTranslate === 0 ) {
431+ // open
432+ sheet . setBreakpoint ( 1 ) ;
433+ } else if ( closestIndex === 0 ) {
434+ // close
435+ sheet . close ( ) ;
436+ } else {
437+ // set bp
438+ currentBreakpointIndex = closestIndex - 1 ;
439+ sheet . setBreakpoint ( params . breakpoints [ currentBreakpointIndex ] ) ;
440+ }
441+ } else if ( timeDiff >= 300 ) {
442+ // LONG SWIPES SWIPE STEP
377443 const stepOpened = ! $el . hasClass ( 'modal-in-swipe-step' ) ;
378444 if ( ! stepOpened ) {
379445 if ( absCurrentTranslate < absSwipeStepTranslate / 2 ) {
@@ -422,44 +488,168 @@ class Sheet extends Modal {
422488 }
423489 }
424490
425- sheet . setSwipeStep = function setSwipeStep ( byResize = true ) {
426- const $swipeStepEl = $el . find ( '.sheet-modal-swipe-step' ) . eq ( 0 ) ;
427- if ( ! useBreakpoints && ! $swipeStepEl . length ) return ;
428- if ( useBreakpoints ) {
429- const fullSize = $el [ 0 ] . offsetHeight ;
430- breakpointsTranslate = [ ] ;
431- sheet . params . breakpoints . forEach ( ( ratio ) => {
432- breakpointsTranslate . push ( fullSize - fullSize * ratio ) ;
491+ const setPushBreakpoint = ( breakpoint ) => {
492+ const { pushBreakpoint } = params ;
493+ if (
494+ pushBreakpoint === null ||
495+ typeof pushBreakpoint === 'undefined' ||
496+ ! sheet . push ||
497+ ! pushOffset
498+ )
499+ return ;
500+ if ( breakpoint >= pushBreakpoint ) {
501+ sheet . $htmlEl
502+ . addClass ( 'with-modal-sheet-push' )
503+ . removeClass ( 'with-modal-sheet-push-closing' ) ;
504+ $pushViewEl . transition ( '' ) . forEach ( ( el ) => {
505+ el . style . setProperty (
506+ 'transform' ,
507+ `translate3d(0,0,0) scale(${ pushViewScale ( pushOffset ) } )` ,
508+ 'important' ,
509+ ) ;
433510 } ) ;
434- console . log ( breakpointsTranslate ) ;
435- $el [ 0 ] . style . setProperty ( '--f7-sheet-breakpoint' , `${ breakpointsTranslate [ 0 ] } px` ) ;
436- if ( ! byResize ) {
437- $el . addClass ( 'modal-in-breakpoint' ) ;
438- sheet . emit ( 'local::_swipeStep' , true ) ;
511+ $pushViewEl . css ( 'border-radius' , `${ pushBorderRadius * 1 } px` ) ;
512+ } else {
513+ const pushBreakpoints = [ 0 , ...params . breakpoints , 1 ] ;
514+ const pushTransparentBreakpoint =
515+ pushBreakpoints [ pushBreakpoints . indexOf ( pushBreakpoint ) - 1 ] ;
516+ if ( breakpoint <= pushTransparentBreakpoint ) {
517+ $pushViewEl . transition ( '' ) . css ( 'transform' , '' ) ;
518+ $pushViewEl . css ( 'border-radius' , '' ) ;
519+ sheet . $htmlEl . removeClass ( 'with-modal-sheet-push' ) ;
520+ if ( breakpoint === pushTransparentBreakpoint ) {
521+ sheet . $htmlEl . addClass ( 'with-modal-sheet-push-closing' ) ;
522+ }
523+ } else {
524+ const progress =
525+ ( breakpoint - pushTransparentBreakpoint ) / ( pushBreakpoint - pushTransparentBreakpoint ) ;
526+ sheet . $htmlEl
527+ . addClass ( 'with-modal-sheet-push' )
528+ . removeClass ( 'with-modal-sheet-push-closing' ) ;
529+ $pushViewEl . transition ( 0 ) . forEach ( ( el ) => {
530+ el . style . setProperty (
531+ 'transform' ,
532+ `translate3d(0,0,0) scale(${ 1 - ( 1 - pushViewScale ( pushOffset ) ) * progress } )` ,
533+ 'important' ,
534+ ) ;
535+ } ) ;
536+ $pushViewEl . css ( 'border-radius' , `${ pushBorderRadius * progress } px` ) ;
439537 }
538+ }
539+ } ;
540+ const setBackdropBreakpoint = ( breakpoint ) => {
541+ const { backdrop, backdropBreakpoint } = params ;
542+ if ( ! backdropBreakpoint || ! backdrop || ! $backdropEl . length ) return ;
543+
544+ if ( breakpoint >= backdropBreakpoint ) {
545+ if ( ! backdropBreakpointSet ) {
546+ $backdropEl . transition ( '' ) . css ( { opacity : '' , pointerEvents : '' } ) ;
547+ }
548+ backdropBreakpointSet = true ;
440549 } else {
441- // eslint-disable-next-line
442- if ( $el . hasClass ( 'sheet-modal-top' ) ) {
443- swipeStepTranslate = - (
444- $swipeStepEl . offset ( ) . top -
445- $el . offset ( ) . top +
446- $swipeStepEl [ 0 ] . offsetHeight
447- ) ;
550+ const backdropBreakpoints = [ 0 , ...params . breakpoints , 1 ] ;
551+ const backdropTransparentBreakpoint =
552+ backdropBreakpoints [ backdropBreakpoints . indexOf ( backdropBreakpoint ) - 1 ] ;
553+ if ( breakpoint <= backdropTransparentBreakpoint ) {
554+ if ( backdropBreakpointSet ) {
555+ $backdropEl . transition ( '' ) . css ( { opacity : 0 , pointerEvents : 'none' } ) ;
556+ }
557+ backdropBreakpointSet = false ;
448558 } else {
449- swipeStepTranslate =
450- $el [ 0 ] . offsetHeight -
451- ( $swipeStepEl . offset ( ) . top - $el . offset ( ) . top + $swipeStepEl [ 0 ] . offsetHeight ) ;
559+ const progress =
560+ ( breakpoint - backdropTransparentBreakpoint ) /
561+ ( backdropBreakpoint - backdropTransparentBreakpoint ) ;
562+ $backdropEl . transition ( 0 ) . css ( { opacity : progress , pointerEvents : 'auto' } ) ;
452563 }
453- $el [ 0 ] . style . setProperty ( '--f7-sheet-swipe-step' , `${ swipeStepTranslate } px` ) ;
454- if ( ! byResize ) {
455- $el . addClass ( 'modal-in-swipe-step' ) ;
456- sheet . emit ( 'local::_swipeStep' , true ) ;
564+ }
565+ } ;
566+
567+ sheet . calcBreakpoints = ( ) => {
568+ if ( ! useBreakpoints ) {
569+ return ;
570+ }
571+ const fullSize = $el [ 0 ] . offsetHeight ;
572+ // eslint-disable-next-line
573+ const isTopSheetModal = $el . hasClass ( 'sheet-modal-top' ) ;
574+ breakpointsTranslate = [ ] ;
575+ sheet . params . breakpoints . forEach ( ( ratio ) => {
576+ breakpointsTranslate . push ( ( fullSize - fullSize * ratio ) * ( isTopSheetModal ? - 1 : 1 ) ) ;
577+ } ) ;
578+ } ;
579+
580+ sheet . setBreakpoint = ( value ) => {
581+ if ( ! useBreakpoints ) {
582+ return sheet ;
583+ }
584+ if ( value === 1 ) {
585+ // open
586+ if ( ! sheet . opened ) {
587+ sheet . open ( ) ;
588+ }
589+ $el . removeClass ( 'modal-in-breakpoint' ) ;
590+ currentBreakpointIndex = undefined ;
591+ setBackdropBreakpoint ( value ) ;
592+ setPushBreakpoint ( value ) ;
593+ $el . trigger ( 'sheet:breakpoint' , value ) ;
594+ sheet . emit ( 'local::breakpoint sheetBreakpoint' , sheet , value ) ;
595+ } else if ( value === 0 ) {
596+ // close
597+ $el . trigger ( 'sheet:breakpoint' , value ) ;
598+ sheet . emit ( 'local::breakpoint sheetBreakpoint' , sheet , value ) ;
599+ sheet . close ( ) ;
600+ } else {
601+ const index = params . breakpoints . indexOf ( value ) ;
602+ if ( index < 0 ) return sheet ;
603+ if ( ! sheet . opened ) {
604+ sheet . open ( ) ;
457605 }
606+ setBackdropBreakpoint ( value ) ;
607+ setPushBreakpoint ( value ) ;
608+ $el . trigger ( 'sheet:breakpoint' , index ) ;
609+ sheet . emit ( 'local::breakpoint sheetBreakpoint' , sheet , index ) ;
610+ currentBreakpointIndex = index ;
611+ $el [ 0 ] . style . setProperty ( '--f7-sheet-breakpoint' , `${ breakpointsTranslate [ index ] } px` ) ;
612+ $el . addClass ( 'modal-in-breakpoint' ) ;
613+ }
614+ return sheet ;
615+ } ;
616+
617+ const setBreakpointsOnResize = ( ) => {
618+ sheet . calcBreakpoints ( ) ;
619+ if ( typeof currentBreakpointIndex !== 'undefined' ) {
620+ sheet . setBreakpoint ( params . breakpoints [ currentBreakpointIndex ] ) ;
621+ }
622+ } ;
623+
624+ sheet . setSwipeStep = function setSwipeStep ( byResize = true ) {
625+ const $swipeStepEl = $el . find ( '.sheet-modal-swipe-step' ) . eq ( 0 ) ;
626+ if ( ! $swipeStepEl . length ) return ;
627+
628+ // eslint-disable-next-line
629+ if ( $el . hasClass ( 'sheet-modal-top' ) ) {
630+ swipeStepTranslate = - (
631+ $swipeStepEl . offset ( ) . top -
632+ $el . offset ( ) . top +
633+ $swipeStepEl [ 0 ] . offsetHeight
634+ ) ;
635+ } else {
636+ swipeStepTranslate =
637+ $el [ 0 ] . offsetHeight -
638+ ( $swipeStepEl . offset ( ) . top - $el . offset ( ) . top + $swipeStepEl [ 0 ] . offsetHeight ) ;
639+ }
640+ $el [ 0 ] . style . setProperty ( '--f7-sheet-swipe-step' , `${ swipeStepTranslate } px` ) ;
641+ if ( ! byResize ) {
642+ $el . addClass ( 'modal-in-swipe-step' ) ;
643+ sheet . emit ( 'local::_swipeStep' , true ) ;
458644 }
459645 } ;
460646
461647 function onResize ( ) {
462- sheet . setSwipeStep ( true ) ;
648+ if ( useBreakpoints ) {
649+ setBreakpointsOnResize ( ) ;
650+ } else {
651+ sheet . setSwipeStep ( true ) ;
652+ }
463653 }
464654
465655 const passive = support . passiveListener ? { passive : true } : false ;
@@ -479,10 +669,8 @@ class Sheet extends Modal {
479669 $ ( document ) . on ( 'keydown' , onKeyDown ) ;
480670 }
481671 $el . prevAll ( '.popup.modal-in' ) . addClass ( 'popup-behind' ) ;
482- if ( sheet . params . swipeToStep || useBreakpoints ) {
483- sheet . setSwipeStep ( false ) ;
484- app . on ( 'resize' , onResize ) ;
485- }
672+
673+ app . on ( 'resize' , onResize ) ;
486674 if ( sheet . params . scrollToEl ) {
487675 scrollToElementOnOpen ( ) ;
488676 }
@@ -493,7 +681,9 @@ class Sheet extends Modal {
493681 if ( ! pushOffset ) pushOffset = app . theme === 'ios' ? 44 : 48 ;
494682 sheet . $htmlEl [ 0 ] . style . setProperty ( '--f7-sheet-push-offset' , `${ pushOffset } px` ) ;
495683 $el . addClass ( 'sheet-modal-push' ) ;
496- sheet . $htmlEl . addClass ( 'with-modal-sheet-push' ) ;
684+ if ( ! useBreakpoints ) {
685+ sheet . $htmlEl . addClass ( 'with-modal-sheet-push' ) ;
686+ }
497687 if ( ! sheet . params . swipeToStep && ! useBreakpoints ) {
498688 sheet . $htmlEl [ 0 ] . style . setProperty ( '--f7-sheet-push-scale' , pushViewScale ( pushOffset ) ) ;
499689 } else {
@@ -504,13 +694,21 @@ class Sheet extends Modal {
504694 $pushViewEl . css ( 'border-radius' , '0px' ) ;
505695 }
506696 }
697+
698+ if ( useBreakpoints ) {
699+ sheet . calcBreakpoints ( ) ;
700+ sheet . setBreakpoint ( params . breakpoints [ 0 ] ) ;
701+ } else if ( sheet . params . swipeToStep ) {
702+ sheet . setSwipeStep ( false ) ;
703+ }
507704 } ) ;
508705 sheet . on ( 'opened' , ( ) => {
509706 if ( sheet . params . closeByOutsideClick || sheet . params . closeByBackdropClick ) {
510707 app . on ( 'click' , handleClick ) ;
511708 }
512709 } ) ;
513710 sheet . on ( 'close' , ( ) => {
711+ currentBreakpointIndex = undefined ;
514712 if ( sheet . params . swipeToStep || useBreakpoints ) {
515713 $el . removeClass ( 'modal-in-swipe-step modal-in-breakpoint' ) ;
516714 sheet . emit ( 'local::_swipeStep' , false ) ;
@@ -529,6 +727,8 @@ class Sheet extends Modal {
529727 if ( sheet . push && pushOffset ) {
530728 sheet . $htmlEl . removeClass ( 'with-modal-sheet-push' ) ;
531729 sheet . $htmlEl . addClass ( 'with-modal-sheet-push-closing' ) ;
730+ $pushViewEl . transform ( '' ) ;
731+ $pushViewEl . css ( 'border-radius' , '' ) ;
532732 }
533733 } ) ;
534734 sheet . on ( 'closed' , ( ) => {
0 commit comments