123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- /*!
- * (C) Ionic http://ionicframework.com - MIT License
- */
- import { c as createAnimation } from './animation.js';
- import { g as getIonPageElement } from './index2.js';
- const DURATION = 540;
- // TODO(FW-2832): types
- const getClonedElement = (tagName) => {
- return document.querySelector(`${tagName}.ion-cloned-element`);
- };
- const shadow = (el) => {
- return el.shadowRoot || el;
- };
- const getLargeTitle = (refEl) => {
- const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
- const query = 'ion-content ion-header:not(.header-collapse-condense-inactive) ion-title.title-large';
- if (tabs != null) {
- const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
- return activeTab != null ? activeTab.querySelector(query) : null;
- }
- return refEl.querySelector(query);
- };
- const getBackButton = (refEl, backDirection) => {
- const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
- let buttonsList = [];
- if (tabs != null) {
- const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
- if (activeTab != null) {
- buttonsList = activeTab.querySelectorAll('ion-buttons');
- }
- }
- else {
- buttonsList = refEl.querySelectorAll('ion-buttons');
- }
- for (const buttons of buttonsList) {
- const parentHeader = buttons.closest('ion-header');
- const activeHeader = parentHeader && !parentHeader.classList.contains('header-collapse-condense-inactive');
- const backButton = buttons.querySelector('ion-back-button');
- const buttonsCollapse = buttons.classList.contains('buttons-collapse');
- const startSlot = buttons.slot === 'start' || buttons.slot === '';
- if (backButton !== null && startSlot && ((buttonsCollapse && activeHeader && backDirection) || !buttonsCollapse)) {
- return backButton;
- }
- }
- return null;
- };
- const createLargeTitleTransition = (rootAnimation, rtl, backDirection, enteringEl, leavingEl) => {
- const enteringBackButton = getBackButton(enteringEl, backDirection);
- const leavingLargeTitle = getLargeTitle(leavingEl);
- const enteringLargeTitle = getLargeTitle(enteringEl);
- const leavingBackButton = getBackButton(leavingEl, backDirection);
- const shouldAnimationForward = enteringBackButton !== null && leavingLargeTitle !== null && !backDirection;
- const shouldAnimationBackward = enteringLargeTitle !== null && leavingBackButton !== null && backDirection;
- if (shouldAnimationForward) {
- const leavingLargeTitleBox = leavingLargeTitle.getBoundingClientRect();
- const enteringBackButtonBox = enteringBackButton.getBoundingClientRect();
- const enteringBackButtonTextEl = shadow(enteringBackButton).querySelector('.button-text');
- // Text element not rendered if developers pass text="" to the back button
- const enteringBackButtonTextBox = enteringBackButtonTextEl === null || enteringBackButtonTextEl === void 0 ? void 0 : enteringBackButtonTextEl.getBoundingClientRect();
- const leavingLargeTitleTextEl = shadow(leavingLargeTitle).querySelector('.toolbar-title');
- const leavingLargeTitleTextBox = leavingLargeTitleTextEl.getBoundingClientRect();
- animateLargeTitle(rootAnimation, rtl, backDirection, leavingLargeTitle, leavingLargeTitleBox, leavingLargeTitleTextBox, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox);
- animateBackButton(rootAnimation, rtl, backDirection, enteringBackButton, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox, leavingLargeTitle, leavingLargeTitleTextBox);
- }
- else if (shouldAnimationBackward) {
- const enteringLargeTitleBox = enteringLargeTitle.getBoundingClientRect();
- const leavingBackButtonBox = leavingBackButton.getBoundingClientRect();
- const leavingBackButtonTextEl = shadow(leavingBackButton).querySelector('.button-text');
- // Text element not rendered if developers pass text="" to the back button
- const leavingBackButtonTextBox = leavingBackButtonTextEl === null || leavingBackButtonTextEl === void 0 ? void 0 : leavingBackButtonTextEl.getBoundingClientRect();
- const enteringLargeTitleTextEl = shadow(enteringLargeTitle).querySelector('.toolbar-title');
- const enteringLargeTitleTextBox = enteringLargeTitleTextEl.getBoundingClientRect();
- animateLargeTitle(rootAnimation, rtl, backDirection, enteringLargeTitle, enteringLargeTitleBox, enteringLargeTitleTextBox, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox);
- animateBackButton(rootAnimation, rtl, backDirection, leavingBackButton, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox, enteringLargeTitle, enteringLargeTitleTextBox);
- }
- return {
- forward: shouldAnimationForward,
- backward: shouldAnimationBackward,
- };
- };
- const animateBackButton = (rootAnimation, rtl, backDirection, backButtonEl, backButtonBox, backButtonTextEl, backButtonTextBox, largeTitleEl, largeTitleTextBox) => {
- var _a, _b;
- const BACK_BUTTON_START_OFFSET = rtl ? `calc(100% - ${backButtonBox.right + 4}px)` : `${backButtonBox.left - 4}px`;
- const TEXT_ORIGIN_X = rtl ? 'right' : 'left';
- const ICON_ORIGIN_X = rtl ? 'left' : 'right';
- const CONTAINER_ORIGIN_X = rtl ? 'right' : 'left';
- let WIDTH_SCALE = 1;
- let HEIGHT_SCALE = 1;
- let TEXT_START_SCALE = `scale(${HEIGHT_SCALE})`;
- const TEXT_END_SCALE = 'scale(1)';
- if (backButtonTextEl && backButtonTextBox) {
- /**
- * When the title and back button texts match then they should overlap during the
- * page transition. If the texts do not match up then the back button text scale
- * adjusts to not perfectly match the large title text otherwise the proportions
- * will be incorrect. When the texts match we scale both the width and height to
- * account for font weight differences between the title and back button.
- */
- const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
- WIDTH_SCALE = largeTitleTextBox.width / backButtonTextBox.width;
- /**
- * Subtract an offset to account for slight sizing/padding differences between the
- * title and the back button.
- */
- HEIGHT_SCALE = (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET) / backButtonTextBox.height;
- /**
- * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
- * to re-compute this here since the HEIGHT_SCALE may have changed.
- */
- TEXT_START_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
- }
- const backButtonIconEl = shadow(backButtonEl).querySelector('ion-icon');
- const backButtonIconBox = backButtonIconEl.getBoundingClientRect();
- /**
- * We need to offset the container by the icon dimensions
- * so that the back button text aligns with the large title
- * text. Otherwise, the back button icon will align with the
- * large title text but the back button text will not.
- */
- const CONTAINER_START_TRANSLATE_X = rtl
- ? `${backButtonIconBox.width / 2 - (backButtonIconBox.right - backButtonBox.right)}px`
- : `${backButtonBox.left - backButtonIconBox.width / 2}px`;
- const CONTAINER_END_TRANSLATE_X = rtl ? `-${window.innerWidth - backButtonBox.right}px` : `${backButtonBox.left}px`;
- /**
- * Back button container should be
- * aligned to the top of the title container
- * so the texts overlap as the back button
- * text begins to fade in.
- */
- const CONTAINER_START_TRANSLATE_Y = `${largeTitleTextBox.top}px`;
- /**
- * The cloned back button should align exactly with the
- * real back button on the entering page otherwise there will
- * be a layout shift.
- */
- const CONTAINER_END_TRANSLATE_Y = `${backButtonBox.top}px`;
- /**
- * In the forward direction, the cloned back button
- * container should translate from over the large title
- * to over the back button. In the backward direction,
- * it should translate from over the back button to over
- * the large title.
- */
- const FORWARD_CONTAINER_KEYFRAMES = [
- { offset: 0, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
- { offset: 1, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
- ];
- const BACKWARD_CONTAINER_KEYFRAMES = [
- { offset: 0, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
- { offset: 1, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
- ];
- const CONTAINER_KEYFRAMES = backDirection ? BACKWARD_CONTAINER_KEYFRAMES : FORWARD_CONTAINER_KEYFRAMES;
- /**
- * In the forward direction, the text in the cloned back button
- * should start to be (roughly) the size of the large title
- * and then scale down to be the size of the actual back button.
- * The text should also translate, but that translate is handled
- * by the container keyframes.
- */
- const FORWARD_TEXT_KEYFRAMES = [
- { offset: 0, opacity: 0, transform: TEXT_START_SCALE },
- { offset: 1, opacity: 1, transform: TEXT_END_SCALE },
- ];
- const BACKWARD_TEXT_KEYFRAMES = [
- { offset: 0, opacity: 1, transform: TEXT_END_SCALE },
- { offset: 1, opacity: 0, transform: TEXT_START_SCALE },
- ];
- const TEXT_KEYFRAMES = backDirection ? BACKWARD_TEXT_KEYFRAMES : FORWARD_TEXT_KEYFRAMES;
- /**
- * The icon should scale in/out in the second
- * half of the animation. The icon should also
- * translate, but that translate is handled by the
- * container keyframes.
- */
- const FORWARD_ICON_KEYFRAMES = [
- { offset: 0, opacity: 0, transform: 'scale(0.6)' },
- { offset: 0.6, opacity: 0, transform: 'scale(0.6)' },
- { offset: 1, opacity: 1, transform: 'scale(1)' },
- ];
- const BACKWARD_ICON_KEYFRAMES = [
- { offset: 0, opacity: 1, transform: 'scale(1)' },
- { offset: 0.2, opacity: 0, transform: 'scale(0.6)' },
- { offset: 1, opacity: 0, transform: 'scale(0.6)' },
- ];
- const ICON_KEYFRAMES = backDirection ? BACKWARD_ICON_KEYFRAMES : FORWARD_ICON_KEYFRAMES;
- const enteringBackButtonTextAnimation = createAnimation();
- const enteringBackButtonIconAnimation = createAnimation();
- const enteringBackButtonAnimation = createAnimation();
- const clonedBackButtonEl = getClonedElement('ion-back-button');
- const clonedBackButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text');
- const clonedBackButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon');
- clonedBackButtonEl.text = backButtonEl.text;
- clonedBackButtonEl.mode = backButtonEl.mode;
- clonedBackButtonEl.icon = backButtonEl.icon;
- clonedBackButtonEl.color = backButtonEl.color;
- clonedBackButtonEl.disabled = backButtonEl.disabled;
- clonedBackButtonEl.style.setProperty('display', 'block');
- clonedBackButtonEl.style.setProperty('position', 'fixed');
- enteringBackButtonIconAnimation.addElement(clonedBackButtonIconEl);
- enteringBackButtonTextAnimation.addElement(clonedBackButtonTextEl);
- enteringBackButtonAnimation.addElement(clonedBackButtonEl);
- enteringBackButtonAnimation
- .beforeStyles({
- position: 'absolute',
- top: '0px',
- [CONTAINER_ORIGIN_X]: '0px',
- })
- /**
- * The write hooks must be set on this animation as it is guaranteed to run. Other
- * animations such as the back button text animation will not run if the back button
- * has no visible text.
- */
- .beforeAddWrite(() => {
- backButtonEl.style.setProperty('display', 'none');
- clonedBackButtonEl.style.setProperty(TEXT_ORIGIN_X, BACK_BUTTON_START_OFFSET);
- })
- .afterAddWrite(() => {
- backButtonEl.style.setProperty('display', '');
- clonedBackButtonEl.style.setProperty('display', 'none');
- clonedBackButtonEl.style.removeProperty(TEXT_ORIGIN_X);
- })
- .keyframes(CONTAINER_KEYFRAMES);
- enteringBackButtonTextAnimation
- .beforeStyles({
- 'transform-origin': `${TEXT_ORIGIN_X} top`,
- })
- .keyframes(TEXT_KEYFRAMES);
- enteringBackButtonIconAnimation
- .beforeStyles({
- 'transform-origin': `${ICON_ORIGIN_X} center`,
- })
- .keyframes(ICON_KEYFRAMES);
- rootAnimation.addAnimation([
- enteringBackButtonTextAnimation,
- enteringBackButtonIconAnimation,
- enteringBackButtonAnimation,
- ]);
- };
- const animateLargeTitle = (rootAnimation, rtl, backDirection, largeTitleEl, largeTitleBox, largeTitleTextBox, backButtonBox, backButtonTextEl, backButtonTextBox) => {
- var _a, _b;
- /**
- * The horizontal transform origin for the large title
- */
- const ORIGIN_X = rtl ? 'right' : 'left';
- const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`;
- /**
- * The cloned large should align exactly with the
- * real large title on the leaving page otherwise there will
- * be a layout shift.
- */
- const START_TRANSLATE_X = '0px';
- const START_TRANSLATE_Y = `${largeTitleBox.top}px`;
- /**
- * How much to offset the large title translation by.
- * This accounts for differences in sizing between the large
- * title and the back button due to padding and font weight.
- */
- const LARGE_TITLE_TRANSLATION_OFFSET = 8;
- let END_TRANSLATE_X = rtl
- ? `-${window.innerWidth - backButtonBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
- : `${backButtonBox.x + LARGE_TITLE_TRANSLATION_OFFSET}px`;
- /**
- * How much to scale the large title up/down by.
- */
- let HEIGHT_SCALE = 0.5;
- /**
- * The large title always starts full size.
- */
- const START_SCALE = 'scale(1)';
- /**
- * By default, we don't worry about having the large title scaled to perfectly
- * match the back button because we don't know if the back button's text matches
- * the large title's text.
- */
- let END_SCALE = `scale(${HEIGHT_SCALE})`;
- // Text element not rendered if developers pass text="" to the back button
- if (backButtonTextEl && backButtonTextBox) {
- /**
- * The scaled title should (roughly) overlap the back button. This ensures that
- * the back button and title overlap during the animation. Note that since both
- * elements either fade in or fade out over the course of the animation, neither
- * element will be fully visible on top of the other. As a result, the overlap
- * does not need to be perfect, so approximate values are acceptable here.
- */
- END_TRANSLATE_X = rtl
- ? `-${window.innerWidth - backButtonTextBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
- : `${backButtonTextBox.x - LARGE_TITLE_TRANSLATION_OFFSET}px`;
- /**
- * In the forward direction, the large title should start at its normal size and
- * then scale down to be (roughly) the size of the back button on the other view.
- * In the backward direction, the large title should start at (roughly) the size
- * of the back button and then scale up to its original size.
- * Note that since both elements either fade in or fade out over the course of the
- * animation, neither element will be fully visible on top of the other. As a result,
- * the overlap does not need to be perfect, so approximate values are acceptable here.
- */
- /**
- * When the title and back button texts match then they should overlap during the
- * page transition. If the texts do not match up then the large title text scale
- * adjusts to not perfectly match the back button text otherwise the proportions
- * will be incorrect. When the texts match we scale both the width and height to
- * account for font weight differences between the title and back button.
- */
- const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
- const WIDTH_SCALE = backButtonTextBox.width / largeTitleTextBox.width;
- HEIGHT_SCALE = backButtonTextBox.height / (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET);
- /**
- * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
- * to re-compute this here since the HEIGHT_SCALE may have changed.
- */
- END_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
- }
- /**
- * The midpoints of the back button and the title should align such that the back
- * button and title appear to be centered with each other.
- */
- const backButtonMidPoint = backButtonBox.top + backButtonBox.height / 2;
- const titleMidPoint = (largeTitleBox.height * HEIGHT_SCALE) / 2;
- const END_TRANSLATE_Y = `${backButtonMidPoint - titleMidPoint}px`;
- const BACKWARDS_KEYFRAMES = [
- { offset: 0, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
- { offset: 0.1, opacity: 0 },
- { offset: 1, opacity: 1, transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}` },
- ];
- const FORWARDS_KEYFRAMES = [
- {
- offset: 0,
- opacity: 0.99,
- transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}`,
- },
- { offset: 0.6, opacity: 0 },
- { offset: 1, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
- ];
- const KEYFRAMES = backDirection ? BACKWARDS_KEYFRAMES : FORWARDS_KEYFRAMES;
- const clonedTitleEl = getClonedElement('ion-title');
- const clonedLargeTitleAnimation = createAnimation();
- clonedTitleEl.innerText = largeTitleEl.innerText;
- clonedTitleEl.size = largeTitleEl.size;
- clonedTitleEl.color = largeTitleEl.color;
- clonedLargeTitleAnimation.addElement(clonedTitleEl);
- clonedLargeTitleAnimation
- .beforeStyles({
- 'transform-origin': `${ORIGIN_X} top`,
- /**
- * Since font size changes will cause
- * the dimension of the large title to change
- * we need to set the cloned title height
- * equal to that of the original large title height.
- */
- height: `${largeTitleBox.height}px`,
- display: '',
- position: 'relative',
- [ORIGIN_X]: TITLE_START_OFFSET,
- })
- .beforeAddWrite(() => {
- largeTitleEl.style.setProperty('opacity', '0');
- })
- .afterAddWrite(() => {
- largeTitleEl.style.setProperty('opacity', '');
- clonedTitleEl.style.setProperty('display', 'none');
- })
- .keyframes(KEYFRAMES);
- rootAnimation.addAnimation(clonedLargeTitleAnimation);
- };
- const iosTransitionAnimation = (navEl, opts) => {
- var _a;
- try {
- const EASING = 'cubic-bezier(0.32,0.72,0,1)';
- const OPACITY = 'opacity';
- const TRANSFORM = 'transform';
- const CENTER = '0%';
- const OFF_OPACITY = 0.8;
- const isRTL = navEl.ownerDocument.dir === 'rtl';
- const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
- const OFF_LEFT = isRTL ? '33%' : '-33%';
- const enteringEl = opts.enteringEl;
- const leavingEl = opts.leavingEl;
- const backDirection = opts.direction === 'back';
- const contentEl = enteringEl.querySelector(':scope > ion-content');
- const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
- const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
- const rootAnimation = createAnimation();
- const enteringContentAnimation = createAnimation();
- rootAnimation
- .addElement(enteringEl)
- .duration(((_a = opts.duration) !== null && _a !== void 0 ? _a : 0) || DURATION)
- .easing(opts.easing || EASING)
- .fill('both')
- .beforeRemoveClass('ion-page-invisible');
- // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
- if (leavingEl && navEl !== null && navEl !== undefined) {
- const navDecorAnimation = createAnimation();
- navDecorAnimation.addElement(navEl);
- rootAnimation.addAnimation(navDecorAnimation);
- }
- if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
- enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
- }
- else {
- enteringContentAnimation.addElement(contentEl); // REVIEW
- enteringContentAnimation.addElement(headerEls);
- }
- rootAnimation.addAnimation(enteringContentAnimation);
- if (backDirection) {
- enteringContentAnimation
- .beforeClearStyles([OPACITY])
- .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
- .fromTo(OPACITY, OFF_OPACITY, 1);
- }
- else {
- // entering content, forward direction
- enteringContentAnimation
- .beforeClearStyles([OPACITY])
- .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
- }
- if (contentEl) {
- const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
- if (enteringTransitionEffectEl) {
- const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
- const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
- const enteringTransitionEffect = createAnimation();
- const enteringTransitionCover = createAnimation();
- const enteringTransitionShadow = createAnimation();
- enteringTransitionEffect
- .addElement(enteringTransitionEffectEl)
- .beforeStyles({ opacity: '1', display: 'block' })
- .afterStyles({ opacity: '', display: '' });
- enteringTransitionCover
- .addElement(enteringTransitionCoverEl) // REVIEW
- .beforeClearStyles([OPACITY])
- .fromTo(OPACITY, 0, 0.1);
- enteringTransitionShadow
- .addElement(enteringTransitionShadowEl) // REVIEW
- .beforeClearStyles([OPACITY])
- .fromTo(OPACITY, 0.03, 0.7);
- enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
- enteringContentAnimation.addAnimation([enteringTransitionEffect]);
- }
- }
- const enteringContentHasLargeTitle = enteringEl.querySelector('ion-header.header-collapse-condense');
- const { forward, backward } = createLargeTitleTransition(rootAnimation, isRTL, backDirection, enteringEl, leavingEl);
- enteringToolBarEls.forEach((enteringToolBarEl) => {
- const enteringToolBar = createAnimation();
- enteringToolBar.addElement(enteringToolBarEl);
- rootAnimation.addAnimation(enteringToolBar);
- const enteringTitle = createAnimation();
- enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title')); // REVIEW
- const enteringToolBarButtons = createAnimation();
- const buttons = Array.from(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
- const parentHeader = enteringToolBarEl.closest('ion-header');
- const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
- let buttonsToAnimate;
- if (backDirection) {
- buttonsToAnimate = buttons.filter((button) => {
- const isCollapseButton = button.classList.contains('buttons-collapse');
- return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
- });
- }
- else {
- buttonsToAnimate = buttons.filter((button) => !button.classList.contains('buttons-collapse'));
- }
- enteringToolBarButtons.addElement(buttonsToAnimate);
- const enteringToolBarItems = createAnimation();
- enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
- const enteringToolBarBg = createAnimation();
- enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background')); // REVIEW
- const enteringBackButton = createAnimation();
- const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
- if (backButtonEl) {
- enteringBackButton.addElement(backButtonEl);
- }
- enteringToolBar.addAnimation([
- enteringTitle,
- enteringToolBarButtons,
- enteringToolBarItems,
- enteringToolBarBg,
- enteringBackButton,
- ]);
- enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
- enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
- if (backDirection) {
- if (!inactiveHeader) {
- enteringTitle
- .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
- .fromTo(OPACITY, 0.01, 1);
- }
- enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
- // back direction, entering page has a back button
- enteringBackButton.fromTo(OPACITY, 0.01, 1);
- }
- else {
- // entering toolbar, forward direction
- if (!enteringContentHasLargeTitle) {
- enteringTitle
- .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`)
- .fromTo(OPACITY, 0.01, 1);
- }
- enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
- enteringToolBarBg.beforeClearStyles([OPACITY, 'transform']);
- const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
- if (!translucentHeader) {
- enteringToolBarBg.fromTo(OPACITY, 0.01, 'var(--opacity)');
- }
- else {
- enteringToolBarBg.fromTo('transform', isRTL ? 'translateX(-100%)' : 'translateX(100%)', 'translateX(0px)');
- }
- // forward direction, entering page has a back button
- if (!forward) {
- enteringBackButton.fromTo(OPACITY, 0.01, 1);
- }
- if (backButtonEl && !forward) {
- const enteringBackBtnText = createAnimation();
- enteringBackBtnText
- .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
- .fromTo(`transform`, isRTL ? 'translateX(-100px)' : 'translateX(100px)', 'translateX(0px)');
- enteringToolBar.addAnimation(enteringBackBtnText);
- }
- }
- });
- // setup leaving view
- if (leavingEl) {
- const leavingContent = createAnimation();
- const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
- const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
- const leavingHeaderEls = leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
- if (!leavingContentEl && leavingToolBarEls.length === 0 && leavingHeaderEls.length === 0) {
- leavingContent.addElement(leavingEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
- }
- else {
- leavingContent.addElement(leavingContentEl); // REVIEW
- leavingContent.addElement(leavingHeaderEls);
- }
- rootAnimation.addAnimation(leavingContent);
- if (backDirection) {
- // leaving content, back direction
- leavingContent
- .beforeClearStyles([OPACITY])
- .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
- const leavingPage = getIonPageElement(leavingEl);
- rootAnimation.afterAddWrite(() => {
- if (rootAnimation.getDirection() === 'normal') {
- leavingPage.style.setProperty('display', 'none');
- }
- });
- }
- else {
- // leaving content, forward direction
- leavingContent
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
- .fromTo(OPACITY, 1, OFF_OPACITY);
- }
- if (leavingContentEl) {
- const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
- if (leavingTransitionEffectEl) {
- const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
- const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
- const leavingTransitionEffect = createAnimation();
- const leavingTransitionCover = createAnimation();
- const leavingTransitionShadow = createAnimation();
- leavingTransitionEffect
- .addElement(leavingTransitionEffectEl)
- .beforeStyles({ opacity: '1', display: 'block' })
- .afterStyles({ opacity: '', display: '' });
- leavingTransitionCover
- .addElement(leavingTransitionCoverEl) // REVIEW
- .beforeClearStyles([OPACITY])
- .fromTo(OPACITY, 0.1, 0);
- leavingTransitionShadow
- .addElement(leavingTransitionShadowEl) // REVIEW
- .beforeClearStyles([OPACITY])
- .fromTo(OPACITY, 0.7, 0.03);
- leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
- leavingContent.addAnimation([leavingTransitionEffect]);
- }
- }
- leavingToolBarEls.forEach((leavingToolBarEl) => {
- const leavingToolBar = createAnimation();
- leavingToolBar.addElement(leavingToolBarEl);
- const leavingTitle = createAnimation();
- leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title')); // REVIEW
- const leavingToolBarButtons = createAnimation();
- const buttons = leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]');
- const parentHeader = leavingToolBarEl.closest('ion-header');
- const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
- const buttonsToAnimate = Array.from(buttons).filter((button) => {
- const isCollapseButton = button.classList.contains('buttons-collapse');
- return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
- });
- leavingToolBarButtons.addElement(buttonsToAnimate);
- const leavingToolBarItems = createAnimation();
- const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
- if (leavingToolBarItemEls.length > 0) {
- leavingToolBarItems.addElement(leavingToolBarItemEls);
- }
- const leavingToolBarBg = createAnimation();
- leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background')); // REVIEW
- const leavingBackButton = createAnimation();
- const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
- if (backButtonEl) {
- leavingBackButton.addElement(backButtonEl);
- }
- leavingToolBar.addAnimation([
- leavingTitle,
- leavingToolBarButtons,
- leavingToolBarItems,
- leavingBackButton,
- leavingToolBarBg,
- ]);
- rootAnimation.addAnimation(leavingToolBar);
- // fade out leaving toolbar items
- leavingBackButton.fromTo(OPACITY, 0.99, 0);
- leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
- leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
- if (backDirection) {
- if (!inactiveHeader) {
- // leaving toolbar, back direction
- leavingTitle
- .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)')
- .fromTo(OPACITY, 0.99, 0);
- }
- leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
- leavingToolBarBg.beforeClearStyles([OPACITY, 'transform']);
- // leaving toolbar, back direction, and there's no entering toolbar
- // should just slide out, no fading out
- const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
- if (!translucentHeader) {
- leavingToolBarBg.fromTo(OPACITY, 'var(--opacity)', 0);
- }
- else {
- leavingToolBarBg.fromTo('transform', 'translateX(0px)', isRTL ? 'translateX(-100%)' : 'translateX(100%)');
- }
- if (backButtonEl && !backward) {
- const leavingBackBtnText = createAnimation();
- leavingBackBtnText
- .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
- leavingToolBar.addAnimation(leavingBackBtnText);
- }
- }
- else {
- // leaving toolbar, forward direction
- if (!inactiveHeader) {
- leavingTitle
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
- .fromTo(OPACITY, 0.99, 0)
- .afterClearStyles([TRANSFORM, OPACITY]);
- }
- leavingToolBarItems
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
- .afterClearStyles([TRANSFORM, OPACITY]);
- leavingBackButton.afterClearStyles([OPACITY]);
- leavingTitle.afterClearStyles([OPACITY]);
- leavingToolBarButtons.afterClearStyles([OPACITY]);
- }
- });
- }
- return rootAnimation;
- }
- catch (err) {
- throw err;
- }
- };
- /**
- * The scale of the back button during the animation
- * is computed based on the scale of the large title
- * and vice versa. However, we need to account for slight
- * variations in the size of the large title due to
- * padding and font weight. This value should be used to subtract
- * a small amount from the large title height when computing scales
- * to get more accurate scale results.
- */
- const LARGE_TITLE_SIZE_OFFSET = 10;
- export { iosTransitionAnimation, shadow };
|