UNPKG

5.91 kBJavaScriptView Raw
1/*!
2 * (C) Ionic http://ionicframework.com - MIT License
3 */
4import { readTask, writeTask, proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
5import { b as getIonMode } from './ionic-global.js';
6import { j as clamp, c as componentOnReady } from './helpers.js';
7
8const handleFooterFade = (scrollEl, baseEl) => {
9 readTask(() => {
10 const scrollTop = scrollEl.scrollTop;
11 const maxScroll = scrollEl.scrollHeight - scrollEl.clientHeight;
12 /**
13 * Toolbar background will fade
14 * out over fadeDuration in pixels.
15 */
16 const fadeDuration = 10;
17 /**
18 * Begin fading out maxScroll - 30px
19 * from the bottom of the content.
20 * Also determine how close we are
21 * to starting the fade. If we are
22 * before the starting point, the
23 * scale value will get clamped to 0.
24 * If we are after the maxScroll (rubber
25 * band scrolling), the scale value will
26 * get clamped to 1.
27 */
28 const fadeStart = maxScroll - fadeDuration;
29 const distanceToStart = scrollTop - fadeStart;
30 const scale = clamp(0, 1 - (distanceToStart / fadeDuration), 1);
31 writeTask(() => {
32 baseEl.style.setProperty('--opacity-scale', scale.toString());
33 });
34 });
35};
36
37const footerIosCss = "ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-ios ion-toolbar:first-of-type{--border-width:0.55px 0 0}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.footer-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.footer-translucent-ios ion-toolbar{--opacity:.8}}.footer-ios.ion-no-border ion-toolbar:first-of-type{--border-width:0}.footer-collapse-fade ion-toolbar{--opacity-scale:inherit}";
38
39const footerMdCss = "ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-md::before{left:0;top:-2px;bottom:auto;background-position:left 0 top 0;position:absolute;width:100%;height:2px;background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAHBAMAAADzDtBxAAAAD1BMVEUAAAAAAAAAAAAAAAAAAABPDueNAAAABXRSTlMUCS0gBIh/TXEAAAAaSURBVAjXYxCEAgY4UIICBmMogMsgFLtAAQCNSwXZKOdPxgAAAABJRU5ErkJggg==\");background-repeat:repeat-x;content:\"\"}[dir=rtl] .footer-md::before,:host-context([dir=rtl]) .footer-md::before{left:unset;right:unset;right:0}[dir=rtl] .footer-md::before,:host-context([dir=rtl]) .footer-md::before{background-position:right 0 top 0}.footer-md.ion-no-border::before{display:none}";
40
41const Footer = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
42 constructor() {
43 super();
44 this.__registerHost();
45 /**
46 * If `true`, the footer will be translucent.
47 * Only applies when the mode is `"ios"` and the device supports
48 * [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
49 *
50 * Note: In order to scroll content behind the footer, the `fullscreen`
51 * attribute needs to be set on the content.
52 */
53 this.translucent = false;
54 this.checkCollapsibleFooter = () => {
55 const mode = getIonMode(this);
56 if (mode !== 'ios') {
57 return;
58 }
59 const { collapse } = this;
60 const hasFade = collapse === 'fade';
61 this.destroyCollapsibleFooter();
62 if (hasFade) {
63 const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
64 const contentEl = (pageEl) ? pageEl.querySelector('ion-content') : null;
65 this.setupFadeFooter(contentEl);
66 }
67 };
68 this.setupFadeFooter = async (contentEl) => {
69 if (!contentEl) {
70 console.error('ion-footer requires a content to collapse. Make sure there is an ion-content.');
71 return;
72 }
73 await new Promise(resolve => componentOnReady(contentEl, resolve));
74 const scrollEl = this.scrollEl = await contentEl.getScrollElement();
75 /**
76 * Handle fading of toolbars on scroll
77 */
78 this.contentScrollCallback = () => { handleFooterFade(scrollEl, this.el); };
79 scrollEl.addEventListener('scroll', this.contentScrollCallback);
80 handleFooterFade(scrollEl, this.el);
81 };
82 }
83 componentDidLoad() {
84 this.checkCollapsibleFooter();
85 }
86 componentDidUpdate() {
87 this.checkCollapsibleFooter();
88 }
89 destroyCollapsibleFooter() {
90 if (this.scrollEl && this.contentScrollCallback) {
91 this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
92 this.contentScrollCallback = undefined;
93 }
94 }
95 render() {
96 const { translucent, collapse } = this;
97 const mode = getIonMode(this);
98 return (h(Host, { role: "contentinfo", class: {
99 [mode]: true,
100 // Used internally for styling
101 [`footer-${mode}`]: true,
102 [`footer-translucent`]: translucent,
103 [`footer-translucent-${mode}`]: translucent,
104 [`footer-collapse-${collapse}`]: collapse !== undefined,
105 } }, mode === 'ios' && translucent &&
106 h("div", { class: "footer-background" }), h("slot", null)));
107 }
108 get el() { return this; }
109 static get style() { return {
110 ios: footerIosCss,
111 md: footerMdCss
112 }; }
113}, [36, "ion-footer", {
114 "collapse": [1],
115 "translucent": [4]
116 }]);
117function defineCustomElement$1() {
118 if (typeof customElements === "undefined") {
119 return;
120 }
121 const components = ["ion-footer"];
122 components.forEach(tagName => { switch (tagName) {
123 case "ion-footer":
124 if (!customElements.get(tagName)) {
125 customElements.define(tagName, Footer);
126 }
127 break;
128 } });
129}
130
131const IonFooter = Footer;
132const defineCustomElement = defineCustomElement$1;
133
134export { IonFooter, defineCustomElement };