cupertino-pane
Advanced tools
Comparing version
@@ -5,2 +5,78 @@ | ||
## [1.2.6] - 2021-03-18 | ||
### BREAKING CHANGES | ||
- All Z-Stack and 3D Push properties was merged into `zStack` object. [Readme](https://github.com/roman-rr/cupertino-pane/blob/master/README.md#z-stack) | ||
```js | ||
let settings = { | ||
... | ||
zStack: { | ||
pushElements: string[]; | ||
minPushHeight?: number; | ||
cardYOffset?: number; | ||
cardZScale?: number; | ||
cardContrast?: number; | ||
stackZAngle?: number; | ||
} | ||
} | ||
``` | ||
### Extra | ||
- [Advanced Z-stack available](https://output.jsbin.com/benidub) | ||
### Features | ||
- 3D Push transitions and gestures now available as cumulative options with `pushElements` property. Define array of elements which will be pushed when main element execute transitions. All styles from all elements will be accumulated together. | ||
```js | ||
let settings = { | ||
... | ||
zStack: { | ||
pushElements: ['.card-1', '.card-2', '.card-3'] | ||
} | ||
} | ||
``` | ||
### Bug Fixes | ||
- Click to elements fixed with `.disableDrag()` method [#140](https://github.com/roman-rr/cupertino-pane/issues/140) | ||
- Fixed css variable `--cupertino-pane-icon-close-color` [#139](https://github.com/roman-rr/cupertino-pane/issues/139) | ||
- Fixed pane jump on drag with positive scroll from lower breakpoints [#135](https://github.com/roman-rr/cupertino-pane/issues/135) | ||
## [1.2.5] - 2021-02-20 | ||
### BREAKING CHANGES | ||
- Added `cssClass` property to settings. Pass custom class for `.cupertino-pane-wrapper` here to style later, instead of picking custom class from your element. | ||
- Removed `darkmode` property and `setDarkmode()` method. Proper way you can style darkmode with variables: | ||
```css | ||
body.dark { | ||
--cupertino-pane-icon-close-color: #a8a7ae; | ||
--cupertino-pane-background: #1c1c1d; | ||
--cupertino-pane-color: #ffffff; | ||
--cupertino-pane-shadow: 0 4px 16px rgb(0 0 0 / 12%); | ||
--cupertino-pane-border-radius: 20px; | ||
--cupertino-pane-move-background: #424246; | ||
--cupertino-pane-destroy-button-background: #424246; | ||
} | ||
``` | ||
### Extra | ||
- 3 Panes live environment [demo available](https://jsbin.com/xavifaf) | ||
### Features | ||
- CSS variables available [Readme](https://github.com/roman-rr/cupertino-pane/blob/master/README.md#css-variables) | ||
### Bug Fixes | ||
- Fixed styles for few panes in single DOM [#133](https://github.com/roman-rr/cupertino-pane/issues/133) | ||
- Fixed with internal styles injector in DOM. Minified styles now injected once inside `<head>` tag. | ||
- Fixed backdrop with `{ animate:false }` | ||
## [1.2.4] - 2021-01-28 | ||
### Enhancements | ||
- Keyboard will move pane up, only if focused element is child of Pane | ||
- `window.resize` events are now automatically managed [#127](https://github.com/roman-rr/cupertino-pane/issues/127) | ||
### Bug Fixes | ||
- Fixed `currentBreak()` method | ||
- Fixed and improved keyboard events [#125](https://github.com/roman-rr/cupertino-pane/issues/125) | ||
## [1.2.3] - 2021-01-22 | ||
@@ -7,0 +83,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { PaneSettings, PaneBreaks } from './models'; | ||
import { PaneSettings, PaneBreaks, ZStackSettings } from './models'; | ||
export declare type CupertinoSettings = Partial<PaneSettings>; | ||
@@ -10,3 +10,2 @@ export declare class CupertinoPane { | ||
preventedDismiss: boolean; | ||
private iconCloseColor; | ||
rendered: boolean; | ||
@@ -18,9 +17,8 @@ wrapperEl: HTMLDivElement; | ||
contentEl: HTMLElement; | ||
private parentEl; | ||
parentEl: HTMLElement; | ||
backdropEl: HTMLDivElement; | ||
private draggableEl; | ||
private moveEl; | ||
private backdropEl; | ||
private destroyButtonEl; | ||
private followerEl; | ||
private pushElement; | ||
private settings; | ||
@@ -30,2 +28,3 @@ private device; | ||
private breakpoints; | ||
private zStackDefaults; | ||
constructor(selector: (string | HTMLElement), conf?: CupertinoSettings); | ||
@@ -37,12 +36,5 @@ private drawBaseElements; | ||
getPaneHeight(): number; | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private attachAllEvents; | ||
private detachAllEvents; | ||
private resetEvents; | ||
updateScreenHeights(): void; | ||
scrollElementInit(): void; | ||
setOverflowHeight(offset?: number): void; | ||
private getTimingFunction; | ||
checkOpacityAttr(val: any): void; | ||
@@ -52,9 +44,17 @@ checkOverflowAttr(val: any): void; | ||
swipeNextPoint: (diff: any, maxDiff: any, closest: any) => any; | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private getTimingFunction; | ||
private isBackdropPresented; | ||
private renderBackdrop; | ||
/** | ||
* Utility function to add CSS in multiple passes. | ||
* Utility function to add minified internal CSS to head. | ||
* @param {string} styleString | ||
*/ | ||
private addStyle; | ||
private setPushMultiplicators; | ||
private clearPushMultiplicators; | ||
private getPushMulitplicator; | ||
setZstackConfig(zStack: ZStackSettings): void; | ||
/** | ||
@@ -66,8 +66,2 @@ * Backdrop | ||
}): any; | ||
/************************************ | ||
* Events | ||
*/ | ||
private touchEvents; | ||
private attachEvents; | ||
private detachEvents; | ||
getPanelTransformY(): number; | ||
@@ -89,5 +83,2 @@ /************************************ | ||
enableDrag(): void; | ||
setDarkMode(conf?: { | ||
enable: boolean; | ||
}): void; | ||
/** | ||
@@ -98,3 +89,3 @@ * Public user method to reset breakpoints | ||
setBreakpoints(conf?: PaneBreaks): Promise<void>; | ||
calcFitHeight(): Promise<void>; | ||
calcFitHeight(): Promise<any>; | ||
moveToBreak(val: string): any; | ||
@@ -101,0 +92,0 @@ moveToHeight(val: number): any; |
/** | ||
* Cupertino Pane 1.2.32 | ||
* Multiplatform slide-over pane | ||
* Cupertino Pane 1.2.61 | ||
* Multi-functional panes and boards for next generation progressive applications | ||
* https://github.com/roman-rr/cupertino-pane/ | ||
@@ -10,3 +10,3 @@ * | ||
* | ||
* Released on: January 24, 2021 | ||
* Released on: March 30, 2021 | ||
*/ | ||
@@ -29,3 +29,3 @@ | ||
***************************************************************************** */ | ||
function __awaiter(t,e,s,i){return new(s||(s=Promise))((function(n,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof s?e:new s((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}Object.defineProperty(exports,"__esModule",{value:!0});class Support{static get touch(){return window.Modernizr&&!0===window.Modernizr.touch||!!(window.navigator.maxTouchPoints>0||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch)}static get observer(){return"MutationObserver"in window||"WebkitMutationObserver"in window}static get backdropFilter(){return CSS.supports("backdrop-filter","blur(0px)")||CSS.supports("-webkit-backdrop-filter","blur(0px)")}static get passiveListener(){let t=!1;try{const e=Object.defineProperty({},"passive",{get(){t=!0}});window.addEventListener("testPassiveListener",null,e)}catch(t){}return t}static get gestures(){return"ongesturestart"in window}static get pointerEvents(){return!!window.PointerEvent&&"maxTouchPoints"in window.navigator&&window.navigator.maxTouchPoints>0}}class Device{constructor(){this.ios=!1,this.android=!1,this.androidChrome=!1,this.desktop=!1,this.iphone=!1,this.ipod=!1,this.ipad=!1,this.edge=!1,this.ie=!1,this.firefox=!1,this.macos=!1,this.windows=!1,this.cordova=!(!window.cordova&&!window.phonegap),this.phonegap=!(!window.cordova&&!window.phonegap),this.electron=!1,this.ionic=!!document.querySelector("ion-app");const t=window.navigator.platform,e=window.navigator.userAgent,s=window.screen.width,i=window.screen.height;let n=e.match(/(Android);?[\s\/]+([\d.]+)?/),o=e.match(/(iPad).*OS\s([\d_]+)/),r=e.match(/(iPod)(.*OS\s([\d_]+))?/),a=!this.ipad&&e.match(/(iPhone\sOS|iOS)\s([\d_]+)/),h=e.indexOf("MSIE ")>=0||e.indexOf("Trident/")>=0,l=e.indexOf("Edge/")>=0,p=e.indexOf("Gecko/")>=0&&e.indexOf("Firefox/")>=0,d="Win32"===t,c=e.toLowerCase().indexOf("electron")>=0,u="MacIntel"===t;!o&&u&&Support.touch&&(1024===s&&1366===i||834===s&&1194===i||834===s&&1112===i||768===s&&1024===i)&&(o=e.match(/(Version)\/([\d.]+)/),u=!1),this.ie=h,this.edge=l,this.firefox=p,n&&!d&&(this.os="android",this.osVersion=n[2],this.android=!0,this.androidChrome=e.toLowerCase().indexOf("chrome")>=0),(o||a||r)&&(this.os="ios",this.ios=!0),a&&!r&&(this.osVersion=a[2].replace(/_/g,"."),this.iphone=!0),o&&(this.osVersion=o[2].replace(/_/g,"."),this.ipad=!0),r&&(this.osVersion=r[3]?r[3].replace(/_/g,"."):null,this.ipod=!0),this.ios&&this.osVersion&&e.indexOf("Version/")>=0&&"10"===this.osVersion.split(".")[0]&&(this.osVersion=e.toLowerCase().split("version/")[1].split(" ")[0]),this.webView=!(!(a||o||r)||!e.match(/.*AppleWebKit(?!.*Safari)/i)&&!window.navigator.standalone)||window.matchMedia&&window.matchMedia("(display-mode: standalone)").matches,this.webview=this.webView,this.standalone=this.webView,this.desktop=!(this.ios||this.android)||c,this.desktop&&(this.electron=c,this.macos=u,this.windows=d,this.macos&&(this.os="macos"),this.windows&&(this.os="windows")),this.pixelRatio=window.devicePixelRatio||1}}class Events{constructor(t,e,s,i){this.instance=t,this.settings=e,this.device=s,this.breakpoints=i,this.allowClick=!0,this.disableDragAngle=!1,this.pointerDown=!1,this.contentScrollTop=0,this.steps=[],this.inputBlured=!1,this.touchStartCb=t=>this.touchStart(t),this.touchMoveBackdropCb=t=>this.touchMoveBackdrop(t),this.touchMoveCb=t=>this.touchMove(t),this.touchEndCb=t=>this.touchEnd(t),this.onClickCb=t=>this.onClick(t),this.onKeyboardShowCb=t=>this.onKeyboardShow(t),this.onKeyboardHideCb=t=>this.onKeyboardHide(t),this.onOrientationChangeCb=t=>this.onOrientationChange(t)}touchStart(t){if(this.settings.onDragStart(t),this.instance.disableDragEvents)return;this.allowClick=!0,this.disableDragAngle=!1,this.instance.preventedDismiss=!1;const e="touchstart"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]),s="touchstart"===t.type?e.clientY:t.clientY,i="touchstart"===t.type?e.clientX:t.clientX;"mousedown"===t.type&&(this.pointerDown=!0),this.startY=s,this.startX=i,this.isDragScrollabe(t.path||t.composedPath())&&(this.startY+=this.contentScrollTop),this.steps.push(this.startY)}touchMoveBackdrop(t){this.settings.touchMoveStopPropagation&&t.stopPropagation()}touchMove(t){if(this.settings.onDrag(t),this.instance.disableDragEvents)return;if(this.disableDragAngle)return;if(this.instance.preventedDismiss)return;this.settings.touchMoveStopPropagation&&t.stopPropagation();const e="touchmove"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]),s="touchmove"===t.type?e.clientY:t.clientY,i="touchmove"===t.type?e.clientX:t.clientX;if("mousemove"===t.type&&!this.pointerDown)return;let n=s,o=i;const r=n-this.steps[this.steps.length-1];let a=this.instance.getPanelTransformY()+r;if(!this.isFormElement(t.target)||!this.isElementScrollable(t.target)){if(this.steps.length>2&&this.isFormElement(document.activeElement)&&!this.isFormElement(t.target)&&(document.activeElement.blur(),this.inputBlured=!0),this.settings.touchAngle){let t;const e=o-this.startX,s=n-this.startY;if(t=180*Math.atan2(Math.abs(s),Math.abs(e))/Math.PI,e*e+s*s>=25&&90-t>this.settings.touchAngle&&1===this.steps.length)return void(this.disableDragAngle=!0)}if(this.isDragScrollabe(t.path||t.composedPath())&&"auto"===this.instance.overflowEl.style.overflowY){if(this.instance.overflowEl.addEventListener("scroll",t=>{this.contentScrollTop=t.target.scrollTop}),this.settings.inverse&&this.willScrolled(t))return void(this.contentScrollTop=0);if(a>this.breakpoints.topper&&this.contentScrollTop>0||a<=this.breakpoints.topper)return}if(!this.settings.inverse&&!this.settings.upperThanTop&&a<=this.breakpoints.topper)this.instance.paneEl.style.transform=`translateY(${this.breakpoints.topper}px) translateZ(0px)`;else{if(a<=this.breakpoints.topper&&this.settings.upperThanTop){const t=(-this.breakpoints.topper+this.breakpoints.topper-this.instance.getPanelTransformY())/this.breakpoints.topper/-8;a=this.instance.getPanelTransformY()+r*t}if((!this.settings.lowerThanBottom||this.settings.inverse)&&a>=this.breakpoints.bottomer)return this.instance.paneEl.style.transform=`translateY(${this.breakpoints.bottomer}px) translateZ(0px)`,void this.instance.checkOpacityAttr(a);if(!this.instance.preventedDismiss&&this.instance.preventDismissEvent&&this.settings.bottomClose){let e=(-this.breakpoints.topper+this.breakpoints.topper-this.instance.getPanelTransformY())/this.breakpoints.topper/-8;if(a=this.instance.getPanelTransformY()+r*(.5-e),-1*(t.touches[0].screenY-220-this.instance.screen_height)<=this.instance.screen_height-this.breakpoints.bottomer)return this.instance.preventedDismiss=!0,this.settings.onWillDismiss({prevented:!0}),void this.instance.moveToBreak(this.breakpoints.prevBreakpoint)}this.allowClick=!1,this.instance.checkOpacityAttr(a),this.instance.checkOverflowAttr(a),this.instance.doTransition({type:"move",translateY:a}),this.steps.push(n)}}}touchEnd(t){if(this.instance.disableDragEvents)return;const e="touchmove"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]);"touchmove"===t.type?e.clientY:t.clientY;"mouseup"===t.type&&(this.pointerDown=!1);let s=this.breakpoints.getClosestBreakY();const i=this.steps[this.steps.length-1]-this.steps[this.steps.length-2],n=window.hasOwnProperty("cordova")?this.settings.fastSwipeSensivity+1:this.settings.fastSwipeSensivity;if(Math.abs(i)>=n&&(s=this.instance.swipeNextPoint(i,n,s),this.settings.fastSwipeClose&&this.breakpoints.currentBreakpoint<s))return void this.instance.destroy({animate:!0});let o=!1;this.isFormElement(document.activeElement)&&!this.isFormElement(t.target)&&2===this.steps.length&&(o=!0),this.steps=[],this.breakpoints.currentBreakpoint=s,this.settings.onDragEnd(t),isNaN(i)||o||(this.instance.checkOpacityAttr(this.breakpoints.currentBreakpoint),this.instance.checkOverflowAttr(this.breakpoints.currentBreakpoint),this.settings.bottomClose&&s===this.breakpoints.breaks.bottom?this.instance.destroy({animate:!0}):(this.instance.getPanelTransformY()===s&&this.settings.onTransitionEnd({target:this.instance.paneEl}),this.instance.doTransition({type:"end",translateY:s})))}onClick(t){if(this.allowClick){if(this.settings.clickBottomOpen&&this.breakpoints.breaks.bottom===this.instance.getPanelTransformY()){let t;this.settings.breaks.top.enabled&&(t="top"),this.settings.breaks.middle.enabled&&(t="middle"),this.instance.moveToBreak(t)}}else this.settings.preventClicks&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())}onKeyboardShow(t){if(this.instance.paneEl&&0===this.instance.paneEl.offsetWidth&&0===this.instance.paneEl.offsetHeight)return;this.device.android&&setTimeout(()=>this.fixAndroidResize(),20),this.breakpoints.prevBreakpoint=Object.entries(this.breakpoints.breaks).find(t=>t[1]===this.instance.getPanelTransformY())[0];let e=this.settings.breaks[this.instance.currentBreak()].height+t.keyboardHeight;if(this.instance.screen_height<e){this.instance.screen_height;e=this.instance.screen_height-47.25,this.instance.setOverflowHeight(t.keyboardHeight),this.instance.moveToBreak(this.settings.breaks.top.enabled?"top":"middle")}else this.instance.setOverflowHeight(t.keyboardHeight),this.instance.moveToHeight(e),setTimeout(()=>this.instance.overflowEl.scrollTop=document.activeElement.offsetTop)}onKeyboardHide(t){this.instance.paneEl&&0===this.instance.paneEl.offsetWidth&&0===this.instance.paneEl.offsetHeight||(this.device.android&&this.fixAndroidResize(),this.inputBlured?this.inputBlured=!1:this.instance.isHidden()||this.instance.moveToBreak(this.breakpoints.prevBreakpoint),setTimeout(()=>this.instance.setOverflowHeight()))}onOrientationChange(t){return __awaiter(this,void 0,void 0,(function*(){yield new Promise(t=>setTimeout(()=>t(!0),150)),this.instance.updateScreenHeights(),this.breakpoints.buildBreakpoints(JSON.parse(this.breakpoints.lockedBreakpoints),!1)}))}fixAndroidResize(){if(!this.instance.paneEl)return;document.querySelector("ion-app");window.requestAnimationFrame(()=>{this.instance.wrapperEl.style.width="100%",this.instance.paneEl.style.position="absolute",window.requestAnimationFrame(()=>{this.instance.wrapperEl.style.width="unset",this.instance.paneEl.style.position="fixed"})})}isDragScrollabe(t){return!!t.find(t=>t===this.instance.overflowEl)}willScrolled(t){return!(!this.isElementScrollable(this.instance.overflowEl)||"hidden"===this.instance.overflowEl.style.overflow||!this.isDragScrollabe(t.path||t.composedPath()))}isFormElement(t){return!!(t&&t.tagName&&["input","select","option","textarea","button","label"].includes(t.tagName.toLowerCase()))}isElementScrollable(t){return t.scrollHeight>t.clientHeight}}class Settings{constructor(){this.instance={initialBreak:"middle",inverse:!1,parentElement:null,followerElement:null,fitHeight:!1,maxFitHeight:null,fitScreenHeight:!0,pushElement:null,pushMinHeight:null,pushYOffset:0,backdrop:!1,backdropOpacity:.4,animationType:"ease",animationDuration:300,dragBy:null,bottomOffset:0,darkMode:!1,bottomClose:!1,fastSwipeClose:!1,fastSwipeSensivity:3,freeMode:!1,buttonDestroy:!0,buttonClose:!0,topperOverflow:!0,topperOverflowOffset:0,lowerThanBottom:!0,upperThanTop:!1,showDraggable:!0,draggableOver:!1,clickBottomOpen:!0,preventClicks:!0,handleKeyboard:!0,simulateTouch:!0,passiveListeners:!0,touchMoveStopPropagation:!1,touchAngle:null,breaks:{},onDidDismiss:()=>{},onWillDismiss:()=>{},onDidPresent:()=>{},onWillPresent:()=>{},onDragStart:()=>{},onDrag:()=>{},onDragEnd:()=>{},onBackdropTap:()=>{},onTransitionStart:()=>{},onTransitionEnd:()=>{}}}}class Breakpoints{constructor(t,e){this.instance=t,this.settings=e,this.breaks={},this.calcHeightInProcess=!1,this.brs=[],this.defaultBreaksConf={top:{enabled:!0,height:window.innerHeight-47.25},middle:{enabled:!0,height:300},bottom:{enabled:!0,height:100}}}buildBreakpoints(t,e=!0){var s,i;return __awaiter(this,void 0,void 0,(function*(){if(this.breaks={top:this.instance.screenHeightOffset,middle:this.instance.screenHeightOffset,bottom:this.instance.screenHeightOffset},this.settings.fitHeight){this.settings.fitScreenHeight=!1,this.settings.initialBreak="top",this.settings.topperOverflow=!1;let e=yield this.getPaneFitHeight();this.settings.maxFitHeight&&e>this.settings.maxFitHeight&&(e=this.settings.maxFitHeight,this.settings.topperOverflow=!0),t={top:{enabled:!0,height:e},middle:{enabled:!1},bottom:{enabled:!1}}}if(["top","middle","bottom"].forEach(e=>{var s,i;this.breaks[e]-=this.settings.bottomOffset,this.settings.breaks[e]||(this.settings.breaks[e]=this.defaultBreaksConf[e]),t&&t[e]&&(this.settings.breaks[e]=t[e]),this.settings.fitScreenHeight&&((null===(s=this.settings.breaks[e])||void 0===s?void 0:s.height)>this.instance.screen_height&&(this.settings.breaks[e].height=this.instance.screen_height-this.settings.bottomOffset),this.settings.breaks.top&&this.settings.breaks.middle&&this.settings.breaks.top.height===(null===(i=this.settings.breaks.middle)||void 0===i?void 0:i.height)&&(this.settings.breaks.middle.enabled=!1,this.settings.initialBreak="top")),this.settings.fitHeight&&"top"===e&&(this.settings.breaks[e].height>this.instance.screen_height?(this.settings.breaks[e].height=this.instance.screen_height-2*this.settings.bottomOffset,this.settings.topperOverflow=!0):this.instance.overflowEl&&!this.settings.maxFitHeight&&(this.settings.topperOverflow=!1,this.instance.overflowEl.style.overflowY="hidden")),this.settings.breaks[e]&&this.settings.breaks[e].enabled&&this.settings.breaks[e].height&&(this.settings.inverse?this.breaks[e]=this.settings.breaks[e].height:this.breaks[e]-=this.settings.breaks[e].height)}),e&&(this.lockedBreakpoints=JSON.stringify(this.settings.breaks)),this.instance.isPanePresented()||this.settings.breaks[this.settings.initialBreak].enabled||console.warn("Cupertino Pane: Please set initialBreak for enabled breakpoint"),this.settings.breaks.middle.height>=this.settings.breaks.top.height&&console.warn("Cupertino Pane: Please set middle height lower than top height"),this.settings.breaks.middle.height<=this.settings.breaks.bottom.height&&console.warn("Cupertino Pane: Please set bottom height lower than middle height"),this.brs=[],["top","middle","bottom"].forEach(t=>{this.settings.breaks[t].enabled&&this.brs.push(this.breaks[t])}),this.topper=this.brs.reduce((t,e)=>e<t?e:t),this.bottomer=this.brs.reduce((t,e)=>Math.abs(e)>Math.abs(t)?e:t),this.instance.isPanePresented()||(this.currentBreakpoint=this.breaks[this.settings.initialBreak]),this.instance.isPanePresented()){if((null===(s=this.settings.breaks[this.prevBreakpoint])||void 0===s?void 0:s.enabled)&&this.instance.moveToBreak(this.prevBreakpoint),!(null===(i=this.settings.breaks[this.prevBreakpoint])||void 0===i?void 0:i.enabled)){let t=this.instance.swipeNextPoint(1,1,this.getClosestBreakY());const e=Object.entries(this.breaks).find(e=>e[1]===t);this.instance.moveToBreak(e[0])}this.instance.paneEl.style.top=this.settings.inverse?`-${this.bottomer}px`:"unset",this.instance.paneEl.style.height=this.instance.getPaneHeight()+"px",this.instance.scrollElementInit(),this.instance.checkOpacityAttr(this.currentBreakpoint),this.instance.checkOverflowAttr(this.currentBreakpoint)}}))}getCurrentBreakName(){return this.breaks.top===this.currentBreakpoint?"top":this.breaks.middle===this.currentBreakpoint?"middle":this.breaks.bottom===this.currentBreakpoint?"bottom":null}getPaneFitHeight(){return __awaiter(this,void 0,void 0,(function*(){this.calcHeightInProcess=!0;let t,e=this.instance.el.querySelectorAll("img");this.instance.el.style.height="unset",this.instance.rendered||(this.instance.el.style.visibility="hidden",this.instance.el.style.pointerEvents="none",this.instance.el.style.display="block",this.instance.wrapperEl.style.visibility="hidden",this.instance.wrapperEl.style.pointerEvents="none",this.instance.wrapperEl.style.display="block");let s=[];return e.length&&(s=Array.from(e).map(t=>new Promise(e=>{t.complete&&t.naturalHeight?e(!0):t.onload=()=>e(!0)}))),s.push(new Promise(t=>setTimeout(()=>t(!0),this.instance.rendered?0:150))),yield Promise.all(s),t=parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("height"))+(parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("margin-top"))+parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("margin-bottom"))),t+=this.instance.el.offsetTop,this.instance.rendered||(this.instance.el.style.visibility="unset",this.instance.el.style.pointerEvents="unset",this.instance.el.style.display="none",this.instance.wrapperEl.style.visibility="unset",this.instance.wrapperEl.style.pointerEvents="unset",this.instance.wrapperEl.style.display="none"),this.calcHeightInProcess=!1,t}))}getClosestBreakY(){return this.brs.reduce((t,e)=>Math.abs(e-this.instance.getPanelTransformY())<Math.abs(t-this.instance.getPanelTransformY())?e:t)}}class CupertinoPane{constructor(t,e={}){this.selector=t,this.disableDragEvents=!1,this.preventDismissEvent=!1,this.preventedDismiss=!1,this.iconCloseColor="#7a7a7e",this.rendered=!1,this.settings=(new Settings).instance,this.device=new Device,this.swipeNextPoint=(t,e,s)=>{let i={},n={};if(this.settings.inverse?(i.top=this.breakpoints.breaks.bottom,i.middle=this.breakpoints.breaks.middle,i.bottom=this.breakpoints.breaks.top,n.top=Object.assign({},this.settings.breaks.bottom),n.middle=Object.assign({},this.settings.breaks.middle),n.bottom=Object.assign({},this.settings.breaks.top)):(i=Object.assign({},this.breakpoints.breaks),n=Object.assign({},this.settings.breaks)),this.breakpoints.currentBreakpoint===i.top){if(t>e){if(n.middle.enabled)return i.middle;if(n.bottom.enabled)return i.middle<s?s:i.bottom}return i.top}if(this.breakpoints.currentBreakpoint===i.middle)return t<-e&&n.top.enabled?i.top:t>e&&n.bottom.enabled?i.bottom:i.middle;if(this.breakpoints.currentBreakpoint===i.bottom){if(t<-e){if(n.middle.enabled)return i.middle>s?s:i.middle;if(n.top.enabled)return i.top}return i.bottom}return s},this.touchEvents=(()=>{const t=["touchstart","touchmove","touchend","touchcancel"];let e=["mousedown","mousemove","mouseup"];Support.pointerEvents&&(e=["pointerdown","pointermove","pointerup"]);const s={start:t[0],move:t[1],end:t[2],cancel:t[3]},i={start:e[0],move:e[1],end:e[2]};return Support.touch||!this.settings.simulateTouch?s:i})(),t instanceof HTMLElement?this.selector=t:this.selector=document.querySelector(t),this.selector?this.isPanePresented()?console.error("Cupertino Pane: specified selector or DOM element already in use",this.selector):(this.el=this.selector,this.el.style.display="none",this.settings=Object.assign(Object.assign({},this.settings),e),this.settings.parentElement?this.settings.parentElement=document.querySelector(this.settings.parentElement):this.settings.parentElement=this.el.parentElement,this.breakpoints=new Breakpoints(this,this.settings),this.events=new Events(this,this.settings,this.device,this.breakpoints)):console.warn("Cupertino Pane: wrong selector or DOM element specified",this.selector)}drawBaseElements(){this.parentEl=this.settings.parentElement,this.wrapperEl=document.createElement("div"),this.wrapperEl.className="cupertino-pane-wrapper "+this.el.className,this.addStyle("\n .cupertino-pane-wrapper {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n }\n "),this.paneEl=document.createElement("div"),this.paneEl.className="pane",this.addStyle(`\n .cupertino-pane-wrapper .pane {\n position: fixed;\n z-index: 11;\n width: 100%;\n max-width: 500px;\n left: 0px;\n right: 0px;\n margin-left: auto;\n margin-right: auto;\n background: #ffffff;\n box-shadow: 0 4px 16px rgba(0,0,0,.12);\n overflow = hidden;\n will-change = transform;\n transform: translateY(${this.screenHeightOffset}px) translateZ(0px);\n ${this.settings.inverse?"padding-bottom: 15px; border-radius: 0 0 20px 20px;":"padding-top: 15px; border-radius: 20px 20px 0 0;"}\n }\n .cupertino-pane-wrapper.darkmode .pane {\n background: #1c1c1d; \n color: #ffffff;\n }\n `),this.draggableEl=document.createElement("div"),this.draggableEl.className="draggable",this.addStyle(`\n .cupertino-pane-wrapper .draggable {\n padding: 5px;\n position: absolute;\n left: 0;\n right: 0;\n margin-left: auto;\n margin-right: auto;\n height: 30px;\n z-index: 12;\n ${this.settings.inverse?"bottom: 0;":"top: 0;"}\n ${this.settings.showDraggable?"":"opacity: 0;"}\n ${this.settings.draggableOver?"top: -30px;padding: 15px;":""}\n }\n `),this.moveEl=document.createElement("div"),this.moveEl.className="move",this.addStyle(`\n .cupertino-pane-wrapper .move {\n margin: 0 auto;\n height: 5px;\n background: #c0c0c0;\n width: 36px;\n border-radius: 4px;\n ${this.settings.inverse?"margin-top: 15px;":""}\n ${this.settings.draggableOver?"width: 70px; background: rgba(225, 225, 225, 0.6);":""}\n ${this.settings.draggableOver&&Support.backdropFilter?"\n backdrop-filter: saturate(180%) blur(20px);\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n ":""}\n }\n .cupertino-pane-wrapper.darkmode .move {\n background: #5a5a5e;\n }\n `),this.destroyButtonEl=document.createElement("div"),this.destroyButtonEl.className="destroy-button",this.addStyle(`\n .cupertino-pane-wrapper .destroy-button {\n ${this.settings.inverse?"":"\n width: 26px;\n height: 26px;\n position: absolute;\n background: #ebebeb;\n right: 20px;\n z-index: 14;\n border-radius: 100%;\n top: 16px;\n "}\n }\n .cupertino-pane-wrapper.darkmode .destroy-button {\n background: #424246;\n }\n `),this.contentEl=this.el,this.contentEl.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.contentEl.style.overflowX="hidden",this.parentEl.appendChild(this.wrapperEl),this.wrapperEl.appendChild(this.paneEl),this.paneEl.appendChild(this.draggableEl),this.paneEl.appendChild(this.contentEl),this.draggableEl.appendChild(this.moveEl)}present(t={animate:!1}){var e;return __awaiter(this,void 0,void 0,(function*(){if(this.el)if(this.isPanePresented()&&this.rendered)this.moveToBreak(this.settings.initialBreak);else if(!this.isPanePresented()||this.rendered){if(this.settings.onWillPresent(),this.updateScreenHeights(),yield this.drawBaseElements(),yield this.setBreakpoints(),this.paneEl.style.height=this.getPaneHeight()+"px",this.settings.inverse&&(this.paneEl.style.top=`-${this.breakpoints.bottomer}px`),this.wrapperEl.style.display="block",this.contentEl.style.display="block",this.wrapperEl.classList.add("rendered"),this.rendered=!0,this.settings.followerElement){if(!document.querySelector(this.settings.followerElement))return void console.warn("Cupertino Pane: wrong follower element selector specified",this.settings.followerElement);this.followerEl=document.querySelector(this.settings.followerElement),this.followerEl.style.willChange="transform, border-radius",this.followerEl.style.transform="translateY(0px) translateZ(0px)",this.followerEl.style.transition=`all ${this.settings.animationDuration}ms ${this.getTimingFunction(null===(e=this.settings.breaks[this.currentBreak()])||void 0===e?void 0:e.bounce)} 0s`}this.settings.pushElement&&(this.pushElement=document.querySelector(this.settings.pushElement)),this.settings.darkMode&&this.setDarkMode({enable:!0}),this.settings.buttonClose&&this.settings.buttonDestroy&&!this.settings.inverse&&(this.paneEl.appendChild(this.destroyButtonEl),this.destroyButtonEl.addEventListener("click",t=>this.destroy({animate:!0,destroyButton:!0})),this.destroyButtonEl.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\n <path fill="${this.iconCloseColor}" d="M278.6 256l68.2-68.2c6.2-6.2 6.2-16.4 0-22.6-6.2-6.2-16.4-6.2-22.6 0L256 233.4l-68.2-68.2c-6.2-6.2-16.4-6.2-22.6 0-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3l68.2 68.2-68.2 68.2c-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3 6.2 6.2 16.4 6.2 22.6 0l68.2-68.2 68.2 68.2c6.2 6.2 16.4 6.2 22.6 0 6.2-6.2 6.2-16.4 0-22.6L278.6 256z"/>\n </svg>`),this.settings.bottomClose&&(this.settings.breaks.bottom.enabled=!0),this.settings.freeMode&&(this.settings.lowerThanBottom=!1),this.settings.backdrop&&this.renderBackdrop(),this.device.android&&(document.body.style.overscrollBehaviorY="none"),this.attachAllEvents(),t.animate?this.doTransition({type:"present",translateY:this.breakpoints.breaks[this.settings.initialBreak]}):(this.breakpoints.prevBreakpoint=this.settings.initialBreak,this.paneEl.style.transform=`translateY(${this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.settings.pushElement&&this.pushTransition(this.breakpoints.breaks[this.settings.initialBreak],"unset"),this.settings.onDidPresent()),this.checkOpacityAttr(this.breakpoints.currentBreakpoint),yield new Promise(t=>setTimeout(()=>t(!0),150)),this.scrollElementInit(),this.checkOverflowAttr(this.breakpoints.currentBreakpoint)}else console.warn("Cupertino Pane: specified selector or DOM element already in use",this.selector)}))}getPaneHeight(){return this.settings.inverse?this.breakpoints.bottomer+this.settings.bottomOffset:this.screen_height-this.breakpoints.topper-this.settings.bottomOffset}attachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.attachEvents(e)}):this.attachEvents(this.paneEl),this.settings.handleKeyboard&&this.device.cordova&&(window.addEventListener("keyboardWillShow",this.events.onKeyboardShowCb),window.addEventListener("keyboardWillHide",this.events.onKeyboardHideCb)),!this.settings.handleKeyboard&&this.device.cordova&&this.device.android&&window.addEventListener("keyboardWillHide",()=>{this.parentEl.scrollTop=0,this.parentEl.parentElement&&(this.parentEl.parentElement.scrollTop=0,this.parentEl.parentElement.parentElement&&(this.parentEl.parentElement.parentElement.scrollTop=0))}),window.addEventListener("orientationchange",this.events.onOrientationChangeCb)}detachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.detachEvents(e)}):this.detachEvents(this.paneEl),this.settings.handleKeyboard&&this.device.cordova&&(window.removeEventListener("keyboardWillShow",this.events.onKeyboardShowCb),window.removeEventListener("keyboardWillHide",this.events.onKeyboardHideCb)),window.removeEventListener("orientationchange",this.events.onOrientationChangeCb)}resetEvents(){this.detachAllEvents(),this.attachAllEvents()}updateScreenHeights(){this.settings.inverse?(this.screen_height=window.innerHeight,this.screenHeightOffset=0):(this.screen_height=window.innerHeight,this.screenHeightOffset=window.innerHeight)}scrollElementInit(){let t=this.el.querySelectorAll("[overflow-y]");!t.length||t.length>1?this.overflowEl=this.contentEl:(this.overflowEl=t[0],this.overflowEl.style.overflowX="hidden"),this.settings.topperOverflow&&(this.settings.upperThanTop&&console.warn('Cupertino Pane: "upperThanTop" allowed for disabled "topperOverflow"'),this.setOverflowHeight())}setOverflowHeight(t=0){0===this.overflowEl.offsetHeight&&0===this.overflowEl.offsetWidth||(this.settings.inverse?this.overflowEl.style.height=this.getPaneHeight()-30-this.settings.topperOverflowOffset-this.overflowEl.offsetTop+"px":this.overflowEl.style.height=this.getPaneHeight()-this.settings.topperOverflowOffset-this.overflowEl.offsetTop-t+"px")}getTimingFunction(t){return t?"cubic-bezier(0.175, 0.885, 0.370, 1.120)":this.settings.animationType}checkOpacityAttr(t){let e=this.el.querySelectorAll("[hide-on-bottom]");e.length&&(this.settings.inverse||e.forEach(e=>{e.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,e.style.opacity=t>=this.breakpoints.breaks.bottom?"0":"1"}))}checkOverflowAttr(t){this.settings.topperOverflow&&(this.settings.inverse?this.overflowEl.style.overflowY=t>=this.breakpoints.bottomer?"auto":"hidden":this.overflowEl.style.overflowY=t<=this.breakpoints.topper?"auto":"hidden")}isPanePresented(){let t=Array.from(document.querySelectorAll(".cupertino-pane-wrapper.rendered"));return!!t.length&&!!t.find(t=>t.contains(this.selector))}isBackdropPresented(){return!!document.querySelector(".cupertino-pane-wrapper .backdrop")}renderBackdrop(){this.backdropEl=document.createElement("div"),this.backdropEl.className="backdrop",this.addStyle(`\n .cupertino-pane-wrapper .backdrop {\n overflow: hidden;\n position: fixed;\n width: 100%;\n bottom: 0;\n right: 0;\n left: 0;\n top: 0;\n display: none;\n z-index: 10;\n transition: all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s;\n background-color: rgba(0,0,0, ${this.settings.backdropOpacity});\n }\n `),this.wrapperEl.appendChild(this.backdropEl),this.backdropEl.addEventListener("click",t=>this.settings.onBackdropTap())}addStyle(t){const e=document.createElement("style");e.textContent=t,document.head.prepend(e)}backdrop(t={show:!0}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call backdrop()"),null;this.isBackdropPresented()||(this.renderBackdrop(),this.resetEvents());const e=()=>{this.backdropEl.style.transition="initial",this.backdropEl.style.display="none",this.backdropEl.removeEventListener("transitionend",e)};if(this.backdropEl.style.transition=`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.backdropEl.style.backgroundColor="rgba(0,0,0,.0)",t.show)this.backdropEl.style.display="block",setTimeout(()=>{this.backdropEl.style.backgroundColor=`rgba(0,0,0, ${this.settings.backdropOpacity})`},50);else{if("none"===this.backdropEl.style.display)return;this.backdropEl.addEventListener("transitionend",e)}}attachEvents(t){var e,s,i;if(!Support.touch&&Support.pointerEvents)t.addEventListener(this.touchEvents.start,this.events.touchStartCb,!1),t.addEventListener(this.touchEvents.move,this.events.touchMoveCb,!1),t.addEventListener(this.touchEvents.end,this.events.touchEndCb,!1),null===(e=this.backdropEl)||void 0===e||e.addEventListener(this.touchEvents.move,this.events.touchMoveBackdropCb,!1);else{if(Support.touch){const e=!("touchstart"!==this.touchEvents.start||!Support.passiveListener||!this.settings.passiveListeners)&&{passive:!0,capture:!1};t.addEventListener(this.touchEvents.start,this.events.touchStartCb,e),t.addEventListener(this.touchEvents.move,this.events.touchMoveCb,!!Support.passiveListener&&{passive:!1,capture:!1}),t.addEventListener(this.touchEvents.end,this.events.touchEndCb,e),null===(s=this.backdropEl)||void 0===s||s.addEventListener(this.touchEvents.move,this.events.touchMoveBackdropCb,!!Support.passiveListener&&{passive:!1,capture:!1}),this.touchEvents.cancel&&t.addEventListener(this.touchEvents.cancel,this.events.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.addEventListener("mousedown",this.events.touchStartCb,!1),t.addEventListener("mousemove",this.events.touchMoveCb,!1),t.addEventListener("mouseup",this.events.touchEndCb,!1),null===(i=this.backdropEl)||void 0===i||i.addEventListener("mousemove",this.events.touchMoveBackdropCb,!1))}this.settings.preventClicks&&t.addEventListener("click",this.events.onClickCb,!0)}detachEvents(t){var e,s,i;if(!Support.touch&&Support.pointerEvents)t.removeEventListener(this.touchEvents.start,this.events.touchStartCb,!1),t.removeEventListener(this.touchEvents.move,this.events.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.events.touchEndCb,!1),null===(e=this.backdropEl)||void 0===e||e.removeEventListener(this.touchEvents.move,this.events.touchMoveBackdropCb,!1);else{if(Support.touch){const e=!("onTouchStart"!==this.touchEvents.start||!Support.passiveListener||!this.settings.passiveListeners)&&{passive:!0,capture:!1};t.removeEventListener(this.touchEvents.start,this.events.touchStartCb,e),t.removeEventListener(this.touchEvents.move,this.events.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.events.touchEndCb,e),null===(s=this.backdropEl)||void 0===s||s.removeEventListener(this.touchEvents.move,this.events.touchMoveBackdropCb,!1),this.touchEvents.cancel&&t.removeEventListener(this.touchEvents.cancel,this.events.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.removeEventListener("mousedown",this.events.touchStartCb,!1),t.removeEventListener("mousemove",this.events.touchMoveCb,!1),t.removeEventListener("mouseup",this.events.touchEndCb,!1),null===(i=this.backdropEl)||void 0===i||i.removeEventListener("mousemove",this.events.touchMoveBackdropCb,!1))}this.settings.preventClicks&&t.removeEventListener("click",this.events.onClickCb,!0)}getPanelTransformY(){return parseFloat(/\.*translateY\((.*)px\)/i.exec(this.paneEl.style.transform)[1])}preventDismiss(t=!1){this.preventDismissEvent=t}disableDrag(){this.disableDragEvents=!0}enableDrag(){this.disableDragEvents=!1}setDarkMode(t={enable:!0}){t.enable?(this.wrapperEl.classList.add("darkmode"),this.iconCloseColor="#a8a7ae"):(this.wrapperEl.classList.remove("darkmode"),this.iconCloseColor="#7a7a7e")}setBreakpoints(t){return __awaiter(this,void 0,void 0,(function*(){!this.isPanePresented()||t?yield this.breakpoints.buildBreakpoints(t):console.warn("Cupertino Pane: Provide any breaks configuration")}))}calcFitHeight(){return __awaiter(this,void 0,void 0,(function*(){this.breakpoints.calcHeightInProcess?console.warn("Cupertino Pane: calcFitHeight() already in process"):yield this.breakpoints.buildBreakpoints(this.breakpoints.lockedBreakpoints)}))}moveToBreak(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToBreak()"),null;this.settings.breaks[t].enabled?(this.checkOpacityAttr(this.breakpoints.breaks[t]),this.checkOverflowAttr(this.breakpoints.breaks[t]),this.doTransition({type:"breakpoint",translateY:this.breakpoints.breaks[t]}),this.breakpoints.currentBreakpoint=this.breakpoints.breaks[t]):console.warn("Cupertino Pane: %s breakpoint disabled",t)}moveToHeight(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToHeight()"),null;let e=this.screenHeightOffset?this.screen_height-t:t;this.checkOpacityAttr(e),this.doTransition({type:"breakpoint",translateY:e})}hide(){return this.isPanePresented()?this.isHidden()?(console.warn("Cupertino Pane: Pane already hidden"),null):void this.doTransition({type:"hide",translateY:this.screenHeightOffset}):(console.warn("Cupertino Pane: Present pane before call hide()"),null)}isHidden(){return this.isPanePresented()?this.paneEl.style.transform===`translateY(${this.screenHeightOffset}px) translateZ(0px)`:(console.warn("Cupertino Pane: Present pane before call isHidden()"),null)}currentBreak(){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call currentBreak()"),null;this.breakpoints.getCurrentBreakName()}destroyResets(){this.parentEl.appendChild(this.contentEl),this.wrapperEl.remove(),this.detachAllEvents(),delete this.rendered,delete this.breakpoints.prevBreakpoint,this.contentEl.style.display="none"}destroy(t={animate:!1,destroyButton:!1}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call destroy()"),null;this.preventDismissEvent?this.preventedDismiss||(this.settings.onWillDismiss({prevented:!0}),this.moveToBreak(this.breakpoints.prevBreakpoint)):(this.settings.onWillDismiss(),t.animate?this.doTransition({type:"destroy",translateY:this.screenHeightOffset,destroyButton:t.destroyButton}):(this.destroyResets(),this.settings.onDidDismiss({destroyButton:t.destroyButton})))}pushTransition(t,e){t=this.screenHeightOffset-t;const s=this.settings.pushMinHeight?this.settings.pushMinHeight:this.screenHeightOffset-this.breakpoints.bottomer,i=this.screenHeightOffset-this.breakpoints.topper;this.pushElement.style.transition=e;const n=(t,e,s,i)=>{this.pushElement.style.transform=`translateY(${e}px) scale(${t})`,this.pushElement.style.borderRadius=s+"px",this.pushElement.style.filter=`contrast(${i})`};if(t<=s)return void n(1,0,0,1);const o=(e,n)=>{let o=-1*(i*n-s*e);return o-=(e-n)*t,o/=s-i,o>n&&(o=n),o<e&&(o=e),o};n(o(.93,1),o(-6-this.settings.pushYOffset,0),-1*o(-10,0),o(.85,1))}doTransition(t={}){var e;if("move"===t.type)return this.paneEl.style.transition="all 0ms linear 0ms",this.paneEl.style.transform=`translateY(${t.translateY}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transition="all 0ms linear 0ms",this.followerEl.style.transform=`translateY(${t.translateY-this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`),void(this.settings.pushElement&&this.pushTransition(this.getPanelTransformY(),"all 0ms linear 0ms"));const s=()=>{"destroy"===t.type&&this.destroyResets(),this.paneEl.style.transition="initial",this.followerEl&&(this.followerEl.style.transition="initial"),this.settings.backdrop&&("destroy"!==t.type&&"hide"!==t.type||(this.backdropEl.style.transition="initial",this.backdropEl.style.display="none")),"present"===t.type&&this.settings.onDidPresent(),"destroy"===t.type&&this.settings.onDidDismiss({destroyButton:t.destroyButton}),this.settings.onTransitionEnd({target:document.body.contains(this.paneEl)?this.paneEl:null}),this.paneEl.removeEventListener("transitionend",s)};if("breakpoint"===t.type||"end"===t.type||"present"===t.type||"hide"===t.type||"destroy"===t.type){if(this.settings.backdrop&&(this.isHidden()||"hide"===t.type||"destroy"===t.type||"present"===t.type)&&(this.backdropEl.style.backgroundColor="rgba(0,0,0,.0)",this.backdropEl.style.transition=`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,"hide"!==t.type&&"destroy"!==t.type&&(this.backdropEl.style.display="block",setTimeout(()=>{this.backdropEl.style.backgroundColor=`rgba(0,0,0, ${this.settings.backdropOpacity})`},50))),"end"===t.type&&this.settings.freeMode)return;const i=Object.entries(this.settings.breaks).find(e=>e[1].height===this.screenHeightOffset-t.translateY),n=this.getTimingFunction(!(!i||!(null===(e=i[1])||void 0===e?void 0:e.bounce)));this.paneEl.style.transition=`transform ${this.settings.animationDuration}ms ${n} 0s`,this.followerEl&&(this.followerEl.style.transition=`transform ${this.settings.animationDuration}ms ${n} 0s`),this.settings.pushElement&&setTimeout(()=>{this.pushTransition(t.translateY,`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`)},this.settings.pushYOffset?50:0),setTimeout(()=>{this.settings.onTransitionStart({translateY:{new:t.translateY}}),this.paneEl.style.transform=`translateY(${t.translateY}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transform=`translateY(${t.translateY-this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`)},"present"===t.type?50:0);let o=Object.entries(this.breakpoints.breaks).find(e=>e[1]===t.translateY);return o&&(this.breakpoints.prevBreakpoint=o[0]),void this.paneEl.addEventListener("transitionend",s)}}}exports.CupertinoPane=CupertinoPane; | ||
function __awaiter(t,e,s,i){return new(s||(s=Promise))((function(n,r){function o(t){try{h(i.next(t))}catch(t){r(t)}}function a(t){try{h(i.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof s?e:new s((function(t){t(e)}))).then(o,a)}h((i=i.apply(t,e||[])).next())}))}Object.defineProperty(exports,"__esModule",{value:!0});class Support{static get touch(){return window.Modernizr&&!0===window.Modernizr.touch||!!(window.navigator.maxTouchPoints>0||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch)}static get observer(){return"MutationObserver"in window||"WebkitMutationObserver"in window}static get backdropFilter(){return CSS.supports("backdrop-filter","blur(0px)")||CSS.supports("-webkit-backdrop-filter","blur(0px)")}static get passiveListener(){let t=!1;try{const e=Object.defineProperty({},"passive",{get(){t=!0}});window.addEventListener("testPassiveListener",null,e)}catch(t){}return t}static get gestures(){return"ongesturestart"in window}static get pointerEvents(){return!!window.PointerEvent&&"maxTouchPoints"in window.navigator&&window.navigator.maxTouchPoints>0}}class Device{constructor(){this.ios=!1,this.android=!1,this.androidChrome=!1,this.desktop=!1,this.iphone=!1,this.ipod=!1,this.ipad=!1,this.edge=!1,this.ie=!1,this.firefox=!1,this.macos=!1,this.windows=!1,this.cordova=!(!window.cordova&&!window.phonegap),this.phonegap=!(!window.cordova&&!window.phonegap),this.electron=!1,this.ionic=!!document.querySelector("ion-app");const t=window.navigator.platform,e=window.navigator.userAgent,s=window.screen.width,i=window.screen.height;let n=e.match(/(Android);?[\s\/]+([\d.]+)?/),r=e.match(/(iPad).*OS\s([\d_]+)/),o=e.match(/(iPod)(.*OS\s([\d_]+))?/),a=!this.ipad&&e.match(/(iPhone\sOS|iOS)\s([\d_]+)/),h=e.indexOf("MSIE ")>=0||e.indexOf("Trident/")>=0,l=e.indexOf("Edge/")>=0,p=e.indexOf("Gecko/")>=0&&e.indexOf("Firefox/")>=0,c="Win32"===t,d=e.toLowerCase().indexOf("electron")>=0,u="MacIntel"===t;!r&&u&&Support.touch&&(1024===s&&1366===i||834===s&&1194===i||834===s&&1112===i||768===s&&1024===i)&&(r=e.match(/(Version)\/([\d.]+)/),u=!1),this.ie=h,this.edge=l,this.firefox=p,n&&!c&&(this.os="android",this.osVersion=n[2],this.android=!0,this.androidChrome=e.toLowerCase().indexOf("chrome")>=0),(r||a||o)&&(this.os="ios",this.ios=!0),a&&!o&&(this.osVersion=a[2].replace(/_/g,"."),this.iphone=!0),r&&(this.osVersion=r[2].replace(/_/g,"."),this.ipad=!0),o&&(this.osVersion=o[3]?o[3].replace(/_/g,"."):null,this.ipod=!0),this.ios&&this.osVersion&&e.indexOf("Version/")>=0&&"10"===this.osVersion.split(".")[0]&&(this.osVersion=e.toLowerCase().split("version/")[1].split(" ")[0]),this.webView=!(!(a||r||o)||!e.match(/.*AppleWebKit(?!.*Safari)/i)&&!window.navigator.standalone)||window.matchMedia&&window.matchMedia("(display-mode: standalone)").matches,this.webview=this.webView,this.standalone=this.webView,this.desktop=!(this.ios||this.android)||d,this.desktop&&(this.electron=d,this.macos=u,this.windows=c,this.macos&&(this.os="macos"),this.windows&&(this.os="windows")),this.pixelRatio=window.devicePixelRatio||1}}class Events{constructor(t,e,s,i){this.instance=t,this.settings=e,this.device=s,this.breakpoints=i,this.allowClick=!0,this.disableDragAngle=!1,this.pointerDown=!1,this.contentScrollTop=0,this.steps=[],this.inputBluredbyMove=!1,this.movedByKeyboard=!1,this.touchEvents=(()=>{const t=["touchstart","touchmove","touchend","touchcancel"];let e=["mousedown","mousemove","mouseup"];Support.pointerEvents&&(e=["pointerdown","pointermove","pointerup"]);const s={start:t[0],move:t[1],end:t[2],cancel:t[3]},i={start:e[0],move:e[1],end:e[2]};return Support.touch||!this.settings.simulateTouch?s:i})(),this.touchStartCb=t=>this.touchStart(t),this.touchMoveBackdropCb=t=>this.touchMoveBackdrop(t),this.touchMoveCb=t=>this.touchMove(t),this.touchEndCb=t=>this.touchEnd(t),this.onClickCb=t=>this.onClick(t),this.onKeyboardShowCb=t=>this.onKeyboardShow(t),this.onKeyboardHideCb=t=>this.onKeyboardHide(t),this.onWindowResizeCb=t=>this.onWindowResize(t)}attachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.eventListeners("addEventListener",e)}):this.eventListeners("addEventListener",this.instance.paneEl),this.settings.handleKeyboard&&this.device.cordova&&(window.addEventListener("keyboardWillShow",this.onKeyboardShowCb),window.addEventListener("keyboardWillHide",this.onKeyboardHideCb)),!this.settings.handleKeyboard&&this.device.cordova&&this.device.android&&window.addEventListener("keyboardWillHide",()=>{this.instance.parentEl.scrollTop=0,this.instance.parentEl.parentElement&&(this.instance.parentEl.parentElement.scrollTop=0,this.instance.parentEl.parentElement.parentElement&&(this.instance.parentEl.parentElement.parentElement.scrollTop=0))}),window.addEventListener("resize",this.onWindowResizeCb)}detachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.eventListeners("removeEventListener",e)}):this.eventListeners("removeEventListener",this.instance.paneEl),this.settings.handleKeyboard&&this.device.cordova&&(window.removeEventListener("keyboardWillShow",this.onKeyboardShowCb),window.removeEventListener("keyboardWillHide",this.onKeyboardHideCb)),window.removeEventListener("resize",this.onWindowResizeCb)}resetEvents(){this.detachAllEvents(),this.attachAllEvents()}eventListeners(t,e){var s,i,n;if(!Support.touch&&Support.pointerEvents)e[t](this.touchEvents.start,this.touchStartCb,!1),e[t](this.touchEvents.move,this.touchMoveCb,!1),e[t](this.touchEvents.end,this.touchEndCb,!1),null===(s=this.instance.backdropEl)||void 0===s||s[t](this.touchEvents.move,this.touchMoveBackdropCb,!1);else{if(Support.touch){const s=!("touchstart"!==this.touchEvents.start||!Support.passiveListener||!this.settings.passiveListeners)&&{passive:!0,capture:!1};e[t](this.touchEvents.start,this.touchStartCb,s),e[t](this.touchEvents.move,this.touchMoveCb,!!Support.passiveListener&&{passive:!1,capture:!1}),e[t](this.touchEvents.end,this.touchEndCb,s),null===(i=this.instance.backdropEl)||void 0===i||i[t](this.touchEvents.move,this.touchMoveBackdropCb,!!Support.passiveListener&&{passive:!1,capture:!1}),this.touchEvents.cancel&&e[t](this.touchEvents.cancel,this.touchEndCb,s)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(e[t]("mousedown",this.touchStartCb,!1),e[t]("mousemove",this.touchMoveCb,!1),e[t]("mouseup",this.touchEndCb,!1),null===(n=this.instance.backdropEl)||void 0===n||n[t]("mousemove",this.touchMoveBackdropCb,!1))}this.settings.preventClicks&&e[t]("click",this.onClickCb,!0)}touchStart(t){if(this.settings.onDragStart(t),this.allowClick=!0,this.instance.disableDragEvents)return;this.disableDragAngle=!1,this.instance.preventedDismiss=!1;const{clientY:e,clientX:s}=this.getEvetClientYX(t,"touchstart");this.startY=e,this.startX=s,"mousedown"===t.type&&(this.pointerDown=!0),this.contentScrollTop&&this.willScrolled(t)&&this.isDragScrollabe(t.path||t.composedPath())&&(this.startY+=this.contentScrollTop),this.steps.push(this.startY)}touchMoveBackdrop(t){this.settings.touchMoveStopPropagation&&t.stopPropagation()}touchMove(t){const{clientY:e,clientX:s}=this.getEvetClientYX(t,"touchmove");if(t.delta=this.steps[0]-e,this.settings.onDrag(t),this.instance.disableDragEvents)return void(this.steps=[]);if(this.disableDragAngle)return;if(this.instance.preventedDismiss)return;if(this.settings.touchMoveStopPropagation&&t.stopPropagation(),"mousemove"===t.type&&!this.pointerDown)return;const i=e-this.steps[this.steps.length-1];let n=this.instance.getPanelTransformY()+i;if(!this.isFormElement(t.target)||!this.isElementScrollable(t.target)){if(this.steps.length>2&&this.isFormElement(document.activeElement)&&!this.isFormElement(t.target)&&(document.activeElement.blur(),this.inputBluredbyMove=!0),this.settings.touchAngle){let t;const i=s-this.startX,n=e-this.startY;if(t=180*Math.atan2(Math.abs(n),Math.abs(i))/Math.PI,i*i+n*n>=25&&90-t>this.settings.touchAngle&&1===this.steps.length)return void(this.disableDragAngle=!0)}if(this.isDragScrollabe(t.path||t.composedPath())&&"auto"===this.instance.overflowEl.style.overflowY){if(this.instance.overflowEl.addEventListener("scroll",t=>{this.contentScrollTop=t.target.scrollTop}),this.settings.inverse&&this.willScrolled(t))return void(this.contentScrollTop=0);if(n>this.breakpoints.topper&&this.contentScrollTop>0||n<=this.breakpoints.topper)return}if(!this.settings.inverse&&!this.settings.upperThanTop&&n<=this.breakpoints.topper)this.instance.paneEl.style.transform=`translateY(${this.breakpoints.topper}px) translateZ(0px)`;else{if(n<=this.breakpoints.topper&&this.settings.upperThanTop){const t=(-this.breakpoints.topper+this.breakpoints.topper-this.instance.getPanelTransformY())/this.breakpoints.topper/-8;n=this.instance.getPanelTransformY()+i*t}if((!this.settings.lowerThanBottom||this.settings.inverse)&&n>=this.breakpoints.bottomer)return this.instance.paneEl.style.transform=`translateY(${this.breakpoints.bottomer}px) translateZ(0px)`,void this.instance.checkOpacityAttr(n);if(!this.instance.preventedDismiss&&this.instance.preventDismissEvent&&this.settings.bottomClose){let t=(-this.breakpoints.topper+this.breakpoints.topper-this.instance.getPanelTransformY())/this.breakpoints.topper/-8;if(n=this.instance.getPanelTransformY()+i*(.5-t),-1*(e-220-this.instance.screen_height)<=this.instance.screen_height-this.breakpoints.bottomer)return this.instance.preventedDismiss=!0,this.settings.onWillDismiss({prevented:!0}),void this.instance.moveToBreak(this.breakpoints.prevBreakpoint)}this.allowClick=!1,this.instance.checkOpacityAttr(n),this.instance.checkOverflowAttr(n),this.instance.doTransition({type:"move",translateY:n}),this.steps.push(e)}}}touchEnd(t){if(this.instance.disableDragEvents)return;"mouseup"===t.type&&(this.pointerDown=!1);let e=this.breakpoints.getClosestBreakY();const s=this.steps[this.steps.length-1]-this.steps[this.steps.length-2],i=window.hasOwnProperty("cordova")?this.settings.fastSwipeSensivity+1:this.settings.fastSwipeSensivity;if(Math.abs(s)>=i&&(e=this.instance.swipeNextPoint(s,i,e),this.settings.fastSwipeClose&&this.breakpoints.currentBreakpoint<e))return void this.instance.destroy({animate:!0});let n=!1;this.isFormElement(document.activeElement)&&!this.isFormElement(t.target)&&2===this.steps.length&&(n=!0),this.steps=[],this.breakpoints.currentBreakpoint=e,this.settings.onDragEnd(t),isNaN(s)||n||(this.instance.checkOpacityAttr(this.breakpoints.currentBreakpoint),this.instance.checkOverflowAttr(this.breakpoints.currentBreakpoint),this.settings.bottomClose&&e===this.breakpoints.breaks.bottom?this.instance.destroy({animate:!0}):(this.instance.getPanelTransformY()===e&&this.settings.onTransitionEnd({target:this.instance.paneEl}),this.instance.doTransition({type:"end",translateY:e})))}onClick(t){if(this.allowClick){if(this.settings.clickBottomOpen&&this.breakpoints.breaks.bottom===this.instance.getPanelTransformY()){let t;this.settings.breaks.top.enabled&&(t="top"),this.settings.breaks.middle.enabled&&(t="middle"),this.instance.moveToBreak(t)}}else this.settings.preventClicks&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())}onKeyboardShow(t){if(!this.isPaneDescendant(document.activeElement))return;if(!this.isOnViewport())return;this.device.android&&setTimeout(()=>this.fixAndroidResize(),20),this.movedByKeyboard=!0,this.breakpoints.prevBreakpoint=Object.entries(this.breakpoints.breaks).find(t=>t[1]===this.instance.getPanelTransformY())[0];let e=this.settings.breaks[this.instance.currentBreak()].height+t.keyboardHeight;window.matchMedia("(orientation: landscape)").matches&&(e=this.instance.screen_height),e>this.instance.screen_height-80&&(e=this.instance.screen_height-80),e-50>=this.settings.breaks[this.instance.currentBreak()].height&&this.instance.moveToHeight(e),setTimeout(()=>{this.instance.setOverflowHeight(t.keyboardHeight-this.settings.topperOverflowOffset),this.instance.overflowEl.scrollTop=document.activeElement.offsetTop},300)}onKeyboardHide(t){this.movedByKeyboard&&this.isOnViewport()&&(this.device.android&&this.fixAndroidResize(),this.movedByKeyboard=!1,this.instance.setOverflowHeight(),this.inputBluredbyMove?this.inputBluredbyMove=!1:this.instance.isHidden()||this.instance.moveToBreak(this.breakpoints.prevBreakpoint))}onWindowResize(t){return __awaiter(this,void 0,void 0,(function*(){yield new Promise(t=>setTimeout(()=>t(!0),150)),this.instance.updateScreenHeights(),this.breakpoints.buildBreakpoints(JSON.parse(this.breakpoints.lockedBreakpoints),!1)}))}getEvetClientYX(t,e){const s=t.type===e&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]);return{clientY:t.type===e?s.clientY:t.clientY,clientX:t.type===e?s.clientX:t.clientX}}fixAndroidResize(){if(!this.instance.paneEl)return;document.querySelector("ion-app");window.requestAnimationFrame(()=>{this.instance.wrapperEl.style.width="100%",this.instance.paneEl.style.position="absolute",window.requestAnimationFrame(()=>{this.instance.wrapperEl.style.width="unset",this.instance.paneEl.style.position="fixed"})})}isDragScrollabe(t){return!!t.find(t=>t===this.instance.overflowEl)}willScrolled(t){return!(!this.isElementScrollable(this.instance.overflowEl)||"hidden"===this.instance.overflowEl.style.overflow||!this.isDragScrollabe(t.path||t.composedPath()))}isPaneDescendant(t){let e=t.parentNode;for(;null!=e;){if(e==this.instance.paneEl)return!0;e=e.parentNode}return!1}isFormElement(t){return!!(t&&t.tagName&&["input","select","option","textarea","button","label"].includes(t.tagName.toLowerCase()))}isElementScrollable(t){return t.scrollHeight>t.clientHeight}isOnViewport(){return!this.instance.paneEl||0!==this.instance.paneEl.offsetWidth||0!==this.instance.paneEl.offsetHeight}}class Settings{constructor(){this.instance={initialBreak:"middle",inverse:!1,parentElement:null,followerElement:null,cssClass:null,fitHeight:!1,maxFitHeight:null,fitScreenHeight:!0,backdrop:!1,backdropOpacity:.4,animationType:"ease",animationDuration:300,dragBy:null,bottomOffset:0,bottomClose:!1,fastSwipeClose:!1,fastSwipeSensivity:3,freeMode:!1,buttonDestroy:!0,buttonClose:!0,topperOverflow:!0,topperOverflowOffset:0,lowerThanBottom:!0,upperThanTop:!1,showDraggable:!0,draggableOver:!1,clickBottomOpen:!0,preventClicks:!0,handleKeyboard:!0,simulateTouch:!0,passiveListeners:!0,touchMoveStopPropagation:!1,touchAngle:null,breaks:{},zStack:null,onDidDismiss:()=>{},onWillDismiss:()=>{},onDidPresent:()=>{},onWillPresent:()=>{},onDragStart:()=>{},onDrag:()=>{},onDragEnd:()=>{},onBackdropTap:()=>{},onTransitionStart:()=>{},onTransitionEnd:()=>{}}}}class Breakpoints{constructor(t,e){this.instance=t,this.settings=e,this.breaks={},this.calcHeightInProcess=!1,this.brs=[],this.defaultBreaksConf={top:{enabled:!0,height:window.innerHeight-47.25},middle:{enabled:!0,height:300},bottom:{enabled:!0,height:100}}}buildBreakpoints(t,e=!0){var s,i;return __awaiter(this,void 0,void 0,(function*(){if(this.breaks={top:this.instance.screenHeightOffset,middle:this.instance.screenHeightOffset,bottom:this.instance.screenHeightOffset},this.settings.fitHeight){this.settings.fitScreenHeight=!1,this.settings.initialBreak="top",this.settings.topperOverflow=!1;let e=yield this.getPaneFitHeight();this.settings.maxFitHeight&&e>this.settings.maxFitHeight&&(e=this.settings.maxFitHeight,this.settings.topperOverflow=!0),t={top:{enabled:!0,height:e},middle:{enabled:!1},bottom:{enabled:!1}}}if(["top","middle","bottom"].forEach(e=>{var s;this.breaks[e]-=this.settings.bottomOffset,this.settings.breaks[e]||(this.settings.breaks[e]=this.defaultBreaksConf[e]),t&&t[e]&&(this.settings.breaks[e]=t[e]),this.settings.fitScreenHeight&&((null===(s=this.settings.breaks[e])||void 0===s?void 0:s.height)>this.instance.screen_height&&(this.settings.breaks[e].height=this.instance.screen_height-this.settings.bottomOffset),this.settings.breaks.top&&this.settings.breaks.middle&&this.settings.breaks.top.height-50<=this.settings.breaks.middle.height&&(this.settings.breaks.middle.enabled=!1,this.settings.initialBreak="top")),this.settings.fitHeight&&"top"===e&&(this.settings.breaks[e].height>this.instance.screen_height?(this.settings.breaks[e].height=this.instance.screen_height-2*this.settings.bottomOffset,this.settings.topperOverflow=!0):this.instance.overflowEl&&!this.settings.maxFitHeight&&(this.settings.topperOverflow=!1,this.instance.overflowEl.style.overflowY="hidden")),this.settings.breaks[e]&&this.settings.breaks[e].enabled&&this.settings.breaks[e].height&&(this.settings.inverse?this.breaks[e]=this.settings.breaks[e].height:this.breaks[e]-=this.settings.breaks[e].height)}),this.lockedBreakpoints||(this.lockedBreakpoints=JSON.stringify(this.settings.breaks)),this.instance.isPanePresented()||this.settings.breaks[this.settings.initialBreak].enabled||console.warn("Cupertino Pane: Please set initialBreak for enabled breakpoint"),this.settings.breaks.middle.height>=this.settings.breaks.top.height&&console.warn("Cupertino Pane: Please set middle height lower than top height"),this.settings.breaks.middle.height<=this.settings.breaks.bottom.height&&console.warn("Cupertino Pane: Please set bottom height lower than middle height"),this.brs=[],["top","middle","bottom"].forEach(t=>{this.settings.breaks[t].enabled&&this.brs.push(this.breaks[t])}),this.topper=this.brs.reduce((t,e)=>e<t?e:t),this.bottomer=this.brs.reduce((t,e)=>Math.abs(e)>Math.abs(t)?e:t),this.instance.isPanePresented()||(this.currentBreakpoint=this.breaks[this.settings.initialBreak],!this.settings.inverse||this.settings.breaks.bottom.enabled||this.settings.breaks.middle.enabled||(this.settings.topperOverflow=!1)),this.instance.isPanePresented()){if((null===(s=this.settings.breaks[this.prevBreakpoint])||void 0===s?void 0:s.enabled)&&this.instance.moveToBreak(this.prevBreakpoint),!(null===(i=this.settings.breaks[this.prevBreakpoint])||void 0===i?void 0:i.enabled)){let t=this.instance.swipeNextPoint(1,1,this.getClosestBreakY());const e=Object.entries(this.breaks).find(e=>e[1]===t);this.instance.moveToBreak(e[0])}this.instance.paneEl.style.top=this.settings.inverse?`-${this.bottomer}px`:"unset",this.instance.paneEl.style.height=this.instance.getPaneHeight()+"px",this.instance.scrollElementInit(),this.instance.checkOpacityAttr(this.currentBreakpoint),this.instance.checkOverflowAttr(this.currentBreakpoint)}}))}getCurrentBreakName(){return this.breaks.top===this.currentBreakpoint?"top":this.breaks.middle===this.currentBreakpoint?"middle":this.breaks.bottom===this.currentBreakpoint?"bottom":null}getPaneFitHeight(){return __awaiter(this,void 0,void 0,(function*(){this.calcHeightInProcess=!0;let t,e=this.instance.el.querySelectorAll("img");this.instance.el.style.height="unset",this.instance.rendered||(this.instance.el.style.visibility="hidden",this.instance.el.style.pointerEvents="none",this.instance.el.style.display="block",this.instance.wrapperEl.style.visibility="hidden",this.instance.wrapperEl.style.pointerEvents="none",this.instance.wrapperEl.style.display="block");let s=[];return e.length&&(s=Array.from(e).map(t=>new Promise(e=>{t.complete&&t.naturalHeight?e(!0):t.onload=()=>e(!0)}))),s.push(new Promise(t=>setTimeout(()=>t(!0),this.instance.rendered?0:150))),yield Promise.all(s),t=parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("height"))+(parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("margin-top"))+parseInt(document.defaultView.getComputedStyle(this.instance.el,"").getPropertyValue("margin-bottom"))),t+=this.instance.el.offsetTop,this.instance.rendered||(this.instance.el.style.visibility="unset",this.instance.el.style.pointerEvents="unset",this.instance.el.style.display="none",this.instance.wrapperEl.style.visibility="unset",this.instance.wrapperEl.style.pointerEvents="unset",this.instance.wrapperEl.style.display="none"),this.calcHeightInProcess=!1,t}))}getClosestBreakY(){return this.brs.reduce((t,e)=>Math.abs(e-this.instance.getPanelTransformY())<Math.abs(t-this.instance.getPanelTransformY())?e:t)}}class CupertinoPane{constructor(t,e={}){this.selector=t,this.disableDragEvents=!1,this.preventDismissEvent=!1,this.preventedDismiss=!1,this.rendered=!1,this.settings=(new Settings).instance,this.device=new Device,this.zStackDefaults={pushElements:null,minPushHeight:null,cardYOffset:0,cardZScale:.93,cardContrast:.85,stackZAngle:160},this.swipeNextPoint=(t,e,s)=>{let i={},n={};if(this.settings.inverse?(i.top=this.breakpoints.breaks.bottom,i.middle=this.breakpoints.breaks.middle,i.bottom=this.breakpoints.breaks.top,n.top=Object.assign({},this.settings.breaks.bottom),n.middle=Object.assign({},this.settings.breaks.middle),n.bottom=Object.assign({},this.settings.breaks.top)):(i=Object.assign({},this.breakpoints.breaks),n=Object.assign({},this.settings.breaks)),this.breakpoints.currentBreakpoint===i.top){if(t>e){if(n.middle.enabled)return i.middle;if(n.bottom.enabled)return i.middle<s?s:i.bottom}return i.top}if(this.breakpoints.currentBreakpoint===i.middle)return t<-e&&n.top.enabled?i.top:t>e&&n.bottom.enabled?i.bottom:i.middle;if(this.breakpoints.currentBreakpoint===i.bottom){if(t<-e){if(n.middle.enabled)return i.middle>s?s:i.middle;if(n.top.enabled)return i.top}return i.bottom}return s},t instanceof HTMLElement?this.selector=t:this.selector=document.querySelector(t),this.selector?this.isPanePresented()?console.error("Cupertino Pane: specified selector or DOM element already in use",this.selector):(this.el=this.selector,this.el.style.display="none",this.settings=Object.assign(Object.assign({},this.settings),e),this.settings.parentElement?this.settings.parentElement=document.querySelector(this.settings.parentElement):this.settings.parentElement=this.el.parentElement,this.breakpoints=new Breakpoints(this,this.settings),this.events=new Events(this,this.settings,this.device,this.breakpoints)):console.warn("Cupertino Pane: wrong selector or DOM element specified",this.selector)}drawBaseElements(){this.parentEl=this.settings.parentElement,this.wrapperEl=document.createElement("div"),this.wrapperEl.classList.add("cupertino-pane-wrapper"),this.settings.inverse&&this.wrapperEl.classList.add("inverse"),this.settings.cssClass&&(this.wrapperEl.className+=" "+this.settings.cssClass);let t="";t+="\n .cupertino-pane-wrapper {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n }\n ",this.paneEl=document.createElement("div"),this.paneEl.style.transform=`translateY(${this.screenHeightOffset}px) translateZ(0px)`,this.paneEl.classList.add("pane"),t+="\n .cupertino-pane-wrapper .pane {\n position: fixed;\n z-index: 11;\n width: 100%;\n max-width: 500px;\n left: 0px;\n right: 0px;\n margin-left: auto;\n margin-right: auto;\n background: var(--cupertino-pane-background, #ffffff);\n color: var(--cupertino-pane-color, #333333);\n box-shadow: var(--cupertino-pane-shadow, 0 4px 16px rgba(0,0,0,.12));\n will-change: transform;\n padding-top: 15px; \n border-radius: var(--cupertino-pane-border-radius, 20px) \n var(--cupertino-pane-border-radius, 20px) \n 0 0;\n }\n .cupertino-pane-wrapper.inverse .pane {\n padding-bottom: 15px; \n border-radius: 0 0 20px 20px;\n border-radius: 0 0\n var(--cupertino-pane-border-radius, 20px) \n var(--cupertino-pane-border-radius, 20px);\n }\n ",this.draggableEl=document.createElement("div"),this.draggableEl.classList.add("draggable"),this.settings.draggableOver&&this.draggableEl.classList.add("over"),t+="\n .cupertino-pane-wrapper .draggable {\n padding: 5px;\n position: absolute;\n left: 0;\n right: 0;\n margin-left: auto;\n margin-right: auto;\n height: 30px;\n z-index: 12;\n top: 0;\n bottom: initial;\n }\n .cupertino-pane-wrapper .draggable.over {\n top: -30px;\n padding: 15px;\n }\n .cupertino-pane-wrapper.inverse .draggable {\n bottom: 0;\n top: initial;\n }\n .cupertino-pane-wrapper.inverse .draggable.over {\n bottom: -30px;\n top: initial;\n }\n ",this.moveEl=document.createElement("div"),this.moveEl.classList.add("move"),t+=`\n .cupertino-pane-wrapper .move {\n margin: 0 auto;\n height: 5px;\n background: var(--cupertino-pane-move-background, #c0c0c0);\n width: 36px;\n border-radius: 4px;\n }\n .cupertino-pane-wrapper .draggable.over .move {\n width: 70px; \n background: var(--cupertino-pane-move-background, rgba(225, 225, 225, 0.6));\n ${Support.backdropFilter?"\n backdrop-filter: saturate(180%) blur(20px);\n -webkit-backdrop-filter: saturate(180%) blur(20px);\n ":""}\n }\n .cupertino-pane-wrapper.inverse .move {\n margin-top: 15px;\n }\n .cupertino-pane-wrapper.inverse .draggable.over .move {\n margin-top: -5px;\n }\n `,this.destroyButtonEl=document.createElement("div"),this.destroyButtonEl.classList.add("destroy-button"),t+="\n .cupertino-pane-wrapper .destroy-button {\n width: 26px;\n height: 26px;\n position: absolute;\n background: var(--cupertino-pane-destroy-button-background, #ebebeb);\n fill: var(--cupertino-pane-icon-close-color, #7a7a7e);\n right: 20px;\n z-index: 14;\n border-radius: 100%;\n top: 16px;\n }\n ",this.contentEl=this.el,this.contentEl.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.contentEl.style.overflowX="hidden",t+="\n .cupertino-pane-wrapper .backdrop {\n overflow: hidden;\n position: fixed;\n width: 100%;\n bottom: 0;\n right: 0;\n left: 0;\n top: 0;\n display: none;\n z-index: 10;\n }\n ",this.addStyle(t),this.parentEl.appendChild(this.wrapperEl),this.wrapperEl.appendChild(this.paneEl),this.paneEl.appendChild(this.contentEl),this.settings.showDraggable&&(this.paneEl.appendChild(this.draggableEl),this.draggableEl.appendChild(this.moveEl))}present(t={animate:!1}){var e;return __awaiter(this,void 0,void 0,(function*(){if(this.el)if(this.isPanePresented()&&this.rendered)this.moveToBreak(this.settings.initialBreak);else if(!this.isPanePresented()||this.rendered){if(this.settings.onWillPresent(),this.updateScreenHeights(),this.drawBaseElements(),yield this.setBreakpoints(),this.paneEl.style.height=this.getPaneHeight()+"px",this.settings.inverse&&(this.paneEl.style.top=`-${this.breakpoints.bottomer}px`),this.wrapperEl.style.display="block",this.contentEl.style.display="block",this.wrapperEl.classList.add("rendered"),this.rendered=!0,this.settings.followerElement){if(!document.querySelector(this.settings.followerElement))return void console.warn("Cupertino Pane: wrong follower element selector specified",this.settings.followerElement);this.followerEl=document.querySelector(this.settings.followerElement),this.followerEl.style.willChange="transform, border-radius",this.followerEl.style.transform="translateY(0px) translateZ(0px)",this.followerEl.style.transition=`all ${this.settings.animationDuration}ms ${this.getTimingFunction(null===(e=this.settings.breaks[this.currentBreak()])||void 0===e?void 0:e.bounce)} 0s`}this.settings.zStack&&(this.setZstackConfig(this.settings.zStack),this.setPushMultiplicators()),this.settings.buttonClose&&this.settings.buttonDestroy&&!this.settings.inverse&&(this.paneEl.appendChild(this.destroyButtonEl),this.destroyButtonEl.addEventListener("click",t=>this.destroy({animate:!0,destroyButton:!0})),this.destroyButtonEl.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\n <path d="M278.6 256l68.2-68.2c6.2-6.2 6.2-16.4 0-22.6-6.2-6.2-16.4-6.2-22.6 0L256 233.4l-68.2-68.2c-6.2-6.2-16.4-6.2-22.6 0-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3l68.2 68.2-68.2 68.2c-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3 6.2 6.2 16.4 6.2 22.6 0l68.2-68.2 68.2 68.2c6.2 6.2 16.4 6.2 22.6 0 6.2-6.2 6.2-16.4 0-22.6L278.6 256z"/>\n </svg>'),this.settings.bottomClose&&(this.settings.breaks.bottom.enabled=!0),this.settings.freeMode&&(this.settings.lowerThanBottom=!1),this.settings.backdrop&&this.renderBackdrop(),this.device.android&&(document.body.style.overscrollBehaviorY="none"),this.events.attachAllEvents(),t.animate?this.doTransition({type:"present",translateY:this.breakpoints.breaks[this.settings.initialBreak]}):(this.breakpoints.prevBreakpoint=this.settings.initialBreak,this.paneEl.style.transform=`translateY(${this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.settings.backdrop&&(this.backdropEl.style.display="block"),this.settings.zStack&&this.settings.zStack.pushElements.forEach(t=>this.pushTransition(document.querySelector(t),this.breakpoints.breaks[this.settings.initialBreak],"unset")),this.settings.onDidPresent()),this.checkOpacityAttr(this.breakpoints.currentBreakpoint),yield new Promise(t=>setTimeout(()=>t(!0),150)),this.scrollElementInit(),this.checkOverflowAttr(this.breakpoints.currentBreakpoint)}else console.warn("Cupertino Pane: specified selector or DOM element already in use",this.selector)}))}getPaneHeight(){return this.settings.inverse?this.breakpoints.bottomer+this.settings.bottomOffset:this.screen_height-this.breakpoints.topper-this.settings.bottomOffset}updateScreenHeights(){this.settings.inverse?(this.screen_height=window.innerHeight,this.screenHeightOffset=0):(this.screen_height=window.innerHeight,this.screenHeightOffset=window.innerHeight)}scrollElementInit(){let t=this.el.querySelectorAll("[overflow-y]");!t.length||t.length>1?this.overflowEl=this.contentEl:(this.overflowEl=t[0],this.overflowEl.style.overflowX="hidden"),this.settings.topperOverflow&&(this.settings.upperThanTop&&console.warn('Cupertino Pane: "upperThanTop" allowed for disabled "topperOverflow"'),this.setOverflowHeight())}setOverflowHeight(t=0){this.settings.inverse?this.overflowEl.style.height=this.getPaneHeight()-30-this.settings.topperOverflowOffset-this.overflowEl.offsetTop+"px":this.overflowEl.style.height=this.getPaneHeight()-this.settings.topperOverflowOffset-this.overflowEl.offsetTop-t+"px"}checkOpacityAttr(t){let e=this.el.querySelectorAll("[hide-on-bottom]");e.length&&(this.settings.inverse||e.forEach(e=>{e.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,e.style.opacity=t>=this.breakpoints.breaks.bottom?"0":"1"}))}checkOverflowAttr(t){this.settings.topperOverflow&&this.overflowEl&&(this.settings.inverse?this.overflowEl.style.overflowY=t>=this.breakpoints.bottomer?"auto":"hidden":this.overflowEl.style.overflowY=t<=this.breakpoints.topper?"auto":"hidden")}isPanePresented(){let t=Array.from(document.querySelectorAll(".cupertino-pane-wrapper.rendered"));return!!t.length&&!!t.find(t=>t.contains(this.selector))}getTimingFunction(t){return t?"cubic-bezier(0.175, 0.885, 0.370, 1.120)":this.settings.animationType}isBackdropPresented(){return!!document.querySelector(".cupertino-pane-wrapper .backdrop")}renderBackdrop(){this.backdropEl=document.createElement("div"),this.backdropEl.classList.add("backdrop"),this.backdropEl.style.transition=`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.backdropEl.style.backgroundColor=`rgba(0,0,0, ${this.settings.backdropOpacity})`,this.wrapperEl.appendChild(this.backdropEl),this.backdropEl.addEventListener("click",t=>this.settings.onBackdropTap())}addStyle(t){if(document.querySelector("#cupertino-panes-internal"))return;const e=document.createElement("style");e.id="cupertino-panes-internal",t=t.replace(/\s\s+/g," "),e.textContent=t,document.head.prepend(e)}setPushMultiplicators(){this.settings.zStack.pushElements.forEach(t=>{let e=document.querySelector(t),s=this.getPushMulitplicator(e);s=s?s+1:1,e.style.setProperty("--push-multiplicator",""+s)})}clearPushMultiplicators(){for(let t=0;t<this.settings.zStack.pushElements.length;t++){let e=document.querySelector(this.settings.zStack.pushElements[t]),s=this.getPushMulitplicator(e);s-=1,s?e.style.setProperty("--push-multiplicator",""+s):e.style.removeProperty("--push-multiplicator")}}getPushMulitplicator(t){let e=t.style.getPropertyValue("--push-multiplicator");return parseInt(e)}setZstackConfig(t){this.settings.zStack=t?Object.assign(Object.assign({},this.zStackDefaults),t):null}backdrop(t={show:!0}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call backdrop()"),null;this.isBackdropPresented()||(this.renderBackdrop(),this.events.resetEvents());const e=()=>{this.backdropEl.style.transition="initial",this.backdropEl.style.display="none",this.backdropEl.removeEventListener("transitionend",e)};if(this.backdropEl.style.transition=`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.backdropEl.style.backgroundColor="rgba(0,0,0,.0)",t.show)this.backdropEl.style.display="block",setTimeout(()=>{this.backdropEl.style.backgroundColor=`rgba(0,0,0, ${this.settings.backdropOpacity})`},50);else{if("none"===this.backdropEl.style.display)return;this.backdropEl.addEventListener("transitionend",e)}}getPanelTransformY(){return parseFloat(/\.*translateY\((.*)px\)/i.exec(this.paneEl.style.transform)[1])}preventDismiss(t=!1){this.preventDismissEvent=t}disableDrag(){this.disableDragEvents=!0}enableDrag(){this.disableDragEvents=!1}setBreakpoints(t){return __awaiter(this,void 0,void 0,(function*(){!this.isPanePresented()||t?yield this.breakpoints.buildBreakpoints(t):console.warn("Cupertino Pane: Provide any breaks configuration")}))}calcFitHeight(){return __awaiter(this,void 0,void 0,(function*(){return this.wrapperEl&&this.el?this.breakpoints.calcHeightInProcess?(console.warn("Cupertino Pane: calcFitHeight() already in process"),null):void(yield this.breakpoints.buildBreakpoints(this.breakpoints.lockedBreakpoints)):null}))}moveToBreak(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToBreak()"),null;this.settings.breaks[t].enabled?(this.checkOpacityAttr(this.breakpoints.breaks[t]),this.checkOverflowAttr(this.breakpoints.breaks[t]),this.doTransition({type:"breakpoint",translateY:this.breakpoints.breaks[t]}),this.breakpoints.currentBreakpoint=this.breakpoints.breaks[t]):console.warn("Cupertino Pane: %s breakpoint disabled",t)}moveToHeight(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToHeight()"),null;let e=this.screenHeightOffset?this.screen_height-t:t;this.checkOpacityAttr(e),this.doTransition({type:"breakpoint",translateY:e})}hide(){return this.isPanePresented()?this.isHidden()?(console.warn("Cupertino Pane: Pane already hidden"),null):void this.doTransition({type:"hide",translateY:this.screenHeightOffset}):(console.warn("Cupertino Pane: Present pane before call hide()"),null)}isHidden(){return this.isPanePresented()?this.paneEl.style.transform===`translateY(${this.screenHeightOffset}px) translateZ(0px)`:(console.warn("Cupertino Pane: Present pane before call isHidden()"),null)}currentBreak(){return this.isPanePresented()?this.breakpoints.getCurrentBreakName():(console.warn("Cupertino Pane: Present pane before call currentBreak()"),null)}destroyResets(){this.parentEl.appendChild(this.contentEl),this.wrapperEl.remove(),this.events.detachAllEvents(),this.settings.zStack,delete this.rendered,delete this.breakpoints.prevBreakpoint,this.contentEl.style.display="none"}destroy(t={animate:!1,destroyButton:!1}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call destroy()"),null;this.preventDismissEvent?this.preventedDismiss||(this.settings.onWillDismiss({prevented:!0}),this.moveToBreak(this.breakpoints.prevBreakpoint)):(this.settings.onWillDismiss(),t.animate?this.doTransition({type:"destroy",translateY:this.screenHeightOffset,destroyButton:t.destroyButton}):(this.destroyResets(),this.settings.onDidDismiss({destroyButton:t.destroyButton})))}pushTransition(t,e,s){let i=this.settings.zStack.pushElements;t.style.transition=s,e=this.screenHeightOffset-e;const n=this.settings.zStack.minPushHeight?this.settings.zStack.minPushHeight:this.screenHeightOffset-this.breakpoints.bottomer,r=this.screenHeightOffset-this.breakpoints.topper;let o=this.getPushMulitplicator(t),a=Math.pow(this.settings.zStack.cardZScale,o),h=Math.pow(this.settings.zStack.cardZScale,o-1),l=6+this.settings.zStack.cardYOffset,p=l*o*-1,c=p+l,d=Math.pow(this.settings.zStack.cardContrast,o),u=Math.pow(this.settings.zStack.cardContrast,o-1);const g=(s,n,r,o)=>{let a=Math.pow(s,this.settings.zStack.stackZAngle/100);t.style.transform=`translateY(${n*(a/s)}px) scale(${s})`,t.style.borderRadius=o+"px",t.style.filter=`contrast(${r})`;let h=document.querySelector(i[i.length-1]);e||t.className!==h.className||this.clearPushMultiplicators()};if(e<=n)return void g(h,c,u,0);const b=(t,s)=>{let i=-1*(r*s-n*t);return i-=(t-s)*e,i/=n-r,i>s&&(i=s),i<t&&(i=t),i};g(b(a,h),b(p,c),b(d,u),-1*b(-10,0))}doTransition(t={}){var e;if("move"===t.type)return this.paneEl.style.transition="all 0ms linear 0ms",this.paneEl.style.transform=`translateY(${t.translateY}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transition="all 0ms linear 0ms",this.followerEl.style.transform=`translateY(${t.translateY-this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`),void(this.settings.zStack&&this.settings.zStack.pushElements.forEach(t=>this.pushTransition(document.querySelector(t),this.getPanelTransformY(),"all 0ms linear 0ms")));const s=()=>{"destroy"===t.type&&this.destroyResets(),this.paneEl.style.transition="initial",this.followerEl&&(this.followerEl.style.transition="initial"),this.settings.backdrop&&("destroy"!==t.type&&"hide"!==t.type||(this.backdropEl.style.transition="initial",this.backdropEl.style.display="none")),"present"===t.type&&this.settings.onDidPresent(),"destroy"===t.type&&this.settings.onDidDismiss({destroyButton:t.destroyButton}),this.settings.onTransitionEnd({target:document.body.contains(this.paneEl)?this.paneEl:null}),this.paneEl.removeEventListener("transitionend",s)};if("breakpoint"===t.type||"end"===t.type||"present"===t.type||"hide"===t.type||"destroy"===t.type){if(this.settings.backdrop&&(this.isHidden()||"hide"===t.type||"destroy"===t.type||"present"===t.type)&&(this.backdropEl.style.backgroundColor="rgba(0,0,0,.0)",this.backdropEl.style.transition=`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,"hide"!==t.type&&"destroy"!==t.type&&(this.backdropEl.style.display="block",setTimeout(()=>{this.backdropEl.style.backgroundColor=`rgba(0,0,0, ${this.settings.backdropOpacity})`},50))),"end"===t.type&&this.settings.freeMode)return;const i=Object.entries(this.settings.breaks).find(e=>e[1].height===this.screenHeightOffset-t.translateY),n=this.getTimingFunction(!(!i||!(null===(e=i[1])||void 0===e?void 0:e.bounce)));this.paneEl.style.transition=`transform ${this.settings.animationDuration}ms ${n} 0s`,this.followerEl&&(this.followerEl.style.transition=`transform ${this.settings.animationDuration}ms ${n} 0s`),this.settings.zStack&&setTimeout(()=>{this.settings.zStack.pushElements.forEach(e=>this.pushTransition(document.querySelector(e),t.translateY,`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`))},this.settings.zStack.cardYOffset&&"present"===t.type?50:0),setTimeout(()=>{this.settings.onTransitionStart({translateY:{new:t.translateY}}),this.paneEl.style.transform=`translateY(${t.translateY}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transform=`translateY(${t.translateY-this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`)},"present"===t.type?50:0);let r=Object.entries(this.breakpoints.breaks).find(e=>e[1]===t.translateY);return r&&(this.breakpoints.prevBreakpoint=r[0]),void this.paneEl.addEventListener("transitionend",s)}}}exports.CupertinoPane=CupertinoPane; | ||
//# sourceMappingURL=cupertino-pane.min.js.map |
@@ -20,4 +20,10 @@ import { CupertinoPane, CupertinoSettings } from 'cupertino-pane'; | ||
private steps; | ||
private inputBlured; | ||
private inputBluredbyMove; | ||
private movedByKeyboard; | ||
constructor(instance: CupertinoPane, settings: CupertinoSettings, device: Device, breakpoints: Breakpoints); | ||
attachAllEvents(): void; | ||
detachAllEvents(): void; | ||
resetEvents(): void; | ||
private touchEvents; | ||
private eventListeners; | ||
/** | ||
@@ -69,7 +75,8 @@ * Touch Start Event | ||
*/ | ||
onOrientationChangeCb: (e: any) => Promise<void>; | ||
private onOrientationChange; | ||
onWindowResizeCb: (e: any) => Promise<void>; | ||
private onWindowResize; | ||
/** | ||
* Private class methods | ||
*/ | ||
private getEvetClientYX; | ||
/** | ||
@@ -85,4 +92,6 @@ * Fix android keyboard issue with transition | ||
private willScrolled; | ||
private isPaneDescendant; | ||
private isFormElement; | ||
private isElementScrollable; | ||
private isOnViewport; | ||
} |
@@ -11,2 +11,10 @@ export interface PaneBreak { | ||
} | ||
export interface ZStackSettings { | ||
pushElements: string[]; | ||
minPushHeight?: number; | ||
cardYOffset?: number; | ||
cardZScale?: number; | ||
cardContrast?: number; | ||
stackZAngle?: number; | ||
} | ||
export interface TransitionStartEvent { | ||
@@ -22,8 +30,6 @@ translateY: { | ||
followerElement: string; | ||
cssClass: string; | ||
fitHeight: boolean; | ||
maxFitHeight: number; | ||
fitScreenHeight: boolean; | ||
pushElement: any; | ||
pushMinHeight: number; | ||
pushYOffset: number; | ||
backdrop: boolean; | ||
@@ -34,3 +40,2 @@ backdropOpacity: number; | ||
bottomOffset: number; | ||
darkMode: boolean; | ||
bottomClose: boolean; | ||
@@ -57,2 +62,3 @@ fastSwipeClose: boolean; | ||
breaks: PaneBreaks; | ||
zStack: ZStackSettings; | ||
onDidDismiss: (event?: CustomEvent) => void; | ||
@@ -63,3 +69,3 @@ onWillDismiss: (event?: CustomEvent) => void; | ||
onDragStart: (event?: CustomEvent) => void; | ||
onDrag: (event?: CustomEvent) => void; | ||
onDrag: (event?: any) => void; | ||
onDragEnd: (event?: CustomEvent) => void; | ||
@@ -66,0 +72,0 @@ onBackdropTap: (event?: CustomEvent) => void; |
{ | ||
"name": "cupertino-pane", | ||
"description": "Multiplatform slide-over pane", | ||
"version": "1.2.32", | ||
"description": "Multi-functional panes and boards for next generation progressive applications", | ||
"version": "1.2.61", | ||
"author": "Roman Antonov (roman-rr)", | ||
@@ -6,0 +6,0 @@ "homepage": "https://github.com/roman-rr/cupertino-pane/", |
105
README.md
@@ -1,3 +0,7 @@ | ||
# Cupertino Pane | ||
<p align="center"> | ||
<img alt="Cupertino Panes is multi-functional panes & boards with touch technologies" src="docs/logo/logo-1-mini.jpg" width="600" /> | ||
</p> | ||
# Cupertino Panes | ||
[](https://circleci.com/gh/roman-rr/cupertino-pane) | ||
@@ -9,7 +13,9 @@  | ||
[](https://github.com/airbnb/javascript) | ||
[](https://opencollective.com/cupertino-pane) | ||
<!-- <img src="https://user-images.githubusercontent.com/10646478/79794348-4846bc00-837c-11ea-8b74-7c71fac120aa.png" | ||
align="right" alt="Cupertino Pane logo Roman Antonov" width="260px" height="421px"> --> | ||
Cupertino Pane is great modern slide-over pane with touch technologies. <br> | ||
Cupertino Panes is multi-functional panes & boards with touch technologies. <br> | ||
@@ -24,23 +30,53 @@ * **Small.** 5kb (minified and gzipped). No dependencies. | ||
* [Breaking changes](#breaking-changes) | ||
* [Demonstration](#demonstration) | ||
* [Financial Contributors](#financial-contributors) | ||
* [Supporting platforms](#supporting-platforms) | ||
* [Getting Started](#getting-started) | ||
* [Settings](#settings) | ||
* [Breakpoints](#breakpoints) | ||
* [Z-Stack](#z-stack) | ||
* [Callbacks](#callback) | ||
* [Public Methods](#public-methods) | ||
* [Attributes](#attributes) | ||
* [CSS Variables](#css-variables) | ||
* [Keyboard issues](#keyboard-issues) | ||
* [Future Goals](#future-goals) | ||
* [Contributing](#contributing) | ||
* [Contributors](#contributors) | ||
* [Changelog](https://github.com/roman-rr/cupertino-pane/blob/master/CHANGELOG.md) | ||
* [License](#license) | ||
## Financial Contributors | ||
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/cupertino-pane/contribute)] | ||
#### Individuals | ||
<a href="https://opencollective.com/cupertino-pane"><img src="https://opencollective.com/cupertino-pane/individuals.svg?width=890"></a> | ||
#### Organizations | ||
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/cupertino-pane/contribute)] | ||
<a href="https://opencollective.com/cupertino-pane/organization/0/website"><img src="https://opencollective.com/cupertino-pane/organization/0/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/1/website"><img src="https://opencollective.com/cupertino-pane/organization/1/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/2/website"><img src="https://opencollective.com/cupertino-pane/organization/2/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/3/website"><img src="https://opencollective.com/cupertino-pane/organization/3/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/4/website"><img src="https://opencollective.com/cupertino-pane/organization/4/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/5/website"><img src="https://opencollective.com/cupertino-pane/organization/5/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/6/website"><img src="https://opencollective.com/cupertino-pane/organization/6/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/7/website"><img src="https://opencollective.com/cupertino-pane/organization/7/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/8/website"><img src="https://opencollective.com/cupertino-pane/organization/8/avatar.svg"></a> | ||
<a href="https://opencollective.com/cupertino-pane/organization/9/website"><img src="https://opencollective.com/cupertino-pane/organization/9/avatar.svg"></a> | ||
## Demonstration | ||
- [Base live](https://output.jsbin.com/fuhisey) | ||
- [Z-Stack live](https://output.jsbin.com/wedegox) | ||
- [Overflow top live](https://output.jsbin.com/baguroy) | ||
- [Z-stack full live](https://output.jsbin.com/benidub) | ||
- [Z-Stack simple live](https://output.jsbin.com/daqihir) | ||
- [3D Push live](https://output.jsbin.com/vidaqa) | ||
- [3 Panes live](https://jsbin.com/xavifaf) | ||
- [Overflow top-middle live](https://output.jsbin.com/piwecad) | ||
- [Draggable over live](https://jsbin.com/hamedec) | ||
- [Prevent dismiss live](https://output.jsbin.com/keravam) | ||
- [Top-to-bottom live](https://output.jsbin.com/muhabuf) | ||
- [3D Push live](https://output.jsbin.com/tutegad) | ||
- [Overflow top live](https://output.jsbin.com/baguroy) | ||
- [Overflow top-middle live](https://output.jsbin.com/piwecad) | ||
- [Follower live](https://output.jsbin.com/xogavec) | ||
@@ -161,10 +197,7 @@ - [Apple Clips live](https://output.jsbin.com/luqaxud) | ||
| **followerElement** | `string` | Follower element selector | Element with selector will following pane transitions | | ||
| **cssClass** | `string` | null | Additional classes to apply for wrapper to stylize different panes | | ||
| **fitHeight** | `boolean` | 'false' | Automatically calc and define content height as top breakpoint. Middle and bottom breakpoint will be disabled | | ||
| **maxFitHeight** | `number` | 'null' | Define a maximum possible automatically calculated height with `fitHeight` property | | ||
| **fitScreenHeight** | `boolean` | 'true' | On `true` will automatically adjust pane maximum height to screen height | | ||
| **pushElement** | `string` | Push element selector | DOM Element will be pushed and scaled | | ||
| **pushMinHeight** | `number` | Most bottom available point | Height from which 3d push effect will be started | | ||
| **pushYOffset** | `number` | Negative margin value to place pushed element upper | | ||
| **initialBreak** | `'top' \| 'middle' \| 'bottom'` | 'middle' | Initial pane position | | ||
| **darkMode** | `boolean` | false | Initial pane styles | | ||
| **backdrop** | `boolean` | false | Dimmed overlay will rendered with pane if `true` | | ||
@@ -194,2 +227,3 @@ | **backdropOpacity** | `number` | 0.4 | Dimmed overlay opacity value | | ||
| **passiveListeners** | `boolean` | true | (Indicates that the function specified by listener will never call preventDefault()) | | ||
### Breakpoints | ||
@@ -216,2 +250,22 @@ Package now supports 3 base breakpoints | ||
### Z-Stack | ||
Configuration for 3D push effects and z-stack | ||
```js | ||
let settings = { | ||
... | ||
zStack: { | ||
pushElements: ['.card-1', '.main-content'], | ||
pushYOffset: 10 | ||
} | ||
} | ||
``` | ||
| Property | Type | Default | Description | | ||
| - | - | - | - | | ||
| **pushElements** | `string[]` | null | DOM Element will be pushed and scaled | | ||
| **minPushHeight** | `number` | null | Height from which 3d push effect will be started | | ||
| **cardYOffset** | `number` | null | Margin value to place pushed elements upper | | ||
| **cardZScale** | `number` | 0.93 | Scale value for each pushed element | | ||
| **cardContrast** | `number` | 0.85 | Contrast value for each pushed element | | ||
| **stackZAngle** | `number` | 160 | Value from 0 to 3000 that define angle of z-stack in common. 0 - 150 positive expontial angle. 150 - 170 = 45 degree angle. 200 - 3000 negative exponential angle | | ||
### Callbacks | ||
@@ -289,7 +343,2 @@ The function that executes when the event fires. | ||
``` | ||
### setDarkMode({enable: **boolean = false**}) | ||
Enable dark scheme color for some elements | ||
```javascript | ||
myPane.setDarkMode({enable: true}); // enable darkmode | ||
``` | ||
### setBreakpoints(breakpoints: **PaneBreaks**) | ||
@@ -350,2 +399,13 @@ Method updates breakpoints configuration for rendered Pane | ||
## CSS Variables | ||
| Variable | Default | | ||
| - | - | | ||
| **--cupertino-pane-background** | `#ffffff` | | ||
| **--cupertino-pane-color** | `#333333` | | ||
| **--cupertino-pane-shadow** | `#0 4px 16px rgba(0,0,0,.12)` | | ||
| **--cupertino-pane-border-radius** | `#20px` | | ||
| **--cupertino-pane-move-background** | `#c0c0c0` | | ||
| **--cupertino-pane-destroy-button-background** | `#ebebeb` | | ||
| **--cupertino-pane-icon-close-color** | `#7a7a7e` | | ||
## Keyboard issues | ||
@@ -371,11 +431,6 @@ Inputs and textareas in pane may push mobile keyboard on devices, and close pane visibility. Next cases describe how to proper handle this issues. | ||
## Future Goals | ||
- [Issues] Handle keyboard only for Pane inputs, #125, #127 | ||
- [Docs] ($150 budget) -> Package branding | ||
- [Code] Fix immutable issue in breakpoint class | ||
- [Accurance] Draw experiment application (Normal/TimeStamp/Native) - Native Touch Plugin | ||
- [Docs] (Traffic + Carbon ads) -> Docs engine (F7, Netlify, Gatsby, GH pages) | ||
- [Showcase] Apple Music F7 | ||
- [Platforms] C++ QT version | ||
Project under regularly maintanance and bug fixes. | ||
All **new features** and **new investigations** moved to open collective [Goals](https://opencollective.com/cupertino-pane/conversations/all-goals-and-featured-packages-o60ddaqg) | ||
## Contributing | ||
## Contributors | ||
We are welcome contributions of all kinds from anyone. | ||
@@ -382,0 +437,0 @@ Please review the [contributing](https://github.com/roman-rr/cupertino-pane/blob/master/CONTRIBUTING.md) guideline. |
@@ -80,6 +80,7 @@ import { CupertinoPane, CupertinoSettings } from './cupertino-pane'; | ||
} | ||
if (this.settings.breaks['top'] && this.settings.breaks['middle'] | ||
&& this.settings.breaks['top'].height === this.settings.breaks['middle']?.height) { | ||
this.settings.breaks['middle'].enabled = false; | ||
this.settings.initialBreak = 'top'; | ||
if (this.settings.breaks['top'] && this.settings.breaks['middle']) { | ||
if (this.settings.breaks['top'].height - 50 <= this.settings.breaks['middle'].height) { | ||
this.settings.breaks['middle'].enabled = false; | ||
this.settings.initialBreak = 'top'; | ||
} | ||
} | ||
@@ -113,9 +114,8 @@ } | ||
// Save breakpoints (not for resize event) | ||
// TODO: solve immutable issue: 1.Weak set 2. Use In events.ts | ||
if (lock) { | ||
// initial lock on present | ||
if (!this.lockedBreakpoints) { | ||
this.lockedBreakpoints = JSON.stringify(this.settings.breaks); | ||
} | ||
// Warnings | ||
// Warnings | ||
if (!this.instance.isPanePresented()) { | ||
@@ -152,2 +152,10 @@ if (!this.settings.breaks[this.settings.initialBreak].enabled) { | ||
this.currentBreakpoint = this.breaks[this.settings.initialBreak]; | ||
// Disable overflow for top bulletin | ||
if (this.settings.inverse | ||
&& !this.settings.breaks.bottom.enabled | ||
&& !this.settings.breaks.middle.enabled) { | ||
this.settings.topperOverflow = false; | ||
} | ||
} | ||
@@ -171,3 +179,3 @@ | ||
this.instance.paneEl.style.height = `${this.instance.getPaneHeight()}px`; | ||
this.instance.scrollElementInit(); | ||
@@ -174,0 +182,0 @@ this.instance.checkOpacityAttr(this.currentBreakpoint); |
import { Support } from './support'; | ||
import { Device } from './device'; | ||
import { Events } from './events'; | ||
import { PaneSettings, PaneBreaks } from './models'; | ||
import { PaneSettings, PaneBreaks, ZStackSettings } from './models'; | ||
import { Settings } from './settings'; | ||
@@ -15,3 +15,2 @@ import { Breakpoints } from './breakpoints'; | ||
public preventedDismiss: boolean = false; | ||
private iconCloseColor: string = '#7a7a7e'; | ||
public rendered: boolean = false; | ||
@@ -24,9 +23,8 @@ | ||
public contentEl: HTMLElement; | ||
private parentEl: HTMLElement; | ||
public parentEl: HTMLElement; | ||
public backdropEl: HTMLDivElement; | ||
private draggableEl: HTMLDivElement; | ||
private moveEl: HTMLDivElement; | ||
private backdropEl: HTMLDivElement; | ||
private destroyButtonEl: HTMLDivElement; | ||
private followerEl: HTMLElement; | ||
private pushElement: HTMLElement; | ||
@@ -38,2 +36,11 @@ private settings: CupertinoSettings = (new Settings()).instance; | ||
private zStackDefaults: ZStackSettings = { | ||
pushElements: null, | ||
minPushHeight: null, | ||
cardYOffset: 0, | ||
cardZScale: 0.93, | ||
cardContrast: 0.85, | ||
stackZAngle: 160, | ||
}; | ||
constructor(private selector: (string | HTMLElement), | ||
@@ -77,2 +84,3 @@ conf: CupertinoSettings = {}) { | ||
private drawBaseElements() { | ||
// Parent | ||
this.parentEl = this.settings.parentElement; | ||
@@ -82,4 +90,11 @@ | ||
this.wrapperEl = document.createElement('div'); | ||
this.wrapperEl.className = `cupertino-pane-wrapper ${this.el.className}`; | ||
this.addStyle(` | ||
this.wrapperEl.classList.add('cupertino-pane-wrapper'); | ||
if (this.settings.inverse) { | ||
this.wrapperEl.classList.add('inverse'); | ||
} | ||
if (this.settings.cssClass) { | ||
this.wrapperEl.className += ` ${this.settings.cssClass}`; | ||
}; | ||
let internalStyles: string = ''; | ||
internalStyles += ` | ||
.cupertino-pane-wrapper { | ||
@@ -91,8 +106,9 @@ display: none; | ||
} | ||
`); | ||
`; | ||
// Panel | ||
// Panel (appying transform ASAP, avoid timeouts for animate:true) | ||
this.paneEl = document.createElement('div'); | ||
this.paneEl.className = 'pane'; | ||
this.addStyle(` | ||
this.paneEl.style.transform = `translateY(${this.screenHeightOffset}px) translateZ(0px)`; | ||
this.paneEl.classList.add('pane'); | ||
internalStyles += ` | ||
.cupertino-pane-wrapper .pane { | ||
@@ -107,23 +123,27 @@ position: fixed; | ||
margin-right: auto; | ||
background: #ffffff; | ||
box-shadow: 0 4px 16px rgba(0,0,0,.12); | ||
overflow = hidden; | ||
will-change = transform; | ||
transform: translateY(${this.screenHeightOffset}px) translateZ(0px); | ||
${ | ||
!this.settings.inverse ? | ||
`padding-top: 15px; border-radius: 20px 20px 0 0;` | ||
: `padding-bottom: 15px; border-radius: 0 0 20px 20px;` | ||
} | ||
background: var(--cupertino-pane-background, #ffffff); | ||
color: var(--cupertino-pane-color, #333333); | ||
box-shadow: var(--cupertino-pane-shadow, 0 4px 16px rgba(0,0,0,.12)); | ||
will-change: transform; | ||
padding-top: 15px; | ||
border-radius: var(--cupertino-pane-border-radius, 20px) | ||
var(--cupertino-pane-border-radius, 20px) | ||
0 0; | ||
} | ||
.cupertino-pane-wrapper.darkmode .pane { | ||
background: #1c1c1d; | ||
color: #ffffff; | ||
.cupertino-pane-wrapper.inverse .pane { | ||
padding-bottom: 15px; | ||
border-radius: 0 0 20px 20px; | ||
border-radius: 0 0 | ||
var(--cupertino-pane-border-radius, 20px) | ||
var(--cupertino-pane-border-radius, 20px); | ||
} | ||
`); | ||
`; | ||
// Draggable | ||
this.draggableEl = document.createElement('div'); | ||
this.draggableEl.className = 'draggable'; | ||
this.addStyle(` | ||
this.draggableEl.classList.add('draggable'); | ||
if (this.settings.draggableOver) { | ||
this.draggableEl.classList.add('over'); | ||
} | ||
internalStyles += ` | ||
.cupertino-pane-wrapper .draggable { | ||
@@ -138,25 +158,34 @@ padding: 5px; | ||
z-index: 12; | ||
${ | ||
!this.settings.inverse ? | ||
`top: 0;` | ||
: `bottom: 0;` | ||
} | ||
${!this.settings.showDraggable ? `opacity: 0;` : ``} | ||
${this.settings.draggableOver ? `top: -30px;padding: 15px;` : ``} | ||
top: 0; | ||
bottom: initial; | ||
} | ||
`); | ||
.cupertino-pane-wrapper .draggable.over { | ||
top: -30px; | ||
padding: 15px; | ||
} | ||
.cupertino-pane-wrapper.inverse .draggable { | ||
bottom: 0; | ||
top: initial; | ||
} | ||
.cupertino-pane-wrapper.inverse .draggable.over { | ||
bottom: -30px; | ||
top: initial; | ||
} | ||
`; | ||
// Move | ||
this.moveEl = document.createElement('div'); | ||
this.moveEl.className = 'move'; | ||
this.addStyle(` | ||
this.moveEl.classList.add('move'); | ||
internalStyles += ` | ||
.cupertino-pane-wrapper .move { | ||
margin: 0 auto; | ||
height: 5px; | ||
background: #c0c0c0; | ||
background: var(--cupertino-pane-move-background, #c0c0c0); | ||
width: 36px; | ||
border-radius: 4px; | ||
${this.settings.inverse ? `margin-top: 15px;`: ``} | ||
${this.settings.draggableOver ? `width: 70px; background: rgba(225, 225, 225, 0.6);` : ``} | ||
${this.settings.draggableOver && Support.backdropFilter ? ` | ||
} | ||
.cupertino-pane-wrapper .draggable.over .move { | ||
width: 70px; | ||
background: var(--cupertino-pane-move-background, rgba(225, 225, 225, 0.6)); | ||
${Support.backdropFilter ? ` | ||
backdrop-filter: saturate(180%) blur(20px); | ||
@@ -166,17 +195,20 @@ -webkit-backdrop-filter: saturate(180%) blur(20px); | ||
} | ||
.cupertino-pane-wrapper.darkmode .move { | ||
background: #5a5a5e; | ||
.cupertino-pane-wrapper.inverse .move { | ||
margin-top: 15px; | ||
} | ||
`); | ||
.cupertino-pane-wrapper.inverse .draggable.over .move { | ||
margin-top: -5px; | ||
} | ||
`; | ||
// Close button | ||
// Destroy button | ||
this.destroyButtonEl = document.createElement('div'); | ||
this.destroyButtonEl.className = 'destroy-button'; | ||
this.addStyle(` | ||
this.destroyButtonEl.classList.add('destroy-button'); | ||
internalStyles += ` | ||
.cupertino-pane-wrapper .destroy-button { | ||
${!this.settings.inverse ? ` | ||
width: 26px; | ||
height: 26px; | ||
position: absolute; | ||
background: #ebebeb; | ||
background: var(--cupertino-pane-destroy-button-background, #ebebeb); | ||
fill: var(--cupertino-pane-icon-close-color, #7a7a7e); | ||
right: 20px; | ||
@@ -186,8 +218,4 @@ z-index: 14; | ||
top: 16px; | ||
`:``} | ||
} | ||
.cupertino-pane-wrapper.darkmode .destroy-button { | ||
background: #424246; | ||
} | ||
`); | ||
`; | ||
@@ -198,9 +226,29 @@ // Content user element | ||
this.contentEl.style.overflowX = 'hidden'; | ||
// Backdrop | ||
internalStyles += ` | ||
.cupertino-pane-wrapper .backdrop { | ||
overflow: hidden; | ||
position: fixed; | ||
width: 100%; | ||
bottom: 0; | ||
right: 0; | ||
left: 0; | ||
top: 0; | ||
display: none; | ||
z-index: 10; | ||
} | ||
`; | ||
// inject DOM | ||
this.parentEl.appendChild(this.wrapperEl); | ||
this.wrapperEl.appendChild(this.paneEl); | ||
this.paneEl.appendChild(this.draggableEl); | ||
this.paneEl.appendChild(this.contentEl); | ||
this.draggableEl.appendChild(this.moveEl); | ||
// Inject internal CSS | ||
this.addStyle(internalStyles); | ||
// inject DOM | ||
this.parentEl.appendChild(this.wrapperEl); | ||
this.wrapperEl.appendChild(this.paneEl); | ||
this.paneEl.appendChild(this.contentEl); | ||
if (this.settings.showDraggable) { | ||
this.paneEl.appendChild(this.draggableEl); | ||
this.draggableEl.appendChild(this.moveEl); | ||
} | ||
} | ||
@@ -227,5 +275,6 @@ | ||
this.updateScreenHeights(); | ||
await this.drawBaseElements(); | ||
this.drawBaseElements(); | ||
await this.setBreakpoints(); | ||
// Necessary Inlines with breakpoints | ||
this.paneEl.style.height = `${this.getPaneHeight()}px`; | ||
@@ -235,2 +284,4 @@ if (this.settings.inverse) { | ||
} | ||
// Show elements | ||
this.wrapperEl.style.display = 'block'; | ||
@@ -240,3 +291,3 @@ this.contentEl.style.display = 'block'; | ||
this.rendered = true; | ||
if (this.settings.followerElement) { | ||
@@ -256,10 +307,8 @@ if (!<HTMLElement>document.querySelector(this.settings.followerElement)) { | ||
if (this.settings.pushElement) { | ||
this.pushElement = <HTMLElement>document.querySelector(this.settings.pushElement); | ||
} | ||
if (this.settings.darkMode) { | ||
this.setDarkMode({enable: true}); | ||
} | ||
// Assign multiplicators for push elements | ||
if (this.settings.zStack) { | ||
this.setZstackConfig(this.settings.zStack); | ||
this.setPushMultiplicators(); | ||
} | ||
if ((this.settings.buttonClose && this.settings.buttonDestroy) && !this.settings.inverse) { | ||
@@ -269,3 +318,3 @@ this.paneEl.appendChild(this.destroyButtonEl); | ||
this.destroyButtonEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> | ||
<path fill="${this.iconCloseColor}" d="M278.6 256l68.2-68.2c6.2-6.2 6.2-16.4 0-22.6-6.2-6.2-16.4-6.2-22.6 0L256 233.4l-68.2-68.2c-6.2-6.2-16.4-6.2-22.6 0-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3l68.2 68.2-68.2 68.2c-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3 6.2 6.2 16.4 6.2 22.6 0l68.2-68.2 68.2 68.2c6.2 6.2 16.4 6.2 22.6 0 6.2-6.2 6.2-16.4 0-22.6L278.6 256z"/> | ||
<path d="M278.6 256l68.2-68.2c6.2-6.2 6.2-16.4 0-22.6-6.2-6.2-16.4-6.2-22.6 0L256 233.4l-68.2-68.2c-6.2-6.2-16.4-6.2-22.6 0-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3l68.2 68.2-68.2 68.2c-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3 6.2 6.2 16.4 6.2 22.6 0l68.2-68.2 68.2 68.2c6.2 6.2 16.4 6.2 22.6 0 6.2-6.2 6.2-16.4 0-22.6L278.6 256z"/> | ||
</svg>`; | ||
@@ -293,3 +342,3 @@ } | ||
/****** Attach Events *******/ | ||
this.attachAllEvents(); | ||
this.events.attachAllEvents(); | ||
@@ -303,5 +352,13 @@ /****** Animation & Transition ******/ | ||
this.paneEl.style.transform = `translateY(${this.breakpoints.breaks[this.settings.initialBreak]}px) translateZ(0px)`; | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.breakpoints.breaks[this.settings.initialBreak], 'unset'); | ||
if (this.settings.backdrop) { | ||
this.backdropEl.style.display = `block`; | ||
} | ||
if (this.settings.zStack) { | ||
this.settings.zStack.pushElements.forEach(item => | ||
this.pushTransition( | ||
document.querySelector(item), | ||
this.breakpoints.breaks[this.settings.initialBreak], 'unset' | ||
) | ||
); | ||
} | ||
// Emit event | ||
@@ -326,63 +383,2 @@ this.settings.onDidPresent(); | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private attachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.attachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.attachEvents(el); | ||
}); | ||
} | ||
// Handle keyboard events for cordova | ||
if (this.settings.handleKeyboard && this.device.cordova) { | ||
window.addEventListener('keyboardWillShow', this.events.onKeyboardShowCb); | ||
window.addEventListener('keyboardWillHide', this.events.onKeyboardHideCb); | ||
} | ||
// Fix Android issue with resize if not handle | ||
if (!this.settings.handleKeyboard | ||
&& this.device.cordova | ||
&& this.device.android) { | ||
window.addEventListener('keyboardWillHide', () => { | ||
this.parentEl.scrollTop = 0; | ||
if (this.parentEl.parentElement) { | ||
this.parentEl.parentElement.scrollTop = 0; | ||
if (this.parentEl.parentElement.parentElement) { | ||
this.parentEl.parentElement.parentElement.scrollTop = 0; | ||
} | ||
} | ||
}); | ||
} | ||
window.addEventListener('orientationchange', this.events.onOrientationChangeCb); | ||
} | ||
private detachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.detachEvents(el); | ||
}); | ||
} | ||
// Handle keyboard events for cordova | ||
if (this.settings.handleKeyboard && this.device.cordova) { | ||
window.removeEventListener('keyboardWillShow', this.events.onKeyboardShowCb); | ||
window.removeEventListener('keyboardWillHide', this.events.onKeyboardHideCb); | ||
} | ||
window.removeEventListener('orientationchange', this.events.onOrientationChangeCb); | ||
} | ||
private resetEvents() { | ||
this.detachAllEvents(); | ||
this.attachAllEvents(); | ||
} | ||
public updateScreenHeights():void { | ||
@@ -417,9 +413,2 @@ if (this.settings.inverse) { | ||
public setOverflowHeight(offset = 0) { | ||
// overflowEl is not visible - ignoring execution | ||
// TODO: inputs only for visible elements | ||
if (this.overflowEl.offsetHeight === 0 | ||
&& this.overflowEl.offsetWidth === 0) { | ||
return; | ||
} | ||
if (!this.settings.inverse) { | ||
@@ -438,6 +427,2 @@ this.overflowEl.style.height = `${this.getPaneHeight() | ||
private getTimingFunction(bounce) { | ||
return bounce ? 'cubic-bezier(0.175, 0.885, 0.370, 1.120)' : this.settings.animationType; | ||
} | ||
public checkOpacityAttr(val) { | ||
@@ -454,3 +439,6 @@ let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
public checkOverflowAttr(val) { | ||
if (!this.settings.topperOverflow) return; | ||
if (!this.settings.topperOverflow | ||
|| !this.overflowEl) { | ||
return; | ||
} | ||
@@ -466,3 +454,3 @@ if (!this.settings.inverse) { | ||
// Check through all presented panes | ||
let wrappers = Array.from(document.querySelectorAll('.cupertino-pane-wrapper.rendered')); | ||
let wrappers = Array.from(document.querySelectorAll(`.cupertino-pane-wrapper.rendered`)); | ||
if (!wrappers.length) return false; | ||
@@ -527,2 +515,9 @@ return wrappers.find((item) => item.contains(<HTMLElement>this.selector)) ? true: false; | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private getTimingFunction(bounce) { | ||
return bounce ? 'cubic-bezier(0.175, 0.885, 0.370, 1.120)' : this.settings.animationType; | ||
} | ||
private isBackdropPresented() { | ||
@@ -535,19 +530,5 @@ return document.querySelector(`.cupertino-pane-wrapper .backdrop`) | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.addStyle(` | ||
.cupertino-pane-wrapper .backdrop { | ||
overflow: hidden; | ||
position: fixed; | ||
width: 100%; | ||
bottom: 0; | ||
right: 0; | ||
left: 0; | ||
top: 0; | ||
display: none; | ||
z-index: 10; | ||
transition: all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s; | ||
background-color: rgba(0,0,0, ${this.settings.backdropOpacity}); | ||
} | ||
`); | ||
this.backdropEl.classList.add('backdrop'); | ||
this.backdropEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.backdropEl.style.backgroundColor = `rgba(0,0,0, ${this.settings.backdropOpacity})`; | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
@@ -558,10 +539,47 @@ this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
/** | ||
* Utility function to add CSS in multiple passes. | ||
* Utility function to add minified internal CSS to head. | ||
* @param {string} styleString | ||
*/ | ||
private addStyle(styleString): void { | ||
if (document.querySelector('#cupertino-panes-internal')) return; | ||
const style = document.createElement('style'); | ||
style.id = 'cupertino-panes-internal'; | ||
styleString = styleString.replace(/\s\s+/g, ' '); | ||
style.textContent = styleString; | ||
document.head.prepend(style); | ||
}; | ||
// Z-Stack: Pushed elements multiplicators | ||
private setPushMultiplicators(): void { | ||
this.settings.zStack.pushElements.forEach((item) => { | ||
let pushElement: HTMLElement = document.querySelector(item); | ||
let multiplicator = this.getPushMulitplicator(pushElement); | ||
multiplicator = multiplicator ? multiplicator + 1 : 1; | ||
pushElement.style.setProperty('--push-multiplicator', `${multiplicator}`); | ||
}); | ||
} | ||
private clearPushMultiplicators(): void { | ||
for (let i = 0; i < this.settings.zStack.pushElements.length; i++) { | ||
let pushElement: HTMLElement = document.querySelector( | ||
this.settings.zStack.pushElements[i] | ||
); | ||
let multiplicator = this.getPushMulitplicator(pushElement); | ||
multiplicator -= 1; | ||
if (multiplicator) { | ||
pushElement.style.setProperty('--push-multiplicator', `${multiplicator}`); | ||
} else { | ||
pushElement.style.removeProperty('--push-multiplicator'); | ||
} | ||
} | ||
} | ||
private getPushMulitplicator(el: HTMLElement): number { | ||
let multiplicator: (string | number) = el.style.getPropertyValue('--push-multiplicator'); | ||
return parseInt(multiplicator); | ||
} | ||
public setZstackConfig(zStack: ZStackSettings): void { | ||
this.settings.zStack = zStack ? {...this.zStackDefaults, ...zStack} : null;; | ||
} | ||
@@ -580,3 +598,3 @@ /** | ||
// Reset events to attach backdrop stop propagation | ||
this.resetEvents(); | ||
this.events.resetEvents(); | ||
} | ||
@@ -606,104 +624,2 @@ | ||
/************************************ | ||
* Events | ||
*/ | ||
private touchEvents = (() => { | ||
const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel']; | ||
let desktop = ['mousedown', 'mousemove', 'mouseup']; | ||
if (Support.pointerEvents) { | ||
desktop = ['pointerdown', 'pointermove', 'pointerup']; | ||
} | ||
const touchEventsTouch = { | ||
start: touch[0], | ||
move: touch[1], | ||
end: touch[2], | ||
cancel: touch[3], | ||
}; | ||
const touchEventsDesktop = { | ||
start: desktop[0], | ||
move: desktop[1], | ||
end: desktop[2], | ||
}; | ||
return Support.touch || !this.settings.simulateTouch ? touchEventsTouch : touchEventsDesktop; | ||
})(); | ||
private attachEvents(el: Element) { | ||
// Touch Events | ||
if (!Support.touch && Support.pointerEvents) { | ||
el.addEventListener(this.touchEvents.start, this.events.touchStartCb, false); | ||
el.addEventListener(this.touchEvents.move, this.events.touchMoveCb, false); | ||
el.addEventListener(this.touchEvents.end, this.events.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener(this.touchEvents.move, this.events.touchMoveBackdropCb, false); | ||
} else { | ||
if (Support.touch) { | ||
const passiveListener = this.touchEvents.start === 'touchstart' && Support.passiveListener && this.settings.passiveListeners ? { passive: true, capture: false } : false; | ||
el.addEventListener(this.touchEvents.start, this.events.touchStartCb, passiveListener); | ||
el.addEventListener(this.touchEvents.move, this.events.touchMoveCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
el.addEventListener(this.touchEvents.end, this.events.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener(this.touchEvents.move, this.events.touchMoveBackdropCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
if (this.touchEvents['cancel']) { | ||
el.addEventListener(this.touchEvents['cancel'], this.events.touchEndCb, passiveListener); | ||
} | ||
} | ||
if ((this.settings.simulateTouch && !this.device.ios && !this.device.android) || (this.settings.simulateTouch && !Support.touch && this.device.ios)) { | ||
el.addEventListener('mousedown', this.events.touchStartCb, false); | ||
el.addEventListener('mousemove', this.events.touchMoveCb, false); | ||
el.addEventListener('mouseup', this.events.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener('mousemove', this.events.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.addEventListener('click', this.events.onClickCb, true); | ||
} | ||
} | ||
private detachEvents(el: Element) { | ||
// Touch Events | ||
if (!Support.touch && Support.pointerEvents) { | ||
el.removeEventListener(this.touchEvents.start, this.events.touchStartCb, false); | ||
el.removeEventListener(this.touchEvents.move, this.events.touchMoveCb, false); | ||
el.removeEventListener(this.touchEvents.end, this.events.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener(this.touchEvents.move, this.events.touchMoveBackdropCb, false); | ||
} else { | ||
if (Support.touch) { | ||
const passiveListener = this.touchEvents.start === 'onTouchStart' && Support.passiveListener && this.settings.passiveListeners ? { passive: true, capture: false } : false; | ||
el.removeEventListener(this.touchEvents.start, this.events.touchStartCb, passiveListener); | ||
el.removeEventListener(this.touchEvents.move, this.events.touchMoveCb, false); | ||
el.removeEventListener(this.touchEvents.end, this.events.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener(this.touchEvents.move, this.events.touchMoveBackdropCb, false); | ||
if (this.touchEvents['cancel']) { | ||
el.removeEventListener(this.touchEvents['cancel'], this.events.touchEndCb, passiveListener); | ||
} | ||
} | ||
if ((this.settings.simulateTouch && !this.device.ios && !this.device.android) || (this.settings.simulateTouch && !Support.touch && this.device.ios)) { | ||
el.removeEventListener('mousedown', this.events.touchStartCb, false); | ||
el.removeEventListener('mousemove', this.events.touchMoveCb, false); | ||
el.removeEventListener('mouseup', this.events.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener('mousemove', this.events.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.removeEventListener('click', this.events.onClickCb, true); | ||
} | ||
} | ||
// TODO: static method | ||
@@ -740,12 +656,2 @@ public getPanelTransformY():number { | ||
public setDarkMode(conf: {enable: boolean} = {enable: true}) { | ||
if (conf.enable) { | ||
this.wrapperEl.classList.add('darkmode'); | ||
this.iconCloseColor = '#a8a7ae'; | ||
} else { | ||
this.wrapperEl.classList.remove('darkmode'); | ||
this.iconCloseColor = '#7a7a7e'; | ||
} | ||
} | ||
/** | ||
@@ -765,5 +671,10 @@ * Public user method to reset breakpoints | ||
public async calcFitHeight() { | ||
// Allow user to call method asap, dont check with this.isPanePresented() | ||
if (!this.wrapperEl || !this.el) { | ||
return null; | ||
} | ||
if (this.breakpoints.calcHeightInProcess) { | ||
console.warn(`Cupertino Pane: calcFitHeight() already in process`); | ||
return; | ||
return null; | ||
} | ||
@@ -831,3 +742,3 @@ | ||
this.breakpoints.getCurrentBreakName(); | ||
return this.breakpoints.getCurrentBreakName(); | ||
}; | ||
@@ -840,4 +751,9 @@ | ||
/****** Detach Events *******/ | ||
this.detachAllEvents(); | ||
this.events.detachAllEvents(); | ||
// Clear pushed elements | ||
if (this.settings.zStack) { | ||
// this.clearPushMultiplicators(); | ||
} | ||
// Reset vars | ||
@@ -887,19 +803,47 @@ delete this.rendered; | ||
private pushTransition(newPaneY: number, transition: string) { | ||
private pushTransition(pushElement: HTMLElement, newPaneY: number, transition: string) { | ||
let zStack = this.settings.zStack.pushElements; | ||
pushElement.style.transition = transition; | ||
newPaneY = this.screenHeightOffset - newPaneY; | ||
const topHeight = this.settings.pushMinHeight ? this.settings.pushMinHeight : this.screenHeightOffset - this.breakpoints.bottomer; | ||
const topHeight = this.settings.zStack.minPushHeight | ||
? this.settings.zStack.minPushHeight : this.screenHeightOffset - this.breakpoints.bottomer; | ||
const minHeight = this.screenHeightOffset - this.breakpoints.topper; | ||
this.pushElement.style.transition = transition; | ||
const setStyles = (scale, y, border, contrast) => { | ||
this.pushElement.style.transform = `translateY(${y}px) scale(${scale})`; | ||
this.pushElement.style.borderRadius = `${border}px`; | ||
this.pushElement.style.filter = `contrast(${contrast})`; | ||
// Math calculations | ||
let multiplicator = this.getPushMulitplicator(pushElement); | ||
let scaleNew = Math.pow(this.settings.zStack.cardZScale, multiplicator); | ||
let scaleNormal = Math.pow(this.settings.zStack.cardZScale, multiplicator - 1); | ||
let pushY = 6 + this.settings.zStack.cardYOffset; // 6 is iOS style offset for z-stacks | ||
let yNew = -1 * (pushY * multiplicator); | ||
let yNormal = (yNew + pushY); | ||
let contrastNew = Math.pow(this.settings.zStack.cardContrast, multiplicator); | ||
let contrastNormal = Math.pow(this.settings.zStack.cardContrast, multiplicator - 1); | ||
// Accumulated styles from each pusher to pushed | ||
const setStyles = (scale, y, contrast, border) => { | ||
let exponentAngle = Math.pow(scale, this.settings.zStack.stackZAngle / 100); | ||
pushElement.style.transform = `translateY(${y * (exponentAngle/scale)}px) scale(${scale})`; | ||
pushElement.style.borderRadius = `${border}px`; | ||
pushElement.style.filter = `contrast(${contrast})`; | ||
// When destroy transition and last item moved we reduce multiplicators | ||
let lastPushed = document.querySelector(zStack[zStack.length - 1]); | ||
if (!newPaneY && pushElement.className === lastPushed.className) { | ||
this.clearPushMultiplicators(); | ||
} | ||
}; | ||
// Pusher cleared or pane destroyed | ||
if (newPaneY <= topHeight) { | ||
setStyles(1, 0, 0, 1); | ||
// defaults | ||
setStyles( | ||
scaleNormal, // scale | ||
yNormal, // transformY | ||
contrastNormal, // contrast | ||
0 // border | ||
); | ||
return; | ||
} | ||
// Pusher drag/move | ||
const getXbyY = (min, max) => { | ||
@@ -915,6 +859,6 @@ let val = (minHeight * max - topHeight * min) * -1; | ||
setStyles( | ||
getXbyY(0.93, 1), | ||
getXbyY(-6 - this.settings.pushYOffset, 0), // *-1 for reverse animation | ||
getXbyY(scaleNew, scaleNormal), | ||
getXbyY(yNew, yNormal), | ||
getXbyY(contrastNew, contrastNormal), | ||
getXbyY(-10, 0) * -1, | ||
getXbyY(0.85, 1) | ||
); | ||
@@ -927,3 +871,2 @@ } | ||
public doTransition(params:any = {}): void { | ||
// touchmove simple event | ||
@@ -939,5 +882,10 @@ if (params.type === 'move') { | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.getPanelTransformY(), 'all 0ms linear 0ms'); | ||
// Push transition for each element | ||
if (this.settings.zStack) { | ||
this.settings.zStack.pushElements.forEach(item => | ||
this.pushTransition( | ||
document.querySelector(item), | ||
this.getPanelTransformY(), 'all 0ms linear 0ms' | ||
) | ||
); | ||
} | ||
@@ -1021,11 +969,17 @@ | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
if (this.settings.zStack) { | ||
// Reason of timeout is to hide empty space when present pane and push element | ||
// we should start push after pushMinHeight but for present | ||
// transition we can't calculate where pane Y is. | ||
// transition we can't calculate where pane Y is. | ||
setTimeout(() => { | ||
this.pushTransition(params.translateY, `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`); | ||
}, this.settings.pushYOffset ? 50 : 0); | ||
this.settings.zStack.pushElements.forEach(item => | ||
this.pushTransition( | ||
document.querySelector(item), | ||
params.translateY, | ||
`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s` | ||
) | ||
); | ||
}, (this.settings.zStack.cardYOffset && params.type === 'present') ? 50 : 0); | ||
} | ||
@@ -1032,0 +986,0 @@ |
import { CupertinoPane, CupertinoSettings } from 'cupertino-pane'; | ||
import { Device } from './device'; | ||
import { Support } from './support'; | ||
import { Breakpoints } from './breakpoints'; | ||
@@ -19,3 +20,4 @@ | ||
private steps: any[] = []; | ||
private inputBlured: boolean = false; | ||
private inputBluredbyMove: boolean = false; | ||
private movedByKeyboard: boolean = false; | ||
@@ -29,2 +31,122 @@ | ||
public attachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.eventListeners('addEventListener', this.instance.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.eventListeners('addEventListener', el); | ||
}); | ||
} | ||
// Handle keyboard events for cordova | ||
if (this.settings.handleKeyboard && this.device.cordova) { | ||
window.addEventListener('keyboardWillShow', this.onKeyboardShowCb); | ||
window.addEventListener('keyboardWillHide', this.onKeyboardHideCb); | ||
} | ||
// Fix Android issue with resize if not handle | ||
if (!this.settings.handleKeyboard | ||
&& this.device.cordova | ||
&& this.device.android) { | ||
window.addEventListener('keyboardWillHide', () => { | ||
this.instance.parentEl.scrollTop = 0; | ||
if (this.instance.parentEl.parentElement) { | ||
this.instance.parentEl.parentElement.scrollTop = 0; | ||
if (this.instance.parentEl.parentElement.parentElement) { | ||
this.instance.parentEl.parentElement.parentElement.scrollTop = 0; | ||
} | ||
} | ||
}); | ||
} | ||
// Orientation change + window resize | ||
window.addEventListener('resize', this.onWindowResizeCb); | ||
} | ||
public detachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.eventListeners('removeEventListener', this.instance.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.eventListeners('removeEventListener', el); | ||
}); | ||
} | ||
// Handle keyboard events for cordova | ||
if (this.settings.handleKeyboard && this.device.cordova) { | ||
window.removeEventListener('keyboardWillShow', this.onKeyboardShowCb); | ||
window.removeEventListener('keyboardWillHide', this.onKeyboardHideCb); | ||
} | ||
// Orientation change + window resize | ||
window.removeEventListener('resize', this.onWindowResizeCb); | ||
} | ||
public resetEvents() { | ||
this.detachAllEvents(); | ||
this.attachAllEvents(); | ||
} | ||
private touchEvents = (() => { | ||
const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel']; | ||
let desktop = ['mousedown', 'mousemove', 'mouseup']; | ||
if (Support.pointerEvents) { | ||
desktop = ['pointerdown', 'pointermove', 'pointerup']; | ||
} | ||
const touchEventsTouch = { | ||
start: touch[0], | ||
move: touch[1], | ||
end: touch[2], | ||
cancel: touch[3], | ||
}; | ||
const touchEventsDesktop = { | ||
start: desktop[0], | ||
move: desktop[1], | ||
end: desktop[2], | ||
}; | ||
return Support.touch || !this.settings.simulateTouch ? touchEventsTouch : touchEventsDesktop; | ||
})(); | ||
private eventListeners(type: 'addEventListener' | 'removeEventListener', el: Element) { | ||
// Touch Events | ||
if (!Support.touch && Support.pointerEvents) { | ||
el[type](this.touchEvents.start, this.touchStartCb, false); | ||
el[type](this.touchEvents.move, this.touchMoveCb, false); | ||
el[type](this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.instance.backdropEl?.[type](this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} else { | ||
if (Support.touch) { | ||
const passiveListener = this.touchEvents.start === 'touchstart' && Support.passiveListener && this.settings.passiveListeners ? { passive: true, capture: false } : false; | ||
el[type](this.touchEvents.start, this.touchStartCb, passiveListener); | ||
el[type](this.touchEvents.move, this.touchMoveCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
el[type](this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
this.instance.backdropEl?.[type](this.touchEvents.move, this.touchMoveBackdropCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
if (this.touchEvents['cancel']) { | ||
el[type](this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
} | ||
} | ||
if ((this.settings.simulateTouch && !this.device.ios && !this.device.android) || (this.settings.simulateTouch && !Support.touch && this.device.ios)) { | ||
el[type]('mousedown', this.touchStartCb, false); | ||
el[type]('mousemove', this.touchMoveCb, false); | ||
el[type]('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.instance.backdropEl?.[type]('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el[type]('click', this.onClickCb, true); | ||
} | ||
} | ||
/** | ||
@@ -36,10 +158,11 @@ * Touch Start Event | ||
private touchStart(t) { | ||
// Liam the best :) | ||
// Event emitter | ||
this.settings.onDragStart(t as CustomEvent); | ||
// Allow clicks by default -> disallow on move (allow click with disabled drag) | ||
this.allowClick = true; | ||
if (this.instance.disableDragEvents) return; | ||
// Allow clicks by default, disallow on move | ||
this.allowClick = true; | ||
// Allow touch angle by default, disallow no move with condition | ||
@@ -51,15 +174,16 @@ this.disableDragAngle = false; | ||
const targetTouch = t.type === 'touchstart' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchstart' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchstart' ? targetTouch.clientX : t.clientX; | ||
const { clientY, clientX } = this.getEvetClientYX(t, 'touchstart'); | ||
this.startY = clientY; | ||
this.startX = clientX; | ||
if (t.type === 'mousedown') this.pointerDown = true; | ||
this.startY = screenY; | ||
this.startX = screenX; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
if (this.contentScrollTop | ||
&& this.willScrolled(t) | ||
&& this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startY += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startY); | ||
@@ -85,6 +209,12 @@ } | ||
private touchMove(t) { | ||
const { clientY, clientX } = this.getEvetClientYX(t, 'touchmove'); | ||
// Event emitter | ||
this.settings.onDrag(t as CustomEvent); | ||
if (this.instance.disableDragEvents) return; | ||
t.delta = this.steps[0] - clientY; | ||
this.settings.onDrag(t); | ||
if (this.instance.disableDragEvents) { | ||
this.steps = []; | ||
return; | ||
} | ||
if (this.disableDragAngle) return; | ||
@@ -98,11 +228,6 @@ if (this.instance.preventedDismiss) return; | ||
// Handle desktop/mobile events | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchmove' ? targetTouch.clientX : t.clientX; | ||
if(t.type === 'mousemove' && !this.pointerDown) return; | ||
// Delta | ||
let n = screenY; | ||
let v = screenX; | ||
const diffY = n - this.steps[this.steps.length - 1]; | ||
const diffY = clientY - this.steps[this.steps.length - 1]; | ||
let newVal = this.instance.getPanelTransformY() + diffY; | ||
@@ -122,3 +247,3 @@ | ||
(<any>document.activeElement).blur(); | ||
this.inputBlured = true; | ||
this.inputBluredbyMove = true; | ||
} | ||
@@ -131,4 +256,4 @@ } | ||
let touchAngle; | ||
const diffX = v - this.startX; | ||
const diffY = n - this.startY; | ||
const diffX = clientX - this.startX; | ||
const diffY = clientY - this.startY; | ||
touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; | ||
@@ -189,3 +314,3 @@ if (diffX * diffX + diffY * diffY >= 25 | ||
let mousePointY = (t.touches[0].screenY - 220 - this.instance.screen_height) * -1; | ||
let mousePointY = (clientY - 220 - this.instance.screen_height) * -1; | ||
if (mousePointY <= this.instance.screen_height - this.breakpoints.bottomer) { | ||
@@ -206,3 +331,3 @@ this.instance.preventedDismiss = true; | ||
this.instance.doTransition({type: 'move', translateY: newVal}); | ||
this.steps.push(n); | ||
this.steps.push(clientY); | ||
} | ||
@@ -216,7 +341,4 @@ | ||
private touchEnd(t) { | ||
if (this.instance.disableDragEvents) return; | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
if (t.type === 'mouseup') this.pointerDown = false; | ||
@@ -234,6 +356,6 @@ | ||
closest = this.instance.swipeNextPoint(diff, swipeNextSensivity, closest); | ||
// Fast swipe toward bottom - close | ||
if (this.settings.fastSwipeClose | ||
&& this.breakpoints.currentBreakpoint < closest) { | ||
&& this.breakpoints.currentBreakpoint < closest) { | ||
this.instance.destroy({animate:true}); | ||
@@ -318,10 +440,12 @@ return; | ||
private onKeyboardShow(e) { | ||
// TODO: instead of this -> check that inputBlured is instance child | ||
if (this.instance.paneEl | ||
&& this.instance.paneEl.offsetWidth === 0 | ||
&& this.instance.paneEl.offsetHeight === 0 ) { | ||
// focud element not inside pane | ||
if (!this.isPaneDescendant(document.activeElement)) { | ||
return; | ||
} | ||
// TODO! | ||
// pane not visible on viewport | ||
if (!this.isOnViewport()) { | ||
return; | ||
} | ||
if (this.device.android) { | ||
@@ -331,15 +455,28 @@ setTimeout(() => this.fixAndroidResize(), 20); | ||
this.movedByKeyboard = true; | ||
this.breakpoints.prevBreakpoint = Object.entries(this.breakpoints.breaks).find(val => val[1] === this.instance.getPanelTransformY())[0]; | ||
let newHeight = this.settings.breaks[this.instance.currentBreak()].height + e.keyboardHeight; | ||
// Landscape case | ||
let isLandscape = window.matchMedia('(orientation: landscape)').matches; | ||
if (isLandscape) { | ||
newHeight = this.instance.screen_height; | ||
} | ||
if (this.instance.screen_height < newHeight) { | ||
let diff = newHeight - this.instance.screen_height + (135 * 0.35); | ||
newHeight = this.instance.screen_height - (135 * 0.35); | ||
this.instance.setOverflowHeight(e.keyboardHeight); | ||
this.instance.moveToBreak(this.settings.breaks.top.enabled ? 'top' : 'middle'); | ||
} else { | ||
this.instance.setOverflowHeight(e.keyboardHeight); | ||
// higher than screen + offsets | ||
if (newHeight > this.instance.screen_height - 80) { | ||
newHeight = this.instance.screen_height - 80; | ||
} | ||
// Move pane up if new position more than 50px | ||
if (newHeight - 50 >= this.settings.breaks[this.instance.currentBreak()].height) { | ||
this.instance.moveToHeight(newHeight); | ||
setTimeout(() => this.instance.overflowEl.scrollTop = (<any>document.activeElement).offsetTop); | ||
} | ||
} | ||
// Remove offset because on new height no offsets needs | ||
// Timeout await for keyboard presented | ||
setTimeout(() => { | ||
this.instance.setOverflowHeight(e.keyboardHeight - this.settings.topperOverflowOffset); | ||
this.instance.overflowEl.scrollTop = (<any>document.activeElement).offsetTop; | ||
}, 300); | ||
} | ||
@@ -353,10 +490,12 @@ | ||
private onKeyboardHide(e) { | ||
// TODO: instead of this -> check that inputBlured is instance child | ||
if (this.instance.paneEl | ||
&& this.instance.paneEl.offsetWidth === 0 | ||
&& this.instance.paneEl.offsetHeight === 0 ) { | ||
// Move back | ||
if (!this.movedByKeyboard) { | ||
return; | ||
} | ||
// TODO! | ||
// pane not visible on viewport | ||
if (!this.isOnViewport()) { | ||
return; | ||
} | ||
if (this.device.android) { | ||
@@ -366,11 +505,14 @@ this.fixAndroidResize(); | ||
if (this.inputBlured) { | ||
this.inputBlured = false; | ||
} else { | ||
if (!this.instance.isHidden()) { | ||
this.instance.moveToBreak(this.breakpoints.prevBreakpoint); | ||
} | ||
this.movedByKeyboard = false; | ||
this.instance.setOverflowHeight(); | ||
if (this.inputBluredbyMove) { | ||
this.inputBluredbyMove = false; | ||
return; | ||
} | ||
if (!this.instance.isHidden()) { | ||
this.instance.moveToBreak(this.breakpoints.prevBreakpoint); | ||
} | ||
setTimeout(() => this.instance.setOverflowHeight()); | ||
} | ||
@@ -382,5 +524,4 @@ | ||
*/ | ||
public onOrientationChangeCb = (e) => this.onOrientationChange(e); | ||
private async onOrientationChange(e) { | ||
// Browsers issue: Currently no proper way to get window.innerHeight without timeout | ||
public onWindowResizeCb = (e) => this.onWindowResize(e); | ||
private async onWindowResize(e) { | ||
await new Promise((resolve) => setTimeout(() => resolve(true), 150)); | ||
@@ -395,2 +536,9 @@ this.instance.updateScreenHeights(); | ||
private getEvetClientYX(ev, name) { | ||
const targetTouch = ev.type === name && ev.targetTouches && (ev.targetTouches[0] || ev.changedTouches[0]); | ||
const clientY = ev.type === name ? targetTouch.clientY : ev.clientY; | ||
const clientX = ev.type === name ? targetTouch.clientX : ev.clientX; | ||
return {clientY, clientX}; | ||
} | ||
/** | ||
@@ -430,2 +578,13 @@ * Fix android keyboard issue with transition | ||
private isPaneDescendant(el): boolean { | ||
let node = el.parentNode; | ||
while (node != null) { | ||
if (node == this.instance.paneEl) { | ||
return true; | ||
} | ||
node = node.parentNode; | ||
} | ||
return false; | ||
} | ||
private isFormElement(el):boolean { | ||
@@ -447,2 +606,13 @@ const formElements: string[] = [ | ||
} | ||
private isOnViewport(): boolean { | ||
if (this.instance.paneEl | ||
&& this.instance.paneEl.offsetWidth === 0 | ||
&& this.instance.paneEl.offsetHeight === 0 ) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
} |
@@ -13,2 +13,11 @@ export interface PaneBreak { | ||
export interface ZStackSettings { | ||
pushElements: string[]; | ||
minPushHeight?: number; | ||
cardYOffset?: number; | ||
cardZScale?: number; | ||
cardContrast?: number; | ||
stackZAngle?: number; | ||
} | ||
export interface TransitionStartEvent { | ||
@@ -23,8 +32,6 @@ translateY: { new: number}; | ||
followerElement: string; | ||
cssClass: string; | ||
fitHeight: boolean; | ||
maxFitHeight: number; | ||
fitScreenHeight: boolean; | ||
pushElement: any; | ||
pushMinHeight: number; | ||
pushYOffset: number; | ||
backdrop: boolean; | ||
@@ -35,3 +42,2 @@ backdropOpacity: number; | ||
bottomOffset: number, | ||
darkMode: boolean; | ||
bottomClose: boolean; | ||
@@ -58,2 +64,3 @@ fastSwipeClose: boolean; | ||
breaks: PaneBreaks; | ||
zStack: ZStackSettings; // todo; remove question mark | ||
onDidDismiss: (event?: CustomEvent) => void, | ||
@@ -64,3 +71,3 @@ onWillDismiss: (event?: CustomEvent) => void, | ||
onDragStart: (event?: CustomEvent) => void, | ||
onDrag: (event?: CustomEvent) => void, | ||
onDrag: (event?: any) => void, | ||
onDragEnd: (event?: CustomEvent) => void, | ||
@@ -67,0 +74,0 @@ onBackdropTap: (event?: CustomEvent) => void, |
@@ -12,8 +12,6 @@ import { CupertinoSettings } from './cupertino-pane'; | ||
followerElement: null, | ||
cssClass: null, | ||
fitHeight: false, | ||
maxFitHeight: null, | ||
fitScreenHeight: true, | ||
pushElement: null, | ||
pushMinHeight: null, | ||
pushYOffset: 0, | ||
backdrop: false, | ||
@@ -25,3 +23,2 @@ backdropOpacity: 0.4, | ||
bottomOffset: 0, | ||
darkMode: false, | ||
bottomClose: false, | ||
@@ -47,2 +44,3 @@ fastSwipeClose: false, | ||
breaks: {}, | ||
zStack: null, | ||
onDidDismiss: () => {}, | ||
@@ -57,5 +55,5 @@ onWillDismiss: () => {}, | ||
onTransitionStart: () => {}, | ||
onTransitionEnd: () => {} | ||
onTransitionEnd: () => {}, | ||
}; | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
14343190
18.61%65
14.04%6223
5.24%433
14.55%