cupertino-pane
Advanced tools
Comparing version 1.1.65 to 1.1.81
--- | ||
name: Bug report | ||
about: Create a report to help us improve | ||
title: '' | ||
labels: '' | ||
assignees: '' | ||
name: 🐜 Bug report | ||
about: If something is not working as excepted | ||
title: '[BUG] ' | ||
--- | ||
@@ -9,0 +6,0 @@ |
@@ -9,3 +9,4 @@ import { Settings } from './models'; | ||
private steps; | ||
private startP; | ||
private startY; | ||
private startX; | ||
private pointerDown; | ||
@@ -16,4 +17,6 @@ private topper; | ||
private contentScrollTop; | ||
private draggableScrollOffset; | ||
private disableDragEvents; | ||
private disableDragAngle; | ||
private rendered; | ||
private allowClick; | ||
private breaks; | ||
@@ -33,3 +36,3 @@ private brs; | ||
private device; | ||
constructor(selector: string, conf?: CupertinoSettings); | ||
constructor(selector: (string | HTMLElement), conf?: CupertinoSettings); | ||
private drawElements; | ||
@@ -39,2 +42,10 @@ present(conf?: { | ||
}): void; | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private attachAllEvents; | ||
private detachAllEvents; | ||
private resetEvents; | ||
private scrollElementInit; | ||
private getTimingFunction; | ||
private checkOpacityAttr; | ||
@@ -57,2 +68,8 @@ private checkOverflowAttr; | ||
*/ | ||
private touchMoveBackdropCb; | ||
private touchMoveBackdrop; | ||
/** | ||
* Touch Move Event | ||
* @param t | ||
*/ | ||
private touchMoveCb; | ||
@@ -66,3 +83,17 @@ private touchMove; | ||
private touchEnd; | ||
/** | ||
* Click Event | ||
* @param t | ||
*/ | ||
private onClickCb; | ||
private onClick; | ||
private swipeNextPoint; | ||
private isBackdropPresented; | ||
private renderBackdrop; | ||
/** | ||
* Backdrop | ||
*/ | ||
backdrop(conf?: { | ||
show: boolean; | ||
}): any; | ||
/************************************ | ||
@@ -94,2 +125,3 @@ * Events | ||
}): any; | ||
private pushTransition; | ||
/*********************************** | ||
@@ -96,0 +128,0 @@ * Transitions handler |
/** | ||
* Cupertino Pane 1.1.65 | ||
* Cupertino Pane 1.1.81 | ||
* Multiplatform slide-over pane | ||
@@ -10,3 +10,3 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 24, 2020 | ||
* Released on: September 1, 2020 | ||
*/ | ||
@@ -68,2 +68,3 @@ | ||
this.electron = false; | ||
this.ionic = !!document.querySelector('ion-app'); | ||
const platform = window.navigator.platform; | ||
@@ -158,2 +159,4 @@ const ua = window.navigator.userAgent; | ||
followerElement: null, | ||
pushElement: null, | ||
pushMinHeight: null, | ||
backdrop: false, | ||
@@ -172,7 +175,11 @@ backdropOpacity: 0.4, | ||
lowerThanBottom: true, | ||
upperThanTop: false, | ||
showDraggable: true, | ||
draggableOver: false, | ||
clickBottomOpen: true, | ||
preventClicks: true, | ||
simulateTouch: true, | ||
passiveListeners: true, | ||
touchMoveStopPropagation: false, | ||
touchAngle: null, | ||
breaks: {}, | ||
@@ -199,4 +206,6 @@ onDidDismiss: () => { }, | ||
this.contentScrollTop = 0; | ||
this.draggableScrollOffset = 0; | ||
this.disableDragEvents = false; | ||
this.disableDragAngle = false; | ||
this.rendered = false; | ||
this.allowClick = true; | ||
this.breaks = {}; | ||
@@ -214,2 +223,7 @@ this.brs = []; | ||
*/ | ||
this.touchMoveBackdropCb = (t) => this.touchMoveBackdrop(t); | ||
/** | ||
* Touch Move Event | ||
* @param t | ||
*/ | ||
this.touchMoveCb = (t) => this.touchMove(t); | ||
@@ -221,2 +235,7 @@ /** | ||
this.touchEndCb = (t) => this.touchEnd(t); | ||
/** | ||
* Click Event | ||
* @param t | ||
*/ | ||
this.onClickCb = (t) => this.onClick(t); | ||
this.swipeNextPoint = (diff, maxDiff, closest) => { | ||
@@ -288,13 +307,20 @@ if (this.currentBreakpoint === this.breaks['top']) { | ||
})(); | ||
// Unable attach DOM element | ||
if (!document.querySelector(this.selector)) { | ||
console.warn('Cupertino Pane: wrong selector specified', this.selector); | ||
// Element or selector | ||
if (selector instanceof HTMLElement) { | ||
this.selector = selector; | ||
} | ||
else { | ||
this.selector = document.querySelector(selector); | ||
} | ||
// Unable attach selector or DOM element | ||
if (!this.selector) { | ||
console.warn('Cupertino Pane: wrong selector or DOM element specified', this.selector); | ||
return; | ||
} | ||
// Pane already was rendered | ||
// Pane class created | ||
if (this.isPanePresented()) { | ||
console.warn('Cupertino Pane: specified selector already in use', this.selector); | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
this.el = document.querySelector(this.selector); | ||
this.el = this.selector; | ||
this.el.style.display = 'none'; | ||
@@ -362,16 +388,2 @@ this.settings = Object.assign(Object.assign({}, this.settings), conf); | ||
this.contentEl.style.overflowX = 'hidden'; | ||
// Backdrop | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
// Close button | ||
@@ -386,2 +398,3 @@ this.closeEl = document.createElement('div'); | ||
this.closeEl.style.right = '20px'; | ||
this.closeEl.style.zIndex = '14'; | ||
this.closeEl.style.borderRadius = '100%'; | ||
@@ -392,7 +405,12 @@ } | ||
return; | ||
// Pane already was rendered | ||
if (this.isPanePresented()) { | ||
// Pane already exist and was rendered | ||
if (this.isPanePresented() && this.rendered) { | ||
this.moveToBreak(this.settings.initialBreak); | ||
return; | ||
} | ||
// Pane already exist but not rendered in this class | ||
if (this.isPanePresented() && !this.rendered) { | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
// Emit event | ||
@@ -415,4 +433,4 @@ this.settings.onWillPresent(); | ||
&& this.settings.breaks[val].enabled | ||
&& (this.settings.breaks[val].offset || this.settings.breaks[val].height)) { | ||
this.breaks[val] -= (this.settings.breaks[val].offset || this.settings.breaks[val].height); | ||
&& this.settings.breaks[val].height) { | ||
this.breaks[val] -= this.settings.breaks[val].height; | ||
} | ||
@@ -452,2 +470,3 @@ }); | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
if (this.settings.followerElement) { | ||
@@ -461,4 +480,7 @@ if (!document.querySelector(this.settings.followerElement)) { | ||
this.followerEl.style.transform = `translateY(0px) translateZ(0px)`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.getTimingFunction(this.settings.breaks[this.currentBreak()].bounce)} 0s`; | ||
} | ||
if (this.settings.pushElement) { | ||
this.settings.pushElement = document.querySelector(this.settings.pushElement); | ||
} | ||
if (!this.settings.showDraggable) { | ||
@@ -507,22 +529,47 @@ this.draggableEl.style.opacity = '0'; | ||
if (this.settings.backdrop) { | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
this.renderBackdrop(); | ||
} | ||
// Get overflow element | ||
let attrElements = document.querySelectorAll(`${this.selector} [overflow-y]`); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
this.scrollElementInit(); | ||
this.checkOpacityAttr(this.currentBreakpoint); | ||
this.checkOverflowAttr(this.currentBreakpoint); | ||
/****** Fix android issues *******/ | ||
if (this.device.android) { | ||
// Body patch prevent android pull-to-refresh | ||
document.body.style['overscrollBehaviorY'] = 'none'; | ||
if (this.device.ionic | ||
&& this.device.cordova) { | ||
// TODO: manual keyboard control (#49 issue) | ||
// Fix android keyboard issue with transition (resize height on hide) | ||
window.addEventListener('keyboardWillHide', () => { | ||
if (!this.paneEl) | ||
return; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = '100%'; | ||
this.paneEl.style.position = 'absolute'; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = 'unset'; | ||
this.paneEl.style.position = 'fixed'; | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
/****** Attach Events *******/ | ||
this.attachAllEvents(); | ||
/****** Animation & Transition ******/ | ||
if (conf.animate) { | ||
this.doTransition({ type: 'present', translateY: this.breaks[this.settings.initialBreak] }); | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
// Emit event | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.breaks[this.settings.initialBreak], 'unset'); | ||
} | ||
this.settings.onDidPresent(); | ||
} | ||
if (this.settings.topperOverflow) { | ||
this.overflowEl.style.height = `${this.screen_height - this.topper - 51 | ||
+ (this.settings.draggableOver ? 30 : 0) | ||
- this.settings.topperOverflowOffset}px`; | ||
} | ||
this.checkOpacityAttr(this.currentBreakpoint); | ||
this.checkOverflowAttr(this.currentBreakpoint); | ||
/****** Attach Events *******/ | ||
} | ||
/** | ||
* Private Utils methods | ||
*/ | ||
attachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
@@ -538,13 +585,44 @@ this.attachEvents(this.paneEl); | ||
} | ||
/****** Animation & Transition ******/ | ||
if (conf.animate) { | ||
this.doTransition({ type: 'present', translateY: this.breaks[this.settings.initialBreak] }); | ||
} | ||
detachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
// Emit event | ||
this.settings.onDidPresent(); | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
} | ||
resetEvents() { | ||
this.detachAllEvents(); | ||
this.attachAllEvents(); | ||
} | ||
scrollElementInit() { | ||
let attrElements = this.el.querySelectorAll('[overflow-y]'); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
} | ||
if (this.settings.topperOverflow) { | ||
// Good to get rid of timeout | ||
// but render dom take a time | ||
setTimeout(() => { | ||
this.overflowEl.style.height = `${this.screen_height | ||
- this.topper | ||
- this.settings.bottomOffset | ||
- this.settings.topperOverflowOffset | ||
- this.overflowEl.offsetTop}px`; | ||
}, 150); | ||
} | ||
} | ||
getTimingFunction(bounce) { | ||
return bounce ? 'cubic-bezier(0.175, 0.885, 0.370, 1.120)' : this.settings.animationType; | ||
} | ||
checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) | ||
@@ -563,4 +641,7 @@ return; | ||
isPanePresented() { | ||
return document.querySelector(`.cupertino-pane-wrapper ${this.selector}`) | ||
? true : false; | ||
// Check through all presented panes | ||
let wrappers = Array.from(document.querySelectorAll('.cupertino-pane-wrapper')); | ||
if (!wrappers.length) | ||
return false; | ||
return wrappers.find((item) => item.contains(this.selector)) ? true : false; | ||
} | ||
@@ -578,14 +659,25 @@ /** | ||
return; | ||
// Allow clicks by default, disallow on move | ||
this.allowClick = true; | ||
// Allow touch angle by default, disallow no move with condition | ||
this.disableDragAngle = false; | ||
const targetTouch = t.type === 'touchstart' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchstart' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchstart' ? targetTouch.clientX : t.clientX; | ||
if (t.type === 'mousedown') | ||
this.pointerDown = true; | ||
this.startP = screenY; | ||
this.startY = screenY; | ||
this.startX = screenX; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path)) { | ||
this.startP += this.contentScrollTop; | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startY += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
this.steps.push(this.startY); | ||
} | ||
touchMoveBackdrop(t) { | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
} | ||
touchMove(t) { | ||
@@ -596,5 +688,11 @@ // Event emitter | ||
return; | ||
if (this.disableDragAngle) | ||
return; | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
// Handle desktop/mobile events | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchmove' ? targetTouch.clientX : t.clientX; | ||
if (t.type === 'mousemove' && !this.pointerDown) | ||
@@ -604,6 +702,19 @@ return; | ||
let n = screenY; | ||
const diff = n - this.steps[this.steps.length - 1]; | ||
const newVal = this.getPanelTransformY() + diff; | ||
let v = screenX; | ||
const diffY = n - this.steps[this.steps.length - 1]; | ||
let newVal = this.getPanelTransformY() + diffY; | ||
// Touch angle | ||
if (this.settings.touchAngle) { | ||
let touchAngle; | ||
const diffX = v - this.startX; | ||
const diffY = n - this.startY; | ||
touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; | ||
if (diffX * diffX + diffY * diffY >= 25 | ||
&& (90 - touchAngle > this.settings.touchAngle)) { | ||
this.disableDragAngle = true; | ||
return; | ||
} | ||
} | ||
// Not allow move panel with positive overflow scroll | ||
if (this.isDragScrollabe(t.path) | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
@@ -619,6 +730,14 @@ this.overflowEl.addEventListener('scroll', (s) => { | ||
} | ||
// Not allow drag upper than topper point | ||
// Not allow drag topper than top point | ||
if (newVal <= this.topper && !this.settings.upperThanTop) { | ||
this.paneEl.style.transform = `translateY(${this.topper}px) translateZ(0px)`; | ||
return; | ||
} | ||
// Allow drag topper than top point | ||
if (newVal <= this.topper && this.settings.upperThanTop) { | ||
const differKoef = ((-this.topper + this.topper - this.getPanelTransformY()) / this.topper) / -8; | ||
newVal = this.getPanelTransformY() + (diffY * differKoef); | ||
} | ||
// Not allow drag lower than bottom if free mode | ||
if ((newVal <= this.topper) | ||
|| (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer))) { | ||
if (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer)) { | ||
return; | ||
@@ -632,2 +751,4 @@ } | ||
} | ||
// Disallow accidentaly clicks while slide gestures | ||
this.allowClick = false; | ||
this.checkOpacityAttr(newVal); | ||
@@ -644,3 +765,3 @@ this.checkOverflowAttr(newVal); | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
if (t.type === 'mouseup') | ||
@@ -678,3 +799,70 @@ this.pointerDown = false; | ||
} | ||
onClick(t) { | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (!this.allowClick) { | ||
if (this.settings.preventClicks) { | ||
t.preventDefault(); | ||
t.stopPropagation(); | ||
t.stopImmediatePropagation(); | ||
} | ||
} | ||
} | ||
isBackdropPresented() { | ||
return document.querySelector(`.cupertino-pane-wrapper .backdrop`) | ||
? true : false; | ||
} | ||
renderBackdrop() { | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
// Reset events to attach backdrop stop propagation | ||
this.resetEvents(); | ||
} | ||
/** | ||
* Backdrop | ||
*/ | ||
backdrop(conf = { show: true }) { | ||
if (!this.isPanePresented()) { | ||
console.warn(`Cupertino Pane: Present pane before call backdrop()`); | ||
return null; | ||
} | ||
if (!this.isBackdropPresented()) { | ||
this.renderBackdrop(); | ||
} | ||
const transitionEnd = () => { | ||
this.backdropEl.style.transition = `initial`; | ||
this.backdropEl.style.display = `none`; | ||
this.backdropEl.removeEventListener('transitionend', transitionEnd); | ||
}; | ||
this.backdropEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.backdropEl.style.backgroundColor = 'rgba(0,0,0,.0)'; | ||
if (!conf.show) { | ||
// Destroy | ||
if (this.backdropEl.style.display === 'none') | ||
return; | ||
this.backdropEl.addEventListener('transitionend', transitionEnd); | ||
} | ||
else { | ||
// Present | ||
this.backdropEl.style.display = 'block'; | ||
setTimeout(() => { | ||
this.backdropEl.style.backgroundColor = `rgba(0,0,0, ${this.settings.backdropOpacity})`; | ||
}, 50); | ||
} | ||
} | ||
attachEvents(el) { | ||
var _a, _b, _c; | ||
// Touch Events | ||
@@ -685,2 +873,4 @@ if (!Support.touch && Support.pointerEvents) { | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_a = this.backdropEl) === null || _a === void 0 ? void 0 : _a.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} | ||
@@ -693,2 +883,4 @@ else { | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
(_b = this.backdropEl) === null || _b === void 0 ? void 0 : _b.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -702,6 +894,13 @@ el.addEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.addEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_c = this.backdropEl) === null || _c === void 0 ? void 0 : _c.addEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.addEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
detachEvents(el) { | ||
var _a, _b, _c; | ||
// Touch Events | ||
@@ -712,2 +911,4 @@ if (!Support.touch && Support.pointerEvents) { | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_a = this.backdropEl) === null || _a === void 0 ? void 0 : _a.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} | ||
@@ -720,2 +921,4 @@ else { | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
(_b = this.backdropEl) === null || _b === void 0 ? void 0 : _b.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -729,4 +932,10 @@ el.removeEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.removeEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_c = this.backdropEl) === null || _c === void 0 ? void 0 : _c.removeEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.removeEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
@@ -802,12 +1011,3 @@ getPanelTransformY() { | ||
/****** Detach Events *******/ | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
this.detachAllEvents(); | ||
// Reset vars | ||
@@ -835,2 +1035,28 @@ this.currentBreakpoint = this.breaks[this.settings.initialBreak]; | ||
} | ||
pushTransition(newPaneY, transition) { | ||
newPaneY = this.screen_height - newPaneY; | ||
const topHeight = this.settings.pushMinHeight ? this.settings.pushMinHeight : this.screen_height - this.bottomer; | ||
const minHeight = this.screen_height - this.topper; | ||
this.settings.pushElement.style.transition = transition; | ||
const setStyles = (scale, y, border, contrast) => { | ||
this.settings.pushElement.style.transform = `translateY(${y}px) scale(${scale})`; | ||
this.settings.pushElement.style.borderRadius = `${border}px`; | ||
this.settings.pushElement.style.filter = `contrast(${contrast})`; | ||
}; | ||
if (newPaneY <= topHeight) { | ||
setStyles(1, 0, 0, 1); | ||
return; | ||
} | ||
const getXbyY = (min, max) => { | ||
let val = (minHeight * max - topHeight * min) * -1; | ||
val -= (min - max) * newPaneY; | ||
val /= (topHeight - minHeight); | ||
if (val > max) | ||
val = max; | ||
if (val < min) | ||
val = min; | ||
return val; | ||
}; | ||
setStyles(getXbyY(0.93, 1), getXbyY(-6, 0) * -1, getXbyY(-10, 0) * -1, getXbyY(0.85, 1)); | ||
} | ||
/*********************************** | ||
@@ -849,2 +1075,6 @@ * Transitions handler | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.getPanelTransformY(), 'all 0ms linear 0ms'); | ||
} | ||
return; | ||
@@ -905,8 +1135,16 @@ } | ||
return; | ||
// Get timing function && push for next | ||
// TODO: getBreakByHeight or by translateY() | ||
const nextBreak = Object.entries(this.settings.breaks).find(val => val[1].height === (this.screen_height - params.translateY)); | ||
const timingForNext = this.getTimingFunction(nextBreak && nextBreak[1].bounce ? true : false); | ||
// style | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
// Bind for follower same transitions | ||
if (this.followerEl) { | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(params.translateY, `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`); | ||
} | ||
// Main transitions | ||
@@ -917,4 +1155,4 @@ if (params.type === 'present') { | ||
// Emit event | ||
this.settings.onTransitionStart({ translateY: { new: this.breaks[this.settings.initialBreak] } }); | ||
this.paneEl.style.transform = `translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`; | ||
this.settings.onTransitionStart({ translateY: { new: params.translateY } }); | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
// Bind for follower same transitions | ||
@@ -921,0 +1159,0 @@ if (this.followerEl) { |
/** | ||
* Cupertino Pane 1.1.65 | ||
* Cupertino Pane 1.1.81 | ||
* Multiplatform slide-over pane | ||
@@ -10,3 +10,3 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 24, 2020 | ||
* Released on: September 1, 2020 | ||
*/ | ||
@@ -72,2 +72,3 @@ | ||
this.electron = false; | ||
this.ionic = !!document.querySelector('ion-app'); | ||
const platform = window.navigator.platform; | ||
@@ -162,2 +163,4 @@ const ua = window.navigator.userAgent; | ||
followerElement: null, | ||
pushElement: null, | ||
pushMinHeight: null, | ||
backdrop: false, | ||
@@ -176,7 +179,11 @@ backdropOpacity: 0.4, | ||
lowerThanBottom: true, | ||
upperThanTop: false, | ||
showDraggable: true, | ||
draggableOver: false, | ||
clickBottomOpen: true, | ||
preventClicks: true, | ||
simulateTouch: true, | ||
passiveListeners: true, | ||
touchMoveStopPropagation: false, | ||
touchAngle: null, | ||
breaks: {}, | ||
@@ -203,4 +210,6 @@ onDidDismiss: () => { }, | ||
this.contentScrollTop = 0; | ||
this.draggableScrollOffset = 0; | ||
this.disableDragEvents = false; | ||
this.disableDragAngle = false; | ||
this.rendered = false; | ||
this.allowClick = true; | ||
this.breaks = {}; | ||
@@ -218,2 +227,7 @@ this.brs = []; | ||
*/ | ||
this.touchMoveBackdropCb = (t) => this.touchMoveBackdrop(t); | ||
/** | ||
* Touch Move Event | ||
* @param t | ||
*/ | ||
this.touchMoveCb = (t) => this.touchMove(t); | ||
@@ -225,2 +239,7 @@ /** | ||
this.touchEndCb = (t) => this.touchEnd(t); | ||
/** | ||
* Click Event | ||
* @param t | ||
*/ | ||
this.onClickCb = (t) => this.onClick(t); | ||
this.swipeNextPoint = (diff, maxDiff, closest) => { | ||
@@ -292,13 +311,20 @@ if (this.currentBreakpoint === this.breaks['top']) { | ||
})(); | ||
// Unable attach DOM element | ||
if (!document.querySelector(this.selector)) { | ||
console.warn('Cupertino Pane: wrong selector specified', this.selector); | ||
// Element or selector | ||
if (selector instanceof HTMLElement) { | ||
this.selector = selector; | ||
} | ||
else { | ||
this.selector = document.querySelector(selector); | ||
} | ||
// Unable attach selector or DOM element | ||
if (!this.selector) { | ||
console.warn('Cupertino Pane: wrong selector or DOM element specified', this.selector); | ||
return; | ||
} | ||
// Pane already was rendered | ||
// Pane class created | ||
if (this.isPanePresented()) { | ||
console.warn('Cupertino Pane: specified selector already in use', this.selector); | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
this.el = document.querySelector(this.selector); | ||
this.el = this.selector; | ||
this.el.style.display = 'none'; | ||
@@ -366,16 +392,2 @@ this.settings = Object.assign(Object.assign({}, this.settings), conf); | ||
this.contentEl.style.overflowX = 'hidden'; | ||
// Backdrop | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
// Close button | ||
@@ -390,2 +402,3 @@ this.closeEl = document.createElement('div'); | ||
this.closeEl.style.right = '20px'; | ||
this.closeEl.style.zIndex = '14'; | ||
this.closeEl.style.borderRadius = '100%'; | ||
@@ -396,7 +409,12 @@ } | ||
return; | ||
// Pane already was rendered | ||
if (this.isPanePresented()) { | ||
// Pane already exist and was rendered | ||
if (this.isPanePresented() && this.rendered) { | ||
this.moveToBreak(this.settings.initialBreak); | ||
return; | ||
} | ||
// Pane already exist but not rendered in this class | ||
if (this.isPanePresented() && !this.rendered) { | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
// Emit event | ||
@@ -419,4 +437,4 @@ this.settings.onWillPresent(); | ||
&& this.settings.breaks[val].enabled | ||
&& (this.settings.breaks[val].offset || this.settings.breaks[val].height)) { | ||
this.breaks[val] -= (this.settings.breaks[val].offset || this.settings.breaks[val].height); | ||
&& this.settings.breaks[val].height) { | ||
this.breaks[val] -= this.settings.breaks[val].height; | ||
} | ||
@@ -456,2 +474,3 @@ }); | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
if (this.settings.followerElement) { | ||
@@ -465,4 +484,7 @@ if (!document.querySelector(this.settings.followerElement)) { | ||
this.followerEl.style.transform = `translateY(0px) translateZ(0px)`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.getTimingFunction(this.settings.breaks[this.currentBreak()].bounce)} 0s`; | ||
} | ||
if (this.settings.pushElement) { | ||
this.settings.pushElement = document.querySelector(this.settings.pushElement); | ||
} | ||
if (!this.settings.showDraggable) { | ||
@@ -511,22 +533,47 @@ this.draggableEl.style.opacity = '0'; | ||
if (this.settings.backdrop) { | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
this.renderBackdrop(); | ||
} | ||
// Get overflow element | ||
let attrElements = document.querySelectorAll(`${this.selector} [overflow-y]`); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
this.scrollElementInit(); | ||
this.checkOpacityAttr(this.currentBreakpoint); | ||
this.checkOverflowAttr(this.currentBreakpoint); | ||
/****** Fix android issues *******/ | ||
if (this.device.android) { | ||
// Body patch prevent android pull-to-refresh | ||
document.body.style['overscrollBehaviorY'] = 'none'; | ||
if (this.device.ionic | ||
&& this.device.cordova) { | ||
// TODO: manual keyboard control (#49 issue) | ||
// Fix android keyboard issue with transition (resize height on hide) | ||
window.addEventListener('keyboardWillHide', () => { | ||
if (!this.paneEl) | ||
return; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = '100%'; | ||
this.paneEl.style.position = 'absolute'; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = 'unset'; | ||
this.paneEl.style.position = 'fixed'; | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
/****** Attach Events *******/ | ||
this.attachAllEvents(); | ||
/****** Animation & Transition ******/ | ||
if (conf.animate) { | ||
this.doTransition({ type: 'present', translateY: this.breaks[this.settings.initialBreak] }); | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
// Emit event | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.breaks[this.settings.initialBreak], 'unset'); | ||
} | ||
this.settings.onDidPresent(); | ||
} | ||
if (this.settings.topperOverflow) { | ||
this.overflowEl.style.height = `${this.screen_height - this.topper - 51 | ||
+ (this.settings.draggableOver ? 30 : 0) | ||
- this.settings.topperOverflowOffset}px`; | ||
} | ||
this.checkOpacityAttr(this.currentBreakpoint); | ||
this.checkOverflowAttr(this.currentBreakpoint); | ||
/****** Attach Events *******/ | ||
} | ||
/** | ||
* Private Utils methods | ||
*/ | ||
attachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
@@ -542,13 +589,44 @@ this.attachEvents(this.paneEl); | ||
} | ||
/****** Animation & Transition ******/ | ||
if (conf.animate) { | ||
this.doTransition({ type: 'present', translateY: this.breaks[this.settings.initialBreak] }); | ||
} | ||
detachAllEvents() { | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
// Emit event | ||
this.settings.onDidPresent(); | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
} | ||
resetEvents() { | ||
this.detachAllEvents(); | ||
this.attachAllEvents(); | ||
} | ||
scrollElementInit() { | ||
let attrElements = this.el.querySelectorAll('[overflow-y]'); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
} | ||
if (this.settings.topperOverflow) { | ||
// Good to get rid of timeout | ||
// but render dom take a time | ||
setTimeout(() => { | ||
this.overflowEl.style.height = `${this.screen_height | ||
- this.topper | ||
- this.settings.bottomOffset | ||
- this.settings.topperOverflowOffset | ||
- this.overflowEl.offsetTop}px`; | ||
}, 150); | ||
} | ||
} | ||
getTimingFunction(bounce) { | ||
return bounce ? 'cubic-bezier(0.175, 0.885, 0.370, 1.120)' : this.settings.animationType; | ||
} | ||
checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) | ||
@@ -567,4 +645,7 @@ return; | ||
isPanePresented() { | ||
return document.querySelector(`.cupertino-pane-wrapper ${this.selector}`) | ||
? true : false; | ||
// Check through all presented panes | ||
let wrappers = Array.from(document.querySelectorAll('.cupertino-pane-wrapper')); | ||
if (!wrappers.length) | ||
return false; | ||
return wrappers.find((item) => item.contains(this.selector)) ? true : false; | ||
} | ||
@@ -582,14 +663,25 @@ /** | ||
return; | ||
// Allow clicks by default, disallow on move | ||
this.allowClick = true; | ||
// Allow touch angle by default, disallow no move with condition | ||
this.disableDragAngle = false; | ||
const targetTouch = t.type === 'touchstart' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchstart' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchstart' ? targetTouch.clientX : t.clientX; | ||
if (t.type === 'mousedown') | ||
this.pointerDown = true; | ||
this.startP = screenY; | ||
this.startY = screenY; | ||
this.startX = screenX; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path)) { | ||
this.startP += this.contentScrollTop; | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startY += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
this.steps.push(this.startY); | ||
} | ||
touchMoveBackdrop(t) { | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
} | ||
touchMove(t) { | ||
@@ -600,5 +692,11 @@ // Event emitter | ||
return; | ||
if (this.disableDragAngle) | ||
return; | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
// Handle desktop/mobile events | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchmove' ? targetTouch.clientX : t.clientX; | ||
if (t.type === 'mousemove' && !this.pointerDown) | ||
@@ -608,6 +706,19 @@ return; | ||
let n = screenY; | ||
const diff = n - this.steps[this.steps.length - 1]; | ||
const newVal = this.getPanelTransformY() + diff; | ||
let v = screenX; | ||
const diffY = n - this.steps[this.steps.length - 1]; | ||
let newVal = this.getPanelTransformY() + diffY; | ||
// Touch angle | ||
if (this.settings.touchAngle) { | ||
let touchAngle; | ||
const diffX = v - this.startX; | ||
const diffY = n - this.startY; | ||
touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; | ||
if (diffX * diffX + diffY * diffY >= 25 | ||
&& (90 - touchAngle > this.settings.touchAngle)) { | ||
this.disableDragAngle = true; | ||
return; | ||
} | ||
} | ||
// Not allow move panel with positive overflow scroll | ||
if (this.isDragScrollabe(t.path) | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
@@ -623,6 +734,14 @@ this.overflowEl.addEventListener('scroll', (s) => { | ||
} | ||
// Not allow drag upper than topper point | ||
// Not allow drag topper than top point | ||
if (newVal <= this.topper && !this.settings.upperThanTop) { | ||
this.paneEl.style.transform = `translateY(${this.topper}px) translateZ(0px)`; | ||
return; | ||
} | ||
// Allow drag topper than top point | ||
if (newVal <= this.topper && this.settings.upperThanTop) { | ||
const differKoef = ((-this.topper + this.topper - this.getPanelTransformY()) / this.topper) / -8; | ||
newVal = this.getPanelTransformY() + (diffY * differKoef); | ||
} | ||
// Not allow drag lower than bottom if free mode | ||
if ((newVal <= this.topper) | ||
|| (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer))) { | ||
if (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer)) { | ||
return; | ||
@@ -636,2 +755,4 @@ } | ||
} | ||
// Disallow accidentaly clicks while slide gestures | ||
this.allowClick = false; | ||
this.checkOpacityAttr(newVal); | ||
@@ -648,3 +769,3 @@ this.checkOverflowAttr(newVal); | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
if (t.type === 'mouseup') | ||
@@ -682,3 +803,70 @@ this.pointerDown = false; | ||
} | ||
onClick(t) { | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (!this.allowClick) { | ||
if (this.settings.preventClicks) { | ||
t.preventDefault(); | ||
t.stopPropagation(); | ||
t.stopImmediatePropagation(); | ||
} | ||
} | ||
} | ||
isBackdropPresented() { | ||
return document.querySelector(`.cupertino-pane-wrapper .backdrop`) | ||
? true : false; | ||
} | ||
renderBackdrop() { | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
// Reset events to attach backdrop stop propagation | ||
this.resetEvents(); | ||
} | ||
/** | ||
* Backdrop | ||
*/ | ||
backdrop(conf = { show: true }) { | ||
if (!this.isPanePresented()) { | ||
console.warn(`Cupertino Pane: Present pane before call backdrop()`); | ||
return null; | ||
} | ||
if (!this.isBackdropPresented()) { | ||
this.renderBackdrop(); | ||
} | ||
const transitionEnd = () => { | ||
this.backdropEl.style.transition = `initial`; | ||
this.backdropEl.style.display = `none`; | ||
this.backdropEl.removeEventListener('transitionend', transitionEnd); | ||
}; | ||
this.backdropEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.backdropEl.style.backgroundColor = 'rgba(0,0,0,.0)'; | ||
if (!conf.show) { | ||
// Destroy | ||
if (this.backdropEl.style.display === 'none') | ||
return; | ||
this.backdropEl.addEventListener('transitionend', transitionEnd); | ||
} | ||
else { | ||
// Present | ||
this.backdropEl.style.display = 'block'; | ||
setTimeout(() => { | ||
this.backdropEl.style.backgroundColor = `rgba(0,0,0, ${this.settings.backdropOpacity})`; | ||
}, 50); | ||
} | ||
} | ||
attachEvents(el) { | ||
var _a, _b, _c; | ||
// Touch Events | ||
@@ -689,2 +877,4 @@ if (!Support.touch && Support.pointerEvents) { | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_a = this.backdropEl) === null || _a === void 0 ? void 0 : _a.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} | ||
@@ -697,2 +887,4 @@ else { | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
(_b = this.backdropEl) === null || _b === void 0 ? void 0 : _b.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -706,6 +898,13 @@ el.addEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.addEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_c = this.backdropEl) === null || _c === void 0 ? void 0 : _c.addEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.addEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
detachEvents(el) { | ||
var _a, _b, _c; | ||
// Touch Events | ||
@@ -716,2 +915,4 @@ if (!Support.touch && Support.pointerEvents) { | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_a = this.backdropEl) === null || _a === void 0 ? void 0 : _a.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} | ||
@@ -724,2 +925,4 @@ else { | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
(_b = this.backdropEl) === null || _b === void 0 ? void 0 : _b.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -733,4 +936,10 @@ el.removeEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.removeEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
(_c = this.backdropEl) === null || _c === void 0 ? void 0 : _c.removeEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.removeEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
@@ -806,12 +1015,3 @@ getPanelTransformY() { | ||
/****** Detach Events *******/ | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
this.detachAllEvents(); | ||
// Reset vars | ||
@@ -839,2 +1039,28 @@ this.currentBreakpoint = this.breaks[this.settings.initialBreak]; | ||
} | ||
pushTransition(newPaneY, transition) { | ||
newPaneY = this.screen_height - newPaneY; | ||
const topHeight = this.settings.pushMinHeight ? this.settings.pushMinHeight : this.screen_height - this.bottomer; | ||
const minHeight = this.screen_height - this.topper; | ||
this.settings.pushElement.style.transition = transition; | ||
const setStyles = (scale, y, border, contrast) => { | ||
this.settings.pushElement.style.transform = `translateY(${y}px) scale(${scale})`; | ||
this.settings.pushElement.style.borderRadius = `${border}px`; | ||
this.settings.pushElement.style.filter = `contrast(${contrast})`; | ||
}; | ||
if (newPaneY <= topHeight) { | ||
setStyles(1, 0, 0, 1); | ||
return; | ||
} | ||
const getXbyY = (min, max) => { | ||
let val = (minHeight * max - topHeight * min) * -1; | ||
val -= (min - max) * newPaneY; | ||
val /= (topHeight - minHeight); | ||
if (val > max) | ||
val = max; | ||
if (val < min) | ||
val = min; | ||
return val; | ||
}; | ||
setStyles(getXbyY(0.93, 1), getXbyY(-6, 0) * -1, getXbyY(-10, 0) * -1, getXbyY(0.85, 1)); | ||
} | ||
/*********************************** | ||
@@ -853,2 +1079,6 @@ * Transitions handler | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.getPanelTransformY(), 'all 0ms linear 0ms'); | ||
} | ||
return; | ||
@@ -909,8 +1139,16 @@ } | ||
return; | ||
// Get timing function && push for next | ||
// TODO: getBreakByHeight or by translateY() | ||
const nextBreak = Object.entries(this.settings.breaks).find(val => val[1].height === (this.screen_height - params.translateY)); | ||
const timingForNext = this.getTimingFunction(nextBreak && nextBreak[1].bounce ? true : false); | ||
// style | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
// Bind for follower same transitions | ||
if (this.followerEl) { | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(params.translateY, `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`); | ||
} | ||
// Main transitions | ||
@@ -921,4 +1159,4 @@ if (params.type === 'present') { | ||
// Emit event | ||
this.settings.onTransitionStart({ translateY: { new: this.breaks[this.settings.initialBreak] } }); | ||
this.paneEl.style.transform = `translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`; | ||
this.settings.onTransitionStart({ translateY: { new: params.translateY } }); | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
// Bind for follower same transitions | ||
@@ -925,0 +1163,0 @@ if (this.followerEl) { |
/** | ||
* Cupertino Pane 1.1.65 | ||
* Cupertino Pane 1.1.81 | ||
* Multiplatform slide-over pane | ||
@@ -10,6 +10,6 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 24, 2020 | ||
* Released on: September 1, 2020 | ||
*/ | ||
"use strict";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;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,d=e.indexOf("Gecko/")>=0&&e.indexOf("Firefox/")>=0,p="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=d,n&&!p&&(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=p,this.macos&&(this.os="macos"),this.windows&&(this.os="windows")),this.pixelRatio=window.devicePixelRatio||1}}class CupertinoPane{constructor(t,e={}){this.selector=t,this.settings={initialBreak:"middle",parentElement:null,followerElement:null,backdrop:!1,backdropOpacity:.4,animationType:"ease",animationDuration:300,dragBy:null,bottomOffset:0,darkMode:!1,bottomClose:!1,freeMode:!1,buttonClose:!0,topperOverflow:!0,topperOverflowOffset:0,lowerThanBottom:!0,showDraggable:!0,draggableOver:!1,clickBottomOpen:!0,simulateTouch:!0,passiveListeners:!0,breaks:{},onDidDismiss:()=>{},onWillDismiss:()=>{},onDidPresent:()=>{},onWillPresent:()=>{},onDragStart:()=>{},onDrag:()=>{},onDragEnd:()=>{},onBackdropTap:()=>{},onTransitionStart:()=>{},onTransitionEnd:()=>{}},this.defaultBreaksConf={top:{enabled:!0,height:window.innerHeight-47.25},middle:{enabled:!0,height:300},bottom:{enabled:!0,height:100}},this.screen_height=window.innerHeight,this.steps=[],this.pointerDown=!1,this.contentScrollTop=0,this.draggableScrollOffset=0,this.disableDragEvents=!1,this.breaks={},this.brs=[],this.device=new Device,this.touchStartCb=t=>this.touchStart(t),this.touchMoveCb=t=>this.touchMove(t),this.touchEndCb=t=>this.touchEnd(t),this.swipeNextPoint=(t,e,s)=>{if(this.currentBreakpoint===this.breaks.top){if(t>e){if(this.settings.breaks.middle.enabled)return this.breaks.middle;if(this.settings.breaks.bottom.enabled)return this.breaks.middle<s?s:this.breaks.bottom}return this.breaks.top}if(this.currentBreakpoint===this.breaks.middle)return t<-e&&this.settings.breaks.top.enabled?this.breaks.top:t>e&&this.settings.breaks.bottom.enabled?this.breaks.bottom:this.breaks.middle;if(this.currentBreakpoint===this.breaks.bottom){if(t<-e){if(this.settings.breaks.middle.enabled)return this.breaks.middle>s?s:this.breaks.middle;if(this.settings.breaks.top.enabled)return this.breaks.top}return this.breaks.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})(),document.querySelector(this.selector)?this.isPanePresented()?console.warn("Cupertino Pane: specified selector already in use",this.selector):(this.el=document.querySelector(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):console.warn("Cupertino Pane: wrong selector specified",this.selector)}drawElements(){this.parentEl=this.settings.parentElement,this.wrapperEl=document.createElement("div"),this.wrapperEl.className="cupertino-pane-wrapper "+this.el.className,this.wrapperEl.style.position="absolute",this.wrapperEl.style.top="0",this.wrapperEl.style.left="0",this.paneEl=document.createElement("div"),this.paneEl.className="pane",this.paneEl.style.position="fixed",this.paneEl.style.zIndex="11",this.paneEl.style.paddingTop="15px",this.paneEl.style.width="100%",this.paneEl.style.maxWidth="500px",this.paneEl.style.left="0px",this.paneEl.style.right="0px",this.paneEl.style.marginLeft="auto",this.paneEl.style.marginRight="auto",this.paneEl.style.height=this.screen_height-this.topper-this.settings.bottomOffset+"px",this.paneEl.style.background="#ffffff",this.paneEl.style.borderTopLeftRadius="20px",this.paneEl.style.borderTopRightRadius="20px",this.paneEl.style.boxShadow="0 4px 16px rgba(0,0,0,.12)",this.paneEl.style.overflow="hidden",this.paneEl.style.willChange="transform",this.paneEl.style.transform=`translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.draggableEl=document.createElement("div"),this.draggableEl.className="draggable",this.draggableEl.style.padding="5px",this.draggableEl.style.position="absolute",this.draggableEl.style.top="0",this.draggableEl.style.left="0",this.draggableEl.style.right="0",this.draggableEl.style.marginLeft="auto",this.draggableEl.style.marginRight="auto",this.draggableEl.style.height="30px",this.draggableEl.style.zIndex="12",this.moveEl=document.createElement("div"),this.moveEl.className="move",this.moveEl.style.margin="0 auto",this.moveEl.style.height="5px",this.moveEl.style.background="#c0c0c0",this.moveEl.style.width="36px",this.moveEl.style.borderRadius="4px",this.contentEl=this.el,this.contentEl.style.display="block",this.contentEl.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.contentEl.style.overflowX="hidden",this.backdropEl=document.createElement("div"),this.backdropEl.className="backdrop",this.backdropEl.style.overflow="hidden",this.backdropEl.style.position="fixed",this.backdropEl.style.width="100%",this.backdropEl.style.bottom="0",this.backdropEl.style.right="0",this.backdropEl.style.left="0",this.backdropEl.style.top="0",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.backdropEl.style.display="none",this.backdropEl.style.zIndex="10",this.closeEl=document.createElement("div"),this.closeEl.className="close-button",this.closeEl.style.width="26px",this.closeEl.style.height="26px",this.closeEl.style.position="absolute",this.closeEl.style.background="#ebebeb",this.closeEl.style.top="16px",this.closeEl.style.right="20px",this.closeEl.style.borderRadius="100%"}present(t={animate:!1}){if(!this.el)return;if(this.isPanePresented())return void this.moveToBreak(this.settings.initialBreak);if(this.settings.onWillPresent(),this.breaks={top:this.screen_height,middle:this.screen_height,bottom:this.screen_height},["top","middle","bottom"].forEach(t=>{this.breaks[t]-=this.settings.bottomOffset,this.settings.breaks[t]||(this.settings.breaks[t]=this.defaultBreaksConf[t]),this.settings.breaks[t]&&this.settings.breaks[t].enabled&&(this.settings.breaks[t].offset||this.settings.breaks[t].height)&&(this.breaks[t]-=this.settings.breaks[t].offset||this.settings.breaks[t].height)}),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)=>Math.abs(e)<Math.abs(t)?e:t),this.bottomer=this.brs.reduce((t,e)=>Math.abs(e)>Math.abs(t)?e:t),this.currentBreakpoint=this.breaks[this.settings.initialBreak],this.drawElements(),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),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.settings.animationType} 0s`}if(this.settings.showDraggable||(this.draggableEl.style.opacity="0"),this.settings.draggableOver&&(this.paneEl.style.background="transparent",this.paneEl.style.boxShadow="none",this.paneEl.style.paddingTop="30px",this.contentEl.style.background="#ffffff",this.contentEl.style.display="block",this.contentEl.style.borderTopLeftRadius="20px",this.contentEl.style.borderTopRightRadius="20px",this.contentEl.style.boxShadow="0 4px 16px rgba(0,0,0,.12)",this.closeEl.style.top="45px",this.draggableEl.style.padding="15px",this.moveEl.style.width="45px",this.moveEl.style.background="rgba(225, 225, 225, 0.6)",Support.backdropFilter&&(this.moveEl.style.backdropFilter="saturate(180%) blur(20px)",this.moveEl.style.webkitBackdropFilter="saturate(180%) blur(20px)")),this.settings.darkMode&&(this.paneEl.style.background="#1c1c1d",this.paneEl.style.color="#ffffff",this.moveEl.style.background="#5a5a5e"),this.settings.buttonClose){this.paneEl.appendChild(this.closeEl),this.closeEl.addEventListener("click",t=>this.destroy({animate:!0}));let t="#7a7a7e";this.settings.darkMode&&(this.closeEl.style.background="#424246",t="#a8a7ae"),this.closeEl.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\n <path fill="${t}" 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.backdrop&&(this.wrapperEl.appendChild(this.backdropEl),this.backdropEl.style.display="block",this.backdropEl.addEventListener("click",t=>this.settings.onBackdropTap()));let e=document.querySelectorAll(this.selector+" [overflow-y]");!e.length||e.length>1?this.overflowEl=this.contentEl:this.overflowEl=e[0],this.settings.topperOverflow&&(this.overflowEl.style.height=this.screen_height-this.topper-51+(this.settings.draggableOver?30:0)-this.settings.topperOverflowOffset+"px"),this.checkOpacityAttr(this.currentBreakpoint),this.checkOverflowAttr(this.currentBreakpoint),this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.attachEvents(e)}):this.attachEvents(this.paneEl),t.animate?this.doTransition({type:"present",translateY:this.breaks[this.settings.initialBreak]}):this.settings.onDidPresent()}checkOpacityAttr(t){let e=document.querySelectorAll(this.selector+" [hide-on-bottom]");e.length&&e.forEach(e=>{e.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,e.style.opacity=t>=this.breaks.bottom?"0":"1"})}checkOverflowAttr(t){this.settings.topperOverflow&&(this.overflowEl.style.overflowY=t<=this.topper?"auto":"hidden")}isPanePresented(){return!!document.querySelector(".cupertino-pane-wrapper "+this.selector)}isDragScrollabe(t){return!!t.find(t=>t===this.overflowEl)}touchStart(t){if(this.settings.onDragStart(t),this.disableDragEvents)return;const e="touchstart"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]),s="touchstart"===t.type?e.screenY:t.screenY;"mousedown"===t.type&&(this.pointerDown=!0),this.startP=s,this.isDragScrollabe(t.path)&&(this.startP+=this.contentScrollTop),this.steps.push(this.startP)}touchMove(t){if(this.settings.onDrag(t),this.disableDragEvents)return;const e="touchmove"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]),s="touchmove"===t.type?e.screenY:t.screenY;if("mousemove"===t.type&&!this.pointerDown)return;let i=s;const n=i-this.steps[this.steps.length-1],o=this.getPanelTransformY()+n;this.isDragScrollabe(t.path)&&"auto"===this.overflowEl.style.overflowY&&(this.overflowEl.addEventListener("scroll",t=>{this.contentScrollTop=t.target.scrollTop}),o>this.topper&&this.contentScrollTop>0||o<=this.topper)||o<=this.topper||this.settings.freeMode&&!this.settings.bottomClose&&o>=this.bottomer||(!this.settings.lowerThanBottom&&o>=this.bottomer?this.destroy({animate:!0}):(this.checkOpacityAttr(o),this.checkOverflowAttr(o),this.doTransition({type:"move",translateY:o}),this.steps.push(i)))}touchEnd(t){if(this.settings.onDragEnd(t),this.disableDragEvents)return;const e="touchmove"===t.type&&t.targetTouches&&(t.targetTouches[0]||t.changedTouches[0]);"touchmove"===t.type?e.screenY:t.screenY;"mouseup"===t.type&&(this.pointerDown=!1);let s=this.brs.reduce((t,e)=>Math.abs(e-this.getPanelTransformY())<Math.abs(t-this.getPanelTransformY())?e:t);const i=this.steps[this.steps.length-1]-this.steps[this.steps.length-2],n=window.hasOwnProperty("cordova")?4:3;Math.abs(i)>=n&&(s=this.swipeNextPoint(i,n,s)),this.settings.clickBottomOpen&&this.currentBreakpoint===this.breaks.bottom&&isNaN(i)&&(s=this.settings.breaks.middle.enabled?this.breaks.middle:this.settings.breaks.top.enabled?this.breaks.top:this.breaks.bottom),this.steps=[],this.currentBreakpoint=s,this.checkOpacityAttr(this.currentBreakpoint),this.checkOverflowAttr(this.currentBreakpoint),this.settings.bottomClose&&s===this.breaks.bottom?this.destroy({animate:!0}):this.doTransition({type:"end",translateY:s})}attachEvents(t){if(!Support.touch&&Support.pointerEvents)t.addEventListener(this.touchEvents.start,this.touchStartCb,!1),t.addEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.addEventListener(this.touchEvents.end,this.touchEndCb,!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.touchStartCb,e),t.addEventListener(this.touchEvents.move,this.touchMoveCb,!!Support.passiveListener&&{passive:!1,capture:!1}),t.addEventListener(this.touchEvents.end,this.touchEndCb,e),this.touchEvents.cancel&&t.addEventListener(this.touchEvents.cancel,this.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.addEventListener("mousedown",this.touchStartCb,!1),t.addEventListener("mousemove",this.touchMoveCb,!1),t.addEventListener("mouseup",this.touchEndCb,!1))}}detachEvents(t){if(!Support.touch&&Support.pointerEvents)t.removeEventListener(this.touchEvents.start,this.touchStartCb,!1),t.removeEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.touchEndCb,!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.touchStartCb,e),t.removeEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.touchEndCb,e),this.touchEvents.cancel&&t.removeEventListener(this.touchEvents.cancel,this.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.removeEventListener("mousedown",this.touchStartCb,!1),t.removeEventListener("mousemove",this.touchMoveCb,!1),t.removeEventListener("mouseup",this.touchEndCb,!1))}}getPanelTransformY(){return parseFloat(/\.*translateY\((.*)px\)/i.exec(this.paneEl.style.transform)[1])}disableDrag(){this.disableDragEvents=!0}enableDrag(){this.disableDragEvents=!1}moveToBreak(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToBreak()"),null;this.settings.breaks[t].enabled?(this.checkOpacityAttr(this.breaks[t]),this.checkOverflowAttr(this.breaks[t]),this.doTransition({type:"breakpoint",translateY:this.breaks[t]}),this.currentBreakpoint=this.breaks[t]):console.warn("Cupertino Pane: %s breakpoint disabled",t)}hide(){return this.isPanePresented()?this.isHidden()?(console.warn("Cupertino Pane: Pane already hidden"),null):void this.doTransition({type:"hide",translateY:this.screen_height}):(console.warn("Cupertino Pane: Present pane before call hide()"),null)}isHidden(){return this.isPanePresented()?this.paneEl.style.transform===`translateY(${this.screen_height}px) translateZ(0px)`:(console.warn("Cupertino Pane: Present pane before call isHidden()"),null)}currentBreak(){return this.isPanePresented()?this.breaks.top===this.currentBreakpoint?"top":this.breaks.middle===this.currentBreakpoint?"middle":this.breaks.bottom===this.currentBreakpoint?"bottom":null:(console.warn("Cupertino Pane: Present pane before call currentBreak()"),null)}destroyResets(){this.parentEl.appendChild(this.contentEl),this.wrapperEl.remove(),this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.detachEvents(e)}):this.detachEvents(this.paneEl),this.currentBreakpoint=this.breaks[this.settings.initialBreak],this.contentEl.style.display="none"}destroy(t={animate:!1}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call destroy()"),null;this.settings.onWillDismiss(),t.animate?this.doTransition({type:"destroy",translateY:this.screen_height}):(this.destroyResets(),this.settings.onDidDismiss())}doTransition(t={}){if("move"===t.type)return this.paneEl.style.transition="all 0ms linear 0ms",this.paneEl.style.transform=`translateY(${t.translateY}px) translateZ(0px)`,void(this.followerEl&&(this.followerEl.style.transition="all 0ms linear 0ms",this.followerEl.style.transform=`translateY(${t.translateY-this.breaks[this.settings.initialBreak]}px) translateZ(0px)`));const e=()=>{"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(),this.settings.onTransitionEnd(),this.paneEl.removeEventListener("transitionend",e)};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;return this.paneEl.style.transition=`transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.followerEl&&(this.followerEl.style.transition=`transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`),"present"===t.type?(this.paneEl.style.transform=`translateY(${this.screen_height}px) translateZ(0px)`,setTimeout(()=>{this.settings.onTransitionStart({translateY:{new:this.breaks[this.settings.initialBreak]}}),this.paneEl.style.transform=`translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transform="translateY(0px) translateZ(0px)")},50)):(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.breaks[this.settings.initialBreak]}px) translateZ(0px)`)),void this.paneEl.addEventListener("transitionend",e)}}}exports.CupertinoPane=CupertinoPane; | ||
"use strict";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 CupertinoPane{constructor(t,e={}){this.selector=t,this.settings={initialBreak:"middle",parentElement:null,followerElement:null,pushElement:null,pushMinHeight:null,backdrop:!1,backdropOpacity:.4,animationType:"ease",animationDuration:300,dragBy:null,bottomOffset:0,darkMode:!1,bottomClose:!1,freeMode:!1,buttonClose:!0,topperOverflow:!0,topperOverflowOffset:0,lowerThanBottom:!0,upperThanTop:!1,showDraggable:!0,draggableOver:!1,clickBottomOpen:!0,preventClicks:!0,simulateTouch:!0,passiveListeners:!0,touchMoveStopPropagation:!1,touchAngle:null,breaks:{},onDidDismiss:()=>{},onWillDismiss:()=>{},onDidPresent:()=>{},onWillPresent:()=>{},onDragStart:()=>{},onDrag:()=>{},onDragEnd:()=>{},onBackdropTap:()=>{},onTransitionStart:()=>{},onTransitionEnd:()=>{}},this.defaultBreaksConf={top:{enabled:!0,height:window.innerHeight-47.25},middle:{enabled:!0,height:300},bottom:{enabled:!0,height:100}},this.screen_height=window.innerHeight,this.steps=[],this.pointerDown=!1,this.contentScrollTop=0,this.disableDragEvents=!1,this.disableDragAngle=!1,this.rendered=!1,this.allowClick=!0,this.breaks={},this.brs=[],this.device=new Device,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.swipeNextPoint=(t,e,s)=>{if(this.currentBreakpoint===this.breaks.top){if(t>e){if(this.settings.breaks.middle.enabled)return this.breaks.middle;if(this.settings.breaks.bottom.enabled)return this.breaks.middle<s?s:this.breaks.bottom}return this.breaks.top}if(this.currentBreakpoint===this.breaks.middle)return t<-e&&this.settings.breaks.top.enabled?this.breaks.top:t>e&&this.settings.breaks.bottom.enabled?this.breaks.bottom:this.breaks.middle;if(this.currentBreakpoint===this.breaks.bottom){if(t<-e){if(this.settings.breaks.middle.enabled)return this.breaks.middle>s?s:this.breaks.middle;if(this.settings.breaks.top.enabled)return this.breaks.top}return this.breaks.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.warn("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):console.warn("Cupertino Pane: wrong selector or DOM element specified",this.selector)}drawElements(){this.parentEl=this.settings.parentElement,this.wrapperEl=document.createElement("div"),this.wrapperEl.className="cupertino-pane-wrapper "+this.el.className,this.wrapperEl.style.position="absolute",this.wrapperEl.style.top="0",this.wrapperEl.style.left="0",this.paneEl=document.createElement("div"),this.paneEl.className="pane",this.paneEl.style.position="fixed",this.paneEl.style.zIndex="11",this.paneEl.style.paddingTop="15px",this.paneEl.style.width="100%",this.paneEl.style.maxWidth="500px",this.paneEl.style.left="0px",this.paneEl.style.right="0px",this.paneEl.style.marginLeft="auto",this.paneEl.style.marginRight="auto",this.paneEl.style.height=this.screen_height-this.topper-this.settings.bottomOffset+"px",this.paneEl.style.background="#ffffff",this.paneEl.style.borderTopLeftRadius="20px",this.paneEl.style.borderTopRightRadius="20px",this.paneEl.style.boxShadow="0 4px 16px rgba(0,0,0,.12)",this.paneEl.style.overflow="hidden",this.paneEl.style.willChange="transform",this.paneEl.style.transform=`translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.draggableEl=document.createElement("div"),this.draggableEl.className="draggable",this.draggableEl.style.padding="5px",this.draggableEl.style.position="absolute",this.draggableEl.style.top="0",this.draggableEl.style.left="0",this.draggableEl.style.right="0",this.draggableEl.style.marginLeft="auto",this.draggableEl.style.marginRight="auto",this.draggableEl.style.height="30px",this.draggableEl.style.zIndex="12",this.moveEl=document.createElement("div"),this.moveEl.className="move",this.moveEl.style.margin="0 auto",this.moveEl.style.height="5px",this.moveEl.style.background="#c0c0c0",this.moveEl.style.width="36px",this.moveEl.style.borderRadius="4px",this.contentEl=this.el,this.contentEl.style.display="block",this.contentEl.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,this.contentEl.style.overflowX="hidden",this.closeEl=document.createElement("div"),this.closeEl.className="close-button",this.closeEl.style.width="26px",this.closeEl.style.height="26px",this.closeEl.style.position="absolute",this.closeEl.style.background="#ebebeb",this.closeEl.style.top="16px",this.closeEl.style.right="20px",this.closeEl.style.zIndex="14",this.closeEl.style.borderRadius="100%"}present(t={animate:!1}){if(this.el)if(this.isPanePresented()&&this.rendered)this.moveToBreak(this.settings.initialBreak);else if(!this.isPanePresented()||this.rendered){if(this.settings.onWillPresent(),this.breaks={top:this.screen_height,middle:this.screen_height,bottom:this.screen_height},["top","middle","bottom"].forEach(t=>{this.breaks[t]-=this.settings.bottomOffset,this.settings.breaks[t]||(this.settings.breaks[t]=this.defaultBreaksConf[t]),this.settings.breaks[t]&&this.settings.breaks[t].enabled&&this.settings.breaks[t].height&&(this.breaks[t]-=this.settings.breaks[t].height)}),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)=>Math.abs(e)<Math.abs(t)?e:t),this.bottomer=this.brs.reduce((t,e)=>Math.abs(e)>Math.abs(t)?e:t),this.currentBreakpoint=this.breaks[this.settings.initialBreak],this.drawElements(),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),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(this.settings.breaks[this.currentBreak()].bounce)} 0s`}if(this.settings.pushElement&&(this.settings.pushElement=document.querySelector(this.settings.pushElement)),this.settings.showDraggable||(this.draggableEl.style.opacity="0"),this.settings.draggableOver&&(this.paneEl.style.background="transparent",this.paneEl.style.boxShadow="none",this.paneEl.style.paddingTop="30px",this.contentEl.style.background="#ffffff",this.contentEl.style.display="block",this.contentEl.style.borderTopLeftRadius="20px",this.contentEl.style.borderTopRightRadius="20px",this.contentEl.style.boxShadow="0 4px 16px rgba(0,0,0,.12)",this.closeEl.style.top="45px",this.draggableEl.style.padding="15px",this.moveEl.style.width="45px",this.moveEl.style.background="rgba(225, 225, 225, 0.6)",Support.backdropFilter&&(this.moveEl.style.backdropFilter="saturate(180%) blur(20px)",this.moveEl.style.webkitBackdropFilter="saturate(180%) blur(20px)")),this.settings.darkMode&&(this.paneEl.style.background="#1c1c1d",this.paneEl.style.color="#ffffff",this.moveEl.style.background="#5a5a5e"),this.settings.buttonClose){this.paneEl.appendChild(this.closeEl),this.closeEl.addEventListener("click",t=>this.destroy({animate:!0}));let t="#7a7a7e";this.settings.darkMode&&(this.closeEl.style.background="#424246",t="#a8a7ae"),this.closeEl.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\n <path fill="${t}" 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.backdrop&&this.renderBackdrop(),this.scrollElementInit(),this.checkOpacityAttr(this.currentBreakpoint),this.checkOverflowAttr(this.currentBreakpoint),this.device.android&&(document.body.style.overscrollBehaviorY="none",this.device.ionic&&this.device.cordova&&window.addEventListener("keyboardWillHide",()=>{this.paneEl&&window.requestAnimationFrame(()=>{this.wrapperEl.style.width="100%",this.paneEl.style.position="absolute",window.requestAnimationFrame(()=>{this.wrapperEl.style.width="unset",this.paneEl.style.position="fixed"})})})),this.attachAllEvents(),t.animate?this.doTransition({type:"present",translateY:this.breaks[this.settings.initialBreak]}):(this.settings.pushElement&&this.pushTransition(this.breaks[this.settings.initialBreak],"unset"),this.settings.onDidPresent())}else console.warn("Cupertino Pane: specified selector or DOM element already in use",this.selector)}attachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.attachEvents(e)}):this.attachEvents(this.paneEl)}detachAllEvents(){this.settings.dragBy?this.settings.dragBy.forEach(t=>{const e=document.querySelector(t);e&&this.detachEvents(e)}):this.detachEvents(this.paneEl)}resetEvents(){this.detachAllEvents(),this.attachAllEvents()}scrollElementInit(){let t=this.el.querySelectorAll("[overflow-y]");!t.length||t.length>1?this.overflowEl=this.contentEl:this.overflowEl=t[0],this.settings.topperOverflow&&setTimeout(()=>{this.overflowEl.style.height=this.screen_height-this.topper-this.settings.bottomOffset-this.settings.topperOverflowOffset-this.overflowEl.offsetTop+"px"},150)}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&&e.forEach(e=>{e.style.transition=`opacity ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`,e.style.opacity=t>=this.breaks.bottom?"0":"1"})}checkOverflowAttr(t){this.settings.topperOverflow&&(this.overflowEl.style.overflowY=t<=this.topper?"auto":"hidden")}isPanePresented(){let t=Array.from(document.querySelectorAll(".cupertino-pane-wrapper"));return!!t.length&&!!t.find(t=>t.contains(this.selector))}isDragScrollabe(t){return!!t.find(t=>t===this.overflowEl)}touchStart(t){if(this.settings.onDragStart(t),this.disableDragEvents)return;this.allowClick=!0,this.disableDragAngle=!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.disableDragEvents)return;if(this.disableDragAngle)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.getPanelTransformY()+r;if(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)return void(this.disableDragAngle=!0)}if(!(this.isDragScrollabe(t.path||t.composedPath())&&"auto"===this.overflowEl.style.overflowY&&(this.overflowEl.addEventListener("scroll",t=>{this.contentScrollTop=t.target.scrollTop}),a>this.topper&&this.contentScrollTop>0||a<=this.topper)))if(a<=this.topper&&!this.settings.upperThanTop)this.paneEl.style.transform=`translateY(${this.topper}px) translateZ(0px)`;else{if(a<=this.topper&&this.settings.upperThanTop){const t=(-this.topper+this.topper-this.getPanelTransformY())/this.topper/-8;a=this.getPanelTransformY()+r*t}this.settings.freeMode&&!this.settings.bottomClose&&a>=this.bottomer||(!this.settings.lowerThanBottom&&a>=this.bottomer?this.destroy({animate:!0}):(this.allowClick=!1,this.checkOpacityAttr(a),this.checkOverflowAttr(a),this.doTransition({type:"move",translateY:a}),this.steps.push(n)))}}touchEnd(t){if(this.settings.onDragEnd(t),this.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.brs.reduce((t,e)=>Math.abs(e-this.getPanelTransformY())<Math.abs(t-this.getPanelTransformY())?e:t);const i=this.steps[this.steps.length-1]-this.steps[this.steps.length-2],n=window.hasOwnProperty("cordova")?4:3;Math.abs(i)>=n&&(s=this.swipeNextPoint(i,n,s)),this.settings.clickBottomOpen&&this.currentBreakpoint===this.breaks.bottom&&isNaN(i)&&(s=this.settings.breaks.middle.enabled?this.breaks.middle:this.settings.breaks.top.enabled?this.breaks.top:this.breaks.bottom),this.steps=[],this.currentBreakpoint=s,this.checkOpacityAttr(this.currentBreakpoint),this.checkOverflowAttr(this.currentBreakpoint),this.settings.bottomClose&&s===this.breaks.bottom?this.destroy({animate:!0}):this.doTransition({type:"end",translateY:s})}onClick(t){this.allowClick||this.settings.preventClicks&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())}isBackdropPresented(){return!!document.querySelector(".cupertino-pane-wrapper .backdrop")}renderBackdrop(){this.backdropEl=document.createElement("div"),this.backdropEl.className="backdrop",this.backdropEl.style.overflow="hidden",this.backdropEl.style.position="fixed",this.backdropEl.style.width="100%",this.backdropEl.style.bottom="0",this.backdropEl.style.right="0",this.backdropEl.style.left="0",this.backdropEl.style.top="0",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.backdropEl.style.display="none",this.backdropEl.style.zIndex="10",this.wrapperEl.appendChild(this.backdropEl),this.backdropEl.style.display="block",this.backdropEl.addEventListener("click",t=>this.settings.onBackdropTap()),this.resetEvents()}backdrop(t={show:!0}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call backdrop()"),null;this.isBackdropPresented()||this.renderBackdrop();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.touchStartCb,!1),t.addEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.addEventListener(this.touchEvents.end,this.touchEndCb,!1),null===(e=this.backdropEl)||void 0===e||e.addEventListener(this.touchEvents.move,this.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.touchStartCb,e),t.addEventListener(this.touchEvents.move,this.touchMoveCb,!!Support.passiveListener&&{passive:!1,capture:!1}),t.addEventListener(this.touchEvents.end,this.touchEndCb,e),null===(s=this.backdropEl)||void 0===s||s.addEventListener(this.touchEvents.move,this.touchMoveBackdropCb,!!Support.passiveListener&&{passive:!1,capture:!1}),this.touchEvents.cancel&&t.addEventListener(this.touchEvents.cancel,this.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.addEventListener("mousedown",this.touchStartCb,!1),t.addEventListener("mousemove",this.touchMoveCb,!1),t.addEventListener("mouseup",this.touchEndCb,!1),null===(i=this.backdropEl)||void 0===i||i.addEventListener("mousemove",this.touchMoveBackdropCb,!1))}this.settings.preventClicks&&t.addEventListener("click",this.onClickCb,!0)}detachEvents(t){var e,s,i;if(!Support.touch&&Support.pointerEvents)t.removeEventListener(this.touchEvents.start,this.touchStartCb,!1),t.removeEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.touchEndCb,!1),null===(e=this.backdropEl)||void 0===e||e.removeEventListener(this.touchEvents.move,this.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.touchStartCb,e),t.removeEventListener(this.touchEvents.move,this.touchMoveCb,!1),t.removeEventListener(this.touchEvents.end,this.touchEndCb,e),null===(s=this.backdropEl)||void 0===s||s.removeEventListener(this.touchEvents.move,this.touchMoveBackdropCb,!1),this.touchEvents.cancel&&t.removeEventListener(this.touchEvents.cancel,this.touchEndCb,e)}(this.settings.simulateTouch&&!this.device.ios&&!this.device.android||this.settings.simulateTouch&&!Support.touch&&this.device.ios)&&(t.removeEventListener("mousedown",this.touchStartCb,!1),t.removeEventListener("mousemove",this.touchMoveCb,!1),t.removeEventListener("mouseup",this.touchEndCb,!1),null===(i=this.backdropEl)||void 0===i||i.removeEventListener("mousemove",this.touchMoveBackdropCb,!1))}this.settings.preventClicks&&t.removeEventListener("click",this.onClickCb,!0)}getPanelTransformY(){return parseFloat(/\.*translateY\((.*)px\)/i.exec(this.paneEl.style.transform)[1])}disableDrag(){this.disableDragEvents=!0}enableDrag(){this.disableDragEvents=!1}moveToBreak(t){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call moveToBreak()"),null;this.settings.breaks[t].enabled?(this.checkOpacityAttr(this.breaks[t]),this.checkOverflowAttr(this.breaks[t]),this.doTransition({type:"breakpoint",translateY:this.breaks[t]}),this.currentBreakpoint=this.breaks[t]):console.warn("Cupertino Pane: %s breakpoint disabled",t)}hide(){return this.isPanePresented()?this.isHidden()?(console.warn("Cupertino Pane: Pane already hidden"),null):void this.doTransition({type:"hide",translateY:this.screen_height}):(console.warn("Cupertino Pane: Present pane before call hide()"),null)}isHidden(){return this.isPanePresented()?this.paneEl.style.transform===`translateY(${this.screen_height}px) translateZ(0px)`:(console.warn("Cupertino Pane: Present pane before call isHidden()"),null)}currentBreak(){return this.isPanePresented()?this.breaks.top===this.currentBreakpoint?"top":this.breaks.middle===this.currentBreakpoint?"middle":this.breaks.bottom===this.currentBreakpoint?"bottom":null:(console.warn("Cupertino Pane: Present pane before call currentBreak()"),null)}destroyResets(){this.parentEl.appendChild(this.contentEl),this.wrapperEl.remove(),this.detachAllEvents(),this.currentBreakpoint=this.breaks[this.settings.initialBreak],this.contentEl.style.display="none"}destroy(t={animate:!1}){if(!this.isPanePresented())return console.warn("Cupertino Pane: Present pane before call destroy()"),null;this.settings.onWillDismiss(),t.animate?this.doTransition({type:"destroy",translateY:this.screen_height}):(this.destroyResets(),this.settings.onDidDismiss())}pushTransition(t,e){t=this.screen_height-t;const s=this.settings.pushMinHeight?this.settings.pushMinHeight:this.screen_height-this.bottomer,i=this.screen_height-this.topper;this.settings.pushElement.style.transition=e;const n=(t,e,s,i)=>{this.settings.pushElement.style.transform=`translateY(${e}px) scale(${t})`,this.settings.pushElement.style.borderRadius=s+"px",this.settings.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),-1*o(-6,0),-1*o(-10,0),o(.85,1))}doTransition(t={}){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.breaks[this.settings.initialBreak]}px) translateZ(0px)`),void(this.settings.pushElement&&this.pushTransition(this.getPanelTransformY(),"all 0ms linear 0ms"));const e=()=>{"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(),this.settings.onTransitionEnd(),this.paneEl.removeEventListener("transitionend",e)};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 s=Object.entries(this.settings.breaks).find(e=>e[1].height===this.screen_height-t.translateY),i=this.getTimingFunction(!(!s||!s[1].bounce));return this.paneEl.style.transition=`transform ${this.settings.animationDuration}ms ${i} 0s`,this.followerEl&&(this.followerEl.style.transition=`transform ${this.settings.animationDuration}ms ${i} 0s`),this.settings.pushElement&&this.pushTransition(t.translateY,`all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`),"present"===t.type?(this.paneEl.style.transform=`translateY(${this.screen_height}px) translateZ(0px)`,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(0px) translateZ(0px)")},50)):(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.breaks[this.settings.initialBreak]}px) translateZ(0px)`)),void this.paneEl.addEventListener("transitionend",e)}}}exports.CupertinoPane=CupertinoPane; | ||
//# sourceMappingURL=cupertino-pane.min.js.map |
@@ -23,3 +23,4 @@ export declare class Device { | ||
pixelRatio: any; | ||
ionic: boolean; | ||
constructor(); | ||
} |
@@ -0,17 +1,10 @@ | ||
export interface PaneBreak { | ||
enabled: boolean; | ||
height?: number; | ||
bounce?: boolean; | ||
} | ||
export interface PaneBreaks { | ||
top?: { | ||
enabled: boolean; | ||
height?: number; | ||
offset?: number; | ||
}; | ||
middle?: { | ||
enabled: boolean; | ||
height?: number; | ||
offset?: number; | ||
}; | ||
bottom?: { | ||
enabled: boolean; | ||
height?: number; | ||
offset?: number; | ||
}; | ||
top?: PaneBreak; | ||
middle?: PaneBreak; | ||
bottom?: PaneBreak; | ||
} | ||
@@ -27,5 +20,7 @@ export interface TransitionStartEvent { | ||
followerElement: string; | ||
pushElement: any; | ||
pushMinHeight: number; | ||
backdrop: boolean; | ||
backdropOpacity: number; | ||
animationType: ('ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'cubic-bezier'); | ||
animationType: string; | ||
animationDuration: number; | ||
@@ -40,2 +35,3 @@ bottomOffset: number; | ||
lowerThanBottom: boolean; | ||
upperThanTop: boolean; | ||
showDraggable: boolean; | ||
@@ -45,4 +41,7 @@ draggableOver: boolean; | ||
dragBy: string[]; | ||
preventClicks: boolean; | ||
simulateTouch: boolean; | ||
passiveListeners: boolean; | ||
touchMoveStopPropagation: boolean; | ||
touchAngle: number; | ||
breaks: PaneBreaks; | ||
@@ -49,0 +48,0 @@ onDidDismiss: (event?: CustomEvent) => void; |
{ | ||
"name": "cupertino-pane", | ||
"description": "Multiplatform slide-over pane", | ||
"version": "1.1.65", | ||
"version": "1.1.81", | ||
"author": "Roman Antonov (roman-rr)", | ||
@@ -6,0 +6,0 @@ "homepage": "https://github.com/roman-rr/cupertino-pane/", |
@@ -23,2 +23,4 @@ <!-- https://github.com/ai/nanoid - cover --> | ||
⭐ We appreciate your star, it helps! | ||
* [Breaking changes](#breaking-changes) | ||
@@ -33,2 +35,3 @@ * [Demonstration](#demonstration) | ||
* [Contributing](#contributing) | ||
* [Changelog](https://github.com/roman-rr/cupertino-pane/blob/master/CHANGELOG.md) | ||
* [License](#license) | ||
@@ -61,7 +64,10 @@ | ||
- [Base live](https://output.jsbin.com/fuhisey) | ||
- [Overflow live](https://output.jsbin.com/baguroy) | ||
- [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) | ||
- [Apple Clips live](https://output.jsbin.com/luqaxud) | ||
- [Bulletin live](https://output.jsbin.com/fonavuy) | ||
- [Bulletin live](https://output.jsbin.com/maqigod) | ||
- [Starbucks live](https://output.jsbin.com/jayicip) | ||
- [Backdrop drag-opacity live](https://output.jsbin.com/riwahab) | ||
@@ -130,3 +136,3 @@ <div style="display:flex;flex-wrap:wrap;"> | ||
breaks: { | ||
middle: { enabled: true, height: 300 }, | ||
middle: { enabled: true, height: 300, bounce: true }, | ||
bottom: { enabled: true, height: 80 }, | ||
@@ -147,3 +153,3 @@ }, | ||
var myPane = new CupertinoPane('.cupertino-pane', { /* ... */ }); | ||
myPane.present(); | ||
myPane.present({animate: true}); | ||
}); | ||
@@ -158,5 +164,16 @@ ``` | ||
let myPane = new CupertinoPane('.cupertino-pane', CupertinoSettings); | ||
myPane.present(); | ||
myPane.present({animate: true}); | ||
``` | ||
### Class creation | ||
You can pass html element or string selector to class constructor | ||
```javascript | ||
// String selector | ||
new CupertinoPane('.cupertino-pane'); | ||
// HTML element | ||
let element = document.querySelector('.cupertino-pane'); | ||
new CupertinoPane(element); // HTMLElement | ||
``` | ||
## Settings | ||
@@ -168,2 +185,4 @@ ### Common configuration | ||
| **followerElement** | `string` | Follower element selector | Element with selector will following pane transitions | | ||
| **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 | | ||
| **initialBreak** | `'top' \| 'middle' \| 'bottom'` | 'middle' | Initial pane position | | ||
@@ -173,3 +192,3 @@ | **darkMode** | `boolean` | false | Initial pane styles | | ||
| **backdropOpacity** | `number` | 0.4 | Dimmed overlay opacity value | | ||
| **animationType** | `'ease' \| 'ease-in' \| 'ease-out' \| 'ease-in-out' \| 'cubic-bezier'` | 'ease' | Transition property animation type | | ||
| **animationType** | `string` | 'ease' | Base transition timing function | | ||
| **animationDuration** | `number` | 300 | Transition property duration | | ||
@@ -179,2 +198,4 @@ | **bottomClose** | `boolean` | false | Close pane with drag to bottom breakpoint | | ||
| **lowerThanBottom** | `boolean` | true | By default allow user to drag pane lower than bottom position. On `false` will automatically place pane to bottom position on lower than bottom attemption | | ||
| **upperThanTop** | `boolean` | false | Allow user to drag pane upper than maximum top position. Useful with bulletin style without overflow-y | | ||
| **touchAngle** | `number` | null | Allowable angle (in degrees) to trigger touch move | | ||
| **buttonClose** | `boolean` | true | Determinate whetever close button will render or not | | ||
@@ -188,2 +209,4 @@ | **bottomOffset** | `number` | 0 | Margin bottom for pane from screen bottom point | | ||
| **dragBy** | `string[]` | null | Array of selectors for whom elements drag events will be attached. By default drag events attached to pane element. If you are about to drag only with draggable component set option to ['.pane .draggable'] | | ||
| **preventClicks** | `boolean` | true | Prevent accidental unwanted clicks events during move gestures | | ||
| **touchMoveStopPropagation** | `boolean` | false | If enabled, then propagation of "touchmove" will be stopped | | ||
| **simulateTouch** | `boolean` | true | Simulate touch events for Desktop | | ||
@@ -198,3 +221,4 @@ | **passiveListeners** | `boolean` | true | (Indicates that the function specified by listener will never call preventDefault()) | | ||
enabled: true, // Enable or disable breakpoint | ||
height: 0 // Pane breakpoint height | ||
height: 700, // Pane breakpoint height | ||
bounce: true // Bounce pane on transition | ||
}, | ||
@@ -206,5 +230,8 @@ middle: { ... }, | ||
``` | ||
Bottom and middle heights normalized accross devices by default | ||
Default top height: `window.screen.height - (135 * 0.35)` | ||
Bottom and middle heights normalized accross devices by default | ||
Add property `bounce` to break and enjoy transitions in apple stocks style with `cubic-bezier(0.175, 0.885, 0.370, 1.120)` | ||
### Callbacks | ||
@@ -220,3 +247,3 @@ The function that executes when the event fires. | ||
| **onDrag** | `void: () => {}` | Call executes on each new position of pane | | ||
| **onDragEng** | `void: () => {}` | Executes when drag event complete | | ||
| **onDragEnd** | `void: () => {}` | Executes when drag event complete | | ||
| **onBackdropTap** | `void: () => {}` | Call when user tap backdrop overlay | | ||
@@ -272,2 +299,8 @@ | **onTransitionStart** | `void: () => {}` | Executes before auto transition and animation start | | ||
``` | ||
### backdrop({show: **boolean = true**}) | ||
Show/Hide backdrop method | ||
```javascript | ||
myPane.backdrop({show: true}); // show | ||
myPane.backdrop({show: false}); // hide | ||
``` | ||
@@ -294,17 +327,8 @@ ## Attributes | ||
## Future Goals | ||
- [Pull] Element or Selector | ||
- [Pull] Backdrop present/dismiss methods | ||
- [Quality] Touch angle 45 | ||
- [Quality] Click item/drag pane precision on device (threshold) | ||
- [Quality] Topper than top (if scroll - overflow enable else 10px-20px) | ||
- [Quality] Transition timing: easeOutElastic | ||
- [Showcase] Apple Music F7 | ||
- [Accurance] Draw experiment application (Normal/TimeStamp/Native) | ||
- [Accurance] Native Touch Plugin | ||
- [UI] 3D effect (ion-modal example) | ||
- [UI] Drawer control effect (simple/circle) | ||
- [UI] 3D button toggle effect | ||
- [Docs] Docs engine | ||
- [Docs] Live example hosted in pages | ||
- [Platforms] React Native version with one core | ||
- [UI] No taps UI (increase User - Machine information throughput) | ||
- [Docs] Docs engine (F7) | ||
- [Platforms] React Native version | ||
- [Platforms] C++ QT version | ||
@@ -311,0 +335,0 @@ ## Contributing |
import { Support } from './support'; | ||
import { Device } from './device'; | ||
import { Settings } from './models'; | ||
import { Settings, PaneBreaks } from './models'; | ||
export type CupertinoSettings = Partial<Settings>; | ||
@@ -12,4 +12,6 @@ | ||
followerElement: null, | ||
pushElement: null, | ||
pushMinHeight: null, | ||
backdrop: false, | ||
backdropOpacity: 0.4, | ||
backdropOpacity: 0.4, | ||
animationType: 'ease', | ||
@@ -26,7 +28,11 @@ animationDuration: 300, | ||
lowerThanBottom: true, | ||
upperThanTop: false, | ||
showDraggable: true, | ||
draggableOver: false, | ||
clickBottomOpen: true, | ||
preventClicks: true, | ||
simulateTouch: true, | ||
passiveListeners: true, | ||
touchMoveStopPropagation: false, | ||
touchAngle: null, | ||
breaks: {}, | ||
@@ -45,10 +51,12 @@ onDidDismiss: () => {}, | ||
private defaultBreaksConf = { | ||
top: { enabled: true, height: window.innerHeight - (135 * 0.35)}, | ||
middle: { enabled: true, height: 300}, | ||
bottom: { enabled: true, height: 100}, | ||
private defaultBreaksConf: PaneBreaks = { | ||
top: { enabled: true, height: window.innerHeight - (135 * 0.35) }, | ||
middle: { enabled: true, height: 300 }, | ||
bottom: { enabled: true, height: 100 }, | ||
}; | ||
private screen_height: number = window.innerHeight; | ||
private steps: any[] = []; | ||
private startP: any; | ||
private startY: number; | ||
private startX: number; | ||
private pointerDown: boolean = false; | ||
@@ -59,4 +67,6 @@ private topper: number; | ||
private contentScrollTop: number = 0; | ||
private draggableScrollOffset: number = 0; | ||
private disableDragEvents: boolean = false; | ||
private disableDragAngle: boolean = false; | ||
private rendered: boolean = false; | ||
private allowClick: boolean = true; | ||
@@ -80,16 +90,25 @@ private breaks: {} = {} | ||
constructor(private selector: string, conf: CupertinoSettings = {}) { | ||
// Unable attach DOM element | ||
if (!<HTMLElement>document.querySelector(this.selector)) { | ||
console.warn('Cupertino Pane: wrong selector specified', this.selector); | ||
constructor(private selector: (string | HTMLElement), | ||
conf: CupertinoSettings = {}) { | ||
// Element or selector | ||
if (selector instanceof HTMLElement) { | ||
this.selector = selector; | ||
} else { | ||
this.selector = <HTMLElement>document.querySelector(selector); | ||
} | ||
// Unable attach selector or DOM element | ||
if (!this.selector) { | ||
console.warn('Cupertino Pane: wrong selector or DOM element specified', this.selector); | ||
return; | ||
} | ||
// Pane already was rendered | ||
// Pane class created | ||
if (this.isPanePresented()) { | ||
console.warn('Cupertino Pane: specified selector already in use', this.selector); | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
this.el = <HTMLElement>document.querySelector(this.selector); | ||
this.el = this.selector; | ||
this.el.style.display = 'none'; | ||
@@ -109,3 +128,3 @@ this.settings = {...this.settings, ...conf}; | ||
this.parentEl = this.settings.parentElement; | ||
// Wrapper | ||
@@ -167,17 +186,2 @@ this.wrapperEl = document.createElement('div'); | ||
// Backdrop | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
// Close button | ||
@@ -192,2 +196,3 @@ this.closeEl = document.createElement('div'); | ||
this.closeEl.style.right = '20px'; | ||
this.closeEl.style.zIndex = '14'; | ||
this.closeEl.style.borderRadius = '100%'; | ||
@@ -199,7 +204,13 @@ } | ||
// Pane already was rendered | ||
if (this.isPanePresented()) { | ||
// Pane already exist and was rendered | ||
if (this.isPanePresented() && this.rendered) { | ||
this.moveToBreak(this.settings.initialBreak); | ||
return; | ||
} | ||
// Pane already exist but not rendered in this class | ||
if (this.isPanePresented() && !this.rendered) { | ||
console.warn('Cupertino Pane: specified selector or DOM element already in use', this.selector); | ||
return; | ||
} | ||
@@ -223,8 +234,8 @@ // Emit event | ||
} | ||
// Add offsets (offset or height, later need remove ofsfset) | ||
if (this.settings.breaks[val] | ||
&& this.settings.breaks[val].enabled | ||
&& (this.settings.breaks[val].offset || this.settings.breaks[val].height)) { | ||
this.breaks[val] -= (this.settings.breaks[val].offset || this.settings.breaks[val].height); | ||
&& this.settings.breaks[val].height) { | ||
this.breaks[val] -= this.settings.breaks[val].height; | ||
} | ||
@@ -269,2 +280,3 @@ }); | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
@@ -282,5 +294,9 @@ if (this.settings.followerElement) { | ||
this.followerEl.style.transform = `translateY(0px) translateZ(0px)`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `all ${this.settings.animationDuration}ms ${this.getTimingFunction(this.settings.breaks[this.currentBreak()].bounce)} 0s`; | ||
} | ||
if (this.settings.pushElement) { | ||
this.settings.pushElement = document.querySelector(this.settings.pushElement); | ||
} | ||
if (!this.settings.showDraggable) { | ||
@@ -338,34 +354,35 @@ this.draggableEl.style.opacity = '0'; | ||
if (this.settings.backdrop) { | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
this.renderBackdrop(); | ||
} | ||
// Get overflow element | ||
let attrElements = document.querySelectorAll(`${this.selector} [overflow-y]`); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
} else { | ||
this.overflowEl = <HTMLElement>attrElements[0]; | ||
} | ||
if (this.settings.topperOverflow) { | ||
this.overflowEl.style.height = `${this.screen_height - this.topper - 51 | ||
+ (this.settings.draggableOver ? 30 : 0) | ||
- this.settings.topperOverflowOffset}px`; | ||
} | ||
this.scrollElementInit(); | ||
this.checkOpacityAttr(this.currentBreakpoint); | ||
this.checkOverflowAttr(this.currentBreakpoint); | ||
/****** Attach Events *******/ | ||
if (!this.settings.dragBy) { | ||
this.attachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.attachEvents(el); | ||
}); | ||
/****** Fix android issues *******/ | ||
if (this.device.android) { | ||
// Body patch prevent android pull-to-refresh | ||
document.body.style['overscrollBehaviorY'] = 'none'; | ||
if (this.device.ionic | ||
&& this.device.cordova) { | ||
// TODO: manual keyboard control (#49 issue) | ||
// Fix android keyboard issue with transition (resize height on hide) | ||
window.addEventListener('keyboardWillHide', () => { | ||
if (!this.paneEl) return; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = '100%'; | ||
this.paneEl.style.position = 'absolute'; | ||
window.requestAnimationFrame(() => { | ||
this.wrapperEl.style.width = 'unset'; | ||
this.paneEl.style.position = 'fixed'; | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
/****** Attach Events *******/ | ||
this.attachAllEvents(); | ||
/****** Animation & Transition ******/ | ||
@@ -376,2 +393,5 @@ if (conf.animate) { | ||
// Emit event | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.breaks[this.settings.initialBreak], 'unset'); | ||
} | ||
this.settings.onDidPresent(); | ||
@@ -381,4 +401,60 @@ } | ||
/** | ||
* 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); | ||
}); | ||
} | ||
} | ||
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); | ||
}); | ||
} | ||
} | ||
private resetEvents() { | ||
this.detachAllEvents(); | ||
this.attachAllEvents(); | ||
} | ||
private scrollElementInit() { | ||
let attrElements = this.el.querySelectorAll('[overflow-y]'); | ||
if (!attrElements.length || attrElements.length > 1) { | ||
this.overflowEl = this.contentEl; | ||
} else { | ||
this.overflowEl = <HTMLElement>attrElements[0]; | ||
} | ||
if (this.settings.topperOverflow) { | ||
// Good to get rid of timeout | ||
// but render dom take a time | ||
setTimeout(() => { | ||
this.overflowEl.style.height = `${this.screen_height | ||
- this.topper | ||
- this.settings.bottomOffset | ||
- this.settings.topperOverflowOffset | ||
- this.overflowEl.offsetTop}px`; | ||
}, 150); | ||
} | ||
} | ||
private getTimingFunction(bounce) { | ||
return bounce ? 'cubic-bezier(0.175, 0.885, 0.370, 1.120)' : this.settings.animationType; | ||
} | ||
private checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) return; | ||
@@ -397,4 +473,6 @@ attrElements.forEach((item) => { | ||
private isPanePresented():boolean { | ||
return document.querySelector(`.cupertino-pane-wrapper ${this.selector}`) | ||
? true : false; | ||
// Check through all presented panes | ||
let wrappers = Array.from(document.querySelectorAll('.cupertino-pane-wrapper')); | ||
if (!wrappers.length) return false; | ||
return wrappers.find((item) => item.contains(<HTMLElement>this.selector)) ? true: false; | ||
} | ||
@@ -420,14 +498,22 @@ | ||
// Allow clicks by default, disallow on move | ||
this.allowClick = true; | ||
// Allow touch angle by default, disallow no move with condition | ||
this.disableDragAngle = false; | ||
const targetTouch = t.type === 'touchstart' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchstart' ? targetTouch.clientY : t.clientY; | ||
const screenX = t.type === 'touchstart' ? targetTouch.clientX : t.clientX; | ||
if (t.type === 'mousedown') this.pointerDown = true; | ||
this.startP = screenY; | ||
this.startY = screenY; | ||
this.startX = screenX; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path)) { | ||
this.startP += this.contentScrollTop; | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startY += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
this.steps.push(this.startY); | ||
} | ||
@@ -439,2 +525,13 @@ | ||
*/ | ||
private touchMoveBackdropCb = (t) => this.touchMoveBackdrop(t); | ||
private touchMoveBackdrop(t) { | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
} | ||
/** | ||
* Touch Move Event | ||
* @param t | ||
*/ | ||
private touchMoveCb = (t) => this.touchMove(t); | ||
@@ -446,6 +543,12 @@ private touchMove(t) { | ||
if (this.disableDragEvents) return; | ||
if (this.disableDragAngle) return; | ||
if (this.settings.touchMoveStopPropagation) { | ||
t.stopPropagation(); | ||
} | ||
// Handle desktop/mobile events | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
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; | ||
@@ -455,7 +558,21 @@ | ||
let n = screenY; | ||
const diff = n - this.steps[this.steps.length - 1]; | ||
const newVal = this.getPanelTransformY() + diff; | ||
let v = screenX; | ||
const diffY = n - this.steps[this.steps.length - 1]; | ||
let newVal = this.getPanelTransformY() + diffY; | ||
// Touch angle | ||
if (this.settings.touchAngle) { | ||
let touchAngle; | ||
const diffX = v - this.startX; | ||
const diffY = n - this.startY; | ||
touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; | ||
if (diffX * diffX + diffY * diffY >= 25 | ||
&& (90 - touchAngle > this.settings.touchAngle)) { | ||
this.disableDragAngle = true; | ||
return; | ||
} | ||
} | ||
// Not allow move panel with positive overflow scroll | ||
if (this.isDragScrollabe(t.path) | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
@@ -472,6 +589,16 @@ this.overflowEl.addEventListener('scroll', (s: any) => { | ||
// Not allow drag upper than topper point | ||
// Not allow drag topper than top point | ||
if (newVal <= this.topper && !this.settings.upperThanTop) { | ||
this.paneEl.style.transform = `translateY(${this.topper}px) translateZ(0px)`; | ||
return; | ||
} | ||
// Allow drag topper than top point | ||
if (newVal <= this.topper && this.settings.upperThanTop) { | ||
const differKoef = ((-this.topper + this.topper - this.getPanelTransformY()) / this.topper) / -8; | ||
newVal = this.getPanelTransformY() + (diffY * differKoef); | ||
} | ||
// Not allow drag lower than bottom if free mode | ||
if ((newVal <= this.topper) | ||
|| (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer))) { | ||
if (this.settings.freeMode && !this.settings.bottomClose && (newVal >= this.bottomer)) { | ||
return; | ||
@@ -487,2 +614,5 @@ } | ||
// Disallow accidentaly clicks while slide gestures | ||
this.allowClick = false; | ||
this.checkOpacityAttr(newVal); | ||
@@ -507,3 +637,3 @@ this.checkOverflowAttr(newVal); | ||
const targetTouch = t.type === 'touchmove' && t.targetTouches && (t.targetTouches[0] || t.changedTouches[0]); | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
const screenY = t.type === 'touchmove' ? targetTouch.clientY : t.clientY; | ||
if (t.type === 'mouseup') this.pointerDown = false; | ||
@@ -548,2 +678,18 @@ | ||
/** | ||
* Click Event | ||
* @param t | ||
*/ | ||
private onClickCb = (t) => this.onClick(t); | ||
private onClick(t) { | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (!this.allowClick) { | ||
if (this.settings.preventClicks) { | ||
t.preventDefault(); | ||
t.stopPropagation(); | ||
t.stopImmediatePropagation(); | ||
} | ||
} | ||
} | ||
private swipeNextPoint = (diff, maxDiff, closest) => { | ||
@@ -589,2 +735,65 @@ if (this.currentBreakpoint === this.breaks['top']) { | ||
private isBackdropPresented() { | ||
return document.querySelector(`.cupertino-pane-wrapper .backdrop`) | ||
? true : false; | ||
} | ||
private renderBackdrop() { | ||
this.backdropEl = document.createElement('div'); | ||
this.backdropEl.className = 'backdrop'; | ||
this.backdropEl.style.overflow = 'hidden'; | ||
this.backdropEl.style.position = 'fixed'; | ||
this.backdropEl.style.width = '100%'; | ||
this.backdropEl.style.bottom = '0'; | ||
this.backdropEl.style.right = '0'; | ||
this.backdropEl.style.left = '0'; | ||
this.backdropEl.style.top = '0'; | ||
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.backdropEl.style.display = 'none'; | ||
this.backdropEl.style.zIndex = '10'; | ||
this.wrapperEl.appendChild(this.backdropEl); | ||
this.backdropEl.style.display = 'block'; | ||
this.backdropEl.addEventListener('click', (t) => this.settings.onBackdropTap()); | ||
// Reset events to attach backdrop stop propagation | ||
this.resetEvents(); | ||
} | ||
/** | ||
* Backdrop | ||
*/ | ||
public backdrop(conf = { show: true }) { | ||
if (!this.isPanePresented()) { | ||
console.warn(`Cupertino Pane: Present pane before call backdrop()`); | ||
return null; | ||
} | ||
if (!this.isBackdropPresented()) { | ||
this.renderBackdrop(); | ||
} | ||
const transitionEnd = () => { | ||
this.backdropEl.style.transition = `initial`; | ||
this.backdropEl.style.display = `none`; | ||
this.backdropEl.removeEventListener('transitionend', transitionEnd); | ||
} | ||
this.backdropEl.style.transition = `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.backdropEl.style.backgroundColor = 'rgba(0,0,0,.0)'; | ||
if (!conf.show) { | ||
// Destroy | ||
if (this.backdropEl.style.display === 'none') return; | ||
this.backdropEl.addEventListener('transitionend', transitionEnd); | ||
} else { | ||
// Present | ||
this.backdropEl.style.display = 'block'; | ||
setTimeout(() => { | ||
this.backdropEl.style.backgroundColor = `rgba(0,0,0, ${this.settings.backdropOpacity})`; | ||
}, 50); | ||
} | ||
} | ||
@@ -620,2 +829,5 @@ /************************************ | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} else { | ||
@@ -628,2 +840,5 @@ | ||
el.addEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener(this.touchEvents.move, this.touchMoveBackdropCb, Support.passiveListener ? { passive: false, capture: false } : false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -638,4 +853,12 @@ el.addEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.addEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.addEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.addEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
@@ -649,2 +872,5 @@ | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
} else { | ||
@@ -656,2 +882,5 @@ if (Support.touch) { | ||
el.removeEventListener(this.touchEvents.end, this.touchEndCb, passiveListener); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener(this.touchEvents.move, this.touchMoveBackdropCb, false); | ||
if (this.touchEvents['cancel']) { | ||
@@ -665,4 +894,12 @@ el.removeEventListener(this.touchEvents['cancel'], this.touchEndCb, passiveListener); | ||
el.removeEventListener('mouseup', this.touchEndCb, false); | ||
// Backdrop propagation fix | ||
this.backdropEl?.removeEventListener('mousemove', this.touchMoveBackdropCb, false); | ||
} | ||
} | ||
// Prevent accidental unwanted clicks events during swiping | ||
if (this.settings.preventClicks) { | ||
el.removeEventListener('click', this.onClickCb, true); | ||
} | ||
} | ||
@@ -750,10 +987,3 @@ | ||
/****** Detach Events *******/ | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.detachEvents(el); | ||
}); | ||
} | ||
this.detachAllEvents(); | ||
@@ -786,2 +1016,36 @@ // Reset vars | ||
private pushTransition(newPaneY: number, transition: string) { | ||
newPaneY = this.screen_height - newPaneY; | ||
const topHeight = this.settings.pushMinHeight ? this.settings.pushMinHeight : this.screen_height - this.bottomer; | ||
const minHeight = this.screen_height - this.topper; | ||
this.settings.pushElement.style.transition = transition; | ||
const setStyles = (scale, y, border, contrast) => { | ||
this.settings.pushElement.style.transform = `translateY(${y}px) scale(${scale})`; | ||
this.settings.pushElement.style.borderRadius = `${border}px`; | ||
this.settings.pushElement.style.filter = `contrast(${contrast})`; | ||
}; | ||
if (newPaneY <= topHeight) { | ||
setStyles(1, 0, 0, 1); | ||
return; | ||
} | ||
const getXbyY = (min, max) => { | ||
let val = (minHeight * max - topHeight * min) * -1; | ||
val -= (min - max) * newPaneY; | ||
val /= (topHeight - minHeight); | ||
if (val > max) val = max; | ||
if (val < min) val = min; | ||
return val; | ||
}; | ||
setStyles( | ||
getXbyY(0.93, 1), | ||
getXbyY(-6, 0) * -1, | ||
getXbyY(-10, 0) * -1, | ||
getXbyY(0.85, 1) | ||
); | ||
} | ||
/*********************************** | ||
@@ -791,2 +1055,3 @@ * Transitions handler | ||
private doTransition(params:any = {}): void { | ||
// touchmove simple event | ||
@@ -801,2 +1066,7 @@ if (params.type === 'move') { | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(this.getPanelTransformY(), 'all 0ms linear 0ms'); | ||
} | ||
@@ -823,3 +1093,3 @@ return; | ||
} | ||
} | ||
} | ||
@@ -867,9 +1137,21 @@ // Emit event | ||
// Get timing function && push for next | ||
// TODO: getBreakByHeight or by translateY() | ||
const nextBreak = Object.entries(this.settings.breaks).find( | ||
val => val[1].height === (this.screen_height - params.translateY) | ||
); | ||
const timingForNext = this.getTimingFunction(nextBreak && nextBreak[1].bounce ? true : false); | ||
// style | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.paneEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
// Bind for follower same transitions | ||
if (this.followerEl) { | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`; | ||
this.followerEl.style.transition = `transform ${this.settings.animationDuration}ms ${timingForNext} 0s`; | ||
} | ||
// Push transition | ||
if (this.settings.pushElement) { | ||
this.pushTransition(params.translateY, `all ${this.settings.animationDuration}ms ${this.settings.animationType} 0s`); | ||
} | ||
// Main transitions | ||
@@ -880,5 +1162,5 @@ if (params.type === 'present') { | ||
// Emit event | ||
this.settings.onTransitionStart({translateY: {new: this.breaks[this.settings.initialBreak]}}); | ||
this.settings.onTransitionStart({translateY: {new: params.translateY}}); | ||
this.paneEl.style.transform = `translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`; | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
// Bind for follower same transitions | ||
@@ -885,0 +1167,0 @@ if (this.followerEl) { |
@@ -25,2 +25,3 @@ import { Support } from './support'; | ||
public pixelRatio: any; | ||
public ionic: boolean = !!document.querySelector('ion-app'); | ||
@@ -27,0 +28,0 @@ constructor() { |
@@ -0,5 +1,11 @@ | ||
export interface PaneBreak { | ||
enabled: boolean, | ||
height?: number, | ||
bounce?: boolean | ||
} | ||
export interface PaneBreaks { | ||
top?: {enabled: boolean, height?: number, offset?: number}; | ||
middle?: {enabled: boolean, height?: number, offset?: number}; | ||
bottom?: {enabled: boolean, height?: number, offset?: number}; | ||
top?: PaneBreak; | ||
middle?: PaneBreak; | ||
bottom?: PaneBreak; | ||
} | ||
@@ -15,5 +21,7 @@ | ||
followerElement: string; | ||
pushElement: any; | ||
pushMinHeight: number; | ||
backdrop: boolean; | ||
backdropOpacity: number; | ||
animationType: ('ease'|'ease-in'|'ease-out'|'ease-in-out'|'cubic-bezier'); | ||
animationType: string; | ||
animationDuration: number; | ||
@@ -28,2 +36,3 @@ bottomOffset: number, | ||
lowerThanBottom: boolean; | ||
upperThanTop: boolean; | ||
showDraggable: boolean; | ||
@@ -33,4 +42,7 @@ draggableOver: boolean; | ||
dragBy: string[]; | ||
preventClicks: boolean; | ||
simulateTouch: boolean; | ||
passiveListeners: boolean; | ||
touchMoveStopPropagation: boolean; | ||
touchAngle: number; | ||
breaks: PaneBreaks; | ||
@@ -37,0 +49,0 @@ onDidDismiss: (event?: CustomEvent) => void, |
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
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
11975921
49
4099
326