cupertino-pane
Advanced tools
Comparing version 1.1.6 to 1.1.7
--- | ||
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 @@ |
@@ -15,3 +15,5 @@ import { Settings } from './models'; | ||
private contentScrollTop; | ||
private draggableScrollOffset; | ||
private disableDragEvents; | ||
private rendered; | ||
private breaks; | ||
@@ -31,3 +33,3 @@ private brs; | ||
private device; | ||
constructor(selector: string, conf?: CupertinoSettings); | ||
constructor(selector: (string | HTMLElement), conf?: CupertinoSettings); | ||
private drawElements; | ||
@@ -37,2 +39,6 @@ present(conf?: { | ||
}): void; | ||
/** | ||
* Private Utils methods | ||
*/ | ||
private scrollElementInit; | ||
private checkOpacityAttr; | ||
@@ -42,2 +48,6 @@ private checkOverflowAttr; | ||
/** | ||
* Check if drag event fired by scrollable element | ||
*/ | ||
private isDragScrollabe; | ||
/** | ||
* Touch Start Event | ||
@@ -61,2 +71,10 @@ * @param t | ||
private swipeNextPoint; | ||
private isBackdropPresented; | ||
private renderBackdrop; | ||
/** | ||
* Backdrop | ||
*/ | ||
backdrop(conf?: { | ||
show: boolean; | ||
}): any; | ||
/************************************ | ||
@@ -63,0 +81,0 @@ * Events |
/** | ||
* Cupertino Pane 1.1.6 | ||
* Cupertino Pane 1.1.7 | ||
* Multiplatform slide-over pane | ||
@@ -10,3 +10,3 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 10, 2020 | ||
* Released on: July 22, 2020 | ||
*/ | ||
@@ -68,2 +68,3 @@ | ||
this.electron = false; | ||
this.ionic = !!document.querySelector('ion-app'); | ||
const platform = window.navigator.platform; | ||
@@ -162,3 +163,3 @@ const ua = window.navigator.userAgent; | ||
animationDuration: 300, | ||
dragBy: ['.cupertino-pane-wrapper .pane'], | ||
dragBy: null, | ||
bottomOffset: 0, | ||
@@ -186,2 +187,3 @@ darkMode: false, | ||
onBackdropTap: () => { }, | ||
onTransitionStart: () => { }, | ||
onTransitionEnd: () => { } | ||
@@ -198,3 +200,5 @@ }; | ||
this.contentScrollTop = 0; | ||
this.draggableScrollOffset = 0; | ||
this.disableDragEvents = false; | ||
this.rendered = false; | ||
this.breaks = {}; | ||
@@ -284,13 +288,20 @@ this.brs = []; | ||
})(); | ||
// 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'; | ||
@@ -320,3 +331,7 @@ this.settings = Object.assign(Object.assign({}, this.settings), conf); | ||
this.paneEl.style.width = '100%'; | ||
this.paneEl.style.maxWidth = '480px'; | ||
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`; | ||
@@ -341,2 +356,3 @@ this.paneEl.style.background = '#ffffff'; | ||
this.draggableEl.style.height = '30px'; | ||
this.draggableEl.style.zIndex = '12'; | ||
// Move | ||
@@ -355,16 +371,2 @@ this.moveEl = document.createElement('div'); | ||
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 | ||
@@ -384,7 +386,12 @@ this.closeEl = document.createElement('div'); | ||
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 | ||
@@ -443,2 +450,3 @@ this.settings.onWillPresent(); | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
if (this.settings.followerElement) { | ||
@@ -497,27 +505,40 @@ if (!document.querySelector(this.settings.followerElement)) { | ||
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 *******/ | ||
if (!this.settings.dragBy) { | ||
this.attachEvents(this.paneEl); | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.attachEvents(el); | ||
}); | ||
} | ||
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 *******/ | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.attachEvents(el); | ||
}); | ||
/****** Animation & Transition ******/ | ||
@@ -532,4 +553,27 @@ if (conf.animate) { | ||
} | ||
/** | ||
* Private Utils methods | ||
*/ | ||
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); | ||
} | ||
} | ||
checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) | ||
@@ -548,5 +592,14 @@ 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; | ||
} | ||
/** | ||
* Check if drag event fired by scrollable element | ||
*/ | ||
isDragScrollabe(path) { | ||
return !!path.find(item => item === this.overflowEl); | ||
} | ||
touchStart(t) { | ||
@@ -559,7 +612,10 @@ // Event emitter | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerdown') | ||
if (t.type === 'mousedown') | ||
this.pointerDown = true; | ||
this.startP = screenY; | ||
// if overflow content was scrolled - increase to scrolled value | ||
this.startP += this.contentScrollTop; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startP += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
@@ -575,3 +631,3 @@ } | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointermove' && !this.pointerDown) | ||
if (t.type === 'mousemove' && !this.pointerDown) | ||
return; | ||
@@ -583,3 +639,4 @@ // Delta | ||
// Not allow move panel with positive overflow scroll | ||
if (this.overflowEl.style.overflowY === 'auto') { | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
this.overflowEl.addEventListener('scroll', (s) => { | ||
@@ -593,3 +650,2 @@ this.contentScrollTop = s.target.scrollTop; | ||
} | ||
this.contentScrollTop = 0; | ||
} | ||
@@ -620,3 +676,3 @@ // Not allow drag upper than topper point | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerup') | ||
if (t.type === 'mouseup') | ||
this.pointerDown = false; | ||
@@ -653,2 +709,56 @@ // Determinate nearest point | ||
} | ||
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()); | ||
} | ||
/** | ||
* 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) { | ||
@@ -771,7 +881,12 @@ // Touch Events | ||
/****** Detach Events *******/ | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
// Reset vars | ||
@@ -873,6 +988,8 @@ this.currentBreakpoint = this.breaks[this.settings.initialBreak]; | ||
} | ||
// main transitions | ||
// Main transitions | ||
if (params.type === 'present') { | ||
this.paneEl.style.transform = `translateY(${this.screen_height}px) translateZ(0px)`; | ||
setTimeout(() => { | ||
// 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)`; | ||
@@ -886,2 +1003,4 @@ // Bind for follower same transitions | ||
else { | ||
// Emit event | ||
this.settings.onTransitionStart({ translateY: { new: params.translateY } }); | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
@@ -888,0 +1007,0 @@ // Bind for follower same transitions |
/** | ||
* Cupertino Pane 1.1.6 | ||
* Cupertino Pane 1.1.7 | ||
* Multiplatform slide-over pane | ||
@@ -10,3 +10,3 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 10, 2020 | ||
* Released on: July 22, 2020 | ||
*/ | ||
@@ -72,2 +72,3 @@ | ||
this.electron = false; | ||
this.ionic = !!document.querySelector('ion-app'); | ||
const platform = window.navigator.platform; | ||
@@ -166,3 +167,3 @@ const ua = window.navigator.userAgent; | ||
animationDuration: 300, | ||
dragBy: ['.cupertino-pane-wrapper .pane'], | ||
dragBy: null, | ||
bottomOffset: 0, | ||
@@ -190,2 +191,3 @@ darkMode: false, | ||
onBackdropTap: () => { }, | ||
onTransitionStart: () => { }, | ||
onTransitionEnd: () => { } | ||
@@ -202,3 +204,5 @@ }; | ||
this.contentScrollTop = 0; | ||
this.draggableScrollOffset = 0; | ||
this.disableDragEvents = false; | ||
this.rendered = false; | ||
this.breaks = {}; | ||
@@ -288,13 +292,20 @@ this.brs = []; | ||
})(); | ||
// 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'; | ||
@@ -324,3 +335,7 @@ this.settings = Object.assign(Object.assign({}, this.settings), conf); | ||
this.paneEl.style.width = '100%'; | ||
this.paneEl.style.maxWidth = '480px'; | ||
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`; | ||
@@ -345,2 +360,3 @@ this.paneEl.style.background = '#ffffff'; | ||
this.draggableEl.style.height = '30px'; | ||
this.draggableEl.style.zIndex = '12'; | ||
// Move | ||
@@ -359,16 +375,2 @@ this.moveEl = document.createElement('div'); | ||
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 | ||
@@ -388,7 +390,12 @@ this.closeEl = document.createElement('div'); | ||
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 | ||
@@ -447,2 +454,3 @@ this.settings.onWillPresent(); | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
if (this.settings.followerElement) { | ||
@@ -501,27 +509,40 @@ if (!document.querySelector(this.settings.followerElement)) { | ||
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 *******/ | ||
if (!this.settings.dragBy) { | ||
this.attachEvents(this.paneEl); | ||
} | ||
else { | ||
this.overflowEl = attrElements[0]; | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.attachEvents(el); | ||
}); | ||
} | ||
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 *******/ | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.attachEvents(el); | ||
}); | ||
/****** Animation & Transition ******/ | ||
@@ -536,4 +557,27 @@ if (conf.animate) { | ||
} | ||
/** | ||
* Private Utils methods | ||
*/ | ||
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); | ||
} | ||
} | ||
checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) | ||
@@ -552,5 +596,14 @@ 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; | ||
} | ||
/** | ||
* Check if drag event fired by scrollable element | ||
*/ | ||
isDragScrollabe(path) { | ||
return !!path.find(item => item === this.overflowEl); | ||
} | ||
touchStart(t) { | ||
@@ -563,7 +616,10 @@ // Event emitter | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerdown') | ||
if (t.type === 'mousedown') | ||
this.pointerDown = true; | ||
this.startP = screenY; | ||
// if overflow content was scrolled - increase to scrolled value | ||
this.startP += this.contentScrollTop; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startP += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
@@ -579,3 +635,3 @@ } | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointermove' && !this.pointerDown) | ||
if (t.type === 'mousemove' && !this.pointerDown) | ||
return; | ||
@@ -587,3 +643,4 @@ // Delta | ||
// Not allow move panel with positive overflow scroll | ||
if (this.overflowEl.style.overflowY === 'auto') { | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
this.overflowEl.addEventListener('scroll', (s) => { | ||
@@ -597,3 +654,2 @@ this.contentScrollTop = s.target.scrollTop; | ||
} | ||
this.contentScrollTop = 0; | ||
} | ||
@@ -624,3 +680,3 @@ // Not allow drag upper than topper point | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerup') | ||
if (t.type === 'mouseup') | ||
this.pointerDown = false; | ||
@@ -657,2 +713,56 @@ // Determinate nearest point | ||
} | ||
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()); | ||
} | ||
/** | ||
* 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) { | ||
@@ -775,7 +885,12 @@ // Touch Events | ||
/****** Detach Events *******/ | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} | ||
else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) | ||
this.detachEvents(el); | ||
}); | ||
} | ||
// Reset vars | ||
@@ -877,6 +992,8 @@ this.currentBreakpoint = this.breaks[this.settings.initialBreak]; | ||
} | ||
// main transitions | ||
// Main transitions | ||
if (params.type === 'present') { | ||
this.paneEl.style.transform = `translateY(${this.screen_height}px) translateZ(0px)`; | ||
setTimeout(() => { | ||
// 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)`; | ||
@@ -890,2 +1007,4 @@ // Bind for follower same transitions | ||
else { | ||
// Emit event | ||
this.settings.onTransitionStart({ translateY: { new: params.translateY } }); | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
@@ -892,0 +1011,0 @@ // Bind for follower same transitions |
/** | ||
* Cupertino Pane 1.1.6 | ||
* Cupertino Pane 1.1.7 | ||
* Multiplatform slide-over pane | ||
@@ -10,6 +10,6 @@ * https://github.com/roman-rr/cupertino-pane/ | ||
* | ||
* Released on: June 10, 2020 | ||
* Released on: July 22, 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,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,backdrop:!1,backdropOpacity:.4,animationType:"ease",animationDuration:300,dragBy:[".cupertino-pane-wrapper .pane"],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:()=>{},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.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="480px",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.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.forEach(t=>{const e=document.querySelector(t);e&&this.attachEvents(e)}),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)}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;"pointerdown"===t.type&&(this.pointerDown=!0),this.startP=s,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("pointermove"===t.type&&!this.pointerDown)return;let i=s;const n=i-this.steps[this.steps.length-1],o=this.getPanelTransformY()+n;if("auto"===this.overflowEl.style.overflowY){if(this.overflowEl.addEventListener("scroll",t=>{this.contentScrollTop=t.target.scrollTop}),o>this.topper&&this.contentScrollTop>0||o<=this.topper)return;this.contentScrollTop=0}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;"pointerup"===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.forEach(t=>{const e=document.querySelector(t);e&&this.detachEvents(e)}),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.paneEl.style.transform=`translateY(${this.breaks[this.settings.initialBreak]}px) translateZ(0px)`,this.followerEl&&(this.followerEl.style.transform="translateY(0px) translateZ(0px)")},50)):(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,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.rendered=!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})(),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.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].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.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.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.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.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()}else console.warn("Cupertino Pane: specified selector or DOM element already in use",this.selector)}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)}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;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||t.composedPath())&&(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||t.composedPath())&&"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})}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())}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){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; | ||
//# sourceMappingURL=cupertino-pane.min.js.map |
@@ -23,3 +23,4 @@ export declare class Device { | ||
pixelRatio: any; | ||
ionic: boolean; | ||
constructor(); | ||
} |
@@ -18,2 +18,7 @@ export interface PaneBreaks { | ||
} | ||
export interface TransitionStartEvent { | ||
translateY: { | ||
new: number; | ||
}; | ||
} | ||
export interface Settings { | ||
@@ -50,3 +55,4 @@ initialBreak: ('top' | 'middle' | 'bottom'); | ||
onBackdropTap: (event?: CustomEvent) => void; | ||
onTransitionStart: (event?: TransitionStartEvent) => void; | ||
onTransitionEnd: (event?: CustomEvent) => void; | ||
} |
{ | ||
"name": "cupertino-pane", | ||
"description": "Multiplatform slide-over pane", | ||
"version": "1.1.6", | ||
"version": "1.1.7", | ||
"author": "Roman Antonov (roman-rr)", | ||
@@ -6,0 +6,0 @@ "homepage": "https://github.com/roman-rr/cupertino-pane/", |
@@ -32,2 +32,3 @@ <!-- https://github.com/ai/nanoid - cover --> | ||
* [Contributing](#contributing) | ||
* [Changelog](https://github.com/roman-rr/cupertino-pane/blob/master/CHANGELOG.md) | ||
* [License](#license) | ||
@@ -59,7 +60,10 @@ | ||
## Demonstration | ||
- [Base live](https://output.jsbin.com/nomakijeta) | ||
- [Overflow live](https://output.jsbin.com/xugokodoka) | ||
- [Follower live](https://output.jsbin.com/qehusacori) | ||
- [Bulletin live](https://output.jsbin.com/peturiweva) | ||
- [Starbucks live](https://output.jsbin.com/dowiqegelo) | ||
- [Base live](https://output.jsbin.com/fuhisey) | ||
- [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) | ||
- [Starbucks live](https://output.jsbin.com/jayicip) | ||
- [Backdrop drag-opacity live](https://output.jsbin.com/riwahab) | ||
@@ -157,2 +161,13 @@ <div style="display:flex;flex-wrap:wrap;"> | ||
### 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 | ||
@@ -180,3 +195,3 @@ ### Common configuration | ||
| **clickBottomOpen** | `boolean` | true | If bottom position reached, simple click to pane will open pane to the next upper point | | ||
| **dragBy** | `string[]` | ['.cupertino-pane-wrapper .pane'] | Array of selectors for whom elements drag events will be attached. If you want drag only by draggable component set option to ['.pane .draggable'] | | ||
| **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'] | | ||
| **simulateTouch** | `boolean` | true | Simulate touch events for Desktop | | ||
@@ -213,2 +228,3 @@ | **passiveListeners** | `boolean` | true | (Indicates that the function specified by listener will never call preventDefault()) | | ||
| **onBackdropTap** | `void: () => {}` | Call when user tap backdrop overlay | | ||
| **onTransitionStart** | `void: () => {}` | Executes before auto transition and animation start | | ||
| **onTransitionEnd** | `void: () => {}` | Executes when transition and animation complete | | ||
@@ -262,2 +278,8 @@ | ||
``` | ||
### backdrop({show: **boolean = true**}) | ||
Show/Hide backdrop method | ||
```javascript | ||
myPane.backdrop({show: true}); // show | ||
myPane.backdrop({show: false}); // hide | ||
``` | ||
@@ -284,15 +306,16 @@ ## Attributes | ||
## Future Goals | ||
- [Code] Divide elements by classes | ||
- [Quality] Touch angle 45 | ||
- [Quality] Topper than top (allow mode/if scroll - overflow enable else 10px-20px) | ||
- [Quality] Click item/drag pane precision on device (threshold) | ||
- [Quality] Topper than top (if scroll - overflow enable else 10px-20px) | ||
- [Quality] Transition timing: easeOutElastic | ||
- [Quality] Transition timing: easeOutElastic | ||
- [UI] 3D effect (ion-modal example) + release | ||
- [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 | ||
- [Quality] Keyboard manual control | ||
- [Docs] Docs engine (F7) | ||
- [Docs] Live example hosted in pages | ||
- [Platforms] React Native version with one core | ||
- [UI] No taps UI (increase User - Machine information throughput) | ||
- [Platforms] React Native version | ||
- [Platforms] C++ QT version | ||
@@ -299,0 +322,0 @@ ## Contributing |
@@ -16,3 +16,3 @@ import { Support } from './support'; | ||
animationDuration: 300, | ||
dragBy: ['.cupertino-pane-wrapper .pane'], | ||
dragBy: null, | ||
bottomOffset: 0, | ||
@@ -40,2 +40,3 @@ darkMode: false, | ||
onBackdropTap: () => {}, | ||
onTransitionStart: () => {}, | ||
onTransitionEnd: () => {} | ||
@@ -57,3 +58,5 @@ }; | ||
private contentScrollTop: number = 0; | ||
private draggableScrollOffset: number = 0; | ||
private disableDragEvents: boolean = false; | ||
private rendered: boolean = false; | ||
@@ -77,16 +80,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'; | ||
@@ -106,3 +118,3 @@ this.settings = {...this.settings, ...conf}; | ||
this.parentEl = this.settings.parentElement; | ||
// Wrapper | ||
@@ -122,3 +134,7 @@ this.wrapperEl = document.createElement('div'); | ||
this.paneEl.style.width = '100%'; | ||
this.paneEl.style.maxWidth = '480px'; | ||
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`; | ||
@@ -144,2 +160,3 @@ this.paneEl.style.background = '#ffffff'; | ||
this.draggableEl.style.height = '30px'; | ||
this.draggableEl.style.zIndex = '12'; | ||
@@ -161,17 +178,2 @@ // Move | ||
// 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,7 +194,13 @@ this.closeEl = document.createElement('div'); | ||
// 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; | ||
} | ||
@@ -261,2 +269,3 @@ // Emit event | ||
this.draggableEl.appendChild(this.moveEl); | ||
this.rendered = true; | ||
@@ -329,29 +338,41 @@ if (this.settings.followerElement) { | ||
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); | ||
/****** 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.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.attachEvents(el); | ||
}); | ||
if (!this.settings.dragBy) { | ||
this.attachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.attachEvents(el); | ||
}); | ||
} | ||
@@ -367,4 +388,29 @@ /****** Animation & Transition ******/ | ||
/** | ||
* Private Utils methods | ||
*/ | ||
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 checkOpacityAttr(val) { | ||
let attrElements = document.querySelectorAll(`${this.selector} [hide-on-bottom]`); | ||
let attrElements = this.el.querySelectorAll('[hide-on-bottom]'); | ||
if (!attrElements.length) return; | ||
@@ -383,6 +429,15 @@ 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; | ||
} | ||
/** | ||
* Check if drag event fired by scrollable element | ||
*/ | ||
private isDragScrollabe(path):boolean { | ||
return !!path.find(item => item === this.overflowEl); | ||
} | ||
/** | ||
@@ -401,7 +456,11 @@ * Touch Start Event | ||
const screenY = t.type === 'touchstart' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerdown') this.pointerDown = true; | ||
if (t.type === 'mousedown') this.pointerDown = true; | ||
this.startP = screenY; | ||
// if overflow content was scrolled - increase to scrolled value | ||
this.startP += this.contentScrollTop; | ||
// if overflow content was scrolled | ||
// increase to scrolled value | ||
if (this.isDragScrollabe(t.path || t.composedPath())) { | ||
this.startP += this.contentScrollTop; | ||
} | ||
this.steps.push(this.startP); | ||
@@ -424,3 +483,3 @@ } | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if(t.type === 'pointermove' && !this.pointerDown) return; | ||
if(t.type === 'mousemove' && !this.pointerDown) return; | ||
@@ -433,3 +492,4 @@ // Delta | ||
// Not allow move panel with positive overflow scroll | ||
if (this.overflowEl.style.overflowY === 'auto') { | ||
if (this.isDragScrollabe(t.path || t.composedPath()) | ||
&& this.overflowEl.style.overflowY === 'auto') { | ||
this.overflowEl.addEventListener('scroll', (s: any) => { | ||
@@ -443,3 +503,2 @@ this.contentScrollTop = s.target.scrollTop; | ||
} | ||
this.contentScrollTop = 0; | ||
} | ||
@@ -481,3 +540,3 @@ | ||
const screenY = t.type === 'touchmove' ? targetTouch.screenY : t.screenY; | ||
if (t.type === 'pointerup') this.pointerDown = false; | ||
if (t.type === 'mouseup') this.pointerDown = false; | ||
@@ -561,2 +620,62 @@ // Determinate nearest point | ||
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()); | ||
} | ||
/** | ||
* 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); | ||
} | ||
} | ||
@@ -716,6 +835,10 @@ /************************************ | ||
/****** Detach Events *******/ | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.detachEvents(el); | ||
}); | ||
if (!this.settings.dragBy) { | ||
this.detachEvents(this.paneEl); | ||
} else { | ||
this.settings.dragBy.forEach((selector) => { | ||
const el = document.querySelector(selector); | ||
if (el) this.detachEvents(el); | ||
}); | ||
} | ||
@@ -832,6 +955,9 @@ // Reset vars | ||
// main transitions | ||
// Main transitions | ||
if (params.type === 'present') { | ||
this.paneEl.style.transform = `translateY(${this.screen_height}px) translateZ(0px)`; | ||
setTimeout(() => { | ||
// 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)`; | ||
@@ -844,2 +970,5 @@ // Bind for follower same transitions | ||
} else { | ||
// Emit event | ||
this.settings.onTransitionStart({translateY: {new: params.translateY}}); | ||
this.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(0px)`; | ||
@@ -846,0 +975,0 @@ // Bind for follower same transitions |
@@ -25,2 +25,3 @@ import { Support } from './support'; | ||
public pixelRatio: any; | ||
public ionic: boolean = !!document.querySelector('ion-app'); | ||
@@ -27,0 +28,0 @@ constructor() { |
@@ -7,2 +7,6 @@ export interface PaneBreaks { | ||
export interface TransitionStartEvent { | ||
translateY: { new: number}; | ||
} | ||
export interface Settings { | ||
@@ -39,3 +43,4 @@ initialBreak: ('top' | 'middle' | 'bottom'); | ||
onBackdropTap: (event?: CustomEvent) => void, | ||
onTransitionStart: (event?: TransitionStartEvent) => void, | ||
onTransitionEnd: (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
Sorry, the diff of this file is not supported yet
11945223
49
3607
321