/
footer.tsx
118 lines (95 loc) · 3.06 KB
/
footer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { findIonContent, getScrollElement, printIonContentErrorMsg } from '../../utils/content';
import { handleFooterFade } from './footer.utils';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@Component({
tag: 'ion-footer',
styleUrls: {
ios: 'footer.ios.scss',
md: 'footer.md.scss',
},
})
export class Footer implements ComponentInterface {
private scrollEl?: HTMLElement;
private contentScrollCallback: any;
@Element() el!: HTMLIonFooterElement;
/**
* Describes the scroll effect that will be applied to the footer.
* Only applies in iOS mode.
*/
@Prop() collapse?: 'fade';
/**
* If `true`, the footer will be translucent.
* Only applies when the mode is `"ios"` and the device supports
* [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*
* Note: In order to scroll content behind the footer, the `fullscreen`
* attribute needs to be set on the content.
*/
@Prop() translucent = false;
componentDidLoad() {
this.checkCollapsibleFooter();
}
componentDidUpdate() {
this.checkCollapsibleFooter();
}
private checkCollapsibleFooter = () => {
const mode = getIonMode(this);
if (mode !== 'ios') {
return;
}
const { collapse } = this;
const hasFade = collapse === 'fade';
this.destroyCollapsibleFooter();
if (hasFade) {
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
const contentEl = pageEl ? findIonContent(pageEl) : null;
if (!contentEl) {
printIonContentErrorMsg(this.el);
return;
}
this.setupFadeFooter(contentEl);
}
};
private setupFadeFooter = async (contentEl: HTMLElement) => {
const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
/**
* Handle fading of toolbars on scroll
*/
this.contentScrollCallback = () => {
handleFooterFade(scrollEl, this.el);
};
scrollEl.addEventListener('scroll', this.contentScrollCallback);
handleFooterFade(scrollEl, this.el);
};
private destroyCollapsibleFooter() {
if (this.scrollEl && this.contentScrollCallback) {
this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
this.contentScrollCallback = undefined;
}
}
render() {
const { translucent, collapse } = this;
const mode = getIonMode(this);
return (
<Host
role="contentinfo"
class={{
[mode]: true,
// Used internally for styling
[`footer-${mode}`]: true,
[`footer-translucent`]: translucent,
[`footer-translucent-${mode}`]: translucent,
[`footer-collapse-${collapse}`]: collapse !== undefined,
}}
>
{mode === 'ios' && translucent && <div class="footer-background"></div>}
<slot></slot>
</Host>
);
}
}