@zoff-tech/zt-bottom-drawer
Version:
Bottom Drawer / Web Component
1,549 lines (1,545 loc) • 50.9 kB
JavaScript
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { w as win } from './index3.js';
import { r as raf } from './helpers.js';
import { createGesture } from './index4.js';
import { d as defineCustomElement$2 } from './nav.js';
/*!
* (C) Ionic http://ionicframework.com - MIT License
*/
let animationPrefix;
/**
* Web Animations requires hyphenated CSS properties
* to be written in camelCase when animating
*/
const processKeyframes = (keyframes) => {
keyframes.forEach((keyframe) => {
for (const key in keyframe) {
// eslint-disable-next-line no-prototype-builtins
if (keyframe.hasOwnProperty(key)) {
const value = keyframe[key];
if (key === 'easing') {
const newKey = 'animation-timing-function';
keyframe[newKey] = value;
delete keyframe[key];
}
else {
const newKey = convertCamelCaseToHypen(key);
if (newKey !== key) {
keyframe[newKey] = value;
delete keyframe[key];
}
}
}
}
});
return keyframes;
};
const convertCamelCaseToHypen = (str) => {
return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
};
const getAnimationPrefix = (el) => {
if (animationPrefix === undefined) {
const supportsUnprefixed = el.style.animationName !== undefined;
const supportsWebkitPrefix = el.style.webkitAnimationName !== undefined;
animationPrefix = !supportsUnprefixed && supportsWebkitPrefix ? '-webkit-' : '';
}
return animationPrefix;
};
const setStyleProperty = (element, propertyName, value) => {
const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
element.style.setProperty(prefix + propertyName, value);
};
const removeStyleProperty = (element, propertyName) => {
const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
element.style.removeProperty(prefix + propertyName);
};
const animationEnd = (el, callback) => {
let unRegTrans;
const opts = { passive: true };
const unregister = () => {
if (unRegTrans) {
unRegTrans();
}
};
const onTransitionEnd = (ev) => {
if (el === ev.target) {
unregister();
callback(ev);
}
};
if (el) {
el.addEventListener('webkitAnimationEnd', onTransitionEnd, opts);
el.addEventListener('animationend', onTransitionEnd, opts);
unRegTrans = () => {
el.removeEventListener('webkitAnimationEnd', onTransitionEnd, opts);
el.removeEventListener('animationend', onTransitionEnd, opts);
};
}
return unregister;
};
// TODO(FW-2832): type
const generateKeyframeRules = (keyframes = []) => {
return keyframes
.map((keyframe) => {
const offset = keyframe.offset;
const frameString = [];
for (const property in keyframe) {
// eslint-disable-next-line no-prototype-builtins
if (keyframe.hasOwnProperty(property) && property !== 'offset') {
frameString.push(`${property}: ${keyframe[property]};`);
}
}
return `${offset * 100}% { ${frameString.join(' ')} }`;
})
.join(' ');
};
const keyframeIds = [];
const generateKeyframeName = (keyframeRules) => {
let index = keyframeIds.indexOf(keyframeRules);
if (index < 0) {
index = keyframeIds.push(keyframeRules) - 1;
}
return `ion-animation-${index}`;
};
const getStyleContainer = (element) => {
// getRootNode is not always available in SSR environments.
// TODO(FW-2832): types
const rootNode = element.getRootNode !== undefined ? element.getRootNode() : element;
return rootNode.head || rootNode;
};
const createKeyframeStylesheet = (keyframeName, keyframeRules, element) => {
var _a;
const styleContainer = getStyleContainer(element);
const keyframePrefix = getAnimationPrefix(element);
const existingStylesheet = styleContainer.querySelector('#' + keyframeName);
if (existingStylesheet) {
return existingStylesheet;
}
const stylesheet = ((_a = element.ownerDocument) !== null && _a !== void 0 ? _a : document).createElement('style');
stylesheet.id = keyframeName;
stylesheet.textContent = `@${keyframePrefix}keyframes ${keyframeName} { ${keyframeRules} } @${keyframePrefix}keyframes ${keyframeName}-alt { ${keyframeRules} }`;
styleContainer.appendChild(stylesheet);
return stylesheet;
};
const addClassToArray = (classes = [], className) => {
if (className !== undefined) {
const classNameToAppend = Array.isArray(className) ? className : [className];
return [...classes, ...classNameToAppend];
}
return classes;
};
/*!
* (C) Ionic http://ionicframework.com - MIT License
*/
const createAnimation = (animationId) => {
let _delay;
let _duration;
let _easing;
let _iterations;
let _fill;
let _direction;
let _keyframes = [];
let beforeAddClasses = [];
let beforeRemoveClasses = [];
let initialized = false;
let parentAnimation;
let beforeStylesValue = {};
let afterAddClasses = [];
let afterRemoveClasses = [];
let afterStylesValue = {};
let numAnimationsRunning = 0;
let shouldForceLinearEasing = false;
let shouldForceSyncPlayback = false;
let cssAnimationsTimerFallback;
let forceDirectionValue;
let forceDurationValue;
let forceDelayValue;
let willComplete = true;
let finished = false;
let shouldCalculateNumAnimations = true;
let keyframeName;
let ani;
let paused = false;
const id = animationId;
const onFinishCallbacks = [];
const onFinishOneTimeCallbacks = [];
const elements = [];
const childAnimations = [];
const stylesheets = [];
const _beforeAddReadFunctions = [];
const _beforeAddWriteFunctions = [];
const _afterAddReadFunctions = [];
const _afterAddWriteFunctions = [];
const webAnimations = [];
const supportsAnimationEffect = typeof AnimationEffect === 'function' ||
(win !== undefined && typeof win.AnimationEffect === 'function');
const supportsWebAnimations = typeof Element === 'function' &&
typeof Element.prototype.animate === 'function' &&
supportsAnimationEffect;
const ANIMATION_END_FALLBACK_PADDING_MS = 100;
const getWebAnimations = () => {
return webAnimations;
};
const destroy = (clearStyleSheets) => {
childAnimations.forEach((childAnimation) => {
childAnimation.destroy(clearStyleSheets);
});
cleanUp(clearStyleSheets);
elements.length = 0;
childAnimations.length = 0;
_keyframes.length = 0;
clearOnFinish();
initialized = false;
shouldCalculateNumAnimations = true;
return ani;
};
/**
* Cancels any Web Animations, removes
* any animation properties from the
* animation's elements, and removes the
* animation's stylesheets from the DOM.
*/
const cleanUp = (clearStyleSheets) => {
cleanUpElements();
if (clearStyleSheets) {
cleanUpStyleSheets();
}
};
const resetFlags = () => {
shouldForceLinearEasing = false;
shouldForceSyncPlayback = false;
shouldCalculateNumAnimations = true;
forceDirectionValue = undefined;
forceDurationValue = undefined;
forceDelayValue = undefined;
numAnimationsRunning = 0;
finished = false;
willComplete = true;
paused = false;
};
const isRunning = () => {
return numAnimationsRunning !== 0 && !paused;
};
const onFinish = (callback, opts) => {
const callbacks = (opts === null || opts === void 0 ? void 0 : opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
callbacks.push({ c: callback, o: opts });
return ani;
};
const clearOnFinish = () => {
onFinishCallbacks.length = 0;
onFinishOneTimeCallbacks.length = 0;
return ani;
};
/**
* Cancels any Web Animations and removes
* any animation properties from the
* the animation's elements.
*/
const cleanUpElements = () => {
if (supportsWebAnimations) {
webAnimations.forEach((animation) => {
animation.cancel();
});
webAnimations.length = 0;
}
else {
const elementsArray = elements.slice();
raf(() => {
elementsArray.forEach((element) => {
removeStyleProperty(element, 'animation-name');
removeStyleProperty(element, 'animation-duration');
removeStyleProperty(element, 'animation-timing-function');
removeStyleProperty(element, 'animation-iteration-count');
removeStyleProperty(element, 'animation-delay');
removeStyleProperty(element, 'animation-play-state');
removeStyleProperty(element, 'animation-fill-mode');
removeStyleProperty(element, 'animation-direction');
});
});
}
};
/**
* Removes the animation's stylesheets
* from the DOM.
*/
const cleanUpStyleSheets = () => {
stylesheets.forEach((stylesheet) => {
/**
* When sharing stylesheets, it's possible
* for another animation to have already
* cleaned up a particular stylesheet
*/
if (stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.parentNode) {
stylesheet.parentNode.removeChild(stylesheet);
}
});
stylesheets.length = 0;
};
const beforeAddRead = (readFn) => {
_beforeAddReadFunctions.push(readFn);
return ani;
};
const beforeAddWrite = (writeFn) => {
_beforeAddWriteFunctions.push(writeFn);
return ani;
};
const afterAddRead = (readFn) => {
_afterAddReadFunctions.push(readFn);
return ani;
};
const afterAddWrite = (writeFn) => {
_afterAddWriteFunctions.push(writeFn);
return ani;
};
const beforeAddClass = (className) => {
beforeAddClasses = addClassToArray(beforeAddClasses, className);
return ani;
};
const beforeRemoveClass = (className) => {
beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
return ani;
};
/**
* Set CSS inline styles to the animation's
* elements before the animation begins.
*/
const beforeStyles = (styles = {}) => {
beforeStylesValue = styles;
return ani;
};
/**
* Clear CSS inline styles from the animation's
* elements before the animation begins.
*/
const beforeClearStyles = (propertyNames = []) => {
for (const property of propertyNames) {
beforeStylesValue[property] = '';
}
return ani;
};
const afterAddClass = (className) => {
afterAddClasses = addClassToArray(afterAddClasses, className);
return ani;
};
const afterRemoveClass = (className) => {
afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
return ani;
};
const afterStyles = (styles = {}) => {
afterStylesValue = styles;
return ani;
};
const afterClearStyles = (propertyNames = []) => {
for (const property of propertyNames) {
afterStylesValue[property] = '';
}
return ani;
};
const getFill = () => {
if (_fill !== undefined) {
return _fill;
}
if (parentAnimation) {
return parentAnimation.getFill();
}
return 'both';
};
const getDirection = () => {
if (forceDirectionValue !== undefined) {
return forceDirectionValue;
}
if (_direction !== undefined) {
return _direction;
}
if (parentAnimation) {
return parentAnimation.getDirection();
}
return 'normal';
};
const getEasing = () => {
if (shouldForceLinearEasing) {
return 'linear';
}
if (_easing !== undefined) {
return _easing;
}
if (parentAnimation) {
return parentAnimation.getEasing();
}
return 'linear';
};
const getDuration = () => {
if (shouldForceSyncPlayback) {
return 0;
}
if (forceDurationValue !== undefined) {
return forceDurationValue;
}
if (_duration !== undefined) {
return _duration;
}
if (parentAnimation) {
return parentAnimation.getDuration();
}
return 0;
};
const getIterations = () => {
if (_iterations !== undefined) {
return _iterations;
}
if (parentAnimation) {
return parentAnimation.getIterations();
}
return 1;
};
const getDelay = () => {
if (forceDelayValue !== undefined) {
return forceDelayValue;
}
if (_delay !== undefined) {
return _delay;
}
if (parentAnimation) {
return parentAnimation.getDelay();
}
return 0;
};
const getKeyframes = () => {
return _keyframes;
};
const direction = (animationDirection) => {
_direction = animationDirection;
update(true);
return ani;
};
const fill = (animationFill) => {
_fill = animationFill;
update(true);
return ani;
};
const delay = (animationDelay) => {
_delay = animationDelay;
update(true);
return ani;
};
const easing = (animationEasing) => {
_easing = animationEasing;
update(true);
return ani;
};
const duration = (animationDuration) => {
/**
* CSS Animation Durations of 0ms work fine on Chrome
* but do not run on Safari, so force it to 1ms to
* get it to run on both platforms.
*/
if (!supportsWebAnimations && animationDuration === 0) {
animationDuration = 1;
}
_duration = animationDuration;
update(true);
return ani;
};
const iterations = (animationIterations) => {
_iterations = animationIterations;
update(true);
return ani;
};
const parent = (animation) => {
parentAnimation = animation;
return ani;
};
const addElement = (el) => {
if (el != null) {
if (el.nodeType === 1) {
elements.push(el);
}
else if (el.length >= 0) {
for (let i = 0; i < el.length; i++) {
elements.push(el[i]);
}
}
else {
console.error('Invalid addElement value');
}
}
return ani;
};
const addAnimation = (animationToAdd) => {
if (animationToAdd != null) {
if (Array.isArray(animationToAdd)) {
for (const animation of animationToAdd) {
animation.parent(ani);
childAnimations.push(animation);
}
}
else {
animationToAdd.parent(ani);
childAnimations.push(animationToAdd);
}
}
return ani;
};
const keyframes = (keyframeValues) => {
const different = _keyframes !== keyframeValues;
_keyframes = keyframeValues;
if (different) {
updateKeyframes(_keyframes);
}
return ani;
};
const updateKeyframes = (keyframeValues) => {
if (supportsWebAnimations) {
getWebAnimations().forEach((animation) => {
if (animation.effect.setKeyframes) {
animation.effect.setKeyframes(keyframeValues);
}
else {
const newEffect = new KeyframeEffect(animation.effect.target, keyframeValues, animation.effect.getTiming());
animation.effect = newEffect;
}
});
}
else {
initializeCSSAnimation();
}
};
/**
* Run all "before" animation hooks.
*/
const beforeAnimation = () => {
// Runs all before read callbacks
_beforeAddReadFunctions.forEach((callback) => callback());
// Runs all before write callbacks
_beforeAddWriteFunctions.forEach((callback) => callback());
// Updates styles and classes before animation runs
const addClasses = beforeAddClasses;
const removeClasses = beforeRemoveClasses;
const styles = beforeStylesValue;
elements.forEach((el) => {
const elementClassList = el.classList;
addClasses.forEach((c) => elementClassList.add(c));
removeClasses.forEach((c) => elementClassList.remove(c));
for (const property in styles) {
// eslint-disable-next-line no-prototype-builtins
if (styles.hasOwnProperty(property)) {
setStyleProperty(el, property, styles[property]);
}
}
});
};
/**
* Run all "after" animation hooks.
*/
const afterAnimation = () => {
clearCSSAnimationsTimeout();
// Runs all after read callbacks
_afterAddReadFunctions.forEach((callback) => callback());
// Runs all after write callbacks
_afterAddWriteFunctions.forEach((callback) => callback());
// Updates styles and classes before animation ends
const currentStep = willComplete ? 1 : 0;
const addClasses = afterAddClasses;
const removeClasses = afterRemoveClasses;
const styles = afterStylesValue;
elements.forEach((el) => {
const elementClassList = el.classList;
addClasses.forEach((c) => elementClassList.add(c));
removeClasses.forEach((c) => elementClassList.remove(c));
for (const property in styles) {
// eslint-disable-next-line no-prototype-builtins
if (styles.hasOwnProperty(property)) {
setStyleProperty(el, property, styles[property]);
}
}
});
onFinishCallbacks.forEach((onFinishCallback) => {
return onFinishCallback.c(currentStep, ani);
});
onFinishOneTimeCallbacks.forEach((onFinishCallback) => {
return onFinishCallback.c(currentStep, ani);
});
onFinishOneTimeCallbacks.length = 0;
shouldCalculateNumAnimations = true;
if (willComplete) {
finished = true;
}
willComplete = true;
};
const animationFinish = () => {
if (numAnimationsRunning === 0) {
return;
}
numAnimationsRunning--;
if (numAnimationsRunning === 0) {
afterAnimation();
if (parentAnimation) {
parentAnimation.animationFinish();
}
}
};
const initializeCSSAnimation = (toggleAnimationName = true) => {
cleanUpStyleSheets();
const processedKeyframes = processKeyframes(_keyframes);
elements.forEach((element) => {
if (processedKeyframes.length > 0) {
const keyframeRules = generateKeyframeRules(processedKeyframes);
keyframeName = animationId !== undefined ? animationId : generateKeyframeName(keyframeRules);
const stylesheet = createKeyframeStylesheet(keyframeName, keyframeRules, element);
stylesheets.push(stylesheet);
setStyleProperty(element, 'animation-duration', `${getDuration()}ms`);
setStyleProperty(element, 'animation-timing-function', getEasing());
setStyleProperty(element, 'animation-delay', `${getDelay()}ms`);
setStyleProperty(element, 'animation-fill-mode', getFill());
setStyleProperty(element, 'animation-direction', getDirection());
const iterationsCount = getIterations() === Infinity ? 'infinite' : getIterations().toString();
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
setStyleProperty(element, 'animation-play-state', 'paused');
if (toggleAnimationName) {
setStyleProperty(element, 'animation-name', `${stylesheet.id}-alt`);
}
raf(() => {
setStyleProperty(element, 'animation-name', stylesheet.id || null);
});
}
});
};
const initializeWebAnimation = () => {
elements.forEach((element) => {
const animation = element.animate(_keyframes, {
id,
delay: getDelay(),
duration: getDuration(),
easing: getEasing(),
iterations: getIterations(),
fill: getFill(),
direction: getDirection(),
});
animation.pause();
webAnimations.push(animation);
});
if (webAnimations.length > 0) {
webAnimations[0].onfinish = () => {
animationFinish();
};
}
};
const initializeAnimation = (toggleAnimationName = true) => {
beforeAnimation();
if (_keyframes.length > 0) {
if (supportsWebAnimations) {
initializeWebAnimation();
}
else {
initializeCSSAnimation(toggleAnimationName);
}
}
initialized = true;
};
const setAnimationStep = (step) => {
step = Math.min(Math.max(step, 0), 0.9999);
if (supportsWebAnimations) {
webAnimations.forEach((animation) => {
animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
animation.pause();
});
}
else {
const animationDuration = `-${getDuration() * step}ms`;
elements.forEach((element) => {
if (_keyframes.length > 0) {
setStyleProperty(element, 'animation-delay', animationDuration);
setStyleProperty(element, 'animation-play-state', 'paused');
}
});
}
};
const updateWebAnimation = (step) => {
webAnimations.forEach((animation) => {
animation.effect.updateTiming({
delay: getDelay(),
duration: getDuration(),
easing: getEasing(),
iterations: getIterations(),
fill: getFill(),
direction: getDirection(),
});
});
if (step !== undefined) {
setAnimationStep(step);
}
};
const updateCSSAnimation = (toggleAnimationName = true, step) => {
raf(() => {
elements.forEach((element) => {
setStyleProperty(element, 'animation-name', keyframeName || null);
setStyleProperty(element, 'animation-duration', `${getDuration()}ms`);
setStyleProperty(element, 'animation-timing-function', getEasing());
setStyleProperty(element, 'animation-delay', step !== undefined ? `-${step * getDuration()}ms` : `${getDelay()}ms`);
setStyleProperty(element, 'animation-fill-mode', getFill() || null);
setStyleProperty(element, 'animation-direction', getDirection() || null);
const iterationsCount = getIterations() === Infinity ? 'infinite' : getIterations().toString();
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
if (toggleAnimationName) {
setStyleProperty(element, 'animation-name', `${keyframeName}-alt`);
}
raf(() => {
setStyleProperty(element, 'animation-name', keyframeName || null);
});
});
});
};
const update = (deep = false, toggleAnimationName = true, step) => {
if (deep) {
childAnimations.forEach((animation) => {
animation.update(deep, toggleAnimationName, step);
});
}
if (supportsWebAnimations) {
updateWebAnimation(step);
}
else {
updateCSSAnimation(toggleAnimationName, step);
}
return ani;
};
const progressStart = (forceLinearEasing = false, step) => {
childAnimations.forEach((animation) => {
animation.progressStart(forceLinearEasing, step);
});
pauseAnimation();
shouldForceLinearEasing = forceLinearEasing;
if (!initialized) {
initializeAnimation();
}
update(false, true, step);
return ani;
};
const progressStep = (step) => {
childAnimations.forEach((animation) => {
animation.progressStep(step);
});
setAnimationStep(step);
return ani;
};
const progressEnd = (playTo, step, dur) => {
shouldForceLinearEasing = false;
childAnimations.forEach((animation) => {
animation.progressEnd(playTo, step, dur);
});
if (dur !== undefined) {
forceDurationValue = dur;
}
finished = false;
willComplete = true;
if (playTo === 0) {
forceDirectionValue = getDirection() === 'reverse' ? 'normal' : 'reverse';
if (forceDirectionValue === 'reverse') {
willComplete = false;
}
if (supportsWebAnimations) {
update();
setAnimationStep(1 - step);
}
else {
forceDelayValue = (1 - step) * getDuration() * -1;
update(false, false);
}
}
else if (playTo === 1) {
if (supportsWebAnimations) {
update();
setAnimationStep(step);
}
else {
forceDelayValue = step * getDuration() * -1;
update(false, false);
}
}
if (playTo !== undefined) {
onFinish(() => {
forceDurationValue = undefined;
forceDirectionValue = undefined;
forceDelayValue = undefined;
}, {
oneTimeCallback: true,
});
if (!parentAnimation) {
play();
}
}
return ani;
};
const pauseAnimation = () => {
if (initialized) {
if (supportsWebAnimations) {
webAnimations.forEach((animation) => {
animation.pause();
});
}
else {
elements.forEach((element) => {
setStyleProperty(element, 'animation-play-state', 'paused');
});
}
paused = true;
}
};
const pause = () => {
childAnimations.forEach((animation) => {
animation.pause();
});
pauseAnimation();
return ani;
};
const onAnimationEndFallback = () => {
cssAnimationsTimerFallback = undefined;
animationFinish();
};
const clearCSSAnimationsTimeout = () => {
if (cssAnimationsTimerFallback) {
clearTimeout(cssAnimationsTimerFallback);
}
};
const playCSSAnimations = () => {
clearCSSAnimationsTimeout();
raf(() => {
elements.forEach((element) => {
if (_keyframes.length > 0) {
setStyleProperty(element, 'animation-play-state', 'running');
}
});
});
if (_keyframes.length === 0 || elements.length === 0) {
animationFinish();
}
else {
/**
* This is a catchall in the event that a CSS Animation did not finish.
* The Web Animations API has mechanisms in place for preventing this.
* CSS Animations will not fire an `animationend` event
* for elements with `display: none`. The Web Animations API
* accounts for this, but using raw CSS Animations requires
* this workaround.
*/
const animationDelay = getDelay() || 0;
const animationDuration = getDuration() || 0;
const animationIterations = getIterations() || 1;
// No need to set a timeout when animation has infinite iterations
if (isFinite(animationIterations)) {
cssAnimationsTimerFallback = setTimeout(onAnimationEndFallback, animationDelay + animationDuration * animationIterations + ANIMATION_END_FALLBACK_PADDING_MS);
}
animationEnd(elements[0], () => {
clearCSSAnimationsTimeout();
/**
* Ensure that clean up
* is always done a frame
* before the onFinish handlers
* are fired. Otherwise, there
* may be flickering if a new
* animation is started on the same
* element too quickly
*/
raf(() => {
clearCSSAnimationPlayState();
raf(animationFinish);
});
});
}
};
const clearCSSAnimationPlayState = () => {
elements.forEach((element) => {
removeStyleProperty(element, 'animation-duration');
removeStyleProperty(element, 'animation-delay');
removeStyleProperty(element, 'animation-play-state');
});
};
const playWebAnimations = () => {
webAnimations.forEach((animation) => {
animation.play();
});
if (_keyframes.length === 0 || elements.length === 0) {
animationFinish();
}
};
const resetAnimation = () => {
if (supportsWebAnimations) {
setAnimationStep(0);
updateWebAnimation();
}
else {
updateCSSAnimation();
}
};
const play = (opts) => {
return new Promise((resolve) => {
if (opts === null || opts === void 0 ? void 0 : opts.sync) {
shouldForceSyncPlayback = true;
onFinish(() => (shouldForceSyncPlayback = false), { oneTimeCallback: true });
}
if (!initialized) {
initializeAnimation();
}
if (finished) {
resetAnimation();
finished = false;
}
if (shouldCalculateNumAnimations) {
numAnimationsRunning = childAnimations.length + 1;
shouldCalculateNumAnimations = false;
}
onFinish(() => resolve(), { oneTimeCallback: true });
childAnimations.forEach((animation) => {
animation.play();
});
if (supportsWebAnimations) {
playWebAnimations();
}
else {
playCSSAnimations();
}
paused = false;
});
};
const stop = () => {
childAnimations.forEach((animation) => {
animation.stop();
});
if (initialized) {
cleanUpElements();
initialized = false;
}
resetFlags();
};
const from = (property, value) => {
const firstFrame = _keyframes[0];
if (firstFrame !== undefined && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
firstFrame[property] = value;
}
else {
_keyframes = [{ offset: 0, [property]: value }, ..._keyframes];
}
return ani;
};
const to = (property, value) => {
const lastFrame = _keyframes[_keyframes.length - 1];
if (lastFrame !== undefined && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
lastFrame[property] = value;
}
else {
_keyframes = [..._keyframes, { offset: 1, [property]: value }];
}
return ani;
};
const fromTo = (property, fromValue, toValue) => {
return from(property, fromValue).to(property, toValue);
};
return (ani = {
parentAnimation,
elements,
childAnimations,
id,
animationFinish,
from,
to,
fromTo,
parent,
play,
pause,
stop,
destroy,
keyframes,
addAnimation,
addElement,
update,
fill,
direction,
iterations,
duration,
easing,
delay,
getWebAnimations,
getKeyframes,
getFill,
getDirection,
getDelay,
getIterations,
getEasing,
getDuration,
afterAddRead,
afterAddWrite,
afterClearStyles,
afterStyles,
afterRemoveClass,
afterAddClass,
beforeAddRead,
beforeAddWrite,
beforeClearStyles,
beforeStyles,
beforeRemoveClass,
beforeAddClass,
onFinish,
isRunning,
progressStart,
progressStep,
progressEnd,
});
};
const ztBottomDrawerCss = "zt-bottom-drawer{--zt-sat:env(safe-area-inset-top);--zt-sar:env(safe-area-inset-right);--zt-sab:env(safe-area-inset-bottom);--zt-sal:env(safe-area-inset-left);position:absolute;width:100%;height:100%}zt-bottom-drawer ion-nav ion-header ion-toolbar:first-of-type{padding-top:0px}";
const ZTBottomDrawer = /*@__PURE__*/ proxyCustomElement(class ZTBottomDrawer extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.ztChangePositionEvent = createEvent(this, "ztChangePositionEvent", 7);
this.ztHideEvent = createEvent(this, "ztHideEvent", 7);
this.ztNavDidChange = createEvent(this, "ztNavDidChange", 7);
this.ztNavWillChange = createEvent(this, "ztNavWillChange", 7);
this.navegando = false;
this.deltaChangeSate = 5;
this.enTouchMove = false;
this.cancelMove = false;
this.windowh = -1;
this.ultimoValuePosY = 0;
this.positionName = undefined;
this.hideOnPositionZero = false;
this.fixCurrentPosition = false;
this.disableGesture = false;
this.allowScroll = true;
this.positions = "close-b-10,bottom-b-200,middle-b-450,top-t-60";
this.hidden = false;
this.coefAnimationTime = 40;
this.safeAreaTop = undefined;
this.safeAreaBottom = undefined;
}
setDisableGesture(value) {
if (!value && !this.gesture && this._htmlElements.gestureTarget) {
this.gesture = createGesture({
el: this._htmlElements.gestureTarget,
threshold: 0,
gestureName: 'drawer-drag',
disableScroll: true,
passive: true,
direction: "y",
onStart: ev => this.onStart(ev),
onMove: (ev) => { this.onMove(ev); },
onEnd: (ev) => { this.onEnd(ev); }
});
}
if (this.gesture)
this.gesture.enable(!value);
}
setAllowScroll(value) {
if (this.ionContent) {
this.ionContent.scrollY = value;
this.ionContent.scrollEvents = value;
}
}
async getNav() {
return this.nav;
}
async goBack(amountBack, opts, done) {
if (amountBack) {
amountBack = amountBack - 1;
const cantidadHijos = this.el.firstChild.childNodes.length;
if (amountBack < cantidadHijos) {
await this.nav.removeIndex(cantidadHijos - amountBack - 1, amountBack);
}
else {
return await this.nav.popToRoot();
}
}
return this.nav.pop(opts, done);
}
async goBackToRoot(opts, done) {
return this.nav.popToRoot(opts, done);
}
async goBackToIndex(index, opts, done) {
return this.nav.popTo(index, opts, done);
}
async getNavActive() {
return this.nav.getActive();
}
async getNavCurrentComponent() {
return this.currentComponent;
}
isElement(o) {
return (typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string");
}
async saveStateInActiveComponent() {
let contentActive = await this.nav.getActive();
contentActive.component.__zt_navDrawer.options.allowScroll = this.allowScroll;
contentActive.component.__zt_navDrawer.options.disableGesture = this.disableGesture;
contentActive.component.__zt_navDrawer.options.positionName = this.positionName;
contentActive.component.__zt_navDrawer.options.positions = this.positions;
contentActive.component.__zt_navDrawer.options.fixCurrentPosition = this.fixCurrentPosition;
}
async pushNav(component, propsComponent, options) {
if (this.navegando)
throw new Error("The Bottom Drawer is navigating, wait after call again. Please use the promise.");
if (!options) {
options = {};
}
if (!options.positions && !this.positions)
throw new Error("The position by default or in the options are required.");
this.navegando = true;
await new Promise(async (resolve, reject) => {
if (options && !options.selectorContent) {
options.selectorContent = "ion-content";
}
if (typeof (component) == "string")
component = document.createElement(component);
if (this.isElement(component)) {
component.__zt_navDrawer = {
resolve: resolve,
reject: reject,
options: options
};
console.log(options);
this.nav.push(component, propsComponent);
}
});
this.navegando = false;
this.setHeightContainer("CONTENT");
return true;
}
async getActiveComponentTagName() {
return this._tagNameComponetActive;
}
async getCurrentIndex() {
return this.el.firstChild.childNodes.length;
}
async navDidChange() {
let contentActive = await this.nav.getActive();
this._tagNameComponetActive = contentActive.component.tagName;
const opts = contentActive.component.__zt_navDrawer.options;
if (opts.allowScroll != undefined)
this.allowScroll = opts.allowScroll;
if (opts.disableGesture != undefined)
this.disableGesture = opts.disableGesture;
await Promise.all([this.initActiveContentNav(contentActive), new Promise(async (resolve) => {
if (opts.positions) {
this.setPositions(opts.positions);
}
if (opts.positionName) {
await this.setPositionByName(opts.positionName, true);
}
if (opts.fixCurrentPosition != undefined)
this.fixCurrentPosition = opts.fixCurrentPosition;
resolve();
})]);
contentActive.component.__zt_navDrawer.resolve(true);
this.ztNavDidChange.emit(contentActive);
}
async initActiveContentNav(contentActive) {
if (contentActive) {
const opts = contentActive.component.__zt_navDrawer.options;
this.currentComponent = contentActive.element;
this._htmlElements.content = this.currentComponent.querySelector(opts.selectorContent);
if (!this._htmlElements.content)
throw new Error(`Bottom Drawer - Error - The selector ${opts.selectorContent} not found any element`);
let gestureTarget = contentActive.element;
if (opts.selectorGesture)
gestureTarget = contentActive.element.querySelector(opts.selectorGesture);
this.addGesture(gestureTarget);
if (this._htmlElements &&
this._htmlElements.content &&
this._htmlElements.content.nodeName == "ION-CONTENT") {
this.ionContent = this._htmlElements.content;
this.ionContent.scrollY = this.allowScroll;
this.ionContent.scrollEvents = this.allowScroll;
}
else {
this.ionContent = this._htmlElements.content;
}
}
}
async componentDidLoad() {
var _a, _b;
this._htmlElements = { drawer: null, gestureTarget: null, content: null };
this._htmlElements.drawer = this.el;
this.safeAreaTop = Number(((_a = getComputedStyle(this.el).getPropertyValue("--zt-sat")) !== null && _a !== void 0 ? _a : "0").replace("px", ""));
this.safeAreaBottom = Number(((_b = getComputedStyle(this.el).getPropertyValue("--zt-sab")) !== null && _b !== void 0 ? _b : "0").replace("px", ""));
this.el.style.setProperty("height", (this.getWHWindow().height) + "px");
this.setPositions(this.positions);
this.setAnimation();
}
addGesture(target) {
if (this.gesture) {
this.gesture.destroy();
}
this.gesture = createGesture({
el: target,
threshold: 0,
gestureName: 'drawer-drag',
disableScroll: true,
passive: false,
direction: "y",
onStart: ev => { this.onStart(ev); },
onMove: (ev) => { this.onMove(ev); },
onEnd: (ev) => { this.onEnd(ev); }
});
if (this.gesture)
this.gesture.enable(!this.disableGesture);
}
setPositions(newPositions) {
let positions = [];
let index = 1;
let splitPositions = newPositions.toLowerCase().split(",");
let dimensionesWin = this.getWHWindow();
let previous;
splitPositions.forEach(positionCadena => {
var _a, _b;
let splitPosition = positionCadena.split("-");
if (splitPosition.length === 3) {
try {
let position = {
index: index, name: splitPosition[0],
distanceTo: (splitPosition[1].toLowerCase() === "t" ? "TOP" : "BOTTOM"),
distance: Number.parseInt(splitPosition[2]),
distanceToTop: 0,
previousPosition: null,
nextPosition: null
};
if (position.distanceTo === "TOP") {
position.distanceToTop = position.distance + ((_a = this.safeAreaTop) !== null && _a !== void 0 ? _a : 0);
}
else {
position.distanceToTop = dimensionesWin.height - ((_b = this.safeAreaBottom) !== null && _b !== void 0 ? _b : 0) - position.distance;
}
if (previous) {
position.previousPosition = previous;
previous.nextPosition = position;
}
previous = position;
index = index + 1;
positions.push(position);
}
catch (err) {
throw Error("ZTBottomDrawer - Positions is invalid : " + positionCadena + " must be name:string-[t|b]:string-distance:number ");
}
}
});
positions.forEach((position) => {
if (!position.nextPosition) {
this.maxTop = position.distanceToTop;
}
});
this._positions = positions;
}
async setAnimation() {
this.animation = createAnimation()
.addElement(this.el);
this.animation
.duration(1000)
.fromTo('transform', `translateY(${this.getWHWindow().height}px)`, `translateY(0px)`);
this.animation.progressStart(true, .1);
if (this._position) {
this.animation.progressStep(1 - this._position.distanceToTop / this.getWHWindow().height);
}
}
async getCurrrentPositionDto() {
return Object.assign({}, this._position);
}
async getPositionByName(name) {
return this._positions.find((value) => { return value.name == name; });
}
async getPositionByIndex(index) {
let positionFind = this._positions.find((value) => { return value.index == index; });
return positionFind;
}
async hide() {
this.gesture.enable(false);
this.hidden = true;
let hidePos = this.getWHWindow().height + 10;
await this.setTranslateY(hidePos, true);
this.el.style.setProperty("display", "none");
}
async show(positionName) {
if (!positionName) {
return;
}
this.el.style.setProperty("display", "inline");
let positionToShow = await this.getPositionByName(positionName);
if (!positionToShow) {
return;
}
await this.setPosition(positionToShow);
this.hidden = false;
}
getPositionByPosY(posY, direccion) {
let result = { newPosition: null, close: false };
result.newPosition = this._positions.find((position) => {
if (direccion === "UP") {
if (position.previousPosition && posY < position.previousPosition.distanceToTop + this.deltaChangeSate && (!position.nextPosition || (position.nextPosition && posY > position.distanceToTop - this.deltaChangeSate)))
return position;
if (!position.previousPosition && posY > position.distanceToTop - this.deltaChangeSate)
return position;
}
if (direccion === "DOWN") {
if (position.nextPosition && posY > position.nextPosition.distanceToTop + this.deltaChangeSate && (!position.previousPosition || (position.previousPosition && posY < position.distanceToTop + this.deltaChangeSate)))
return position;
if (!position.nextPosition && posY < position.distanceToTop + this.deltaChangeSate)
return position;
}
});
if (posY > this.getWHWindow().height) {
result.close = true;
return result;
}
return result;
}
onStart(ev) {
if (this.fixCurrentPosition) {
this.cancelMove = true;
return;
}
if (ev.event.path) {
let elementos = ev.event.path;
let eleContent = elementos.find((el) => {
return el === this._htmlElements.content;
});
if (eleContent) {
this.cancelMove = true;
return;
}
}
this.cancelMove = false;
if (this.ionContent) {
this.ionContent.scrollToTop(0);
if (this.allowScroll) {
this.ionContent.scrollY = false;
this.ionContent.scrollEvents = false;
}
}
this.setHeightContainer("MAX");
this.startPosTopMove = this._htmlElements.drawer.getBoundingClientRect().top;
this.lastPositionY = this.startPosTopMove;
}
async onMove(ev) {
if (this.cancelMove)
return;
if (this.moveFastAnimationProgress)
await this.moveFastAnimationProgress;
this.lastCalc = this.startPosTopMove + ev.deltaY;
if (this.lastCalc < this.maxTop)
this.lastCalc = this.maxTop;
this.previusPositionY = this.lastPositionY;
this.lastPositionY = ev.currentY;
this.setTranslateY(this.lastCalc);
}
async onEnd(ev) {
if (this.cancelMove)
return;
this.moveFast = false;
this.gesture.enable(false);
if (this.ionContent && this.allowScroll) {
this.ionContent.scrollY = true;
this.ionContent.scrollEvents = true;
}
this.changeStateByGesture(ev);
this.startPosTopMove = 0;
this.setDisableGesture(this.disableGesture);
return true;
}
getDirectionGesture() {
let deltaY = this.lastPositionY - this.previusPositionY;
if (deltaY / Math.abs(deltaY) * -1 > 0)
return "UP";
else
return "DOWN";
}
async changeStateByGesture(ev) {
if (Math.abs(ev.deltaY) == 0) {
let posY = this._position.distanceToTop;
await this.setTranslateY(posY);
this.setHeightContainer("CONTENT");
return;
}
if (this.gesture)
this.gesture.enable(false);
let calculatePosition = this._position;
let calc = this.startPosTopMove + ev.deltaY;
let result = this.getPositionByPosY(calc, this.getDirectionGesture());
if (result.close) {
if (this.hideOnPositionZero) {
this.ztHideEvent.emit();
return this.hide();
}
}
if (result.newPosition) {
calculatePosition = result.newPosition;
}
if (calculatePosition != this._position) {
await this.setPosition(calculatePosition);
return;
}
await this.setTranslateY(this._position.distanceToTop, true);
this.setDisableGesture(this.disableGesture);
this.setHeightContainer("CONTENT");
}
getWHWindow(ignoreCache = false) {
let result = this.windowh;
if (ignoreCache) {
result = window._zt_wh || window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
if (result === -1) {
result = this.windowh = window._zt_wh || window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
return {
height: result,
width: window._zt_wh || window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth
};
}
async setPositionByName(name, force = false) {
if (this.fixCurrentPosition && !force)
throw new Error("The CurentPosition of the bottom drawer is fixed");
let newPosition = await this.getPositionByName(name);
if (newPosition && (force || (!this._position ||
(this._position && this._position.name !== newPosition.name)))) {
return await this.setPosition(newPosition, force);
}
}
async setPosition(value, force = false) {
if (!value)
return;
if (this.fixCurrentPosition && !force)
throw new Error("The CurentPosition of the bottom drawer is fixed");
if (this.gesture)
this.gesture.enable(false);
const lastPosition = this._position ? this._position.name : undefined;
if (!this._position || force || (this._position && value.name !== this._position.name)) {
this._position = value;
this.positionName = this._position.name;
this.ztChangePositionEvent.emit({ positionName: this.positionName, lastPositionName: lastPosition, htmlElements: this._htmlElements });
}
if (!value.distanceToTop) {
let dimensionesWin = this.getWHWindow();
if (value.distanceTo === "TOP") {
value.distanceToTop = value.distance;
}
else {
value.distanceToTop = dimensionesWin.height - value.distance;
}
}
this.setHeightContainer("MAX");
if (this.ionContent) {
this.ionContent.scrollToTop(0);
}
await this.setTranslateY(value.distanceToTop, true);
this.setHeightContainer("CONTENT");
this.setDisableGesture(this.disableGesture);
}
getDuration(delta) {
let duration = (delta / 1000) * this.coefAnimationTime;
return duration;
}
async animateRolo(initialY, finalY) {
if (this.animateRoloPromise)
return this.animateRoloPromise;
const delta = Math.abs(initialY - finalY);
const paso = delta / this.getDuration(delta);
const signo = initialY > finalY ? -1 : 1;
this.posyAnimate = initialY;
this.animateRoloPromise = new Promise((resolve) => {
this.intervalAnimation = setInterval(() => {
this.posyAnimate = this.posyAnimate + paso * signo;
this.animation.progressStep(1 - this.posyAnimate / this.getWHWindow().height);
if ((signo > 0 && this.posyAnimate > finalY) || (signo < 0 && this.posyAnimate < finalY)) {
this.animation.progressStep(1 - finalY / this.getWHWindow().height);
clearInterval(this.intervalAnimation);
resolve();
}
}, this.getDuration(delta));
});
await this.animateRoloPromise;
this.animateRoloPromise = undefined;
}
async setTranslateY(posY, applyAnimation = false) {
return new Promise(async (resolve) => {
if (this.ultimoValuePosY === posY) {
return resolve();
}
if (!this.ultimoValuePosY) {
this.animation.progressStep(1 - posY / this.getWHWindow().height);
}
else {
if (applyAnimation)
await this.animateRolo(this.ultimoValuePosY, posY);
else {
this.animation.progressStep(1 - posY / this.getWHWindow().height);
}
}
this.ultimoValuePosY = posY;
resolve();
});
}
setHeightContainer(heightOf, ignorarCacheWindowHeight = false) {
const h = this.getWHWindow(ignorarCacheWindowHeight).height;
let value = h;
if (heightOf === "MAX") {
value = value - this.maxTop;
}
else {
if (!this.ionContent || this.navegando)
return;
const brContent = this.ionContent.getBoundingClientRect();
const topcontent = brContent.top;
const topParent = this.el.getBoundingClientRect().top;
if (h > topcontent) {
value = value - topParent;
}
}
this.nav.style.setProperty("height", (value - this.safeAreaBottom) + "px");
}
async refreshSizeContent() {
return this.setHeightContainer("CONTENT", true);
}
async setScrollToTop(duration = 200) {
if (this.ionContent) {
return this.ionContent.scrollToTop(duration);
}
}
render() {
return (h(Host, null, h("ion-nav", { onIonNavWillChange: () => { this.navWillchange(); }, onIonNavDidChange: () => { this.navDidChange(); }, ref: elNsv => this.nav = elNsv })));
}
navWillchange() {
this.ztNavWillChange.emit();
}
get el() { return this; }
static get watchers() { return {
"disableGesture": ["setDisableGesture"],
"allowScroll": ["setAllowScroll"],
"positions": ["setPositions"]
}; }
static get style() { return ztBottomDrawerCss; }
}, [0, "zt-bottom-drawer", {
"positionName": [1537, "position-name"],
"hideOnPositionZero": [1540, "hide-on-position-zero"],
"fixCurrentPosition": [1540, "fix-current-position"],
"disableGesture": [1540, "disable-gesture"],
"allowScroll": [1540, "allow-scroll"],
"positions": [1537],
"hidden": [1540],
"coefAnimationTime": [1538, "coef-animation-time"],
"safeAreaTop": [1538, "safe-area-top"],
"safeAreaBottom": [1538, "safe-area-bottom"],
"getNav": [64],
"goBack": [64],
"goBackToRoot": [64],
"goBackToIndex": [64],
"getNavActive": [64],
"getNavCurrentComponent": [64],
"saveStateInActiveComponent": [64],
"pushNav": [64],
"getActiveComponentTagName": [64],
"getCurrentIndex": [64],
"getCurrrentPositionDto": [64],
"getPositionByName": [64],
"getPositionByIndex":