UNPKG

@zoff-tech/zt-bottom-drawer

Version:
1,549 lines (1,545 loc) 50.9 kB
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":